Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-05-26 15:08:29 +00:00
parent afd476d5fd
commit cac0926ddb
46 changed files with 592 additions and 664 deletions

View file

@ -802,35 +802,35 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/doc/user/workspace/index.md @fneill
[Authentication and Authorization]
/app/assets/javascripts/access_tokens @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/access_tokens/ @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/alerts_settings/graphql/mutations/reset_http_token.mutation.graphql @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/authentication @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/authentication/ @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/ide/components/shared/tokened_input.vue @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/invite_members/components/members_token_select.vue @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/logs/components/tokens @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/packages_and_registries/package_registry/components/list/tokens @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/pages/admin/impersonation_tokens @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/pages/groups/settings/access_tokens @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/pages/ldap @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/pages/oauth @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/pages/omniauth_callbacks @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/pages/profiles/password_prompt @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/pages/profiles/personal_access_tokens @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/pages/profiles/two_factor_auths @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/pages/projects/settings/access_tokens @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/logs/components/tokens/ @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/packages_and_registries/package_registry/components/list/tokens/ @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/pages/admin/impersonation_tokens/ @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/pages/groups/settings/access_tokens/ @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/pages/ldap/ @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/pages/oauth/ @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/pages/omniauth_callbacks/ @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/pages/profiles/password_prompt/ @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/pages/profiles/personal_access_tokens/ @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/pages/profiles/two_factor_auths/ @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/pages/projects/settings/access_tokens/ @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/pages/sessions/new/oauth_remember_me.js @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/pipelines/components/pipelines_list/tokens/constants.js @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/pipelines/components/pipelines_list/tokens/pipeline_branch_name_token.vue @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/pipelines/components/pipelines_list/tokens/pipeline_source_token.vue @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/pipelines/components/pipelines_list/tokens/pipeline_status_token.vue @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/pipelines/components/pipelines_list/tokens/pipeline_tag_name_token.vue @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/projects/settings/topics/components @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/projects/settings/topics/components/ @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/related_issues/components/issue_token.vue @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/runner/components/registration/registration_token.vue @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/runner/components/registration/registration_token_reset_dropdown_item.vue @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/runner/components/search_tokens @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/runner/components/search_tokens/ @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/build_uneditable_token.js @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/token_access/components @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/token_access/components/ @gitlab-org/manage/authentication-and-authorization
/app/assets/javascripts/token_access/index.js @gitlab-org/manage/authentication-and-authorization
/app/assets/stylesheets/page_bundles/profile_two_factor_auth.scss @gitlab-org/manage/authentication-and-authorization
/app/controllers/admin/impersonation_tokens_controller.rb @gitlab-org/manage/authentication-and-authorization
@ -845,8 +845,8 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/app/controllers/concerns/snippet_authorizations.rb @gitlab-org/manage/authentication-and-authorization
/app/controllers/concerns/workhorse_authorization.rb @gitlab-org/manage/authentication-and-authorization
/app/controllers/groups/settings/access_tokens_controller.rb @gitlab-org/manage/authentication-and-authorization
/app/controllers/ldap @gitlab-org/manage/authentication-and-authorization
/app/controllers/oauth @gitlab-org/manage/authentication-and-authorization
/app/controllers/ldap/ @gitlab-org/manage/authentication-and-authorization
/app/controllers/oauth/ @gitlab-org/manage/authentication-and-authorization
/app/controllers/omniauth_callbacks_controller.rb @gitlab-org/manage/authentication-and-authorization
/app/controllers/passwords_controller.rb @gitlab-org/manage/authentication-and-authorization
/app/controllers/profiles/passwords_controller.rb @gitlab-org/manage/authentication-and-authorization
@ -854,7 +854,7 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/app/controllers/profiles/two_factor_auths_controller.rb @gitlab-org/manage/authentication-and-authorization
/app/controllers/profiles/webauthn_registrations_controller.rb @gitlab-org/manage/authentication-and-authorization
/app/controllers/projects/settings/access_tokens_controller.rb @gitlab-org/manage/authentication-and-authorization
/app/finders/groups/projects_requiring_authorizations_refresh @gitlab-org/manage/authentication-and-authorization
/app/finders/groups/projects_requiring_authorizations_refresh/ @gitlab-org/manage/authentication-and-authorization
/app/finders/personal_access_tokens_finder.rb @gitlab-org/manage/authentication-and-authorization
/app/helpers/access_tokens_helper.rb @gitlab-org/manage/authentication-and-authorization
/app/helpers/auth_helper.rb @gitlab-org/manage/authentication-and-authorization
@ -863,7 +863,7 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/app/models/concerns/mirror_authentication.rb @gitlab-org/manage/authentication-and-authorization
/app/models/concerns/select_for_project_authorization.rb @gitlab-org/manage/authentication-and-authorization
/app/models/concerns/token_authenticatable.rb @gitlab-org/manage/authentication-and-authorization
/app/models/concerns/token_authenticatable_strategies @gitlab-org/manage/authentication-and-authorization
/app/models/concerns/token_authenticatable_strategies/ @gitlab-org/manage/authentication-and-authorization
/app/models/oauth_access_grant.rb @gitlab-org/manage/authentication-and-authorization
/app/models/oauth_access_token.rb @gitlab-org/manage/authentication-and-authorization
/app/models/personal_access_token.rb @gitlab-org/manage/authentication-and-authorization
@ -872,22 +872,22 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/app/models/webauthn_registration.rb @gitlab-org/manage/authentication-and-authorization
/app/policies/personal_access_token_policy.rb @gitlab-org/manage/authentication-and-authorization
/app/services/access_token_validation_service.rb @gitlab-org/manage/authentication-and-authorization
/app/services/auth @gitlab-org/manage/authentication-and-authorization
/app/services/authorized_project_update @gitlab-org/manage/authentication-and-authorization
/app/services/auth/ @gitlab-org/manage/authentication-and-authorization
/app/services/authorized_project_update/ @gitlab-org/manage/authentication-and-authorization
/app/services/chat_names/authorize_user_service.rb @gitlab-org/manage/authentication-and-authorization
/app/services/personal_access_tokens @gitlab-org/manage/authentication-and-authorization
/app/services/personal_access_tokens/ @gitlab-org/manage/authentication-and-authorization
/app/services/projects/move_project_authorizations_service.rb @gitlab-org/manage/authentication-and-authorization
/app/services/resource_access_tokens @gitlab-org/manage/authentication-and-authorization
/app/services/resource_access_tokens/ @gitlab-org/manage/authentication-and-authorization
/app/services/todos/destroy/unauthorized_features_service.rb @gitlab-org/manage/authentication-and-authorization
/app/services/users/authorized_build_service.rb @gitlab-org/manage/authentication-and-authorization
/app/services/users/authorized_create_service.rb @gitlab-org/manage/authentication-and-authorization
/app/services/users/refresh_authorized_projects_service.rb @gitlab-org/manage/authentication-and-authorization
/app/services/webauthn @gitlab-org/manage/authentication-and-authorization
/app/services/webauthn/ @gitlab-org/manage/authentication-and-authorization
/app/validators/json_schemas/cluster_agent_authorization_configuration.json @gitlab-org/manage/authentication-and-authorization
/app/views/admin/application_settings/_external_authorization_service_form.html.haml @gitlab-org/manage/authentication-and-authorization
/app/views/admin/impersonation_tokens @gitlab-org/manage/authentication-and-authorization
/app/views/authentication @gitlab-org/manage/authentication-and-authorization
/app/views/ci/token_access @gitlab-org/manage/authentication-and-authorization
/app/views/admin/impersonation_tokens/ @gitlab-org/manage/authentication-and-authorization
/app/views/authentication/ @gitlab-org/manage/authentication-and-authorization
/app/views/ci/token_access/ @gitlab-org/manage/authentication-and-authorization
/app/views/dashboard/projects/_zero_authorized_projects.html.haml @gitlab-org/manage/authentication-and-authorization
/app/views/devise/mailer/password_change.html.haml @gitlab-org/manage/authentication-and-authorization
/app/views/devise/mailer/password_change.text.erb @gitlab-org/manage/authentication-and-authorization
@ -895,17 +895,17 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/app/views/devise/mailer/password_change_by_admin.text.erb @gitlab-org/manage/authentication-and-authorization
/app/views/devise/mailer/reset_password_instructions.html.haml @gitlab-org/manage/authentication-and-authorization
/app/views/devise/mailer/reset_password_instructions.text.erb @gitlab-org/manage/authentication-and-authorization
/app/views/devise/passwords @gitlab-org/manage/authentication-and-authorization
/app/views/devise/passwords/ @gitlab-org/manage/authentication-and-authorization
/app/views/devise/shared/_omniauth_box.html.haml @gitlab-org/manage/authentication-and-authorization
/app/views/devise/shared/_signup_omniauth_provider_list.haml @gitlab-org/manage/authentication-and-authorization
/app/views/devise/shared/_signup_omniauth_providers.haml @gitlab-org/manage/authentication-and-authorization
/app/views/devise/shared/_signup_omniauth_providers_top.haml @gitlab-org/manage/authentication-and-authorization
/app/views/doorkeeper/authorizations @gitlab-org/manage/authentication-and-authorization
/app/views/doorkeeper/authorized_applications @gitlab-org/manage/authentication-and-authorization
/app/views/doorkeeper/authorizations/ @gitlab-org/manage/authentication-and-authorization
/app/views/doorkeeper/authorized_applications/ @gitlab-org/manage/authentication-and-authorization
/app/views/errors/omniauth_error.html.haml @gitlab-org/manage/authentication-and-authorization
/app/views/groups/settings/_resource_access_token_creation.html.haml @gitlab-org/manage/authentication-and-authorization
/app/views/groups/settings/_two_factor_auth.html.haml @gitlab-org/manage/authentication-and-authorization
/app/views/groups/settings/access_tokens @gitlab-org/manage/authentication-and-authorization
/app/views/groups/settings/access_tokens/ @gitlab-org/manage/authentication-and-authorization
/app/views/layouts/oauth_error.html.haml @gitlab-org/manage/authentication-and-authorization
/app/views/notify/access_token_about_to_expire_email.html.haml @gitlab-org/manage/authentication-and-authorization
/app/views/notify/access_token_about_to_expire_email.text.erb @gitlab-org/manage/authentication-and-authorization
@ -913,20 +913,20 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/app/views/notify/access_token_created_email.text.erb @gitlab-org/manage/authentication-and-authorization
/app/views/notify/access_token_expired_email.html.haml @gitlab-org/manage/authentication-and-authorization
/app/views/notify/access_token_expired_email.text.erb @gitlab-org/manage/authentication-and-authorization
/app/views/profiles/passwords @gitlab-org/manage/authentication-and-authorization
/app/views/profiles/personal_access_tokens @gitlab-org/manage/authentication-and-authorization
/app/views/profiles/two_factor_auths @gitlab-org/manage/authentication-and-authorization
/app/views/profiles/passwords/ @gitlab-org/manage/authentication-and-authorization
/app/views/profiles/personal_access_tokens/ @gitlab-org/manage/authentication-and-authorization
/app/views/profiles/two_factor_auths/ @gitlab-org/manage/authentication-and-authorization
/app/views/projects/mirrors/_authentication_method.html.haml @gitlab-org/manage/authentication-and-authorization
/app/views/projects/settings/access_tokens @gitlab-org/manage/authentication-and-authorization
/app/views/projects/settings/access_tokens/ @gitlab-org/manage/authentication-and-authorization
/app/views/shared/_no_password.html.haml @gitlab-org/manage/authentication-and-authorization
/app/views/shared/_two_factor_auth_recovery_settings_check.html.haml @gitlab-org/manage/authentication-and-authorization
/app/views/shared/access_tokens @gitlab-org/manage/authentication-and-authorization
/app/views/shared/access_tokens/ @gitlab-org/manage/authentication-and-authorization
/app/views/shared/members/_two_factor_auth_badge.html.haml @gitlab-org/manage/authentication-and-authorization
/app/views/shared/tokens @gitlab-org/manage/authentication-and-authorization
/app/views/shared/tokens/ @gitlab-org/manage/authentication-and-authorization
/app/workers/authorized_keys_worker.rb @gitlab-org/manage/authentication-and-authorization
/app/workers/authorized_project_update @gitlab-org/manage/authentication-and-authorization
/app/workers/authorized_project_update/ @gitlab-org/manage/authentication-and-authorization
/app/workers/authorized_projects_worker.rb @gitlab-org/manage/authentication-and-authorization
/app/workers/personal_access_tokens @gitlab-org/manage/authentication-and-authorization
/app/workers/personal_access_tokens/ @gitlab-org/manage/authentication-and-authorization
/config/feature_flags/development/application_settings_tokens_optional_encryption.yml @gitlab-org/manage/authentication-and-authorization
/config/feature_flags/development/enforce_auth_checks_on_uploads.yml @gitlab-org/manage/authentication-and-authorization
/config/feature_flags/development/forti_authenticator.yml @gitlab-org/manage/authentication-and-authorization
@ -936,6 +936,7 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/config/feature_flags/development/omniauth_login_minimal_scopes.yml @gitlab-org/manage/authentication-and-authorization
/config/feature_flags/development/personal_access_tokens_scoped_to_projects.yml @gitlab-org/manage/authentication-and-authorization
/config/feature_flags/development/projects_tokens_optional_encryption.yml @gitlab-org/manage/authentication-and-authorization
/config/feature_flags/development/refresh_authorizations_via_affected_projects_on_group_membership.yml @gitlab-org/manage/authentication-and-authorization
/config/feature_flags/development/specialized_worker_for_group_lock_update_auth_recalculation.yml @gitlab-org/manage/authentication-and-authorization
/config/feature_flags/development/webauthn.yml @gitlab-org/manage/authentication-and-authorization
/config/feature_flags/ops/block_password_auth_for_saml_users.yml @gitlab-org/manage/authentication-and-authorization
@ -949,27 +950,27 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/config/initializers/webauthn.rb @gitlab-org/manage/authentication-and-authorization
/config/initializers_before_autoloader/100_patch_omniauth_oauth2.rb @gitlab-org/manage/authentication-and-authorization
/config/initializers_before_autoloader/100_patch_omniauth_saml.rb @gitlab-org/manage/authentication-and-authorization
/ee/app/assets/javascripts/access_tokens @gitlab-org/manage/authentication-and-authorization
/ee/app/assets/javascripts/audit_events/components/tokens @gitlab-org/manage/authentication-and-authorization
/ee/app/assets/javascripts/access_tokens/ @gitlab-org/manage/authentication-and-authorization
/ee/app/assets/javascripts/audit_events/components/tokens/ @gitlab-org/manage/authentication-and-authorization
/ee/app/assets/javascripts/audit_events/token_utils.js @gitlab-org/manage/authentication-and-authorization
/ee/app/assets/javascripts/groups/settings/components @gitlab-org/manage/authentication-and-authorization
/ee/app/assets/javascripts/pages/groups/omniauth_callbacks @gitlab-org/manage/authentication-and-authorization
/ee/app/assets/javascripts/pipelines/components/pipelines_list @gitlab-org/manage/authentication-and-authorization
/ee/app/assets/javascripts/requirements/components/tokens @gitlab-org/manage/authentication-and-authorization
/ee/app/assets/javascripts/groups/settings/components/ @gitlab-org/manage/authentication-and-authorization
/ee/app/assets/javascripts/pages/groups/omniauth_callbacks/ @gitlab-org/manage/authentication-and-authorization
/ee/app/assets/javascripts/pipelines/components/pipelines_list/ @gitlab-org/manage/authentication-and-authorization
/ee/app/assets/javascripts/requirements/components/tokens/ @gitlab-org/manage/authentication-and-authorization
/ee/app/assets/javascripts/saml_providers/scim_token_service.js @gitlab-org/manage/authentication-and-authorization
/ee/app/assets/javascripts/saml_sso/components @gitlab-org/manage/authentication-and-authorization
/ee/app/assets/javascripts/saml_sso/components/ @gitlab-org/manage/authentication-and-authorization
/ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/approvals_auth.vue @gitlab-org/manage/authentication-and-authorization
/ee/app/controllers/concerns/ee/authenticates_with_two_factor.rb @gitlab-org/manage/authentication-and-authorization
/ee/app/controllers/concerns/ee/enforces_two_factor_authentication.rb @gitlab-org/manage/authentication-and-authorization
/ee/app/controllers/concerns/saml_authorization.rb @gitlab-org/manage/authentication-and-authorization
/ee/app/controllers/ee/ldap @gitlab-org/manage/authentication-and-authorization
/ee/app/controllers/ee/ldap/ @gitlab-org/manage/authentication-and-authorization
/ee/app/controllers/ee/omniauth_callbacks_controller.rb @gitlab-org/manage/authentication-and-authorization
/ee/app/controllers/ee/passwords_controller.rb @gitlab-org/manage/authentication-and-authorization
/ee/app/controllers/groups/omniauth_callbacks_controller.rb @gitlab-org/manage/authentication-and-authorization
/ee/app/controllers/groups/scim_oauth_controller.rb @gitlab-org/manage/authentication-and-authorization
/ee/app/controllers/oauth @gitlab-org/manage/authentication-and-authorization
/ee/app/controllers/oauth/ @gitlab-org/manage/authentication-and-authorization
/ee/app/controllers/omniauth_kerberos_spnego_controller.rb @gitlab-org/manage/authentication-and-authorization
/ee/app/finders/auth @gitlab-org/manage/authentication-and-authorization
/ee/app/finders/auth/ @gitlab-org/manage/authentication-and-authorization
/ee/app/helpers/ee/access_tokens_helper.rb @gitlab-org/manage/authentication-and-authorization
/ee/app/helpers/ee/auth_helper.rb @gitlab-org/manage/authentication-and-authorization
/ee/app/helpers/ee/personal_access_tokens_helper.rb @gitlab-org/manage/authentication-and-authorization
@ -977,10 +978,10 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/ee/app/models/ee/project_authorization.rb @gitlab-org/manage/authentication-and-authorization
/ee/app/models/scim_oauth_access_token.rb @gitlab-org/manage/authentication-and-authorization
/ee/app/serializers/scim_oauth_access_token_entity.rb @gitlab-org/manage/authentication-and-authorization
/ee/app/services/ee/auth @gitlab-org/manage/authentication-and-authorization
/ee/app/services/ee/personal_access_tokens @gitlab-org/manage/authentication-and-authorization
/ee/app/services/ee/resource_access_tokens @gitlab-org/manage/authentication-and-authorization
/ee/app/services/personal_access_tokens @gitlab-org/manage/authentication-and-authorization
/ee/app/services/ee/auth/ @gitlab-org/manage/authentication-and-authorization
/ee/app/services/ee/personal_access_tokens/ @gitlab-org/manage/authentication-and-authorization
/ee/app/services/ee/resource_access_tokens/ @gitlab-org/manage/authentication-and-authorization
/ee/app/services/personal_access_tokens/ @gitlab-org/manage/authentication-and-authorization
/ee/app/services/security/token_revocation_service.rb @gitlab-org/manage/authentication-and-authorization
/ee/app/views/admin/application_settings/_personal_access_token_expiration_policy.html.haml @gitlab-org/manage/authentication-and-authorization
/ee/app/views/credentials_inventory_mailer/personal_access_token_revoked_email.html.haml @gitlab-org/manage/authentication-and-authorization
@ -989,22 +990,21 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/ee/app/views/groups/sso/_authorize_pane.html.haml @gitlab-org/manage/authentication-and-authorization
/ee/app/views/notify/policy_revoked_personal_access_tokens_email.html.haml @gitlab-org/manage/authentication-and-authorization
/ee/app/views/notify/policy_revoked_personal_access_tokens_email.text.erb @gitlab-org/manage/authentication-and-authorization
/ee/app/views/oauth @gitlab-org/manage/authentication-and-authorization
/ee/app/views/oauth/ @gitlab-org/manage/authentication-and-authorization
/ee/app/views/shared/credentials_inventory/_personal_access_tokens.html.haml @gitlab-org/manage/authentication-and-authorization
/ee/app/views/shared/credentials_inventory/_project_access_tokens.html.haml @gitlab-org/manage/authentication-and-authorization
/ee/app/views/shared/credentials_inventory/personal_access_tokens @gitlab-org/manage/authentication-and-authorization
/ee/app/views/shared/credentials_inventory/project_access_tokens @gitlab-org/manage/authentication-and-authorization
/ee/app/workers/personal_access_tokens @gitlab-org/manage/authentication-and-authorization
/ee/app/views/shared/credentials_inventory/personal_access_tokens/ @gitlab-org/manage/authentication-and-authorization
/ee/app/views/shared/credentials_inventory/project_access_tokens/ @gitlab-org/manage/authentication-and-authorization
/ee/app/workers/personal_access_tokens/ @gitlab-org/manage/authentication-and-authorization
/ee/config/routes/oauth.rb @gitlab-org/manage/authentication-and-authorization
/ee/lib/ee/gitlab/auth @gitlab-org/manage/authentication-and-authorization
/ee/lib/ee/gitlab/auth.rb @gitlab-org/manage/authentication-and-authorization
/ee/lib/ee/gitlab/auth/ @gitlab-org/manage/authentication-and-authorization
/ee/lib/ee/gitlab/omniauth_initializer.rb @gitlab-org/manage/authentication-and-authorization
/ee/lib/gitlab/auth @gitlab-org/manage/authentication-and-authorization
/ee/lib/gitlab/auth/ @gitlab-org/manage/authentication-and-authorization
/ee/lib/gitlab/auth_logger.rb @gitlab-org/manage/authentication-and-authorization
/ee/lib/gitlab/authority_analyzer.rb @gitlab-org/manage/authentication-and-authorization
/ee/lib/gitlab/geo/oauth @gitlab-org/manage/authentication-and-authorization
/ee/lib/gitlab/kerberos @gitlab-org/manage/authentication-and-authorization
/ee/lib/omni_auth @gitlab-org/manage/authentication-and-authorization
/ee/lib/gitlab/geo/oauth/ @gitlab-org/manage/authentication-and-authorization
/ee/lib/gitlab/kerberos/ @gitlab-org/manage/authentication-and-authorization
/ee/lib/omni_auth/ @gitlab-org/manage/authentication-and-authorization
/ee/lib/system_check/geo/authorized_keys_check.rb @gitlab-org/manage/authentication-and-authorization
/ee/lib/system_check/geo/authorized_keys_flag_check.rb @gitlab-org/manage/authentication-and-authorization
/lib/api/entities/ci/reset_token_result.rb @gitlab-org/manage/authentication-and-authorization
@ -1019,27 +1019,28 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/lib/api/personal_access_tokens.rb @gitlab-org/manage/authentication-and-authorization
/lib/api/resource_access_tokens.rb @gitlab-org/manage/authentication-and-authorization
/lib/api/support/token_with_expiration.rb @gitlab-org/manage/authentication-and-authorization
/lib/gitlab/api_authentication @gitlab-org/manage/authentication-and-authorization
/lib/gitlab/auth @gitlab-org/manage/authentication-and-authorization
/lib/gitlab/api_authentication/ @gitlab-org/manage/authentication-and-authorization
/lib/gitlab/auth/ @gitlab-org/manage/authentication-and-authorization
/lib/gitlab/auth.rb @gitlab-org/manage/authentication-and-authorization
/lib/gitlab/auth_logger.rb @gitlab-org/manage/authentication-and-authorization
/lib/gitlab/authorized_keys.rb @gitlab-org/manage/authentication-and-authorization
/lib/gitlab/background_migration/encrypt_static_object_token.rb @gitlab-org/manage/authentication-and-authorization
/lib/gitlab/background_migration/expire_o_auth_tokens.rb @gitlab-org/manage/authentication-and-authorization
/lib/gitlab/background_migration/migrate_u2f_webauthn.rb @gitlab-org/manage/authentication-and-authorization
/lib/gitlab/background_migration/update_users_where_two_factor_auth_required_from_group.rb @gitlab-org/manage/authentication-and-authorization
/lib/gitlab/chat_name_token.rb @gitlab-org/manage/authentication-and-authorization
/lib/gitlab/ci/pipeline/expression/token.rb @gitlab-org/manage/authentication-and-authorization
/lib/gitlab/external_authorization @gitlab-org/manage/authentication-and-authorization
/lib/gitlab/external_authorization/ @gitlab-org/manage/authentication-and-authorization
/lib/gitlab/external_authorization.rb @gitlab-org/manage/authentication-and-authorization
/lib/gitlab/graphql/authorize @gitlab-org/manage/authentication-and-authorization
/lib/gitlab/graphql/authorize/ @gitlab-org/manage/authentication-and-authorization
/lib/gitlab/jwt_authenticatable.rb @gitlab-org/manage/authentication-and-authorization
/lib/gitlab/jwt_token.rb @gitlab-org/manage/authentication-and-authorization
/lib/gitlab/lfs_token.rb @gitlab-org/manage/authentication-and-authorization
/lib/gitlab/mail_room @gitlab-org/manage/authentication-and-authorization
/lib/gitlab/mail_room/ @gitlab-org/manage/authentication-and-authorization
/lib/gitlab/omniauth_initializer.rb @gitlab-org/manage/authentication-and-authorization
/lib/gitlab/project_authorizations.rb @gitlab-org/manage/authentication-and-authorization
/lib/json_web_token @gitlab-org/manage/authentication-and-authorization
/lib/omni_auth @gitlab-org/manage/authentication-and-authorization
/lib/json_web_token/ @gitlab-org/manage/authentication-and-authorization
/lib/omni_auth/ @gitlab-org/manage/authentication-and-authorization
/lib/system_check/app/authorized_keys_permission_check.rb @gitlab-org/manage/authentication-and-authorization
/lib/system_check/incoming_email/imap_authentication_check.rb @gitlab-org/manage/authentication-and-authorization
/lib/tasks/gitlab/password.rake @gitlab-org/manage/authentication-and-authorization

View file

@ -63,10 +63,12 @@ function maybeMerge(a, b) {
function createSourceMapAttributes(hastNode, source) {
const { position } = hastNode;
return {
sourceMapKey: `${position.start.offset}:${position.end.offset}`,
sourceMarkdown: source.substring(position.start.offset, position.end.offset),
};
return position.end
? {
sourceMapKey: `${position.start.offset}:${position.end.offset}`,
sourceMarkdown: source.substring(position.start.offset, position.end.offset),
}
: {};
}
/**
@ -252,11 +254,19 @@ const createProseMirrorNodeFactories = (schema, proseMirrorFactorySpecs, source)
const factories = {
root: {
selector: 'root',
handle: (state, hastNode) => state.openNode(schema.topNodeType, hastNode, {}),
handle: (state, hastNode) =>
state.openNode(
schema.topNodeType,
hastNode,
{},
{
wrapTextInParagraph: true,
},
),
},
text: {
selector: 'text',
handle: (state, hastNode) => {
handle: (state, hastNode, parent) => {
const { factorySpec } = state.top;
if (/^\s+$/.test(hastNode.value)) {
@ -264,7 +274,7 @@ const createProseMirrorNodeFactories = (schema, proseMirrorFactorySpecs, source)
}
if (factorySpec.wrapTextInParagraph === true) {
state.openNode(schema.nodeType('paragraph'));
state.openNode(schema.nodeType('paragraph'), hastNode, getAttrs({}, parent, [], source));
state.addText(schema, hastNode.value);
state.closeNode();
} else {

View file

@ -30,7 +30,7 @@ export default {
<p>{{ $options.i18n.description }}</p>
<gl-form :action="url" method="post">
<input :value="$options.csrf.token" type="hidden" name="authenticity_token" />
<gl-button category="secondary" variant="warning" type="submit">
<gl-button category="secondary" variant="danger" type="submit">
{{ $options.i18n.title }}
</gl-button>
</gl-form>

View file

@ -27,7 +27,7 @@ export default {
return this.getNoteableData.confidential;
},
isMergeRequest() {
return this.getNoteableData.targetType === 'merge_request' && this.glFeatures.updatedMrHeader;
return this.getNoteableData.targetType === 'merge_request';
},
warningIconsMeta() {
return [

View file

@ -74,8 +74,7 @@ export default {
return [
CLASSES[this.state],
{
'gl-vertical-align-bottom':
this.issuableType === IssuableType.MergeRequest && this.glFeatures.updatedMrHeader,
'gl-vertical-align-bottom': this.issuableType === IssuableType.MergeRequest,
},
];
},

View file

@ -156,11 +156,7 @@ MergeRequest.toggleDraftStatus = function (title, isReady) {
} else {
toast(__('Marked as draft. Can only be merged when marked as ready.'));
}
const titleEl = document.querySelector(
`.merge-request .detail-page-${
window.gon?.features?.updatedMrHeader ? 'header' : 'description'
} .title`,
);
const titleEl = document.querySelector(`.merge-request .detail-page-header .title`);
if (titleEl) {
titleEl.textContent = title;

View file

@ -1,100 +0,0 @@
<script>
import {
GlLink,
GlTooltipDirective,
GlModalDirective,
GlSafeHtmlDirective as SafeHtml,
GlSprintf,
} from '@gitlab/ui';
import { constructWebIDEPath } from '~/lib/utils/url_utility';
import { s__ } from '~/locale';
import clipboardButton from '~/vue_shared/components/clipboard_button.vue';
import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate/tooltip_on_truncate.vue';
import MrWidgetIcon from './mr_widget_icon.vue';
export default {
name: 'MRWidgetHeader',
components: {
clipboardButton,
TooltipOnTruncate,
MrWidgetIcon,
GlLink,
GlSprintf,
},
directives: {
GlTooltip: GlTooltipDirective,
GlModalDirective,
SafeHtml,
},
props: {
mr: {
type: Object,
required: true,
},
},
computed: {
shouldShowCommitsBehindText() {
return this.mr.divergedCommitsCount > 0;
},
branchNameClipboardData() {
// This supports code in app/assets/javascripts/copy_to_clipboard.js that
// works around ClipboardJS limitations to allow the context-specific
// copy/pasting of plain text or GFM.
return JSON.stringify({
text: this.mr.sourceBranch,
gfm: `\`${this.mr.sourceBranch}\``,
});
},
webIdePath() {
return constructWebIDEPath(this.mr);
},
isFork() {
return this.mr.sourceProjectFullPath !== this.mr.targetProjectFullPath;
},
},
i18n: {
webIdeText: s__('mrWidget|Open in Web IDE'),
gitpodText: s__('mrWidget|Open in Gitpod'),
},
};
</script>
<template>
<div class="gl-display-flex mr-source-target">
<mr-widget-icon name="git-merge" />
<div class="git-merge-container d-flex">
<div class="normal">
<strong>
{{ s__('mrWidget|Request to merge') }}
<tooltip-on-truncate
v-safe-html="mr.sourceBranchLink"
:title="mr.sourceBranch"
truncate-target="child"
class="label-branch label-truncate js-source-branch"
/><clipboard-button
data-testid="mr-widget-copy-clipboard"
:text="branchNameClipboardData"
:title="__('Copy branch name')"
category="tertiary"
/>
{{ s__('mrWidget|into') }}
<tooltip-on-truncate
:title="mr.targetBranch"
truncate-target="child"
class="label-branch label-truncate"
>
<a :href="mr.targetBranchTreePath" class="js-target-branch"> {{ mr.targetBranch }} </a>
</tooltip-on-truncate>
</strong>
<div v-if="shouldShowCommitsBehindText" class="diverged-commits-count">
<gl-sprintf :message="s__('mrWidget|The source branch is %{link} the target branch')">
<template #link>
<gl-link :href="mr.targetBranchPath">{{
n__('%d commit behind', '%d commits behind', mr.divergedCommitsCount)
}}</gl-link>
</template>
</gl-sprintf>
</div>
</div>
</div>
</div>
</template>

View file

@ -93,9 +93,7 @@ export default {
</span>
</p>
<div
v-if="
divergedCommitsCount > 0 && glFeatures.updatedMrHeader && !glFeatures.restructuredMrWidget
"
v-if="divergedCommitsCount > 0 && !glFeatures.restructuredMrWidget"
class="diverged-commits-count"
>
<gl-sprintf :message="s__('mrWidget|The source branch is %{link} the target branch')">

View file

@ -722,10 +722,7 @@ export default {
{{ __('Merge details') }}
</strong>
<ul class="gl-pl-4 gl-m-0">
<li
v-if="mr.divergedCommitsCount > 0 && glFeatures.updatedMrHeader"
class="gl-line-height-normal"
>
<li v-if="mr.divergedCommitsCount > 0" class="gl-line-height-normal">
<gl-sprintf
:message="s__('mrWidget|The source branch is %{link} the target branch')"
>

View file

@ -15,7 +15,6 @@ import SmartInterval from '~/smart_interval';
import { setFaviconOverlay } from '../lib/utils/favicon';
import Loading from './components/loading.vue';
import MrWidgetAlertMessage from './components/mr_widget_alert_message.vue';
import WidgetHeader from './components/mr_widget_header.vue';
import MrWidgetPipelineContainer from './components/mr_widget_pipeline_container.vue';
import WidgetRelatedLinks from './components/mr_widget_related_links.vue';
import WidgetSuggestPipeline from './components/mr_widget_suggest_pipeline.vue';
@ -59,7 +58,6 @@ export default {
components: {
Loading,
ExtensionsContainer,
'mr-widget-header': WidgetHeader,
'mr-widget-suggest-pipeline': WidgetSuggestPipeline,
MrWidgetPipelineContainer,
'mr-widget-related-links': WidgetRelatedLinks,
@ -234,9 +232,6 @@ export default {
isRestructuredMrWidgetEnabled() {
return window.gon?.features?.restructuredMrWidget;
},
isUpdatedHeaderEnabled() {
return window.gon?.features?.updatedMrHeader;
},
},
watch: {
'mr.machineValue': {
@ -531,14 +526,12 @@ export default {
<template>
<div v-if="isLoaded" class="mr-state-widget gl-mt-3">
<header
v-if="shouldRenderCollaborationStatus || !isUpdatedHeaderEnabled"
:class="{ 'mr-widget-workflow gl-mt-0!': isUpdatedHeaderEnabled }"
class="gl-rounded-base gl-border-solid gl-border-1 gl-border-gray-100 gl-overflow-hidden"
v-if="shouldRenderCollaborationStatus"
class="gl-rounded-base gl-border-solid gl-border-1 gl-border-gray-100 gl-overflow-hidden mr-widget-workflow gl-mt-0!"
>
<mr-widget-alert-message v-if="shouldRenderCollaborationStatus" type="info">
{{ s__('mrWidget|Members who can merge are allowed to add commits.') }}
</mr-widget-alert-message>
<mr-widget-header v-if="!isUpdatedHeaderEnabled" :mr="mr" />
</header>
<mr-widget-suggest-pipeline
v-if="shouldSuggestPipelines"

View file

@ -45,7 +45,6 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
push_frontend_feature_flag(:realtime_labels, project)
push_frontend_feature_flag(:updated_diff_expansion_buttons, project)
push_frontend_feature_flag(:mr_attention_requests, current_user)
push_frontend_feature_flag(:updated_mr_header, project)
push_frontend_feature_flag(:remove_diff_header_icons, project)
push_frontend_feature_flag(:moved_mr_sidebar, project)
end

View file

@ -28,18 +28,16 @@ module IssuesHelper
end
def status_box_class(item)
updated_mr_header_enabled = Feature.enabled?(:updated_mr_header, @project)
if item.try(:expired?)
'gl-bg-orange-500'
elsif item.try(:merged?)
updated_mr_header_enabled ? 'badge-info' : 'gl-bg-blue-500'
'badge-info'
elsif item.closed?
item.is_a?(MergeRequest) && updated_mr_header_enabled ? 'badge-danger' : 'gl-bg-red-500'
item.is_a?(MergeRequest) ? 'badge-danger' : 'gl-bg-red-500'
elsif item.try(:upcoming?)
'gl-bg-gray-500'
else
item.is_a?(MergeRequest) && updated_mr_header_enabled ? 'badge-success' : 'gl-bg-green-500'
item.is_a?(MergeRequest) ? 'badge-success' : 'gl-bg-green-500'
end
end

View file

@ -170,6 +170,7 @@ class Member < ApplicationRecord
scope :owners_and_maintainers, -> { active.where(access_level: [OWNER, MAINTAINER]) }
scope :with_user, -> (user) { where(user: user) }
scope :by_access_level, -> (access_level) { active.where(access_level: access_level) }
scope :all_by_access_level, -> (access_level) { where(access_level: access_level) }
scope :preload_user_and_notification_settings, -> { preload(user: :notification_settings) }

View file

@ -1366,9 +1366,16 @@ class User < ApplicationRecord
end
def solo_owned_groups
@solo_owned_groups ||= owned_groups.includes(:owners).select do |group|
group.owners == [self]
end
# For each owned group, count the owners found in self and ancestors.
counts = GroupMember
.from('unnest(namespaces.traversal_ids) AS ancestors(ancestor_id), members')
.where('members.source_id = ancestors.ancestor_id')
.all_by_access_level(GroupMember::OWNER)
.having('count(members.user_id) = 1')
Group
.from(owned_groups, :namespaces)
.where_exists(counts)
end
def with_defaults

View file

@ -1,9 +1,3 @@
- updated_mr_header = Feature.enabled?(:updated_mr_header, @project)
.detail-page-description.py-2{ class: "#{'is-merge-request' if updated_mr_header && !fluid_layout}" }
- if updated_mr_header
= render 'shared/issuable/status_box', issuable: @merge_request
= merge_request_header(@project, @merge_request)
- else
%h2.title.mb-0{ data: { qa_selector: 'title_content' } }
= markdown_field(@merge_request, :title)
.detail-page-description.py-2{ class: "#{'is-merge-request' if !fluid_layout}" }
= render 'shared/issuable/status_box', issuable: @merge_request
= merge_request_header(@project, @merge_request)

View file

@ -2,8 +2,7 @@
- can_update_merge_request = can?(current_user, :update_merge_request, @merge_request)
- can_reopen_merge_request = can?(current_user, :reopen_merge_request, @merge_request)
- are_close_and_open_buttons_hidden = merge_request_button_hidden?(@merge_request, true) && merge_request_button_hidden?(@merge_request, false)
- updated_mr_header_enabled = Feature.enabled?(:updated_mr_header, @project)
- cache_key = [@project, @merge_request, can_update_merge_request, can_reopen_merge_request, are_close_and_open_buttons_hidden, current_user&.preferred_language, "1.1-#{updated_mr_header_enabled}", moved_mr_sidebar_enabled?]
- cache_key = [@project, @merge_request, can_update_merge_request, can_reopen_merge_request, are_close_and_open_buttons_hidden, current_user&.preferred_language, "1.1-updated_header", moved_mr_sidebar_enabled?]
= cache(cache_key, expires_in: 1.day) do
- if @merge_request.closed_or_merged_without_fork?
@ -13,24 +12,18 @@
= c.body do
= _('The source project of this merge request has been removed.')
.detail-page-header.border-bottom-0.pt-0.pb-0{ class: "#{'gl-display-block gl-md-display-flex!' if updated_mr_header_enabled} #{'is-merge-request' if moved_mr_sidebar_enabled? && !fluid_layout}" }
.detail-page-header.border-bottom-0.pt-0.pb-0.gl-display-block{ class: "gl-md-display-flex! #{'is-merge-request' if moved_mr_sidebar_enabled? && !fluid_layout}" }
.detail-page-header-body
- unless updated_mr_header_enabled
= render "shared/issuable/status_box", issuable: @merge_request
.issuable-meta{ class: "#{'gl-display-flex' if updated_mr_header_enabled}" }
- if updated_mr_header_enabled
#js-issuable-header-warnings
%h2.title.gl-my-0.gl-display-inline-block{ data: { qa_selector: 'title_content' } }
= markdown_field(@merge_request, :title)
- else
#js-issuable-header-warnings
= issuable_meta(@merge_request, @project)
.issuable-meta.gl-display-flex
#js-issuable-header-warnings
%h2.title.gl-my-0.gl-display-inline-block{ data: { qa_selector: 'title_content' } }
= markdown_field(@merge_request, :title)
%div
%button.gl-button.btn.btn-default.btn-icon.float-right.gl-display-block.gutter-toggle.issuable-gutter-toggle.js-sidebar-toggle{ type: 'button', class: "#{'gl-md-display-none!' if moved_mr_sidebar_enabled? } #{'gl-sm-display-none!' unless moved_mr_sidebar_enabled?}" }
= sprite_icon('chevron-double-lg-left')
.detail-page-header-actions.js-issuable-actions{ class: "#{'gl-align-self-start is-merge-request' if updated_mr_header_enabled}" }
.detail-page-header-actions.gl-align-self-start.is-merge-request.js-issuable-actions
- if can_update_merge_request
= link_to _('Edit'), edit_project_merge_request_path(@project, @merge_request), class: "gl-display-none gl-md-display-block btn gl-button btn-default btn-grouped js-issuable-edit", data: { qa_selector: "edit_button" }

View file

@ -21,7 +21,7 @@
.merge-request-details.issuable-details{ data: { id: @merge_request.project.id } }
= render "projects/merge_requests/mr_box"
.merge-request-tabs-holder{ class: ("js-tabs-affix" unless ENV['RAILS_ENV'] == 'test') }
.merge-request-tabs-container{ class: "#{'is-merge-request' if Feature.enabled?(:updated_mr_header, @project) && !fluid_layout}" }
.merge-request-tabs-container{ class: "#{'is-merge-request' if !fluid_layout}" }
%ul.merge-request-tabs.nav-tabs.nav.nav-links
= render "projects/merge_requests/tabs/tab", class: "notes-tab", qa_selector: "notes_tab" do
= tab_link_for @merge_request, :show, force_link: @commit.present? do

View file

@ -2,11 +2,9 @@
- default_ref = params[:ref] || @project.default_branch
- if @error
.gl-alert.gl-alert-danger
= sprite_icon('error', css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
%button.js-close.gl-alert-dismiss{ type: 'button', 'aria-label' => _('Dismiss') }
= sprite_icon('close', css_class: 'gl-icon')
= @error
= render Pajamas::AlertComponent.new(variant: :danger, dismissible: true, close_button_class: 'gl-alert-dismiss') do |c|
= c.body do
= @error
%h3.page-title
= s_('TagsPage|New Tag')

View file

@ -2,8 +2,7 @@
- badge_icon = state_name_with_icon(issuable)[1]
- badge_variant = issuable.open? ? :success : issuable.merged? ? :info : :danger
- badge_status_class = issuable.open? ? 'issuable-status-badge-open' : issuable.merged? ? 'issuable-status-badge-merged' : 'issuable-status-badge-closed'
- updated_mr_header_enabled = Feature.enabled?(:updated_mr_header, @project) && issuable.is_a?(MergeRequest)
- badge_classes = "js-mr-status-box issuable-status-badge gl-mr-3 #{badge_status_class} #{'gl-vertical-align-bottom' if updated_mr_header_enabled}"
- badge_classes = "js-mr-status-box issuable-status-badge gl-mr-3 #{badge_status_class} #{'gl-vertical-align-bottom' if issuable.is_a?(MergeRequest)}"
= gl_badge_tag({ variant: badge_variant, icon: badge_icon, icon_classes: 'gl-mr-0!' }, { class: badge_classes, data: { project_path: issuable.project.path_with_namespace, iid: issuable.iid, issuable_type: 'merge_request', state: issuable.state } }) do
%span.gl-display-none.gl-sm-display-block.gl-ml-2

View file

@ -1,8 +0,0 @@
---
name: updated_mr_header
introduced_by_url:
rollout_issue_url:
milestone: '14.10'
type: development
group: group::code review
default_enabled: true

View file

@ -7,7 +7,7 @@
body: |
The certificate-based integration with Kubernetes [will be deprecated and removed](https://about.gitlab.com/blog/2021/11/15/deprecating-the-cert-based-kubernetes-integration/).
As a self-managed customer, we are introducing a feature flag in GitLab 15.0 so you can keep your certificate-based integration enabled. However, the feature flag will be disabled by default, so this change is a **breaking change**.
As a self-managed customer, we are introducing the [feature flag](../administration/feature_flags.md#enable-or-disable-the-feature) `certificate_based_clusters` in GitLab 15.0 so you can keep your certificate-based integration enabled. However, the feature flag will be disabled by default, so this change is a **breaking change**.
In GitLab 16.0 we will remove both the feature and its related code. Until the final removal in 16.0, features built on this integration will continue to work, if you enable the feature flag. Until the feature is removed, GitLab will continue to fix security and critical issues as they arise.

View file

@ -70,6 +70,29 @@ curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/a
]
```
## Get single personal access token by ID
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/362239) in GitLab 15.1.
Get a single personal access token by its ID. Users can get their own tokens.
Administrators can get any token.
```plaintext
GET /personal_access_tokens/:id
```
| Attribute | Type | required | Description |
|-----------|---------|----------|---------------------|
| `id` | integer/string | yes | ID of personal access token |
```shell
curl --request GET --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/personal_access_tokens/<id>"
```
### Responses
- `401: Unauthorized` if the user doesn't have access to the token they're requesting the ID or if the token with matching ID doesn't exist.
## Revoke a personal access token
Revoke a personal access token by either:

View file

@ -189,3 +189,23 @@ the middleware level, this can be used at the controller or API level.
See the `CheckRateLimit` concern for use in controllers. In other parts of the code
the `Gitlab::ApplicationRateLimiter` module can be called directly.
## Next rate limiting architecture
In May 2022 we've started working on the next iteration of our application
limits framework using a forward looking rate limiting architecture.
We are working on defining new requirements and designing the next
architecture, so if you need new functionalities to add new limits, instead of
building them right now, consider contributing to the
[Rate Limiting Architecture Working Group](https://about.gitlab.com/company/team/structure/working-groups/rate-limit-architecture/)
Examples of what features we might want to build into the next iteration of
rate limiting architecture:
1. Making it possible to define and override limits per namespace / per plan.
1. Automatically generating documentation about what limits are implemented and
what the defaults are.
1. Defining limits in a single place that is easy to find an explore.
1. Soft and hard limits, with support for notifying users when a limit is
approaching.

View file

@ -164,12 +164,26 @@ data from the database, file system, or object storage, you should get an extra
of eyes on your changes. When you are defining a new retention policy, you
should double check with PMs and EMs.
### Get your design reviewed
When you are designing a subsystem for pipeline processing and transitioning
CI/CD statuses, request an additional opinion on the design from a Verify maintainer (`@gitlab-org/maintainers/cicd-verify`)
as early as possible and hold others accountable for doing the same. Having your
design reviewed by a Verify maintainer helps to identify any blind spots you might
have overlooked as early as possible and possibly leads to a better solution.
By having the design reviewed before any development work is started, it also helps to
make merge request review more efficient. You would be less likely to encounter
significantly differing opinions or change requests during the maintainer review
if the design has been reviewed by a Verify maintainer. As a result, the merge request
could be merged sooner.
### Get your changes reviewed
When your merge request is ready for reviews you must assign
reviewers and then maintainers. Depending on the complexity of a change, you
might want to involve the people that know the most about the codebase area you are
changing. We do have many domain experts in Verify and it is absolutely acceptable to
changing. We do have many domain experts and maintainers in Verify and it is absolutely acceptable to
ask them to review your code when you are not certain if a reviewer or
maintainer assigned by the Reviewer Roulette has enough context about the
change.
@ -229,7 +243,3 @@ There are much more likely scenarios that
can have disastrous consequences. GitLab CI/CD is being used by companies
building medical, aviation, and automotive software. Continuous Integration is
a mission critical part of software engineering.
When you are working on a subsystem for pipeline processing and transitioning
CI/CD statuses, request an additional opinion on the design from a domain expert
as early as possible and hold others accountable for doing the same.

View file

@ -1654,7 +1654,7 @@ changes to your code, settings, or workflow.
The certificate-based integration with Kubernetes [will be deprecated and removed](https://about.gitlab.com/blog/2021/11/15/deprecating-the-cert-based-kubernetes-integration/).
As a self-managed customer, we are introducing a feature flag in GitLab 15.0 so you can keep your certificate-based integration enabled. However, the feature flag will be disabled by default, so this change is a **breaking change**.
As a self-managed customer, we are introducing the [feature flag](../administration/feature_flags.md#enable-or-disable-the-feature) `certificate_based_clusters` in GitLab 15.0 so you can keep your certificate-based integration enabled. However, the feature flag will be disabled by default, so this change is a **breaking change**.
In GitLab 16.0 we will remove both the feature and its related code. Until the final removal in 16.0, features built on this integration will continue to work, if you enable the feature flag. Until the feature is removed, GitLab will continue to fix security and critical issues as they arise.

View file

@ -54,6 +54,14 @@ module API
present paginate(tokens), with: Entities::PersonalAccessToken
end
get ':id' do
token = PersonalAccessToken.find_by_id(params[:id])
unauthorized! unless token && Ability.allowed?(current_user, :read_user_personal_access_tokens, token.user)
present token, with: Entities::PersonalAccessToken
end
delete 'self' do
revoke_token(access_token)
end

View file

@ -42,7 +42,9 @@ module Gitlab
end
def fetch_local_content
context.project.repository.blob_data_at(context.sha, location)
context.logger.instrument(:config_file_fetch_local_content) do
context.project.repository.blob_data_at(context.sha, location)
end
rescue GRPC::InvalidArgument
errors.push("Sha #{context.sha} is not valid!")

View file

@ -65,7 +65,9 @@ module Gitlab
return unless can_access_local_content?
return unless sha
project.repository.blob_data_at(sha, location)
context.logger.instrument(:config_file_fetch_project_content) do
project.repository.blob_data_at(sha, location)
end
rescue GRPC::NotFound, GRPC::Internal
nil
end

View file

@ -40,7 +40,9 @@ module Gitlab
def fetch_remote_content
begin
response = Gitlab::HTTP.get(location)
response = context.logger.instrument(:config_file_fetch_remote_content) do
Gitlab::HTTP.get(location)
end
rescue SocketError
errors.push("Remote file `#{masked_location}` could not be fetched because of a socket error!")
rescue Timeout::Error

View file

@ -52,7 +52,9 @@ module Gitlab
end
def fetch_template_content
Gitlab::Template::GitlabCiYmlTemplate.find(template_name, context.project)&.content
context.logger.instrument(:config_file_fetch_template_content) do
Gitlab::Template::GitlabCiYmlTemplate.find(template_name, context.project)&.content
end
end
def masked_raw

View file

@ -24,7 +24,7 @@ module Gitlab
instrumented_payload = Gitlab::Usage::ServicePing::InstrumentedPayload.new(instrumented_metrics_key_paths, output_method).build
old_payload.deep_merge(instrumented_payload)
old_payload.with_indifferent_access.deep_merge(instrumented_payload)
end
def all_metrics_values(cached)

View file

@ -45360,12 +45360,6 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
msgid "mrWidget|Open in Gitpod"
msgstr ""
msgid "mrWidget|Open in Web IDE"
msgstr ""
msgid "mrWidget|Please restore it or use a different %{type} branch."
msgstr ""
@ -45384,9 +45378,6 @@ msgstr ""
msgid "mrWidget|Remove from merge train"
msgstr ""
msgid "mrWidget|Request to merge"
msgstr ""
msgid "mrWidget|Resolve conflicts"
msgstr ""
@ -45462,9 +45453,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
msgid "mrWidget|into"
msgstr ""
msgid "must be a Debian package"
msgstr ""

View file

@ -115,12 +115,9 @@ module QA
element :description_content
end
view 'app/views/projects/merge_requests/_mr_box.html.haml' do
element :title_content, required: true
end
view 'app/views/projects/merge_requests/_mr_title.html.haml' do
element :edit_button
element :title_content, required: true
end
view 'app/views/projects/merge_requests/show.html.haml' do

View file

@ -10,16 +10,6 @@ RSpec.describe 'Project > Merge request > View user status' do
subject { visit merge_request_path(merge_request) }
describe 'the status of the merge request author' do
before do
stub_feature_flags(updated_mr_header: false)
end
it_behaves_like 'showing user status' do
let(:user_with_status) { merge_request.author }
end
end
context 'for notes', :js do
describe 'the status of the author of a note on a merge request' do
let(:note) { create(:note, noteable: merge_request, project: project, author: create(:user)) }

View file

@ -206,6 +206,19 @@ describe('Client side Markdown processing', () => {
),
),
},
{
markdown: `
<i class="foo">
*bar*
</i>
`,
expectedDoc: doc(
paragraph(
sourceAttrs('0:28', '<i class="foo">\n *bar*\n</i>'),
italic(sourceAttrs('0:28', '<i class="foo">\n *bar*\n</i>'), '\n *bar*\n'),
),
),
},
{
markdown: '[GitLab](https://gitlab.com "Go to GitLab")',
expectedDoc: doc(
@ -342,8 +355,14 @@ two
expectedDoc: doc(
bulletList(
sourceAttrs('0:27', '- List item 1\n- List item 2'),
listItem(sourceAttrs('0:13', '- List item 1'), paragraph('List item 1')),
listItem(sourceAttrs('14:27', '- List item 2'), paragraph('List item 2')),
listItem(
sourceAttrs('0:13', '- List item 1'),
paragraph(sourceAttrs('0:13', '- List item 1'), 'List item 1'),
),
listItem(
sourceAttrs('14:27', '- List item 2'),
paragraph(sourceAttrs('14:27', '- List item 2'), 'List item 2'),
),
),
),
},
@ -355,8 +374,14 @@ two
expectedDoc: doc(
bulletList(
sourceAttrs('0:27', '* List item 1\n* List item 2'),
listItem(sourceAttrs('0:13', '* List item 1'), paragraph('List item 1')),
listItem(sourceAttrs('14:27', '* List item 2'), paragraph('List item 2')),
listItem(
sourceAttrs('0:13', '* List item 1'),
paragraph(sourceAttrs('0:13', '* List item 1'), 'List item 1'),
),
listItem(
sourceAttrs('14:27', '* List item 2'),
paragraph(sourceAttrs('14:27', '* List item 2'), 'List item 2'),
),
),
),
},
@ -368,8 +393,14 @@ two
expectedDoc: doc(
bulletList(
sourceAttrs('0:27', '+ List item 1\n+ List item 2'),
listItem(sourceAttrs('0:13', '+ List item 1'), paragraph('List item 1')),
listItem(sourceAttrs('14:27', '+ List item 2'), paragraph('List item 2')),
listItem(
sourceAttrs('0:13', '+ List item 1'),
paragraph(sourceAttrs('0:13', '+ List item 1'), 'List item 1'),
),
listItem(
sourceAttrs('14:27', '+ List item 2'),
paragraph(sourceAttrs('14:27', '+ List item 2'), 'List item 2'),
),
),
),
},
@ -381,8 +412,14 @@ two
expectedDoc: doc(
orderedList(
sourceAttrs('0:29', '1. List item 1\n1. List item 2'),
listItem(sourceAttrs('0:14', '1. List item 1'), paragraph('List item 1')),
listItem(sourceAttrs('15:29', '1. List item 2'), paragraph('List item 2')),
listItem(
sourceAttrs('0:14', '1. List item 1'),
paragraph(sourceAttrs('0:14', '1. List item 1'), 'List item 1'),
),
listItem(
sourceAttrs('15:29', '1. List item 2'),
paragraph(sourceAttrs('15:29', '1. List item 2'), 'List item 2'),
),
),
),
},
@ -394,8 +431,14 @@ two
expectedDoc: doc(
orderedList(
sourceAttrs('0:29', '1. List item 1\n2. List item 2'),
listItem(sourceAttrs('0:14', '1. List item 1'), paragraph('List item 1')),
listItem(sourceAttrs('15:29', '2. List item 2'), paragraph('List item 2')),
listItem(
sourceAttrs('0:14', '1. List item 1'),
paragraph(sourceAttrs('0:14', '1. List item 1'), 'List item 1'),
),
listItem(
sourceAttrs('15:29', '2. List item 2'),
paragraph(sourceAttrs('15:29', '2. List item 2'), 'List item 2'),
),
),
),
},
@ -407,8 +450,14 @@ two
expectedDoc: doc(
orderedList(
sourceAttrs('0:29', '1) List item 1\n2) List item 2'),
listItem(sourceAttrs('0:14', '1) List item 1'), paragraph('List item 1')),
listItem(sourceAttrs('15:29', '2) List item 2'), paragraph('List item 2')),
listItem(
sourceAttrs('0:14', '1) List item 1'),
paragraph(sourceAttrs('0:14', '1) List item 1'), 'List item 1'),
),
listItem(
sourceAttrs('15:29', '2) List item 2'),
paragraph(sourceAttrs('15:29', '2) List item 2'), 'List item 2'),
),
),
),
},
@ -422,10 +471,13 @@ two
sourceAttrs('0:33', '- List item 1\n - Sub list item 1'),
listItem(
sourceAttrs('0:33', '- List item 1\n - Sub list item 1'),
paragraph('List item 1\n'),
paragraph(sourceAttrs('0:33', '- List item 1\n - Sub list item 1'), 'List item 1\n'),
bulletList(
sourceAttrs('16:33', '- Sub list item 1'),
listItem(sourceAttrs('16:33', '- Sub list item 1'), paragraph('Sub list item 1')),
listItem(
sourceAttrs('16:33', '- Sub list item 1'),
paragraph(sourceAttrs('16:33', '- Sub list item 1'), 'Sub list item 1'),
),
),
),
),
@ -477,8 +529,14 @@ two
sourceAttrs('0:31', '> - List item 1\n> - List item 2'),
bulletList(
sourceAttrs('2:31', '- List item 1\n> - List item 2'),
listItem(sourceAttrs('2:15', '- List item 1'), paragraph('List item 1')),
listItem(sourceAttrs('18:31', '- List item 2'), paragraph('List item 2')),
listItem(
sourceAttrs('2:15', '- List item 1'),
paragraph(sourceAttrs('2:15', '- List item 1'), 'List item 1'),
),
listItem(
sourceAttrs('18:31', '- List item 2'),
paragraph(sourceAttrs('18:31', '- List item 2'), 'List item 2'),
),
),
),
),

View file

@ -1,176 +0,0 @@
import { shallowMount, mount } from '@vue/test-utils';
import Header from '~/vue_merge_request_widget/components/mr_widget_header.vue';
describe('MRWidgetHeader', () => {
let wrapper;
const createComponent = (propsData = {}) => {
wrapper = shallowMount(Header, {
propsData,
});
};
afterEach(() => {
wrapper.destroy();
gon.relative_url_root = '';
});
const commonMrProps = {
divergedCommitsCount: 1,
sourceBranch: 'mr-widget-refactor',
sourceBranchLink: '<a href="/foo/bar/mr-widget-refactor">Link</a>',
targetBranch: 'main',
targetBranchPath: '/foo/bar/main',
statusPath: 'abc',
};
describe('computed', () => {
describe('shouldShowCommitsBehindText', () => {
it('return true when there are divergedCommitsCount', () => {
createComponent({
mr: {
divergedCommitsCount: 12,
sourceBranch: 'mr-widget-refactor',
sourceBranchLink: '<a href="/foo/bar/mr-widget-refactor">Link</a>',
targetBranch: 'main',
statusPath: 'abc',
},
});
expect(wrapper.vm.shouldShowCommitsBehindText).toBe(true);
});
it('returns false where there are no divergedComits count', () => {
createComponent({
mr: {
divergedCommitsCount: 0,
sourceBranch: 'mr-widget-refactor',
sourceBranchLink: '<a href="/foo/bar/mr-widget-refactor">Link</a>',
targetBranch: 'main',
statusPath: 'abc',
},
});
expect(wrapper.vm.shouldShowCommitsBehindText).toBe(false);
});
});
describe('commitsBehindText', () => {
it('returns singular when there is one commit', () => {
wrapper = mount(Header, {
propsData: {
mr: commonMrProps,
},
});
expect(wrapper.find('.diverged-commits-count').element.innerHTML).toBe(
'The source branch is <a href="/foo/bar/main" class="gl-link">1 commit behind</a> the target branch',
);
});
it('returns plural when there is more than one commit', () => {
wrapper = mount(Header, {
propsData: {
mr: {
...commonMrProps,
divergedCommitsCount: 2,
},
},
});
expect(wrapper.find('.diverged-commits-count').element.innerHTML).toBe(
'The source branch is <a href="/foo/bar/main" class="gl-link">2 commits behind</a> the target branch',
);
});
});
});
describe('template', () => {
describe('common elements', () => {
beforeEach(() => {
createComponent({
mr: {
divergedCommitsCount: 12,
sourceBranch: 'mr-widget-refactor',
sourceBranchLink: '<a href="/foo/bar/mr-widget-refactor">mr-widget-refactor</a>',
sourceBranchRemoved: false,
targetBranchPath: 'foo/bar/commits-path',
targetBranchTreePath: 'foo/bar/tree/path',
targetBranch: 'main',
isOpen: true,
emailPatchesPath: '/mr/email-patches',
plainDiffPath: '/mr/plainDiffPath',
statusPath: 'abc',
},
});
});
it('renders source branch link', () => {
expect(wrapper.find('.js-source-branch').html()).toContain(
'<a href="/foo/bar/mr-widget-refactor">mr-widget-refactor</a>',
);
});
it('renders clipboard button', () => {
expect(wrapper.find('[data-testid="mr-widget-copy-clipboard"]')).not.toBe(null);
});
it('renders target branch', () => {
expect(wrapper.find('.js-target-branch').text().trim()).toBe('main');
});
});
describe('without diverged commits', () => {
beforeEach(() => {
createComponent({
mr: {
divergedCommitsCount: 0,
sourceBranch: 'mr-widget-refactor',
sourceBranchLink: '<a href="/foo/bar/mr-widget-refactor">mr-widget-refactor</a>',
sourceBranchRemoved: false,
targetBranchPath: 'foo/bar/commits-path',
targetBranchTreePath: 'foo/bar/tree/path',
targetBranch: 'main',
isOpen: true,
emailPatchesPath: '/mr/email-patches',
plainDiffPath: '/mr/plainDiffPath',
statusPath: 'abc',
},
});
});
it('does not render diverged commits info', () => {
expect(wrapper.find('.diverged-commits-count').exists()).toBe(false);
});
});
describe('with diverged commits', () => {
beforeEach(() => {
wrapper = mount(Header, {
propsData: {
mr: {
...commonMrProps,
divergedCommitsCount: 12,
sourceBranchRemoved: false,
targetBranchPath: 'foo/bar/commits-path',
targetBranchTreePath: 'foo/bar/tree/path',
isOpen: true,
emailPatchesPath: '/mr/email-patches',
plainDiffPath: '/mr/plainDiffPath',
},
},
});
});
it('renders diverged commits info', () => {
expect(wrapper.find('.diverged-commits-count').text().trim()).toBe(
'The source branch is 12 commits behind the target branch',
);
expect(wrapper.find('.diverged-commits-count a').text().trim()).toBe('12 commits behind');
expect(wrapper.find('.diverged-commits-count a').attributes('href')).toBe(
wrapper.vm.mr.targetBranchPath,
);
});
});
});
});

View file

@ -441,85 +441,38 @@ RSpec.describe IssuesHelper do
end
describe '#status_box_class' do
context 'when updated_mr_header feature flag is enabled' do
before do
stub_feature_flags(updated_mr_header: true)
end
context 'when object is expired' do
it 'returns orange background' do
milestone = build(:milestone, due_date: Date.today.prev_month)
expect(helper.status_box_class(milestone)).to eq('gl-bg-orange-500')
end
end
context 'when object is merged' do
it 'returns blue background' do
merge_request = build(:merge_request, :merged)
expect(helper.status_box_class(merge_request)).to eq('badge-info')
end
end
context 'when object is closed' do
it 'returns red background' do
merge_request = build(:merge_request, :closed)
expect(helper.status_box_class(merge_request)).to eq('badge-danger')
end
end
context 'when object is upcoming' do
it 'returns gray background' do
milestone = build(:milestone, start_date: Date.today.next_month)
expect(helper.status_box_class(milestone)).to eq('gl-bg-gray-500')
end
end
context 'when object is opened' do
it 'returns green background' do
merge_request = build(:merge_request, :opened)
expect(helper.status_box_class(merge_request)).to eq('badge-success')
end
context 'when object is expired' do
it 'returns orange background' do
milestone = build(:milestone, due_date: Date.today.prev_month)
expect(helper.status_box_class(milestone)).to eq('gl-bg-orange-500')
end
end
context 'when updated_mr_header feature flag is disabled' do
before do
stub_feature_flags(updated_mr_header: false)
context 'when object is merged' do
it 'returns blue background' do
merge_request = build(:merge_request, :merged)
expect(helper.status_box_class(merge_request)).to eq('badge-info')
end
end
context 'when object is expired' do
it 'returns orange background' do
milestone = build(:milestone, due_date: Date.today.prev_month)
expect(helper.status_box_class(milestone)).to eq('gl-bg-orange-500')
end
context 'when object is closed' do
it 'returns red background' do
merge_request = build(:merge_request, :closed)
expect(helper.status_box_class(merge_request)).to eq('badge-danger')
end
end
context 'when object is merged' do
it 'returns blue background' do
merge_request = build(:merge_request, :merged)
expect(helper.status_box_class(merge_request)).to eq('gl-bg-blue-500')
end
context 'when object is upcoming' do
it 'returns gray background' do
milestone = build(:milestone, start_date: Date.today.next_month)
expect(helper.status_box_class(milestone)).to eq('gl-bg-gray-500')
end
end
context 'when object is closed' do
it 'returns red background' do
merge_request = build(:merge_request, :closed)
expect(helper.status_box_class(merge_request)).to eq('gl-bg-red-500')
end
end
context 'when object is upcoming' do
it 'returns gray background' do
milestone = build(:milestone, start_date: Date.today.next_month)
expect(helper.status_box_class(milestone)).to eq('gl-bg-gray-500')
end
end
context 'when object is opened' do
it 'returns green background' do
merge_request = build(:merge_request, :opened)
expect(helper.status_box_class(merge_request)).to eq('gl-bg-green-500')
end
context 'when object is opened' do
it 'returns green background' do
merge_request = build(:merge_request, :opened)
expect(helper.status_box_class(merge_request)).to eq('badge-success')
end
end
end

View file

@ -6,7 +6,7 @@ RSpec.describe Gitlab::Ci::Config::External::Mapper do
include StubRequests
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { create(:user) }
let_it_be(:user) { project.owner }
let(:local_file) { '/lib/gitlab/ci/templates/non-existent-file.yml' }
let(:remote_url) { 'https://gitlab.com/gitlab-org/gitlab-foss/blob/1234/.gitlab-ci-1.yml' }
@ -34,6 +34,19 @@ RSpec.describe Gitlab::Ci::Config::External::Mapper do
describe '#process' do
subject(:process) { mapper.process }
shared_examples 'logging config file fetch' do |key, count|
it 'propagates the pipeline logger' do
process
fetch_content_log_count = mapper
.logger
.observations_hash
.dig(key, 'count')
expect(fetch_content_log_count).to eq(count)
end
end
context "when single 'include' keyword is defined" do
context 'when the string is a local file' do
let(:values) do
@ -45,6 +58,8 @@ RSpec.describe Gitlab::Ci::Config::External::Mapper do
expect(subject).to contain_exactly(
an_instance_of(Gitlab::Ci::Config::External::File::Local))
end
it_behaves_like 'logging config file fetch', 'config_file_fetch_local_content_duration_s', 1
end
context 'when the key is a local file hash' do
@ -68,6 +83,8 @@ RSpec.describe Gitlab::Ci::Config::External::Mapper do
expect(subject).to contain_exactly(
an_instance_of(Gitlab::Ci::Config::External::File::Remote))
end
it_behaves_like 'logging config file fetch', 'config_file_fetch_remote_content_duration_s', 1
end
context 'when the key is a remote file hash' do
@ -92,6 +109,8 @@ RSpec.describe Gitlab::Ci::Config::External::Mapper do
expect(subject).to contain_exactly(
an_instance_of(Gitlab::Ci::Config::External::File::Template))
end
it_behaves_like 'logging config file fetch', 'config_file_fetch_template_content_duration_s', 1
end
context 'when the key is a hash of file and remote' do
@ -118,6 +137,8 @@ RSpec.describe Gitlab::Ci::Config::External::Mapper do
expect(subject).to contain_exactly(
an_instance_of(Gitlab::Ci::Config::External::File::Project))
end
it_behaves_like 'logging config file fetch', 'config_file_fetch_project_content_duration_s', 1
end
context "when the key is project's files" do
@ -131,6 +152,8 @@ RSpec.describe Gitlab::Ci::Config::External::Mapper do
an_instance_of(Gitlab::Ci::Config::External::File::Project),
an_instance_of(Gitlab::Ci::Config::External::File::Project))
end
it_behaves_like 'logging config file fetch', 'config_file_fetch_project_content_duration_s', 2
end
end

View file

@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe Gitlab::Usage::ServicePingReport, :use_clean_rails_memory_store_caching do
include UsageDataHelpers
let(:usage_data) { { uuid: "1111", counts: { issue: 0 } } }
let(:usage_data) { { uuid: "1111", counts: { issue: 0 } }.deep_stringify_keys }
before do
allow_next_instance_of(Gitlab::Usage::ServicePing::PayloadKeysProcessor) do |instance|
@ -20,7 +20,7 @@ RSpec.describe Gitlab::Usage::ServicePingReport, :use_clean_rails_memory_store_c
context 'all_metrics_values' do
it 'generates the service ping when there are no missing values' do
expect(Gitlab::UsageData).to receive(:data).and_return(usage_data)
expect(described_class.for(output: :all_metrics_values)).to eq({ uuid: "1111", counts: { issue: 0 } })
expect(described_class.for(output: :all_metrics_values)).to eq({ uuid: "1111", counts: { issue: 0 } }.deep_stringify_keys)
end
it 'generates the service ping with the missing values' do
@ -33,7 +33,24 @@ RSpec.describe Gitlab::Usage::ServicePingReport, :use_clean_rails_memory_store_c
end
expect(Gitlab::UsageData).to receive(:data).and_return(usage_data)
expect(described_class.for(output: :all_metrics_values)).to eq({ uuid: "1111", counts: { issue: 0, boards: 1 } })
expect(described_class.for(output: :all_metrics_values)).to eq({ uuid: "1111", counts: { issue: 0, boards: 1 } }.deep_stringify_keys)
end
context 'with usage data payload with symbol keys and instrumented payload with string keys' do
let(:usage_data) { { uuid: "1111", counts: { issue: 0 } } }
it 'correctly merges string and symbol keys' do
expect_next_instance_of(Gitlab::Usage::ServicePing::PayloadKeysProcessor, usage_data) do |instance|
expect(instance).to receive(:missing_instrumented_metrics_key_paths).and_return(['counts.boards'])
end
expect_next_instance_of(Gitlab::Usage::ServicePing::InstrumentedPayload, ['counts.boards'], :with_value) do |instance|
expect(instance).to receive(:build).and_return({ 'counts' => { 'boards' => 1 } })
end
expect(Gitlab::UsageData).to receive(:data).and_return(usage_data)
expect(described_class.for(output: :all_metrics_values)).to eq({ uuid: "1111", counts: { issue: 0, boards: 1 } }.deep_stringify_keys)
end
end
end
@ -54,9 +71,9 @@ RSpec.describe Gitlab::Usage::ServicePingReport, :use_clean_rails_memory_store_c
end
context 'when using cached' do
context 'for cached: true' do
let(:new_usage_data) { { uuid: "1112" } }
let(:new_usage_data) { { 'uuid' => '1112' } }
context 'for cached: true' do
it 'caches the values' do
allow(Gitlab::UsageData).to receive(:data).and_return(usage_data, new_usage_data)
@ -78,8 +95,6 @@ RSpec.describe Gitlab::Usage::ServicePingReport, :use_clean_rails_memory_store_c
end
context 'when no caching' do
let(:new_usage_data) { { uuid: "1112" } }
it 'returns fresh data' do
allow(Gitlab::UsageData).to receive(:data).and_return(usage_data, new_usage_data)

View file

@ -3740,7 +3740,7 @@ RSpec.describe User do
end
context 'has owned groups' do
let_it_be(:group) { create(:group) }
let(:group) { create(:group) }
before do
group.add_owner(user)
@ -3749,11 +3749,23 @@ RSpec.describe User do
context 'not solo owner' do
let_it_be(:user2) { create(:user) }
before do
group.add_owner(user2)
context 'with another direct owner' do
before do
group.add_owner(user2)
end
it { is_expected.to be_empty }
end
it { is_expected.to be_empty }
context 'with an inherited owner' do
let_it_be(:group) { create(:group, :nested) }
before do
group.parent.add_owner(user2)
end
it { is_expected.to be_empty }
end
end
context 'solo owner' do

View file

@ -73,6 +73,61 @@ RSpec.describe API::PersonalAccessTokens do
end
end
describe 'GET /personal_access_tokens/:id' do
let_it_be(:user_token) { create(:personal_access_token, user: current_user) }
let_it_be(:user_token_path) { "/personal_access_tokens/#{user_token.id}" }
let_it_be(:invalid_path) { "/personal_access_tokens/#{non_existing_record_id}" }
context 'when current_user is an administrator', :enable_admin_mode do
let_it_be(:admin_user) { create(:admin) }
let_it_be(:admin_token) { create(:personal_access_token, user: admin_user) }
let_it_be(:admin_path) { "/personal_access_tokens/#{admin_token.id}" }
it 'returns admins own PAT by id' do
get api(admin_path, admin_user)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['id']).to eq(admin_token.id)
end
it 'returns a different users PAT by id' do
get api(user_token_path, admin_user)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['id']).to eq(user_token.id)
end
it 'fails to return PAT because no PAT exists with this id' do
get api(invalid_path, admin_user)
expect(response).to have_gitlab_http_status(:unauthorized)
end
end
context 'when current_user is not an administrator' do
let_it_be(:other_users_path) { "/personal_access_tokens/#{token1.id}" }
it 'returns users own PAT by id' do
get api(user_token_path, current_user)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['id']).to eq(user_token.id)
end
it 'fails to return other users PAT by id' do
get api(other_users_path, current_user)
expect(response).to have_gitlab_http_status(:unauthorized)
end
it 'fails to return PAT because no PAT exists with this id' do
get api(invalid_path, current_user)
expect(response).to have_gitlab_http_status(:unauthorized)
end
end
end
describe 'DELETE /personal_access_tokens/self' do
let(:path) { '/personal_access_tokens/self' }
let(:token) { create(:personal_access_token, user: current_user) }

View file

@ -2098,7 +2098,7 @@ RSpec.describe API::Users do
describe "DELETE /users/:id" do
let_it_be(:issue) { create(:issue, author: user) }
it "deletes user", :sidekiq_might_not_need_inline do
it "deletes user", :sidekiq_inline do
namespace_id = user.namespace.id
perform_enqueued_jobs { delete api("/users/#{user.id}", admin) }
@ -2119,11 +2119,27 @@ RSpec.describe API::Users do
end
context "hard delete enabled" do
it "delete user and group", :sidekiq_might_not_need_inline do
it "delete user and group", :sidekiq_inline do
perform_enqueued_jobs { delete api("/users/#{user.id}?hard_delete=true", admin) }
expect(response).to have_gitlab_http_status(:no_content)
expect(Group.exists?(group.id)).to be_falsy
end
context "with subgroup owning" do
let(:parent_group) { create(:group) }
let(:subgroup) { create(:group, parent: parent_group) }
before do
parent_group.add_owner(create(:user))
subgroup.add_owner(user)
end
it "delete only user", :sidekiq_inline do
perform_enqueued_jobs { delete api("/users/#{user.id}?hard_delete=true", admin) }
expect(response).to have_gitlab_http_status(:no_content)
expect(Group.exists?(subgroup.id)).to be_truthy
end
end
end
end

View file

@ -215,6 +215,27 @@ RSpec.describe Users::DestroyService do
end
end
context 'deletions with inherited group owners' do
let(:group) { create(:group, :nested) }
let(:user) { create(:user) }
let(:inherited_owner) { create(:user) }
before do
group.parent.add_owner(inherited_owner)
group.add_owner(user)
service.execute(user, delete_solo_owned_groups: true)
end
it 'does not delete the group' do
expect(Group.exists?(id: group)).to be_truthy
end
it 'deletes the user' do
expect(User.exists?(id: user)).to be_falsey
end
end
context 'migrating associated records' do
let!(:issue) { create(:issue, author: user) }

View file

@ -31,13 +31,37 @@ RSpec.describe Tooling::FindCodeowners do
end
end.to output(<<~CODEOWNERS).to_stdout
[Section name]
/dir0/dir1 @group
/dir0/dir1/ @group
/file @group
CODEOWNERS
end
end
describe '#load_definitions' do
before do
allow(subject).to receive(:load_config).and_return(
{
'[Authentication and Authorization]': {
'@gitlab-org/manage/authentication-and-authorization': {
allow: {
keywords: %w[password auth token],
patterns:
%w[
/{,ee/}app/**/*%{keyword}*{,/**/*}
/{,ee/}config/**/*%{keyword}*{,/**/*}
/{,ee/}lib/**/*%{keyword}*{,/**/*}
]
},
deny: {
keywords: %w[*author.* *author_* *authored*],
patterns: ['%{keyword}']
}
}
}
}
)
end
it 'expands the allow and deny list with keywords and patterns' do
subject.load_definitions.each do |section, group_defintions|
group_defintions.each do |group, definitions|
@ -54,56 +78,20 @@ RSpec.describe Tooling::FindCodeowners do
expect(auth).to eq(
allow: %w[
/{,ee/}app/**/*password*{/**/*,}
/{,ee/}config/**/*password*{/**/*,}
/{,ee/}lib/**/*password*{/**/*,}
/{,ee/}app/**/*auth*{/**/*,}
/{,ee/}config/**/*auth*{/**/*,}
/{,ee/}lib/**/*auth*{/**/*,}
/{,ee/}app/**/*token*{/**/*,}
/{,ee/}config/**/*token*{/**/*,}
/{,ee/}lib/**/*token*{/**/*,}
/{,ee/}app/**/*password*{,/**/*}
/{,ee/}config/**/*password*{,/**/*}
/{,ee/}lib/**/*password*{,/**/*}
/{,ee/}app/**/*auth*{,/**/*}
/{,ee/}config/**/*auth*{,/**/*}
/{,ee/}lib/**/*auth*{,/**/*}
/{,ee/}app/**/*token*{,/**/*}
/{,ee/}config/**/*token*{,/**/*}
/{,ee/}lib/**/*token*{,/**/*}
],
deny: %w[
**/*author.*{/**/*,}
**/*author_*{/**/*,}
**/*authored*{/**/*,}
**/*authoring*{/**/*,}
**/*.png*{/**/*,}
**/*.svg*{/**/*,}
**/*deploy_token*{/**/*,}
**/*runner{,s}_token*{/**/*,}
**/*job_token*{/**/*,}
**/*autocomplete_tokens*{/**/*,}
**/*dast_site_token*{/**/*,}
**/*reset_prometheus_token*{/**/*,}
**/*reset_registration_token*{/**/*,}
**/*runners_registration_token*{/**/*,}
**/*terraform_registry_token*{/**/*,}
**/*tokenizer*{/**/*,}
**/*filtered_search*{/**/*,}
**/*/alert_management/*{/**/*,}
**/*/analytics/*{/**/*,}
**/*/bitbucket/*{/**/*,}
**/*/clusters/*{/**/*,}
**/*/clusters_list/*{/**/*,}
**/*/dast/*{/**/*,}
**/*/dast_profiles/*{/**/*,}
**/*/dast_site_tokens/*{/**/*,}
**/*/dast_site_validation/*{/**/*,}
**/*/dependency_proxy/*{/**/*,}
**/*/error_tracking/*{/**/*,}
**/*/google_api/*{/**/*,}
**/*/google_cloud/*{/**/*,}
**/*/jira_connect/*{/**/*,}
**/*/kubernetes/*{/**/*,}
**/*/protected_environments/*{/**/*,}
**/*/config/feature_flags/development/jira_connect_*{/**/*,}
**/*/config/metrics/*{/**/*,}
**/*/app/controllers/groups/dependency_proxy_auth_controller.rb*{/**/*,}
**/*/app/finders/ci/auth_job_finder.rb*{/**/*,}
**/*/ee/config/metrics/*{/**/*,}
**/*/lib/gitlab/conan_token.rb*{/**/*,}
*author.*
*author_*
*authored*
]
)
end
@ -159,12 +147,31 @@ RSpec.describe Tooling::FindCodeowners do
expected_flags =
::File::FNM_DOTMATCH | ::File::FNM_PATHNAME | ::File::FNM_EXTGLOB
expect(File).to receive(:fnmatch?).with(pattern, path, expected_flags)
expect(File).to receive(:fnmatch?)
.with("/**/#{pattern}", path, expected_flags)
subject.path_matches?(pattern, path)
end
end
describe '#normalize_pattern' do
it 'returns /**/* if the input is *' do
expect(subject.normalize_pattern('*')).to eq('/**/*')
end
it 'prepends /** if the input does not start with /' do
expect(subject.normalize_pattern('app')).to eq('/**/app')
end
it 'returns the pattern if the input starts with /' do
expect(subject.normalize_pattern('/app')).to eq('/app')
end
it 'appends **/* if the input ends with /' do
expect(subject.normalize_pattern('/app/')).to eq('/app/**/*')
end
end
describe '#consolidate_paths' do
before do
allow(subject).to receive(:find_dir_maxdepth_1).and_return(<<~LINES)

View file

@ -6,53 +6,52 @@
'@gitlab-org/manage/authentication-and-authorization':
allow:
keywords:
- password
- auth
- token
- 'password'
- 'auth'
- 'token'
patterns:
- '/{,ee/}app/**/*%{keyword}*{/**/*,}'
- '/{,ee/}config/**/*%{keyword}*{/**/*,}'
- '/{,ee/}lib/**/*%{keyword}*{/**/*,}'
- '/{,ee/}app/**/*%{keyword}*{,/**/*}'
- '/{,ee/}config/**/*%{keyword}*{,/**/*}'
- '/{,ee/}lib/**/*%{keyword}*{,/**/*}'
deny:
keywords:
- author.
- author_
- authored
- authoring
- .png
- .svg
- deploy_token
- runner{,s}_token
- job_token
- autocomplete_tokens
- dast_site_token
- reset_prometheus_token
- reset_registration_token
- runners_registration_token
- terraform_registry_token
- tokenizer
- filtered_search
- /alert_management/
- /analytics/
- /bitbucket/
- /clusters/
- /clusters_list/
- /dast/
- /dast_profiles/
- /dast_site_tokens/
- /dast_site_validation/
- /dependency_proxy/
- /error_tracking/
- /google_api/
- /google_cloud/
- /jira_connect/
- /kubernetes/
- /protected_environments/
- /config/feature_flags/development/jira_connect_
- /config/metrics/
- /app/controllers/groups/dependency_proxy_auth_controller.rb
- /app/finders/ci/auth_job_finder.rb
- /ee/config/metrics/
- /lib/gitlab/conan_token.rb
- '*author.*'
- '*author_*'
- '*authored*'
- '*authoring*'
- '*.png'
- '*.svg'
- '*deploy_token{,s}{*,/**/*}'
- '*runner{,s}_token*'
- '*job_token{,_scope}{*,/**/*}'
- '*autocomplete_tokens*'
- 'dast_site_token*'
- 'reset_prometheus_token*'
- 'reset_registration_token*'
- 'runners_registration_token{*,/**/*}'
- 'terraform_registry_token*'
- 'filtered_search{_bar,}/'
- 'alert_management/'
- 'analytics/'
- 'bitbucket/'
- 'clusters/'
- 'clusters_list/'
- 'dast/'
- 'dast_profiles/'
- 'dast_site_tokens/'
- 'dast_site_validation/'
- 'dependency_proxy/'
- 'error_tracking/'
- 'google_api/'
- 'google_cloud/'
- 'jira_connect/'
- 'kubernetes/'
- 'protected_environments/'
- '/config/feature_flags/development/jira_connect_*'
- '/config/metrics/'
- '/app/controllers/groups/dependency_proxy_auth_controller.rb'
- '/app/finders/ci/auth_job_finder.rb'
- '/ee/config/metrics/'
- '/lib/gitlab/conan_token.rb'
patterns:
- '**/*%{keyword}*{/**/*,}'
- '%{keyword}'

View file

@ -31,8 +31,14 @@ module Tooling
consolidated_again = consolidate_paths(consolidated)
end
consolidated.each do |file|
puts "/#{file.chomp} #{group}"
consolidated.each do |line|
path = line.chomp
if File.directory?(path)
puts "/#{path}/ #{group}"
else
puts "/#{path} #{group}"
end
end
end
end
@ -76,7 +82,27 @@ module Tooling
flags |= ::File::FNM_EXTGLOB
# END extension
::File.fnmatch?(pattern, path, flags)
::File.fnmatch?(normalize_pattern(pattern), path, flags)
end
# Copied from ee/lib/gitlab/code_owners/file.rb
def normalize_pattern(pattern)
# Remove `\` when escaping `\#`
pattern = pattern.sub(/\A\\#/, '#')
# Replace all whitespace preceded by a \ with a regular whitespace
pattern = pattern.gsub(/\\\s+/, ' ')
return '/**/*' if pattern == '*'
unless pattern.start_with?('/')
pattern = "/**/#{pattern}"
end
if pattern.end_with?('/')
pattern = "#{pattern}**/*"
end
pattern
end
def consolidate_paths(matched_files)