From 45e83c7575318e62f41ff3b3d115a425ec53ffa6 Mon Sep 17 00:00:00 2001 From: Marten Sytema Date: Sun, 24 Oct 2021 10:30:59 +0200 Subject: [PATCH 1/4] Allow authorization URI to be configured as a function --- src/ring/middleware/oauth2.clj | 17 ++++++++++------- test/ring/middleware/oauth2_test.clj | 10 ++++++++++ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/ring/middleware/oauth2.clj b/src/ring/middleware/oauth2.clj index 1cfe870..d3da3f3 100644 --- a/src/ring/middleware/oauth2.clj +++ b/src/ring/middleware/oauth2.clj @@ -17,13 +17,16 @@ (str/join " " (map name (:scopes profile)))) (defn- authorize-uri [profile request state] - (str (:authorize-uri profile) - (if (.contains ^String (:authorize-uri profile) "?") "&" "?") - (codec/form-encode {:response_type "code" - :client_id (:client-id profile) - :redirect_uri (redirect-uri profile request) - :scope (scopes profile) - :state state}))) + (let [auth-uri (if (string? (:authorize-uri profile)) + (:authorize-uri profile) + ((:authorize-uri profile) profile request state))] + (str auth-uri + (if (.contains ^String auth-uri "?") "&" "?") + (codec/form-encode {:response_type "code" + :client_id (:client-id profile) + :redirect_uri (redirect-uri profile request) + :scope (scopes profile) + :state state})))) (defn- random-state [] (-> (random/base64 9) (str/replace "+" "-") (str/replace "/" "_"))) diff --git a/test/ring/middleware/oauth2_test.clj b/test/ring/middleware/oauth2_test.clj index 033cb87..06675f6 100644 --- a/test/ring/middleware/oauth2_test.clj +++ b/test/ring/middleware/oauth2_test.clj @@ -56,6 +56,16 @@ location (get-in response [:headers "Location"])] (is (.startsWith ^String location "https://example.com/oauth2/authorize?business_partner_id=XXXX&")))) +(deftest test-authorize-uri-as-a-function + (let [profile (assoc test-profile + :authorize-uri + (fn [profile request state] + "https://mycustom-url.example.com/oauth2/authorize")) + handler (wrap-oauth2 token-handler {:test profile}) + response (handler (mock/request :get "/oauth2/test")) + location (get-in response [:headers "Location"])] + (is (.startsWith ^String location "https://mycustom-url.example.com/oauth2/authorize")))) + (def token-response {:status 200 :headers {"Content-Type" "application/json"} From 0478b19e3e4c15e7bd5e57f6bda25b29327e0a3c Mon Sep 17 00:00:00 2001 From: Marten Sytema Date: Sun, 24 Oct 2021 10:56:27 +0200 Subject: [PATCH 2/4] Allow access-token-uri to be configured as a function --- src/ring/middleware/oauth2.clj | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/ring/middleware/oauth2.clj b/src/ring/middleware/oauth2.clj index d3da3f3..304d1a6 100644 --- a/src/ring/middleware/oauth2.clj +++ b/src/ring/middleware/oauth2.clj @@ -77,11 +77,14 @@ [{:keys [access-token-uri client-id client-secret basic-auth?] :or {basic-auth? false} :as profile} request] (format-access-token - (http/post access-token-uri - (cond-> {:accept :json, :as :json, - :form-params (request-params profile request)} - basic-auth? (add-header-credentials client-id client-secret) - (not basic-auth?) (add-form-credentials client-id client-secret))))) + (http/post + (if (string? access-token-uri) + access-token-uri + (access-token-uri profile request)) + (cond-> {:accept :json, :as :json, + :form-params (request-params profile request)} + basic-auth? (add-header-credentials client-id client-secret) + (not basic-auth?) (add-form-credentials client-id client-secret))))) (defn state-mismatch-handler [_] {:status 400, :headers {}, :body "State mismatch"}) From dec756eea934df8978623f028dc4bec6efaa53bb Mon Sep 17 00:00:00 2001 From: Marten Sytema Date: Sun, 24 Oct 2021 11:02:56 +0200 Subject: [PATCH 3/4] Update readme to explain :authorize-uri et al. as fn configurations --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 127495a..b83f09a 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,18 @@ These are URLs provided by the third-party website. If you look at the OAuth documentation for the site you're authenticating against, it should tell you which URLs to use. +Note: If you need to construct the URI at runtime, you can also configure a function +instead of a string for these parameters: + +```clojure +{:authorize-uri (fn [profile request] + ;; return a URI + ) + :access-token-uri (fn [profile request] + ;; return a URI + )} +``` + Next is the client ID and secret: * `:client-id` From 1117254965f3aed3ffcda515fc557956a3b42c54 Mon Sep 17 00:00:00 2001 From: Marten Sytema Date: Sun, 24 Oct 2021 11:03:28 +0200 Subject: [PATCH 4/4] Remove state param from authorize-uri callback --- src/ring/middleware/oauth2.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ring/middleware/oauth2.clj b/src/ring/middleware/oauth2.clj index 304d1a6..a5be812 100644 --- a/src/ring/middleware/oauth2.clj +++ b/src/ring/middleware/oauth2.clj @@ -19,7 +19,7 @@ (defn- authorize-uri [profile request state] (let [auth-uri (if (string? (:authorize-uri profile)) (:authorize-uri profile) - ((:authorize-uri profile) profile request state))] + ((:authorize-uri profile) profile request))] (str auth-uri (if (.contains ^String auth-uri "?") "&" "?") (codec/form-encode {:response_type "code"