Skip to content

SSH key expiring soon email notification

Aishwarya Subramanian requested to merge expiring-ssh-key-notification into master

What does this MR do?

This MR adds changes to send an email to users when their SSH is about to expire in the next 7 days.

It adds a column before_expiry_notification_delivered_at to track notification delivery to user.

Note: The implementation is similar to email sent on expiry.

Mentions #322637 (closed)

Screenshots (strongly suggested)

Screen_Shot_2021-04-05_at_10.54.17_AM

Database migrations

Migration
== 20210401175134 AddBeforeExpiryNotificationDeliveredToKeys: migrating =======
-- add_column(:keys, :before_expiry_notification_delivered_at, :datetime_with_timezone)
   -> 0.0041s
== 20210401175134 AddBeforeExpiryNotificationDeliveredToKeys: migrated (0.0042s)

== 20210401192808 AddIndexToKeysOnExpiresAtAndBeforeExpiryNotificationUndelivered: migrating
-- transaction_open?()
   -> 0.0000s
-- index_exists?(:keys, "date(timezone('UTC', expires_at)), before_expiry_notification_delivered_at", {:where=>"before_expiry_notification_delivered_at IS NULL", :name=>"idx_keys_expires_at_and_before_expiry_notification_undelivered", :algorithm=>:concurrently})
   -> 0.0044s
-- execute("SET statement_timeout TO 0")
   -> 0.0006s
-- add_index(:keys, "date(timezone('UTC', expires_at)), before_expiry_notification_delivered_at", {:where=>"before_expiry_notification_delivered_at IS NULL", :name=>"idx_keys_expires_at_and_before_expiry_notification_undelivered", :algorithm=>:concurrently})
   -> 0.0067s
-- execute("RESET ALL")
   -> 0.0007s
== 20210401192808 AddIndexToKeysOnExpiresAtAndBeforeExpiryNotificationUndelivered: migrated (0.0134s)
Rollback
== 20210401175134 AddBeforeExpiryNotificationDeliveredToKeys: reverting =======
-- remove_column(:keys, :before_expiry_notification_delivered_at, :datetime_with_timezone)
   -> 0.0023s
== 20210401175134 AddBeforeExpiryNotificationDeliveredToKeys: reverted (0.0050s)

== 20210401192808 AddIndexToKeysOnExpiresAtAndBeforeExpiryNotificationUndelivered: reverting
-- transaction_open?()
   -> 0.0000s
-- indexes(:keys)
   -> 0.0059s
-- execute("SET statement_timeout TO 0")
   -> 0.0008s
-- remove_index(:keys, {:algorithm=>:concurrently, :name=>"idx_keys_expires_at_and_before_expiry_notification_undelivered"})
   -> 0.0070s
-- execute("RESET ALL")
   -> 0.0006s
== 20210401192808 AddIndexToKeysOnExpiresAtAndBeforeExpiryNotificationUndelivered: reverted (0.0330s)

Database Queries

User.with_ssh_key_expiring_soon

Query:

SELECT
  "users".*
FROM
  "users"
WHERE (EXISTS (
    SELECT
      1
    FROM
      "keys"
    WHERE (keys.user_id = users.id)
    AND (date(expires_at AT TIME ZONE 'UTC') > CURRENT_DATE
      AND date(expires_at AT TIME ZONE 'UTC') < '2021-04-12'
      AND before_expiry_notification_delivered_at IS NULL)))

Details and visualization:

Before index After index
Link Link

Statistics:

Time: 20.218 ms
  - planning: 9.233 ms
  - execution: 10.985 ms
    - I/O read: 1.116 ms
    - I/O write: N/A

Shared buffers:
  - hits: 2127 (~16.60 MiB) from the buffer pool
  - reads: 42 (~336.00 KiB) from the OS file cache, including disk I/O
  - dirtied: 0
  - writes: 0
Key.expiring_soon_and_not_notified

Query:

SELECT
  "keys".*
FROM
  "keys"
WHERE (date(expires_at AT TIME ZONE 'UTC') > CURRENT_DATE
  AND date(expires_at AT TIME ZONE 'UTC') < '2021-04-12'
  AND before_expiry_notification_delivered_at IS NULL)

Details and visualization:

Before index After index
Link Link

Statistics:

Time: 7.371 ms
  - planning: 3.071 ms
  - execution: 4.300 ms
    - I/O read: N/A
    - I/O write: N/A

Shared buffers:
  - hits: 453 (~3.50 MiB) from the buffer pool
  - reads: 0 from the OS file cache, including disk I/O
  - dirtied: 0
  - writes: 0

Does this MR meet the acceptance criteria?

Conformity

Availability and Testing

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 Aishwarya Subramanian

Merge request reports