diff --git a/ee/lib/api/project_google_cloud_integration.rb b/ee/lib/api/project_google_cloud_integration.rb index 6a60b1bd59c5a8a11f849f02baeedbec0be5005c..80431b0afa300f07ae68db7ed90bf43c4cd83ef3 100644 --- a/ee/lib/api/project_google_cloud_integration.rb +++ b/ee/lib/api/project_google_cloud_integration.rb @@ -6,6 +6,8 @@ class ProjectGoogleCloudIntegration < ::API::Base include GrapePathHelpers::NamedRouteMatcher + GOOGLE_PROJECT_ID_REGEXP = /\A[a-z][a-z0-9-]{5,28}[a-z0-9]\z/ + before { authorize_admin_project } before do not_found! unless ::Gitlab::Saas.feature_available?(:google_cloud_support) @@ -21,7 +23,7 @@ class ProjectGoogleCloudIntegration < ::API::Base end params do optional :enable_google_cloud_artifact_registry, types: Boolean - optional :google_cloud_artifact_registry_project_id, types: String + optional :google_cloud_artifact_registry_project_id, types: String, regexp: GOOGLE_PROJECT_ID_REGEXP at_least_one_of :enable_google_cloud_artifact_registry end get '/integrations.sh' do @@ -59,7 +61,7 @@ class ProjectGoogleCloudIntegration < ::API::Base detail 'This feature is experimental.' end params do - requires :google_cloud_project_id, types: String + requires :google_cloud_project_id, types: String, regexp: GOOGLE_PROJECT_ID_REGEXP end get '/runner_deployment_project.sh' do env['api.format'] = :binary diff --git a/ee/spec/requests/api/project_google_cloud_integration_spec.rb b/ee/spec/requests/api/project_google_cloud_integration_spec.rb index 20cf8bddf1804c5cfcc096b873d888b7e44b1344..49926601ad073c608ccda50b7374c2274097c7d6 100644 --- a/ee/spec/requests/api/project_google_cloud_integration_spec.rb +++ b/ee/spec/requests/api/project_google_cloud_integration_spec.rb @@ -43,6 +43,30 @@ end end + shared_examples 'does not return the shell script' do |invalid_param:| + let(:invalid_google_project_ids) do + [ + '$(curl evil-website.biz)', + 'abcd', + 'a' * 31, + 'my-project-', + 'Capital-Letters' + ] + end + + it do + invalid_google_project_ids.each do |project_id| + get(api(path, owner), params: { + enable_google_cloud_artifact_registry: true, + "#{invalid_param}": project_id + }) + + expect(response).to have_gitlab_http_status(:bad_request) + expect(json_response['error']).to eq("#{invalid_param} is invalid") + end + end + end + describe 'GET /projects/:id/google_cloud/setup/runner_deployment_project.sh' do let(:path) { "/projects/#{project.id}/google_cloud/setup/runner_deployment_project.sh" } let(:params) do @@ -62,6 +86,10 @@ stub_saas_features(google_cloud_support: true) end + context 'when google_cloud_project_id is invalid' do + it_behaves_like 'does not return the shell script', invalid_param: :google_cloud_project_id + end + it_behaves_like 'an endpoint generating a bash script for Google Cloud' end end @@ -89,6 +117,10 @@ create(:google_cloud_platform_workload_identity_federation_integration, project: project) end + context 'when google_cloud_artifact_registry_project_id is invalid' do + it_behaves_like 'does not return the shell script', invalid_param: :google_cloud_artifact_registry_project_id + end + it_behaves_like 'an endpoint generating a bash script for Google Cloud' end