Fix missing SSO JIT account creation template (#679)

* Add UI and functionality for new user registration via OIDC integration

* Add tests and localization for new user registration via OIDC

---------

Co-authored-by: luckyPipewrench <luckypipewrench@proton.me>
This commit is contained in:
LPW
2026-01-16 15:00:24 -05:00
committed by GitHub
parent c391ba2b23
commit 1ca84d8048
4 changed files with 92 additions and 2 deletions

View File

@@ -102,10 +102,12 @@ class OidcAccountsController < ApplicationController
# Security: JIT users should NOT have password_digest set to prevent
# chained authentication attacks where SSO users gain local login access
# via password reset.
# Allow user to edit first_name and last_name from the form, but email comes from OIDC
user_params = params.fetch(:user, {}).permit(:first_name, :last_name)
@user = User.new(
email: email,
first_name: @pending_auth["first_name"],
last_name: @pending_auth["last_name"],
first_name: user_params[:first_name].presence || @pending_auth["first_name"],
last_name: user_params[:last_name].presence || @pending_auth["last_name"],
skip_password_validation: true
)

View File

@@ -0,0 +1,37 @@
<%
header_title t("oidc_accounts.new_user.title")
%>
<div class="mb-6 p-4 bg-blue-50 border border-blue-200 rounded-md">
<h3 class="text-sm font-medium text-blue-800 mb-2"><%= t("oidc_accounts.new_user.heading") %></h3>
<p class="text-sm text-blue-700">
<%= t("oidc_accounts.new_user.description", provider: @pending_auth["provider"]) %>
</p>
</div>
<%= styled_form_with model: @user, url: create_user_oidc_account_path, class: "space-y-4", data: { turbo: false } do |form| %>
<div class="p-4 bg-container border border-secondary rounded-md">
<p class="text-sm text-secondary mb-1"><%= t("oidc_accounts.new_user.email_label") %></p>
<p class="text-sm text-primary font-medium"><%= @pending_auth["email"] %></p>
</div>
<%= form.text_field :first_name,
label: t("oidc_accounts.new_user.first_name_label"),
placeholder: t("oidc_accounts.new_user.first_name_placeholder"),
autofocus: true %>
<%= form.text_field :last_name,
label: t("oidc_accounts.new_user.last_name_label"),
placeholder: t("oidc_accounts.new_user.last_name_placeholder") %>
<%= form.submit t("oidc_accounts.new_user.submit") %>
<% end %>
<div class="mt-6 text-center">
<%= render DS::Link.new(
text: t("oidc_accounts.new_user.cancel"),
href: new_session_path,
variant: :default,
class: "font-medium text-sm text-primary hover:underline transition"
) %>
</div>

View File

@@ -3,3 +3,14 @@ en:
oidc_accounts:
link:
account_creation_disabled: New account creation via single sign-on is disabled. Please contact an administrator to create your account.
new_user:
title: Complete Your Account
heading: Create Your Account
description: Please confirm your details to complete account creation with your %{provider} identity.
email_label: Email (from SSO provider)
first_name_label: First Name
first_name_placeholder: Enter your first name
last_name_label: Last Name
last_name_placeholder: Enter your last name
submit: Create Account
cancel: Cancel

View File

@@ -98,6 +98,18 @@ class OidcAccountsControllerTest < ActionController::TestCase
}
end
test "should show new_user page when pending auth exists" do
session[:pending_oidc_auth] = new_user_auth
get :new_user
assert_response :success
end
test "should redirect new_user to login when no pending auth" do
get :new_user
assert_redirected_to new_session_path
assert_equal "No pending OIDC authentication found", flash[:alert]
end
test "should show create account option for new user" do
session[:pending_oidc_auth] = new_user_auth
@@ -175,6 +187,34 @@ class OidcAccountsControllerTest < ActionController::TestCase
assert_equal new_user_auth["uid"], oidc_identity.uid
end
test "create_user uses form params for name when provided" do
session[:pending_oidc_auth] = new_user_auth
assert_difference [ "User.count", "OidcIdentity.count" ], 1 do
post :create_user, params: {
user: { first_name: "Custom", last_name: "Name" }
}
end
assert_redirected_to root_path
new_user = User.find_by(email: new_user_auth["email"])
assert_equal "Custom", new_user.first_name
assert_equal "Name", new_user.last_name
end
test "create_user falls back to OIDC data when form params are blank" do
session[:pending_oidc_auth] = new_user_auth
post :create_user, params: {
user: { first_name: "", last_name: "" }
}
new_user = User.find_by(email: new_user_auth["email"])
assert_equal new_user_auth["first_name"], new_user.first_name
assert_equal new_user_auth["last_name"], new_user.last_name
end
test "should create session after OIDC registration" do
session[:pending_oidc_auth] = new_user_auth