From 3b1df712c7a15c9b6abadd61e9c8894fdeb0442a Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Thu, 1 Jun 2023 09:09:24 +0000 Subject: Add latest changes from gitlab-org/gitlab@master --- .rubocop_todo/rspec/context_wording.yml | 1 - .rubocop_todo/rspec/missing_feature_category.yml | 1 - GITLAB_SHELL_VERSION | 2 +- Gemfile | 2 +- Gemfile.checksum | 4 +- Gemfile.lock | 4 +- app/helpers/application_helper.rb | 15 ++- app/models/application_setting.rb | 37 ++++-- app/models/ci/pipeline.rb | 1 - app/models/plan_limits.rb | 4 +- app/views/projects/_files.html.haml | 3 +- app/views/projects/blob/_blob.html.haml | 3 +- .../projects/commit/_signature_badge.html.haml | 2 +- .../development/pipeline_trigger_merge_status.yml | 8 -- ...1_add_vertex_ai_host_to_application_settings.rb | 21 +++ ...ervice_desk_enabled_to_service_desk_settings.rb | 7 + db/migrate/20230530003417_rename_tofa_settings.rb | 21 +++ .../20230530003634_cleanup_tofa_settings.rb | 23 ++++ db/schema_migrations/20230524012641 | 1 + db/schema_migrations/20230525064706 | 1 + db/schema_migrations/20230530003417 | 1 + db/schema_migrations/20230530003634 | 1 + db/structure.sql | 11 +- doc/development/ai_features.md | 7 +- doc/development/code_review.md | 5 +- .../admin_area/settings/sign_in_restrictions.md | 12 +- doc/user/enterprise_user/index.md | 9 +- doc/user/project/import/github.md | 1 + .../common/pipelines/members_pipeline.rb | 2 +- .../transformers/member_attributes_transformer.rb | 51 ++++++++ .../transformers/member_attributes_transformer.rb | 51 -------- lib/gitlab/usage_data.rb | 10 +- locale/gitlab.pot | 24 +++- package.json | 2 +- .../admin/application_settings_controller_spec.rb | 2 +- .../admin/instance_review_controller_spec.rb | 2 +- spec/features/admin/admin_settings_spec.rb | 2 +- spec/helpers/application_helper_spec.rb | 23 ++++ .../member_attributes_transformer_spec.rb | 143 +++++++++++++++++++++ .../member_attributes_transformer_spec.rb | 128 ------------------ spec/lib/gitlab/usage_data_spec.rb | 8 -- .../menus/security_compliance_menu_spec.rb | 1 + spec/models/ci/pipeline_spec.rb | 8 -- spec/models/plan_limits_spec.rb | 4 +- .../api/usage_data_non_sql_metrics_spec.rb | 2 +- spec/requests/api/usage_data_queries_spec.rb | 2 +- .../gitlab/delete_tags_service_spec.rb | 2 +- spec/support/rspec_order_todo.yml | 1 - ...vice_ping_metrics_definitions_shared_context.rb | 3 +- ...omplete_service_ping_payload_shared_examples.rb | 2 +- spec/tasks/gitlab/usage_data_rake_spec.rb | 2 +- yarn.lock | 8 +- 52 files changed, 407 insertions(+), 284 deletions(-) delete mode 100644 config/feature_flags/development/pipeline_trigger_merge_status.yml create mode 100644 db/migrate/20230524012641_add_vertex_ai_host_to_application_settings.rb create mode 100644 db/migrate/20230525064706_add_service_desk_enabled_to_service_desk_settings.rb create mode 100644 db/migrate/20230530003417_rename_tofa_settings.rb create mode 100644 db/post_migrate/20230530003634_cleanup_tofa_settings.rb create mode 100644 db/schema_migrations/20230524012641 create mode 100644 db/schema_migrations/20230525064706 create mode 100644 db/schema_migrations/20230530003417 create mode 100644 db/schema_migrations/20230530003634 create mode 100644 lib/bulk_imports/common/transformers/member_attributes_transformer.rb delete mode 100644 lib/bulk_imports/groups/transformers/member_attributes_transformer.rb create mode 100644 spec/lib/bulk_imports/common/transformers/member_attributes_transformer_spec.rb delete mode 100644 spec/lib/bulk_imports/groups/transformers/member_attributes_transformer_spec.rb diff --git a/.rubocop_todo/rspec/context_wording.yml b/.rubocop_todo/rspec/context_wording.yml index 54b40a045a7..f6fbdd31463 100644 --- a/.rubocop_todo/rspec/context_wording.yml +++ b/.rubocop_todo/rspec/context_wording.yml @@ -1598,7 +1598,6 @@ RSpec/ContextWording: - 'spec/lib/bulk_imports/clients/http_spec.rb' - 'spec/lib/bulk_imports/common/pipelines/lfs_objects_pipeline_spec.rb' - 'spec/lib/bulk_imports/common/pipelines/milestones_pipeline_spec.rb' - - 'spec/lib/bulk_imports/groups/transformers/member_attributes_transformer_spec.rb' - 'spec/lib/bulk_imports/projects/pipelines/ci_pipelines_pipeline_spec.rb' - 'spec/lib/bulk_imports/projects/pipelines/issues_pipeline_spec.rb' - 'spec/lib/bulk_imports/projects/pipelines/merge_requests_pipeline_spec.rb' diff --git a/.rubocop_todo/rspec/missing_feature_category.yml b/.rubocop_todo/rspec/missing_feature_category.yml index cb0976bc516..a5cee560ef1 100644 --- a/.rubocop_todo/rspec/missing_feature_category.yml +++ b/.rubocop_todo/rspec/missing_feature_category.yml @@ -2803,7 +2803,6 @@ RSpec/MissingFeatureCategory: - 'spec/lib/bulk_imports/groups/pipelines/group_pipeline_spec.rb' - 'spec/lib/bulk_imports/groups/pipelines/namespace_settings_pipeline_spec.rb' - 'spec/lib/bulk_imports/groups/pipelines/subgroup_entities_pipeline_spec.rb' - - 'spec/lib/bulk_imports/groups/transformers/member_attributes_transformer_spec.rb' - 'spec/lib/bulk_imports/groups/transformers/subgroup_to_entity_transformer_spec.rb' - 'spec/lib/bulk_imports/network_error_spec.rb' - 'spec/lib/bulk_imports/pipeline/context_spec.rb' diff --git a/GITLAB_SHELL_VERSION b/GITLAB_SHELL_VERSION index 0edfba1c6f4..4dff17b159d 100644 --- a/GITLAB_SHELL_VERSION +++ b/GITLAB_SHELL_VERSION @@ -1 +1 @@ -14.21.0 +14.22.0 diff --git a/Gemfile b/Gemfile index 70cc3276a9d..3b8e8506416 100644 --- a/Gemfile +++ b/Gemfile @@ -210,7 +210,7 @@ gem 'rack', '~> 2.2.7' gem 'rack-timeout', '~> 0.6.3', require: 'rack/timeout/base' group :puma do - gem 'puma', '~> 6.2', require: false + gem 'puma', '~> 6.3', require: false gem 'sd_notify', '~> 0.1.0', require: false end diff --git a/Gemfile.checksum b/Gemfile.checksum index e2252689e1b..ba1e800812b 100644 --- a/Gemfile.checksum +++ b/Gemfile.checksum @@ -464,8 +464,8 @@ {"name":"pry-rails","version":"0.3.9","platform":"ruby","checksum":"468662575abb6b67f4a9831219f99290d5eae7bf186e64dd810d0a3e4a8cc4b1"}, {"name":"pry-shell","version":"0.6.1","platform":"ruby","checksum":"a99a6b3dffe4df274ea1751866816906861a23851f13346e10a8e8f61b53360c"}, {"name":"public_suffix","version":"5.0.0","platform":"ruby","checksum":"26ee4fbce33ada25eb117ac71f2c24bf4d8b3414ab6b34f05b4708a3e90f1c6b"}, -{"name":"puma","version":"6.2.2","platform":"java","checksum":"979623e8072876a1d44092f91dfaddf337be103323b321fe779adc92def7106a"}, -{"name":"puma","version":"6.2.2","platform":"ruby","checksum":"4503e79d1d9f13985a30928c72cd1518cebf1da5fcf720efd1aa21ef6795c479"}, +{"name":"puma","version":"6.3.0","platform":"java","checksum":"5e2ff95953608d1ba0350b80a3961a43e9bbb78ec60ebd5e4db1940c2921d5d8"}, +{"name":"puma","version":"6.3.0","platform":"ruby","checksum":"b0e35b4fe7ae440237a9ff1647c6bb252a1c0951ff356020670d2e62c1aeeeec"}, {"name":"pyu-ruby-sasl","version":"0.0.3.3","platform":"ruby","checksum":"5683a6bc5738db5a1bf5ceddeaf545405fb241b4184dd4f2587e679a7e9497e5"}, {"name":"raabro","version":"1.4.0","platform":"ruby","checksum":"d4fa9ff5172391edb92b242eed8be802d1934b1464061ae5e70d80962c5da882"}, {"name":"racc","version":"1.6.2","platform":"java","checksum":"0880781e7dfde09e665d0b6160b583e01ed52fcc2955d7891447d33c2d1d2cf1"}, diff --git a/Gemfile.lock b/Gemfile.lock index cd96633ac2f..3c0284593f0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1160,7 +1160,7 @@ GEM tty-markdown tty-prompt public_suffix (5.0.0) - puma (6.2.2) + puma (6.3.0) nio4r (~> 2.0) pyu-ruby-sasl (0.0.3.3) raabro (1.4.0) @@ -1863,7 +1863,7 @@ DEPENDENCIES pry-byebug pry-rails (~> 0.3.9) pry-shell (~> 0.6.1) - puma (~> 6.2) + puma (~> 6.3) rack (~> 2.2.7) rack-attack (~> 6.6.1) rack-cors (~> 1.1.1) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 71f8478544b..7f1c28de8a7 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -191,16 +191,17 @@ module ApplicationHelper } end - def edited_time_ago_with_tooltip(object, placement: 'top', html_class: 'time_ago', exclude_author: false) - return unless object.edited? + def edited_time_ago_with_tooltip(editable_object, placement: 'top', html_class: 'time_ago', exclude_author: false) + return unless editable_object.edited? content_tag :small, class: 'edited-text' do - output = content_tag(:span, 'Edited ') - output << time_ago_with_tooltip(object.last_edited_at, placement: placement, html_class: html_class) + timeago = time_ago_with_tooltip(editable_object.last_edited_at, placement: placement, html_class: html_class) - if !exclude_author && object.last_edited_by - output << content_tag(:span, ' by ') - output << link_to_member(object.project, object.last_edited_by, avatar: false, extra_class: 'gl-hover-text-decoration-underline', author_class: nil) + if !exclude_author && editable_object.last_edited_by + author_link = link_to_member(editable_object.project, editable_object.last_edited_by, avatar: false, extra_class: 'gl-hover-text-decoration-underline', author_class: nil) + output = safe_format(_("Edited %{timeago} by %{author}"), timeago: timeago, author: author_link) + else + output = safe_format(_("Edited %{timeago}"), timeago: timeago) end output diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb index 907d578eb37..4232e654d13 100644 --- a/app/models/application_setting.rb +++ b/app/models/application_setting.rb @@ -14,6 +14,31 @@ class ApplicationSetting < MainClusterwide::ApplicationRecord ignore_column :send_user_confirmation_email, remove_with: '15.8', remove_after: '2022-12-18' ignore_column :web_ide_clientside_preview_enabled, remove_with: '15.11', remove_after: '2023-04-22' ignore_columns %i[instance_administration_project_id instance_administrators_group_id], remove_with: '16.2', remove_after: '2023-06-22' + ignore_columns %i[ + encrypted_tofa_access_token_expires_in + encrypted_tofa_access_token_expires_in_iv + encrypted_tofa_client_library_args + encrypted_tofa_client_library_args_iv + encrypted_tofa_client_library_class + encrypted_tofa_client_library_class_iv + encrypted_tofa_client_library_create_credentials_method + encrypted_tofa_client_library_create_credentials_method_iv + encrypted_tofa_client_library_fetch_access_token_method + encrypted_tofa_client_library_fetch_access_token_method_iv + encrypted_tofa_credentials + encrypted_tofa_credentials_iv + encrypted_tofa_host + encrypted_tofa_host_iv + encrypted_tofa_request_json_keys + encrypted_tofa_request_json_keys_iv + encrypted_tofa_request_payload + encrypted_tofa_request_payload_iv + encrypted_tofa_response_json_keys + encrypted_tofa_response_json_keys_iv + encrypted_tofa_url + encrypted_tofa_url_iv + vertex_project + ], remove_with: '16.2', remove_after: '2023-06-22' INSTANCE_REVIEW_MIN_USERS = 50 GRAFANA_URL_ERROR_MESSAGE = 'Please check your Grafana URL setting in ' \ @@ -722,18 +747,6 @@ class ApplicationSetting < MainClusterwide::ApplicationRecord attr_encrypted :product_analytics_configurator_connection_string, encryption_options_base_32_aes_256_gcm.merge(encode: false, encode_iv: false) attr_encrypted :openai_api_key, encryption_options_base_32_aes_256_gcm.merge(encode: false, encode_iv: false) attr_encrypted :anthropic_api_key, encryption_options_base_32_aes_256_gcm.merge(encode: false, encode_iv: false) - # TOFA API integration settngs - attr_encrypted :tofa_client_library_args, encryption_options_base_32_aes_256_gcm.merge(encode: false, encode_iv: false) - attr_encrypted :tofa_client_library_class, encryption_options_base_32_aes_256_gcm.merge(encode: false, encode_iv: false) - attr_encrypted :tofa_client_library_create_credentials_method, encryption_options_base_32_aes_256_gcm.merge(encode: false, encode_iv: false) - attr_encrypted :tofa_client_library_fetch_access_token_method, encryption_options_base_32_aes_256_gcm.merge(encode: false, encode_iv: false) - attr_encrypted :tofa_credentials, encryption_options_base_32_aes_256_gcm.merge(encode: false, encode_iv: false) - attr_encrypted :tofa_host, encryption_options_base_32_aes_256_gcm.merge(encode: false, encode_iv: false) - attr_encrypted :tofa_request_json_keys, encryption_options_base_32_aes_256_gcm.merge(encode: false, encode_iv: false) - attr_encrypted :tofa_request_payload, encryption_options_base_32_aes_256_gcm.merge(encode: false, encode_iv: false) - attr_encrypted :tofa_response_json_keys, encryption_options_base_32_aes_256_gcm.merge(encode: false, encode_iv: false) - attr_encrypted :tofa_url, encryption_options_base_32_aes_256_gcm.merge(encode: false, encode_iv: false) - attr_encrypted :tofa_access_token_expires_in, encryption_options_base_32_aes_256_gcm.merge(encode: false, encode_iv: false) attr_encrypted :ai_access_token, encryption_options_base_32_aes_256_gcm.merge(encode: false, encode_iv: false) validates :disable_feed_token, diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index babea831d85..05ca9dd6596 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -366,7 +366,6 @@ module Ci project = pipeline&.project next unless project - next unless Feature.enabled?(:pipeline_trigger_merge_status, project) pipeline.run_after_commit do next if pipeline.child? diff --git a/app/models/plan_limits.rb b/app/models/plan_limits.rb index 7544e0d1411..2e9a6552b5d 100644 --- a/app/models/plan_limits.rb +++ b/app/models/plan_limits.rb @@ -9,8 +9,8 @@ class PlanLimits < ApplicationRecord belongs_to :plan - validates :notification_limit, numericality: { only_integer: true } - validates :enforcement_limit, numericality: { only_integer: true } + validates :notification_limit, numericality: { only_integer: true, greater_than_or_equal_to: 0 } + validates :enforcement_limit, numericality: { only_integer: true, greater_than_or_equal_to: 0 } def exceeded?(limit_name, subject, alternate_limit: 0) limit = limit_for(limit_name, alternate_limit: alternate_limit) diff --git a/app/views/projects/_files.html.haml b/app/views/projects/_files.html.haml index 60535d704c4..b5bbb57d58f 100644 --- a/app/views/projects/_files.html.haml +++ b/app/views/projects/_files.html.haml @@ -11,7 +11,8 @@ .info-well.gl-display-none.gl-sm-display-flex.project-last-commit.gl-flex-direction-column.gl-mt-5 #js-last-commit.gl-m-auto = gl_loading_icon(size: 'md') - #js-code-owners{ data: { branch: @ref, can_view_branch_rules: can_view_branch_rules?, branch_rules_path: branch_rules_path } } + - if project.licensed_feature_available?(:code_owners) + #js-code-owners{ data: { branch: @ref, can_view_branch_rules: can_view_branch_rules?, branch_rules_path: branch_rules_path } } .nav-block.gl-display-flex.gl-xs-flex-direction-column.gl-align-items-stretch = render 'projects/tree/tree_header', tree: @tree, is_project_overview: is_project_overview diff --git a/app/views/projects/blob/_blob.html.haml b/app/views/projects/blob/_blob.html.haml index 453a60a62f4..2aed0a92407 100644 --- a/app/views/projects/blob/_blob.html.haml +++ b/app/views/projects/blob/_blob.html.haml @@ -10,7 +10,8 @@ %ul.blob-commit-info = render 'projects/commits/commit', commit: @last_commit, project: @project, ref: @ref - #js-code-owners{ data: { blob_path: blob.path, project_path: @project.full_path, branch: @ref, can_view_branch_rules: can_view_branch_rules?, branch_rules_path: branch_rules_path } } + - if project.licensed_feature_available?(:code_owners) + #js-code-owners{ data: { blob_path: blob.path, project_path: @project.full_path, branch: @ref, can_view_branch_rules: can_view_branch_rules?, branch_rules_path: branch_rules_path } } = render "projects/blob/auxiliary_viewer", blob: blob - if project.forked? diff --git a/app/views/projects/commit/_signature_badge.html.haml b/app/views/projects/commit/_signature_badge.html.haml index 9cca928e794..5b99a88f29e 100644 --- a/app/views/projects/commit/_signature_badge.html.haml +++ b/app/views/projects/commit/_signature_badge.html.haml @@ -29,5 +29,5 @@ = link_to(_('Learn about signing commits'), help_page_path('user/project/repository/gpg_signed_commits/index.md'), class: 'gl-link gl-display-block gl-mt-3') -%a.signature-badge.gl-display-inline-block{ role: 'button', tabindex: 0, data: { toggle: 'popover', html: 'true', placement: 'top', title: title, content: content } } +%a.signature-badge.gl-display-inline-block.gl-ml-4{ role: 'button', tabindex: 0, data: { toggle: 'popover', html: 'true', placement: 'top', title: title, content: content } } = gl_badge_tag label, variant: variant diff --git a/config/feature_flags/development/pipeline_trigger_merge_status.yml b/config/feature_flags/development/pipeline_trigger_merge_status.yml deleted file mode 100644 index 840b5353123..00000000000 --- a/config/feature_flags/development/pipeline_trigger_merge_status.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -name: pipeline_trigger_merge_status -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/112525 -rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/392989 -milestone: '15.10' -type: development -group: group::code review -default_enabled: true diff --git a/db/migrate/20230524012641_add_vertex_ai_host_to_application_settings.rb b/db/migrate/20230524012641_add_vertex_ai_host_to_application_settings.rb new file mode 100644 index 00000000000..99f178959ee --- /dev/null +++ b/db/migrate/20230524012641_add_vertex_ai_host_to_application_settings.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class AddVertexAiHostToApplicationSettings < Gitlab::Database::Migration[2.1] + disable_ddl_transaction! + + def up + with_lock_retries do + add_column :application_settings, :vertex_ai_host, :text, if_not_exists: true + end + + add_text_limit :application_settings, :vertex_ai_host, 255 + end + + def down + remove_text_limit :application_settings, :vertex_ai_host + + with_lock_retries do + remove_column :application_settings, :vertex_ai_host, if_exists: true + end + end +end diff --git a/db/migrate/20230525064706_add_service_desk_enabled_to_service_desk_settings.rb b/db/migrate/20230525064706_add_service_desk_enabled_to_service_desk_settings.rb new file mode 100644 index 00000000000..ed2d679bca5 --- /dev/null +++ b/db/migrate/20230525064706_add_service_desk_enabled_to_service_desk_settings.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class AddServiceDeskEnabledToServiceDeskSettings < Gitlab::Database::Migration[2.1] + def change + add_column :service_desk_settings, :service_desk_enabled, :boolean, null: false, default: true + end +end diff --git a/db/migrate/20230530003417_rename_tofa_settings.rb b/db/migrate/20230530003417_rename_tofa_settings.rb new file mode 100644 index 00000000000..2ce88fe85f2 --- /dev/null +++ b/db/migrate/20230530003417_rename_tofa_settings.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class RenameTofaSettings < Gitlab::Database::Migration[2.1] + disable_ddl_transaction! + + def up + rename_column_concurrently :application_settings, :encrypted_tofa_credentials, :encrypted_vertex_ai_credentials + rename_column_concurrently :application_settings, :encrypted_tofa_credentials_iv, + :encrypted_vertex_ai_credentials_iv + + rename_column_concurrently :application_settings, :vertex_project, :vertex_ai_project + end + + def down + undo_rename_column_concurrently :application_settings, :encrypted_tofa_credentials, :encrypted_vertex_ai_credentials + undo_rename_column_concurrently :application_settings, :encrypted_tofa_credentials_iv, + :encrypted_vertex_ai_credentials_iv + + undo_rename_column_concurrently :application_settings, :vertex_project, :vertex_ai_project + end +end diff --git a/db/post_migrate/20230530003634_cleanup_tofa_settings.rb b/db/post_migrate/20230530003634_cleanup_tofa_settings.rb new file mode 100644 index 00000000000..0e580a52bfd --- /dev/null +++ b/db/post_migrate/20230530003634_cleanup_tofa_settings.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +class CleanupTofaSettings < Gitlab::Database::Migration[2.1] + disable_ddl_transaction! + + def up + cleanup_concurrent_column_rename :application_settings, :encrypted_tofa_credentials, + :encrypted_vertex_ai_credentials + cleanup_concurrent_column_rename :application_settings, :encrypted_tofa_credentials_iv, + :encrypted_vertex_ai_credentials_iv + cleanup_concurrent_column_rename :application_settings, :vertex_project, + :vertex_ai_project + end + + def down + undo_cleanup_concurrent_column_rename :application_settings, :encrypted_tofa_credentials, + :encrypted_vertex_ai_credentials + undo_cleanup_concurrent_column_rename :application_settings, :encrypted_tofa_credentials_iv, + :encrypted_vertex_ai_credentials_iv + undo_cleanup_concurrent_column_rename :application_settings, :vertex_project, + :vertex_ai_project + end +end diff --git a/db/schema_migrations/20230524012641 b/db/schema_migrations/20230524012641 new file mode 100644 index 00000000000..7f01ad8b013 --- /dev/null +++ b/db/schema_migrations/20230524012641 @@ -0,0 +1 @@ +3fa8bd64992a6c1bf7d9dc1d9fca2173b425df72d9b5e44fcc72ebbca93d3995 \ No newline at end of file diff --git a/db/schema_migrations/20230525064706 b/db/schema_migrations/20230525064706 new file mode 100644 index 00000000000..dbd9a6a5425 --- /dev/null +++ b/db/schema_migrations/20230525064706 @@ -0,0 +1 @@ +e532fbf81ec8ce67616f93945c7ac384ff491410227a388aff7a2a01c43e4f2a \ No newline at end of file diff --git a/db/schema_migrations/20230530003417 b/db/schema_migrations/20230530003417 new file mode 100644 index 00000000000..e75305f71a8 --- /dev/null +++ b/db/schema_migrations/20230530003417 @@ -0,0 +1 @@ +4604d184499892cace131232cdf728745b0e616261bdcfa6acd5ff304056759b \ No newline at end of file diff --git a/db/schema_migrations/20230530003634 b/db/schema_migrations/20230530003634 new file mode 100644 index 00000000000..28f38a3d676 --- /dev/null +++ b/db/schema_migrations/20230530003634 @@ -0,0 +1 @@ +0c2334dff5bb442d05e9b4c5cfe03128dfebf8d085625ce9df1b7bdc33ed439c \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index acdbe3e2cb9..0a510da3292 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -11812,8 +11812,6 @@ CREATE TABLE application_settings ( silent_mode_enabled boolean DEFAULT false NOT NULL, package_metadata_purl_types smallint[] DEFAULT '{}'::smallint[], ci_max_includes integer DEFAULT 150 NOT NULL, - encrypted_tofa_credentials bytea, - encrypted_tofa_credentials_iv bytea, encrypted_tofa_host bytea, encrypted_tofa_host_iv bytea, encrypted_tofa_url bytea, @@ -11840,12 +11838,15 @@ CREATE TABLE application_settings ( diagramsnet_enabled boolean DEFAULT true NOT NULL, diagramsnet_url text DEFAULT 'https://embed.diagrams.net'::text, allow_account_deletion boolean DEFAULT true NOT NULL, - vertex_project text, wiki_asciidoc_allow_uri_includes boolean DEFAULT false NOT NULL, namespace_aggregation_schedule_lease_duration_in_seconds integer DEFAULT 300 NOT NULL, container_registry_data_repair_detail_worker_max_concurrency integer DEFAULT 2 NOT NULL, encrypted_ai_access_token bytea, encrypted_ai_access_token_iv bytea, + vertex_ai_host text, + encrypted_vertex_ai_credentials bytea, + encrypted_vertex_ai_credentials_iv bytea, + vertex_ai_project text, CONSTRAINT app_settings_container_reg_cleanup_tags_max_list_size_positive CHECK ((container_registry_cleanup_tags_service_max_list_size >= 0)), CONSTRAINT app_settings_container_registry_pre_import_tags_rate_positive CHECK ((container_registry_pre_import_tags_rate >= (0)::numeric)), CONSTRAINT app_settings_dep_proxy_ttl_policies_worker_capacity_positive CHECK ((dependency_proxy_ttl_group_policy_worker_capacity >= 0)), @@ -11861,6 +11862,7 @@ CREATE TABLE application_settings ( CONSTRAINT app_settings_yaml_max_depth_positive CHECK ((max_yaml_depth > 0)), CONSTRAINT app_settings_yaml_max_size_positive CHECK ((max_yaml_size_bytes > 0)), CONSTRAINT check_0542340619 CHECK ((char_length(diagramsnet_url) <= 2048)), + CONSTRAINT check_12f01f1dcd CHECK ((char_length(vertex_ai_project) <= 255)), CONSTRAINT check_17d9558205 CHECK ((char_length((kroki_url)::text) <= 1024)), CONSTRAINT check_2b820eaac3 CHECK ((char_length(database_grafana_tag) <= 255)), CONSTRAINT check_2dba05b802 CHECK ((char_length(gitpod_url) <= 255)), @@ -11887,7 +11889,7 @@ CREATE TABLE application_settings ( CONSTRAINT check_9a719834eb CHECK ((char_length(secret_detection_token_revocation_url) <= 255)), CONSTRAINT check_9c6c447a13 CHECK ((char_length(maintenance_mode_message) <= 255)), CONSTRAINT check_a5704163cc CHECK ((char_length(secret_detection_revocation_token_types_url) <= 255)), - CONSTRAINT check_a8dc89f7c2 CHECK ((char_length(vertex_project) <= 255)), + CONSTRAINT check_ae53cf7f82 CHECK ((char_length(vertex_ai_host) <= 255)), CONSTRAINT check_b8c74ea5b3 CHECK ((char_length(deactivation_email_additional_text) <= 1000)), CONSTRAINT check_d03919528d CHECK ((char_length(container_registry_vendor) <= 255)), CONSTRAINT check_d820146492 CHECK ((char_length(spam_check_endpoint_url) <= 255)), @@ -22577,6 +22579,7 @@ CREATE TABLE service_desk_settings ( custom_email_smtp_username text, encrypted_custom_email_smtp_password bytea, encrypted_custom_email_smtp_password_iv bytea, + service_desk_enabled boolean DEFAULT true NOT NULL, CONSTRAINT check_57a79552e1 CHECK ((char_length(custom_email) <= 255)), CONSTRAINT check_b283637a9e CHECK ((char_length(custom_email_smtp_address) <= 255)), CONSTRAINT check_e3535d46ee CHECK ((char_length(custom_email_smtp_username) <= 255)) diff --git a/doc/development/ai_features.md b/doc/development/ai_features.md index e5d5581f704..6d7c0b9072f 100644 --- a/doc/development/ai_features.md +++ b/doc/development/ai_features.md @@ -111,12 +111,11 @@ In order to obtain a GCP service key for local development, please follow the st - Open the Rails console. Update the settings to: ```ruby -Gitlab::CurrentSettings.update(tofa_credentials: File.read('/YOUR_FILE.json')) +Gitlab::CurrentSettings.update(vertex_ai_credentials: File.read('/YOUR_FILE.json')) # Note: These credential examples will not work locally for all models -Gitlab::CurrentSettings.update(tofa_host: "") # Example: us-central1-aiplatform.googleapis.com -Gitlab::CurrentSettings.update(tofa_url: "") # Example: https://ROOT-DOMAIN/v1/projects/MY-COOL-PROJECT/locations/us-central1/publishers/google/models/MY-SPECIAL-MODEL:predict -Gitlab::CurrentSettings.update(vertex_project: "") # Example: cloud-large-language-models +Gitlab::CurrentSettings.update(vertex_ai_host: "") # Example: us-central1-aiplatform.googleapis.com +Gitlab::CurrentSettings.update(vertex_ai_project: "") # Example: cloud-large-language-models ``` Internal team members can [use this snippet](https://gitlab.com/gitlab-com/gl-infra/production/-/snippets/2541742) for help configuring these endpoints. diff --git a/doc/development/code_review.md b/doc/development/code_review.md index e590eb60812..2abd6034fc6 100644 --- a/doc/development/code_review.md +++ b/doc/development/code_review.md @@ -156,7 +156,10 @@ please use in your personal YAML file entry: `- reviewer database local` instead As described in the section on the responsibility of the maintainer below, you are recommended to get your merge request approved and merged by maintainers -with [domain expertise](#domain-experts). +with [domain expertise](#domain-experts). The optional approval of the first +reviewer is not covered here. However, your merge request should be reviewed +by a reviewer before passing it to a maintainer as described in the +[overview](#getting-your-merge-request-reviewed-approved-and-merged) section. | If your merge request includes | It must be approved by a | | ------------------------------- | ------------------------ | diff --git a/doc/user/admin_area/settings/sign_in_restrictions.md b/doc/user/admin_area/settings/sign_in_restrictions.md index 951e0784c88..df719004062 100644 --- a/doc/user/admin_area/settings/sign_in_restrictions.md +++ b/doc/user/admin_area/settings/sign_in_restrictions.md @@ -32,13 +32,13 @@ In the event of an external authentication provider outage, use the [GitLab Rail > [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2158) in GitLab 13.10. -If you are an administrator, you might want to work in GitLab without the access that -comes from being an administrator. While you could create a separate user account that -doesn't have administrator access, a more secure solution is to use *Admin Mode*. +If you're an administrator, you might want to work in GitLab without administrator access. +You could either create a separate user account that does not have +administrator access or use Admin Mode. -With Admin Mode, your account does not have administrative access by default. -You can continue to access groups and projects you are a member of, but to access -administrative functionality, you must authenticate. +With Admin Mode, your account does not have administrator access by default. +You can continue to access groups and projects you're a member of. However, for administrative tasks, +you must authenticate (except for [certain features](#limitations-of-admin-mode)). When Admin Mode is enabled, it applies to all administrators on the instance. diff --git a/doc/user/enterprise_user/index.md b/doc/user/enterprise_user/index.md index 7bb8705ace0..2d89d7e5997 100644 --- a/doc/user/enterprise_user/index.md +++ b/doc/user/enterprise_user/index.md @@ -25,7 +25,8 @@ A user account is considered an enterprise account when: A user can also [manually connect an identity provider (IdP) to a GitLab account whose email address matches the subscribing organization's domain](../group/saml_sso/index.md#link-saml-to-your-existing-gitlabcom-account). By selecting **Authorize** when connecting these two accounts, the user account with the matching email address is classified as an enterprise user. However, this -user account does not have an **Enterprise** badge in GitLab. +user account does not have an **Enterprise** badge in GitLab, and a group Owner cannot +disable the user's two-factor authentication. Although a user can be a member of more than one group, each user account can be provisioned by only one group. As a result, a user is considered an enterprise @@ -160,3 +161,9 @@ A top-level group Owner can [set up verified domains to bypass confirmation emai A top-level group Owner can use the [group and project members API](../../api/members.md) to access users' information, including email addresses. + +## Troubleshooting + +### Cannot disable two-factor authentication for an enterprise user + +If an enterprise user does not have an **Enterprise** badge, a top-level group Owner cannot [disable or reset 2FA](#disable-two-factor-authentication) for that user. Instead, the Owner should tell the enterprise user to consider available [recovery options](../profile/account/two_factor_authentication.md#recovery-options). diff --git a/doc/user/project/import/github.md b/doc/user/project/import/github.md index 118e7caf123..e7732c02fdf 100644 --- a/doc/user/project/import/github.md +++ b/doc/user/project/import/github.md @@ -30,6 +30,7 @@ When importing projects: - The importer also imports branches on forks of projects related to open pull requests. These branches are imported with a naming scheme similar to `GH-SHA-username/pull-request-number/fork-name/branch`. This may lead to a discrepancy in branches compared to those of the GitHub repository. +- The organization the repository belongs to must not impose restrictions of a [third-party application access policy](https://docs.github.com/en/organizations/managing-oauth-access-to-your-organizations-data/about-oauth-app-access-restrictions) on the GitLab instance you import to. For an overview of the import process, see [Migrating from GitHub to GitLab](https://youtu.be/VYOXuOg9tQI). diff --git a/lib/bulk_imports/common/pipelines/members_pipeline.rb b/lib/bulk_imports/common/pipelines/members_pipeline.rb index f35eb5ccf5e..548b191dc25 100644 --- a/lib/bulk_imports/common/pipelines/members_pipeline.rb +++ b/lib/bulk_imports/common/pipelines/members_pipeline.rb @@ -7,7 +7,7 @@ module BulkImports include Pipeline transformer Common::Transformers::ProhibitedAttributesTransformer - transformer BulkImports::Groups::Transformers::MemberAttributesTransformer + transformer Common::Transformers::MemberAttributesTransformer def extract(context) graphql_extractor.extract(context) diff --git a/lib/bulk_imports/common/transformers/member_attributes_transformer.rb b/lib/bulk_imports/common/transformers/member_attributes_transformer.rb new file mode 100644 index 00000000000..382e6a51a73 --- /dev/null +++ b/lib/bulk_imports/common/transformers/member_attributes_transformer.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +module BulkImports + module Common + module Transformers + class MemberAttributesTransformer + def transform(context, data) + user = find_user(data&.dig('user', 'public_email')) + access_level = data&.dig('access_level', 'integer_value') + + return unless data + return unless user + return unless valid_access_level?(access_level) + + cache_source_user_id(data, user, context) + + { + user_id: user.id, + access_level: access_level, + created_at: data['created_at'], + updated_at: data['updated_at'], + expires_at: data['expires_at'], + created_by_id: context.current_user.id + } + end + + private + + def find_user(email) + return unless email + + User.find_by_any_email(email, confirmed: true) + end + + def valid_access_level?(access_level) + Gitlab::Access.options_with_owner.value?(access_level) + end + + def cache_source_user_id(data, user, context) + gid = data&.dig('user', 'user_gid') + + return unless gid + + source_user_id = GlobalID.parse(gid).model_id + + ::BulkImports::UsersMapper.new(context: context).cache_source_user_id(source_user_id, user.id) + end + end + end + end +end diff --git a/lib/bulk_imports/groups/transformers/member_attributes_transformer.rb b/lib/bulk_imports/groups/transformers/member_attributes_transformer.rb deleted file mode 100644 index da50a19ee62..00000000000 --- a/lib/bulk_imports/groups/transformers/member_attributes_transformer.rb +++ /dev/null @@ -1,51 +0,0 @@ -# frozen_string_literal: true - -module BulkImports - module Groups - module Transformers - class MemberAttributesTransformer - def transform(context, data) - user = find_user(data&.dig('user', 'public_email')) - access_level = data&.dig('access_level', 'integer_value') - - return unless data - return unless user - return unless valid_access_level?(access_level) - - cache_source_user_id(data, user, context) - - { - user_id: user.id, - access_level: access_level, - created_at: data['created_at'], - updated_at: data['updated_at'], - expires_at: data['expires_at'], - created_by_id: context.current_user.id - } - end - - private - - def find_user(email) - return unless email - - User.find_by_any_email(email, confirmed: true) - end - - def valid_access_level?(access_level) - Gitlab::Access.options_with_owner.value?(access_level) - end - - def cache_source_user_id(data, user, context) - gid = data&.dig('user', 'user_gid') - - return unless gid - - source_user_id = GlobalID.parse(gid).model_id - - ::BulkImports::UsersMapper.new(context: context).cache_source_user_id(source_user_id, user.id) - end - end - end - end -end diff --git a/lib/gitlab/usage_data.rb b/lib/gitlab/usage_data.rb index 846bb934a3d..83dc8c5dcf8 100644 --- a/lib/gitlab/usage_data.rb +++ b/lib/gitlab/usage_data.rb @@ -42,14 +42,11 @@ module Gitlab clear_memoized with_finished_at(:recording_ce_finished_at) do - usage_data_metrics + { recorded_at: recorded_at } + .merge(usage_data_metrics) end end - def license_usage_data - { recorded_at: recorded_at } - end - def recorded_at @recorded_at ||= Time.current end @@ -552,8 +549,7 @@ module Gitlab end def usage_data_metrics - license_usage_data - .merge(system_usage_data_license) + system_usage_data_license .merge(system_usage_data_settings) .merge(system_usage_data) .merge(system_usage_data_monthly) diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 342daba3f23..c08cf3fbb67 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -4934,9 +4934,6 @@ msgstr "" msgid "An error occurred while loading chart data" msgstr "" -msgid "An error occurred while loading code owners." -msgstr "" - msgid "An error occurred while loading commit signatures" msgstr "" @@ -10952,9 +10949,6 @@ msgstr "" msgid "Code owner approval is required" msgstr "" -msgid "Code owners" -msgstr "" - msgid "Code review" msgstr "" @@ -10973,6 +10967,24 @@ msgstr "" msgid "CodeNavigation|No references found" msgstr "" +msgid "CodeOwners|An error occurred while loading code owners." +msgstr "" + +msgid "CodeOwners|Assign users and groups as approvers for specific file changes." +msgstr "" + +msgid "CodeOwners|Code owners" +msgstr "" + +msgid "CodeOwners|Hide all" +msgstr "" + +msgid "CodeOwners|Learn more." +msgstr "" + +msgid "CodeOwners|Show all" +msgstr "" + msgid "CodeOwner|Pattern" msgstr "" diff --git a/package.json b/package.json index 0050a834333..536d49680b5 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "@gitlab/cluster-client": "^1.2.0", "@gitlab/favicon-overlay": "2.0.0", "@gitlab/fonts": "^1.2.0", - "@gitlab/svgs": "3.49.0", + "@gitlab/svgs": "3.50.0", "@gitlab/ui": "62.12.0", "@gitlab/visual-review-tools": "1.7.3", "@gitlab/web-ide": "0.0.1-dev-20230524134151", diff --git a/spec/controllers/admin/application_settings_controller_spec.rb b/spec/controllers/admin/application_settings_controller_spec.rb index a721722a5c3..537424093fb 100644 --- a/spec/controllers/admin/application_settings_controller_spec.rb +++ b/spec/controllers/admin/application_settings_controller_spec.rb @@ -59,7 +59,7 @@ RSpec.describe Admin::ApplicationSettingsController, :do_not_mock_admin_mode_set end end - describe 'GET #usage_data', feature_category: :service_ping do + describe 'GET #usage_data', :with_license, feature_category: :service_ping do before do stub_usage_data_connections stub_database_flavor_check diff --git a/spec/controllers/admin/instance_review_controller_spec.rb b/spec/controllers/admin/instance_review_controller_spec.rb index f0225a71e00..b69d22ba1e3 100644 --- a/spec/controllers/admin/instance_review_controller_spec.rb +++ b/spec/controllers/admin/instance_review_controller_spec.rb @@ -18,7 +18,7 @@ RSpec.describe Admin::InstanceReviewController, feature_category: :service_ping subject { post :index } - context 'with usage ping enabled' do + context 'with usage ping enabled', :with_license do before do stub_application_setting(usage_ping_enabled: true) stub_usage_data_connections diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb index 1f43caf37e7..d3b43029f2a 100644 --- a/spec/features/admin/admin_settings_spec.rb +++ b/spec/features/admin/admin_settings_spec.rb @@ -977,7 +977,7 @@ RSpec.describe 'Admin updates settings', feature_category: :shared do end end - context 'Service usage data page' do + context 'Service usage data page', :with_license do before do stub_usage_data_connections stub_database_flavor_check diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index e9b0c900867..01be083b506 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -172,6 +172,29 @@ RSpec.describe ApplicationHelper do end end + describe 'edited_time_ago_with_tooltip' do + around do |example| + Time.use_zone('UTC') { example.run } + end + + let(:project) { build_stubbed(:project) } + + context 'when editable object was not edited' do + let(:merge_request) { build_stubbed(:merge_request, source_project: project) } + + it { expect(helper.edited_time_ago_with_tooltip(merge_request)).to eq(nil) } + end + + context 'when editable object was edited' do + let(:user) { build_stubbed(:user) } + let(:now) { Time.zone.parse('2015-07-02 08:23') } + let(:merge_request) { build_stubbed(:merge_request, source_project: project, last_edited_at: now, last_edited_by: user) } + + it { expect(helper.edited_time_ago_with_tooltip(merge_request)).to have_text("Edited #{now.strftime('%b %d, %Y')} by #{user.name}") } + it { expect(helper.edited_time_ago_with_tooltip(merge_request, exclude_author: true)).to have_text("Edited #{now.strftime('%b %d, %Y')}") } + end + end + describe '#active_when' do it { expect(helper.active_when(true)).to eq('active') } it { expect(helper.active_when(false)).to eq(nil) } diff --git a/spec/lib/bulk_imports/common/transformers/member_attributes_transformer_spec.rb b/spec/lib/bulk_imports/common/transformers/member_attributes_transformer_spec.rb new file mode 100644 index 00000000000..1c9ed4f0f97 --- /dev/null +++ b/spec/lib/bulk_imports/common/transformers/member_attributes_transformer_spec.rb @@ -0,0 +1,143 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe BulkImports::Common::Transformers::MemberAttributesTransformer, feature_category: :importers do + let_it_be(:user) { create(:user) } + let_it_be(:secondary_email) { 'secondary@email.com' } + let_it_be(:bulk_import) { create(:bulk_import, user: user) } + + shared_examples 'members attribute transformer' do + let_it_be(:tracker) { create(:bulk_import_tracker, entity: entity) } + let_it_be(:context) { BulkImports::Pipeline::Context.new(tracker) } + + it 'returns nil when receives no data' do + expect(subject.transform(context, nil)).to eq(nil) + end + + it 'returns nil when no user is found' do + expect(subject.transform(context, member_data)).to eq(nil) + expect(subject.transform(context, member_data(email: 'inexistent@email.com'))).to eq(nil) + end + + context 'when the user is not confirmed' do + before do + user.update!(confirmed_at: nil) + end + + it 'returns nil even when the primary email match' do + data = member_data(email: user.email) + + expect(subject.transform(context, data)).to eq(nil) + end + + it 'returns nil even when a secondary email match' do + user.emails << Email.new(email: secondary_email) + data = member_data(email: secondary_email) + + expect(subject.transform(context, data)).to eq(nil) + end + end + + context 'when the user is confirmed' do + before do + user.update!(confirmed_at: Time.now.utc) + end + + it 'finds the user by the primary email' do + data = member_data(email: user.email) + + expect(subject.transform(context, data)).to eq( + access_level: 30, + user_id: user.id, + created_by_id: user.id, + created_at: '2020-01-01T00:00:00Z', + updated_at: '2020-01-01T00:00:00Z', + expires_at: nil + ) + end + + it 'finds the user by the secondary email' do + user.emails << Email.new(email: secondary_email, confirmed_at: Time.now.utc) + data = member_data(email: secondary_email) + + expect(subject.transform(context, data)).to eq( + access_level: 30, + user_id: user.id, + created_by_id: user.id, + created_at: '2020-01-01T00:00:00Z', + updated_at: '2020-01-01T00:00:00Z', + expires_at: nil + ) + end + + describe 'format access level' do + it 'ignores record if no access level is given' do + data = member_data(email: user.email, access_level: nil) + + expect(subject.transform(context, data)).to be_nil + end + + it 'ignores record if is not a valid access level' do + data = member_data(email: user.email, access_level: 999) + + expect(subject.transform(context, data)).to be_nil + end + end + + describe 'source user id caching' do + context 'when user gid is present' do + it 'caches source user id' do + gid = 'gid://gitlab/User/7' + data = member_data(email: user.email, gid: gid) + + expect_next_instance_of(BulkImports::UsersMapper) do |mapper| + expect(mapper).to receive(:cache_source_user_id).with('7', user.id) + end + + subject.transform(context, data) + end + end + + context 'when user gid is missing' do + it 'does not use caching' do + data = member_data(email: user.email) + + expect(BulkImports::UsersMapper).not_to receive(:new) + + subject.transform(context, data) + end + end + end + end + end + + context 'with a project' do + let_it_be(:entity) { create(:bulk_import_entity, bulk_import: bulk_import, project: project) } + let_it_be(:project) { create(:project) } + + include_examples 'members attribute transformer' + end + + context 'with a group' do + let_it_be(:entity) { create(:bulk_import_entity, bulk_import: bulk_import, group: group) } + let_it_be(:group) { create(:group) } + + include_examples 'members attribute transformer' + end + + def member_data(email: '', gid: nil, access_level: 30) + { + 'created_at' => '2020-01-01T00:00:00Z', + 'updated_at' => '2020-01-01T00:00:00Z', + 'expires_at' => nil, + 'access_level' => { + 'integer_value' => access_level + }, + 'user' => { + 'user_gid' => gid, + 'public_email' => email + } + } + end +end diff --git a/spec/lib/bulk_imports/groups/transformers/member_attributes_transformer_spec.rb b/spec/lib/bulk_imports/groups/transformers/member_attributes_transformer_spec.rb deleted file mode 100644 index c8935f71f10..00000000000 --- a/spec/lib/bulk_imports/groups/transformers/member_attributes_transformer_spec.rb +++ /dev/null @@ -1,128 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe BulkImports::Groups::Transformers::MemberAttributesTransformer do - let_it_be(:user) { create(:user) } - let_it_be(:secondary_email) { 'secondary@email.com' } - let_it_be(:group) { create(:group) } - let_it_be(:bulk_import) { create(:bulk_import, user: user) } - let_it_be(:entity) { create(:bulk_import_entity, bulk_import: bulk_import, group: group) } - let_it_be(:tracker) { create(:bulk_import_tracker, entity: entity) } - let_it_be(:context) { BulkImports::Pipeline::Context.new(tracker) } - - it 'returns nil when receives no data' do - expect(subject.transform(context, nil)).to eq(nil) - end - - it 'returns nil when no user is found' do - expect(subject.transform(context, member_data)).to eq(nil) - expect(subject.transform(context, member_data(email: 'inexistent@email.com'))).to eq(nil) - end - - context 'when the user is not confirmed' do - before do - user.update!(confirmed_at: nil) - end - - it 'returns nil even when the primary email match' do - data = member_data(email: user.email) - - expect(subject.transform(context, data)).to eq(nil) - end - - it 'returns nil even when a secondary email match' do - user.emails << Email.new(email: secondary_email) - data = member_data(email: secondary_email) - - expect(subject.transform(context, data)).to eq(nil) - end - end - - context 'when the user is confirmed' do - before do - user.update!(confirmed_at: Time.now.utc) - end - - it 'finds the user by the primary email' do - data = member_data(email: user.email) - - expect(subject.transform(context, data)).to eq( - access_level: 30, - user_id: user.id, - created_by_id: user.id, - created_at: '2020-01-01T00:00:00Z', - updated_at: '2020-01-01T00:00:00Z', - expires_at: nil - ) - end - - it 'finds the user by the secondary email' do - user.emails << Email.new(email: secondary_email, confirmed_at: Time.now.utc) - data = member_data(email: secondary_email) - - expect(subject.transform(context, data)).to eq( - access_level: 30, - user_id: user.id, - created_by_id: user.id, - created_at: '2020-01-01T00:00:00Z', - updated_at: '2020-01-01T00:00:00Z', - expires_at: nil - ) - end - - context 'format access level' do - it 'ignores record if no access level is given' do - data = member_data(email: user.email, access_level: nil) - - expect(subject.transform(context, data)).to be_nil - end - - it 'ignores record if is not a valid access level' do - data = member_data(email: user.email, access_level: 999) - - expect(subject.transform(context, data)).to be_nil - end - end - - context 'source user id caching' do - context 'when user gid is present' do - it 'caches source user id' do - gid = 'gid://gitlab/User/7' - data = member_data(email: user.email, gid: gid) - - expect_next_instance_of(BulkImports::UsersMapper) do |mapper| - expect(mapper).to receive(:cache_source_user_id).with('7', user.id) - end - - subject.transform(context, data) - end - end - - context 'when user gid is missing' do - it 'does not use caching' do - data = member_data(email: user.email) - - expect(BulkImports::UsersMapper).not_to receive(:new) - - subject.transform(context, data) - end - end - end - end - - def member_data(email: '', gid: nil, access_level: 30) - { - 'created_at' => '2020-01-01T00:00:00Z', - 'updated_at' => '2020-01-01T00:00:00Z', - 'expires_at' => nil, - 'access_level' => { - 'integer_value' => access_level - }, - 'user' => { - 'user_gid' => gid, - 'public_email' => email - } - } - end -end diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb index 4544cb2eb26..4da5f899ea9 100644 --- a/spec/lib/gitlab/usage_data_spec.rb +++ b/spec/lib/gitlab/usage_data_spec.rb @@ -661,14 +661,6 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures, feature_category: :servic end end - describe '.license_usage_data' do - subject { described_class.license_usage_data } - - it 'gathers license data' do - expect(subject[:recorded_at]).to be_a(Time) - end - end - context 'when not relying on database records' do describe '.features_usage_data_ce' do subject { described_class.features_usage_data_ce } diff --git a/spec/lib/sidebars/projects/menus/security_compliance_menu_spec.rb b/spec/lib/sidebars/projects/menus/security_compliance_menu_spec.rb index 697359b7941..4b4706bd311 100644 --- a/spec/lib/sidebars/projects/menus/security_compliance_menu_spec.rb +++ b/spec/lib/sidebars/projects/menus/security_compliance_menu_spec.rb @@ -23,6 +23,7 @@ RSpec.describe Sidebars::Projects::Menus::SecurityComplianceMenu do context 'when the Security and Compliance is disabled' do before do allow(Ability).to receive(:allowed?).with(user, :access_security_and_compliance, project).and_return(false) + allow(Ability).to receive(:allowed?).with(user, :read_security_resource, project).and_return(false) end it { is_expected.to be_falsey } diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index 5b67cbbc86b..b336018247c 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -1821,14 +1821,6 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep, feature_category: it_behaves_like 'state transition not triggering GraphQL subscription mergeRequestMergeStatusUpdated' end - - context 'when pipeline_trigger_merge_status feature flag is disabled' do - before do - stub_feature_flags(pipeline_trigger_merge_status: false) - end - - it_behaves_like 'state transition not triggering GraphQL subscription mergeRequestMergeStatusUpdated' - end end context 'when pipeline has merge requests' do diff --git a/spec/models/plan_limits_spec.rb b/spec/models/plan_limits_spec.rb index 236b185fca1..e1f441405ef 100644 --- a/spec/models/plan_limits_spec.rb +++ b/spec/models/plan_limits_spec.rb @@ -13,8 +13,8 @@ RSpec.describe PlanLimits do end describe 'validations' do - it { is_expected.to validate_numericality_of(:notification_limit).only_integer } - it { is_expected.to validate_numericality_of(:enforcement_limit).only_integer } + it { is_expected.to validate_numericality_of(:notification_limit).only_integer.is_greater_than_or_equal_to(0) } + it { is_expected.to validate_numericality_of(:enforcement_limit).only_integer.is_greater_than_or_equal_to(0) } end describe '#exceeded?' do diff --git a/spec/requests/api/usage_data_non_sql_metrics_spec.rb b/spec/requests/api/usage_data_non_sql_metrics_spec.rb index b2929caf676..4ca6c5cace3 100644 --- a/spec/requests/api/usage_data_non_sql_metrics_spec.rb +++ b/spec/requests/api/usage_data_non_sql_metrics_spec.rb @@ -12,7 +12,7 @@ RSpec.describe API::UsageDataNonSqlMetrics, :aggregate_failures, feature_categor stub_usage_data_connections end - describe 'GET /usage_data/non_sql_metrics' do + describe 'GET /usage_data/non_sql_metrics', :with_license do let(:endpoint) { '/usage_data/non_sql_metrics' } context 'with authentication' do diff --git a/spec/requests/api/usage_data_queries_spec.rb b/spec/requests/api/usage_data_queries_spec.rb index ab3c38adb81..584b0f31a07 100644 --- a/spec/requests/api/usage_data_queries_spec.rb +++ b/spec/requests/api/usage_data_queries_spec.rb @@ -14,7 +14,7 @@ RSpec.describe API::UsageDataQueries, :aggregate_failures, feature_category: :se stub_database_flavor_check end - describe 'GET /usage_data/usage_data_queries' do + describe 'GET /usage_data/usage_data_queries', :with_license do let(:endpoint) { '/usage_data/queries' } context 'with authentication' do diff --git a/spec/services/projects/container_repository/gitlab/delete_tags_service_spec.rb b/spec/services/projects/container_repository/gitlab/delete_tags_service_spec.rb index c4e6c7f4a11..ecabaa28119 100644 --- a/spec/services/projects/container_repository/gitlab/delete_tags_service_spec.rb +++ b/spec/services/projects/container_repository/gitlab/delete_tags_service_spec.rb @@ -55,7 +55,7 @@ RSpec.describe Projects::ContainerRepository::Gitlab::DeleteTagsService, feature context 'with timeout' do context 'set to a valid value' do before do - allow(Time.zone).to receive(:now).and_return(10, 15, 25) # third call to Time.zone.now will be triggering the timeout + allow(service).to receive(:timeout?).and_return(false, true) stub_delete_reference_requests('A' => 200) end diff --git a/spec/support/rspec_order_todo.yml b/spec/support/rspec_order_todo.yml index a94ceb98741..4a2740c28b7 100644 --- a/spec/support/rspec_order_todo.yml +++ b/spec/support/rspec_order_todo.yml @@ -5424,7 +5424,6 @@ - './spec/lib/bulk_imports/groups/pipelines/subgroup_entities_pipeline_spec.rb' - './spec/lib/bulk_imports/groups/stage_spec.rb' - './spec/lib/bulk_imports/groups/transformers/group_attributes_transformer_spec.rb' -- './spec/lib/bulk_imports/groups/transformers/member_attributes_transformer_spec.rb' - './spec/lib/bulk_imports/groups/transformers/subgroup_to_entity_transformer_spec.rb' - './spec/lib/bulk_imports/ndjson_pipeline_spec.rb' - './spec/lib/bulk_imports/network_error_spec.rb' diff --git a/spec/support/shared_contexts/services/service_ping/stubbed_service_ping_metrics_definitions_shared_context.rb b/spec/support/shared_contexts/services/service_ping/stubbed_service_ping_metrics_definitions_shared_context.rb index cd792ccc4e3..b34d95519a2 100644 --- a/spec/support/shared_contexts/services/service_ping/stubbed_service_ping_metrics_definitions_shared_context.rb +++ b/spec/support/shared_contexts/services/service_ping/stubbed_service_ping_metrics_definitions_shared_context.rb @@ -3,9 +3,8 @@ RSpec.shared_context 'stubbed service ping metrics definitions' do include UsageDataHelpers - let(:metrics_definitions) { standard_metrics + subscription_metrics + operational_metrics + optional_metrics } + let(:metrics_definitions) { standard_metrics + operational_metrics + optional_metrics } # ToDo: remove during https://gitlab.com/gitlab-org/gitlab/-/issues/396824 (license metrics migration) - let(:subscription_metrics) { [] } let(:standard_metrics) do [ metric_attributes('recorded_at', 'standard'), diff --git a/spec/support/shared_examples/services/service_ping/complete_service_ping_payload_shared_examples.rb b/spec/support/shared_examples/services/service_ping/complete_service_ping_payload_shared_examples.rb index 8dcff99fb6f..fd3c53f3675 100644 --- a/spec/support/shared_examples/services/service_ping/complete_service_ping_payload_shared_examples.rb +++ b/spec/support/shared_examples/services/service_ping/complete_service_ping_payload_shared_examples.rb @@ -3,7 +3,7 @@ RSpec.shared_examples 'complete service ping payload' do it_behaves_like 'service ping payload with all expected metrics' do let(:expected_metrics) do - standard_metrics + subscription_metrics + operational_metrics + optional_metrics + standard_metrics + operational_metrics + optional_metrics end end end diff --git a/spec/tasks/gitlab/usage_data_rake_spec.rb b/spec/tasks/gitlab/usage_data_rake_spec.rb index 72f284b0b7f..11aab1b1b42 100644 --- a/spec/tasks/gitlab/usage_data_rake_spec.rb +++ b/spec/tasks/gitlab/usage_data_rake_spec.rb @@ -2,7 +2,7 @@ require 'rake_helper' -RSpec.describe 'gitlab:usage data take tasks', :silence_stdout, feature_category: :service_ping do +RSpec.describe 'gitlab:usage data take tasks', :silence_stdout, :with_license, feature_category: :service_ping do include StubRequests include UsageDataHelpers diff --git a/yarn.lock b/yarn.lock index 77f67caff26..207e554e458 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1110,10 +1110,10 @@ stylelint-declaration-strict-value "1.8.0" stylelint-scss "4.2.0" -"@gitlab/svgs@3.49.0": - version "3.49.0" - resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-3.49.0.tgz#5ac366ce709c20f3a94f108556d00c3baf637e1e" - integrity sha512-2HkBtkf4X7NtTgd+1b7pnmeTRFDYoEmXduNov4yWRFB7UHy3SlGcmeH7HHWfXKwjr52iuYrmwdqSsXQUV3sbvg== +"@gitlab/svgs@3.50.0": + version "3.50.0" + resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-3.50.0.tgz#5ef7c0dabcd32ff32b5aaa3f576cf2bba7d5b466" + integrity sha512-Ssw+TXeAJd/LRKovx/P5RHi1ofPTdroFidej9vdyIVhcGZh7lZYt+qCBq4FfCXGefK86jisyVmNuStdpZxGHng== "@gitlab/ui@62.12.0": version "62.12.0" -- cgit v1.2.3