Skip to content

Commit

Permalink
fix: store logout URL in user session, not guardian claims (#2408)
Browse files Browse the repository at this point in the history
* fix: store logout URL in user session, not guardian claims

* fixup! fix: store logout URL in user session, not guardian claims
  • Loading branch information
lemald authored Feb 21, 2024
1 parent 63c5999 commit 83f104e
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 10 deletions.
23 changes: 13 additions & 10 deletions lib/skate_web/controllers/auth_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ defmodule SkateWeb.AuthController do
|> Guardian.Plug.sign_in(
AuthManager,
%{id: user_id},
%{groups: groups, sign_out_url: sign_out_url(auth)},
%{groups: groups},
ttl: {1, :hour}
)
|> put_session(:sign_out_url, sign_out_url(auth))
|> redirect(to: ~p"/")
else
send_resp(conn, :forbidden, "forbidden")
Expand Down Expand Up @@ -90,20 +91,22 @@ defmodule SkateWeb.AuthController do

@spec logout(Plug.Conn.t(), map()) :: Plug.Conn.t()
def logout(conn, %{"provider" => "keycloak"}) do
case Guardian.Plug.current_claims(conn) do
%{"sign_out_url" => sign_out_url} when not is_nil(sign_out_url) ->
conn
|> session_cleanup()
|> redirect(external: sign_out_url)
claims = Guardian.Plug.current_claims(conn)

sign_out_url = get_session(conn, :sign_out_url) || Map.get(claims, "sign_out_url")

if is_nil(sign_out_url) do
# The router makes sure we can't call `/auth/:provider/callback`
# unless we have a session.
# So the potential `nil` from `current_claims` and the potential map with
# `sign_out_url=nil` can be handled the same
_ ->
conn
|> session_cleanup()
|> redirect(to: "/")
conn
|> session_cleanup()
|> redirect(to: "/")
else
conn
|> session_cleanup()
|> redirect(external: sign_out_url)
end
end

Expand Down
27 changes: 27 additions & 0 deletions test/skate_web/controllers/auth_controller_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ defmodule SkateWeb.AuthControllerTest do

import Test.Support.Helpers

import Skate.Factory

alias Skate.Settings.User

describe "GET /auth/:provider" do
Expand Down Expand Up @@ -129,6 +131,31 @@ defmodule SkateWeb.AuthControllerTest do
assert redirected_to(conn) == redirect_url
end

test "falls back to `sign_out_url` from Guardian claims", %{conn: conn} do
redirect_url = "redirect.url.localhost"

user = insert(:user)

resource = %{id: user.id}

reassign_env(:skate, :logout_url_fn, fn _, _ ->
{:ok, redirect_url}
end)

conn =
conn
|> init_test_session(%{})
|> Guardian.Plug.sign_in(SkateWeb.AuthManager, resource, %{sign_out_url: redirect_url})

assert Guardian.Plug.authenticated?(conn)

conn = get(conn, ~p"/auth/keycloak/logout")

refute Guardian.Plug.authenticated?(conn)

assert redirected_to(conn) == redirect_url
end

@tag :authenticated
test "clears guardian session", %{conn: conn} do
assert Guardian.Plug.authenticated?(conn)
Expand Down

0 comments on commit 83f104e

Please sign in to comment.