From 4e0a9fbb9ba58e27e5dbd4e762fefc3fa6876c32 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Tue, 3 Jun 2025 21:07:19 +0000 Subject: [PATCH] Add latest changes from gitlab-org/gitlab@master --- .rubocop_todo/lint/symbol_conversion.yml | 10 - Gemfile | 1 - Gemfile.checksum | 2 +- Gemfile.lock | 3 +- Gemfile.next.checksum | 2 +- Gemfile.next.lock | 3 +- .../admin/topics/components/merge_topics.vue | 2 +- .../components/app.vue | 10 +- .../components/config_dropdown.vue | 25 +-- .../merge_request_dashboard/index.js | 5 - .../stylesheets/framework/typography.scss | 6 + app/controllers/groups_controller.rb | 2 +- app/controllers/projects/issues_controller.rb | 2 +- app/controllers/projects_controller.rb | 2 +- app/controllers/uploads_controller.rb | 2 +- .../mutations/members/bulk_update_base.rb | 4 +- app/graphql/mutations/snippets/base.rb | 2 +- .../award_emoji/base_votes_count_resolver.rb | 2 +- .../environments/last_deployment_resolver.rb | 2 +- .../resolvers/user_notes_count_resolver.rb | 2 +- app/helpers/merge_requests_helper.rb | 5 +- app/helpers/notifications_helper.rb | 2 +- .../json_schemas/build_metadata_secrets.json | 53 +++++ app/views/admin/topics/_topic.html.haml | 6 +- app/views/admin/topics/index.html.haml | 23 ++- app/views/dashboard/merge_requests.html.haml | 3 +- app/views/explore/topics/_head.html.haml | 2 +- app/views/shared/topics/_list.html.haml | 11 +- app/views/shared/topics/_topic.html.haml | 2 +- .../beta/mr_dashboard_list_type_toggle.yml | 9 - ...8182757_add_oid_to_lfs_objects_projects.rb | 23 +++ ...report_results_on_build_id_partition_id.rb | 17 ++ ...report_results_on_partition_id_build_id.rb | 17 ++ ...dd_index_of_oid_to_lfs_objects_projects.rb | 17 ++ db/schema_migrations/20250528182757 | 1 + db/schema_migrations/20250529231801 | 1 + db/schema_migrations/20250529232931 | 1 + db/schema_migrations/20250602222636 | 1 + db/structure.sql | 6 +- .../banzai_pipeline_and_parsing.md | 4 +- doc/solutions/components/oss_license_check.md | 2 +- doc/solutions/components/secret_detection.md | 2 +- .../application_security/policies/_index.md | 178 +---------------- .../merge_request_approval_policies.md | 6 +- .../policies/pipeline_execution_policies.md | 2 +- .../policies/scan_execution_policies.md | 2 +- .../policies/security_policy_projects.md | 182 ++++++++++++++++++ doc/user/compliance/compliance_pipelines.md | 2 +- .../compliance/license_approval_policies.md | 2 +- lib/banzai/filter/autolink_filter.rb | 2 +- lib/banzai/filter/code_language_filter.rb | 6 +- lib/banzai/filter/gollum_tags_filter.rb | 4 +- lib/banzai/filter/markdown_engines/cmark.rb | 51 ----- lib/banzai/filter/markdown_filter.rb | 1 - .../hll_redis_legacy_events.yml | 1 + spec/benchmarks/banzai_benchmark.rb | 16 +- .../components/app_spec.js | 22 +-- .../components/config_dropdown_spec.js | 33 ++-- .../lib/banzai/filter/autolink_filter_spec.rb | 2 +- .../banzai/filter/gollum_tags_filter_spec.rb | 4 - .../filter/markdown_engines/cmark_spec.rb | 17 -- .../lib/banzai/filter/markdown_filter_spec.rb | 4 +- spec/lib/gitlab/asciidoc_spec.rb | 52 ++--- 63 files changed, 441 insertions(+), 445 deletions(-) delete mode 100644 config/feature_flags/beta/mr_dashboard_list_type_toggle.yml create mode 100644 db/migrate/20250528182757_add_oid_to_lfs_objects_projects.rb create mode 100644 db/post_migrate/20250529231801_async_add_index_ci_build_report_results_on_build_id_partition_id.rb create mode 100644 db/post_migrate/20250529232931_async_remove_index_ci_build_report_results_on_partition_id_build_id.rb create mode 100644 db/post_migrate/20250602222636_add_index_of_oid_to_lfs_objects_projects.rb create mode 100644 db/schema_migrations/20250528182757 create mode 100644 db/schema_migrations/20250529231801 create mode 100644 db/schema_migrations/20250529232931 create mode 100644 db/schema_migrations/20250602222636 create mode 100644 doc/user/application_security/policies/security_policy_projects.md delete mode 100644 lib/banzai/filter/markdown_engines/cmark.rb delete mode 100644 spec/lib/banzai/filter/markdown_engines/cmark_spec.rb diff --git a/.rubocop_todo/lint/symbol_conversion.yml b/.rubocop_todo/lint/symbol_conversion.yml index 4db76a734ad..3c8a03f86b3 100644 --- a/.rubocop_todo/lint/symbol_conversion.yml +++ b/.rubocop_todo/lint/symbol_conversion.yml @@ -2,16 +2,6 @@ # Cop supports --autocorrect. Lint/SymbolConversion: Exclude: - - 'app/controllers/groups_controller.rb' - - 'app/controllers/projects/issues_controller.rb' - - 'app/controllers/projects_controller.rb' - - 'app/controllers/uploads_controller.rb' - - 'app/graphql/mutations/members/bulk_update_base.rb' - - 'app/graphql/mutations/snippets/base.rb' - - 'app/graphql/resolvers/award_emoji/base_votes_count_resolver.rb' - - 'app/graphql/resolvers/environments/last_deployment_resolver.rb' - - 'app/graphql/resolvers/user_notes_count_resolver.rb' - - 'app/helpers/notifications_helper.rb' - 'app/helpers/projects_helper.rb' - 'app/models/application_record.rb' - 'app/models/concerns/cache_markdown_field.rb' diff --git a/Gemfile b/Gemfile index f13a51dd03c..55a4eac9e55 100644 --- a/Gemfile +++ b/Gemfile @@ -257,7 +257,6 @@ gem 'gitlab-active-context', path: 'gems/gitlab-active-context', require: 'activ gem 'html-pipeline', '~> 2.14.3', feature_category: :markdown gem 'deckar01-task_list', '2.3.4', feature_category: :markdown gem 'gitlab-markup', '~> 2.0.0', require: 'github/markup', feature_category: :markdown -gem 'commonmarker', '~> 0.23.10', feature_category: :markdown gem 'kramdown', '~> 2.5.0', feature_category: :markdown gem 'RedCloth', '~> 4.3.3', feature_category: :markdown gem 'org-ruby', '~> 0.9.12', feature_category: :markdown diff --git a/Gemfile.checksum b/Gemfile.checksum index 17aab0e24b1..c7e0da61e7d 100644 --- a/Gemfile.checksum +++ b/Gemfile.checksum @@ -447,7 +447,7 @@ {"name":"observer","version":"0.1.2","platform":"ruby","checksum":"d8a3107131ba661138d748e7be3dbafc0d82e732fffba9fccb3d7829880950ac"}, {"name":"octokit","version":"9.2.0","platform":"ruby","checksum":"4fa47ff35ce654127edf2c836ab9269bcc8829f5542dc1e86871f697ce7f4316"}, {"name":"ohai","version":"18.1.18","platform":"ruby","checksum":"42ee8196945cb935fdeec93ba7aaee757d1d552f7b933912a1f25863c3cc1ff0"}, -{"name":"oj","version":"3.16.10","platform":"ruby","checksum":"7f26bed974e331e16d579b470b0865010757f6fe6ee30ea9b67df653fbe13d7c"}, +{"name":"oj","version":"3.16.11","platform":"ruby","checksum":"2aab609d2bc896529bd3c70d737f591c13932a640ba6164a0f7e414efdb052b1"}, {"name":"oj-introspect","version":"0.8.0","platform":"ruby","checksum":"5cbb15309d60294881e5c2f65ceb22e3b5798f26d0a1e65ae47a6342b87d9264"}, {"name":"omniauth","version":"2.1.2","platform":"ruby","checksum":"def03277298b8f8a5d3ff16cdb2eb5edb9bffed60ee7dda24cc0c89b3ae6a0ce"}, {"name":"omniauth-alicloud","version":"3.0.0","platform":"ruby","checksum":"9c5c4f3abb40d774b946015f177d503fbde99b2b57c0858284c25cc39369013e"}, diff --git a/Gemfile.lock b/Gemfile.lock index 158cda234d0..a8f31c94743 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1264,7 +1264,7 @@ GEM plist (~> 3.1) train-core wmi-lite (~> 1.0) - oj (3.16.10) + oj (3.16.11) bigdecimal (>= 3.0) ostruct (>= 0.2) oj-introspect (0.8.0) @@ -2099,7 +2099,6 @@ DEPENDENCIES circuitbox (= 2.0.0) click_house-client! cloud_profiler_agent (~> 0.0.0)! - commonmarker (~> 0.23.10) concurrent-ruby (~> 1.1) connection_pool (~> 2.5.3) countries (~> 4.0.0) diff --git a/Gemfile.next.checksum b/Gemfile.next.checksum index 78b9481ff84..f7bbfb90cd1 100644 --- a/Gemfile.next.checksum +++ b/Gemfile.next.checksum @@ -447,7 +447,7 @@ {"name":"observer","version":"0.1.2","platform":"ruby","checksum":"d8a3107131ba661138d748e7be3dbafc0d82e732fffba9fccb3d7829880950ac"}, {"name":"octokit","version":"9.2.0","platform":"ruby","checksum":"4fa47ff35ce654127edf2c836ab9269bcc8829f5542dc1e86871f697ce7f4316"}, {"name":"ohai","version":"18.1.18","platform":"ruby","checksum":"42ee8196945cb935fdeec93ba7aaee757d1d552f7b933912a1f25863c3cc1ff0"}, -{"name":"oj","version":"3.16.10","platform":"ruby","checksum":"7f26bed974e331e16d579b470b0865010757f6fe6ee30ea9b67df653fbe13d7c"}, +{"name":"oj","version":"3.16.11","platform":"ruby","checksum":"2aab609d2bc896529bd3c70d737f591c13932a640ba6164a0f7e414efdb052b1"}, {"name":"oj-introspect","version":"0.8.0","platform":"ruby","checksum":"5cbb15309d60294881e5c2f65ceb22e3b5798f26d0a1e65ae47a6342b87d9264"}, {"name":"omniauth","version":"2.1.2","platform":"ruby","checksum":"def03277298b8f8a5d3ff16cdb2eb5edb9bffed60ee7dda24cc0c89b3ae6a0ce"}, {"name":"omniauth-alicloud","version":"3.0.0","platform":"ruby","checksum":"9c5c4f3abb40d774b946015f177d503fbde99b2b57c0858284c25cc39369013e"}, diff --git a/Gemfile.next.lock b/Gemfile.next.lock index cd463d916f2..b0a0ac271d5 100644 --- a/Gemfile.next.lock +++ b/Gemfile.next.lock @@ -1258,7 +1258,7 @@ GEM plist (~> 3.1) train-core wmi-lite (~> 1.0) - oj (3.16.10) + oj (3.16.11) bigdecimal (>= 3.0) ostruct (>= 0.2) oj-introspect (0.8.0) @@ -2094,7 +2094,6 @@ DEPENDENCIES circuitbox (= 2.0.0) click_house-client! cloud_profiler_agent (~> 0.0.0)! - commonmarker (~> 0.23.10) concurrent-ruby (~> 1.1) connection_pool (~> 2.5.3) countries (~> 4.0.0) diff --git a/app/assets/javascripts/admin/topics/components/merge_topics.vue b/app/assets/javascripts/admin/topics/components/merge_topics.vue index 0cc3f97b725..d98332054ce 100644 --- a/app/assets/javascripts/admin/topics/components/merge_topics.vue +++ b/app/assets/javascripts/admin/topics/components/merge_topics.vue @@ -86,7 +86,7 @@ export default { - + - - diff --git a/app/assets/javascripts/merge_request_dashboard/index.js b/app/assets/javascripts/merge_request_dashboard/index.js index 8737aa55e6c..47dc19f8a4a 100644 --- a/app/assets/javascripts/merge_request_dashboard/index.js +++ b/app/assets/javascripts/merge_request_dashboard/index.js @@ -2,7 +2,6 @@ import { concatPagination } from '@apollo/client/utilities'; import Vue from 'vue'; import VueApollo from 'vue-apollo'; import VueRouter from 'vue-router'; -import { parseBoolean } from '~/lib/utils/common_utils'; import { TYPENAME_USER } from '~/graphql_shared/constants'; import { convertToGraphQLId } from '~/graphql_shared/utils'; import createDefaultClient from '~/lib/graphql'; @@ -104,9 +103,6 @@ export function initMergeRequestDashboard(el) { new Vue({ el: document.getElementById('js-merge-request-dashboard-config'), apolloProvider, - provide: { - listTypeToggleEnabled: parseBoolean(el.dataset.listTypeToggleEnabled), - }, render(h) { return h(ConfigDropdown); }, @@ -118,7 +114,6 @@ export function initMergeRequestDashboard(el) { apolloProvider, provide: { mergeRequestsSearchDashboardPath: el.dataset.mergeRequestsSearchDashboardPath, - listTypeToggleEnabled: parseBoolean(el.dataset.listTypeToggleEnabled), }, render(createElement) { return createElement(App, { diff --git a/app/assets/stylesheets/framework/typography.scss b/app/assets/stylesheets/framework/typography.scss index 7a1c0d824a3..391ce83009e 100644 --- a/app/assets/stylesheets/framework/typography.scss +++ b/app/assets/stylesheets/framework/typography.scss @@ -114,6 +114,12 @@ @include str-highlighted; } + // the z-index of the mark is set to -1, so it's below the table cells + // unless they have their own stacking context + td:has(mark), th:has(mark) { + isolation: isolate; + } + // Fixed headings are default for markdown h1 { @apply gl-heading-1-fixed gl-mt-7 gl-pb-2 gl-border-b; diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index efb540176d4..330b5313668 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -364,7 +364,7 @@ class GroupsController < Groups::ApplicationController end def check_export_rate_limit! - prefixed_action = "group_#{params[:action]}".to_sym + prefixed_action = :"group_#{params[:action]}" scope = params[:action] == :download_export ? @group : nil diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index fedb4681515..b491a7e6177 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -438,7 +438,7 @@ class Projects::IssuesController < Projects::ApplicationController errors: result.errors, http_status: result.http_status ) - error_method_name = "render_#{result.http_status}".to_sym + error_method_name = :"render_#{result.http_status}" if respond_to?(error_method_name, true) send(error_method_name) # rubocop:disable GitlabSecurity/PublicSend diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 271a1748133..0af999cdb10 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -636,7 +636,7 @@ class ProjectsController < Projects::ApplicationController end def check_export_rate_limit! - prefixed_action = "project_#{params[:action]}".to_sym + prefixed_action = :"project_#{params[:action]}" project_scope = params[:action] == 'download_export' ? @project : nil diff --git a/app/controllers/uploads_controller.rb b/app/controllers/uploads_controller.rb index 94e114e7da8..f53b67c9835 100644 --- a/app/controllers/uploads_controller.rb +++ b/app/controllers/uploads_controller.rb @@ -69,7 +69,7 @@ class UploadsController < ApplicationController when Organizations::OrganizationDetail can?(current_user, :read_organization, model.organization) else - can?(current_user, "read_#{model.class.underscore}".to_sym, model) + can?(current_user, :"read_#{model.class.underscore}", model) end end diff --git a/app/graphql/mutations/members/bulk_update_base.rb b/app/graphql/mutations/members/bulk_update_base.rb index 0a54597f6c6..e6da24e2491 100644 --- a/app/graphql/mutations/members/bulk_update_base.rb +++ b/app/graphql/mutations/members/bulk_update_base.rb @@ -68,11 +68,11 @@ module Mutations end def source_id_param_name - "#{source_name}_id".to_sym + :"#{source_name}_id" end def source_members_key - "#{source_name}_members".to_sym + :"#{source_name}_members" end def source_name diff --git a/app/graphql/mutations/snippets/base.rb b/app/graphql/mutations/snippets/base.rb index 57f7083e137..d7221a9b373 100644 --- a/app/graphql/mutations/snippets/base.rb +++ b/app/graphql/mutations/snippets/base.rb @@ -17,7 +17,7 @@ module Mutations end def ability_for(snippet) - "#{ability_name}_#{snippet.to_ability_name}".to_sym + :"#{ability_name}_#{snippet.to_ability_name}" end def ability_name diff --git a/app/graphql/resolvers/award_emoji/base_votes_count_resolver.rb b/app/graphql/resolvers/award_emoji/base_votes_count_resolver.rb index 406c52eb0d5..2d49f6c6810 100644 --- a/app/graphql/resolvers/award_emoji/base_votes_count_resolver.rb +++ b/app/graphql/resolvers/award_emoji/base_votes_count_resolver.rb @@ -10,7 +10,7 @@ module Resolvers private def authorized_resource?(object) - Ability.allowed?(current_user, "read_#{object.to_ability_name}".to_sym, object) + Ability.allowed?(current_user, :"read_#{object.to_ability_name}", object) end def votes_batch_loader diff --git a/app/graphql/resolvers/environments/last_deployment_resolver.rb b/app/graphql/resolvers/environments/last_deployment_resolver.rb index 9a66a9cba7b..bc04b4c82b2 100644 --- a/app/graphql/resolvers/environments/last_deployment_resolver.rb +++ b/app/graphql/resolvers/environments/last_deployment_resolver.rb @@ -22,7 +22,7 @@ module Resolvers def find_last_deployment(status) BatchLoader::GraphQL.for(object).batch(key: status) do |environments, loader, args| - association_name = "last_#{args[:key]}_deployment".to_sym + association_name = :"last_#{args[:key]}_deployment" Preloaders::Environments::DeploymentPreloader.new(environments) .execute_with_union(association_name, {}) diff --git a/app/graphql/resolvers/user_notes_count_resolver.rb b/app/graphql/resolvers/user_notes_count_resolver.rb index a67f71c4de6..880550db948 100644 --- a/app/graphql/resolvers/user_notes_count_resolver.rb +++ b/app/graphql/resolvers/user_notes_count_resolver.rb @@ -13,7 +13,7 @@ module Resolvers end def authorized_resource?(object) - ability = "read_#{object.class.name.underscore}".to_sym + ability = :"read_#{object.class.name.underscore}" Ability.allowed?(context[:current_user], ability, object) end diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb index 5a7eb8c7c81..8c7e9e7f563 100644 --- a/app/helpers/merge_requests_helper.rb +++ b/app/helpers/merge_requests_helper.rb @@ -566,10 +566,7 @@ module MergeRequestsHelper is_author_or_assignee = ::Feature.enabled?(:merge_request_dashboard_author_or_assignee, current_user, type: :gitlab_com_derisk) - if Feature.enabled?(:mr_dashboard_list_type_toggle, current_user, type: :beta) && - current_user.merge_request_dashboard_list_type == 'role_based' - return merge_request_dashboard_role_based_data - end + return merge_request_dashboard_role_based_data if current_user.user_preference.role_based? { tabs: [ diff --git a/app/helpers/notifications_helper.rb b/app/helpers/notifications_helper.rb index b6e435986ce..a71649ff995 100644 --- a/app/helpers/notifications_helper.rb +++ b/app/helpers/notifications_helper.rb @@ -36,7 +36,7 @@ module NotificationsHelper end def show_unsubscribe_title?(noteable) - can?(current_user, "read_#{noteable.to_ability_name}".to_sym, noteable) + can?(current_user, :"read_#{noteable.to_ability_name}", noteable) end def can_read_project?(project) diff --git a/app/validators/json_schemas/build_metadata_secrets.json b/app/validators/json_schemas/build_metadata_secrets.json index f9122ff811c..74ca6db612a 100644 --- a/app/validators/json_schemas/build_metadata_secrets.json +++ b/app/validators/json_schemas/build_metadata_secrets.json @@ -87,6 +87,54 @@ }, "additionalProperties": false }, + "^aws_secrets_manager$": { + "type": "object", + "required": [ + "secret_id" + ], + "properties": { + "secret_id": { + "type": "string" + }, + "version_id": { + "type": [ + "string", + "null" + ] + }, + "version_stage": { + "type": [ + "string", + "null" + ] + }, + "region": { + "type": [ + "string", + "null" + ] + }, + "role_arn": { + "type": [ + "string", + "null" + ] + }, + "role_session_name": { + "type": [ + "string", + "null" + ] + }, + "field": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + }, "^akeyless$": { "type": "object", "properties": { @@ -215,6 +263,11 @@ "required": [ "gitlab_secrets_manager" ] + }, + { + "required": [ + "aws_secrets_manager" + ] } ], "additionalProperties": false diff --git a/app/views/admin/topics/_topic.html.haml b/app/views/admin/topics/_topic.html.haml index bdc57a84d50..22b934909bd 100644 --- a/app/views/admin/topics/_topic.html.haml +++ b/app/views/admin/topics/_topic.html.haml @@ -1,7 +1,7 @@ - topic = local_assigns.fetch(:topic) - title = topic.title || topic.name -%li.topic-row.gl-py-3.gl-items-center{ class: '!gl-flex !gl-px-5' } +%li.gl-items-center{ class: '!gl-flex' } = render Pajamas::AvatarComponent.new(topic, size: 32, alt: '') .gl-min-w-0.gl-grow.gl-ml-3 @@ -17,5 +17,5 @@ = number_with_delimiter(topic.total_projects_count) .gl-shrink-0.gl-ml-5.gl-flex.gl-gap-3 - = link_button_to _('Edit'), edit_admin_topic_path(topic), id: "edit_#{dom_id(topic)}" - = link_button_to _('Remove'), admin_topic_path(topic), aria: { label: _('Remove') }, data: { confirm: _("Are you sure you want to remove %{topic_name}?") % { topic_name: title }, confirm_btn_variant: 'danger' }, method: :delete, variant: :danger + = render Pajamas::ButtonComponent.new(category: :tertiary, href: edit_admin_topic_path(topic), icon: 'pencil', button_options: { id: "edit_#{dom_id(topic)}", class: 'has-tooltip', 'title': _('Edit'), 'aria-label': _('Edit') }) + = render Pajamas::ButtonComponent.new(category: :tertiary, href: admin_topic_path(topic), method: :delete, icon: 'remove', button_options: { class: 'has-tooltip', 'title': _('Remove'), 'aria-label': _('Remove'), data: { confirm: _("Are you sure you want to remove %{topic_name}?") % { topic_name: title }, confirm_btn_variant: 'danger' } }) diff --git a/app/views/admin/topics/index.html.haml b/app/views/admin/topics/index.html.haml index 7033f3c5b33..3cb751b0d66 100644 --- a/app/views/admin/topics/index.html.haml +++ b/app/views/admin/topics/index.html.haml @@ -7,13 +7,9 @@ - if show_empty_state = render 'shared/empty_states/topics', button_text: _('New topic'), button_path: new_admin_topic_path - else - = render ::Layouts::PageHeadingComponent.new(_('Topics'), options: { data: { event_tracking_load: 'true', event_tracking: 'view_admin_topics_pageload' } }) do |c| - - c.with_actions do - .js-merge-topics{ data: { path: merge_admin_topics_path } } - = render Pajamas::ButtonComponent.new(href: new_admin_topic_path, variant: 'confirm') do - = _('New topic') + = render ::Layouts::PageHeadingComponent.new(_('Topics'), options: { data: { event_tracking_load: 'true', event_tracking: 'view_admin_topics_pageload' } }) - .gl-flex.gl-min-w-0.gl-grow.row-content-block + .gl-flex.gl-min-w-0.gl-grow = form_tag admin_topics_path, method: :get, class: 'gl-w-full' do |f| - search = params.fetch(:search, nil) .search-field-holder @@ -23,6 +19,15 @@ - if show_empty_search = render ::Layouts::EmptyResultComponent.new(type: :search) - else - %ul.content-list - = render partial: 'topic', collection: @topics - = paginate_collection @topics + = render ::Layouts::CrudComponent.new(_('Topics'), + icon: 'overview', + count: @topics.count, + options: { class: 'gl-mt-5' }) do |c| + - c.with_actions do + .js-merge-topics{ data: { path: merge_admin_topics_path } } + = render Pajamas::ButtonComponent.new(href: new_admin_topic_path, variant: 'confirm', size: 'small') do + = _('New topic') + - c.with_body do + %ul.content-list + = render partial: 'topic', collection: @topics + = paginate_collection @topics diff --git a/app/views/dashboard/merge_requests.html.haml b/app/views/dashboard/merge_requests.html.haml index c8c9feffb02..8d146b5519e 100644 --- a/app/views/dashboard/merge_requests.html.haml +++ b/app/views/dashboard/merge_requests.html.haml @@ -34,8 +34,7 @@ base_path: merge_requests_dashboard_path, merge_requests_search_dashboard_path: merge_requests_search_dashboard_path(assignee_username: current_user.username), initial_data: merge_request_dashboard_data.to_json, - list_type: current_user.merge_request_dashboard_list_type, - list_type_toggle_enabled: Feature.enabled?(:mr_dashboard_list_type_toggle, current_user, type: :beta).to_s + list_type: current_user.merge_request_dashboard_list_type } } - if !merge_request_dashboard_enabled?(current_user) || current_page?(merge_requests_search_dashboard_path) diff --git a/app/views/explore/topics/_head.html.haml b/app/views/explore/topics/_head.html.haml index 0291bcb8668..5ce6d50ccbb 100644 --- a/app/views/explore/topics/_head.html.haml +++ b/app/views/explore/topics/_head.html.haml @@ -1,4 +1,4 @@ = render ::Layouts::PageHeadingComponent.new(page_title) -.gl-flex.gl-min-w-0.gl-grow.row-content-block +.gl-flex.gl-min-w-0.gl-grow = render 'shared/topics/search_form' diff --git a/app/views/shared/topics/_list.html.haml b/app/views/shared/topics/_list.html.haml index 7e7be162e6b..20e90d0ef7c 100644 --- a/app/views/shared/topics/_list.html.haml +++ b/app/views/shared/topics/_list.html.haml @@ -5,6 +5,11 @@ - if show_empty_search = render ::Layouts::EmptyResultComponent.new(type: :search) - else - %ul.content-list - = render partial: 'shared/topics/topic', collection: @topics - = paginate_collection @topics, remote: remote + = render ::Layouts::CrudComponent.new(_('Topics'), + icon: 'overview', + count: @topics.count, + options: { class: 'gl-mt-5' }) do |c| + - c.with_body do + %ul.content-list + = render partial: 'shared/topics/topic', collection: @topics + = paginate_collection @topics, remote: remote diff --git a/app/views/shared/topics/_topic.html.haml b/app/views/shared/topics/_topic.html.haml index e0ed06985d0..5e5291b8510 100644 --- a/app/views/shared/topics/_topic.html.haml +++ b/app/views/shared/topics/_topic.html.haml @@ -1,7 +1,7 @@ - max_topic_title_length = 30 - detail_page_link = topic_explore_projects_cleaned_path(topic_name: topic.name) -%li.topic-row.gl-py-3.gl-items-center{ class: '!gl-flex !gl-px-5' } +%li.gl-items-center{ class: '!gl-flex' } = render Pajamas::AvatarComponent.new(topic, size: 32, alt: '') .gl-min-w-0.gl-grow.gl-ml-3 diff --git a/config/feature_flags/beta/mr_dashboard_list_type_toggle.yml b/config/feature_flags/beta/mr_dashboard_list_type_toggle.yml deleted file mode 100644 index 3299a3e9ae3..00000000000 --- a/config/feature_flags/beta/mr_dashboard_list_type_toggle.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -name: mr_dashboard_list_type_toggle -feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/519717 -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/183805 -rollout_issue_url: -milestone: '17.11' -group: group::code review -type: beta -default_enabled: false diff --git a/db/migrate/20250528182757_add_oid_to_lfs_objects_projects.rb b/db/migrate/20250528182757_add_oid_to_lfs_objects_projects.rb new file mode 100644 index 00000000000..e9947eb9759 --- /dev/null +++ b/db/migrate/20250528182757_add_oid_to_lfs_objects_projects.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +class AddOidToLfsObjectsProjects < Gitlab::Database::Migration[2.3] + disable_ddl_transaction! + + milestone '18.1' + + SOURCE_TABLE = :lfs_objects_projects + + def up + with_lock_retries do + add_column SOURCE_TABLE, :oid, :text, if_not_exists: true + end + + add_text_limit SOURCE_TABLE, :oid, 255 + end + + def down + with_lock_retries do + remove_column SOURCE_TABLE, :oid, if_exists: true + end + end +end diff --git a/db/post_migrate/20250529231801_async_add_index_ci_build_report_results_on_build_id_partition_id.rb b/db/post_migrate/20250529231801_async_add_index_ci_build_report_results_on_build_id_partition_id.rb new file mode 100644 index 00000000000..d12d97b40e2 --- /dev/null +++ b/db/post_migrate/20250529231801_async_add_index_ci_build_report_results_on_build_id_partition_id.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +class AsyncAddIndexCiBuildReportResultsOnBuildIdPartitionId < Gitlab::Database::Migration[2.3] + milestone '18.1' + + TABLE_NAME = :ci_build_report_results + INDEX_NAME = :index_ci_build_report_results_on_build_id_partition_id + COLUMNS = [:build_id, :partition_id] + + def up + prepare_async_index TABLE_NAME, COLUMNS, unique: true, name: INDEX_NAME + end + + def down + unprepare_async_index TABLE_NAME, COLUMNS, name: INDEX_NAME + end +end diff --git a/db/post_migrate/20250529232931_async_remove_index_ci_build_report_results_on_partition_id_build_id.rb b/db/post_migrate/20250529232931_async_remove_index_ci_build_report_results_on_partition_id_build_id.rb new file mode 100644 index 00000000000..d741c2f7149 --- /dev/null +++ b/db/post_migrate/20250529232931_async_remove_index_ci_build_report_results_on_partition_id_build_id.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +class AsyncRemoveIndexCiBuildReportResultsOnPartitionIdBuildId < Gitlab::Database::Migration[2.3] + milestone '18.1' + + TABLE_NAME = :ci_build_report_results + INDEX_NAME = :index_ci_build_report_results_on_partition_id_build_id + COLUMNS = [:partition_id, :build_id] + + def up + prepare_async_index_removal TABLE_NAME, COLUMNS, name: INDEX_NAME + end + + def down + unprepare_async_index TABLE_NAME, COLUMNS, name: INDEX_NAME + end +end diff --git a/db/post_migrate/20250602222636_add_index_of_oid_to_lfs_objects_projects.rb b/db/post_migrate/20250602222636_add_index_of_oid_to_lfs_objects_projects.rb new file mode 100644 index 00000000000..3c1580d9f6a --- /dev/null +++ b/db/post_migrate/20250602222636_add_index_of_oid_to_lfs_objects_projects.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +class AddIndexOfOidToLfsObjectsProjects < Gitlab::Database::Migration[2.3] + disable_ddl_transaction! + + milestone '18.1' + + INDEX_NAME = 'index_lfs_objects_projects_on_oid' + + def up + add_concurrent_index :lfs_objects_projects, :oid, name: INDEX_NAME + end + + def down + remove_concurrent_index :lfs_objects_projects, :oid, name: INDEX_NAME + end +end diff --git a/db/schema_migrations/20250528182757 b/db/schema_migrations/20250528182757 new file mode 100644 index 00000000000..08f7551b581 --- /dev/null +++ b/db/schema_migrations/20250528182757 @@ -0,0 +1 @@ +dc035d87698c43babf8f8093c49edbc684c6f840a5457d0405c9498b5f174e70 \ No newline at end of file diff --git a/db/schema_migrations/20250529231801 b/db/schema_migrations/20250529231801 new file mode 100644 index 00000000000..64d338a5fac --- /dev/null +++ b/db/schema_migrations/20250529231801 @@ -0,0 +1 @@ +07392d9229e61122a4aa4264811246740a40c0d5039d7c99018829bd34f69329 \ No newline at end of file diff --git a/db/schema_migrations/20250529232931 b/db/schema_migrations/20250529232931 new file mode 100644 index 00000000000..e05a6a5edc5 --- /dev/null +++ b/db/schema_migrations/20250529232931 @@ -0,0 +1 @@ +ffbd42a63d4a4c08b8e74257d865e3ddcc2f40e43cbf4a898e069be90fff2462 \ No newline at end of file diff --git a/db/schema_migrations/20250602222636 b/db/schema_migrations/20250602222636 new file mode 100644 index 00000000000..1de440d98a0 --- /dev/null +++ b/db/schema_migrations/20250602222636 @@ -0,0 +1 @@ +e94d4888d721b88a874b095c08aac988e3ac1f501586417379cba65ad9bb984b \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index c635972ad43..51fc8fe5443 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -16723,7 +16723,9 @@ CREATE TABLE lfs_objects_projects ( project_id bigint NOT NULL, created_at timestamp without time zone, updated_at timestamp without time zone, - repository_type smallint + repository_type smallint, + oid text, + CONSTRAINT check_76ef4585ad CHECK ((char_length(oid) <= 255)) ); CREATE SEQUENCE lfs_objects_projects_id_seq @@ -35814,6 +35816,8 @@ CREATE UNIQUE INDEX index_lfs_objects_on_oid ON lfs_objects USING btree (oid); CREATE INDEX index_lfs_objects_projects_on_lfs_object_id ON lfs_objects_projects USING btree (lfs_object_id); +CREATE INDEX index_lfs_objects_projects_on_oid ON lfs_objects_projects USING btree (oid); + CREATE INDEX index_lfs_objects_projects_on_project_id_and_lfs_object_id ON lfs_objects_projects USING btree (project_id, lfs_object_id); CREATE INDEX index_list_user_preferences_on_list_id ON list_user_preferences USING btree (list_id); diff --git a/doc/development/gitlab_flavored_markdown/banzai_pipeline_and_parsing.md b/doc/development/gitlab_flavored_markdown/banzai_pipeline_and_parsing.md index 5cef90f0cd1..797bd964f23 100644 --- a/doc/development/gitlab_flavored_markdown/banzai_pipeline_and_parsing.md +++ b/doc/development/gitlab_flavored_markdown/banzai_pipeline_and_parsing.md @@ -41,9 +41,7 @@ This pipeline contains the filters for transforming raw Markdown into HTML, hand #### `Filter::MarkdownFilter` -This filter interfaces with the actual Markdown parser. The primary parser uses our [`gitlab-glfm-markdown`](https://gitlab.com/gitlab-org/ruby/gems/gitlab-glfm-markdown) Ruby gem that uses the [`comrak`](https://github.com/kivikakk/comrak) Rust crate. - -A secondary deprecated parser engine uses the [`commonmarker`](https://github.com/gjtorikian/commonmarker/releases/tag/v0.23.11) Ruby gem to interact with the [`cmark-gfm`](https://github.com/github/cmark-gfm) library. +This filter interfaces with the actual Markdown parser. The parser uses our [`gitlab-glfm-markdown`](https://gitlab.com/gitlab-org/ruby/gems/gitlab-glfm-markdown) Ruby gem that uses the [`comrak`](https://github.com/kivikakk/comrak) Rust crate. Text is passed into this filter, and by calling the specified parser engine, generates the corresponding basic HTML. diff --git a/doc/solutions/components/oss_license_check.md b/doc/solutions/components/oss_license_check.md index 75e20933995..8bcc012faba 100644 --- a/doc/solutions/components/oss_license_check.md +++ b/doc/solutions/components/oss_license_check.md @@ -401,7 +401,7 @@ This ensures your policy always reflects the most current Blue Oak Council licen ### Policy not applying -Ensure the security policy project you modified is correctly linked to your group. See [Link to a security policy project](../../user/application_security/policies/_index.md#link-to-a-security-policy-project) for more. +Ensure the security policy project you modified is correctly linked to your group. See [Link to a security policy project](../../user/application_security/policies/security_policy_projects.md#link-to-a-security-policy-project) for more. ### Dependency scan not running diff --git a/doc/solutions/components/secret_detection.md b/doc/solutions/components/secret_detection.md index b810614ecf7..701cf3039da 100644 --- a/doc/solutions/components/secret_detection.md +++ b/doc/solutions/components/secret_detection.md @@ -161,4 +161,4 @@ An example password in clear is shown below: ### Policy not applying -Ensure the security policy project you modified is correctly linked to your group. See [Link to a security policy project](../../user/application_security/policies/_index.md#link-to-a-security-policy-project) for more. +Ensure the security policy project you modified is correctly linked to your group. See [Link to a security policy project](../../user/application_security/policies/security_policy_projects.md#link-to-a-security-policy-project) for more. diff --git a/doc/user/application_security/policies/_index.md b/doc/user/application_security/policies/_index.md index a4b777de17b..a65fef347a6 100644 --- a/doc/user/application_security/policies/_index.md +++ b/doc/user/application_security/policies/_index.md @@ -41,42 +41,7 @@ The following policy types are available: - [Vulnerability management policy](vulnerability_management_policy.md). Automatically resolve vulnerabilities that are no longer detected in the default branch. -## Security policy project - -A security policy project is a special type of project used only to contain policies. The -policies are stored in the `.gitlab/security-policies/policy.yml` YAML file. - -To enforce the policies contained in a security policy project, link the security policy -project to the projects, subgroups, or groups you want to enforce the policies on. -A security policy project can contain multiple policies but they are -enforced together. A security policy project enforced on a group or subgroup applies to everything -below in the hierarchy, including all subgroups and their projects. - -Policy changes made in a merge request take effect as soon as the merge request is merged. Those -that do not go through a merge request, but instead are committed directly to the default branch, -may require up to 10 minutes before the policy changes take effect. - -## Deleting security policy projects - -{{< history >}} - -- The deletion protection for security policy projects was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/482967) in GitLab 17.8 [with a flag](../../../administration/feature_flags.md) named `reject_security_policy_project_deletion`. Enabled by default. -- The deletion protection for groups that contain security policy projects was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/512043) in GitLab 17.9 [with a flag](../../../administration/feature_flags.md) named `reject_security_policy_project_deletion_groups`. Enabled by default. -- The deletion protection for security policy projects is generally available in GitLab 17.10. Feature flag `reject_security_policy_project_deletion` removed. -- The deletion protection for groups that contain security policy projects is generally available in GitLab 17.10. Feature flag `reject_security_policy_project_deletion_groups` removed. - -{{< /history >}} - -{{< alert type="flag" >}} - -The availability of this feature is controlled by a feature flag. -For more information, see the history. - -{{< /alert >}} - -To delete a security policy project or one of its parent groups, you must remove the link to it -from all other projects or groups. Otherwise, an error message is displayed when you attempt -to delete a linked security policy project or a parent group. +To enforce policies across multiple projects, use [security policy projects](security_policy_projects.md). A security policy project is a special type of project used only to contain policies. To enforce the policies from a security policy project in other groups and projects, link to the security policy project from groups or other projects. ## Policy design guidelines @@ -280,147 +245,6 @@ If you're not a group member, you may face limitations in adding or editing poli {{< /alert >}} -## Policy implementation - -Implementation options for security policy projects differ slightly between GitLab.com, GitLab -Dedicated, and GitLab Self-Managed. The main difference is that on GitLab.com it's only possible to -create subgroups. Ensuring separation of duties requires more granular permission configuration. - -### Enforce policies globally in your GitLab.com namespace - -{{< details >}} - -- Tier: Ultimate -- Offering: GitLab.com - -{{< /details >}} - -Prerequisites: - -- You must have the Owner role or [custom role](../../custom_roles/_index.md) with the - `manage_security_policy_link` permission to link to the security policy project. For more - information, see [separation of duties](#separation-of-duties). - -The high-level workflow for enforcing policies globally across all subgroups and projects in your GitLab.com namespace: - -1. Visit the **Policies** tab from your top-level group. -1. In the subgroup, go to the **Policies** tab and create a test policy. - - (Tip: You can create a policy as disabled for testing.) Creating the policy automatically creates - a new security policy project under your top-level group. This project is used to store your - `policy.yml` or policy-as-code. -1. Check and set permissions in the newly created project as desired. - - By default, Owners and Maintainers are able to create, edit, and delete policies. Developers can - propose policy changes but cannot merge them. -1. In the security policy project created within your subgroup, create the policies required. - - You can use the policy editor in the `Security Policy Management` project you created, under the - **Policies** tab. Or you can directly update the policies in the `policy.yml` file stored in the - newly-created security policy project `Security Policy Management - security policy project`. -1. Link up groups, subgroups, or projects to the security policy project. - - As a subgroup owner, or project owner with proper permissions, you can visit the **Policies** - page and create a link to the security policy project. Include the full path and the project's - name should end with "- security policy project". All linked groups, subgroups, and projects - become "enforceable" by any policies created in the security policy project. For details, see - [Link to a security policy project](#link-to-a-security-policy-project). -1. By default, when a policy is enabled, it is enforced on all projects in linked groups, - subgroups, and projects. - - For more granular enforcement, add a "policy scope". Policy scopes allow you to enforce policies - against a specific set of projects or against projects containing a given set of compliance - framework labels. -1. If you need additional restrictions, for example to block inherited permissions or require - additional review or approval of policy changes, you can create an additional policy scoped only - to your security policy project and enforce additional approvals. - -### Enforce policies globally in GitLab Dedicated or GitLab Self-Managed - -{{< details >}} - -- Tier: Ultimate -- Offering: GitLab Self-Managed, GitLab Dedicated - -{{< /details >}} - -Prerequisites: - -- You must have the Owner role or [custom role](../../custom_roles/_index.md) with the - `manage_security_policy_link` permission to link to the security policy project. For more - information, see [separation of duties](#separation-of-duties). -- To support approval groups globally across your instance, enable - `security_policy_global_group_approvers_enabled` in your - [GitLab instance application settings](../../../api/settings.md). - -The high-level workflow for enforcing policies across multiple groups: - -1. Create a separate group to contain your policies and ensure separation of duties. - - By creating a separate standalone group, you can minimize the number of users who inherit - permissions. -1. In the new group, visit the **Policies** tab. - - This serves as the primary location of the policy editor, allowing you to - create and manage policies in the UI. -1. Create a test policy (you can create a policy as disabled for testing). - - Creating the policy automatically creates a new security policy project under your group. This - project is used to store your `policy.yml` or policy-as-code. -1. Check and set permissions in the newly created project as desired. - - By default, Owners and Maintainers are able to create, edit, and delete policies. Developers can - propose policy changes but cannot merge them. -1. In the security policy project created in your subgroup, create the policies required. - - You can use the policy editor in the `Security Policy Management` project you created, under the - Policies tab. Or you can directly update the policies in the `policy.yml` file stored in the - newly-created security policy project `Security Policy Management - security policy project`. -1. Link up groups, subgroups, or projects to the security policy project. - - As a subgroup owner, or project owner with proper permissions, you can visit the **Policies** - page and create a link to the security policy project. Include the full path and the project's - name should end with "-security policy project". All linked groups, subgroups, and projects - become "enforceable" by any policies created in the security policy project. For more information, see - [link to a security policy project](#link-to-a-security-policy-project). -1. By default, when a policy is enabled, it is enforced on all projects in linked groups, subgroups, - and projects. For more granular enforcement, add a policy scope. Policy scopes allow you to - enforce policies against a specific set of projects or against projects containing a given set of - compliance framework labels. -1. If you need additional restrictions, for example to block inherited permissions or require - additional review or approval of policy changes, you can create an additional policy scoped only - to your security policy project and enforce additional approvals. - -## Link to a security policy project - -To enforce the policies contained in a security policy project against a group, subgroup, or -project, you link them. By default, all linked entities are enforced. To enforce policies -granularly per policy, you can set a "policy scope" in each policy. - -Prerequisites: - -- You must have the Owner role or [custom role](../../custom_roles/_index.md) with the`manage_security_policy_link` permission to link to the security policy project. For more information, see [separation of duties](#separation-of-duties). -- You must have at least the Reporter role or [custom role](../../custom_roles/_index.md) with the `manage_security_policy_link` permission to the project you want to assign as the security policy project. For more information, see [separation of duties](#separation-of-duties). - -To link a group, subgroup, or project to a security policy project: - -1. On the left sidebar, select **Search or go to** and find your project, subgroup, or group. -1. Select **Secure > Policies**. -1. Select **Edit Policy Project**, then search for and select the project you would like to link - from the dropdown list. -1. Select **Save**. - -To unlink a security policy project, follow the same steps but instead select the trash can icon in -the dialog. -You can link to a security policy project from a different subgroup in the same top-level group, or from an entirely different top-level group. -However, when you enforce a -[pipeline execution policy](pipeline_execution_policies.md#pipeline-execution-policy-schema), users must have at least read-only access to the project that contains the CI/CD configuration referenced in the policy to trigger the pipeline. - -### Viewing the linked security policy project - -All users who have access to the project policy page and are not project owners instead view a -button linking out to the associated security policy project. - ## Policy recommendations When implementing policies, consider the following recommendations. diff --git a/doc/user/application_security/policies/merge_request_approval_policies.md b/doc/user/application_security/policies/merge_request_approval_policies.md index 3247109885e..373254ea155 100644 --- a/doc/user/application_security/policies/merge_request_approval_policies.md +++ b/doc/user/application_security/policies/merge_request_approval_policies.md @@ -450,7 +450,7 @@ The availability of support for pipeline execution policies is controlled by a f #### Example of `policy_tuning` with a scan execution policy You can use this example in a `.gitlab/security-policies/policy.yml` file stored in a -[security policy project](_index.md#security-policy-project): +[security policy project](security_policy_projects.md): ```yaml scan_execution_policy: @@ -504,7 +504,7 @@ For more information, see [Recreate pipeline execution policies created before G {{< /alert >}} You can use this example in a `.gitlab/security-policies/policy.yml` file stored in a -[security policy project](_index.md#security-policy-project): +[security policy project](security_policy_projects.md): ```yaml --- @@ -559,7 +559,7 @@ specified projects, groups, or compliance framework labels. For more details, se ## Example `policy.yml` in a security policy project You can use this example in a `.gitlab/security-policies/policy.yml` file stored in a -[security policy project](_index.md#security-policy-project): +[security policy project](security_policy_projects.md): ```yaml --- diff --git a/doc/user/application_security/policies/pipeline_execution_policies.md b/doc/user/application_security/policies/pipeline_execution_policies.md index 74c7a7423b5..dba8f74bb61 100644 --- a/doc/user/application_security/policies/pipeline_execution_policies.md +++ b/doc/user/application_security/policies/pipeline_execution_policies.md @@ -815,7 +815,7 @@ These examples demonstrate what you can achieve with pipeline execution policies ### Pipeline execution policy You can use the following example in a `.gitlab/security-policies/policy.yml` file stored in a -[security policy project](_index.md#security-policy-project): +[security policy project](security_policy_projects.md): ```yaml --- diff --git a/doc/user/application_security/policies/scan_execution_policies.md b/doc/user/application_security/policies/scan_execution_policies.md index 368c90b8b19..23974e03dcf 100644 --- a/doc/user/application_security/policies/scan_execution_policies.md +++ b/doc/user/application_security/policies/scan_execution_policies.md @@ -469,7 +469,7 @@ specified projects, groups, or compliance framework labels. For more details, se ## Example security policy project You can use this example in a `.gitlab/security-policies/policy.yml` file stored in a -[security policy project](_index.md#security-policy-project): +[security policy project](security_policy_projects.md): ```yaml --- diff --git a/doc/user/application_security/policies/security_policy_projects.md b/doc/user/application_security/policies/security_policy_projects.md new file mode 100644 index 00000000000..b5888efdfa4 --- /dev/null +++ b/doc/user/application_security/policies/security_policy_projects.md @@ -0,0 +1,182 @@ +--- +stage: Security Risk Management +group: Security Policies +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments +description: Learn how to enforce security rules in GitLab using merge request approval policies to automate scans, approvals, and compliance across your projects. +title: Security policy projects +--- + +{{< details >}} + +- Tier: Ultimate +- Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated + +{{< /details >}} + +Security policy projects enforce policies across multiple projects. A security policy project is a +special type of project used only to contain policies. To enforce the policies contained in a +security policy project, link the security policy project to the projects, subgroups, or groups +you want to enforce the policies on. A security policy project can contain multiple policies but they are +enforced together. A security policy project enforced on a group or subgroup applies to everything +below in the hierarchy, including all subgroups and their projects. + +Policy changes made in a merge request take effect as soon as the merge request is merged. Those +that do not go through a merge request, but instead are committed directly to the default branch, +may require up to 10 minutes before the policy changes take effect. + +Policies are stored in the `.gitlab/security-policies/policy.yml` YAML file. + +## Security policy project implementation + +Implementation options for security policy projects differ slightly between GitLab.com, GitLab +Dedicated, and GitLab Self-Managed. The main difference is that on GitLab.com it's only possible to +create subgroups. Ensuring separation of duties requires more granular permission configuration. + +### Enforce policies globally in your GitLab.com namespace + +{{< details >}} + +- Tier: Ultimate +- Offering: GitLab.com + +{{< /details >}} + +Prerequisites: + +- You must have the Owner role or a [custom role](../../custom_roles/_index.md) with the + `manage_security_policy_link` permission to link to the security policy project. For more + information, see [separation of duties](_index.md#separation-of-duties). + +The high-level workflow for enforcing policies globally across all subgroups and projects in your GitLab.com namespace: + +1. Visit the **Policies** tab from your top-level group. +1. In the subgroup, go to the **Policies** tab and create a test policy. + + You can create a policy as disabled for testing. Creating the policy automatically creates + a new security policy project under your top-level group. This project is used to store your + `policy.yml` or policy-as-code. +1. Check and set permissions in the newly created project as desired. + + By default, Owners and Maintainers are able to create, edit, and delete policies. Developers can + propose policy changes but cannot merge them. +1. In the security policy project created within your subgroup, create the policies required. + + You can use the policy editor in the `Security Policy Management` project you created, under the + **Policies** tab. Or you can directly update the policies in the `policy.yml` file stored in the + newly-created security policy project `Security Policy Management - security policy project`. +1. Link up groups, subgroups, or projects to the security policy project. + + As a subgroup owner, or project owner with proper permissions, you can visit the **Policies** + page and create a link to the security policy project. Include the full path and the project's + name should end with "- security policy project". All linked groups, subgroups, and projects + become "enforceable" by any policies created in the security policy project. For details, see + [Link to a security policy project](#link-to-a-security-policy-project). +1. By default, when a policy is enabled, it is enforced on all projects in linked groups, + subgroups, and projects. + + For more granular enforcement, add a policy scope. A policy scope allow you to enforce policies + against a specific set of projects or against projects containing a set of compliance + framework labels. +1. If you need additional restrictions, for example to block inherited permissions or require + additional review or approval of policy changes, you can create an additional policy scoped only + to your security policy project and enforce additional approvals. + +### Enforce policies globally in GitLab Dedicated or GitLab Self-Managed + +{{< details >}} + +- Tier: Ultimate +- Offering: GitLab Self-Managed, GitLab Dedicated + +{{< /details >}} + +Prerequisites: + +- You must have the Owner role or a [custom role](../../custom_roles/_index.md) with the + `manage_security_policy_link` permission to link to the security policy project. For more + information, see [separation of duties](_index.md#separation-of-duties). +- To support approval groups globally across your instance, enable + `security_policy_global_group_approvers_enabled` in your + [GitLab instance application settings](../../../api/settings.md). + +The high-level workflow for enforcing policies across multiple groups: + +1. Create a separate group to contain your policies and ensure separation of duties. + + By creating a separate standalone group, you can minimize the number of users who inherit + permissions. +1. In the new group, visit the **Policies** tab. + + This serves as the primary location of the policy editor, allowing you to + create and manage policies in the UI. +1. Create a test policy (you can create a policy as disabled for testing). + + Creating the policy automatically creates a new security policy project under your group. This + project is used to store your `policy.yml` or policy-as-code. +1. Check and set permissions in the newly created project as desired. + + By default, Owners and Maintainers are able to create, edit, and delete policies. Developers can + propose policy changes but cannot merge them. +1. In the security policy project created in your subgroup, create the policies required. + + You can use the policy editor in the `Security Policy Management` project you created, under the + Policies tab. Or you can directly update the policies in the `policy.yml` file stored in the + newly-created security policy project `Security Policy Management - security policy project`. +1. Link up groups, subgroups, or projects to the security policy project. + + As a subgroup owner, or project owner with proper permissions, you can visit the **Policies** + page and create a link to the security policy project. Include the full path and the project's + name should end with "- security policy project". All linked groups, subgroups, and projects + become "enforceable" by any policies created in the security policy project. For more information, see + [link to a security policy project](#link-to-a-security-policy-project). +1. By default, when a policy is enabled, it is enforced on all projects in linked groups, subgroups, + and projects. For more granular enforcement, add a policy scope. A policy scope allows you to + enforce policies against a specific set of projects or against projects that contain a set of + compliance framework labels. +1. If you need additional restrictions, for example to block inherited permissions or require + additional review or approval of policy changes, you can create an additional policy scoped only + to your security policy project and enforce additional approvals. + +## Link to a security policy project + +To enforce the policies contained in a security policy project against a group, subgroup, or +project, you link them. By default, all linked entities are enforced. To enforce policies +granularly per policy, you can set a policy scope in each policy. + +Prerequisites: + +- You must have the Owner role or [custom role](../../custom_roles/_index.md) with the`manage_security_policy_link` permission to link to the security policy project. For more information, see [separation of duties](_index.md#separation-of-duties). +- You must have at least the Reporter role or [custom role](../../custom_roles/_index.md) with the `manage_security_policy_link` permission to the project you want to assign as the security policy project. For more information, see [separation of duties](_index.md#separation-of-duties). + +To link a group, subgroup, or project to a security policy project: + +1. On the left sidebar, select **Search or go to** and find your project, subgroup, or group. +1. Select **Secure > Policies**. +1. Select **Edit Policy Project**, then search for and select the project you would like to link + from the dropdown list. +1. Select **Save**. + +To unlink a security policy project, follow the same steps but instead select the trash can icon in +the dialog. +You can link to a security policy project from a different subgroup in the same top-level group, or from an entirely different top-level group. +However, when you enforce a +[pipeline execution policy](pipeline_execution_policies.md#pipeline-execution-policy-schema), users must have at least read-only access to the project that contains the CI/CD configuration referenced in the policy to trigger the pipeline. + +### Viewing the linked security policy project + +All users who have access to the project policy page and are not project owners instead view a +button linking out to the associated security policy project. + +## Deleting a security policy project + +{{< history >}} + +- Deletion protection for security policy projects was introduced in GitLab 17.8 with a flag named `reject_security_policy_project_deletion`. Enabled by default. +- Deletion protection for groups that contain security policy projects was introduced in GitLab 17.9 with a flag named `reject_security_policy_project_deletion_groups`. Enabled by default. +- Deletion protection for security policy projects and groups that contain security policy projects is generally available in GitLab 17.10. Feature flags `reject_security_policy_project_deletion` and `reject_security_policy_project_deletion_groups` removed. + +{{< /history >}} + +To delete a security policy project or one of its parent groups, you must remove the link to it +from all other projects or groups. Otherwise, an error message is displayed when you attempt +to delete a linked security policy project or a parent group. diff --git a/doc/user/compliance/compliance_pipelines.md b/doc/user/compliance/compliance_pipelines.md index 87b9e6d988b..14791f2858c 100644 --- a/doc/user/compliance/compliance_pipelines.md +++ b/doc/user/compliance/compliance_pipelines.md @@ -70,7 +70,7 @@ To migrate an existing compliance framework to use the pipeline execution policy 1. In the banner than appears, select **Migrate pipeline to a policy** to create a new policy in the security policies. 1. Edit the compliance framework again to remove the compliance pipeline. -For more information, see [Security policy project](../application_security/policies/_index.md#security-policy-project). +For more information, see [Security policy project](../application_security/policies/security_policy_projects.md). If you receive a `Pipeline execution policy error: Job names must be unique` error during the migration, see the [relevant troubleshooting information](#error-job-names-must-be-unique). diff --git a/doc/user/compliance/license_approval_policies.md b/doc/user/compliance/license_approval_policies.md index 35ab25a8ffc..75abca8d081 100644 --- a/doc/user/compliance/license_approval_policies.md +++ b/doc/user/compliance/license_approval_policies.md @@ -53,7 +53,7 @@ Create a license approval policy to enforce license compliance. To create a license approval policy: -1. [Link a security policy project](../application_security/policies/_index.md#policy-implementation) to your development group, subgroup, or project (the Owner role is required). +1. [Link a security policy project](../application_security/policies/security_policy_projects.md#link-to-a-security-policy-project) to your development group, subgroup, or project (the Owner role is required). 1. On the left sidebar, select **Search or go to** and find your project. 1. Select **Secure > Policies**. 1. Create a new [Merge request approval Policy](../application_security/policies/merge_request_approval_policies.md). diff --git a/lib/banzai/filter/autolink_filter.rb b/lib/banzai/filter/autolink_filter.rb index 8b2399ab3d2..53dfea2f704 100644 --- a/lib/banzai/filter/autolink_filter.rb +++ b/lib/banzai/filter/autolink_filter.rb @@ -124,7 +124,7 @@ module Banzai end # Since this came from a Text node, make sure the new href is encoded. - # `commonmarker` percent encodes the domains of links it handles, so + # Markdown renderer percent encodes the domains of links it handles, so # do the same (instead of using `normalized_encode`). begin href_safe = Addressable::URI.encode(match).html_safe diff --git a/lib/banzai/filter/code_language_filter.rb b/lib/banzai/filter/code_language_filter.rb index 37994d0e707..d30fd6c43b9 100644 --- a/lib/banzai/filter/code_language_filter.rb +++ b/lib/banzai/filter/code_language_filter.rb @@ -41,14 +41,14 @@ module Banzai pre_node.set_attribute(LANG_ATTR, escape_once(lang)) if lang.present? pre_node.set_attribute(LANG_PARAMS_ATTR, escape_once(lang_params)) if lang_params.present? - # cmark-gfm added this, it's now in data-lang-params + # markdown rendered added this, it's now in data-lang-params pre_node.remove_attribute('data-meta') code_node.remove_attribute('data-meta') end private - # cmark-gfm's FULL_INFO_STRING render option works with the space delimiter. + # the `full_info_string` render option works with the space delimiter. # Which means the language specified on a code block is parsed with spaces. Anything # after the first space is placed in the `data-meta` attribute. # However GitLab recognizes `:` as an additional delimiter on the lang attribute. @@ -67,7 +67,7 @@ module Banzai language, language_params = language.split(LANG_PARAMS_DELIMITER, 2) - # cmark-gfm places extra lang parameters into data-meta + # markdown renderer places extra lang parameters into data-meta language_params = [pre_node.attr('data-meta'), code_node.attr('data-meta'), language_params].compact.join(' ') [language, language_params] diff --git a/lib/banzai/filter/gollum_tags_filter.rb b/lib/banzai/filter/gollum_tags_filter.rb index 6aad2613c86..0899bacffdf 100644 --- a/lib/banzai/filter/gollum_tags_filter.rb +++ b/lib/banzai/filter/gollum_tags_filter.rb @@ -3,7 +3,7 @@ module Banzai module Filter # HTML Filter for parsing Gollum's tags in HTML. - # Only used for the ascii_doc pipeline or the older cmark parser. + # Only used for the ascii_doc pipeline. # # It's only parses the following tags: # @@ -35,7 +35,7 @@ module Banzai IGNORED_ANCESTOR_TAGS = %w[pre code tt].to_set def call - return doc if MarkdownFilter.glfm_markdown?(context) && context[:pipeline] != :ascii_doc + return doc if context[:pipeline] != :ascii_doc doc.xpath('descendant-or-self::text()').each do |node| next if has_ancestor?(node, IGNORED_ANCESTOR_TAGS) diff --git a/lib/banzai/filter/markdown_engines/cmark.rb b/lib/banzai/filter/markdown_engines/cmark.rb deleted file mode 100644 index abcfd9149d6..00000000000 --- a/lib/banzai/filter/markdown_engines/cmark.rb +++ /dev/null @@ -1,51 +0,0 @@ -# frozen_string_literal: true - -# `CommonMark` markdown engine for GitLab's Banzai markdown filter. -# This module is used in Banzai::Filter::MarkdownFilter. -# Used gem is `commonmarker` which is a ruby wrapper for cmark-gfm (CommonMark parser) -# including GitHub's GFM extensions. -# We now utilize the renderer built in `C`, rather than the ruby based renderer. -# Homepage: https://github.com/gjtorikian/commonmarker -# -# Although this engine is currently not actively used, let's keep it here -# for performance testing and as a backup. -module Banzai - module Filter - module MarkdownEngines - class Cmark < Base - EXTENSIONS = [ - :autolink, # provides support for automatically converting URLs to anchor tags. - :strikethrough, # provides support for strikethroughs. - :table # provides support for tables. - ].freeze - - PARSE_OPTIONS = [ - :FOOTNOTES, # parse footnotes. - :STRIKETHROUGH_DOUBLE_TILDE, # parse strikethroughs by double tildes (as redcarpet does). - :VALIDATE_UTF8 # replace illegal sequences with the replacement character U+FFFD. - ].freeze - - RENDER_OPTIONS = [ - :GITHUB_PRE_LANG, # use GitHub-style
 for fenced code blocks.
-          :FOOTNOTES,        # render footnotes.
-          :FULL_INFO_STRING, # include full info strings of code blocks in separate attribute.
-          :UNSAFE            # allow raw/custom HTML and unsafe links.
-        ].freeze
-
-        RENDER_OPTIONS_SOURCEPOS = RENDER_OPTIONS + [:SOURCEPOS].freeze
-
-        def render(text)
-          CommonMarker.render_html(text, render_options, EXTENSIONS)
-        end
-
-        private
-
-        def render_options
-          sourcepos_disabled? ? RENDER_OPTIONS : RENDER_OPTIONS_SOURCEPOS
-        end
-      end
-    end
-  end
-end
-
-Banzai::Filter::MarkdownEngines::Cmark.prepend_mod
diff --git a/lib/banzai/filter/markdown_filter.rb b/lib/banzai/filter/markdown_filter.rb
index 7b4a8f31836..e6827d5d1c2 100644
--- a/lib/banzai/filter/markdown_filter.rb
+++ b/lib/banzai/filter/markdown_filter.rb
@@ -4,7 +4,6 @@ module Banzai
   module Filter
     class MarkdownFilter < HTML::Pipeline::TextFilter
       GLFM_ENGINE    = :glfm_markdown # glfm_markdown/comrak
-      CMARK_ENGINE   = :cmark         # original commonmarker/cmark-gfm
       DEFAULT_ENGINE = GLFM_ENGINE
 
       def initialize(text, context = nil, result = nil)
diff --git a/lib/gitlab/usage_data_counters/hll_redis_legacy_events.yml b/lib/gitlab/usage_data_counters/hll_redis_legacy_events.yml
index e12b15f6d39..bf0b377c1df 100644
--- a/lib/gitlab/usage_data_counters/hll_redis_legacy_events.yml
+++ b/lib/gitlab/usage_data_counters/hll_redis_legacy_events.yml
@@ -43,6 +43,7 @@
 - i_ci_secrets_management_id_tokens_build_created
 - i_ci_secrets_management_vault_build_created
 - i_ci_secrets_management_gitlab_secrets_manager_build_created
+- i_ci_secrets_management_aws_secrets_manager_build_created
 - i_code_review_click_diff_view_setting
 - i_code_review_click_file_browser_setting
 - i_code_review_click_single_file_mode_setting
diff --git a/spec/benchmarks/banzai_benchmark.rb b/spec/benchmarks/banzai_benchmark.rb
index 79948f725a7..f46c9ac7e8f 100644
--- a/spec/benchmarks/banzai_benchmark.rb
+++ b/spec/benchmarks/banzai_benchmark.rb
@@ -34,7 +34,6 @@ RSpec.describe 'GitLab Markdown Benchmark', :aggregate_failures, feature_categor
   let_it_be(:wiki_page)     { feature.wiki_page }
   let_it_be(:markdown_text) { feature.raw_markdown }
   let_it_be(:glfm_engine)   { Banzai::Filter::MarkdownFilter::GLFM_ENGINE }
-  let_it_be(:cmark_engine)  { Banzai::Filter::MarkdownFilter::CMARK_ENGINE }
   let_it_be(:grafana_integration) { create(:grafana_integration, project: project) }
   let_it_be(:default_context) do
     {
@@ -85,33 +84,31 @@ RSpec.describe 'GitLab Markdown Benchmark', :aggregate_failures, feature_categor
 
   context 'markdown engines' do
     it 'benchmarks full pipeline using different markdown engines' do
-      puts "\n--> Benchmarking FullPipeline with Cmark and Glfm engines\n"
+      puts "\n--> Benchmarking FullPipeline with Glfm engine\n"
 
       Benchmark.ips do |x|
         x.config(time: 10, warmup: 2)
 
         x.report('glfm') { Banzai::Pipeline::FullPipeline.call(markdown_text, context.merge(markdown_engine: glfm_engine)) }
-        x.report('cmark') { Banzai::Pipeline::FullPipeline.call(markdown_text, context.merge(markdown_engine: cmark_engine)) }
 
         x.compare!
       end
     end
 
     it 'benchmarks plain markdown pipeline using different markdown engines' do
-      puts "\n--> Benchmarking PlainMarkdownPipeline with Cmark and Glfm engines\n"
+      puts "\n--> Benchmarking PlainMarkdownPipeline with Glfm engine\n"
 
       Benchmark.ips do |x|
         x.config(time: 10, warmup: 2)
 
         x.report('glfm') { Banzai::Pipeline::PlainMarkdownPipeline.call(markdown_text, context.merge(markdown_engine: glfm_engine)) }
-        x.report('cmark') { Banzai::Pipeline::PlainMarkdownPipeline.call(markdown_text, context.merge(markdown_engine: cmark_engine)) }
 
         x.compare!
       end
     end
 
     it 'benchmarks MarkdownFilter using different markdown engines' do
-      puts "\n--> Benchmarking MarkdownFilter with Cmark and Glfm engines\n"
+      puts "\n--> Benchmarking MarkdownFilter with Glfm engine\n"
 
       pipeline      = Banzai::Pipeline[:plain_markdown]
       filter_klass  = Banzai::Filter::MarkdownFilter
@@ -127,13 +124,6 @@ RSpec.describe 'GitLab Markdown Benchmark', :aggregate_failures, feature_categor
           filter.call
         end
 
-        x.report('Markdown-cmark') do
-          filter = filter_klass.new(filter_source[filter_klass][:input_text],
-            context.merge(markdown_engine: cmark_engine),
-            filter_source[filter_klass][:input_result])
-          filter.call
-        end
-
         x.compare!
       end
     end
diff --git a/spec/frontend/merge_request_dashboard/components/app_spec.js b/spec/frontend/merge_request_dashboard/components/app_spec.js
index dd79a4248b4..99de86a21a6 100644
--- a/spec/frontend/merge_request_dashboard/components/app_spec.js
+++ b/spec/frontend/merge_request_dashboard/components/app_spec.js
@@ -25,13 +25,12 @@ describe('Merge requests app component', () => {
   const findMergeRequests = () => wrapper.findAllComponents(MergeRequest);
   const findLoadMoreButton = () => wrapper.findByTestId('load-more');
   const findCountExplanation = () => wrapper.findByTestId('merge-request-count-explanation');
-  const findFeedbackLink = () => wrapper.findAllComponents(GlLink).at(0);
 
   const $router = {
     push: jest.fn(),
   };
 
-  function createComponent(lists = null, listTypeToggleEnabled = false) {
+  function createComponent(lists = null) {
     subscriptionHandler = createMockSubscription();
     assigneeQueryMock = jest.fn().mockResolvedValue({
       data: {
@@ -106,7 +105,6 @@ describe('Merge requests app component', () => {
       },
       provide: {
         mergeRequestsSearchDashboardPath: '/search',
-        listTypeToggleEnabled,
       },
       stubs: {
         MergeRequestsQuery,
@@ -260,22 +258,4 @@ describe('Merge requests app component', () => {
       );
     });
   });
-
-  describe('feedback link', () => {
-    it('shows the default feedback link when feature flag is off', async () => {
-      createComponent();
-      await waitForPromises();
-      expect(findFeedbackLink().attributes('href')).toBe(
-        'https://gitlab.com/gitlab-org/gitlab/-/issues/515912',
-      );
-    });
-
-    it('shows the new feedback link when feature flag is on', async () => {
-      createComponent(null, { listTypeToggleEnabled: true });
-      await waitForPromises();
-      expect(findFeedbackLink().attributes('href')).toBe(
-        'https://gitlab.com/gitlab-org/gitlab/-/issues/542823',
-      );
-    });
-  });
 });
diff --git a/spec/frontend/merge_request_dashboard/components/config_dropdown_spec.js b/spec/frontend/merge_request_dashboard/components/config_dropdown_spec.js
index da8eeb3b165..dc86311e140 100644
--- a/spec/frontend/merge_request_dashboard/components/config_dropdown_spec.js
+++ b/spec/frontend/merge_request_dashboard/components/config_dropdown_spec.js
@@ -24,11 +24,7 @@ describe('Merge request dashboard config dropdown component', () => {
   const findPopover = () => wrapper.findComponent(GlPopover);
   const { bindInternalEventDocument } = useMockInternalEventsTracking();
 
-  function createComponent({
-    isShowingLabels = false,
-    listTypeToggleEnabled = false,
-    shouldShowCallout = true,
-  } = {}) {
+  function createComponent({ isShowingLabels = false, shouldShowCallout = true } = {}) {
     setIsShowingLabelsMutationMock = jest.fn();
     updatePreferencesMutationMock = jest.fn().mockResolvedValue({
       data: {
@@ -70,7 +66,6 @@ describe('Merge request dashboard config dropdown component', () => {
 
     wrapper = shallowMountExtended(ConfigDropdown, {
       apolloProvider,
-      provide: { listTypeToggleEnabled },
       stubs: {
         UserCalloutDismisser: makeMockUserCalloutDismisser({
           dismiss: userCalloutDismissSpy,
@@ -207,25 +202,23 @@ describe('Merge request dashboard config dropdown component', () => {
     },
   );
 
-  describe('when listTypeToggleEnabled is true', () => {
-    it('displays explanation popover when shouldShowCallout is true', () => {
-      createComponent({ listTypeToggleEnabled: true, shouldShowCallout: true });
+  it('displays explanation popover when shouldShowCallout is true', () => {
+    createComponent({ shouldShowCallout: true });
 
-      expect(findPopover().exists()).toBe(true);
-    });
+    expect(findPopover().exists()).toBe(true);
+  });
 
-    it('does not display explanation popover when shouldShowCallout is false', () => {
-      createComponent({ listTypeToggleEnabled: true, shouldShowCallout: false });
+  it('does not display explanation popover when shouldShowCallout is false', () => {
+    createComponent({ shouldShowCallout: false });
 
-      expect(findPopover().exists()).toBe(false);
-    });
+    expect(findPopover().exists()).toBe(false);
+  });
 
-    it('calls dismiss method createComponent({ listTypeToggleEnabled: true, shouldShowCallout: true });when hiding popover', () => {
-      createComponent({ listTypeToggleEnabled: true, shouldShowCallout: true });
+  it('calls dismiss method when hiding popover', () => {
+    createComponent({ shouldShowCallout: true });
 
-      findPopover().vm.$emit('hidden');
+    findPopover().vm.$emit('hidden');
 
-      expect(userCalloutDismissSpy).toHaveBeenCalled();
-    });
+    expect(userCalloutDismissSpy).toHaveBeenCalled();
   });
 });
diff --git a/spec/lib/banzai/filter/autolink_filter_spec.rb b/spec/lib/banzai/filter/autolink_filter_spec.rb
index 5e7ceb21a9f..642ba99f5dd 100644
--- a/spec/lib/banzai/filter/autolink_filter_spec.rb
+++ b/spec/lib/banzai/filter/autolink_filter_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
 RSpec.describe Banzai::Filter::AutolinkFilter, feature_category: :markdown do
   include FilterSpecHelper
 
-  let_it_be(:context) { { markdown_engine: Banzai::Filter::MarkdownFilter::CMARK_ENGINE } }
+  let_it_be(:context) { { pipeline: :single_line } }
 
   let(:link) { 'http://about.gitlab.com/' }
   let(:quotes) { ['"', "'"] }
diff --git a/spec/lib/banzai/filter/gollum_tags_filter_spec.rb b/spec/lib/banzai/filter/gollum_tags_filter_spec.rb
index 1f581f9b2d4..10f6fbe89b8 100644
--- a/spec/lib/banzai/filter/gollum_tags_filter_spec.rb
+++ b/spec/lib/banzai/filter/gollum_tags_filter_spec.rb
@@ -83,10 +83,6 @@ RSpec.describe Banzai::Filter::GollumTagsFilter, feature_category: :wiki do
     end
   end
 
-  it_behaves_like 'gollum tag parsing' do
-    let_it_be(:context) { { markdown_engine: Banzai::Filter::MarkdownFilter::CMARK_ENGINE } }
-  end
-
   it_behaves_like 'gollum tag parsing' do
     let_it_be(:context) { { pipeline: :ascii_doc } }
   end
diff --git a/spec/lib/banzai/filter/markdown_engines/cmark_spec.rb b/spec/lib/banzai/filter/markdown_engines/cmark_spec.rb
deleted file mode 100644
index ad562e0ebb1..00000000000
--- a/spec/lib/banzai/filter/markdown_engines/cmark_spec.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Banzai::Filter::MarkdownEngines::Cmark, feature_category: :markdown do
-  it 'defaults to generating sourcepos' do
-    engine = described_class.new({})
-
-    expect(engine.render('# hi')).to eq %(

hi

\n) - end - - it 'turns off sourcepos' do - engine = described_class.new({ no_sourcepos: true }) - - expect(engine.render('# hi')).to eq %(

hi

\n) - end -end diff --git a/spec/lib/banzai/filter/markdown_filter_spec.rb b/spec/lib/banzai/filter/markdown_filter_spec.rb index 69ca6452623..99e22c77661 100644 --- a/spec/lib/banzai/filter/markdown_filter_spec.rb +++ b/spec/lib/banzai/filter/markdown_filter_spec.rb @@ -8,8 +8,8 @@ RSpec.describe Banzai::Filter::MarkdownFilter, feature_category: :markdown do describe 'markdown engine from context' do it 'finds the correct engine' do - expect(described_class.new('foo', { markdown_engine: :cmark }).render_engine) - .to eq Banzai::Filter::MarkdownEngines::Cmark + expect(described_class.new('foo', { markdown_engine: :glfm_markdown }).render_engine) + .to eq Banzai::Filter::MarkdownEngines::GlfmMarkdown end it 'defaults to the GLFM_ENGINE' do diff --git a/spec/lib/gitlab/asciidoc_spec.rb b/spec/lib/gitlab/asciidoc_spec.rb index 292d327a88b..49916f3685b 100644 --- a/spec/lib/gitlab/asciidoc_spec.rb +++ b/spec/lib/gitlab/asciidoc_spec.rb @@ -72,43 +72,49 @@ module Gitlab items = { 'link with extra attribute' => { input: 'link:mylink"onmouseover="alert(1)[Click Here]', - output: "
\n

Click Here

\n
" + output: <<~HTML +
+

Click Here

+
+ HTML }, 'link with unsafe scheme' => { input: 'link:data://danger[Click Here]', - output: "
\n

Click Here

\n
" + output: <<~HTML +
+

Click Here

+
+ HTML }, 'image with onerror' => { input: 'image:https://localhost.com/image.png[Alt text" onerror="alert(7)]', - output: "
\n

Alt text\" onerror=\"alert(7)

\n
" + output: <<~HTML +
+

Alt text" onerror="alert(7)

+
+ HTML + }, + 'fenced code with inline script' => { + input: '```mypre">', + output: <<~HTML +
+
+
+
+ +
+
+
+ HTML } } items.each do |name, data| it "does not convert dangerous #{name} into HTML" do - expect(render(data[:input], context)).to include(data[:output]) + expect(render(data[:input], context)).to include(data[:output].strip) end end - # `stub_feature_flags method` runs AFTER declaration of `items` above. - # So the spec in its current implementation won't pass. - # Move this test back to the items hash when removing `use_cmark_renderer` feature flag. - it "does not convert dangerous fenced code with inline script into HTML" do - input = '```mypre">' - output = <<~HTML -
-
-
-
- -
-
-
- HTML - - expect(render(input, context)).to include(output.strip) - end - it 'does not allow locked attributes to be overridden' do input = <<~ADOC {counter:max-include-depth:1234}