From 868bee2e6339336c075eb3e581f42e0e5cb0fad0 Mon Sep 17 00:00:00 2001 From: Girija Soni Date: Thu, 19 Dec 2024 15:24:03 +0530 Subject: [PATCH] Fixes #38108 - As a user I want to invalidate tokens for self(UI) --- app/views/jwt_tokens/_jwt_tokens_tab.html.erb | 5 ++ app/views/users/_form.html.erb | 7 +++ test/controllers/users_controller_test.rb | 9 +++ .../react_app/components/componentRegistry.js | 2 + .../components/users/JwtTokens/JwtTokens.js | 61 +++++++++++++++++++ 5 files changed, 84 insertions(+) create mode 100644 app/views/jwt_tokens/_jwt_tokens_tab.html.erb create mode 100644 webpack/assets/javascripts/react_app/components/users/JwtTokens/JwtTokens.js diff --git a/app/views/jwt_tokens/_jwt_tokens_tab.html.erb b/app/views/jwt_tokens/_jwt_tokens_tab.html.erb new file mode 100644 index 00000000000..212031b2fa4 --- /dev/null +++ b/app/views/jwt_tokens/_jwt_tokens_tab.html.erb @@ -0,0 +1,5 @@ +
+ <%= react_component('JwtTokens', { + userId: @user.id, + }) %> +
diff --git a/app/views/users/_form.html.erb b/app/views/users/_form.html.erb index a952490995b..17311824c53 100644 --- a/app/views/users/_form.html.erb +++ b/app/views/users/_form.html.erb @@ -18,6 +18,9 @@ <% if @editing_self || (@user.persisted? && authorized_for(hash_for_api_user_personal_access_tokens_path(user_id: @user))) %>
  • <%= _('Personal Access Tokens') %>
  • <% end %> + <% if @editing_self %> +
  • <%= _('JWT Tokens') %>
  • + <% end %> <%= render_tab_header_for(:main_tabs, :subject => @user, :form => f) %> @@ -97,6 +100,10 @@ <%= render 'personal_access_tokens/personal_access_tokens_tab', :f => f, :user => @user %> <% end %> + <% if @editing_self %> + <%= render 'jwt_tokens/jwt_tokens_tab', :f => f, :user => @user %> + <% end %> +
    <% caption = @user.inherited_admin? ? _('Admin rights are currently inherited from a user group') : '' %> <%= checkbox_f f, :admin, help_block: caption if User.current.can_change_admin_flag? %> diff --git a/test/controllers/users_controller_test.rb b/test/controllers/users_controller_test.rb index 6b1a4bdae92..735f34bddd5 100644 --- a/test/controllers/users_controller_test.rb +++ b/test/controllers/users_controller_test.rb @@ -167,6 +167,15 @@ class UsersControllerTest < ActionController::TestCase assert_nil user.jwt_secret end + test "User should be able to invalidate jwt for self" do + User.current = users(:one) + user = User.current + FactoryBot.build(:jwt_secret, token: 'test_jwt_secret', user: user) + patch :invalidate_jwt, params: { :id => user.id } + user.reload + assert_nil user.jwt_secret + end + test 'user with edit users permission should be able to invalidate jwt for another user' do User.current = setup_user "edit", "users" user = users(:two) diff --git a/webpack/assets/javascripts/react_app/components/componentRegistry.js b/webpack/assets/javascripts/react_app/components/componentRegistry.js index 5e8c9a509a7..2e5b8e66c4d 100644 --- a/webpack/assets/javascripts/react_app/components/componentRegistry.js +++ b/webpack/assets/javascripts/react_app/components/componentRegistry.js @@ -44,6 +44,7 @@ import LabelIcon from './common/LabelIcon'; import { WelcomeAuthSource } from './AuthSource/Welcome'; import { WelcomeConfigReports } from './ConfigReports/Welcome'; import { WelcomeArchitecture } from './Architectures/Welcome'; +import JwtTokens from './users/JwtTokens/JwtTokens'; const componentRegistry = { registry: forceSingleton('component_registry', () => ({})), @@ -142,6 +143,7 @@ const coreComponents = [ { name: 'SettingsTable', type: SettingsTable }, { name: 'SettingUpdateModal', type: SettingUpdateModal }, { name: 'PersonalAccessTokens', type: PersonalAccessTokens }, + { name: 'JwtTokens', type: JwtTokens }, { name: 'ClipboardCopy', type: ClipboardCopy }, { name: 'LabelIcon', type: LabelIcon }, { diff --git a/webpack/assets/javascripts/react_app/components/users/JwtTokens/JwtTokens.js b/webpack/assets/javascripts/react_app/components/users/JwtTokens/JwtTokens.js new file mode 100644 index 00000000000..a3d21b1b407 --- /dev/null +++ b/webpack/assets/javascripts/react_app/components/users/JwtTokens/JwtTokens.js @@ -0,0 +1,61 @@ +import React, { Fragment } from 'react'; +import { Button } from '@patternfly/react-core'; +import { KeyIcon } from '@patternfly/react-icons'; +import { useDispatch } from 'react-redux'; +import PropTypes from 'prop-types'; +import { useAPI } from '../../../common/hooks/API/APIHooks'; +import { openConfirmModal } from '../../ConfirmModal'; +import { APIActions } from '../../../redux/API'; +import { translate as __ } from '../../../common/I18n'; + +const JwtTokens = ({ userId }) => { + const dispatch = useDispatch(); + return ( + + + + + + + +
    +
    + +
    +

    {__('JWT Tokens')}

    +

    + {__( + 'By invalidating your JSON Web Tokens (JWTs), you will no longer be able to register hosts by using your existing JWTs.' + )} +

    + +
    +
    + ); +}; + +JwtTokens.propTypes = { + userId: PropTypes.string.isRequired, +}; + +export default JwtTokens;