diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb index 70a882832a68209997e9c5db306eed9eb6d2237f..39ef92f17fb79e46d8bf0e297d0c3984b9b2d82c 100644 --- a/app/helpers/application_settings_helper.rb +++ b/app/helpers/application_settings_helper.rb @@ -279,6 +279,7 @@ def visible_attributes :autocomplete_users_limit, :autocomplete_users_unauthenticated_limit, :allow_bypass_placeholder_confirmation, + :ci_cd_catalog_projects_allowlist_raw, :ci_delete_pipelines_in_seconds_limit_human_readable, :ci_job_live_trace_enabled, :ci_partitions_size_limit, diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb index 7595b03993d03d213d5e996a6f147d5aac1197dc..fd5cbd8a9d1edeaec9baa9efeacd8e121830ceca 100644 --- a/app/models/application_setting.rb +++ b/app/models/application_setting.rb @@ -524,7 +524,8 @@ def self.kroki_formats_attributes ci_job_live_trace_enabled: [:boolean, { default: false }], ci_partitions_size_limit: [::Gitlab::Database::Type::JsonbInteger.new, { default: 100.gigabytes }], ci_delete_pipelines_in_seconds_limit: [:integer, { default: ChronicDuration.parse('1 year') }], - git_push_pipeline_limit: [:integer, { default: 4 }] + git_push_pipeline_limit: [:integer, { default: 4 }], + ci_cd_catalog_projects_allowlist: [:string, { array: true, default: [] }] chronic_duration_attr :ci_delete_pipelines_in_seconds_limit_human_readable, :ci_delete_pipelines_in_seconds_limit diff --git a/app/models/application_setting_implementation.rb b/app/models/application_setting_implementation.rb index cdbba3ef20fcd4e9c8fe42596b74da96d3578e65..884e142add271dd6465ea78ef88c714aa52991ba 100644 --- a/app/models/application_setting_implementation.rb +++ b/app/models/application_setting_implementation.rb @@ -438,6 +438,14 @@ def outbound_local_requests_allowlist_raw=(values) self.outbound_local_requests_whitelist = strings_to_array(values) end + def ci_cd_catalog_projects_allowlist_raw + array_to_string(ci_cd_catalog_projects_allowlist) + end + + def ci_cd_catalog_projects_allowlist_raw=(values) + self.ci_cd_catalog_projects_allowlist = strings_to_array(values) + end + def add_to_outbound_local_requests_whitelist(values_array) clear_memoization(:outbound_local_requests_allowlist_arrays) diff --git a/app/services/ci/catalog/resources/release_service.rb b/app/services/ci/catalog/resources/release_service.rb index 68856bd90b623ee84508fe2ba143e33ee77a1906..d5d9e7831f85cd5651f48d1ae2716276058775c0 100644 --- a/app/services/ci/catalog/resources/release_service.rb +++ b/app/services/ci/catalog/resources/release_service.rb @@ -14,7 +14,8 @@ def initialize(release, user, metadata) def execute resource_version = track_release_duration do - check_access + check_user_access + check_project_access validate_catalog_resource create_version end @@ -46,12 +47,19 @@ def track_release_duration result end - def check_access + def check_user_access return if Ability.allowed?(user, :publish_catalog_version, release) errors << 'You are not authorized to publish a version to the CI/CD catalog' end + def check_project_access + projects_allowlist = Gitlab::CurrentSettings.ci_cd_catalog_projects_allowlist + return if projects_allowlist.blank? || projects_allowlist.include?(project.full_path) + + errors << 'The project is not authorized to publish a version to the CI/CD catalog' + end + def validate_catalog_resource return if errors.present? diff --git a/app/views/admin/application_settings/_ci_cd_catalog.html.haml b/app/views/admin/application_settings/_ci_cd_catalog.html.haml new file mode 100644 index 0000000000000000000000000000000000000000..91586bfd0eb7265be9cc13ab7d3efd52a3e97309 --- /dev/null +++ b/app/views/admin/application_settings/_ci_cd_catalog.html.haml @@ -0,0 +1,12 @@ +.settings-content + = gitlab_ui_form_for @application_setting, url: ci_cd_admin_application_settings_path(anchor: 'js-catalog-settings'), html: { class: 'fieldset-form' } do |f| + = form_errors(@application_setting) + + %fieldset + .form-group + = f.label :ci_cd_catalog_projects_allowlist_raw, s_('AdminSettings|CI/CD Catalog publishing restrictions'), class: 'label-bold' + = f.text_area :ci_cd_catalog_projects_allowlist_raw, class: 'form-control gl-form-input', rows: 5, placeholder: 'gitlab-org/component-project' + .form-text.gl-text-subtle + = s_('AdminSettings|Restrict which projects can publish components to the CI/CD Catalog. Enter one project path per line (for example, %{code_start}namespace/project%{code_end}). If empty, all projects can publish to the Catalog.').html_safe % { code_start: ''.html_safe, code_end: ''.html_safe } + + = f.submit _('Save changes'), pajamas_button: true diff --git a/app/views/admin/application_settings/ci_cd.html.haml b/app/views/admin/application_settings/ci_cd.html.haml index 906c9d202bb69f9f8f442940591b2a66d6aa2058..3b5ff6e9d53be862630d6fa4c9593cfd54317c93 100644 --- a/app/views/admin/application_settings/ci_cd.html.haml +++ b/app/views/admin/application_settings/ci_cd.html.haml @@ -33,6 +33,15 @@ - c.with_body do = render 'ci_cd' += render ::Layouts::SettingsBlockComponent.new(_('Catalog'), + id: 'js-catalog-settings', + testid: 'catalog-settings', + expanded: expanded_by_default?) do |c| + - c.with_description do + = _('Configure CI/CD Catalog settings, including publishing restrictions.') + - c.with_body do + = render 'ci_cd_catalog' + = render_if_exists 'admin/application_settings/required_instance_ci_setting', expanded: expanded_by_default? = render_if_exists 'admin/application_settings/package_registry', expanded: expanded_by_default?