Add two step sign in flow

What does this MR do and why?

Related to #574995 (closed)

We are implementing a two step sign in flow that will be used for organization/cells sign in. In this flow the user enters their username, clicks Continue and then enters their password. After clicking continue we make an API request to figure out if they are currently on the correct cell. If they are we show the password field immediately, if they are not we reload the page with the login query param which will then route them to the correct cell. Here is a mermaid chart to help explain:

sequenceDiagram
  actor User as User
  participant Browser as Browser
  participant Router as Router
  participant LegacyCell as Legacy Cell
  participant Topology as Topology Service
  participant Protocell as Protocell

  User ->> Browser: Navigate to gitlab.com/users/sign_in
  Browser ->> Router: GET /users/sign_in
  Router ->> LegacyCell: Route to legacy cell
  LegacyCell ->> Browser: Render sign-in page
  User ->> Browser: Enter email/username
  User ->> Browser: Click "Continue" button
  Browser ->> LegacyCell: AJAX GET /users/sign_in_path?login=john@gmail.com
  alt If user is on Legacy Cell
    LegacyCell->>Browser: JSON response { "sign_in_path": null }
    Browser ->> Browser: Show password field with JavaScript (no reload)
    User ->> Browser: Enter password
    User ->> Browser: Click "Sign in" button
    Browser->>LegacyCell: POST /users/sign_in { "login": "john@gmail.com", "password": "foo" }
    LegacyCell ->> Browser: Authenticate
  else If user is on Protocell
    LegacyCell->>Browser: JSON response { "sign_in_path": '/users/sign_in?login=john@gmail.com' }
    Browser ->> Router: GET /users/sign_in?login=john@gmail.com
    Router ->> Topology: Request cell using `login` param
    Topology ->> Router: Return cell ID
    Router ->> Protocell: Route to protocell
    Protocell ->> Browser: Render sign-in page
    User ->> Browser: Enter password
    User ->> Browser: Click "Sign in" button
    Browser->>Protocell: POST /users/sign_in { "login": "john@gmail.com", "password": "foo" }
    Protocell ->> Browser: Authenticate
  end

References

Screenshots or screen recordings

Current one step flow (no changes)

Click to expand

1Password

Passkey

User is found on current cell (show password field without reloading)

Click to expand

Manual typing

1Password

LastPass

NordPass

Remember me

Passkey

Passkey with remember me

gitlab.com - user is not found on current cell (reload and show password field)

Click to expand

Manual typing

1Password

LastPass

NordPass

Remember me

Passkey

Passkey with remember me

self-managed - show password field without reloading

Click to expand

Manual typing

1Password

LastPass

NordPass

Remember me

Passkey

Passkey with remember me

How to set up and validate locally

  • Add this to gdk.yml in your gdk directory
env:
  GITLAB_SIMULATE_SAAS: true
  • Run gdk restart
  • Go to /rails/features and enable two_step_sign_in feature flag

User is found on current cell

  1. Sign in

User is not found on current cell

  1. Apply this patch
diff --git a/ee/app/controllers/ee/sessions_controller.rb b/ee/app/controllers/ee/sessions_controller.rb
index 1e61e6fdd1ff..8951993f4ee5 100644
--- a/ee/app/controllers/ee/sessions_controller.rb
+++ b/ee/app/controllers/ee/sessions_controller.rb
@@ -43,8 +43,8 @@ def determine_sign_in_path
       login = safe_login_param
       return if login.blank?
 
-      user = ::User.find_by_login(login)
-      return if user.present?
+      # user = ::User.find_by_login(login)
+      # return if user.present?
 
       new_user_session_path(login: login)
     end
  1. Sign in

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 Peter Hegman

Merge request reports

Loading