Adds attributes for email-based OTP to UserDetails

What does this MR do and why?

Adds attributes for email-based OTP to UserDetails

To support sending one-time passcodes with email we first need to have attributes on which to store them:

  • email_otp: is a string column where a SHA256 hash of the OTP will be stored.
    • We validate that this is exactly 64 characters to a) defend against the otp accidentally being stored in plaintext, and b) signal that if the hashing algorithm changes then the column limit needs to change too.
    • We override UserDetail#serializable_hash and exclude this attribute as defense-in-depth against accidental inclusion of the hashed value in API responses.
  • email_otp_required_after: a datetime, which will be used to control when a user is required to perform the Email-based OTP flow during sign in
  • email_otp_last_sent_at: a datetime set every time we send or resend the OTP, used to determine whether the OTP has expired
  • email_otp_last_sent_to: a string containing the email address the OTP was sent to, as an auditing / historical record.
    • We use a string instead of a relation to an Email record as Email#email might change over time, or the Email record might be deleted.
    • The plan in the Architecture Design had signaled using a bigint. We deviate from the plan for the above reason.

We use UserDetail instead of User because the User table is already too wide. See https://docs.gitlab.com/development/database/layout_and_access_patterns/#example. (User is where other token patterns are implemented).

Part of https://gitlab.com/gitlab-org/gitlab/-/issues/554382

Changelog: added

References

For more information on this change:

Development references:

Screenshots or screen recordings

Before After

How to set up and validate locally

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Nick Malcolm

Merge request reports

Loading