diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-12-13 01:59:38 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-12-13 01:59:38 +0300 |
commit | 734bfe3a2e8b86c3e049f6f13d380b3d30e4e359 (patch) | |
tree | a0599c2a6efd4466ba7f48471def5791d2682e53 /spec/requests | |
parent | 27e1dab1ed98c46c91b85e8c5dd1cefd62c0cb96 (diff) |
Add latest changes from gitlab-org/security/gitlab@16-6-stable-ee
Diffstat (limited to 'spec/requests')
-rw-r--r-- | spec/requests/api/ci/pipeline_schedules_spec.rb | 267 | ||||
-rw-r--r-- | spec/requests/api/resource_access_tokens_spec.rb | 88 | ||||
-rw-r--r-- | spec/requests/oauth/tokens_controller_spec.rb | 27 |
3 files changed, 346 insertions, 36 deletions
diff --git a/spec/requests/api/ci/pipeline_schedules_spec.rb b/spec/requests/api/ci/pipeline_schedules_spec.rb index fb67d7cb4fb..a4bb379d01c 100644 --- a/spec/requests/api/ci/pipeline_schedules_spec.rb +++ b/spec/requests/api/ci/pipeline_schedules_spec.rb @@ -628,17 +628,89 @@ RSpec.describe API::Ci::PipelineSchedules, feature_category: :continuous_integra context 'authenticated user with valid permissions' do context 'with required parameters' do - it 'creates pipeline_schedule_variable' do - expect do - post api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}/variables", developer), + let(:pipeline_schedule) do + create(:ci_pipeline_schedule, project: project, owner: api_user) + end + + let_it_be(:maintainer) { create(:user) } + let_it_be(:project_owner) { create(:user) } + + before do + project.add_maintainer(maintainer) + project.add_owner(project_owner) + end + + shared_examples 'creates pipeline_schedule_variables' do + it do + expect do + post api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}/variables", api_user), + params: params.merge(variable_type: 'file') + end.to change { pipeline_schedule.variables.count }.by(1) + + expect(response).to have_gitlab_http_status(:created) + expect(response).to match_response_schema('pipeline_schedule_variable') + expect(json_response['key']).to eq(params[:key]) + expect(json_response['value']).to eq(params[:value]) + expect(json_response['variable_type']).to eq('file') + end + end + + shared_examples 'fails to create pipeline_schedule_variables' do + it do + post api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}/variables", api_user), params: params.merge(variable_type: 'file') - end.to change { pipeline_schedule.variables.count }.by(1) - expect(response).to have_gitlab_http_status(:created) - expect(response).to match_response_schema('pipeline_schedule_variable') - expect(json_response['key']).to eq(params[:key]) - expect(json_response['value']).to eq(params[:value]) - expect(json_response['variable_type']).to eq('file') + expect(pipeline_schedule.variables.count).to eq(0) + expect(response).to have_gitlab_http_status(:forbidden) + end + end + + context 'when project restricts use of user defined variables' do + before do + project.update!(restrict_user_defined_variables: true) + end + + context 'as developer' do + let(:api_user) { developer } + + it_behaves_like 'fails to create pipeline_schedule_variables' + end + + context 'as maintainer' do + let(:api_user) { maintainer } + + it_behaves_like 'creates pipeline_schedule_variables' + end + + context 'as owner' do + let(:api_user) { project_owner } + + it_behaves_like 'creates pipeline_schedule_variables' + end + end + + context 'when project does not restrict use of user defined variables' do + before do + project.update!(restrict_user_defined_variables: false) + end + + context 'as developer' do + let(:api_user) { developer } + + it_behaves_like 'creates pipeline_schedule_variables' + end + + context 'as maintainer' do + let(:api_user) { maintainer } + + it_behaves_like 'creates pipeline_schedule_variables' + end + + context 'as owner' do + let(:api_user) { project_owner } + + it_behaves_like 'creates pipeline_schedule_variables' + end end end @@ -688,14 +760,85 @@ RSpec.describe API::Ci::PipelineSchedules, feature_category: :continuous_integra end context 'authenticated user with valid permissions' do - it 'updates pipeline_schedule_variable' do - put api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}/variables/#{pipeline_schedule_variable.key}", developer), - params: { value: 'updated_value', variable_type: 'file' } + let(:pipeline_schedule) do + create(:ci_pipeline_schedule, project: project, owner: api_user) + end - expect(response).to have_gitlab_http_status(:ok) - expect(response).to match_response_schema('pipeline_schedule_variable') - expect(json_response['value']).to eq('updated_value') - expect(json_response['variable_type']).to eq('file') + let_it_be(:maintainer) { create(:user) } + let_it_be(:project_owner) { create(:user) } + + before do + project.add_maintainer(maintainer) + project.add_owner(project_owner) + end + + shared_examples 'updates pipeline_schedule_variable' do + it do + put api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}/variables/#{pipeline_schedule_variable.key}", api_user), + params: { value: 'updated_value', variable_type: 'file' } + + expect(response).to have_gitlab_http_status(:ok) + expect(response).to match_response_schema('pipeline_schedule_variable') + expect(json_response['value']).to eq('updated_value') + expect(json_response['variable_type']).to eq('file') + end + end + + shared_examples 'fails to update pipeline_schedule_variable' do + it do + put api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}/variables/#{pipeline_schedule_variable.key}", api_user), + params: { value: 'updated_value', variable_type: 'file' } + + expect(response).to have_gitlab_http_status(:forbidden) + end + end + + context 'when project restricts use of user defined variables' do + before do + project.update!(restrict_user_defined_variables: true) + end + + context 'as developer' do + let(:api_user) { developer } + + it_behaves_like 'fails to update pipeline_schedule_variable' + end + + context 'as maintainer' do + let(:api_user) { maintainer } + + it_behaves_like 'updates pipeline_schedule_variable' + end + + context 'as owner' do + let(:api_user) { project_owner } + + it_behaves_like 'updates pipeline_schedule_variable' + end + end + + context 'when project does not restrict use of user defined variables' do + before do + project.update!(restrict_user_defined_variables: false) + end + + context 'as developer' do + let(:api_user) { developer } + + it_behaves_like 'updates pipeline_schedule_variable' + end + + context 'as maintainer' do + let(:api_user) { maintainer } + + it_behaves_like 'updates pipeline_schedule_variable' + end + + context 'as owner' do + let(:api_user) { project_owner } + + it_behaves_like 'updates pipeline_schedule_variable' + end end end @@ -732,19 +875,93 @@ RSpec.describe API::Ci::PipelineSchedules, feature_category: :continuous_integra end context 'authenticated user with valid permissions' do - it 'deletes pipeline_schedule_variable' do - expect do - delete api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}/variables/#{pipeline_schedule_variable.key}", maintainer) - end.to change { Ci::PipelineScheduleVariable.count }.by(-1) + let(:pipeline_schedule) do + create(:ci_pipeline_schedule, project: project, owner: api_user) + end - expect(response).to have_gitlab_http_status(:accepted) - expect(response).to match_response_schema('pipeline_schedule_variable') + let_it_be(:project_owner) { create(:user) } + + before do + project.add_owner(project_owner) end - it 'responds with 404 Not Found if requesting non-existing pipeline_schedule_variable' do - delete api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}/variables/____", maintainer) + shared_examples 'deletes pipeline_schedule_variable' do + it do + expect do + delete api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}/variables/#{pipeline_schedule_variable.key}", api_user) + end.to change { Ci::PipelineScheduleVariable.count }.by(-1) - expect(response).to have_gitlab_http_status(:not_found) + expect(response).to have_gitlab_http_status(:accepted) + expect(response).to match_response_schema('pipeline_schedule_variable') + end + end + + shared_examples 'fails to delete pipeline_schedule_variable' do + it do + expect do + delete api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}/variables/#{pipeline_schedule_variable.key}", api_user) + end.not_to change { Ci::PipelineScheduleVariable.count } + + expect(response).to have_gitlab_http_status(:forbidden) + end + end + + context 'when project restricts use of user defined variables' do + before do + project.update!(restrict_user_defined_variables: true) + end + + context 'as developer' do + let(:api_user) { developer } + + it_behaves_like 'fails to delete pipeline_schedule_variable' + end + + context 'as maintainer' do + let(:api_user) { maintainer } + + it_behaves_like 'deletes pipeline_schedule_variable' + end + + context 'as owner' do + let(:api_user) { project_owner } + + it_behaves_like 'deletes pipeline_schedule_variable' + end + end + + context 'when project does not restrict use of user defined variables' do + before do + project.update!(restrict_user_defined_variables: false) + end + + context 'as developer' do + let(:api_user) { developer } + + it_behaves_like 'deletes pipeline_schedule_variable' + end + + context 'as maintainer' do + let(:api_user) { maintainer } + + it_behaves_like 'deletes pipeline_schedule_variable' + end + + context 'as owner' do + let(:api_user) { project_owner } + + it_behaves_like 'deletes pipeline_schedule_variable' + end + end + + context 'as developer' do + let(:api_user) { developer } + + it 'responds with 404 Not Found if requesting non-existing pipeline_schedule_variable' do + delete api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}/variables/____", maintainer) + + expect(response).to have_gitlab_http_status(:not_found) + end end end diff --git a/spec/requests/api/resource_access_tokens_spec.rb b/spec/requests/api/resource_access_tokens_spec.rb index 01e02651a64..f0282b3a675 100644 --- a/spec/requests/api/resource_access_tokens_spec.rb +++ b/spec/requests/api/resource_access_tokens_spec.rb @@ -481,25 +481,75 @@ RSpec.describe API::ResourceAccessTokens, feature_category: :system_access do let(:path) { "/#{source_type}s/#{resource_id}/access_tokens/#{token_id}/rotate" } - before do - resource.add_maintainer(project_bot) - resource.add_owner(user) + subject(:rotate_token) { post(api(path, user), params: params) } + + context 'when user is owner' do + before do + resource.add_maintainer(project_bot) + resource.add_owner(user) + end + + it "allows owner to rotate token", :freeze_time do + rotate_token + + expect(response).to have_gitlab_http_status(:ok) + expect(json_response['token']).not_to eq(token.token) + expect(json_response['expires_at']).to eq((Date.today + 1.week).to_s) + end end - subject(:rotate_token) { post(api(path, user), params: params) } + context 'when user is maintainer' do + before do + resource.add_maintainer(user) + end + + context "when token has owner access level" do + let(:error_message) { 'Not eligible to rotate token with access level higher than the user' } - it "allows owner to rotate token", :freeze_time do - rotate_token + before do + resource.add_owner(project_bot) + end - expect(response).to have_gitlab_http_status(:ok) - expect(json_response['token']).not_to eq(token.token) - expect(json_response['expires_at']).to eq((Date.today + 1.week).to_s) + it "raises error" do + rotate_token + + if source_type == 'project' + expect(response).to have_gitlab_http_status(:bad_request) + expect(json_response['message']).to eq("400 Bad request - #{error_message}") + else + expect(response).to have_gitlab_http_status(:unauthorized) + end + end + end + + context 'when token has maintainer access level' do + before do + resource.add_maintainer(project_bot) + end + + it "rotates token", :freeze_time do + rotate_token + + if source_type == 'project' + expect(response).to have_gitlab_http_status(:ok) + expect(json_response['token']).not_to eq(token.token) + expect(json_response['expires_at']).to eq((Date.today + 1.week).to_s) + else + expect(response).to have_gitlab_http_status(:unauthorized) + end + end + end end context 'when expiry is defined' do let(:expiry_date) { Date.today + 1.month } let(:params) { { expires_at: expiry_date } } + before do + resource.add_maintainer(project_bot) + resource.add_owner(user) + end + it "allows owner to rotate token", :freeze_time do rotate_token @@ -510,6 +560,11 @@ RSpec.describe API::ResourceAccessTokens, feature_category: :system_access do end context 'without permission' do + before do + resource.add_maintainer(project_bot) + resource.add_owner(user) + end + it 'returns an error message' do another_user = create(:user) resource.add_developer(another_user) @@ -522,10 +577,21 @@ RSpec.describe API::ResourceAccessTokens, feature_category: :system_access do context 'when service raises an error' do let(:error_message) { 'boom!' } + let(:personal_token_service) { PersonalAccessTokens::RotateService } + let(:project_token_service) { ProjectAccessTokens::RotateService } before do - allow_next_instance_of(PersonalAccessTokens::RotateService) do |service| - allow(service).to receive(:execute).and_return(ServiceResponse.error(message: error_message)) + resource.add_maintainer(project_bot) + resource.add_owner(user) + + if source_type == 'project' + allow_next_instance_of(project_token_service) do |service| + allow(service).to receive(:execute).and_return(ServiceResponse.error(message: error_message)) + end + else + allow_next_instance_of(personal_token_service) do |service| + allow(service).to receive(:execute).and_return(ServiceResponse.error(message: error_message)) + end end end diff --git a/spec/requests/oauth/tokens_controller_spec.rb b/spec/requests/oauth/tokens_controller_spec.rb index aaacfce0ce8..b7755a30a78 100644 --- a/spec/requests/oauth/tokens_controller_spec.rb +++ b/spec/requests/oauth/tokens_controller_spec.rb @@ -55,6 +55,33 @@ RSpec.describe Oauth::TokensController, feature_category: :system_access do expect(response).to have_gitlab_http_status(:bad_request) expect(user.reload.failed_attempts).to eq(0) end + + context 'when the user has an identity matching a provider that is not password-based' do + before do + create(:identity, provider: 'google_oauth2', user: user) + end + + it 'fails to authenticate and does not call GitLab::Auth' do + expect(::Gitlab::Auth).not_to receive(:find_with_user_password) + + authenticate(password) + + expect(response).to have_gitlab_http_status(:bad_request) + expect(user.reload.failed_attempts).to eq(0) + end + end + + context 'when the user is a password-based omniauth user' do + before do + create(:identity, provider: 'ldapmain', user: user) + end + + it 'forwards the request to Gitlab::Auth' do + expect(::Gitlab::Auth).to receive(:find_with_user_password) + + authenticate(password) + end + end end end end |