Skip to content

Commit

Permalink
fix: duplicate oauth namespaces, join server response check
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnnyJayJay committed Aug 15, 2024
1 parent 95b05ae commit fa625dd
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 97 deletions.
73 changes: 11 additions & 62 deletions src/co/gaiwan/compass/http/oauth.clj
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,9 @@
[co.gaiwan.compass.config :as config]
[co.gaiwan.compass.db :as db]
[co.gaiwan.compass.util :as util]
[datomic.api :as d]
[hato.client :as hato]
[lambdaisland.uri :as uri]
[ring.util.response :as response]
[io.pedestal.log :as log])
(:import (java.time Instant)))
[io.pedestal.log :as log]))

(def discord-oauth-endpoint "https://discord.com/oauth2/authorize")
(def discord-api-endpoint "https://discord.com/api/v10")
Expand All @@ -20,7 +17,6 @@
(defn bot-auth-headers []
{"Authorization" (str "Bot " (config/value :discord/bot-token))})


(defn flow-init-url
([]
(flow-init-url nil))
Expand Down Expand Up @@ -62,10 +58,6 @@
{:grant_type "refresh_token"
:refresh_token refresh-token}))

(defn- expires-in->instant
[expires-in]
(.plusSeconds (Instant/now) (- expires-in 60)))

(defn current-access-token
"Get a valid Discord bearer access token for a user.
Expand All @@ -90,7 +82,7 @@
(db/transact [{:user/uuid user-id
:discord/access-token (:access_token body)
:discord/refresh-token (:refresh_token body)
:discord/expires-at (expires-in->instant (:discord/expires_in body))}])
:discord/expires-at (util/expires-in->instant (:discord/expires_in body))}])
(:access_token body)))
(:discord/access-token oauth-data))))

Expand All @@ -102,55 +94,12 @@
:oauth-token token})))

(defn join-server [token]
(let [{:keys [id username]} (fetch-user-info token)]
(log/trace :discord/adding-user username)
(hato/put
(str discord-api-endpoint "/guilds/" (config/value :discord/server-id) "/members/" id)
{:as :auto
:content-type :json
:form-params {:access_token token}
:headers (bot-auth-headers)})))

(defn GET-callback [{:keys [query-params]}]
(let [code (get query-params "code")
{:keys [status body]} (exchange-code code)]
(if (not= 200 status)
{:status 302
:headers {"Location" "/"}
:flash [:p
"Discord OAuth2 exchange failed."
[:pre (util/pprint-str body)]]
:session {:identity nil}}
(let [{:keys [access_token refresh_token expires_in]} body
{:keys [id global_name email username]} (fetch-user-info access_token)
user-uuid (:user/uuid (d/entity (db/db) [:user/email email]) (random-uuid))
tx-data
[{:user/uuid user-uuid
:user/email email
:user/name global_name
:user/handle username
:discord/id id
:discord/access-token access_token
:discord/refresh-token refresh_token
:discord/expires-at (expires-in->instant expires_in)}]
{:keys [status]} (join-server access_token)]
@(db/transact tx-data)
{:status 302
:headers {"Location" "/"}
:flash [:p "You are signed in!"
(when-not (= status 200)
[:br "Unfortunately, adding you to our Discord server didn't work."])]
:session {:identity user-uuid}}))))

(defn routes []
[""
["/oauth2"
["/discord"
["/callback"
{:get {:handler #'GET-callback}}]]]
["/logout"
{:get {:handler (fn [req]
(assoc
(response/redirect "/")
:flash "You were signed out"
:session {}))}}]])
(let [{:keys [id username]} (fetch-user-info token)
response
(hato/put
(str discord-api-endpoint "/guilds/" (config/value :discord/server-id) "/members/" id)
{:as :auto
:content-type :json
:form-params {:access_token token}
:headers (bot-auth-headers)})]
(log/trace :discord/user-add username :discord/add-guild-member-response response)))
44 changes: 9 additions & 35 deletions src/co/gaiwan/compass/routes/oauth.clj
Original file line number Diff line number Diff line change
@@ -1,39 +1,15 @@
(ns co.gaiwan.compass.routes.oauth
(:require
[clojure.string :as str]
[co.gaiwan.compass.config :as config]
[co.gaiwan.compass.db :as db]
[co.gaiwan.compass.html.auth :as auth-html]
[co.gaiwan.compass.http.oauth :as oauth]
[co.gaiwan.compass.util :as util]
[datomic.api :as d]
[hato.client :as hato]
[lambdaisland.uri :as uri]
[ring.util.response :as response]))

(defn exchange-code [code]
(hato/post
(str oauth/discord-api-endpoint "/oauth2/token")
{:as :auto
:form-params
{:grant_type "authorization_code"
:code code
:redirect_uri (str (config/value :compass/origin) "/oauth2/discord/callback")}
:basic-auth
{:user (config/value :discord/client-id)
:pass (config/value :discord/client-secret)}}))

(defn fetch-user-info [token]
(:body
(hato/get (str oauth/discord-api-endpoint "/users/@me")
{:as :auto
:headers {"Authorization" (str "Bearer " token)}})))

(defn GET-callback [{:keys [query-params]}]
(let [code (get query-params "code")
state (get query-params "state")
{:keys [status body]} (exchange-code code)
redirect-url (:oauth/redirect-url (db/entity [:oauth/state-id (parse-uuid state)]))]
{:keys [status body]} (oauth/exchange-code code)]
(if (not= 200 status)
{:status 302
:headers {"Location" "/"}
Expand All @@ -42,25 +18,24 @@
[:pre (util/pprint-str body)]]
:session {:identity nil}}
(let [{:keys [access_token refresh_token expires_in]} body
{:keys [id global_name email username] :as user-info} (fetch-user-info access_token)
avatar-url (str "https://cdn.discordapp.com/avatars/" id "/" (:avatar user-info) ".png")
;;_ (prn :avatar-url avatar-url)
{:keys [id global_name email username]} (oauth/fetch-user-info access_token)
user-uuid (:user/uuid (d/entity (db/db) [:user/email email]) (random-uuid))
tx-data
[{:user/uuid user-uuid
:user/email email
:user/name global_name
:user/handle username
:discord/avatar-url avatar-url
:discord/id id
:discord/access-token access_token
:discord/refresh-token refresh_token
:discord/expires-at (.plusSeconds (java.time.Instant/now) (- expires_in 60))}]]
(def tx-data tx-data)
:discord/expires-at (util/expires-in->instant expires_in)}]
{:keys [status]} (oauth/join-server access_token)]
@(db/transact tx-data)
{:status 302
:headers {"Location" (or redirect-url "/")}
#_#_:flash [:p "You are signed in!"]
:headers {"Location" "/"}
:flash [:p "You are signed in!"
(when-not (= 2 (quot status 100))
[:br "Unfortunately, adding you to our Discord server didn't work."])]
:session {:identity user-uuid}}))))

(defn GET-login [req]
Expand All @@ -72,8 +47,7 @@
["/oauth2"
["/discord"
["/callback"
{:get {:handler GET-callback}}]]]
["/login" {:get {:handler GET-login}}]
{:get {:handler #'GET-callback}}]]]
["/logout"
{:get {:handler (fn [req]
(assoc
Expand Down
4 changes: 4 additions & 0 deletions src/co/gaiwan/compass/util.clj
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,7 @@
(vector? res) (mapv deep-underscorize-keys res)
(map? res) (update-vals (underscorize-keys res) deep-underscorize-keys)
:else res))

(defn expires-in->instant
[expires-in]
(.plusSeconds (Instant/now) (- expires-in 60)))

0 comments on commit fa625dd

Please sign in to comment.