summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Release Tools Bot <delivery-team+release-tools@gitlab.com>2022-03-31 13:35:21 +0000
committerGitLab Release Tools Bot <delivery-team+release-tools@gitlab.com>2022-03-31 13:35:21 +0000
commit7bc34aad19503153d8d9b849006e59b43a1eda5b (patch)
tree45e48f5056d711d3f48a4866516599e7ed56d6a0 /spec
parent7bc3851c3276c365434ef23e3785102e5b01705a (diff)
parentd51b185ed5091afd1b668fe8df0c57cd8f629ec0 (diff)
downloadgitlab-ce-7bc34aad19503153d8d9b849006e59b43a1eda5b.tar.gz
Merge remote-tracking branch 'dev/14-8-stable' into 14-8-stable
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/admin/users_controller_spec.rb4
-rw-r--r--spec/controllers/projects/merge_requests/creations_controller_spec.rb18
-rw-r--r--spec/controllers/projects/mirrors_controller_spec.rb1
-rw-r--r--spec/controllers/registrations_controller_spec.rb4
-rw-r--r--spec/factories/users.rb6
-rw-r--r--spec/features/markdown/kroki_spec.rb55
-rw-r--r--spec/features/password_reset_spec.rb4
-rw-r--r--spec/features/profile_spec.rb2
-rw-r--r--spec/features/profiles/password_spec.rb8
-rw-r--r--spec/features/projects/blobs/blob_show_spec.rb47
-rw-r--r--spec/features/users/anonymous_sessions_spec.rb2
-rw-r--r--spec/features/users/login_spec.rb45
-rw-r--r--spec/frontend/behaviors/components/diagram_performance_warning_spec.js40
-rw-r--r--spec/graphql/resolvers/project_pipeline_statistics_resolver_spec.rb70
-rw-r--r--spec/initializers/rdoc_segfault_patch_spec.rb24
-rw-r--r--spec/lib/banzai/filter/kroki_filter_spec.rb12
-rw-r--r--spec/lib/banzai/filter/syntax_highlight_filter_spec.rb6
-rw-r--r--spec/lib/banzai/reference_redactor_spec.rb2
-rw-r--r--spec/lib/gitlab/auth_spec.rb30
-rw-r--r--spec/lib/gitlab/ci/config/external/file/artifact_spec.rb8
-rw-r--r--spec/lib/gitlab/ci/config/external/file/base_spec.rb8
-rw-r--r--spec/lib/gitlab/ci/config/external/file/local_spec.rb22
-rw-r--r--spec/lib/gitlab/ci/config/external/file/project_spec.rb16
-rw-r--r--spec/lib/gitlab/ci/config/external/file/remote_spec.rb15
-rw-r--r--spec/lib/gitlab/ci/config/external/file/template_spec.rb6
-rw-r--r--spec/lib/gitlab/ci/config/external/mapper_spec.rb8
-rw-r--r--spec/lib/gitlab/error_tracking/processor/sanitize_error_message_processor_spec.rb39
-rw-r--r--spec/lib/gitlab/error_tracking_spec.rb43
-rw-r--r--spec/lib/gitlab/exception_log_formatter_spec.rb8
-rw-r--r--spec/lib/gitlab/import_export/members_mapper_spec.rb53
-rw-r--r--spec/lib/gitlab/sanitizers/exception_message_spec.rb54
-rw-r--r--spec/mailers/emails/profile_spec.rb2
-rw-r--r--spec/models/ci/runner_spec.rb14
-rw-r--r--spec/models/hooks/system_hook_spec.rb2
-rw-r--r--spec/models/integrations/asana_spec.rb36
-rw-r--r--spec/models/releases/link_spec.rb11
-rw-r--r--spec/models/ssh_host_key_spec.rb45
-rw-r--r--spec/models/user_spec.rb34
-rw-r--r--spec/policies/project_policy_spec.rb161
-rw-r--r--spec/requests/api/ci/runner/runners_post_spec.rb50
-rw-r--r--spec/requests/api/ci/runners_spec.rb13
-rw-r--r--spec/requests/api/users_spec.rb14
-rw-r--r--spec/requests/git_http_spec.rb4
-rw-r--r--spec/services/ci/create_pipeline_service/creation_errors_and_warnings_spec.rb18
-rw-r--r--spec/services/users/create_service_spec.rb14
-rw-r--r--spec/support/helpers/login_helpers.rb5
-rw-r--r--spec/support/shared_contexts/policies/project_policy_shared_context.rb8
-rw-r--r--spec/support/shared_examples/policies/project_policy_shared_examples.rb13
-rw-r--r--spec/tasks/gitlab/password_rake_spec.rb8
49 files changed, 978 insertions, 134 deletions
diff --git a/spec/controllers/admin/users_controller_spec.rb b/spec/controllers/admin/users_controller_spec.rb
index c52223d4758..c46a12680a2 100644
--- a/spec/controllers/admin/users_controller_spec.rb
+++ b/spec/controllers/admin/users_controller_spec.rb
@@ -612,8 +612,8 @@ RSpec.describe Admin::UsersController do
end
context 'when the new password does not match the password confirmation' do
- let(:password) { Gitlab::Password.test_default }
- let(:password_confirmation) { "not" + Gitlab::Password.test_default }
+ let(:password) { 'some_password' }
+ let(:password_confirmation) { 'not_same_as_password' }
it 'shows the edit page again' do
update_password(user, password, password_confirmation)
diff --git a/spec/controllers/projects/merge_requests/creations_controller_spec.rb b/spec/controllers/projects/merge_requests/creations_controller_spec.rb
index 3c650988b4f..a061a14c7b1 100644
--- a/spec/controllers/projects/merge_requests/creations_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests/creations_controller_spec.rb
@@ -186,6 +186,7 @@ RSpec.describe Projects::MergeRequests::CreationsController do
it 'fetches the commit if a user has access' do
expect(Ability).to receive(:allowed?).with(user, :read_project, project) { true }
+ expect(Ability).to receive(:allowed?).with(user, :create_merge_request_in, project) { true }.at_least(:once)
get :branch_to,
params: {
@@ -199,8 +200,25 @@ RSpec.describe Projects::MergeRequests::CreationsController do
expect(response).to have_gitlab_http_status(:ok)
end
+ it 'does not load the commit when the user cannot create_merge_request_in' do
+ expect(Ability).to receive(:allowed?).with(user, :read_project, project) { true }
+ expect(Ability).to receive(:allowed?).with(user, :create_merge_request_in, project) { false }.at_least(:once)
+
+ get :branch_to,
+ params: {
+ namespace_id: fork_project.namespace,
+ project_id: fork_project,
+ target_project_id: project.id,
+ ref: 'master'
+ }
+
+ expect(assigns(:commit)).to be_nil
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+
it 'does not load the commit when the user cannot read the project' do
expect(Ability).to receive(:allowed?).with(user, :read_project, project) { false }
+ expect(Ability).to receive(:allowed?).with(user, :create_merge_request_in, project) { true }.at_least(:once)
get :branch_to,
params: {
diff --git a/spec/controllers/projects/mirrors_controller_spec.rb b/spec/controllers/projects/mirrors_controller_spec.rb
index 7bc86d7c583..686effd799e 100644
--- a/spec/controllers/projects/mirrors_controller_spec.rb
+++ b/spec/controllers/projects/mirrors_controller_spec.rb
@@ -177,6 +177,7 @@ RSpec.describe Projects::MirrorsController do
INVALID
git@example.com:foo/bar.git
ssh://git@example.com:foo/bar.git
+ ssh://127.0.0.1/foo/bar.git
].each do |url|
it "returns an error with a 400 response for URL #{url.inspect}" do
do_get(project, url)
diff --git a/spec/controllers/registrations_controller_spec.rb b/spec/controllers/registrations_controller_spec.rb
index af34ae2f69b..caff7bcfc7b 100644
--- a/spec/controllers/registrations_controller_spec.rb
+++ b/spec/controllers/registrations_controller_spec.rb
@@ -521,7 +521,7 @@ RSpec.describe RegistrationsController do
end
it 'succeeds if password is confirmed' do
- post :destroy, params: { password: Gitlab::Password.test_default }
+ post :destroy, params: { password: '12345678' }
expect_success
end
@@ -562,7 +562,7 @@ RSpec.describe RegistrationsController do
end
it 'fails' do
- delete :destroy, params: { password: Gitlab::Password.test_default }
+ delete :destroy, params: { password: '12345678' }
expect_failure(s_('Profiles|You must transfer ownership or delete groups you are an owner of before you can delete your account'))
end
diff --git a/spec/factories/users.rb b/spec/factories/users.rb
index 8764ac90af8..7566ec18fa4 100644
--- a/spec/factories/users.rb
+++ b/spec/factories/users.rb
@@ -5,7 +5,7 @@ FactoryBot.define do
email { generate(:email) }
name { generate(:name) }
username { generate(:username) }
- password { Gitlab::Password.test_default }
+ password { "12345678" }
role { 'software_developer' }
confirmed_at { Time.now }
confirmation_token { nil }
@@ -27,6 +27,10 @@ FactoryBot.define do
after(:build) { |user, _| user.block! }
end
+ trait :disallowed_password do
+ password { User::DISALLOWED_PASSWORDS.first }
+ end
+
trait :blocked_pending_approval do
after(:build) { |user, _| user.block_pending_approval! }
end
diff --git a/spec/features/markdown/kroki_spec.rb b/spec/features/markdown/kroki_spec.rb
new file mode 100644
index 00000000000..f02f5d44244
--- /dev/null
+++ b/spec/features/markdown/kroki_spec.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'kroki rendering', :js do
+ let_it_be(:project) { create(:project, :public) }
+
+ before do
+ stub_application_setting(kroki_enabled: true, kroki_url: 'http://localhost:8000')
+ end
+
+ it 'shows kroki image' do
+ plain_text = 'This text length is ignored. ' * 300
+
+ description = <<~KROKI
+ #{plain_text}
+ ```plantuml
+ A -> A: T
+ ```
+ KROKI
+
+ issue = create(:issue, project: project, description: description)
+
+ visit project_issue_path(project, issue)
+
+ within('.description') do
+ expect(page).to have_css('img')
+ expect(page).not_to have_text 'Warning: Displaying this diagram might cause performance issues on this page.'
+ end
+ end
+
+ it 'hides kroki image and shows warning alert when kroki source size is large' do
+ plantuml_text = 'A -> A: T ' * 300
+
+ description = <<~KROKI
+ ```plantuml
+ #{plantuml_text}
+ ```
+ KROKI
+
+ issue = create(:issue, project: project, description: description)
+
+ visit project_issue_path(project, issue)
+
+ within('.description') do
+ expect(page).not_to have_css('img')
+ expect(page).to have_text 'Warning: Displaying this diagram might cause performance issues on this page.'
+
+ click_button 'Display'
+
+ expect(page).to have_css('img')
+ expect(page).not_to have_text 'Warning: Displaying this diagram might cause performance issues on this page.'
+ end
+ end
+end
diff --git a/spec/features/password_reset_spec.rb b/spec/features/password_reset_spec.rb
index 322ccc6a0c0..31b2b2d15aa 100644
--- a/spec/features/password_reset_spec.rb
+++ b/spec/features/password_reset_spec.rb
@@ -44,8 +44,8 @@ RSpec.describe 'Password reset' do
visit(edit_user_password_path(reset_password_token: token))
- fill_in 'New password', with: "new" + Gitlab::Password.test_default
- fill_in 'Confirm new password', with: "new" + Gitlab::Password.test_default
+ fill_in 'New password', with: 'hello1234'
+ fill_in 'Confirm new password', with: 'hello1234'
click_button 'Change your password'
diff --git a/spec/features/profile_spec.rb b/spec/features/profile_spec.rb
index 34eb07d78f1..36657406303 100644
--- a/spec/features/profile_spec.rb
+++ b/spec/features/profile_spec.rb
@@ -29,7 +29,7 @@ RSpec.describe 'Profile account page', :js do
it 'deletes user', :js, :sidekiq_might_not_need_inline do
click_button 'Delete account'
- fill_in 'password', with: Gitlab::Password.test_default
+ fill_in 'password', with: '12345678'
page.within '.modal' do
click_button 'Delete account'
diff --git a/spec/features/profiles/password_spec.rb b/spec/features/profiles/password_spec.rb
index 898e2c2aa59..8e3f7a09eb0 100644
--- a/spec/features/profiles/password_spec.rb
+++ b/spec/features/profiles/password_spec.rb
@@ -39,7 +39,7 @@ RSpec.describe 'Profile > Password' do
describe 'User puts the same passwords in the field and in the confirmation' do
it 'shows a success message' do
- fill_passwords(Gitlab::Password.test_default, Gitlab::Password.test_default)
+ fill_passwords('mypassword', 'mypassword')
page.within('[data-testid="alert-info"]') do
expect(page).to have_content('Password was successfully updated. Please sign in again.')
@@ -79,7 +79,7 @@ RSpec.describe 'Profile > Password' do
end
context 'Change password' do
- let(:new_password) { "new" + Gitlab::Password.test_default }
+ let(:new_password) { '22233344' }
before do
sign_in(user)
@@ -170,8 +170,8 @@ RSpec.describe 'Profile > Password' do
expect(current_path).to eq new_profile_password_path
fill_in :user_password, with: user.password
- fill_in :user_new_password, with: Gitlab::Password.test_default
- fill_in :user_password_confirmation, with: Gitlab::Password.test_default
+ fill_in :user_new_password, with: '12345678'
+ fill_in :user_password_confirmation, with: '12345678'
click_button 'Set new password'
expect(current_path).to eq new_user_session_path
diff --git a/spec/features/projects/blobs/blob_show_spec.rb b/spec/features/projects/blobs/blob_show_spec.rb
index 77194fd6ca1..d4cb9188fc1 100644
--- a/spec/features/projects/blobs/blob_show_spec.rb
+++ b/spec/features/projects/blobs/blob_show_spec.rb
@@ -948,6 +948,53 @@ RSpec.describe 'File blob', :js do
end
end
end
+
+ context 'openapi.yml' do
+ before do
+ file_name = 'openapi.yml'
+
+ create_file(file_name, '
+ swagger: \'2.0\'
+ info:
+ title: Classic API Resource Documentation
+ description: |
+ <div class="foo-bar" style="background-color: red;" data-foo-bar="baz">
+ <h1>Swagger API documentation</h1>
+ </div>
+ version: production
+ basePath: /JSSResource/
+ produces:
+ - application/xml
+ - application/json
+ consumes:
+ - application/xml
+ - application/json
+ security:
+ - basicAuth: []
+ paths:
+ /accounts:
+ get:
+ responses:
+ \'200\':
+ description: No response was specified
+ tags:
+ - accounts
+ operationId: findAccounts
+ summary: Finds all accounts
+ ')
+ visit_blob(file_name, useUnsafeMarkdown: '1')
+ click_button('Display rendered file')
+
+ wait_for_requests
+ end
+
+ it 'removes `style`, `class`, and `data-*`` attributes from HTML' do
+ expect(page).to have_css('h1', text: 'Swagger API documentation')
+ expect(page).not_to have_css('.foo-bar')
+ expect(page).not_to have_css('[style="background-color: red;"]')
+ expect(page).not_to have_css('[data-foo-bar="baz"]')
+ end
+ end
end
context 'realtime pipelines' do
diff --git a/spec/features/users/anonymous_sessions_spec.rb b/spec/features/users/anonymous_sessions_spec.rb
index f9b23626397..6b21412ae3d 100644
--- a/spec/features/users/anonymous_sessions_spec.rb
+++ b/spec/features/users/anonymous_sessions_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe 'Session TTLs', :clean_gitlab_redis_shared_state do
visit new_user_session_path
# The session key only gets created after a post
fill_in 'user_login', with: 'non-existant@gitlab.org'
- fill_in 'user_password', with: Gitlab::Password.test_default
+ fill_in 'user_password', with: '12345678'
click_button 'Sign in'
expect(page).to have_content('Invalid login or password')
diff --git a/spec/features/users/login_spec.rb b/spec/features/users/login_spec.rb
index 2780549eea1..195026ca102 100644
--- a/spec/features/users/login_spec.rb
+++ b/spec/features/users/login_spec.rb
@@ -49,15 +49,15 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
expect(current_path).to eq edit_user_password_path
expect(page).to have_content('Please create a password for your new account.')
- fill_in 'user_password', with: Gitlab::Password.test_default
- fill_in 'user_password_confirmation', with: Gitlab::Password.test_default
+ fill_in 'user_password', with: 'password'
+ fill_in 'user_password_confirmation', with: 'password'
click_button 'Change your password'
expect(current_path).to eq new_user_session_path
expect(page).to have_content(I18n.t('devise.passwords.updated_not_active'))
fill_in 'user_login', with: user.username
- fill_in 'user_password', with: Gitlab::Password.test_default
+ fill_in 'user_password', with: 'password'
click_button 'Sign in'
expect_single_session_with_authenticated_ttl
@@ -150,6 +150,27 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
end
end
+ describe 'with a disallowed password' do
+ let(:user) { create(:user, :disallowed_password) }
+
+ before do
+ expect(authentication_metrics)
+ .to increment(:user_unauthenticated_counter)
+ .and increment(:user_password_invalid_counter)
+ end
+
+ it 'disallows login' do
+ gitlab_sign_in(user, password: user.password)
+
+ expect(page).to have_content('Invalid login or password.')
+ end
+
+ it 'does not update Devise trackable attributes' do
+ expect { gitlab_sign_in(user, password: user.password) }
+ .not_to change { User.ghost.reload.sign_in_count }
+ end
+ end
+
describe 'with the ghost user' do
it 'disallows login' do
expect(authentication_metrics)
@@ -210,7 +231,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
end
it 'does not allow sign-in if the user password is updated before entering a one-time code' do
- user.update!(password: "new" + Gitlab::Password.test_default)
+ user.update!(password: 'new_password')
enter_code(user.current_otp)
@@ -447,7 +468,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
visit new_user_session_path
fill_in 'user_login', with: user.email
- fill_in 'user_password', with: Gitlab::Password.test_default
+ fill_in 'user_password', with: '12345678'
click_button 'Sign in'
expect(current_path).to eq(new_profile_password_path)
@@ -456,7 +477,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
end
context 'with invalid username and password' do
- let(:user) { create(:user, password: "not" + Gitlab::Password.test_default) }
+ let(:user) { create(:user, password: 'not-the-default') }
it 'blocks invalid login' do
expect(authentication_metrics)
@@ -767,7 +788,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
visit new_user_session_path
fill_in 'user_login', with: user.email
- fill_in 'user_password', with: Gitlab::Password.test_default
+ fill_in 'user_password', with: '12345678'
click_button 'Sign in'
@@ -788,7 +809,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
visit new_user_session_path
fill_in 'user_login', with: user.email
- fill_in 'user_password', with: Gitlab::Password.test_default
+ fill_in 'user_password', with: '12345678'
click_button 'Sign in'
@@ -809,7 +830,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
visit new_user_session_path
fill_in 'user_login', with: user.email
- fill_in 'user_password', with: Gitlab::Password.test_default
+ fill_in 'user_password', with: '12345678'
click_button 'Sign in'
@@ -844,7 +865,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
visit new_user_session_path
fill_in 'user_login', with: user.email
- fill_in 'user_password', with: Gitlab::Password.test_default
+ fill_in 'user_password', with: '12345678'
click_button 'Sign in'
fill_in 'user_otp_attempt', with: user.reload.current_otp
@@ -870,7 +891,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
visit new_user_session_path
fill_in 'user_login', with: user.email
- fill_in 'user_password', with: Gitlab::Password.test_default
+ fill_in 'user_password', with: '12345678'
click_button 'Sign in'
expect_to_be_on_terms_page
@@ -878,7 +899,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
expect(current_path).to eq(new_profile_password_path)
- fill_in 'user_password', with: Gitlab::Password.test_default
+ fill_in 'user_password', with: '12345678'
fill_in 'user_new_password', with: 'new password'
fill_in 'user_password_confirmation', with: 'new password'
click_button 'Set new password'
diff --git a/spec/frontend/behaviors/components/diagram_performance_warning_spec.js b/spec/frontend/behaviors/components/diagram_performance_warning_spec.js
new file mode 100644
index 00000000000..c58c2bc55a9
--- /dev/null
+++ b/spec/frontend/behaviors/components/diagram_performance_warning_spec.js
@@ -0,0 +1,40 @@
+import { GlAlert } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import DiagramPerformanceWarning from '~/behaviors/components/diagram_performance_warning.vue';
+
+describe('DiagramPerformanceWarning component', () => {
+ let wrapper;
+
+ const findAlert = () => wrapper.findComponent(GlAlert);
+
+ beforeEach(() => {
+ wrapper = shallowMount(DiagramPerformanceWarning);
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('renders warning alert with button', () => {
+ expect(findAlert().props()).toMatchObject({
+ primaryButtonText: DiagramPerformanceWarning.i18n.buttonText,
+ variant: 'warning',
+ });
+ });
+
+ it('renders warning message', () => {
+ expect(findAlert().text()).toBe(DiagramPerformanceWarning.i18n.bodyText);
+ });
+
+ it('emits event when closing alert', () => {
+ findAlert().vm.$emit('dismiss');
+
+ expect(wrapper.emitted('closeAlert')).toEqual([[]]);
+ });
+
+ it('emits event when accepting alert', () => {
+ findAlert().vm.$emit('primaryAction');
+
+ expect(wrapper.emitted('showImage')).toEqual([[]]);
+ });
+});
diff --git a/spec/graphql/resolvers/project_pipeline_statistics_resolver_spec.rb b/spec/graphql/resolvers/project_pipeline_statistics_resolver_spec.rb
index ccc861baae5..66a5f0277fb 100644
--- a/spec/graphql/resolvers/project_pipeline_statistics_resolver_spec.rb
+++ b/spec/graphql/resolvers/project_pipeline_statistics_resolver_spec.rb
@@ -11,7 +11,7 @@ RSpec.describe Resolvers::ProjectPipelineStatisticsResolver do
let(:current_user) { reporter }
- before_all do
+ before do
project.add_guest(guest)
project.add_reporter(reporter)
end
@@ -20,13 +20,8 @@ RSpec.describe Resolvers::ProjectPipelineStatisticsResolver do
expect(described_class).to have_nullable_graphql_type(::Types::Ci::AnalyticsType)
end
- def resolve_statistics(project, args)
- ctx = { current_user: current_user }
- resolve(described_class, obj: project, args: args, ctx: ctx)
- end
-
- describe '#resolve' do
- it 'returns the pipelines statistics for a given project' do
+ shared_examples 'returns the pipelines statistics for a given project' do
+ it do
result = resolve_statistics(project, {})
expect(result.keys).to contain_exactly(
:week_pipelines_labels,
@@ -42,14 +37,67 @@ RSpec.describe Resolvers::ProjectPipelineStatisticsResolver do
:pipeline_times_values
)
end
+ end
+
+ shared_examples 'it returns nils' do
+ it do
+ result = resolve_statistics(project, {})
+
+ expect(result).to be_nil
+ end
+ end
+
+ def resolve_statistics(project, args)
+ ctx = { current_user: current_user }
+ resolve(described_class, obj: project, args: args, ctx: ctx)
+ end
+
+ describe '#resolve' do
+ it_behaves_like 'returns the pipelines statistics for a given project'
context 'when the user does not have access to the CI/CD analytics data' do
let(:current_user) { guest }
- it 'returns nil' do
- result = resolve_statistics(project, {})
+ it_behaves_like 'it returns nils'
+ end
+
+ context 'when the project is public' do
+ let_it_be(:project) { create(:project, :public) }
+
+ context 'public pipelines are disabled' do
+ before do
+ project.update!(public_builds: false)
+ end
+
+ context 'user is not a member' do
+ let(:current_user) { create(:user) }
+
+ it_behaves_like 'it returns nils'
+ end
+
+ context 'user is a guest' do
+ let(:current_user) { guest }
+
+ it_behaves_like 'it returns nils'
+ end
+
+ context 'user is a reporter or above' do
+ let(:current_user) { reporter }
+
+ it_behaves_like 'returns the pipelines statistics for a given project'
+ end
+ end
+
+ context 'public pipelines are enabled' do
+ before do
+ project.update!(public_builds: true)
+ end
+
+ context 'user is not a member' do
+ let(:current_user) { create(:user) }
- expect(result).to be_nil
+ it_behaves_like 'returns the pipelines statistics for a given project'
+ end
end
end
end
diff --git a/spec/initializers/rdoc_segfault_patch_spec.rb b/spec/initializers/rdoc_segfault_patch_spec.rb
new file mode 100644
index 00000000000..f9630295052
--- /dev/null
+++ b/spec/initializers/rdoc_segfault_patch_spec.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+RSpec.describe 'RDoc segfault patch fix' do
+ describe 'RDoc::Markup::ToHtml' do
+ describe '#parseable?' do
+ it 'returns false' do
+ to_html = RDoc::Markup::ToHtml.new( nil)
+
+ expect(to_html.parseable?('"def foo; end"')).to eq(false)
+ end
+ end
+ end
+
+ describe 'RDoc::Markup::Verbatim' do
+ describe 'ruby?' do
+ it 'returns false' do
+ verbatim = RDoc::Markup::Verbatim.new('def foo; end')
+ verbatim.format = :ruby
+
+ expect(verbatim.ruby?).to eq(false)
+ end
+ end
+ end
+end
diff --git a/spec/lib/banzai/filter/kroki_filter_spec.rb b/spec/lib/banzai/filter/kroki_filter_spec.rb
index 57caba1d4d7..c9594ac702d 100644
--- a/spec/lib/banzai/filter/kroki_filter_spec.rb
+++ b/spec/lib/banzai/filter/kroki_filter_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe Banzai::Filter::KrokiFilter do
stub_application_setting(kroki_enabled: true, kroki_url: "http://localhost:8000")
doc = filter("<pre lang='nomnoml'><code>[Pirate|eyeCount: Int|raid();pillage()|\n [beard]--[parrot]\n [beard]-:>[foul mouth]\n]</code></pre>")
- expect(doc.to_s).to eq '<img src="http://localhost:8000/nomnoml/svg/eNqLDsgsSixJrUmtTHXOL80rsVLwzCupKUrMTNHQtC7IzMlJTE_V0KzhUlCITkpNLEqJ1dWNLkgsKsoviUUSs7KLTssvzVHIzS8tyYjligUAMhEd0g==">'
+ expect(doc.to_s).to eq '<img class="js-render-kroki" src="http://localhost:8000/nomnoml/svg/eNqLDsgsSixJrUmtTHXOL80rsVLwzCupKUrMTNHQtC7IzMlJTE_V0KzhUlCITkpNLEqJ1dWNLkgsKsoviUUSs7KLTssvzVHIzS8tyYjligUAMhEd0g==">'
end
it 'replaces nomnoml pre tag with img tag if both kroki and plantuml are enabled' do
@@ -19,7 +19,7 @@ RSpec.describe Banzai::Filter::KrokiFilter do
plantuml_url: "http://localhost:8080")
doc = filter("<pre lang='nomnoml'><code>[Pirate|eyeCount: Int|raid();pillage()|\n [beard]--[parrot]\n [beard]-:>[foul mouth]\n]</code></pre>")
- expect(doc.to_s).to eq '<img src="http://localhost:8000/nomnoml/svg/eNqLDsgsSixJrUmtTHXOL80rsVLwzCupKUrMTNHQtC7IzMlJTE_V0KzhUlCITkpNLEqJ1dWNLkgsKsoviUUSs7KLTssvzVHIzS8tyYjligUAMhEd0g==">'
+ expect(doc.to_s).to eq '<img class="js-render-kroki" src="http://localhost:8000/nomnoml/svg/eNqLDsgsSixJrUmtTHXOL80rsVLwzCupKUrMTNHQtC7IzMlJTE_V0KzhUlCITkpNLEqJ1dWNLkgsKsoviUUSs7KLTssvzVHIzS8tyYjligUAMhEd0g==">'
end
it 'does not replace nomnoml pre tag with img tag if kroki is disabled' do
@@ -38,4 +38,12 @@ RSpec.describe Banzai::Filter::KrokiFilter do
expect(doc.to_s).to eq '<pre lang="plantuml"><code>Bob-&gt;Alice : hello</code></pre>'
end
+
+ it 'adds hidden attribute when content size is large' do
+ stub_application_setting(kroki_enabled: true, kroki_url: "http://localhost:8000")
+ text = '[Pirate|eyeCount: Int|raid();pillage()|\n [beard]--[parrot]\n [beard]-:>[foul mouth]\n]' * 25
+ doc = filter("<pre lang='nomnoml'><code>#{text}</code></pre>")
+
+ expect(doc.to_s).to eq '<img class="js-render-kroki" src="http://localhost:8000/nomnoml/svg/eNqLDsgsSixJrUmtTHXOL80rsVLwzCupKUrMTNHQtC7IzMlJTE_V0KyJyVNQiE5KTSxKidXVjS5ILCrKL4lFFrSyi07LL81RyM0vLckAysRGjxo8avCowaMGjxo8avCowaMGU8lgAE7mIdc=" hidden>'
+ end
end
diff --git a/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb b/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb
index aee4bd93207..16c958ec10b 100644
--- a/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb
+++ b/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb
@@ -132,6 +132,12 @@ RSpec.describe Banzai::Filter::SyntaxHighlightFilter do
expect(result.to_html.delete("\n")).to eq('<div class="gl-relative markdown-code-block js-markdown-code"><pre data-sourcepos="1:1-3:3" class="code highlight js-syntax-highlight language-plaintext" lang="plaintext" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">This is a test</span></code></pre><copy-code></copy-code></div>')
end
+
+ it "escape sourcepos metadata to prevent XSS" do
+ result = filter('<pre data-sourcepos="&#34;%22 href=&#34;x&#34;></pre><base href=http://unsafe-website.com/><pre x=&#34;"><code></code></pre>')
+
+ expect(result.to_html.delete("\n")).to eq('<div class="gl-relative markdown-code-block js-markdown-code"><pre data-sourcepos=\'"%22 href="x"&gt;&lt;/pre&gt;&lt;base href=http://unsafe-website.com/&gt;&lt;pre x="\' class="code highlight js-syntax-highlight language-plaintext" lang="plaintext" v-pre="true"><code></code></pre><copy-code></copy-code></div>')
+ end
end
context "when Rouge lexing fails" do
diff --git a/spec/lib/banzai/reference_redactor_spec.rb b/spec/lib/banzai/reference_redactor_spec.rb
index 78cceedd0e5..59410fbce71 100644
--- a/spec/lib/banzai/reference_redactor_spec.rb
+++ b/spec/lib/banzai/reference_redactor_spec.rb
@@ -35,7 +35,7 @@ RSpec.describe Banzai::ReferenceRedactor do
end
context 'when data-original attribute provided' do
- let(:original_content) { '<code>foo</code>' }
+ let(:original_content) { '&lt;script&gt;alert(1);&lt;/script&gt;' }
it 'replaces redacted reference with original content' do
doc = Nokogiri::HTML.fragment("<a class='gfm' href='https://www.gitlab.com' data-reference-type='issue' data-original='#{original_content}'>bar</a>")
diff --git a/spec/lib/gitlab/auth_spec.rb b/spec/lib/gitlab/auth_spec.rb
index 706344831b8..f5a74956174 100644
--- a/spec/lib/gitlab/auth_spec.rb
+++ b/spec/lib/gitlab/auth_spec.rb
@@ -87,7 +87,7 @@ RSpec.describe Gitlab::Auth, :use_clean_rails_memory_store_caching do
end
context 'when IP is already banned' do
- subject { gl_auth.find_for_git_client('username', Gitlab::Password.test_default, project: nil, ip: 'ip') }
+ subject { gl_auth.find_for_git_client('username', 'password', project: nil, ip: 'ip') }
before do
expect_next_instance_of(Gitlab::Auth::IpRateLimiter) do |rate_limiter|
@@ -219,16 +219,16 @@ RSpec.describe Gitlab::Auth, :use_clean_rails_memory_store_caching do
end
it 'recognizes master passwords' do
- user = create(:user, password: Gitlab::Password.test_default)
+ user = create(:user, password: 'password')
- expect(gl_auth.find_for_git_client(user.username, Gitlab::Password.test_default, project: nil, ip: 'ip')).to have_attributes(actor: user, project: nil, type: :gitlab_or_ldap, authentication_abilities: described_class.full_authentication_abilities)
+ expect(gl_auth.find_for_git_client(user.username, 'password', project: nil, ip: 'ip')).to have_attributes(actor: user, project: nil, type: :gitlab_or_ldap, authentication_abilities: described_class.full_authentication_abilities)
end
include_examples 'user login operation with unique ip limit' do
- let(:user) { create(:user, password: Gitlab::Password.test_default) }
+ let(:user) { create(:user, password: 'password') }
def operation
- expect(gl_auth.find_for_git_client(user.username, Gitlab::Password.test_default, project: nil, ip: 'ip')).to have_attributes(actor: user, project: nil, type: :gitlab_or_ldap, authentication_abilities: described_class.full_authentication_abilities)
+ expect(gl_auth.find_for_git_client(user.username, 'password', project: nil, ip: 'ip')).to have_attributes(actor: user, project: nil, type: :gitlab_or_ldap, authentication_abilities: described_class.full_authentication_abilities)
end
end
@@ -492,7 +492,7 @@ RSpec.describe Gitlab::Auth, :use_clean_rails_memory_store_caching do
:user,
:blocked,
username: 'normal_user',
- password: Gitlab::Password.test_default
+ password: 'my-secret'
)
expect(gl_auth.find_for_git_client(user.username, user.password, project: nil, ip: 'ip'))
@@ -501,7 +501,7 @@ RSpec.describe Gitlab::Auth, :use_clean_rails_memory_store_caching do
context 'when 2fa is enabled globally' do
let_it_be(:user) do
- create(:user, username: 'normal_user', password: Gitlab::Password.test_default, otp_grace_period_started_at: 1.day.ago)
+ create(:user, username: 'normal_user', password: 'my-secret', otp_grace_period_started_at: 1.day.ago)
end
before do
@@ -525,7 +525,7 @@ RSpec.describe Gitlab::Auth, :use_clean_rails_memory_store_caching do
context 'when 2fa is enabled personally' do
let(:user) do
- create(:user, :two_factor, username: 'normal_user', password: Gitlab::Password.test_default, otp_grace_period_started_at: 1.day.ago)
+ create(:user, :two_factor, username: 'normal_user', password: 'my-secret', otp_grace_period_started_at: 1.day.ago)
end
it 'fails' do
@@ -538,7 +538,7 @@ RSpec.describe Gitlab::Auth, :use_clean_rails_memory_store_caching do
user = create(
:user,
username: 'normal_user',
- password: Gitlab::Password.test_default
+ password: 'my-secret'
)
expect(gl_auth.find_for_git_client(user.username, user.password, project: nil, ip: 'ip'))
@@ -549,7 +549,7 @@ RSpec.describe Gitlab::Auth, :use_clean_rails_memory_store_caching do
user = create(
:user,
username: 'oauth2',
- password: Gitlab::Password.test_default
+ password: 'my-secret'
)
expect(gl_auth.find_for_git_client(user.username, user.password, project: nil, ip: 'ip'))
@@ -624,7 +624,7 @@ RSpec.describe Gitlab::Auth, :use_clean_rails_memory_store_caching do
context 'when deploy token and user have the same username' do
let(:username) { 'normal_user' }
- let(:user) { create(:user, username: username, password: Gitlab::Password.test_default) }
+ let(:user) { create(:user, username: username, password: 'my-secret') }
let(:deploy_token) { create(:deploy_token, username: username, read_registry: false, projects: [project]) }
it 'succeeds for the token' do
@@ -637,7 +637,7 @@ RSpec.describe Gitlab::Auth, :use_clean_rails_memory_store_caching do
it 'succeeds for the user' do
auth_success = { actor: user, project: nil, type: :gitlab_or_ldap, authentication_abilities: described_class.full_authentication_abilities }
- expect(gl_auth.find_for_git_client(username, Gitlab::Password.test_default, project: project, ip: 'ip'))
+ expect(gl_auth.find_for_git_client(username, 'my-secret', project: project, ip: 'ip'))
.to have_attributes(auth_success)
end
end
@@ -831,7 +831,7 @@ RSpec.describe Gitlab::Auth, :use_clean_rails_memory_store_caching do
end
let(:username) { 'John' } # username isn't lowercase, test this
- let(:password) { Gitlab::Password.test_default }
+ let(:password) { 'my-secret' }
it "finds user by valid login/password" do
expect(gl_auth.find_with_user_password(username, password)).to eql user
@@ -956,13 +956,13 @@ RSpec.describe Gitlab::Auth, :use_clean_rails_memory_store_caching do
it "does not find user by using ldap as fallback to for authentication" do
expect(Gitlab::Auth::Ldap::Authentication).to receive(:login).and_return(nil)
- expect(gl_auth.find_with_user_password('ldap_user', Gitlab::Password.test_default)).to be_nil
+ expect(gl_auth.find_with_user_password('ldap_user', 'password')).to be_nil
end
it "find new user by using ldap as fallback to for authentication" do
expect(Gitlab::Auth::Ldap::Authentication).to receive(:login).and_return(user)
- expect(gl_auth.find_with_user_password('ldap_user', Gitlab::Password.test_default)).to eq(user)
+ expect(gl_auth.find_with_user_password('ldap_user', 'password')).to eq(user)
end
end
diff --git a/spec/lib/gitlab/ci/config/external/file/artifact_spec.rb b/spec/lib/gitlab/ci/config/external/file/artifact_spec.rb
index 8dd92c5b5fd..b59fc95a8cc 100644
--- a/spec/lib/gitlab/ci/config/external/file/artifact_spec.rb
+++ b/spec/lib/gitlab/ci/config/external/file/artifact_spec.rb
@@ -127,6 +127,12 @@ RSpec.describe Gitlab::Ci::Config::External::File::Artifact do
let!(:metadata) { create(:ci_job_artifact, :metadata, job: generator_job) }
context 'when file is empty' do
+ let(:params) { { artifact: 'secret_stuff/generated.yml', job: 'generator' } }
+ let(:variables) { Gitlab::Ci::Variables::Collection.new([{ 'key' => 'GITLAB_TOKEN', 'value' => 'secret_stuff', 'masked' => true }]) }
+ let(:context) do
+ Gitlab::Ci::Config::External::Context.new(parent_pipeline: parent_pipeline, variables: variables)
+ end
+
before do
allow_next_instance_of(Gitlab::Ci::ArtifactFileReader) do |reader|
allow(reader).to receive(:read).and_return('')
@@ -134,7 +140,7 @@ RSpec.describe Gitlab::Ci::Config::External::File::Artifact do
end
let(:expected_error) do
- 'File `generated.yml` is empty!'
+ 'File `xxxxxxxxxxxx/generated.yml` is empty!'
end
it_behaves_like 'is invalid'
diff --git a/spec/lib/gitlab/ci/config/external/file/base_spec.rb b/spec/lib/gitlab/ci/config/external/file/base_spec.rb
index 445edb253fd..536f48ecba6 100644
--- a/spec/lib/gitlab/ci/config/external/file/base_spec.rb
+++ b/spec/lib/gitlab/ci/config/external/file/base_spec.rb
@@ -3,7 +3,8 @@
require 'spec_helper'
RSpec.describe Gitlab::Ci::Config::External::File::Base do
- let(:context_params) { { sha: 'HEAD' } }
+ let(:variables) { }
+ let(:context_params) { { sha: 'HEAD', variables: variables } }
let(:context) { Gitlab::Ci::Config::External::Context.new(**context_params) }
let(:test_class) do
@@ -76,7 +77,8 @@ RSpec.describe Gitlab::Ci::Config::External::File::Base do
end
context 'when there are YAML syntax errors' do
- let(:location) { 'some/file/config.yml' }
+ let(:location) { 'some/file/secret_file_name.yml' }
+ let(:variables) { Gitlab::Ci::Variables::Collection.new([{ 'key' => 'GITLAB_TOKEN', 'value' => 'secret_file_name', 'masked' => true }]) }
before do
allow_any_instance_of(test_class)
@@ -85,7 +87,7 @@ RSpec.describe Gitlab::Ci::Config::External::File::Base do
it 'is not a valid file' do
expect(subject).not_to be_valid
- expect(subject.error_message).to match /does not have valid YAML syntax/
+ expect(subject.error_message).to eq('Included file `some/file/xxxxxxxxxxxxxxxx.yml` does not have valid YAML syntax!')
end
end
end
diff --git a/spec/lib/gitlab/ci/config/external/file/local_spec.rb b/spec/lib/gitlab/ci/config/external/file/local_spec.rb
index 3d1fc32a62d..61eb52a615b 100644
--- a/spec/lib/gitlab/ci/config/external/file/local_spec.rb
+++ b/spec/lib/gitlab/ci/config/external/file/local_spec.rb
@@ -7,6 +7,7 @@ RSpec.describe Gitlab::Ci::Config::External::File::Local do
let_it_be(:user) { create(:user) }
let(:sha) { '12345' }
+ let(:variables) { project.predefined_variables.to_runner_variables }
let(:context) { Gitlab::Ci::Config::External::Context.new(**context_params) }
let(:params) { { local: location } }
let(:local_file) { described_class.new(params, context) }
@@ -18,7 +19,7 @@ RSpec.describe Gitlab::Ci::Config::External::File::Local do
sha: sha,
user: user,
parent_pipeline: parent_pipeline,
- variables: project.predefined_variables.to_runner_variables
+ variables: variables
}
end
@@ -66,7 +67,7 @@ RSpec.describe Gitlab::Ci::Config::External::File::Local do
end
end
- context 'when is not a valid local path' do
+ context 'when it is not a valid local path' do
let(:location) { '/lib/gitlab/ci/templates/non-existent-file.yml' }
it 'returns false' do
@@ -74,13 +75,23 @@ RSpec.describe Gitlab::Ci::Config::External::File::Local do
end
end
- context 'when is not a yaml file' do
+ context 'when it is not a yaml file' do
let(:location) { '/config/application.rb' }
it 'returns false' do
expect(local_file.valid?).to be_falsy
end
end
+
+ context 'when it is an empty file' do
+ let(:variables) { Gitlab::Ci::Variables::Collection.new([{ 'key' => 'GITLAB_TOKEN', 'value' => 'secret', 'masked' => true }]) }
+ let(:location) { '/lib/gitlab/ci/templates/secret/existent-file.yml' }
+
+ it 'returns false and adds an error message about an empty file' do
+ allow_any_instance_of(described_class).to receive(:fetch_local_content).and_return("")
+ expect(local_file.errors).to include("Local file `/lib/gitlab/ci/templates/xxxxxx/existent-file.yml` is empty!")
+ end
+ end
end
describe '#content' do
@@ -116,10 +127,11 @@ RSpec.describe Gitlab::Ci::Config::External::File::Local do
end
describe '#error_message' do
- let(:location) { '/lib/gitlab/ci/templates/non-existent-file.yml' }
+ let(:location) { '/lib/gitlab/ci/templates/secret_file.yml' }
+ let(:variables) { Gitlab::Ci::Variables::Collection.new([{ 'key' => 'GITLAB_TOKEN', 'value' => 'secret_file', 'masked' => true }]) }
it 'returns an error message' do
- expect(local_file.error_message).to eq("Local file `#{location}` does not exist!")
+ expect(local_file.error_message).to eq("Local file `/lib/gitlab/ci/templates/xxxxxxxxxxx.yml` does not exist!")
end
end
diff --git a/spec/lib/gitlab/ci/config/external/file/project_spec.rb b/spec/lib/gitlab/ci/config/external/file/project_spec.rb
index c53914c5772..74720c0a3ca 100644
--- a/spec/lib/gitlab/ci/config/external/file/project_spec.rb
+++ b/spec/lib/gitlab/ci/config/external/file/project_spec.rb
@@ -11,6 +11,7 @@ RSpec.describe Gitlab::Ci::Config::External::File::Project do
let(:parent_pipeline) { double(:parent_pipeline) }
let(:context) { Gitlab::Ci::Config::External::Context.new(**context_params) }
let(:project_file) { described_class.new(params, context) }
+ let(:variables) { project.predefined_variables.to_runner_variables }
let(:context_params) do
{
@@ -18,7 +19,7 @@ RSpec.describe Gitlab::Ci::Config::External::File::Project do
sha: '12345',
user: context_user,
parent_pipeline: parent_pipeline,
- variables: project.predefined_variables.to_runner_variables
+ variables: variables
}
end
@@ -108,18 +109,19 @@ RSpec.describe Gitlab::Ci::Config::External::File::Project do
context 'when an empty file is used' do
let(:params) do
- { project: project.full_path, file: '/file.yml' }
+ { project: project.full_path, file: '/secret_file.yml' }
end
+ let(:variables) { Gitlab::Ci::Variables::Collection.new([{ 'key' => 'GITLAB_TOKEN', 'value' => 'secret_file', 'masked' => true }]) }
let(:root_ref_sha) { project.repository.root_ref_sha }
before do
- stub_project_blob(root_ref_sha, '/file.yml') { '' }
+ stub_project_blob(root_ref_sha, '/secret_file.yml') { '' }
end
it 'returns false' do
expect(project_file).not_to be_valid
- expect(project_file.error_message).to include("Project `#{project.full_path}` file `/file.yml` is empty!")
+ expect(project_file.error_message).to include("Project `#{project.full_path}` file `/xxxxxxxxxxx.yml` is empty!")
end
end
@@ -135,13 +137,15 @@ RSpec.describe Gitlab::Ci::Config::External::File::Project do
end
context 'when non-existing file is requested' do
+ let(:variables) { Gitlab::Ci::Variables::Collection.new([{ 'key' => 'GITLAB_TOKEN', 'value' => 'secret-invalid-file', 'masked' => true }]) }
+
let(:params) do
- { project: project.full_path, file: '/invalid-file.yml' }
+ { project: project.full_path, file: '/secret-invalid-file.yml' }
end
it 'returns false' do
expect(project_file).not_to be_valid
- expect(project_file.error_message).to include("Project `#{project.full_path}` file `/invalid-file.yml` does not exist!")
+ expect(project_file.error_message).to include("Project `#{project.full_path}` file `/xxxxxxxxxxxxxxxxxxx.yml` does not exist!")
end
end
diff --git a/spec/lib/gitlab/ci/config/external/file/remote_spec.rb b/spec/lib/gitlab/ci/config/external/file/remote_spec.rb
index ab60ac215ba..2613bfbfdcf 100644
--- a/spec/lib/gitlab/ci/config/external/file/remote_spec.rb
+++ b/spec/lib/gitlab/ci/config/external/file/remote_spec.rb
@@ -5,11 +5,12 @@ require 'spec_helper'
RSpec.describe Gitlab::Ci::Config::External::File::Remote do
include StubRequests
- let(:context_params) { { sha: '12345' } }
+ let(:variables) {Gitlab::Ci::Variables::Collection.new([{ 'key' => 'GITLAB_TOKEN', 'value' => 'secret_file', 'masked' => true }]) }
+ let(:context_params) { { sha: '12345', variables: variables } }
let(:context) { Gitlab::Ci::Config::External::Context.new(**context_params) }
let(:params) { { remote: location } }
let(:remote_file) { described_class.new(params, context) }
- let(:location) { 'https://gitlab.com/gitlab-org/gitlab-foss/blob/1234/.gitlab-ci-1.yml' }
+ let(:location) { 'https://gitlab.com/gitlab-org/gitlab-foss/blob/1234/.secret_file.yml' }
let(:remote_file_content) do
<<~HEREDOC
before_script:
@@ -144,10 +145,10 @@ RSpec.describe Gitlab::Ci::Config::External::File::Remote do
subject { remote_file.error_message }
context 'when remote file location is not valid' do
- let(:location) { 'not-valid://gitlab.com/gitlab-org/gitlab-foss/blob/1234/.gitlab-ci-1.yml' }
+ let(:location) { 'not-valid://gitlab.com/gitlab-org/gitlab-foss/blob/1234/?secret_file.yml' }
it 'returns an error message describing invalid address' do
- expect(subject).to match /does not have a valid address!/
+ expect(subject).to eq('Remote file `not-valid://gitlab.com/gitlab-org/gitlab-foss/blob/1234/?xxxxxxxxxxx.yml` does not have a valid address!')
end
end
@@ -157,7 +158,7 @@ RSpec.describe Gitlab::Ci::Config::External::File::Remote do
end
it 'returns error message about a timeout' do
- expect(subject).to match /could not be fetched because of a timeout error!/
+ expect(subject).to eq('Remote file `https://gitlab.com/gitlab-org/gitlab-foss/blob/1234/.xxxxxxxxxxx.yml` could not be fetched because of a timeout error!')
end
end
@@ -167,7 +168,7 @@ RSpec.describe Gitlab::Ci::Config::External::File::Remote do
end
it 'returns error message about a HTTP error' do
- expect(subject).to match /could not be fetched because of HTTP error!/
+ expect(subject).to eq('Remote file `https://gitlab.com/gitlab-org/gitlab-foss/blob/1234/.xxxxxxxxxxx.yml` could not be fetched because of HTTP error!')
end
end
@@ -177,7 +178,7 @@ RSpec.describe Gitlab::Ci::Config::External::File::Remote do
end
it 'returns error message about a timeout' do
- expect(subject).to match /could not be fetched because of HTTP code `404` error!/
+ expect(subject).to eq('Remote file `https://gitlab.com/gitlab-org/gitlab-foss/blob/1234/.xxxxxxxxxxx.yml` could not be fetched because of HTTP code `404` error!')
end
end
diff --git a/spec/lib/gitlab/ci/config/external/file/template_spec.rb b/spec/lib/gitlab/ci/config/external/file/template_spec.rb
index 75b22c1516c..66a06de3d28 100644
--- a/spec/lib/gitlab/ci/config/external/file/template_spec.rb
+++ b/spec/lib/gitlab/ci/config/external/file/template_spec.rb
@@ -54,11 +54,13 @@ RSpec.describe Gitlab::Ci::Config::External::File::Template do
end
context 'with invalid template name' do
- let(:template) { 'Template.yml' }
+ let(:template) { 'SecretTemplate.yml' }
+ let(:variables) { Gitlab::Ci::Variables::Collection.new([{ 'key' => 'GITLAB_TOKEN', 'value' => 'SecretTemplate', 'masked' => true }]) }
+ let(:context_params) { { project: project, sha: '12345', user: user, variables: variables } }
it 'returns false' do
expect(template_file).not_to be_valid
- expect(template_file.error_message).to include('Template file `Template.yml` is not a valid location!')
+ expect(template_file.error_message).to include('`xxxxxxxxxxxxxx.yml` is not a valid location!')
end
end
diff --git a/spec/lib/gitlab/ci/config/external/mapper_spec.rb b/spec/lib/gitlab/ci/config/external/mapper_spec.rb
index f8754d7e124..f69feba5e59 100644
--- a/spec/lib/gitlab/ci/config/external/mapper_spec.rb
+++ b/spec/lib/gitlab/ci/config/external/mapper_spec.rb
@@ -11,7 +11,8 @@ RSpec.describe Gitlab::Ci::Config::External::Mapper do
let(:local_file) { '/lib/gitlab/ci/templates/non-existent-file.yml' }
let(:remote_url) { 'https://gitlab.com/gitlab-org/gitlab-foss/blob/1234/.gitlab-ci-1.yml' }
let(:template_file) { 'Auto-DevOps.gitlab-ci.yml' }
- let(:context_params) { { project: project, sha: '123456', user: user, variables: project.predefined_variables } }
+ let(:variables) { project.predefined_variables }
+ let(:context_params) { { project: project, sha: '123456', user: user, variables: variables } }
let(:context) { Gitlab::Ci::Config::External::Context.new(**context_params) }
let(:file_content) do
@@ -92,13 +93,16 @@ RSpec.describe Gitlab::Ci::Config::External::Mapper do
end
context 'when the key is a hash of file and remote' do
+ let(:variables) { Gitlab::Ci::Variables::Collection.new([{ 'key' => 'GITLAB_TOKEN', 'value' => 'secret-file', 'masked' => true }]) }
+ let(:local_file) { 'secret-file.yml' }
+ let(:remote_url) { 'https://gitlab.com/secret-file.yml' }
let(:values) do
{ include: { 'local' => local_file, 'remote' => remote_url },
image: 'ruby:2.7' }
end
it 'returns ambigious specification error' do
- expect { subject }.to raise_error(described_class::AmbigiousSpecificationError)
+ expect { subject }.to raise_error(described_class::AmbigiousSpecificationError, 'Include `{"local":"xxxxxxxxxxx.yml","remote":"https://gitlab.com/xxxxxxxxxxx.yml"}` needs to match exactly one accessor!')
end
end
diff --git a/spec/lib/gitlab/error_tracking/processor/sanitize_error_message_processor_spec.rb b/spec/lib/gitlab/error_tracking/processor/sanitize_error_message_processor_spec.rb
new file mode 100644
index 00000000000..b4173617a14
--- /dev/null
+++ b/spec/lib/gitlab/error_tracking/processor/sanitize_error_message_processor_spec.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::ErrorTracking::Processor::SanitizeErrorMessageProcessor, :sentry do
+ describe '.call' do
+ let(:exception) { StandardError.new('raw error') }
+ let(:event) { Raven::Event.from_exception(exception, raven_required_options) }
+ let(:result_hash) { described_class.call(event).to_hash }
+ let(:raven_required_options) do
+ {
+ configuration: Raven.configuration,
+ context: Raven.context,
+ breadcrumbs: Raven.breadcrumbs
+ }
+ end
+
+ it 'cleans the exception message' do
+ expect(Gitlab::Sanitizers::ExceptionMessage).to receive(:clean).with('StandardError', 'raw error').and_return('cleaned')
+
+ expect(result_hash[:exception][:values].first).to include(
+ type: 'StandardError',
+ value: 'cleaned'
+ )
+ end
+
+ context 'when event is invalid' do
+ let(:event) { instance_double('Raven::Event', to_hash: { invalid: true }) }
+
+ it 'does nothing' do
+ extracted_exception = instance_double('Raven::SingleExceptionInterface', value: nil)
+ allow(described_class).to receive(:extract_exceptions_from).and_return([extracted_exception])
+
+ expect(Gitlab::Sanitizers::ExceptionMessage).not_to receive(:clean)
+ expect(result_hash).to eq(invalid: true)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/error_tracking_spec.rb b/spec/lib/gitlab/error_tracking_spec.rb
index a5d44963f4b..284b773ef24 100644
--- a/spec/lib/gitlab/error_tracking_spec.rb
+++ b/spec/lib/gitlab/error_tracking_spec.rb
@@ -301,5 +301,48 @@ RSpec.describe Gitlab::ErrorTracking do
end
end
end
+
+ context 'when processing invalid URI exceptions' do
+ let(:invalid_uri) { 'http://foo:bar' }
+ let(:sentry_exception_values) { sentry_event['exception']['values'] }
+
+ context 'when the error is a URI::InvalidURIError' do
+ let(:exception) do
+ URI.parse(invalid_uri)
+ rescue URI::InvalidURIError => error
+ error
+ end
+
+ it 'filters the URI from the error message' do
+ track_exception
+
+ expect(sentry_exception_values).to include(
+ hash_including(
+ 'type' => 'URI::InvalidURIError',
+ 'value' => 'bad URI(is not URI?): [FILTERED]'
+ )
+ )
+ end
+ end
+
+ context 'when the error is a Addressable::URI::InvalidURIError' do
+ let(:exception) do
+ Addressable::URI.parse(invalid_uri)
+ rescue Addressable::URI::InvalidURIError => error
+ error
+ end
+
+ it 'filters the URI from the error message' do
+ track_exception
+
+ expect(sentry_exception_values).to include(
+ hash_including(
+ 'type' => 'Addressable::URI::InvalidURIError',
+ 'value' => 'Invalid port number: [FILTERED]'
+ )
+ )
+ end
+ end
+ end
end
end
diff --git a/spec/lib/gitlab/exception_log_formatter_spec.rb b/spec/lib/gitlab/exception_log_formatter_spec.rb
index beeeeb2b64c..7dda56f0bf5 100644
--- a/spec/lib/gitlab/exception_log_formatter_spec.rb
+++ b/spec/lib/gitlab/exception_log_formatter_spec.rb
@@ -22,6 +22,14 @@ RSpec.describe Gitlab::ExceptionLogFormatter do
expect(payload['exception.sql']).to be_nil
end
+ it 'cleans the exception message' do
+ expect(Gitlab::Sanitizers::ExceptionMessage).to receive(:clean).with('RuntimeError', 'bad request').and_return('cleaned')
+
+ described_class.format!(exception, payload)
+
+ expect(payload['exception.message']).to eq('cleaned')
+ end
+
context 'when exception is ActiveRecord::StatementInvalid' do
let(:exception) { ActiveRecord::StatementInvalid.new(sql: 'SELECT "users".* FROM "users" WHERE "users"."id" = 1 AND "users"."foo" = $1') }
diff --git a/spec/lib/gitlab/import_export/members_mapper_spec.rb b/spec/lib/gitlab/import_export/members_mapper_spec.rb
index 8d9bff9c610..87ca899a87d 100644
--- a/spec/lib/gitlab/import_export/members_mapper_spec.rb
+++ b/spec/lib/gitlab/import_export/members_mapper_spec.rb
@@ -17,7 +17,7 @@ RSpec.describe Gitlab::ImportExport::MembersMapper do
"notification_level" => 3,
"created_at" => "2016-03-11T10:21:44.822Z",
"updated_at" => "2016-03-11T10:21:44.822Z",
- "created_by_id" => nil,
+ "created_by_id" => 1,
"invite_email" => nil,
"invite_token" => nil,
"invite_accepted_at" => nil,
@@ -38,10 +38,24 @@ RSpec.describe Gitlab::ImportExport::MembersMapper do
"notification_level" => 3,
"created_at" => "2016-03-11T10:21:44.822Z",
"updated_at" => "2016-03-11T10:21:44.822Z",
- "created_by_id" => 1,
+ "created_by_id" => 2,
"invite_email" => 'invite@test.com',
"invite_token" => 'token',
"invite_accepted_at" => nil
+ },
+ {
+ "id" => 3,
+ "access_level" => 40,
+ "source_id" => 14,
+ "source_type" => source_type,
+ "user_id" => nil,
+ "notification_level" => 3,
+ "created_at" => "2016-03-11T10:21:44.822Z",
+ "updated_at" => "2016-03-11T10:21:44.822Z",
+ "created_by_id" => nil,
+ "invite_email" => 'invite2@test.com',
+ "invite_token" => 'token',
+ "invite_accepted_at" => nil
}]
end
@@ -68,12 +82,37 @@ RSpec.describe Gitlab::ImportExport::MembersMapper do
expect(member_class.find_by_invite_email('invite@test.com')).not_to be_nil
end
- it 'removes old user_id from member_hash to avoid conflict with user key' do
+ it 'maps created_by_id to user on new instance' do
+ expect(member_class)
+ .to receive(:create)
+ .once
+ .with(hash_including('user_id' => user2.id, 'created_by_id' => nil))
+ .and_call_original
+ expect(member_class)
+ .to receive(:create)
+ .once
+ .with(hash_including('invite_email' => 'invite@test.com', 'created_by_id' => nil))
+ .and_call_original
+ expect(member_class)
+ .to receive(:create)
+ .once
+ .with(hash_including('invite_email' => 'invite2@test.com', 'created_by_id' => nil))
+ .and_call_original
+
+ members_mapper.map
+ end
+
+ it 'replaced user_id with user_id from new instance' do
+ expect(member_class)
+ .to receive(:create)
+ .once
+ .with(hash_including('user_id' => user2.id))
+ .and_call_original
expect(member_class)
.to receive(:create)
- .twice
- .with(hash_excluding('user_id'))
- .and_call_original
+ .twice
+ .with(hash_excluding('user_id'))
+ .and_call_original
members_mapper.map
end
@@ -99,7 +138,7 @@ RSpec.describe Gitlab::ImportExport::MembersMapper do
end
expect(logger).to receive(:info).with(hash_including(expected_log_params.call(user2.id))).once
- expect(logger).to receive(:info).with(hash_including(expected_log_params.call(nil))).once
+ expect(logger).to receive(:info).with(hash_including(expected_log_params.call(nil))).twice
members_mapper.map
end
diff --git a/spec/lib/gitlab/sanitizers/exception_message_spec.rb b/spec/lib/gitlab/sanitizers/exception_message_spec.rb
new file mode 100644
index 00000000000..8b54b353235
--- /dev/null
+++ b/spec/lib/gitlab/sanitizers/exception_message_spec.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+require 'fast_spec_helper'
+require 'rspec-parameterized'
+
+RSpec.describe Gitlab::Sanitizers::ExceptionMessage do
+ describe '.clean' do
+ let(:exception_name) { exception.class.name }
+ let(:exception_message) { exception.message }
+
+ subject { described_class.clean(exception_name, exception_message) }
+
+ context 'when error is a URI::InvalidURIError' do
+ let(:exception) do
+ URI.parse('http://foo:bar')
+ rescue URI::InvalidURIError => error
+ error
+ end
+
+ it { is_expected.to eq('bad URI(is not URI?): [FILTERED]') }
+ end
+
+ context 'when error is an Addressable::URI::InvalidURIError' do
+ using RSpec::Parameterized::TableSyntax
+
+ let(:exception) do
+ Addressable::URI.parse(uri)
+ rescue Addressable::URI::InvalidURIError => error
+ error
+ end
+
+ where(:uri, :result) do
+ 'http://foo:bar' | 'Invalid port number: [FILTERED]'
+ 'http://foo:%eb' | 'Invalid encoding in port'
+ 'ht%0atp://foo' | 'Invalid scheme format: [FILTERED]'
+ 'http:' | 'Absolute URI missing hierarchical segment: [FILTERED]'
+ '::http' | 'Cannot assemble URI string with ambiguous path: [FILTERED]'
+ 'http://foo bar' | 'Invalid character in host: [FILTERED]'
+ end
+
+ with_them do
+ it { is_expected.to eq(result) }
+ end
+ end
+
+ context 'with any other exception' do
+ let(:exception) { StandardError.new('Error message: http://foo@bar:baz@ex:ample.com') }
+
+ it 'is not invoked and does nothing' do
+ is_expected.to eq('Error message: http://foo@bar:baz@ex:ample.com')
+ end
+ end
+ end
+end
diff --git a/spec/mailers/emails/profile_spec.rb b/spec/mailers/emails/profile_spec.rb
index af77989dbbc..365ca892bb1 100644
--- a/spec/mailers/emails/profile_spec.rb
+++ b/spec/mailers/emails/profile_spec.rb
@@ -49,7 +49,7 @@ RSpec.describe Emails::Profile do
describe 'for users that signed up, the email' do
let(:example_site_path) { root_path }
- let(:new_user) { create(:user, email: new_user_address, password: Gitlab::Password.test_default) }
+ let(:new_user) { create(:user, email: new_user_address, password: "securePassword") }
subject { Notify.new_user_email(new_user.id) }
diff --git a/spec/models/ci/runner_spec.rb b/spec/models/ci/runner_spec.rb
index eb29db697a5..1a9832799d3 100644
--- a/spec/models/ci/runner_spec.rb
+++ b/spec/models/ci/runner_spec.rb
@@ -41,15 +41,25 @@ RSpec.describe Ci::Runner do
context 'when runner is not allowed to pick untagged jobs' do
context 'when runner does not have tags' do
+ let(:runner) { build(:ci_runner, tag_list: [], run_untagged: false) }
+
+ it 'is not valid' do
+ expect(runner).to be_invalid
+ end
+ end
+
+ context 'when runner has too many tags' do
+ let(:runner) { build(:ci_runner, tag_list: (1..::Ci::Runner::TAG_LIST_MAX_LENGTH + 1).map { |i| "tag#{i}" }, run_untagged: false) }
+
it 'is not valid' do
- runner = build(:ci_runner, tag_list: [], run_untagged: false)
expect(runner).to be_invalid
end
end
context 'when runner has tags' do
+ let(:runner) { build(:ci_runner, tag_list: ['tag'], run_untagged: false) }
+
it 'is valid' do
- runner = build(:ci_runner, tag_list: ['tag'], run_untagged: false)
expect(runner).to be_valid
end
end
diff --git a/spec/models/hooks/system_hook_spec.rb b/spec/models/hooks/system_hook_spec.rb
index a3d36058b74..bf69c7219a8 100644
--- a/spec/models/hooks/system_hook_spec.rb
+++ b/spec/models/hooks/system_hook_spec.rb
@@ -37,7 +37,7 @@ RSpec.describe SystemHook do
let(:project) { create(:project, namespace: user.namespace) }
let(:group) { create(:group) }
let(:params) do
- { name: 'John Doe', username: 'jduser', email: 'jg@example.com', password: Gitlab::Password.test_default }
+ { name: 'John Doe', username: 'jduser', email: 'jg@example.com', password: 'mydummypass' }
end
before do
diff --git a/spec/models/integrations/asana_spec.rb b/spec/models/integrations/asana_spec.rb
index b6602964182..43e876a4f47 100644
--- a/spec/models/integrations/asana_spec.rb
+++ b/spec/models/integrations/asana_spec.rb
@@ -20,11 +20,13 @@ RSpec.describe Integrations::Asana do
let(:gid) { "123456789ABCD" }
let(:asana_task) { double(::Asana::Resources::Task) }
let(:asana_integration) { described_class.new }
+ let(:ref) { 'main' }
+ let(:restrict_to_branch) { nil }
let(:data) do
{
object_kind: 'push',
- ref: 'master',
+ ref: ref,
user_name: user.name,
commits: [
{
@@ -40,16 +42,44 @@ RSpec.describe Integrations::Asana do
project: project,
project_id: project.id,
api_key: 'verySecret',
- restrict_to_branch: 'master'
+ restrict_to_branch: restrict_to_branch
)
end
subject(:execute_integration) { asana_integration.execute(data) }
+ context 'with restrict_to_branch' do
+ let(:restrict_to_branch) { 'feature-branch, main' }
+ let(:message) { 'fix #456789' }
+
+ context 'when ref is in scope of restriced branches' do
+ let(:ref) { 'main' }
+
+ it 'calls the Asana integration' do
+ expect(asana_task).to receive(:add_comment)
+ expect(asana_task).to receive(:update).with(completed: true)
+ expect(::Asana::Resources::Task).to receive(:find_by_id).with(anything, '456789').once.and_return(asana_task)
+
+ execute_integration
+ end
+ end
+
+ context 'when ref is not in scope of restricted branches' do
+ let(:ref) { 'mai' }
+
+ it 'does not call the Asana integration' do
+ expect(asana_task).not_to receive(:add_comment)
+ expect(::Asana::Resources::Task).not_to receive(:find_by_id)
+
+ execute_integration
+ end
+ end
+ end
+
context 'when creating a story' do
let(:message) { "Message from commit. related to ##{gid}" }
let(:expected_message) do
- "#{user.name} pushed to branch master of #{project.full_name} ( https://gitlab.com/ ): #{message}"
+ "#{user.name} pushed to branch main of #{project.full_name} ( https://gitlab.com/ ): #{message}"
end
it 'calls Asana integration to create a story' do
diff --git a/spec/models/releases/link_spec.rb b/spec/models/releases/link_spec.rb
index 4dc1e53d59e..74ef38f482b 100644
--- a/spec/models/releases/link_spec.rb
+++ b/spec/models/releases/link_spec.rb
@@ -113,6 +113,17 @@ RSpec.describe Releases::Link do
end
end
+ describe 'when filepath is greater than max length' do
+ let!(:invalid_link) { build(:release_link, filepath: 'x' * (Releases::Link::FILEPATH_MAX_LENGTH + 1), release: release) }
+
+ it 'will not execute regex' do
+ invalid_link.filepath_format_valid?
+
+ expect(invalid_link.errors[:filepath].size).to eq(1)
+ expect(invalid_link.errors[:filepath].first).to start_with("is too long")
+ end
+ end
+
describe 'FILEPATH_REGEX with table' do
using RSpec::Parameterized::TableSyntax
diff --git a/spec/models/ssh_host_key_spec.rb b/spec/models/ssh_host_key_spec.rb
index 4d729d5585f..4b756846598 100644
--- a/spec/models/ssh_host_key_spec.rb
+++ b/spec/models/ssh_host_key_spec.rb
@@ -4,7 +4,9 @@ require 'spec_helper'
RSpec.describe SshHostKey do
using RSpec::Parameterized::TableSyntax
+
include ReactiveCachingHelpers
+ include StubRequests
let(:key1) do
'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC3UpyF2iLqy1d63M6k3jH1vuEnq/NWtE+o' \
@@ -35,6 +37,7 @@ RSpec.describe SshHostKey do
let(:extra) { known_hosts + "foo\nbar\n" }
let(:reversed) { known_hosts.lines.reverse.join }
+ let(:url) { 'ssh://example.com:2222' }
let(:compare_host_keys) { nil }
def stub_ssh_keyscan(args, status: true, stdout: "", stderr: "")
@@ -50,7 +53,7 @@ RSpec.describe SshHostKey do
let(:project) { build(:project) }
- subject(:ssh_host_key) { described_class.new(project: project, url: 'ssh://example.com:2222', compare_host_keys: compare_host_keys) }
+ subject(:ssh_host_key) { described_class.new(project: project, url: url, compare_host_keys: compare_host_keys) }
describe '.primary_key' do
it 'returns a symbol' do
@@ -191,5 +194,45 @@ RSpec.describe SshHostKey do
is_expected.to eq(error: 'Failed to detect SSH host keys')
end
end
+
+ context 'DNS rebinding protection enabled' do
+ before do
+ stub_application_setting(dns_rebinding_protection_enabled: true)
+ end
+
+ it 'sends an address as well as hostname to ssh-keyscan' do
+ stub_dns(url, ip_address: '1.2.3.4')
+
+ stdin = stub_ssh_keyscan(%w[-T 5 -p 2222 -f-])
+
+ cache
+
+ expect(stdin.string).to eq("1.2.3.4 example.com\n")
+ end
+ end
+ end
+
+ describe 'URL validation' do
+ let(:url) { 'ssh://127.0.0.1' }
+
+ context 'when local requests are not allowed' do
+ before do
+ stub_application_setting(allow_local_requests_from_web_hooks_and_services: false)
+ end
+
+ it 'forbids scanning localhost' do
+ expect { ssh_host_key }.to raise_error(/Invalid URL/)
+ end
+ end
+
+ context 'when local requests are allowed' do
+ before do
+ stub_application_setting(allow_local_requests_from_web_hooks_and_services: true)
+ end
+
+ it 'permits scanning localhost' do
+ expect(ssh_host_key.url.to_s).to eq('ssh://127.0.0.1:22')
+ end
+ end
end
end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index e4f25c79e53..cd711757bf1 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -1696,9 +1696,9 @@ RSpec.describe User do
describe '#generate_password' do
it 'does not generate password by default' do
- user = create(:user, password: Gitlab::Password.test_default)
+ user = create(:user, password: 'abcdefghe')
- expect(user.password).to eq(Gitlab::Password.test_default)
+ expect(user.password).to eq('abcdefghe')
end
end
@@ -5623,6 +5623,36 @@ RSpec.describe User do
end
end
+ describe '#valid_password?' do
+ subject { user.valid_password?(password) }
+
+ context 'user with password not in disallowed list' do
+ let(:user) { create(:user) }
+ let(:password) { user.password }
+
+ it { is_expected.to be_truthy }
+
+ context 'using a wrong password' do
+ let(:password) { 'WRONG PASSWORD' }
+
+ it { is_expected.to be_falsey }
+ end
+ end
+
+ context 'user with disallowed password' do
+ let(:user) { create(:user, :disallowed_password) }
+ let(:password) { user.password }
+
+ it { is_expected.to be_falsey }
+
+ context 'using a wrong password' do
+ let(:password) { 'WRONG PASSWORD' }
+
+ it { is_expected.to be_falsey }
+ end
+ end
+ end
+
describe '#password_expired?' do
let(:user) { build(:user, password_expires_at: password_expires_at) }
diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb
index 793b1fffd5f..7cd4191f6fc 100644
--- a/spec/policies/project_policy_spec.rb
+++ b/spec/policies/project_policy_spec.rb
@@ -81,25 +81,62 @@ RSpec.describe ProjectPolicy do
context 'merge requests feature' do
let(:current_user) { owner }
+ let(:mr_permissions) do
+ [:create_merge_request_from, :read_merge_request, :update_merge_request,
+ :admin_merge_request, :create_merge_request_in]
+ end
it 'disallows all permissions when the feature is disabled' do
project.project_feature.update!(merge_requests_access_level: ProjectFeature::DISABLED)
- mr_permissions = [:create_merge_request_from, :read_merge_request,
- :update_merge_request, :admin_merge_request,
- :create_merge_request_in]
-
expect_disallowed(*mr_permissions)
end
+
+ context 'for a guest in a private project' do
+ let(:current_user) { guest }
+ let(:project) { private_project }
+
+ it 'disallows the guest from all merge request permissions' do
+ expect_disallowed(*mr_permissions)
+ end
+ end
end
- context 'for a guest in a private project' do
- let(:current_user) { guest }
- let(:project) { private_project }
+ context 'creating_merge_request_in' do
+ context 'when project is public' do
+ let(:project) { public_project }
+
+ context 'when the current_user is guest' do
+ let(:current_user) { guest }
- it 'disallows the guest from reading the merge request and merge request iid' do
- expect_disallowed(:read_merge_request)
- expect_disallowed(:read_merge_request_iid)
+ it { is_expected.to be_allowed(:create_merge_request_in) }
+ end
+ end
+
+ context 'when project is internal' do
+ let(:project) { internal_project }
+
+ context 'when the current_user is guest' do
+ let(:current_user) { guest }
+
+ it { is_expected.to be_allowed(:create_merge_request_in) }
+ end
+ end
+
+ context 'when project is private' do
+ let(:project) { private_project }
+
+ context 'when the current_user is guest' do
+ let(:current_user) { guest }
+
+ it { is_expected.not_to be_allowed(:create_merge_request_in) }
+ end
+
+ context 'when the current_user is reporter or above' do
+ let(:current_user) { reporter }
+
+ it { is_expected.to be_allowed(:create_merge_request_in) }
+ end
end
end
@@ -1316,6 +1353,110 @@ RSpec.describe ProjectPolicy do
end
end
+ describe 'read_ci_cd_analytics' do
+ context 'public project' do
+ let(:project) { create(:project, :public, :analytics_enabled) }
+ let(:current_user) { create(:user) }
+
+ context 'when public pipelines are disabled for the project' do
+ before do
+ project.update!(public_builds: false)
+ end
+
+ context 'project member' do
+ %w(guest reporter developer maintainer).each do |role|
+ context role do
+ before do
+ project.add_user(current_user, role.to_sym)
+ end
+
+ if role == 'guest'
+ it { is_expected.to be_disallowed(:read_ci_cd_analytics) }
+ else
+ it { is_expected.to be_allowed(:read_ci_cd_analytics) }
+ end
+ end
+ end
+ end
+
+ context 'non member' do
+ let(:current_user) { non_member }
+
+ it { is_expected.to be_disallowed(:read_ci_cd_analytics) }
+ end
+
+ context 'anonymous' do
+ let(:current_user) { anonymous }
+
+ it { is_expected.to be_disallowed(:read_ci_cd_analytics) }
+ end
+ end
+
+ context 'when public pipelines are enabled for the project' do
+ before do
+ project.update!(public_builds: true)
+ end
+
+ context 'project member' do
+ %w(guest reporter developer maintainer).each do |role|
+ context role do
+ before do
+ project.add_user(current_user, role.to_sym)
+ end
+
+ it { is_expected.to be_allowed(:read_ci_cd_analytics) }
+ end
+ end
+ end
+
+ context 'non member' do
+ let(:current_user) { non_member }
+
+ it { is_expected.to be_allowed(:read_ci_cd_analytics) }
+ end
+
+ context 'anonymous' do
+ let(:current_user) { anonymous }
+
+ it { is_expected.to be_allowed(:read_ci_cd_analytics) }
+ end
+ end
+ end
+
+ context 'private project' do
+ let(:project) { create(:project, :private, :analytics_enabled) }
+ let(:current_user) { create(:user) }
+
+ context 'project member' do
+ %w(guest reporter developer maintainer).each do |role|
+ context role do
+ before do
+ project.add_user(current_user, role.to_sym)
+ end
+
+ if role == 'guest'
+ it { is_expected.to be_disallowed(:read_ci_cd_analytics) }
+ else
+ it { is_expected.to be_allowed(:read_ci_cd_analytics) }
+ end
+ end
+ end
+ end
+
+ context 'non member' do
+ let(:current_user) { non_member }
+
+ it { is_expected.to be_disallowed(:read_ci_cd_analytics) }
+ end
+
+ context 'anonymous' do
+ let(:current_user) { anonymous }
+
+ it { is_expected.to be_disallowed(:read_ci_cd_analytics) }
+ end
+ end
+ end
+
it_behaves_like 'Self-managed Core resource access tokens'
describe 'operations feature' do
diff --git a/spec/requests/api/ci/runner/runners_post_spec.rb b/spec/requests/api/ci/runner/runners_post_spec.rb
index 5eb5d3977a3..af2c1df0b58 100644
--- a/spec/requests/api/ci/runner/runners_post_spec.rb
+++ b/spec/requests/api/ci/runner/runners_post_spec.rb
@@ -130,7 +130,7 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
}
end
- let_it_be(:new_runner) { create(:ci_runner) }
+ let_it_be(:new_runner) { build(:ci_runner) }
it 'uses active value in registration' do
expect_next_instance_of(::Ci::RegisterRunnerService) do |service|
@@ -183,6 +183,54 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
expect(response).to have_gitlab_http_status(:created)
expect(::Ci::Runner.last.ip_address).to eq('123.111.123.111')
end
+
+ context 'when tags parameter is provided' do
+ def request
+ post api('/runners'), params: {
+ token: registration_token,
+ tag_list: tag_list
+ }
+ end
+
+ context 'with number of tags above limit' do
+ let(:tag_list) { (1..::Ci::Runner::TAG_LIST_MAX_LENGTH + 1).map { |i| "tag#{i}" } }
+
+ it 'uses tag_list value in registration and returns error' do
+ expect_next_instance_of(::Ci::RegisterRunnerService) do |service|
+ expected_params = { tag_list: tag_list }.stringify_keys
+
+ expect(service).to receive(:execute)
+ .once
+ .with(registration_token, a_hash_including(expected_params))
+ .and_call_original
+ end
+
+ request
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ expect(json_response.dig('message', 'tags_list')).to contain_exactly("Too many tags specified. Please limit the number of tags to #{::Ci::Runner::TAG_LIST_MAX_LENGTH}")
+ end
+ end
+
+ context 'with number of tags below limit' do
+ let(:tag_list) { (1..20).map { |i| "tag#{i}" } }
+
+ it 'uses tag_list value in registration and successfully creates runner' do
+ expect_next_instance_of(::Ci::RegisterRunnerService) do |service|
+ expected_params = { tag_list: tag_list }.stringify_keys
+
+ expect(service).to receive(:execute)
+ .once
+ .with(registration_token, a_hash_including(expected_params))
+ .and_call_original
+ end
+
+ request
+
+ expect(response).to have_gitlab_http_status(:created)
+ end
+ end
+ end
end
end
end
diff --git a/spec/requests/api/ci/runners_spec.rb b/spec/requests/api/ci/runners_spec.rb
index 336ce70d8d2..c0adf5c71cb 100644
--- a/spec/requests/api/ci/runners_spec.rb
+++ b/spec/requests/api/ci/runners_spec.rb
@@ -396,6 +396,19 @@ RSpec.describe API::Ci::Runners do
expect(shared_runner.reload.tag_list).to include('ruby2.1', 'pgsql', 'mysql')
end
+ it 'unrelated runner attribute on an existing runner with too many tags' do
+ # This test ensures that it is possible to update any attribute on a runner that currently fails the
+ # validation that ensures that there aren't too many tags associated with a runner
+ existing_invalid_shared_runner = build(:ci_runner, :instance, tag_list: (1..::Ci::Runner::TAG_LIST_MAX_LENGTH + 1).map { |i| "tag#{i}" } )
+ existing_invalid_shared_runner.save!(validate: false)
+
+ active = existing_invalid_shared_runner.active
+ update_runner(existing_invalid_shared_runner.id, admin, paused: active)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(existing_invalid_shared_runner.reload.active).to eq(!active)
+ end
+
it 'runner untagged flag' do
# Ensure tag list is non-empty before setting untagged to false.
update_runner(shared_runner.id, admin, tag_list: ['ruby2.1', 'pgsql', 'mysql'])
diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb
index 985e07bf174..54095ca80ff 100644
--- a/spec/requests/api/users_spec.rb
+++ b/spec/requests/api/users_spec.rb
@@ -1046,7 +1046,7 @@ RSpec.describe API::Users do
post api('/users', admin),
params: {
email: 'invalid email',
- password: Gitlab::Password.test_default,
+ password: 'password',
name: 'test'
}
expect(response).to have_gitlab_http_status(:bad_request)
@@ -1112,7 +1112,7 @@ RSpec.describe API::Users do
post api('/users', admin),
params: {
email: 'test@example.com',
- password: Gitlab::Password.test_default,
+ password: 'password',
username: 'test',
name: 'foo'
}
@@ -1124,7 +1124,7 @@ RSpec.describe API::Users do
params: {
name: 'foo',
email: 'test@example.com',
- password: Gitlab::Password.test_default,
+ password: 'password',
username: 'foo'
}
end.to change { User.count }.by(0)
@@ -1138,7 +1138,7 @@ RSpec.describe API::Users do
params: {
name: 'foo',
email: 'foo@example.com',
- password: Gitlab::Password.test_default,
+ password: 'password',
username: 'test'
}
end.to change { User.count }.by(0)
@@ -1152,7 +1152,7 @@ RSpec.describe API::Users do
params: {
name: 'foo',
email: 'foo@example.com',
- password: Gitlab::Password.test_default,
+ password: 'password',
username: 'TEST'
}
end.to change { User.count }.by(0)
@@ -1497,8 +1497,8 @@ RSpec.describe API::Users do
context "with existing user" do
before do
- post api("/users", admin), params: { email: 'test@example.com', password: Gitlab::Password.test_default, username: 'test', name: 'test' }
- post api("/users", admin), params: { email: 'foo@bar.com', password: Gitlab::Password.test_default, username: 'john', name: 'john' }
+ post api("/users", admin), params: { email: 'test@example.com', password: 'password', username: 'test', name: 'test' }
+ post api("/users", admin), params: { email: 'foo@bar.com', password: 'password', username: 'john', name: 'john' }
@user = User.all.last
end
diff --git a/spec/requests/git_http_spec.rb b/spec/requests/git_http_spec.rb
index 340ed7bde53..0d24eb9ee2a 100644
--- a/spec/requests/git_http_spec.rb
+++ b/spec/requests/git_http_spec.rb
@@ -319,7 +319,7 @@ RSpec.describe 'Git HTTP requests' do
context 'when user is using credentials with special characters' do
context 'with password with special characters' do
before do
- user.update!(password: Gitlab::Password.test_default)
+ user.update!(password: 'RKszEwéC5kFnû∆f243fycGu§Gh9ftDj!U')
end
it 'allows clones' do
@@ -1688,7 +1688,7 @@ RSpec.describe 'Git HTTP requests' do
context 'when user is using credentials with special characters' do
context 'with password with special characters' do
before do
- user.update!(password: Gitlab::Password.test_default)
+ user.update!(password: 'RKszEwéC5kFnû∆f243fycGu§Gh9ftDj!U')
end
it 'allows clones' do
diff --git a/spec/services/ci/create_pipeline_service/creation_errors_and_warnings_spec.rb b/spec/services/ci/create_pipeline_service/creation_errors_and_warnings_spec.rb
index e62a94b6df8..a920b90b97d 100644
--- a/spec/services/ci/create_pipeline_service/creation_errors_and_warnings_spec.rb
+++ b/spec/services/ci/create_pipeline_service/creation_errors_and_warnings_spec.rb
@@ -53,6 +53,24 @@ RSpec.describe Ci::CreatePipelineService do
end
context 'when failed to create the pipeline' do
+ context 'when errors are raised and masked variables are involved' do
+ let_it_be(:variable) { create(:ci_variable, project: project, key: 'GL_TOKEN', value: 'test_value', masked: true) }
+
+ let(:config) do
+ <<~YAML
+ include:
+ - local: $GL_TOKEN/gitlab-ci.txt
+ YAML
+ end
+
+ it 'contains errors and masks variables' do
+ error_message = "Included file `xxxxxxxxxx/gitlab-ci.txt` does not have YAML extension!"
+ expect(pipeline.yaml_errors).to eq(error_message)
+ expect(pipeline.error_messages.map(&:content)).to contain_exactly(error_message)
+ expect(pipeline.errors.full_messages).to contain_exactly(error_message)
+ end
+ end
+
context 'when warnings are raised' do
let(:config) do
<<~YAML
diff --git a/spec/services/users/create_service_spec.rb b/spec/services/users/create_service_spec.rb
index ab9da82e91c..74340bac055 100644
--- a/spec/services/users/create_service_spec.rb
+++ b/spec/services/users/create_service_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe Users::CreateService do
context 'when required parameters are provided' do
let(:params) do
- { name: 'John Doe', username: 'jduser', email: email, password: Gitlab::Password.test_default }
+ { name: 'John Doe', username: 'jduser', email: email, password: 'mydummypass' }
end
it 'returns a persisted user' do
@@ -82,13 +82,13 @@ RSpec.describe Users::CreateService do
context 'when force_random_password parameter is true' do
let(:params) do
- { name: 'John Doe', username: 'jduser', email: 'jd@example.com', password: Gitlab::Password.test_default, force_random_password: true }
+ { name: 'John Doe', username: 'jduser', email: 'jd@example.com', password: 'mydummypass', force_random_password: true }
end
it 'generates random password' do
user = service.execute
- expect(user.password).not_to eq Gitlab::Password.test_default
+ expect(user.password).not_to eq 'mydummypass'
expect(user.password).to be_present
end
end
@@ -99,7 +99,7 @@ RSpec.describe Users::CreateService do
name: 'John Doe',
username: 'jduser',
email: 'jd@example.com',
- password: Gitlab::Password.test_default,
+ password: 'mydummypass',
password_automatically_set: true
}
end
@@ -121,7 +121,7 @@ RSpec.describe Users::CreateService do
context 'when skip_confirmation parameter is true' do
let(:params) do
- { name: 'John Doe', username: 'jduser', email: 'jd@example.com', password: Gitlab::Password.test_default, skip_confirmation: true }
+ { name: 'John Doe', username: 'jduser', email: 'jd@example.com', password: 'mydummypass', skip_confirmation: true }
end
it 'confirms the user' do
@@ -131,7 +131,7 @@ RSpec.describe Users::CreateService do
context 'when reset_password parameter is true' do
let(:params) do
- { name: 'John Doe', username: 'jduser', email: 'jd@example.com', password: Gitlab::Password.test_default, reset_password: true }
+ { name: 'John Doe', username: 'jduser', email: 'jd@example.com', password: 'mydummypass', reset_password: true }
end
it 'resets password even if a password parameter is given' do
@@ -152,7 +152,7 @@ RSpec.describe Users::CreateService do
context 'with nil user' do
let(:params) do
- { name: 'John Doe', username: 'jduser', email: 'jd@example.com', password: Gitlab::Password.test_default, skip_confirmation: true }
+ { name: 'John Doe', username: 'jduser', email: 'jd@example.com', password: 'mydummypass', skip_confirmation: true }
end
let(:service) { described_class.new(nil, params) }
diff --git a/spec/support/helpers/login_helpers.rb b/spec/support/helpers/login_helpers.rb
index c0734bae375..7666d71f13c 100644
--- a/spec/support/helpers/login_helpers.rb
+++ b/spec/support/helpers/login_helpers.rb
@@ -91,11 +91,12 @@ module LoginHelpers
# user - User instance to login with
# remember - Whether or not to check "Remember me" (default: false)
# two_factor_auth - If two-factor authentication is enabled (default: false)
- def gitlab_sign_in_with(user, remember: false, two_factor_auth: false)
+ # password - password to attempt to login with
+ def gitlab_sign_in_with(user, remember: false, two_factor_auth: false, password: nil)
visit new_user_session_path
fill_in "user_login", with: user.email
- fill_in "user_password", with: Gitlab::Password.test_default
+ fill_in "user_password", with: (password || "12345678")
check 'user_remember_me' if remember
click_button "Sign in"
diff --git a/spec/support/shared_contexts/policies/project_policy_shared_context.rb b/spec/support/shared_contexts/policies/project_policy_shared_context.rb
index 3641edc845a..a78953e8199 100644
--- a/spec/support/shared_contexts/policies/project_policy_shared_context.rb
+++ b/spec/support/shared_contexts/policies/project_policy_shared_context.rb
@@ -15,7 +15,7 @@ RSpec.shared_context 'ProjectPolicy context' do
let(:base_guest_permissions) do
%i[
- award_emoji create_issue create_merge_request_in create_note
+ award_emoji create_issue create_note
create_project read_issue_board read_issue read_issue_iid read_issue_link
read_label read_planning_hierarchy read_issue_board_list read_milestone read_note read_project
read_project_for_iids read_project_member read_release read_snippet
@@ -26,12 +26,12 @@ RSpec.shared_context 'ProjectPolicy context' do
let(:base_reporter_permissions) do
%i[
admin_issue admin_issue_link admin_label admin_issue_board_list
- create_snippet create_incident daily_statistics download_code
+ create_snippet create_incident daily_statistics create_merge_request_in download_code
download_wiki_code fork_project metrics_dashboard read_build
read_commit_status read_confidential_issues read_container_image
read_deployment read_environment read_merge_request
read_metrics_dashboard_annotation read_pipeline read_prometheus
- read_sentry_issue update_issue
+ read_sentry_issue update_issue create_merge_request_in
]
end
@@ -66,7 +66,7 @@ RSpec.shared_context 'ProjectPolicy context' do
let(:public_permissions) do
%i[
- build_download_code build_read_container_image download_code
+ build_download_code build_read_container_image create_merge_request_in download_code
download_wiki_code fork_project read_commit_status read_container_image
read_pipeline read_release
]
diff --git a/spec/support/shared_examples/policies/project_policy_shared_examples.rb b/spec/support/shared_examples/policies/project_policy_shared_examples.rb
index a4243db6bc9..63e4d458ad4 100644
--- a/spec/support/shared_examples/policies/project_policy_shared_examples.rb
+++ b/spec/support/shared_examples/policies/project_policy_shared_examples.rb
@@ -107,6 +107,19 @@ RSpec.shared_examples 'deploy token does not get confused with user' do
end
RSpec.shared_examples 'project policies as guest' do
+ context 'abilities for public projects' do
+ let(:project) { public_project }
+ let(:current_user) { guest }
+
+ it do
+ expect_allowed(*guest_permissions)
+ expect_allowed(*public_permissions)
+ expect_disallowed(*developer_permissions)
+ expect_disallowed(*maintainer_permissions)
+ expect_disallowed(*owner_permissions)
+ end
+ end
+
context 'abilities for non-public projects' do
let(:project) { private_project }
let(:current_user) { guest }
diff --git a/spec/tasks/gitlab/password_rake_spec.rb b/spec/tasks/gitlab/password_rake_spec.rb
index ec18d713351..65bba836024 100644
--- a/spec/tasks/gitlab/password_rake_spec.rb
+++ b/spec/tasks/gitlab/password_rake_spec.rb
@@ -3,7 +3,7 @@
require 'rake_helper'
RSpec.describe 'gitlab:password rake tasks', :silence_stdout do
- let_it_be(:user_1) { create(:user, username: 'foobar', password: Gitlab::Password.test_default) }
+ let_it_be(:user_1) { create(:user, username: 'foobar', password: 'initial_password') }
def stub_username(username)
allow(Gitlab::TaskHelpers).to receive(:prompt).with('Enter username: ').and_return(username)
@@ -19,14 +19,14 @@ RSpec.describe 'gitlab:password rake tasks', :silence_stdout do
Rake.application.rake_require 'tasks/gitlab/password'
stub_username('foobar')
- stub_password(Gitlab::Password.test_default)
+ stub_password('secretpassword')
end
describe ':reset' do
context 'when all inputs are correct' do
it 'updates the password properly' do
run_rake_task('gitlab:password:reset', user_1.username)
- expect(user_1.reload.valid_password?(Gitlab::Password.test_default)).to eq(true)
+ expect(user_1.reload.valid_password?('secretpassword')).to eq(true)
end
end
@@ -55,7 +55,7 @@ RSpec.describe 'gitlab:password rake tasks', :silence_stdout do
context 'when passwords do not match' do
before do
- stub_password(Gitlab::Password.test_default, "different" + Gitlab::Password.test_default)
+ stub_password('randompassword', 'differentpassword')
end
it 'aborts with an error' do