Commit 57edb519 authored by Robert Hunt's avatar Robert Hunt

Adding expiration date and colour to credentials

Adds colour and icons to PATs and SSH keys to warn when a credential
is expiring or expired. Also shows a tooltip for the expired credentials

Added the logic to a separate shared HAML template since it's the same
code

Updated backend logic to find expired as well when doing the DB query

Added spec tests

Adds new shared examples for expiry date within the credentials
inventory

Adds these to the admin and group spec tests
parent 5de6d85d
- if expiry_date&.past? || expiry_date&.today?
%span.d-inline-flex.align-items-center.text-danger.has-tooltip{ title: _('This credential has expired'), data: { testid: 'expiry-date-icon' } }
= sprite_icon('error', size: 16, css_class: "gl-icon mr-1")
= expiry_date.to_date
- elsif expiry_date.present?
- if expires_soon
%span.d-inline-flex.align-items-center.text-warning{ data: { testid: 'expiry-date-icon' } }
= sprite_icon('warning', size: 16, css_class: "gl-icon mr-1")
= expiry_date.to_date
- else
= expiry_date.to_date
- else
= _('Never')
......@@ -3,5 +3,6 @@
.table-section.section-40{ role: 'rowheader' }= _('Owner')
.table-section.section-15{ role: 'rowheader' }= _('Created On')
.table-section.section-15{ role: 'rowheader' }= _('Last Accessed On')
.table-section.section-15{ role: 'rowheader' }= _('Expiration')
= render partial: 'shared/credentials_inventory/ssh_keys/ssh_key', collection: credentials
......@@ -19,10 +19,7 @@
.table-mobile-header{ role: 'rowheader' }
= _('Expiration')
.table-mobile-content
- if personal_access_token.expires?
= personal_access_token.expires_at
- else
= _('Never')
= render 'shared/credentials_inventory/expiry_date', expiry_date: personal_access_token.expires_at, expires_soon: personal_access_token.expires_soon?
.table-section.section-10
.table-mobile-header{ role: 'rowheader' }
= _('Revoked')
......
......@@ -14,3 +14,8 @@
= _('Last Accessed On')
.table-mobile-content
= (last_used_at = ssh_key.last_used_at).present? ? last_used_at.to_date : _('Never')
.table-section.section-15
.table-mobile-header{ role: 'rowheader' }
= _('Expiration')
.table-mobile-content
= render 'shared/credentials_inventory/expiry_date', expiry_date: ssh_key.expires_at, expires_soon: ssh_key.expires_soon?
---
title: Highlight expired SSH or PAT credentials in the credential inventory
merge_request: 35229
author:
type: changed
......@@ -51,20 +51,9 @@ RSpec.describe 'Admin::CredentialsInventory' do
end
context 'by SSH Keys' do
before do
create(:personal_key,
user: create(:user, name: 'Tom'),
created_at: '2019-12-09',
last_used_at: '2019-12-10')
visit admin_credentials_path(filter: 'ssh_keys')
end
let(:credentials_path) { admin_credentials_path(filter: 'ssh_keys') }
it 'shows details of ssh keys' do
expect(first_row.text).to include('Tom')
expect(first_row.text).to include('2019-12-09')
expect(first_row.text).to include('2019-12-10')
end
it_behaves_like 'credentials inventory SSH keys'
end
end
end
......
......@@ -48,20 +48,9 @@ RSpec.describe 'Groups::Security::Credentials' do
end
context 'by SSH Keys' do
before do
create(:personal_key,
user: managed_user,
created_at: '2019-12-09',
last_used_at: '2019-12-10')
visit group_security_credentials_path(group_id: group_id, filter: 'ssh_keys')
end
let(:credentials_path) { group_security_credentials_path(group_id: group_id, filter: 'ssh_keys') }
it 'shows details of ssh keys' do
expect(first_row.text).to include('David')
expect(first_row.text).to include('2019-12-09')
expect(first_row.text).to include('2019-12-10')
end
it_behaves_like 'credentials inventory SSH keys', group_managed_account: true
end
end
end
......
# frozen_string_literal: true
RSpec.shared_examples 'credentials inventory expiry date' do
it 'shows the expiry date' do
visit credentials_path
expect(first_row.text).to include(expiry_date)
end
end
RSpec.shared_examples 'credentials inventory expiry date before' do
it 'shows the expiry without any warnings' do
Timecop.freeze(20.days.ago) do
visit credentials_path
expect(first_row).not_to have_selector('[data-testid="expiry-date-icon"]')
end
end
end
RSpec.shared_examples 'credentials inventory expiry date close or past' do
it 'adds a warning to the expiry date' do
Timecop.freeze(date_time) do
visit credentials_path
expect(first_row).to have_selector('[data-testid="expiry-date-icon"]', class: css_class)
end
end
end
RSpec.shared_examples_for 'credentials inventory personal access tokens' do |group_managed_account: false|
let_it_be(:user) { group_managed_account ? managed_user : create(:user, name: 'David') }
......@@ -23,6 +51,39 @@ RSpec.shared_examples_for 'credentials inventory personal access tokens' do |gro
end
end
context 'when a personal access token has an expiry' do
let(:expiry_date) { 1.day.since.to_date.to_s }
before do
create(:personal_access_token,
user: user,
created_at: '2019-12-10',
updated_at: '2020-06-22',
expires_at: expiry_date)
end
context 'and is not expired' do
it_behaves_like 'credentials inventory expiry date'
it_behaves_like 'credentials inventory expiry date before'
end
context 'and is near expiry' do
let(:css_class) { 'text-warning' }
let(:date_time) { 1.day.ago }
it_behaves_like 'credentials inventory expiry date'
it_behaves_like 'credentials inventory expiry date close or past'
end
context 'and is expired' do
let(:css_class) { 'text-danger' }
let(:date_time) { 2.days.since }
it_behaves_like 'credentials inventory expiry date'
it_behaves_like 'credentials inventory expiry date close or past'
end
end
context 'when a personal access token is revoked' do
before do
create(:personal_access_token,
......@@ -43,3 +104,59 @@ RSpec.shared_examples_for 'credentials inventory personal access tokens' do |gro
end
end
end
RSpec.shared_examples_for 'credentials inventory SSH keys' do |group_managed_account: false|
let_it_be(:user) { group_managed_account ? managed_user : create(:user, name: 'David') }
context 'when a SSH key is active' do
before do
create(:personal_key,
user: user,
created_at: '2019-12-09',
last_used_at: '2019-12-10',
expires_at: nil)
visit credentials_path
end
it 'shows the details with no expiry' do
expect(first_row.text).to include('David')
expect(first_row.text).to include('2019-12-09')
expect(first_row.text).to include('2019-12-10')
expect(first_row.text).to include('Never')
end
end
context 'when a SSH key has an expiry' do
let(:expiry_date) { 1.day.since.to_date.to_s }
before do
create(:personal_key,
user: user,
created_at: '2019-12-10',
last_used_at: '2020-06-22',
expires_at: expiry_date)
end
context 'and is not expired' do
it_behaves_like 'credentials inventory expiry date'
it_behaves_like 'credentials inventory expiry date before'
end
context 'and is near expiry' do
let(:css_class) { 'text-warning' }
let(:date_time) { 1.day.ago }
it_behaves_like 'credentials inventory expiry date'
it_behaves_like 'credentials inventory expiry date close or past'
end
context 'and is expired' do
let(:css_class) { 'text-danger' }
let(:date_time) { 2.days.since }
it_behaves_like 'credentials inventory expiry date'
it_behaves_like 'credentials inventory expiry date close or past'
end
end
end
......@@ -23506,6 +23506,9 @@ msgstr ""
msgid "This content could not be displayed because %{reason}. You can %{options} instead."
msgstr ""
msgid "This credential has expired"
msgstr ""
msgid "This date is after the due date, so this epic won't appear in the roadmap."
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