Email notification for Expired Personal Access Token
What does this MR do?
Adds a cron job that runs at 2 am daily and checks for Personal Access Tokens that have expired on the current day.
Sends out an email notification to the user indicating that their Personal Access Tokens have expired. Also, links the Manage Token page to assist the user to take an action.
Mentions #214721 (closed)
Omnibus changes
Feature flag
Name: expired_pat_email_notification
Disabled by default.
Screenshots
Email preview:
Database changes
Migration
== 20200729151021 AddAfterExpiryNotificationDeliveredToPersonalAccessTokens: migrating
-- add_column(:personal_access_tokens, :after_expiry_notification_delivered, :boolean, {:null=>false, :default=>false})
-> 0.0035s
== 20200729151021 AddAfterExpiryNotificationDeliveredToPersonalAccessTokens: migrated (0.0036s)
Rollback
== 20200729151021 AddAfterExpiryNotificationDeliveredToPersonalAccessTokens: reverting
-- remove_column(:personal_access_tokens, :after_expiry_notification_delivered, :boolean, {:null=>false, :default=>false})
-> 0.0039s
== 20200729151021 AddAfterExpiryNotificationDeliveredToPersonalAccessTokens: reverted (0.0070s)
Query
SELECT
"users".*
FROM
"users"
WHERE (EXISTS (
SELECT
1
FROM
"personal_access_tokens"
WHERE (personal_access_tokens.user_id = users.id)
AND "personal_access_tokens"."impersonation" = FALSE
AND (revoked = FALSE
AND expires_at = CURRENT_DATE
AND after_expiry_notification_delivered = FALSE)))
After index:
Link to execution plan:
https://explain.depesz.com/s/La7N
Execution Time:
Time: 300.623 ms
- planning: 1.081 ms
- execution: 299.542 ms
- I/O read: 243.414 ms
- I/O write: 0.000 ms
Shared buffers:
- hits: 702 (~5.50 MiB) from the buffer pool
- reads: 8800 (~68.80 MiB) from the OS file cache, including disk I/O
- dirtied: 0
- writes: 0
Before index:
Link to execution plan:
https://explain.depesz.com/s/O8lv
Execution Time:
Time: 445.142 ms
- planning: 0.826 ms
- execution: 444.316 ms
- I/O read: 357.225 ms
- I/O write: 0.000 ms
Shared buffers:
- hits: 193 (~1.50 MiB) from the buffer pool
- reads: 11746 (~91.80 MiB) from the OS file cache, including disk I/O
- dirtied: 151 (~1.20 MiB)
- writes: 0
Local testing
- Create a new Personal Access Token that expires today (
<gdk link>/profile/personal_access_tokens
) - Optionally configure the expiry email to be sent immediately (Change
deliver_later
todeliver_now
in the notification service) - Head over to
rails console
:- Execute the job:
PersonalAccessTokens::ExpiredNotificationWorker.new.perform
- Check for a new email
Your personal access token has expired
in<gdk link>/rails/letter_opener
- Execute the job:
Does this MR meet the acceptance criteria?
Conformity
-
Changelog entry - [-] Documentation (if required)
-
Code review guidelines -
Merge request performance guidelines -
Style guides -
Database guides - [-] Separation of EE specific content
Availability and Testing
-
Review and add/update tests for this feature/bug. Consider all test levels. See the Test Planning Process. - [-] Tested in all supported browsers
- [-] Informed Infrastructure department of a default or new setting change, if applicable per definition of done
Security
If this MR contains changes to processing or storing of credentials or tokens, authorization and authentication methods and other items described in the security review guidelines:
- [-] Label as security and @ mention
@gitlab-com/gl-security/appsec
- [-] The MR includes necessary changes to maintain consistency between UI, API, email, or other methods
- [-] Security reports checked/validated by a reviewer from the AppSec team
Edited by Mayra Cabrera