Skip to content

Commit

Permalink
test(ex/skate_web/auth_controller): test for csrf failure (#2586)
Browse files Browse the repository at this point in the history
* test(ex/skate_web/auth_controller): test for csrf failure

* feat(ex/skate_web/auth_controller): redirect csrf issues to login

* test:feat(ex/skate_web/auth_controller): test that second failure returns existing behaviour

* feat(ex/skate_web/auth_controller): only redirect to login on first CSRF error

* cleanup(ex/skate_web/auth_controller): delete "retry" session variable on second try

* cleanup(ex/skate_web/auth_controller): replace failure with module attribute `@ueberauth_csrf_failure`
  • Loading branch information
firestack authored May 8, 2024
1 parent d26f862 commit 2d0b9b6
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 0 deletions.
28 changes: 28 additions & 0 deletions lib/skate_web/controllers/auth_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,34 @@ defmodule SkateWeb.AuthController do
|> redirect(to: ~p"/")
end

def callback(
%{
assigns: %{
ueberauth_failure:
%Ueberauth.Failure{
provider: :keycloak,
errors: [%Ueberauth.Failure.Error{message_key: "csrf_attack"}]
} = auth_struct
}
} = conn,
_params
) do
Logger.error(
"#{__MODULE__} keycloak callback csrf ueberauth_failure struct=#{Kernel.inspect(auth_struct)}"
)

if get_session(conn, :keycloak_csrf_retry) == 1 do
conn
|> delete_session(:keycloak_csrf_retry)
|> send_resp(:unauthorized, "unauthenticated")
else
conn
|> put_session(:keycloak_csrf_retry, 1)
|> Guardian.Plug.sign_out(AuthManager, [])
|> redirect(to: ~p"/auth/keycloak")
end
end

def callback(
%{assigns: %{ueberauth_failure: %{provider: :keycloak} = auth_struct}} = conn,
_params
Expand Down
26 changes: 26 additions & 0 deletions test/skate_web/controllers/auth_controller_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,32 @@ defmodule SkateWeb.AuthControllerTest do

assert response(conn, :unauthorized) == "unauthenticated"
end

@ueberauth_csrf_failure %Ueberauth.Failure{
provider: :keycloak,
errors: [%Ueberauth.Failure.Error{message_key: "csrf_attack"}]
}

test "retries login on first ueberauth CSRF failure", %{conn: conn} do
conn =
conn
|> init_test_session(%{username: "test_username"})
|> assign(:ueberauth_failure, @ueberauth_csrf_failure)
|> get(~p"/auth/keycloak/callback")

assert redirected_to(conn, :found) == ~p"/auth/keycloak"
end

test "when CSRF error is encountered again, returns unauthenticated", %{conn: conn} do
conn =
conn
|> init_test_session(%{username: "test_username"})
|> assign(:ueberauth_failure, @ueberauth_csrf_failure)
|> put_session(:keycloak_csrf_retry, 1)
|> get(~p"/auth/keycloak/callback")

assert response(conn, :unauthorized) == "unauthenticated"
end
end

describe "GET /auth/keycloak/logout" do
Expand Down

0 comments on commit 2d0b9b6

Please sign in to comment.