diff --git a/.gitlab/CODEOWNERS b/.gitlab/CODEOWNERS index ccf502edb5b7594469f97b42a612ecad87ac2c5c..e3c355ea274eae76e2eceb750e7c951aa6f2ac05 100644 --- a/.gitlab/CODEOWNERS +++ b/.gitlab/CODEOWNERS @@ -993,7 +993,7 @@ lib/gitlab/checks/** /app/assets/javascripts/pages/oauth/ /app/assets/javascripts/pages/omniauth_callbacks/ /app/assets/javascripts/pages/profiles/password_prompt/ -/app/assets/javascripts/pages/profiles/personal_access_tokens/ +/app/assets/javascripts/pages/user_settings/personal_access_tokens/ /app/assets/javascripts/pages/profiles/two_factor_auths/ /app/assets/javascripts/pages/projects/settings/access_tokens/ /app/assets/javascripts/pages/sessions/new/oauth_remember_me.js @@ -1019,7 +1019,7 @@ lib/gitlab/checks/** /app/controllers/omniauth_callbacks_controller.rb /app/controllers/passwords_controller.rb /app/controllers/profiles/passwords_controller.rb -/app/controllers/profiles/personal_access_tokens_controller.rb +/app/controllers/user_settings/personal_access_tokens_controller.rb /app/controllers/profiles/two_factor_auths_controller.rb /app/controllers/profiles/webauthn_registrations_controller.rb /app/controllers/projects/settings/access_tokens_controller.rb @@ -1091,7 +1091,7 @@ lib/gitlab/checks/** /app/views/notify/access_token_revoked_email.html.haml /app/views/notify/access_token_revoked_email.text.erb /app/views/profiles/passwords/ -/app/views/profiles/personal_access_tokens/ +/app/views/user_settings/personal_access_tokens/ /app/views/profiles/two_factor_auths/ /app/views/projects/mirrors/_authentication_method.html.haml /app/views/projects/settings/access_tokens/ diff --git a/.rubocop_todo/capybara/testid_finders.yml b/.rubocop_todo/capybara/testid_finders.yml index 07bea3ea04f8805754e3e23f80d390149493f2a1..da7014c2ee3bcdedbbb2001a89b9dffa25bc1ab2 100644 --- a/.rubocop_todo/capybara/testid_finders.yml +++ b/.rubocop_todo/capybara/testid_finders.yml @@ -38,7 +38,6 @@ Capybara/TestidFinders: - 'spec/features/profiles/keys_spec.rb' - 'spec/features/profiles/oauth_applications_spec.rb' - 'spec/features/profiles/password_spec.rb' - - 'spec/features/profiles/personal_access_tokens_spec.rb' - 'spec/features/profiles/user_creates_comment_template_spec.rb' - 'spec/features/profiles/user_deletes_comment_template_spec.rb' - 'spec/features/profiles/user_edit_profile_spec.rb' diff --git a/.rubocop_todo/layout/line_length.yml b/.rubocop_todo/layout/line_length.yml index cfae494dd3d9b2a2b235b82432572acde5694dcf..c699a035ae2eead481caedde93f9ebb129a0ba68 100644 --- a/.rubocop_todo/layout/line_length.yml +++ b/.rubocop_todo/layout/line_length.yml @@ -3198,7 +3198,6 @@ Layout/LineLength: - 'spec/features/oauth_login_spec.rb' - 'spec/features/user_settings/active_sessions_spec.rb' - 'spec/features/profiles/password_spec.rb' - - 'spec/features/profiles/personal_access_tokens_spec.rb' - 'spec/features/profiles/two_factor_auths_spec.rb' - 'spec/features/profiles/user_edit_profile_spec.rb' - 'spec/features/projects/artifacts/file_spec.rb' diff --git a/.rubocop_todo/rspec/feature_category.yml b/.rubocop_todo/rspec/feature_category.yml index 20265808dc59e2765bedaeaffa47612f09898baf..a9738fb77e63440df101b0bf04043d9e418e2e1c 100644 --- a/.rubocop_todo/rspec/feature_category.yml +++ b/.rubocop_todo/rspec/feature_category.yml @@ -1607,7 +1607,6 @@ RSpec/FeatureCategory: - 'spec/controllers/profiles/gpg_keys_controller_spec.rb' - 'spec/controllers/profiles/keys_controller_spec.rb' - 'spec/controllers/profiles/notifications_controller_spec.rb' - - 'spec/controllers/profiles/personal_access_tokens_controller_spec.rb' - 'spec/controllers/profiles/preferences_controller_spec.rb' - 'spec/controllers/profiles/webauthn_registrations_controller_spec.rb' - 'spec/controllers/profiles_controller_spec.rb' diff --git a/.rubocop_todo/rspec/verified_doubles.yml b/.rubocop_todo/rspec/verified_doubles.yml index 24b70629ae4f2156fbb73e0bf27bf7e50805647b..ffc0b2a3824be7aba5a59c5b144f87502fcf98ba 100644 --- a/.rubocop_todo/rspec/verified_doubles.yml +++ b/.rubocop_todo/rspec/verified_doubles.yml @@ -255,7 +255,6 @@ RSpec/VerifiedDoubles: - 'spec/features/help_pages_spec.rb' - 'spec/features/issuables/markdown_references/jira_spec.rb' - 'spec/features/markdown/markdown_spec.rb' - - 'spec/features/profiles/personal_access_tokens_spec.rb' - 'spec/features/projects/container_registry_spec.rb' - 'spec/features/projects/integrations/user_activates_jira_spec.rb' - 'spec/finders/ci/auth_job_finder_spec.rb' diff --git a/.rubocop_todo/style/class_and_module_children.yml b/.rubocop_todo/style/class_and_module_children.yml index fb5031f513cd37c616a7bb7d3e420d2a3b87f858..2feaa0d5f6eca760807a6d6aa3d7569b3dbc323b 100644 --- a/.rubocop_todo/style/class_and_module_children.yml +++ b/.rubocop_todo/style/class_and_module_children.yml @@ -112,7 +112,6 @@ Style/ClassAndModuleChildren: - 'app/controllers/profiles/keys_controller.rb' - 'app/controllers/profiles/notifications_controller.rb' - 'app/controllers/profiles/passwords_controller.rb' - - 'app/controllers/profiles/personal_access_tokens_controller.rb' - 'app/controllers/profiles/preferences_controller.rb' - 'app/controllers/profiles/two_factor_auths_controller.rb' - 'app/controllers/profiles/webauthn_registrations_controller.rb' diff --git a/app/assets/javascripts/pages/profiles/personal_access_tokens/index.js b/app/assets/javascripts/pages/user_settings/personal_access_tokens/index.js similarity index 100% rename from app/assets/javascripts/pages/profiles/personal_access_tokens/index.js rename to app/assets/javascripts/pages/user_settings/personal_access_tokens/index.js diff --git a/app/controllers/profiles/personal_access_tokens_controller.rb b/app/controllers/profiles/personal_access_tokens_controller.rb deleted file mode 100644 index 4b6e2f768fadbf8de2a1332c893803c3330daed3..0000000000000000000000000000000000000000 --- a/app/controllers/profiles/personal_access_tokens_controller.rb +++ /dev/null @@ -1,74 +0,0 @@ -# frozen_string_literal: true - -class Profiles::PersonalAccessTokensController < Profiles::ApplicationController - include RenderAccessTokens - - feature_category :system_access - - before_action :check_personal_access_tokens_enabled - - def index - set_index_vars - scopes = params[:scopes].split(',').map(&:squish).select(&:present?).map(&:to_sym) unless params[:scopes].nil? - @personal_access_token = finder.build( - name: params[:name], - scopes: scopes - ) - - respond_to do |format| - format.html - format.json do - render json: @active_access_tokens - end - end - end - - def create - result = ::PersonalAccessTokens::CreateService.new( - current_user: current_user, - target_user: current_user, - params: personal_access_token_params, - concatenate_errors: false - ).execute - - @personal_access_token = result.payload[:personal_access_token] - - if result.success? - render json: { new_token: @personal_access_token.token, - active_access_tokens: active_access_tokens }, status: :ok - else - render json: { errors: result.errors }, status: :unprocessable_entity - end - end - - def revoke - @personal_access_token = finder.find(params[:id]) - service = PersonalAccessTokens::RevokeService.new(current_user, token: @personal_access_token).execute - service.success? ? flash[:notice] = service.message : flash[:alert] = service.message - - redirect_to profile_personal_access_tokens_path - end - - private - - def finder(options = {}) - PersonalAccessTokensFinder.new({ user: current_user, impersonation: false }.merge(options)) - end - - def personal_access_token_params - params.require(:personal_access_token).permit(:name, :expires_at, scopes: []) - end - - def set_index_vars - @scopes = Gitlab::Auth.available_scopes_for(current_user) - @active_access_tokens = active_access_tokens - end - - def represent(tokens) - ::PersonalAccessTokenSerializer.new.represent(tokens) - end - - def check_personal_access_tokens_enabled - render_404 if Gitlab::CurrentSettings.personal_access_tokens_disabled? - end -end diff --git a/app/controllers/profiles_controller.rb b/app/controllers/profiles_controller.rb index e427f60718623a09a1565719edc4e454dce79b1e..39a070b6405d4df307010d92c2a0285f0c70c340 100644 --- a/app/controllers/profiles_controller.rb +++ b/app/controllers/profiles_controller.rb @@ -42,7 +42,7 @@ def reset_incoming_email_token flash[:notice] = s_("Profiles|Incoming email token was successfully reset") - redirect_to profile_personal_access_tokens_path + redirect_to user_settings_personal_access_tokens_path end def reset_feed_token @@ -52,7 +52,7 @@ def reset_feed_token flash[:notice] = s_('Profiles|Feed token was successfully reset') - redirect_to profile_personal_access_tokens_path + redirect_to user_settings_personal_access_tokens_path end def reset_static_object_token @@ -60,7 +60,7 @@ def reset_static_object_token user.reset_static_object_token! end - redirect_to profile_personal_access_tokens_path, + redirect_to user_settings_personal_access_tokens_path, notice: s_('Profiles|Static object token was successfully reset') end diff --git a/app/controllers/user_settings/active_sessions_controller.rb b/app/controllers/user_settings/active_sessions_controller.rb index da5664a8c1b01656088275fae391b46fd5cbacf7..bfc969d0ff8a809607ad305f5c27ac5e2cf813f4 100644 --- a/app/controllers/user_settings/active_sessions_controller.rb +++ b/app/controllers/user_settings/active_sessions_controller.rb @@ -1,20 +1,22 @@ # frozen_string_literal: true -class UserSettings::ActiveSessionsController < Profiles::ApplicationController - feature_category :system_access +module UserSettings + class ActiveSessionsController < ApplicationController + feature_category :system_access - def index - @sessions = ActiveSession.list(current_user).reject(&:is_impersonated) - end + def index + @sessions = ActiveSession.list(current_user).reject(&:is_impersonated) + end - def destroy - # params[:id] can be an Rack::Session::SessionId#private_id - ActiveSession.destroy_session(current_user, params[:id]) - current_user.forget_me! + def destroy + # params[:id] can be an Rack::Session::SessionId#private_id + ActiveSession.destroy_session(current_user, params[:id]) + current_user.forget_me! - respond_to do |format| - format.html { redirect_to user_settings_active_sessions_url, status: :found } - format.js { head :ok } + respond_to do |format| + format.html { redirect_to user_settings_active_sessions_url, status: :found } + format.js { head :ok } + end end end end diff --git a/app/controllers/user_settings/application_controller.rb b/app/controllers/user_settings/application_controller.rb new file mode 100644 index 0000000000000000000000000000000000000000..d495c604bf37a5dfad16f8d5d6ed6345895741d5 --- /dev/null +++ b/app/controllers/user_settings/application_controller.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module UserSettings + class ApplicationController < ::ApplicationController + layout 'profile' + end +end diff --git a/app/controllers/user_settings/personal_access_tokens_controller.rb b/app/controllers/user_settings/personal_access_tokens_controller.rb new file mode 100644 index 0000000000000000000000000000000000000000..a8e9a328c2606fa5677a071da4f91f77b5ce5a99 --- /dev/null +++ b/app/controllers/user_settings/personal_access_tokens_controller.rb @@ -0,0 +1,76 @@ +# frozen_string_literal: true + +module UserSettings + class PersonalAccessTokensController < ApplicationController + include RenderAccessTokens + + feature_category :system_access + + before_action :check_personal_access_tokens_enabled + + def index + set_index_vars + scopes = params[:scopes].split(',').map(&:squish).select(&:present?).map(&:to_sym) unless params[:scopes].nil? + @personal_access_token = finder.build( + name: params[:name], + scopes: scopes + ) + + respond_to do |format| + format.html + format.json do + render json: @active_access_tokens + end + end + end + + def create + result = ::PersonalAccessTokens::CreateService.new( + current_user: current_user, + target_user: current_user, + params: personal_access_token_params, + concatenate_errors: false + ).execute + + @personal_access_token = result.payload[:personal_access_token] + + if result.success? + render json: { new_token: @personal_access_token.token, + active_access_tokens: active_access_tokens }, status: :ok + else + render json: { errors: result.errors }, status: :unprocessable_entity + end + end + + def revoke + @personal_access_token = finder.find(params[:id]) + service = PersonalAccessTokens::RevokeService.new(current_user, token: @personal_access_token).execute + service.success? ? flash[:notice] = service.message : flash[:alert] = service.message + + redirect_to user_settings_personal_access_tokens_path + end + + private + + def finder(options = {}) + PersonalAccessTokensFinder.new({ user: current_user, impersonation: false }.merge(options)) + end + + def personal_access_token_params + params.require(:personal_access_token).permit(:name, :expires_at, scopes: []) + end + + def set_index_vars + @scopes = Gitlab::Auth.available_scopes_for(current_user) + @active_access_tokens = active_access_tokens + end + + def represent(tokens) + ::PersonalAccessTokenSerializer.new.represent(tokens) + end + + def check_personal_access_tokens_enabled + render_404 if Gitlab::CurrentSettings.personal_access_tokens_disabled? + end + end +end diff --git a/app/controllers/user_settings/user_settings_controller.rb b/app/controllers/user_settings/user_settings_controller.rb index 3d69a9c2fd6ac66a1a8fe3bcbec4c65c46074396..3535a30095a1daa220f9171e61f1c83856154e1b 100644 --- a/app/controllers/user_settings/user_settings_controller.rb +++ b/app/controllers/user_settings/user_settings_controller.rb @@ -2,7 +2,6 @@ module UserSettings class UserSettingsController < ApplicationController - layout 'profile' feature_category :system_access def authentication_log diff --git a/app/helpers/projects/terraform_helper.rb b/app/helpers/projects/terraform_helper.rb index fb35224fad3e591bcf52df527c03a516015b65a4..22cd9eb5c9b44f8dea1670a9b6654e7a7a73bd8f 100644 --- a/app/helpers/projects/terraform_helper.rb +++ b/app/helpers/projects/terraform_helper.rb @@ -6,7 +6,7 @@ def js_terraform_list_data(current_user, project) empty_state_image: image_path('illustrations/empty-state/empty-serverless-lg.svg'), project_path: project.full_path, terraform_admin: current_user&.can?(:admin_terraform_state, project), - access_tokens_path: profile_personal_access_tokens_path, + access_tokens_path: user_settings_personal_access_tokens_path, username: current_user&.username, terraform_api_url: "#{Settings.gitlab.url}/api/v4/projects/#{project.id}/terraform/state" } diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 6da2864b4c12e34151443139d9a6b641ab3a1c6a..a821d014592f2474354be13552f0c96e7dc24d19 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -244,7 +244,7 @@ def no_password_message push_pull_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('topics/git/terminology', anchor: 'pull-and-push') } clone_with_https_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('gitlab-basics/start-using-git', anchor: 'clone-with-https') } set_password_link_start = '<a href="%{url}">'.html_safe % { url: edit_profile_password_path } - set_up_pat_link_start = '<a href="%{url}">'.html_safe % { url: profile_personal_access_tokens_path } + set_up_pat_link_start = '<a href="%{url}">'.html_safe % { url: user_settings_personal_access_tokens_path } message = if current_user.require_password_creation_for_git? _('Your account is authenticated with SSO or SAML. To %{push_pull_link_start}push and pull%{link_end} over %{protocol} with Git using this account, you must %{set_password_link_start}set a password%{link_end} or %{set_up_pat_link_start}set up a Personal Access Token%{link_end} to use instead of a password. For more information, see %{clone_with_https_link_start}Clone with HTTPS%{link_end}.') diff --git a/app/mailers/emails/profile.rb b/app/mailers/emails/profile.rb index 2be4cdf734a874e0d7ff4a837e387c5a865fd74b..9fc3332293cf6f7813f4e8ab3937db8dba0e1aa1 100644 --- a/app/mailers/emails/profile.rb +++ b/app/mailers/emails/profile.rb @@ -88,7 +88,7 @@ def access_token_created_email(user, token_name) return unless user&.active? @user = user - @target_url = profile_personal_access_tokens_url + @target_url = user_settings_personal_access_tokens_url @token_name = token_name email_with_layout(to: @user.notification_email_or_default, subject: subject(_("A new personal access token has been created"))) @@ -99,7 +99,7 @@ def access_token_about_to_expire_email(user, token_names) @user = user @token_names = token_names - @target_url = profile_personal_access_tokens_url + @target_url = user_settings_personal_access_tokens_url @days_to_expire = PersonalAccessToken::DAYS_TO_EXPIRE email_with_layout(to: @user.notification_email_or_default, subject: subject(_("Your personal access tokens will expire in %{days_to_expire} days or less") % { days_to_expire: @days_to_expire })) @@ -110,7 +110,7 @@ def access_token_expired_email(user, token_names = []) @user = user @token_names = token_names - @target_url = profile_personal_access_tokens_url + @target_url = user_settings_personal_access_tokens_url email_with_layout(to: @user.notification_email_or_default, subject: subject(_("Your personal access tokens have expired"))) end @@ -120,7 +120,7 @@ def access_token_revoked_email(user, token_name, source = nil) @user = user @token_name = token_name - @target_url = profile_personal_access_tokens_url + @target_url = user_settings_personal_access_tokens_url @source = source email_with_layout(to: @user.notification_email_or_default, subject: subject(_("Your personal access token has been revoked"))) diff --git a/app/serializers/personal_access_token_entity.rb b/app/serializers/personal_access_token_entity.rb index 49dcdf12a6fe9b3721ca39ae20e48918b6528355..71c31a8191b1ba460b95cc2f7bcce03daf6ed39d 100644 --- a/app/serializers/personal_access_token_entity.rb +++ b/app/serializers/personal_access_token_entity.rb @@ -5,7 +5,7 @@ class PersonalAccessTokenEntity < AccessTokenEntityBase include Gitlab::Routing expose :revoke_path do |token, options| - revoke_profile_personal_access_token_path(token) + revoke_user_settings_personal_access_token_path(token) end end # rubocop: enable Gitlab/NamespacedClass diff --git a/app/views/profiles/personal_access_tokens/index.html.haml b/app/views/user_settings/personal_access_tokens/index.html.haml similarity index 97% rename from app/views/profiles/personal_access_tokens/index.html.haml rename to app/views/user_settings/personal_access_tokens/index.html.haml index 0457561b283a6495c8ec2dfaf48021f26ba736d0..dc87407adc7d26918c34684c69216dcea317a8a1 100644 --- a/app/views/profiles/personal_access_tokens/index.html.haml +++ b/app/views/user_settings/personal_access_tokens/index.html.haml @@ -32,7 +32,7 @@ = render 'shared/access_tokens/form', ajax: true, type: type, - path: profile_personal_access_tokens_path, + path: user_settings_personal_access_tokens_path, token: @personal_access_token, scopes: @scopes, help_path: help_page_path('user/profile/personal_access_tokens', anchor: 'personal-access-token-scopes') diff --git a/config/routes/profile.rb b/config/routes/profile.rb index a7890a7d45f4e9c140240272a37b970afed1d273..57a5977ef0f21b2f81632fb6b31a288ed07c9942 100644 --- a/config/routes/profile.rb +++ b/config/routes/profile.rb @@ -76,12 +76,6 @@ resource :avatar, only: [:destroy] - resources :personal_access_tokens, only: [:index, :create] do - member do - put :revoke - end - end - resource :two_factor_auth, only: [:show, :create, :destroy] do member do post :codes diff --git a/config/routes/user_settings.rb b/config/routes/user_settings.rb index d71202c872b2d8ff3e8261e37092eecf349ea932..2074d62abe426e146e28b2cc59b4074e40079fc0 100644 --- a/config/routes/user_settings.rb +++ b/config/routes/user_settings.rb @@ -6,13 +6,24 @@ get :applications, to: '/oauth/applications#index' end resources :active_sessions, only: [:index, :destroy] + resources :personal_access_tokens, only: [:index, :create] do + member do + put :revoke + end + end end # Redirect routes till GitLab 17.0 release resource :profile, only: [] do resources :active_sessions, only: [:destroy], controller: 'user_settings/active_sessions' + resources :personal_access_tokens, controller: 'user_settings/personal_access_tokens', only: [] do + member do + put :revoke + end + end member do - get :active_sessions, to: redirect('-/user_settings/active_sessions') + get :active_sessions, to: redirect(path: '-/user_settings/active_sessions') + get :personal_access_tokens, to: redirect(path: '-/user_settings/personal_access_tokens') end end diff --git a/doc/development/dangerbot.md b/doc/development/dangerbot.md index dcbb15e5811591072c97d23b44d3a756f9eafb3a..c25c4751ee8c069ec7af1a6317e9085041132bf6 100644 --- a/doc/development/dangerbot.md +++ b/doc/development/dangerbot.md @@ -193,7 +193,7 @@ where Danger is already configured. Contributors can configure Danger for their forks with the following steps: -1. Create a [personal API token](https://gitlab.com/-/profile/personal_access_tokens?name=GitLab+Dangerbot&scopes=api) +1. Create a [personal API token](https://gitlab.com/-/user_settings/personal_access_tokens?name=GitLab+Dangerbot&scopes=api) that has the `api` scope set (don't forget to copy it to the clipboard). 1. In your fork, add a [project CI/CD variable](../ci/variables/index.md#for-a-project) called `DANGER_GITLAB_API_TOKEN` with the token copied in the previous step. diff --git a/doc/development/integrations/jira_connect.md b/doc/development/integrations/jira_connect.md index 338c93db78ae43f5759504ce4edf69c5fdda9db0..fd5ff66243a3f5ad37c21453e0b88c83b9ea0e8b 100644 --- a/doc/development/integrations/jira_connect.md +++ b/doc/development/integrations/jira_connect.md @@ -73,7 +73,7 @@ To avoid external dependencies like Gitpod and a Jira Cloud instance, use the [J ``` 1. Restart GDK. -1. Go to `http://127.0.0.1:3000/-/profile/personal_access_tokens`. +1. Go to `http://127.0.0.1:3000/-/user_settings/personal_access_tokens`. 1. Create a new token with the `api` scope and copy the token. 1. Go to `http://localhost:9292`. 1. Paste the token and select **Install GitLab.com Jira Cloud app**. diff --git a/doc/development/sec/generate_test_vulnerabilities.md b/doc/development/sec/generate_test_vulnerabilities.md index 59fa0d905dfbb94063cc4cdc8251c856dcc6ab65..d862ee91c8324825fcd04fb92fa6bb00ef7f5eef 100644 --- a/doc/development/sec/generate_test_vulnerabilities.md +++ b/doc/development/sec/generate_test_vulnerabilities.md @@ -10,7 +10,7 @@ You can generate test vulnerabilities for the [Vulnerability Report](../../user/ vulnerability management features without running a pipeline. 1. Log in to GitLab. -1. Go to `/-/profile/personal_access_tokens` and generate a personal access token with `api` permissions. +1. Go to `/-/user_settings/personal_access_tokens` and generate a personal access token with `api` permissions. 1. Go to your project page and find the project ID. You can find the project ID below the project title. 1. [Clone the GitLab repository](../../gitlab-basics/start-using-git.md#clone-a-repository) to your local machine. 1. Open a terminal and go to `gitlab/qa` directory. diff --git a/doc/user/profile/personal_access_tokens.md b/doc/user/profile/personal_access_tokens.md index 1f4352ea80543ba1a5e408984c080a974c4a9647..ac6ec4ce2f0905a006145f281ebc28a1aebdd737 100644 --- a/doc/user/profile/personal_access_tokens.md +++ b/doc/user/profile/personal_access_tokens.md @@ -68,7 +68,7 @@ list of scopes. To do this, you can append a `name` parameter and a list of comm to the URL. For example: ```plaintext -https://gitlab.example.com/-/profile/personal_access_tokens?name=Example+Access+token&scopes=api,read_user,read_registry +https://gitlab.example.com/-/user_settings/personal_access_tokens?name=Example+Access+token&scopes=api,read_user,read_registry ``` WARNING: diff --git a/ee/app/mailers/ee/emails/profile.rb b/ee/app/mailers/ee/emails/profile.rb index b37000ba5cbd7c06c03774b1295112759eb3c6f8..9b3162d245fbc6720fd46e49b422a1e1526fe096 100644 --- a/ee/app/mailers/ee/emails/profile.rb +++ b/ee/app/mailers/ee/emails/profile.rb @@ -8,7 +8,7 @@ def policy_revoked_personal_access_tokens_email(user, revoked_token_names) @user = user @revoked_token_names = revoked_token_names - @target_url = profile_personal_access_tokens_url + @target_url = user_settings_personal_access_tokens_url ::Gitlab::I18n.with_locale(@user.preferred_language) do mail(to: user.notification_email_or_default, subject: subject(_("One or more of you personal access tokens were revoked"))) diff --git a/ee/app/views/credentials_inventory_mailer/personal_access_token_revoked_email.html.haml b/ee/app/views/credentials_inventory_mailer/personal_access_token_revoked_email.html.haml index 16d9e763e98be6528814b8dc430ef5ca26c221e9..72f2fd884b22804bcbc92e1f54191f811dcbe90d 100644 --- a/ee/app/views/credentials_inventory_mailer/personal_access_token_revoked_email.html.haml +++ b/ee/app/views/credentials_inventory_mailer/personal_access_token_revoked_email.html.haml @@ -13,4 +13,4 @@ = _("Scopes: %{scope_list}") % { scope_list: @token.scopes.join(', ') } %p - = html_escape(_("You can create a new %{link}.")) % { link: link_to(_('Personal Access Token'), profile_personal_access_tokens_url.html_safe) } + = html_escape(_("You can create a new %{link}.")) % { link: link_to(_('Personal Access Token'), user_settings_personal_access_tokens_url.html_safe) } diff --git a/ee/app/views/credentials_inventory_mailer/personal_access_token_revoked_email.text.haml b/ee/app/views/credentials_inventory_mailer/personal_access_token_revoked_email.text.haml index 84b72f1415a6463fdc78b195e2536abb284a411b..90473103cb4b973d52fd6c3889c3958a593c8d2a 100644 --- a/ee/app/views/credentials_inventory_mailer/personal_access_token_revoked_email.text.haml +++ b/ee/app/views/credentials_inventory_mailer/personal_access_token_revoked_email.text.haml @@ -9,4 +9,4 @@ = _("Scopes: %{scope_list}") % { scope_list: @token.scopes.join(', ') } -= html_escape(_("You can create a new Personal Access Token by visiting %{link}")) % { link: profile_personal_access_tokens_url.html_safe } += html_escape(_("You can create a new Personal Access Token by visiting %{link}")) % { link: user_settings_personal_access_tokens_url.html_safe } diff --git a/ee/spec/mailers/ee/emails/profile_spec.rb b/ee/spec/mailers/ee/emails/profile_spec.rb index 059755362718e9684bbfeb172c0c5c319ae35015..9053a73f1afcd5eeec2b6729858fafafa1115e98 100644 --- a/ee/spec/mailers/ee/emails/profile_spec.rb +++ b/ee/spec/mailers/ee/emails/profile_spec.rb @@ -26,7 +26,7 @@ end it 'includes a link to personal access tokens page' do - is_expected.to have_body_text /#{profile_personal_access_tokens_path}/ + is_expected.to have_body_text /#{user_settings_personal_access_tokens_path}/ end it 'includes the email reason' do diff --git a/lib/sidebars/user_settings/menus/access_tokens_menu.rb b/lib/sidebars/user_settings/menus/access_tokens_menu.rb index ed39b5d6720dde6fb53c39d94ebc8017f05edde2..cb3f319ddde5feeab3830539d1d0fef5ce06b1e1 100644 --- a/lib/sidebars/user_settings/menus/access_tokens_menu.rb +++ b/lib/sidebars/user_settings/menus/access_tokens_menu.rb @@ -6,7 +6,7 @@ module Menus class AccessTokensMenu < ::Sidebars::Menu override :link def link - profile_personal_access_tokens_path + user_settings_personal_access_tokens_path end override :title diff --git a/qa/qa/page/component/access_tokens.rb b/qa/qa/page/component/access_tokens.rb index 3f411c05587cbace514368fb3a3176803c04626c..ef920e6f5360ec5a88b48c14563d0476b2f8e8cb 100644 --- a/qa/qa/page/component/access_tokens.rb +++ b/qa/qa/page/component/access_tokens.rb @@ -40,7 +40,7 @@ def self.included(base) element 'revoke-button' end - base.view 'app/views/profiles/personal_access_tokens/index.html.haml' do + base.view 'app/views/user_settings/personal_access_tokens/index.html.haml' do element 'add-new-token-button' end diff --git a/spec/controllers/profiles/personal_access_tokens_controller_spec.rb b/spec/controllers/user_settings/personal_access_tokens_controller_spec.rb similarity index 95% rename from spec/controllers/profiles/personal_access_tokens_controller_spec.rb rename to spec/controllers/user_settings/personal_access_tokens_controller_spec.rb index 9c9a9a28879567e1aaf931f3b733f6f90209dd20..b1d6fc6f479d9e8bba7b4fe1dc08eeff006cf43f 100644 --- a/spec/controllers/profiles/personal_access_tokens_controller_spec.rb +++ b/spec/controllers/user_settings/personal_access_tokens_controller_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Profiles::PersonalAccessTokensController do +RSpec.describe UserSettings::PersonalAccessTokensController, feature_category: :system_access do let(:access_token_user) { create(:user) } let(:token_attributes) { attributes_for(:personal_access_token) } @@ -49,7 +49,7 @@ def created_token end end - describe 'GET /-/profile/personal_access_tokens' do + describe 'GET /-/user_settings/personal_access_tokens' do let(:get_access_tokens) do get :index response diff --git a/spec/features/profile_spec.rb b/spec/features/profile_spec.rb index b6c96555767791b9547829cd8b10a2cd48730c07..6c6deef5b7405816c851c6274b479e6be9132555 100644 --- a/spec/features/profile_spec.rb +++ b/spec/features/profile_spec.rb @@ -66,7 +66,7 @@ end it 'allows resetting of feed token' do - visit profile_personal_access_tokens_path + visit user_settings_personal_access_tokens_path previous_token = '' @@ -88,7 +88,7 @@ it 'allows resetting of incoming email token' do allow(Gitlab.config.incoming_email).to receive(:enabled).and_return(true) - visit profile_personal_access_tokens_path + visit user_settings_personal_access_tokens_path previous_token = '' diff --git a/spec/features/profiles/personal_access_tokens_spec.rb b/spec/features/user_settings/personal_access_tokens_spec.rb similarity index 80% rename from spec/features/profiles/personal_access_tokens_spec.rb rename to spec/features/user_settings/personal_access_tokens_spec.rb index e59b83c567e1bd0f5dab58de09c930cdbcdfa92f..55f1edfd26a7aa49e464a8cdc791c716abba88de 100644 --- a/spec/features/profiles/personal_access_tokens_spec.rb +++ b/spec/features/user_settings/personal_access_tokens_spec.rb @@ -2,12 +2,15 @@ require 'spec_helper' -RSpec.describe 'Profile > Personal Access Tokens', :js, feature_category: :system_access do +RSpec.describe 'User Settings > Personal Access Tokens', :js, feature_category: :system_access do include Spec::Support::Helpers::ModalHelpers include Features::AccessTokenHelpers let(:user) { create(:user) } - let(:pat_create_service) { double('PersonalAccessTokens::CreateService', execute: ServiceResponse.error(message: 'error', payload: { personal_access_token: PersonalAccessToken.new })) } + let(:pat_create_service) do + instance_double('PersonalAccessTokens::CreateService', + execute: ServiceResponse.error(message: 'error', payload: { personal_access_token: PersonalAccessToken.new })) + end before do sign_in(user) @@ -17,7 +20,7 @@ it "allows creation of a personal access token" do name = 'My PAT' - visit profile_personal_access_tokens_path + visit user_settings_personal_access_tokens_path click_button 'Add new token' fill_in "Token name", with: name @@ -44,7 +47,7 @@ context "when creation fails" do it "displays an error message" do number_tokens_before = PersonalAccessToken.count - visit profile_personal_access_tokens_path + visit user_settings_personal_access_tokens_path click_button 'Add new token' fill_in "Token name", with: 'My PAT' @@ -64,7 +67,7 @@ let!(:personal_access_token) { create(:personal_access_token, user: user) } it 'only shows personal access tokens' do - visit profile_personal_access_tokens_path + visit user_settings_personal_access_tokens_path expect(active_access_tokens).to have_text(personal_access_token.name) expect(active_access_tokens).not_to have_text(impersonation_token.name) @@ -76,7 +79,7 @@ end it 'shows absolute times for expires_at' do - visit profile_personal_access_tokens_path + visit user_settings_personal_access_tokens_path expect(active_access_tokens).to have_text(PersonalAccessToken.last.expires_at.strftime('%b %-d')) end @@ -87,7 +90,7 @@ let!(:personal_access_token) { create(:personal_access_token, user: user) } it "allows revocation of an active token" do - visit profile_personal_access_tokens_path + visit user_settings_personal_access_tokens_path accept_gl_confirm(button_text: 'Revoke') { click_on "Revoke" } expect(active_access_tokens).to have_text("This user has no active personal access tokens.") @@ -95,7 +98,7 @@ it "removes expired tokens from 'active' section" do personal_access_token.update!(expires_at: 5.days.ago) - visit profile_personal_access_tokens_path + visit user_settings_personal_access_tokens_path expect(active_access_tokens).to have_text("This user has no active personal access tokens.") end @@ -105,7 +108,7 @@ allow_next_instance_of(PersonalAccessTokens::RevokeService) do |instance| allow(instance).to receive(:revocation_permitted?).and_return(false) end - visit profile_personal_access_tokens_path + visit user_settings_personal_access_tokens_path accept_gl_confirm(button_text: "Revoke") { click_on "Revoke" } expect(active_access_tokens).to have_text(personal_access_token.name) @@ -115,15 +118,16 @@ describe "feed token" do def feed_token_description - "Your feed token authenticates you when your RSS reader loads a personalized RSS feed or when your calendar application loads a personalized calendar. It is visible in those feed URLs." + "Your feed token authenticates you when your RSS reader loads a personalized RSS feed or when your calendar\ + application loads a personalized calendar. It is visible in those feed URLs." end context "when enabled" do it "displays feed token" do allow(Gitlab::CurrentSettings).to receive(:disable_feed_token).and_return(false) - visit profile_personal_access_tokens_path + visit user_settings_personal_access_tokens_path - within('[data-testid="feed-token-container"]') do + within_testid('feed-token-container') do click_button('Click to reveal') expect(page).to have_field('Feed token', with: user.feed_token) @@ -135,7 +139,7 @@ def feed_token_description context "when disabled" do it "does not display feed token" do allow(Gitlab::CurrentSettings).to receive(:disable_feed_token).and_return(true) - visit profile_personal_access_tokens_path + visit user_settings_personal_access_tokens_path expect(page).not_to have_content(feed_token_description) expect(page).not_to have_field('Feed token') @@ -147,7 +151,7 @@ def feed_token_description name = 'My PAT' scopes = 'api,read_user' - visit profile_personal_access_tokens_path({ name: name, scopes: scopes }) + visit user_settings_personal_access_tokens_path({ name: name, scopes: scopes }) click_button 'Add new token' expect(page).to have_field("Token name", with: name) diff --git a/spec/frontend/access_tokens/components/access_token_table_app_spec.js b/spec/frontend/access_tokens/components/access_token_table_app_spec.js index aa7aad8e93ebcc4878f649a3465f92c640f2d756..dd3fc3a9d98860fccfcf13c4eec772ca3ad19eea 100644 --- a/spec/frontend/access_tokens/components/access_token_table_app_spec.js +++ b/spec/frontend/access_tokens/components/access_token_table_app_spec.js @@ -25,7 +25,7 @@ describe('~/access_tokens/components/access_token_table_app', () => { expires_soon: true, expires_at: null, revoked: false, - revoke_path: '/-/profile/personal_access_tokens/1/revoke', + revoke_path: '/-/user_settings/personal_access_tokens/1/revoke', role: 'Maintainer', }, { @@ -37,7 +37,7 @@ describe('~/access_tokens/components/access_token_table_app', () => { expires_soon: false, expires_at: new Date().toISOString(), revoked: false, - revoke_path: '/-/profile/personal_access_tokens/2/revoke', + revoke_path: '/-/user_settings/personal_access_tokens/2/revoke', role: 'Maintainer', }, ]; @@ -154,7 +154,7 @@ describe('~/access_tokens/components/access_token_table_app', () => { expect(button.attributes()).toMatchObject({ 'aria-label': __('Revoke'), 'data-testid': 'revoke-button', - href: '/-/profile/personal_access_tokens/1/revoke', + href: '/-/user_settings/personal_access_tokens/1/revoke', 'data-confirm': sprintf( __( 'Are you sure you want to revoke the %{accessTokenType} "%{tokenName}"? This action cannot be undone.', @@ -172,7 +172,7 @@ describe('~/access_tokens/components/access_token_table_app', () => { expect(cells.at(11).text()).toBe(__('Expired')); expect(cells.at(12).text()).toBe('Maintainer'); button = cells.at(13).findComponent(GlButton); - expect(button.attributes('href')).toBe('/-/profile/personal_access_tokens/2/revoke'); + expect(button.attributes('href')).toBe('/-/user_settings/personal_access_tokens/2/revoke'); expect(button.props('category')).toBe('tertiary'); }); diff --git a/spec/helpers/projects/terraform_helper_spec.rb b/spec/helpers/projects/terraform_helper_spec.rb index 9c2f009be266afa19a555a784aff5f2c0dceb1cf..49a49e19ea9a979ef698d99b99911b76e4cebf97 100644 --- a/spec/helpers/projects/terraform_helper_spec.rb +++ b/spec/helpers/projects/terraform_helper_spec.rb @@ -23,7 +23,7 @@ end it 'includes access token path' do - expect(subject[:access_tokens_path]).to eq(profile_personal_access_tokens_path) + expect(subject[:access_tokens_path]).to eq(user_settings_personal_access_tokens_path) end it 'includes username' do diff --git a/spec/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb index c92a8942e2281c9d6ac5dcf9e73579edd2af9dac..e612f48cd509ae95512f0da175811e77c068b8b1 100644 --- a/spec/helpers/projects_helper_spec.rb +++ b/spec/helpers/projects_helper_spec.rb @@ -276,7 +276,7 @@ it 'returns message prompting user to set password or set up a PAT' do stub_application_setting(password_authentication_enabled_for_git?: true) - expect(helper.no_password_message).to eq('Your account is authenticated with SSO or SAML. To <a href="/help/topics/git/terminology#pull-and-push" target="_blank" rel="noopener noreferrer">push and pull</a> over HTTP with Git using this account, you must <a href="/-/profile/password/edit">set a password</a> or <a href="/-/profile/personal_access_tokens">set up a Personal Access Token</a> to use instead of a password. For more information, see <a href="/help/gitlab-basics/start-using-git#clone-with-https" target="_blank" rel="noopener noreferrer">Clone with HTTPS</a>.') + expect(helper.no_password_message).to eq('Your account is authenticated with SSO or SAML. To <a href="/help/topics/git/terminology#pull-and-push" target="_blank" rel="noopener noreferrer">push and pull</a> over HTTP with Git using this account, you must <a href="/-/profile/password/edit">set a password</a> or <a href="/-/user_settings/personal_access_tokens">set up a Personal Access Token</a> to use instead of a password. For more information, see <a href="/help/gitlab-basics/start-using-git#clone-with-https" target="_blank" rel="noopener noreferrer">Clone with HTTPS</a>.') end end @@ -284,7 +284,7 @@ it 'returns message prompting user to set up a PAT' do stub_application_setting(password_authentication_enabled_for_git?: false) - expect(helper.no_password_message).to eq('Your account is authenticated with SSO or SAML. To <a href="/help/topics/git/terminology#pull-and-push" target="_blank" rel="noopener noreferrer">push and pull</a> over HTTP with Git using this account, you must <a href="/-/profile/personal_access_tokens">set up a Personal Access Token</a> to use instead of a password. For more information, see <a href="/help/gitlab-basics/start-using-git#clone-with-https" target="_blank" rel="noopener noreferrer">Clone with HTTPS</a>.') + expect(helper.no_password_message).to eq('Your account is authenticated with SSO or SAML. To <a href="/help/topics/git/terminology#pull-and-push" target="_blank" rel="noopener noreferrer">push and pull</a> over HTTP with Git using this account, you must <a href="/-/user_settings/personal_access_tokens">set up a Personal Access Token</a> to use instead of a password. For more information, see <a href="/help/gitlab-basics/start-using-git#clone-with-https" target="_blank" rel="noopener noreferrer">Clone with HTTPS</a>.') end end end diff --git a/spec/lib/sidebars/user_settings/menus/access_tokens_menu_spec.rb b/spec/lib/sidebars/user_settings/menus/access_tokens_menu_spec.rb index fa33e7bedfb0856baeb34fbc6813133a782940d1..eebd089ad3f946cdaab06dcb3305e2a23301b2b9 100644 --- a/spec/lib/sidebars/user_settings/menus/access_tokens_menu_spec.rb +++ b/spec/lib/sidebars/user_settings/menus/access_tokens_menu_spec.rb @@ -4,7 +4,7 @@ RSpec.describe Sidebars::UserSettings::Menus::AccessTokensMenu, feature_category: :navigation do it_behaves_like 'User settings menu', - link: '/-/profile/personal_access_tokens', + link: '/-/user_settings/personal_access_tokens', title: _('Access Tokens'), icon: 'token', active_routes: { controller: :personal_access_tokens } diff --git a/spec/mailers/emails/profile_spec.rb b/spec/mailers/emails/profile_spec.rb index 7ddb4810d53706d18a14cc71941be838130c83ef..e19d4ceabd9e436e8784d5ae674aa25382e9a0e4 100644 --- a/spec/mailers/emails/profile_spec.rb +++ b/spec/mailers/emails/profile_spec.rb @@ -148,7 +148,7 @@ end it 'includes a link to personal access tokens page' do - is_expected.to have_body_text /#{profile_personal_access_tokens_path}/ + is_expected.to have_body_text /#{user_settings_personal_access_tokens_path}/ end it 'includes the email reason' do @@ -254,7 +254,7 @@ end it 'includes a link to personal access tokens page' do - is_expected.to have_body_text /#{profile_personal_access_tokens_path}/ + is_expected.to have_body_text /#{user_settings_personal_access_tokens_path}/ end it 'includes the email reason' do diff --git a/spec/requests/legacy_routes_spec.rb b/spec/requests/legacy_routes_spec.rb index 29d26c8746193fb92eb29394072538f9e823fd1c..f1e93be5ce32840c9279f3c09e828e7c20325f5e 100644 --- a/spec/requests/legacy_routes_spec.rb +++ b/spec/requests/legacy_routes_spec.rb @@ -4,6 +4,7 @@ RSpec.describe "Legacy routes", type: :request, feature_category: :system_access do let(:user) { create(:user) } + let(:token) { create(:personal_access_token, user: user) } before do login_as(user) @@ -19,6 +20,19 @@ expect(response).to redirect_to('/-/user_settings/active_sessions') end + it "/-/profile/personal_access_tokens" do + get "/-/profile/personal_access_tokens" + expect(response).to redirect_to('/-/user_settings/personal_access_tokens') + + get "/-/profile/personal_access_tokens?name=GitLab+Dangerbot&scopes=api" + expect(response).to redirect_to('/-/user_settings/personal_access_tokens?name=GitLab+Dangerbot&scopes=api') + end + + it "/-/profile/personal_access_tokens/:id/revoke" do + put "/-/profile/personal_access_tokens/#{token.id}/revoke" + expect(token.reload).to be_revoked + end + it "/-/profile/applications" do get "/-/profile/applications" expect(response).to redirect_to('/-/user_settings/applications') diff --git a/spec/serializers/personal_access_token_entity_spec.rb b/spec/serializers/personal_access_token_entity_spec.rb index 8a77a4e0036ca482f11dbc0fca407d6eef34f1d1..817d112d15fbb117b58dc8b19378826d2a6fff2a 100644 --- a/spec/serializers/personal_access_token_entity_spec.rb +++ b/spec/serializers/personal_access_token_entity_spec.rb @@ -10,7 +10,7 @@ it 'has the correct attributes' do expected_revoke_path = Gitlab::Routing.url_helpers - .revoke_profile_personal_access_token_path( + .revoke_user_settings_personal_access_token_path( { id: token }) expect(json).to( diff --git a/spec/support/rspec_order_todo.yml b/spec/support/rspec_order_todo.yml index d772a051ac8b8cf5c087f325ab293fb8b5dc77d0..1cb39e6799b9f353f9aafd6f9e08365a58c27ccb 100644 --- a/spec/support/rspec_order_todo.yml +++ b/spec/support/rspec_order_todo.yml @@ -3220,7 +3220,6 @@ - './spec/controllers/profiles/gpg_keys_controller_spec.rb' - './spec/controllers/profiles/keys_controller_spec.rb' - './spec/controllers/profiles/notifications_controller_spec.rb' -- './spec/controllers/profiles/personal_access_tokens_controller_spec.rb' - './spec/controllers/profiles/preferences_controller_spec.rb' - './spec/controllers/profiles/two_factor_auths_controller_spec.rb' - './spec/controllers/profiles/webauthn_registrations_controller_spec.rb' @@ -3728,7 +3727,6 @@ - './spec/features/profiles/oauth_applications_spec.rb' - './spec/features/profiles/password_spec.rb' - './spec/features/profile_spec.rb' -- './spec/features/profiles/personal_access_tokens_spec.rb' - './spec/features/profiles/two_factor_auths_spec.rb' - './spec/features/profiles/user_changes_notified_of_own_activity_spec.rb' - './spec/features/profiles/user_edit_preferences_spec.rb'