Commit 798ae8b6 authored by Jan Provaznik's avatar Jan Provaznik

Merge branch '38133-credential-inventory-for-group-managed-accounts-concern' into 'master'

Refactoring: Move "Credential inventory" to a re-usable concern

Closes #38133

See merge request gitlab-org/gitlab!23495
parents fbb3a6ce de2bb958
# frozen_string_literal: true
class Admin::CredentialsController < Admin::ApplicationController
include Admin::CredentialsHelper
include CredentialsInventoryActions
before_action :check_license_credentials_inventory_available!
def index
@credentials = filter_credentials.page(params[:page]).preload_users.without_count
end
helper_method :credentials_inventory_path, :user_detail_path
private
def filter_credentials
if show_personal_access_tokens?
::PersonalAccessTokensFinder.new({ user: nil, impersonation: false, state: 'active', sort: 'id_desc' }).execute
elsif show_ssh_keys?
::KeysFinder.new(current_user, { user: nil, key_type: 'ssh' }).execute
end
def credentials_inventory_path(args)
admin_credentials_path(args)
end
def user_detail_path(user)
admin_user_path(user)
end
def check_license_credentials_inventory_available!
render_404 unless credentials_inventory_feature_available?
def user
nil
end
end
# frozen_string_literal: true
module CredentialsInventoryActions
extend ActiveSupport::Concern
include CredentialsInventoryHelper
included do
before_action :check_license_credentials_inventory_available!, only: [:index]
end
def index
@credentials = filter_credentials.page(params[:page]).preload_users.without_count # rubocop:disable Gitlab/ModuleWithInstanceVariables
render 'shared/credentials_inventory/index'
end
private
def filter_credentials
if show_personal_access_tokens?
::PersonalAccessTokensFinder.new({ user: user, impersonation: false, state: 'active', sort: 'id_desc' }).execute
elsif show_ssh_keys?
::KeysFinder.new(current_user, { user: user, key_type: 'ssh' }).execute
end
end
def check_license_credentials_inventory_available!
render_404 unless credentials_inventory_feature_available?
end
def user
raise NotImplementedError, "#{self.class} does not implement #{__method__}"
end
end
# frozen_string_literal: true
module Admin
module CredentialsHelper
VALID_FILTERS = %w(ssh_keys personal_access_tokens).freeze
def show_personal_access_tokens?
return true if params[:filter] == 'personal_access_tokens'
VALID_FILTERS.exclude? params[:filter]
end
def show_ssh_keys?
params[:filter] == 'ssh_keys'
end
def credentials_inventory_feature_available?
License.feature_available?(:credentials_inventory)
end
end
end
# frozen_string_literal: true
module CredentialsInventoryHelper
VALID_FILTERS = %w(ssh_keys personal_access_tokens).freeze
def show_personal_access_tokens?
return true if params[:filter] == 'personal_access_tokens'
VALID_FILTERS.exclude? params[:filter]
end
def show_ssh_keys?
params[:filter] == 'ssh_keys'
end
def credentials_inventory_feature_available?
License.feature_available?(:credentials_inventory)
end
def credentials_inventory_path(args)
raise NotImplementedError, "#{self.class} does not implement #{__method__}"
end
def user_detail_path(user)
raise NotImplementedError, "#{self.class} does not implement #{__method__}"
end
end
.table-holder
.thead-white.text-nowrap.gl-responsive-table-row.table-row-header{ role: 'row' }
.table-section.section-25{ role: 'rowheader' }= _('Owner')
.table-section.section-40{ role: 'rowheader' }= _('Owner')
.table-section.section-30{ role: 'rowheader' }= _('Scope')
.table-section.section-10{ role: 'rowheader' }= _('Created On')
.table-section.section-10{ role: 'rowheader' }= _('Expiration')
= render partial: 'admin/credentials/personal_access_tokens/personal_access_token', collection: credentials
= render partial: 'shared/credentials_inventory/personal_access_tokens/personal_access_token', collection: credentials
......@@ -4,4 +4,4 @@
.table-section.section-15{ role: 'rowheader' }= _('Created On')
.table-section.section-15{ role: 'rowheader' }= _('Last Accessed On')
= render partial: 'admin/credentials/ssh_keys/ssh_key', collection: credentials
= render partial: 'shared/credentials_inventory/ssh_keys/ssh_key', collection: credentials
......@@ -7,19 +7,19 @@
= icon('angle-right')
%ul.nav-links.nav.nav-tabs.scrolling-tabs
= nav_link(html_options: { class: active_when(show_personal_access_tokens?) }) do
= link_to admin_credentials_path(filter: 'personal_access_tokens') do
= s_('AdminCredentials|Personal Access Tokens')
= link_to credentials_inventory_path(filter: 'personal_access_tokens') do
= s_('CredentialsInventory|Personal Access Tokens')
= nav_link(html_options: { class: active_when(show_ssh_keys?) }) do
= link_to admin_credentials_path(filter: 'ssh_keys') do
= s_('AdminCredentials|SSH Keys')
= link_to credentials_inventory_path(filter: 'ssh_keys') do
= s_('CredentialsInventory|SSH Keys')
- if @credentials.empty?
.nothing-here-block.border-top-0
= s_('AdminUsers|No credentials found')
= s_('CredentialsInventory|No credentials found')
- else
- if show_personal_access_tokens?
= render partial: 'admin/credentials/personal_access_tokens', locals: { credentials: @credentials }
= render 'shared/credentials_inventory/personal_access_tokens', credentials: @credentials
- elsif show_ssh_keys?
= render partial: 'admin/credentials/ssh_keys', locals: { credentials: @credentials }
= render 'shared/credentials_inventory/ssh_keys', credentials: @credentials
= paginate_without_count @credentials
.gl-responsive-table-row{ role: 'row', data: { qa_selector: 'credentials_personal_access_token_row_content' } }
.table-section.section-25
.table-section.section-40
.table-mobile-header{ role: 'rowheader' }
= _('Owner')
.table-mobile-content
= render 'admin/users/user_detail', user: personal_access_token.user
= render 'shared/credentials_inventory/users/user_detail', user: personal_access_token.user
.table-section.section-30
.table-mobile-header{ role: 'rowheader' }
= _('Scope')
......
......@@ -3,7 +3,7 @@
.table-mobile-header{ role: 'rowheader' }
= _('Owner')
.table-mobile-content
= render 'admin/users/user_detail', user: ssh_key.user
= render 'shared/credentials_inventory/users/user_detail', user: ssh_key.user
.table-section.section-15
.table-mobile-header{ role: 'rowheader' }
= _('Created On')
......
.flex-list
.flex-row
= user_avatar_without_link(user: user, size: 32, css_class: 'avatar s32 d-none d-md-flex')
.row-main-content
.row-title.str-truncated-100
= user_avatar_without_link(user: user, size: 16, css_class: 'avatar s16 d-xs-flex d-md-none mr-1 prepend-top-2')
= link_to user.name, user_detail_path(user), class: 'text-plain js-user-link', data: { user_id: user.id, qa_selector: 'username_link' }
.row-second-line.str-truncated-100
= mail_to user.email, user.email, class: 'text-secondary'
......@@ -2,7 +2,7 @@
require 'spec_helper'
describe Admin::CredentialsHelper do
describe CredentialsInventoryHelper do
let(:filter) { nil }
before do
......
......@@ -1260,12 +1260,6 @@ msgstr ""
msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
msgstr ""
msgid "AdminCredentials|Personal Access Tokens"
msgstr ""
msgid "AdminCredentials|SSH Keys"
msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
......@@ -1413,9 +1407,6 @@ msgstr ""
msgid "AdminUsers|New user"
msgstr ""
msgid "AdminUsers|No credentials found"
msgstr ""
msgid "AdminUsers|No users found"
msgstr ""
......@@ -5622,6 +5613,15 @@ msgstr ""
msgid "Credentials"
msgstr ""
msgid "CredentialsInventory|No credentials found"
msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
msgid "CredentialsInventory|SSH Keys"
msgstr ""
msgid "Critical vulnerabilities present"
msgstr ""
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment