Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
afd476d5fd
commit
cac0926ddb
46 changed files with 592 additions and 664 deletions
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 [
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
];
|
||||
},
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
|
@ -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')">
|
||||
|
|
|
@ -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')"
|
||||
>
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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) }
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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" }
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
4
lib/gitlab/ci/config/external/file/local.rb
vendored
4
lib/gitlab/ci/config/external/file/local.rb
vendored
|
@ -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!")
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
4
lib/gitlab/ci/config/external/file/remote.rb
vendored
4
lib/gitlab/ci/config/external/file/remote.rb
vendored
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 ""
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)) }
|
||||
|
|
|
@ -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'),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
@ -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,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) }
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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) }
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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}'
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue