feat: improve oidc only mode
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
Simon 2026-03-16 14:37:09 +01:00
parent e8f27690a1
commit a8d9fe6121
Signed by: simon
GPG key ID: 40E7A58C4AA1EDB2
4 changed files with 198 additions and 0 deletions

View file

@ -283,6 +283,107 @@ defmodule MvWeb.AuthControllerTest do
assert to =~ "/auth/user/password/sign_in_with_token"
end
describe "when OIDC-only is enabled" do
setup %{conn: authenticated_conn} do
{:ok, settings} = Membership.get_settings()
original_oidc_only = Map.get(settings, :oidc_only, false)
{:ok, _} = Membership.update_settings(settings, %{oidc_only: true})
conn = build_unauthenticated_conn(authenticated_conn)
{:ok, conn: conn, original_oidc_only: original_oidc_only}
end
test "password sign-in is rejected and redirects to sign-in with error", %{
conn: conn,
original_oidc_only: original
} do
try do
_user =
create_test_user(%{
email: "password@example.com",
password: "secret123",
oidc_id: nil
})
{:ok, view, _html} = live(conn, "/sign-in")
result =
view
|> form("#user-password-sign-in-with-password",
user: %{email: "password@example.com", password: "secret123"}
)
|> render_submit()
# When OIDC-only is enabled, password sign-in must not succeed (no redirect to sign_in_with_token).
case result do
{:error, {:redirect, %{to: to}}} ->
refute to =~ "sign_in_with_token",
"Expected password sign-in to be rejected when OIDC-only, got redirect to: #{to}"
_ ->
# LiveView re-rendered (e.g. with flash error) instead of redirecting to success
:ok
end
after
{:ok, s} = Membership.get_settings()
Membership.update_settings(s, %{oidc_only: original})
end
end
end
describe "GET /sign-in when OIDC-only" do
test "redirects to OIDC flow when OIDC-only and OIDC are configured", %{
conn: authenticated_conn
} do
{:ok, settings} = Membership.get_settings()
prev = %{
oidc_only: settings.oidc_only,
oidc_client_id: settings.oidc_client_id,
oidc_base_url: settings.oidc_base_url,
oidc_redirect_uri: settings.oidc_redirect_uri
}
{:ok, _} =
Membership.update_settings(settings, %{
oidc_only: true,
oidc_client_id: "test-client",
oidc_base_url: "https://idp.example.com",
oidc_redirect_uri: "http://localhost:4000/auth/user/oidc/callback",
oidc_client_secret: "test-secret"
})
try do
conn = build_unauthenticated_conn(authenticated_conn)
conn = get(conn, ~p"/sign-in")
assert redirected_to(conn) =~ "/auth/user/oidc"
after
{:ok, s} = Membership.get_settings()
Membership.update_settings(s, prev)
end
end
test "returns 200 when OIDC-only but OIDC not configured", %{conn: authenticated_conn} do
{:ok, settings} = Membership.get_settings()
original_oidc_only = Map.get(settings, :oidc_only, false)
{:ok, _} = Membership.update_settings(settings, %{oidc_only: true})
try do
conn = build_unauthenticated_conn(authenticated_conn)
conn = get(conn, ~p"/sign-in")
assert conn.status == 200
after
{:ok, s} = Membership.get_settings()
Membership.update_settings(s, %{oidc_only: original_oidc_only})
end
end
test "returns 200 when OIDC-only is disabled", %{conn: authenticated_conn} do
conn = build_unauthenticated_conn(authenticated_conn)
conn = get(conn, ~p"/sign-in")
assert conn.status == 200
end
end
# OIDC/Rauthy error handling tests
describe "handle_oidc_failure/2" do
test "Assent.ServerUnreachableError redirects to sign-in with error flash", %{