This commit is contained in:
parent
8e5524de57
commit
bd79a9b9e1
13 changed files with 1321 additions and 174 deletions
|
|
@ -9,7 +9,7 @@ defmodule MvWeb.OidcE2EFlowTest do
|
|||
require Ash.Query
|
||||
|
||||
describe "E2E: New OIDC user registration" do
|
||||
test "new user can register via OIDC", %{conn: conn} do
|
||||
test "new user can register via OIDC", %{conn: _conn} do
|
||||
# Simulate OIDC callback for brand new user
|
||||
user_info = %{
|
||||
"sub" => "new_oidc_user_123",
|
||||
|
|
@ -40,7 +40,7 @@ defmodule MvWeb.OidcE2EFlowTest do
|
|||
end
|
||||
|
||||
describe "E2E: Existing OIDC user sign-in" do
|
||||
test "existing OIDC user can sign in and email updates", %{conn: conn} do
|
||||
test "existing OIDC user can sign in and email updates", %{conn: _conn} do
|
||||
# Create OIDC user
|
||||
user =
|
||||
create_test_user(%{
|
||||
|
|
@ -70,7 +70,7 @@ defmodule MvWeb.OidcE2EFlowTest do
|
|||
|
||||
describe "E2E: OIDC with existing password account (Email Collision)" do
|
||||
test "OIDC registration with password account email triggers PasswordVerificationRequired",
|
||||
%{conn: conn} do
|
||||
%{conn: _conn} do
|
||||
# Step 1: Create a password-only user
|
||||
password_user =
|
||||
create_test_user(%{
|
||||
|
|
@ -106,7 +106,7 @@ defmodule MvWeb.OidcE2EFlowTest do
|
|||
end
|
||||
|
||||
test "full E2E flow: OIDC collision -> password verification -> account linked",
|
||||
%{conn: conn} do
|
||||
%{conn: _conn} do
|
||||
# Step 1: Create password user
|
||||
password_user =
|
||||
create_test_user(%{
|
||||
|
|
@ -168,7 +168,7 @@ defmodule MvWeb.OidcE2EFlowTest do
|
|||
end
|
||||
|
||||
test "E2E: OIDC collision with different email at provider updates email after linking",
|
||||
%{conn: conn} do
|
||||
%{conn: _conn} do
|
||||
# Password user with old email
|
||||
password_user =
|
||||
create_test_user(%{
|
||||
|
|
@ -213,7 +213,7 @@ defmodule MvWeb.OidcE2EFlowTest do
|
|||
end
|
||||
|
||||
describe "E2E: OIDC with linked member" do
|
||||
test "E2E: email sync to member when linking OIDC to password account", %{conn: conn} do
|
||||
test "E2E: email sync to member when linking OIDC to password account", %{conn: _conn} do
|
||||
# Create member
|
||||
member =
|
||||
Ash.Seed.seed!(Mv.Membership.Member, %{
|
||||
|
|
@ -270,7 +270,7 @@ defmodule MvWeb.OidcE2EFlowTest do
|
|||
end
|
||||
|
||||
describe "E2E: Security scenarios" do
|
||||
test "E2E: password-only user cannot be accessed via OIDC without password", %{conn: conn} do
|
||||
test "E2E: password-only user cannot be accessed via OIDC without password", %{conn: _conn} do
|
||||
# Create password user
|
||||
_password_user =
|
||||
create_test_user(%{
|
||||
|
|
@ -315,9 +315,9 @@ defmodule MvWeb.OidcE2EFlowTest do
|
|||
end)
|
||||
end
|
||||
|
||||
test "E2E: user with oidc_id cannot be hijacked by different OIDC provider", %{conn: conn} do
|
||||
test "E2E: user with oidc_id cannot be hijacked by different OIDC provider", %{conn: _conn} do
|
||||
# User linked to OIDC provider A
|
||||
user =
|
||||
_user =
|
||||
create_test_user(%{
|
||||
email: "linked@example.com",
|
||||
oidc_id: "provider_a_123"
|
||||
|
|
@ -329,25 +329,31 @@ defmodule MvWeb.OidcE2EFlowTest do
|
|||
"preferred_username" => "linked@example.com"
|
||||
}
|
||||
|
||||
# Should trigger password requirement (different oidc_id)
|
||||
# Should trigger hard error (not PasswordVerificationRequired)
|
||||
{:error, %Ash.Error.Invalid{errors: errors}} =
|
||||
Mv.Accounts.create_register_with_rauthy(%{
|
||||
user_info: user_info,
|
||||
oauth_tokens: %{}
|
||||
})
|
||||
|
||||
password_error =
|
||||
Enum.find(errors, fn err ->
|
||||
match?(%Mv.Accounts.User.Errors.PasswordVerificationRequired{}, err)
|
||||
end)
|
||||
# Should have hard error about "already linked to a different OIDC account"
|
||||
assert Enum.any?(errors, fn
|
||||
%Ash.Error.Changes.InvalidAttribute{message: msg} ->
|
||||
String.contains?(msg, "already linked to a different OIDC account")
|
||||
|
||||
assert password_error != nil
|
||||
assert password_error.user_id == user.id
|
||||
_ ->
|
||||
false
|
||||
end)
|
||||
|
||||
# Should NOT be PasswordVerificationRequired
|
||||
refute Enum.any?(errors, fn err ->
|
||||
match?(%Mv.Accounts.User.Errors.PasswordVerificationRequired{}, err)
|
||||
end)
|
||||
end
|
||||
|
||||
test "E2E: empty string oidc_id is treated as password-only account", %{conn: conn} do
|
||||
test "E2E: empty string oidc_id is treated as password-only account", %{conn: _conn} do
|
||||
# User with empty oidc_id
|
||||
password_user =
|
||||
_password_user =
|
||||
create_test_user(%{
|
||||
email: "empty@example.com",
|
||||
password: "pass123",
|
||||
|
|
@ -374,7 +380,7 @@ defmodule MvWeb.OidcE2EFlowTest do
|
|||
end
|
||||
|
||||
describe "E2E: Error scenarios" do
|
||||
test "E2E: OIDC registration without oidc_id fails", %{conn: conn} do
|
||||
test "E2E: OIDC registration without oidc_id fails", %{conn: _conn} do
|
||||
user_info = %{
|
||||
"preferred_username" => "noid@example.com"
|
||||
}
|
||||
|
|
@ -390,7 +396,7 @@ defmodule MvWeb.OidcE2EFlowTest do
|
|||
end)
|
||||
end
|
||||
|
||||
test "E2E: OIDC registration without email fails", %{conn: conn} do
|
||||
test "E2E: OIDC registration without email fails", %{conn: _conn} do
|
||||
user_info = %{
|
||||
"sub" => "noemail_123"
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue