Skip to content

Commit

Permalink
✨ Logout handler
Browse files Browse the repository at this point in the history
Why:
- We want to migrate from SPA to SSR. The authentication is currently
  done using Auth0's JavaScript libraries, but in the future it'll need
  to be done server-side.
- With the SPA UI, we only cleared the application session but forgot to
  clear the Auth0 session. This time that is done properly, so that on
  relogin the user has an option of logging with a different account,
  instead of automatically reusing the Auth0 session.
  • Loading branch information
luontola committed Feb 24, 2024
1 parent 349fb9a commit a5325a6
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 6 deletions.
22 changes: 16 additions & 6 deletions src/territory_bro/infra/auth0.clj
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
[territory-bro.infra.util :as util]
[territory-bro.infra.util :refer [getx]])
(:import (com.auth0 AuthenticationController IdentityVerificationException)
(com.auth0.client.auth AuthAPI)
(com.auth0.jwk JwkProviderBuilder)
(com.auth0.jwt JWT)
(java.net URL)
Expand Down Expand Up @@ -89,10 +90,12 @@
(swap! *response response/update-header name concat (list value))))]
[servlet-request servlet-response *response]))

(defn public-url []
(-> (getx config/env :public-url)
(str/replace "8080" "8081"))) ; TODO: remove me

(defn login-handler [ring-request]
(let [public-url (-> (getx config/env :public-url)
(str/replace "8080" "8081")) ; TODO: remove me
callback-url (str public-url "/login-callback")
(let [callback-url (str (public-url) "/login-callback")
[servlet-request servlet-response *ring-response] (ring->servlet ring-request)
authorize-url (-> (.buildAuthorizeUrl auth-controller servlet-request servlet-response callback-url)
(.withScope "openid email profile")
Expand Down Expand Up @@ -122,6 +125,13 @@
;; TODO: html error page
(http-response/forbidden "Login failed"))))

(defn logout-handler [ring-request]
;; TODO
(response/response "TODO"))
(defn logout-handler [_ring-request]
(let [domain (getx config/env :auth0-domain)
client-id (getx config/env :auth0-client-id)
client-secret (getx config/env :auth0-client-secret)
api (AuthAPI. domain client-id client-secret)
return-to-url (str (public-url) "/")
logout-url (-> (.logoutUrl api return-to-url true)
(.build))]
(-> (response/redirect logout-url :see-other)
(assoc :session nil))))
21 changes: 21 additions & 0 deletions test/territory_bro/infra/auth0_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,27 @@
:body "Login failed"}
response)))))))


(deftest logout-handler-test
(let [request {:request-method :get
:uri "/logout"
:headers {}
:session {::auth/user {:user/id (UUID. 0 1)}}}
response (auth0/logout-handler request)]

(testing "clears the application session"
(is (= {:session nil}
(select-keys response [:session]))))

(testing "redirects to the OIDC logout endpoint, to log out of Auth0, and then return to application home page"
;; See https://auth0.com/docs/authenticate/login/logout
;; https://auth0.com/docs/authenticate/login/logout/log-users-out-of-auth0
;; https://auth0.com/docs/api/authentication#oidc-logout
(is (= {:status 303
:headers {"Location" "https://luontola.eu.auth0.com/v2/logout?returnTo=http://localhost:8081/&client_id=8tVkdfnw8ynZ6rXNndD6eZ6ErsHdIgPi"}}
(select-keys response [:status :headers]))))))


(deftest ring->servlet-test
(testing "request URL"
;; Servlet spec: The returned URL contains a protocol, server name, port number,
Expand Down

0 comments on commit a5325a6

Please sign in to comment.