-
Notifications
You must be signed in to change notification settings - Fork 0
/
oauth2.clj
79 lines (57 loc) · 1.79 KB
/
oauth2.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
(ns ajchemist.imgur.alpha.oauth2
(:require
[clojure.string :as str]
[clj-http.client :as http]
[ring.util.codec :as codec]
[crypto.random :as random]
)
(:import
java.time.Instant
java.util.Date
))
;;
(set! *warn-on-reflection* true)
;;
(defn- coerce-to-int
[n]
(if (int? n)
n
(parse-long n)))
(defn random-state
[]
(-> (random/base64 9) (str/replace "+" "-") (str/replace "/" "_")))
;;
(defn authorize-uri
^String
[form-params profile]
(let [^String uri (:authorize-uri profile)]
(str uri
(if (str/includes? uri "?") "&" "?")
(codec/form-encode
(-> form-params
(update "response_type" #(or % (:authorize/response_type profile "token")))
(update "client_id" #(or % (:client-id profile)))
(update "state" #(or % (random-state))))))))
(defn- format-access-token
[{{:strs [access_token expires_in refresh_token] :as body} :body}]
(cond-> {:token access_token
:extra-data (dissoc body "access_token" "expires_in" "refresh_token")}
expires_in (assoc :expires (Date/from (.plusSeconds (Instant/now) (-> expires_in coerce-to-int))))
refresh_token (assoc :refresh-token refresh_token)))
(defn refresh-access-token
"use with try-catch block"
[form-params profile]
{:pre [(find form-params "refresh_token")]}
(format-access-token
(http/post
(:token-uri profile)
{:save-request? true
:accept :json
:as :json-string-keys
:form-params
(-> form-params
(update "client_id" #(or % (:client-id profile)))
(update "client_secret" #(or % (:client-secret profile)))
(update "grant_type" #(or % (:token/grant_type profile "refresh_token"))))})))
;;
(set! *warn-on-reflection* false)