Skip to content
Snippets Groups Projects
Unverified Commit 60f46bd2 authored by John Skarbek's avatar John Skarbek Committed by GitLab
Browse files

Merge branch 'eduardosanz/token-expiration-banner-backport-16-0' into '16-0-stable-ee'

Add a banner informing about token expiration (16.0)

See merge request https://gitlab.com/gitlab-org/gitlab/-/merge_requests/158477



Merged-by: default avatarJohn Skarbek <jskarbek@gitlab.com>
Approved-by: default avatarImre Farkas <ifarkas@gitlab.com>
Approved-by: default avatarSofia Vistas <svistas@gitlab.com>
Co-authored-by: default avatarEduardo Sanz García <esanz-garcia@gitlab.com>
Co-authored-by: default avatarSavas Vedova <svedova@gitlab.com>
parents 74f18217 fe1ec686
No related branches found
No related tags found
No related merge requests found
Showing
with 276 additions and 0 deletions
.gl-broadcast-message.broadcast-banner-message.banner{ role: 'alert',
class: "js-broadcast-notification-#{@id} #{@theme}", data: { testid: 'banner-broadcast-message' } }
.gl-broadcast-message-content
.gl-broadcast-message-icon
= sprite_icon('bullhorn')
.gl-broadcast-message-text
%h2.gl-sr-only= _('Admin message')
= @message
- if @dismissable
= render Pajamas::ButtonComponent.new(category: :tertiary,
icon: 'close',
size: :small,
button_options: { class: 'gl-close-btn-color-inherit gl-broadcast-message-dismiss js-dismiss-current-broadcast-notification',
'aria-label': _('Close'),
data: { id: @id,
expire_date: @expire_date,
dismissal_path: @dismissal_path,
cookie_key: @cookie_key } },
icon_classes: 'gl-text-white')
# frozen_string_literal: true
module Pajamas
class BroadcastBannerComponent < Pajamas::Component
# @param [String] message
# @param [String] id
# @param [String] theme
# @param [Boolean] dismissable
# @param [String] expire_date
# @param [String] cookie_key
# @param [String] dismissal_path
def initialize(message:, id:, theme:, dismissable:, expire_date:, cookie_key:, dismissal_path: nil)
@message = message
@id = id
@theme = theme
@dismissable = dismissable
@expire_date = expire_date
@cookie_key = cookie_key
@dismissal_path = dismissal_path
end
delegate :sprite_icon, to: :helpers
end
end
Loading
Loading
@@ -33,6 +33,10 @@ def expires_at_field_data
min_date: 1.day.from_now.iso8601
}
end
def show_token_expiration_banner?
Gitlab::Auth::TokenExpirationBanner.show_token_expiration_banner?
end
end
 
AccessTokensHelper.prepend_mod
Loading
Loading
@@ -24,6 +24,7 @@
= dispensable_render_if_exists "layouts/header/licensed_user_count_threshold"
= dispensable_render_if_exists "layouts/header/token_expiry_notification"
= dispensable_render "shared/projects/inactive_project_deletion_alert"
= dispensable_render_if_exists "shared/token_expiration_banner"
= dispensable_render "layouts/broadcast"
= dispensable_render "layouts/header/read_only_banner"
= dispensable_render "layouts/header/registration_enabled_callout"
Loading
Loading
- id = 'token_expiration_banner'
- cookie_key = 'hide_broadcast_message_token_expiration_banner'
- return unless show_token_expiration_banner?
- return unless cookies[cookie_key].blank?
-# rubocop:disable Gitlab/DocUrl -- This documentation section is only available in version 17.1 onward.
- link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: 'https://docs.gitlab.com/ee/security/token_overview.html#troubleshooting' }
-# rubocop:enable Gitlab/DocUrl
- message = safe_format(s_('AccessTokens|GitLab now enforces expiry dates on tokens that originally had no set expiration date. Those tokens were given an expiration date of one year later. Please review your personal access tokens, project access tokens and group access tokens to ensure you are aware of upcoming expirations. Administrators of GitLab can find more information on how to identify and mitigate interruption, please take a look at our %{link_start}documentation%{link_end}.'), link_start: link_start, link_end: '</a>'.html_safe)
= render Pajamas::BroadcastBannerComponent.new(message: message, id: id, theme: 'light-indigo', dismissable: true, expire_date: Time.now.next_year.iso8601, cookie_key: cookie_key)
Loading
Loading
@@ -37,6 +37,7 @@ You can use the following environment variables to override certain values:
| `RAILS_ENV` | string | The Rails environment; can be one of `production`, `development`, `staging`, or `test`. |
| `GITLAB_RAILS_CACHE_DEFAULT_TTL_SECONDS` | integer | The default TTL used for entries stored in the Rails-cache. Default is `28800`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/95042) in 15.3. |
| `GITLAB_CI_CONFIG_FETCH_TIMEOUT_SECONDS` | integer | Timeout for resolving remote includes in CI config in seconds. Must be between `0` and `60`. Default is `30`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/116383) in 15.11. |
| `GITLAB_DISABLE_TOKEN_EXPIRATION_BANNER` | string | If set to `true`, `1`, or `yes`, the token expiration banner is not shown. Default is `false`. |
 
## Adding more variables
 
Loading
Loading
# frozen_string_literal: true
module Gitlab
module Auth
module TokenExpirationBanner
module_function
# rubocop:disable Gitlab/ModuleWithInstanceVariables, CodeReuse/ActiveRecord -- simple query and should be memoized per app boot
def show_token_expiration_banner?
return @show_token_expiration_banner unless @show_token_expiration_banner.nil?
if %w[1 yes true].include?(ENV.fetch('GITLAB_DISABLE_TOKEN_EXPIRATION_BANNER', false))
@show_token_expiration_banner = false
return @show_token_expiration_banner
end
unless Gitlab.version_info >= Gitlab::VersionInfo.new(16, 0) &&
Gitlab.version_info < Gitlab::VersionInfo.new(17, 1)
@show_token_expiration_banner = false
return @show_token_expiration_banner
end
@show_token_expiration_banner = Gitlab::Database::BackgroundMigration::BatchedMigration.where(
job_class_name: 'CleanupPersonalAccessTokensWithNilExpiresAt'
).exists?
end
# rubocop:enable Gitlab/ModuleWithInstanceVariables, CodeReuse/ActiveRecord
end
end
end
Loading
Loading
@@ -2291,6 +2291,9 @@ msgstr ""
msgid "AccessTokens|Feed token"
msgstr ""
 
msgid "AccessTokens|GitLab now enforces expiry dates on tokens that originally had no set expiration date. Those tokens were given an expiration date of one year later. Please review your personal access tokens, project access tokens and group access tokens to ensure you are aware of upcoming expirations. Administrators of GitLab can find more information on how to identify and mitigate interruption, please take a look at our %{link_start}documentation%{link_end}."
msgstr ""
msgid "AccessTokens|Incoming email token"
msgstr ""
 
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Pajamas::BroadcastBannerComponent, :aggregate_failures, type: :component, feature_category: :navigation do
before do
render_inline described_class.new(message: message,
id: id,
theme: theme,
dismissable: dismissable,
expire_date: expire_date,
cookie_key: cookie_key,
dismissal_path: dismissal_path
)
end
let(:message) { '_message_' }
let(:id) { '_99_' }
let(:theme) { '_theme_' }
let(:dismissable) { true }
let(:expire_date) { Time.now.iso8601 }
let(:cookie_key) { '_cookie_key_' }
let(:dismissal_path) { '/-/my-path' }
it 'sets the correct classes' do
expect(page).to have_selector(".js-broadcast-notification-#{id}")
expect(page).to have_selector(".#{theme}")
end
it 'contains a screen reader message' do
expect(page).to have_selector('.gl-sr-only', text: _('Admin message'))
end
it 'sets the message' do
expect(page).to have_content(message)
end
context 'when dismissable is true' do
it 'display close button' do
expect(page).to have_selector('button.js-dismiss-current-broadcast-notification')
expect(page).to have_selector("button[data-id='#{id}']")
expect(page).to have_selector("button[data-expire-date='#{expire_date}']")
expect(page).to have_selector("button[data-dismissal-path='#{dismissal_path}']")
expect(page).to have_selector("button[data-cookie-key='#{cookie_key}']")
end
context 'when dismissal_path is no set' do
let(:dismissal_path) { nil }
it 'display close button' do
expect(page).not_to have_selector("button[data-dismissal-path='#{dismissal_path}']")
end
end
end
context 'when dismissable is false' do
let(:dismissable) { false }
it 'does not display close button' do
expect(page).not_to have_selector('button.js-dismiss-current-broadcast-notification')
end
end
end
# frozen_string_literal: true
module Pajamas
class BroadcastBannerComponentPreview < ViewComponent::Preview
# @param message text
# @param id text
# @param theme text
# @param dismissable toggle
# @param expire_date text
# @param cookie_key text
# @param dismissal_path text
def default(
message: 'Message for the broadcast banner',
id: '99',
theme: 'light-indigo',
dismissable: true,
expire_date: Time.now.next_year.iso8601,
cookie_key: 'my_cookie',
dismissal_path: '/my-path'
)
render(Pajamas::BroadcastBannerComponent.new(
message: message,
id: id,
theme: theme,
dismissable: dismissable,
expire_date: expire_date,
cookie_key: cookie_key,
dismissal_path: dismissal_path
))
end
end
end
Loading
Loading
@@ -72,4 +72,12 @@
})
end
end
describe '#show_token_expiration_banner?' do
it 'calls the singleton method from the module' do
expect(Gitlab::Auth::TokenExpirationBanner).to receive(:show_token_expiration_banner?)
helper.show_token_expiration_banner?
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Auth::TokenExpirationBanner, feature_category: :system_access do
describe '.show_token_expiration_banner?' do
subject(:show_token_expiration_banner) { described_class.show_token_expiration_banner? }
let(:gitlab_version) { Gitlab::VersionInfo.new(16, 0) }
let(:model_class) { Gitlab::Database::BackgroundMigration::BatchedMigration }
# this method is meant to be memoized on app boot and not changed
# for specs, we need to reset it each time
before do
described_class.instance_variable_set(:@show_token_expiration_banner, nil)
allow(Gitlab).to receive(:version_info).twice.and_return(gitlab_version)
end
it { is_expected.to be(false) }
it 'memoizes results' do
expect(described_class.show_token_expiration_banner?).to be(false)
expect(model_class).not_to receive(:where)
# Second call shouldn't trigger database query
expect(show_token_expiration_banner).to be(false)
end
context 'when the batched migration is present in the db' do
before do
create(
:batched_background_migration,
job_class_name: 'CleanupPersonalAccessTokensWithNilExpiresAt'
)
end
it { is_expected.to be(true) }
it 'memoizes results' do
expect(described_class.show_token_expiration_banner?).to be(true)
expect(model_class).not_to receive(:where)
# Second call shouldn't trigger database query
expect(show_token_expiration_banner).to be(true)
end
context 'when banner is disabled by env var' do
before do
stub_env('GITLAB_DISABLE_TOKEN_EXPIRATION_BANNER', '1')
end
it { is_expected.to be(false) }
end
context 'when not in affected version range' do
let(:gitlab_version) { Gitlab::VersionInfo.new(17, 2) }
it { is_expected.to be(false) }
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'shared/_token_expiration_banner.html.haml', feature_category: :system_access do
context 'when all conditions are true' do
before do
allow(view).to receive(:show_token_expiration_banner?).and_return(true)
allow(view).to receive(:cookies).and_return({ 'hide_broadcast_message_token_expiration_banner' => nil })
end
it 'renders banner' do
render 'shared/token_expiration_banner'
expect(rendered).to have_content 'GitLab now enforces expiry dates on tokens'
end
end
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment