diff --git a/src/territory_bro/infra/auth0.clj b/src/territory_bro/infra/auth0.clj index c0c87ccf..39da9577 100644 --- a/src/territory_bro/infra/auth0.clj +++ b/src/territory_bro/infra/auth0.clj @@ -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) @@ -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") @@ -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)))) diff --git a/test/territory_bro/infra/auth0_test.clj b/test/territory_bro/infra/auth0_test.clj index fa64db48..8db200ff 100644 --- a/test/territory_bro/infra/auth0_test.clj +++ b/test/territory_bro/infra/auth0_test.clj @@ -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,