From 07f40d55abd429da44fccdd95185a5ee838132d1 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Sun, 2 Oct 2022 21:07:52 +0000 Subject: [PATCH] Add latest changes from gitlab-org/gitlab@master --- .../components/access_token_table_app.vue | 5 +++ app/assets/javascripts/access_tokens/index.js | 2 ++ .../admin/impersonation_tokens_controller.rb | 19 ++++++----- .../impersonation_tokens/index.html.haml | 13 ++------ doc/development/contributing/style_guides.md | 10 ++++++ locale/gitlab.pot | 3 -- rubocop/check_graceful_task.rb | 8 ++++- .../personal_access_tokens_controller_spec.rb | 4 +++ .../admin_users_impersonation_tokens_spec.rb | 14 +++----- .../components/access_token_table_app_spec.js | 13 ++++++-- .../impersonation_tokens_controller_spec.rb | 6 ++++ spec/rubocop/check_graceful_task_spec.rb | 18 ++++++++--- .../features/access_tokens_shared_examples.rb | 32 +++++++++++++++++++ 13 files changed, 107 insertions(+), 40 deletions(-) diff --git a/app/assets/javascripts/access_tokens/components/access_token_table_app.vue b/app/assets/javascripts/access_tokens/components/access_token_table_app.vue index 461b2dad479..76709296c89 100644 --- a/app/assets/javascripts/access_tokens/components/access_token_table_app.vue +++ b/app/assets/javascripts/access_tokens/components/access_token_table_app.vue @@ -45,6 +45,7 @@ export default { 'initialActiveAccessTokens', 'noActiveTokensMessage', 'showRole', + 'information', ], data() { return { @@ -100,6 +101,10 @@ export default {
{{ header }}
+

+ {{ information }} +

+ { const { accessTokenType, accessTokenTypePlural, + information, initialActiveAccessTokens: initialActiveAccessTokensJson, noActiveTokensMessage: noTokensMessage, } = el.dataset; @@ -43,6 +44,7 @@ export const initAccessTokenTableApp = () => { provide: { accessTokenType, accessTokenTypePlural, + information, initialActiveAccessTokens, noActiveTokensMessage, showRole, diff --git a/app/controllers/admin/impersonation_tokens_controller.rb b/app/controllers/admin/impersonation_tokens_controller.rb index eb279298baf..9d884478e98 100644 --- a/app/controllers/admin/impersonation_tokens_controller.rb +++ b/app/controllers/admin/impersonation_tokens_controller.rb @@ -14,11 +14,10 @@ class Admin::ImpersonationTokensController < Admin::ApplicationController @impersonation_token = finder.build(impersonation_token_params) if @impersonation_token.save - PersonalAccessToken.redis_store!(current_user.id, @impersonation_token.token) - redirect_to admin_user_impersonation_tokens_path, notice: _("A new impersonation token has been created.") + render json: { new_token: @impersonation_token.token, + active_access_tokens: active_impersonation_tokens }, status: :ok else - set_index_vars - render :index + render json: { errors: @impersonation_token.errors.full_messages }, status: :unprocessable_entity end end @@ -50,19 +49,19 @@ class Admin::ImpersonationTokensController < Admin::ApplicationController PersonalAccessTokensFinder.new({ user: user, impersonation: true }.merge(options)) end + def active_impersonation_tokens + tokens = finder(state: 'active', sort: 'expires_at_asc_id_desc').execute + ::ImpersonationAccessTokenSerializer.new.represent(tokens) + end + def impersonation_token_params params.require(:personal_access_token).permit(:name, :expires_at, :impersonation, scopes: []) end - # rubocop: disable CodeReuse/ActiveRecord def set_index_vars @scopes = Gitlab::Auth.available_scopes_for(current_user) @impersonation_token ||= finder.build - @inactive_impersonation_tokens = finder(state: 'inactive').execute - @active_impersonation_tokens = finder(state: 'active').execute.order(:expires_at) - - @new_impersonation_token = PersonalAccessToken.redis_getdel(current_user.id) + @active_impersonation_tokens = active_impersonation_tokens end - # rubocop: enable CodeReuse/ActiveRecord end diff --git a/app/views/admin/impersonation_tokens/index.html.haml b/app/views/admin/impersonation_tokens/index.html.haml index 2c526bb38d8..8cf1d8555ce 100644 --- a/app/views/admin/impersonation_tokens/index.html.haml +++ b/app/views/admin/impersonation_tokens/index.html.haml @@ -8,12 +8,10 @@ .row.gl-mt-3 .col-lg-12 - - if @new_impersonation_token - = render 'shared/access_tokens/created_container', - type: type, - new_token_value: @new_impersonation_token + #js-new-access-token-app{ data: { access_token_type: type } } = render 'shared/access_tokens/form', + ajax: true, type: type, title: _('Add an impersonation token'), path: admin_user_impersonation_tokens_path, @@ -22,9 +20,4 @@ scopes: @scopes, help_path: help_page_path('api/index', anchor: 'impersonation-tokens') - = render 'shared/access_tokens/table', - type: type, - type_plural: type_plural, - impersonation: true, - active_tokens: @active_impersonation_tokens, - revoke_route_helper: ->(token) { revoke_admin_user_impersonation_token_path(token.user, token) } + #js-access-token-table-app{ data: { access_token_type: type, access_token_type_plural: type_plural, initial_active_access_tokens: @active_impersonation_tokens.to_json, information: _("To see all the user's personal access tokens you must impersonate them first.") } } diff --git a/doc/development/contributing/style_guides.md b/doc/development/contributing/style_guides.md index 4ef3fa77958..79057ba8142 100644 --- a/doc/development/contributing/style_guides.md +++ b/doc/development/contributing/style_guides.md @@ -169,6 +169,16 @@ A grace period can safely be lifted as soon as there are no warnings for 2 weeks 1. Create an issue to fix TODOs and encourage Community contributions (via ~"good for new contributors" and/or ~"Seeking community contributions"). [See some examples](https://gitlab.com/gitlab-org/gitlab/-/issues/?sort=created_date&state=opened&label_name%5B%5D=good%20for%20new%20contributors&label_name%5B%5D=static%20code%20analysis&first_page_size=20). 1. Create an issue to remove "grace period" after 2 weeks silence in `#f_rubocop` Slack channel. ([See an example](https://gitlab.com/gitlab-org/gitlab/-/issues/374903).) +### Silenced offenses + +When offenses are silenced for cops in ["grace period"](#cop-grace-period), +the `#f_rubocop` Slack channel receives a notification message every two hours. + +To fix this issue: + +1. Find cops with silenced offenses in the linked CI job. +1. [Generate TODOs](../rake_tasks.md#generate-initial-rubocop-todo-list) for these cops. + #### RuboCop node pattern When creating [node patterns](https://docs.rubocop.org/rubocop-ast/node_pattern.html) to match diff --git a/locale/gitlab.pot b/locale/gitlab.pot index fd6310d4df0..61214fa619a 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -1676,9 +1676,6 @@ msgstr "" msgid "A new email address has been added to your GitLab account: %{email}" msgstr "" -msgid "A new impersonation token has been created." -msgstr "" - msgid "A new personal access token has been created" msgstr "" diff --git a/rubocop/check_graceful_task.rb b/rubocop/check_graceful_task.rb index 7ae74e79e38..724f7fa6963 100644 --- a/rubocop/check_graceful_task.rb +++ b/rubocop/check_graceful_task.rb @@ -66,7 +66,13 @@ module RuboCop end channel = 'f_rubocop' - message = ":warning: `#{job_name}` passed :green: but contained silenced offenses. See #{job_url}" + message = format( + ':warning: `%{job_name}` passed :green: but contained <%{job_url}|silenced offenses>. ' \ + 'See <%{docs_link}|docs>.', + docs_link: 'https://docs.gitlab.com/ee/development/contributing/style_guides.html#silenced-offenses', + job_name: job_name, + job_url: job_url) + emoji = 'rubocop' user_name = 'GitLab Bot' diff --git a/spec/controllers/profiles/personal_access_tokens_controller_spec.rb b/spec/controllers/profiles/personal_access_tokens_controller_spec.rb index 99e9644da66..160af8cf3f0 100644 --- a/spec/controllers/profiles/personal_access_tokens_controller_spec.rb +++ b/spec/controllers/profiles/personal_access_tokens_controller_spec.rb @@ -35,6 +35,10 @@ RSpec.describe Profiles::PersonalAccessTokensController do expect(created_token).not_to be_nil expect(created_token.expires_at).to eq(expires_at) end + + it_behaves_like "#create access token" do + let(:url) { :create } + end end describe '#index' do diff --git a/spec/features/admin/admin_users_impersonation_tokens_spec.rb b/spec/features/admin/admin_users_impersonation_tokens_spec.rb index 7e57cffc791..45dccf9921f 100644 --- a/spec/features/admin/admin_users_impersonation_tokens_spec.rb +++ b/spec/features/admin/admin_users_impersonation_tokens_spec.rb @@ -9,15 +9,11 @@ RSpec.describe 'Admin > Users > Impersonation Tokens', :js do let!(:user) { create(:user) } def active_impersonation_tokens - find(".table.active-tokens") - end - - def no_personal_access_tokens_message - find(".settings-message") + find("[data-testid='active-tokens']") end def created_impersonation_token - find("#created-personal-access-token").value + find_field('new-access-token').value end before do @@ -80,8 +76,7 @@ RSpec.describe 'Admin > Users > Impersonation Tokens', :js do accept_gl_confirm(button_text: 'Revoke') { click_on "Revoke" } - expect(page).to have_selector(".settings-message") - expect(no_personal_access_tokens_message).to have_text("This user has no active impersonation tokens.") + expect(active_impersonation_tokens).to have_text("This user has no active impersonation tokens.") end it "removes expired tokens from 'active' section" do @@ -89,8 +84,7 @@ RSpec.describe 'Admin > Users > Impersonation Tokens', :js do visit admin_user_impersonation_tokens_path(user_id: user.username) - expect(page).to have_selector(".settings-message") - expect(no_personal_access_tokens_message).to have_text("This user has no active impersonation tokens.") + expect(active_impersonation_tokens).to have_text("This user has no active impersonation tokens.") end end 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 aed3db4aa4c..a460d18cc60 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 @@ -1,6 +1,6 @@ import { GlButton, GlPagination, GlTable } from '@gitlab/ui'; -import { mount } from '@vue/test-utils'; import { nextTick } from 'vue'; +import { mountExtended } from 'helpers/vue_test_utils_helper'; import AccessTokenTableApp from '~/access_tokens/components/access_token_table_app.vue'; import { EVENT_SUCCESS, PAGE_SIZE } from '~/access_tokens/components/constants'; import { __, s__, sprintf } from '~/locale'; @@ -11,6 +11,7 @@ describe('~/access_tokens/components/access_token_table_app', () => { const accessTokenType = 'personal access token'; const accessTokenTypePlural = 'personal access tokens'; + const information = undefined; const initialActiveAccessTokens = []; const noActiveTokensMessage = 'This user has no active personal access tokens.'; const showRole = false; @@ -43,10 +44,11 @@ describe('~/access_tokens/components/access_token_table_app', () => { ]; const createComponent = (props = {}) => { - wrapper = mount(AccessTokenTableApp, { + wrapper = mountExtended(AccessTokenTableApp, { provide: { accessTokenType, accessTokenTypePlural, + information, initialActiveAccessTokens, noActiveTokensMessage, showRole, @@ -101,6 +103,13 @@ describe('~/access_tokens/components/access_token_table_app', () => { ); }); + it('should render information section', () => { + const info = 'This is my information'; + createComponent({ information: info }); + + expect(wrapper.findByTestId('information-section').text()).toBe(info); + }); + it('should render the `GlTable` component with default 6 column headers', () => { createComponent(); diff --git a/spec/requests/admin/impersonation_tokens_controller_spec.rb b/spec/requests/admin/impersonation_tokens_controller_spec.rb index 018f497e7e5..2017a512bce 100644 --- a/spec/requests/admin/impersonation_tokens_controller_spec.rb +++ b/spec/requests/admin/impersonation_tokens_controller_spec.rb @@ -35,4 +35,10 @@ RSpec.describe Admin::ImpersonationTokensController, :enable_admin_mode do expect(response).to have_gitlab_http_status(:not_found) end end + + describe "#create" do + it_behaves_like "#create access token" do + let(:url) { admin_user_impersonation_tokens_path(user_id: user.username) } + end + end end diff --git a/spec/rubocop/check_graceful_task_spec.rb b/spec/rubocop/check_graceful_task_spec.rb index 0364820a602..c39a00470fd 100644 --- a/spec/rubocop/check_graceful_task_spec.rb +++ b/spec/rubocop/check_graceful_task_spec.rb @@ -62,25 +62,35 @@ RSpec.describe RuboCop::CheckGracefulTask do let(:adjusted_rubocop_status) { status_success } context 'with sufficient environment variables' do + let(:script) { 'scripts/slack' } let(:channel) { 'f_rubocop' } + let(:emoji) { 'rubocop' } + let(:user_name) { 'GitLab Bot' } + let(:job_name) { 'some job name' } + let(:job_url) { 'some job url' } + let(:docs_link) { 'https://docs.gitlab.com/ee/development/contributing/style_guides.html#silenced-offenses' } before do env = { 'CI_SLACK_WEBHOOK_URL' => 'webhook_url', - 'CI_JOB_NAME' => 'job_name', - 'CI_JOB_URL' => 'job_url' + 'CI_JOB_NAME' => job_name, + 'CI_JOB_URL' => job_url } stub_const('ENV', ENV.to_hash.update(env)) end it 'notifies slack' do - popen_args = ['scripts/slack', channel, kind_of(String), 'rubocop', kind_of(String)] popen_result = ['', 0] - expect(Gitlab::Popen).to receive(:popen).with(popen_args).and_return(popen_result) + allow(Gitlab::Popen).to receive(:popen).with(anything).and_return(popen_result) subject + message = a_kind_of(String).and include(job_name).and include(job_url).and include(docs_link) + + expect(Gitlab::Popen).to have_received(:popen) + .with([script, channel, message, emoji, user_name]) + expect(output.string).to include("Notifying Slack ##{channel}.") end diff --git a/spec/support/shared_examples/features/access_tokens_shared_examples.rb b/spec/support/shared_examples/features/access_tokens_shared_examples.rb index 0fc45b154d8..07e64446ab3 100644 --- a/spec/support/shared_examples/features/access_tokens_shared_examples.rb +++ b/spec/support/shared_examples/features/access_tokens_shared_examples.rb @@ -163,3 +163,35 @@ RSpec.shared_examples 'inactive resource access tokens' do |no_active_tokens_tex end end end + +RSpec.shared_examples '#create access token' do + let(:url) { {} } + let_it_be(:admin) { create(:admin) } + let_it_be(:token_attributes) { attributes_for(:personal_access_token) } + + before do + sign_in(admin) + end + + context "when POST is successful" do + it "renders JSON with a new token" do + post url, params: { personal_access_token: token_attributes } + + parsed_body = Gitlab::Json.parse(response.body) + expect(parsed_body['new_token']).not_to be_blank + expect(parsed_body['errors']).to be_blank + expect(response).to have_gitlab_http_status(:success) + end + end + + context "when POST is unsuccessful" do + it "renders JSON with an error" do + post url, params: { personal_access_token: token_attributes.merge(scopes: []) } + + parsed_body = Gitlab::Json.parse(response.body) + expect(parsed_body['new_token']).to be_blank + expect(parsed_body['errors']).not_to be_blank + expect(response).to have_gitlab_http_status(:unprocessable_entity) + end + end +end