0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-09 16:30:37 -05:00

Port fixes from google oauth handlers to github and gitlab.

This commit is contained in:
Andrey Antukh 2021-02-17 16:52:04 +01:00 committed by Andrés Moya
parent 800f97c5a1
commit e3bad997fd
3 changed files with 100 additions and 99 deletions

View file

@ -12,6 +12,7 @@
[app.common.exceptions :as ex] [app.common.exceptions :as ex]
[app.common.spec :as us] [app.common.spec :as us]
[app.config :as cfg] [app.config :as cfg]
[app.http.auth.google :as gg]
[app.util.http :as http] [app.util.http :as http]
[app.util.time :as dt] [app.util.time :as dt]
[clojure.data.json :as json] [clojure.data.json :as json]
@ -67,7 +68,7 @@
nil))) nil)))
(defn- get-user-info (defn- get-user-info
[token] [_ token]
(try (try
(let [req {:uri (str user-info-url) (let [req {:uri (str user-info-url)
:headers {"authorization" (str "token " token)} :headers {"authorization" (str "token " token)}
@ -77,58 +78,56 @@
(when (= 200 (:status res)) (when (= 200 (:status res))
(let [data (json/read-str (:body res))] (let [data (json/read-str (:body res))]
{:email (get data "email") {:email (get data "email")
:backend "github"
:fullname (get data "name")}))) :fullname (get data "name")})))
(catch Exception e (catch Exception e
(log/error e "unexpected exception on get-user-info") (log/error e "unexpected exception on get-user-info")
nil))) nil)))
(defn auth (defn- retrieve-info
[{:keys [tokens] :as cfg} _request] [{:keys [tokens] :as cfg} request]
(let [state (tokens :generate {:iss :github-oauth :exp (dt/in-future "15m")}) (let [token (get-in request [:params :state])
params {:client_id (:client-id cfg/config) state (tokens :verify {:token token :iss :github-oauth})
:redirect_uri (build-redirect-url cfg) info (some->> (get-in request [:params :code])
:state state (get-access-token cfg state)
:scope scope} (get-user-info cfg))]
query (u/map->query-string params) (when-not info
uri (-> authorize-uri (ex/raise :type :internal
(assoc :query query))] :code :unable-to-auth))
(cond-> info
(some? (:invitation-token state))
(assoc :invitation-token (:invitation-token state)))))
(defn auth-handler
[{:keys [tokens] :as cfg} request]
(let [invitation (get-in request [:params :invitation-token])
state (tokens :generate {:iss :github-oauth
:invitation-token invitation
:exp (dt/in-future "15m")})
params {:client_id (:client-id cfg/config)
:redirect_uri (build-redirect-url cfg)
:state state
:scope scope}
query (u/map->query-string params)
uri (-> authorize-uri
(assoc :query query))]
{:status 200 {:status 200
:body {:redirect-uri (str uri)}})) :body {:redirect-uri (str uri)}}))
(defn callback (defn- callback-handler
[{:keys [tokens rpc session] :as cfg} request] [{:keys [session] :as cfg} request]
(try (try
(let [state (get-in request [:params :state]) (let [info (retrieve-info cfg request)
_ (tokens :verify {:token state :iss :github-oauth}) profile (gg/register-profile cfg info)
info (some->> (get-in request [:params :code]) uri (gg/generate-redirect-uri cfg profile)
(get-access-token cfg state) sxf ((:create session) (:id profile))]
(get-user-info)) (->> (gg/redirect-response uri)
(sxf request)))
_ (when-not info
(ex/raise :type :internal
:code :unable-to-auth))
method-fn (get-in rpc [:methods :mutation :login-or-register])
profile (method-fn {:email (:email info)
:backend "github"
:fullname (:fullname info)})
token (tokens :generate
{:iss :auth
:exp (dt/in-future "15m")
:profile-id (:id profile)})
uri (-> (u/uri (:public-uri cfg/config))
(assoc :path "/#/auth/verify-token")
(assoc :query (u/map->query-string {:token token})))
sxf ((:create session) (:id profile))
rsp {:status 302 :headers {"location" (str uri)} :body ""}]
(sxf request rsp))
(catch Exception _e (catch Exception _e
(let [uri (-> (u/uri (:public-uri cfg)) (-> (gg/generate-error-redirect-uri cfg)
(assoc :path "/#/auth/login") (gg/redirect-response)))))
(assoc :query (u/map->query-string {:error "unable-to-auth"})))]
{:status 302
:headers {"location" (str uri)}
:body ""}))))
;; --- ENTRY POINT ;; --- ENTRY POINT
@ -153,8 +152,8 @@
[_ cfg] [_ cfg]
(if (and (:client-id cfg) (if (and (:client-id cfg)
(:client-secret cfg)) (:client-secret cfg))
{:auth-handler #(auth cfg %) {:auth-handler #(auth-handler cfg %)
:callback-handler #(callback cfg %)} :callback-handler #(callback-handler cfg %)}
{:auth-handler default-handler {:auth-handler default-handler
:callback-handler default-handler})) :callback-handler default-handler}))

View file

@ -12,6 +12,7 @@
[app.common.data :as d] [app.common.data :as d]
[app.common.exceptions :as ex] [app.common.exceptions :as ex]
[app.common.spec :as us] [app.common.spec :as us]
[app.http.auth.google :as gg]
[app.util.http :as http] [app.util.http :as http]
[app.util.time :as dt] [app.util.time :as dt]
[clojure.data.json :as json] [clojure.data.json :as json]
@ -76,62 +77,61 @@
(when (= 200 (:status res)) (when (= 200 (:status res))
(let [data (json/read-str (:body res))] (let [data (json/read-str (:body res))]
{:email (get data "email") {:email (get data "email")
:backend "gitlab"
:fullname (get data "name")}))) :fullname (get data "name")})))
(catch Exception e (catch Exception e
(log/error e "unexpected exception on get-user-info") (log/error e "unexpected exception on get-user-info")
nil))) nil)))
(defn auth
[{:keys [tokens] :as cfg} _request]
(let [token (tokens :generate {:iss :gitlab-oauth
:exp (dt/in-future "15m")})
params {:client_id (:client-id cfg) (defn- retrieve-info
:redirect_uri (build-redirect-url cfg) [{:keys [tokens] :as cfg} request]
:response_type "code" (let [token (get-in request [:params :state])
:state token state (tokens :verify {:token token :iss :gitlab-oauth})
:scope scope} info (some->> (get-in request [:params :code])
query (u/map->query-string params) (get-access-token cfg)
uri (-> (build-oauth-uri cfg) (get-user-info cfg))]
(assoc :query query))] (when-not info
(ex/raise :type :internal
:code :unable-to-auth))
(cond-> info
(some? (:invitation-token state))
(assoc :invitation-token (:invitation-token state)))))
(defn- auth-handler
[{:keys [tokens] :as cfg} request]
(let [invitation (get-in request [:params :invitation-token])
state (tokens :generate
{:iss :gitlab-oauth
:invitation-token invitation
:exp (dt/in-future "15m")})
params {:client_id (:client-id cfg)
:redirect_uri (build-redirect-url cfg)
:response_type "code"
:state state
:scope scope}
query (u/map->query-string params)
uri (-> (build-oauth-uri cfg)
(assoc :query query))]
{:status 200 {:status 200
:body {:redirect-uri (str uri)}})) :body {:redirect-uri (str uri)}}))
(defn callback (defn- callback-handler
[{:keys [tokens rpc session] :as cfg} request] [{:keys [session] :as cfg} request]
(try (try
(let [token (get-in request [:params :state]) (let [info (retrieve-info cfg request)
_ (tokens :verify {:token token :iss :gitlab-oauth}) profile (gg/register-profile cfg info)
info (some->> (get-in request [:params :code]) uri (gg/generate-redirect-uri cfg profile)
(get-access-token cfg) sxf ((:create session) (:id profile))]
(get-user-info cfg)) (->> (gg/redirect-response uri)
_ (when-not info (sxf request)))
(ex/raise :type :internal
:code :unable-to-auth))
method-fn (get-in rpc [:methods :mutation :login-or-register])
profile (method-fn {:email (:email info)
:backend "gitlab"
:fullname (:fullname info)})
token (tokens :generate {:iss :auth
:exp (dt/in-future "15m")
:profile-id (:id profile)})
uri (-> (u/uri (:public-uri cfg))
(assoc :path "/#/auth/verify-token")
(assoc :query (u/map->query-string {:token token})))
sxf ((:create session) (:id profile))
rsp {:status 302 :headers {"location" (str uri)} :body ""}]
(sxf request rsp))
(catch Exception _e (catch Exception _e
(let [uri (-> (u/uri (:public-uri cfg)) (-> (gg/generate-error-redirect-uri cfg)
(assoc :path "/#/auth/login") (gg/redirect-response)))))
(assoc :query (u/map->query-string {:error "unable-to-auth"})))]
{:status 302
:headers {"location" (str uri)}
:body ""}))))
(s/def ::client-id ::us/not-empty-string) (s/def ::client-id ::us/not-empty-string)
(s/def ::client-secret ::us/not-empty-string) (s/def ::client-secret ::us/not-empty-string)
@ -162,7 +162,7 @@
[_ cfg] [_ cfg]
(if (and (:client-id cfg) (if (and (:client-id cfg)
(:client-secret cfg)) (:client-secret cfg))
{:auth-handler #(auth cfg %) {:auth-handler #(auth-handler cfg %)
:callback-handler #(callback cfg %)} :callback-handler #(callback-handler cfg %)}
{:auth-handler default-handler {:auth-handler default-handler
:callback-handler default-handler})) :callback-handler default-handler}))

View file

@ -56,7 +56,7 @@
nil))) nil)))
(defn- get-user-info (defn- get-user-info
[token] [_ token]
(try (try
(let [req {:uri "https://openidconnect.googleapis.com/v1/userinfo" (let [req {:uri "https://openidconnect.googleapis.com/v1/userinfo"
:headers {"Authorization" (str "Bearer " token)} :headers {"Authorization" (str "Bearer " token)}
@ -65,6 +65,7 @@
(when (= 200 (:status res)) (when (= 200 (:status res))
(let [data (json/read-str (:body res))] (let [data (json/read-str (:body res))]
{:email (get data "email") {:email (get data "email")
:backend "google"
:fullname (get data "name")}))) :fullname (get data "name")})))
(catch Exception e (catch Exception e
(log/error e "unexpected exception on get-user-info") (log/error e "unexpected exception on get-user-info")
@ -76,7 +77,7 @@
state (tokens :verify {:token token :iss :google-oauth}) state (tokens :verify {:token token :iss :google-oauth})
info (some->> (get-in request [:params :code]) info (some->> (get-in request [:params :code])
(get-access-token cfg) (get-access-token cfg)
(get-user-info))] (get-user-info cfg))]
(when-not info (when-not info
(ex/raise :type :internal (ex/raise :type :internal
:code :unable-to-auth)) :code :unable-to-auth))
@ -85,17 +86,17 @@
(some? (:invitation-token state)) (some? (:invitation-token state))
(assoc :invitation-token (:invitation-token state))))) (assoc :invitation-token (:invitation-token state)))))
(defn- register-profile (defn register-profile
[{:keys [rpc] :as cfg} info] [{:keys [rpc] :as cfg} info]
(let [method-fn (get-in rpc [:methods :mutation :login-or-register]) (let [method-fn (get-in rpc [:methods :mutation :login-or-register])
profile (method-fn {:email (:email info) profile (method-fn {:email (:email info)
:backend "google" :backend (:backend info)
:fullname (:fullname info)})] :fullname (:fullname info)})]
(cond-> profile (cond-> profile
(some? (:invitation-token info)) (some? (:invitation-token info))
(assoc :invitation-token (:invitation-token info))))) (assoc :invitation-token (:invitation-token info)))))
(defn- generate-redirect-uri (defn generate-redirect-uri
[{:keys [tokens] :as cfg} profile] [{:keys [tokens] :as cfg} profile]
(let [token (or (:invitation-token profile) (let [token (or (:invitation-token profile)
(tokens :generate {:iss :auth (tokens :generate {:iss :auth
@ -105,13 +106,13 @@
(assoc :path "/#/auth/verify-token") (assoc :path "/#/auth/verify-token")
(assoc :query (u/map->query-string {:token token}))))) (assoc :query (u/map->query-string {:token token})))))
(defn- generate-error-redirect-uri (defn generate-error-redirect-uri
[cfg] [cfg]
(-> (u/uri (:public-uri cfg)) (-> (u/uri (:public-uri cfg))
(assoc :path "/#/auth/login") (assoc :path "/#/auth/login")
(assoc :query (u/map->query-string {:error "unable-to-auth"})))) (assoc :query (u/map->query-string {:error "unable-to-auth"}))))
(defn- redirect-response (defn redirect-response
[uri] [uri]
{:status 302 {:status 302
:headers {"location" (str uri)} :headers {"location" (str uri)}
@ -145,7 +146,8 @@
profile (register-profile cfg info) profile (register-profile cfg info)
uri (generate-redirect-uri cfg profile) uri (generate-redirect-uri cfg profile)
sxf ((:create session) (:id profile))] sxf ((:create session) (:id profile))]
(sxf request (redirect-response uri))) (->> (redirect-response uri)
(sxf request)))
(catch Exception _e (catch Exception _e
(-> (generate-error-redirect-uri cfg) (-> (generate-error-redirect-uri cfg)
(redirect-response))))) (redirect-response)))))