From a65059990120dcdc67866a9ec184c3f6e97db23f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Prudent?= Date: Sat, 17 Oct 2015 18:04:16 +0200 Subject: [PATCH] redirect-on-auth? can be overloaded in ::friend/auth-config --- src/cemerick/friend/util.clj | 3 +++ src/cemerick/friend/workflows.clj | 32 +++++++++++++-------------- test/test_friend/interactive_form.clj | 28 ++++++++++++++++++++++- 3 files changed, 46 insertions(+), 17 deletions(-) diff --git a/src/cemerick/friend/util.clj b/src/cemerick/friend/util.clj index c8cd559..33403ac 100644 --- a/src/cemerick/friend/util.clj +++ b/src/cemerick/friend/util.clj @@ -8,6 +8,9 @@ first val)) +(defn first-non-nil [xs] + (first (drop-while nil? xs))) + (defn original-url [{:keys [scheme server-name server-port uri query-string headers]}] ;; If your proxy doesn't send x-forwarded-proto headers, then you'll need to diff --git a/src/cemerick/friend/workflows.clj b/src/cemerick/friend/workflows.clj index 9e324ae..e571533 100644 --- a/src/cemerick/friend/workflows.clj +++ b/src/cemerick/friend/workflows.clj @@ -3,7 +3,7 @@ [cemerick.friend.util :as util] [ring.util.request :as req]) (:use [clojure.string :only (trim)] - [cemerick.friend.util :only (gets)]) + [cemerick.friend.util :refer [gets first-non-nil]]) (:import org.apache.commons.codec.binary.Base64)) (defn http-basic-deny @@ -78,19 +78,19 @@ request)))) (defn interactive-form - [& {:keys [login-uri credential-fn login-failure-handler redirect-on-auth?] :as form-config - :or {redirect-on-auth? true}}] + [& {:as form-config}] (fn [{:keys [request-method params form-params] :as request}] - (when (and (= (gets :login-uri form-config (::friend/auth-config request)) (req/path-info request)) - (= :post request-method)) - (let [creds {:username (username form-params params) - :password (password form-params params)} - {:keys [username password]} creds] - (if-let [user-record (and username password - ((gets :credential-fn form-config (::friend/auth-config request)) - (with-meta creds {::friend/workflow :interactive-form})))] - (make-auth user-record - {::friend/workflow :interactive-form - ::friend/redirect-on-auth? redirect-on-auth?}) - ((or (gets :login-failure-handler form-config (::friend/auth-config request)) #'interactive-login-redirect) - (update-in request [::friend/auth-config] merge form-config))))))) + (let [auth-config (request ::friend/auth-config)] + (when (and (= (gets :login-uri form-config auth-config) (req/path-info request)) + (= :post request-method)) + (let [creds {:username (username form-params params) + :password (password form-params params)} + {:keys [username password]} creds] + (if-let [user-record (and username password + ((gets :credential-fn form-config auth-config) + (with-meta creds {::friend/workflow :interactive-form})))] + (make-auth user-record + {::friend/workflow :interactive-form + ::friend/redirect-on-auth? (first-non-nil [(gets :redirect-on-auth? form-config auth-config) true])}) + ((or (gets :login-failure-handler form-config auth-config) #'interactive-login-redirect) + (update-in request [::friend/auth-config] merge form-config)))))))) diff --git a/test/test_friend/interactive_form.clj b/test/test_friend/interactive_form.clj index 5541354..5202b5d 100644 --- a/test/test_friend/interactive_form.clj +++ b/test/test_friend/interactive_form.clj @@ -43,4 +43,30 @@ (is (= auth {:identity "Aladdin"})) (is (= (meta auth) {::friend/workflow :interactive-form :type ::friend/auth - ::friend/redirect-on-auth? true}))))) + ::friend/redirect-on-auth? true}))) + + (testing "redirect-on-auth? can be specified when creating the workflow" + (let [form-handler (interactive-form :login-uri login-uri + :credential-fn (constantly {:identity "Aladdin"}) + :redirect-on-auth? false) + auth (form-handler (assoc (request :post login-uri) + :params {:username "irrelevant but necessary" + :password "irrelevant but necessary"}))] + (is (= false (::friend/redirect-on-auth? (meta auth)))))) + + (testing "redirect-on-auth? is overloaded with global configuration when not specified when creating the workflow" + (let [form-handler (interactive-form :login-uri login-uri + :credential-fn (constantly {:identity "Aladdin"})) + auth (form-handler (assoc (request :post login-uri) + :params {:username "irrelevant but necessary" + :password "irrelevant but necessary"} + ::friend/auth-config {:redirect-on-auth? false}))] + (is (= false (::friend/redirect-on-auth? (meta auth)))))) + + (testing "redirect-on-auth? defaults to true when it's never specified" + (let [form-handler (interactive-form :login-uri login-uri + :credential-fn (constantly {:identity "Aladdin"})) + auth (form-handler (assoc (request :post login-uri) + :params {:username "irrelevant but necessary" + :password "irrelevant but necessary"}))] + (is (= true (::friend/redirect-on-auth? (meta auth)))))))) \ No newline at end of file