/
authcode.clj
81 lines (64 loc) · 2.39 KB
/
authcode.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
80
81
(ns cerber.stores.authcode
"Functions handling OAuth2 authcode storage."
(:require [cerber.oauth2.settings :as settings]
[cerber
[db :as db]
[error :as error]
[helpers :as helpers]
[mappers :as mappers]
[store :refer :all]]))
(def authcode-store (atom :not-initialized))
(defrecord AuthCode [client-id login code scope redirect-uri expires-at created-at])
(defrecord SqlAuthCodeStore [expired-authcodes-cleaner]
Store
(fetch-one [this [code]]
(some-> (db/find-authcode {:code code})
mappers/row->authcode))
(revoke-one! [this [code]]
(db/delete-authcode {:code code}))
(store! [this k authcode]
(= 1 (db/insert-authcode authcode)))
(purge! [this]
(db/clear-authcodes))
(close! [this]
(db/stop-periodic expired-authcodes-cleaner)))
(defmulti create-authcode-store (fn [type config] type))
(defmethod create-authcode-store :in-memory [_ _]
(->MemoryStore "authcodes" (atom {})))
(defmethod create-authcode-store :redis [_ redis-spec]
(->RedisStore "authcodes" redis-spec))
(defmethod create-authcode-store :sql [_ db-conn]
(when db-conn
(db/bind-queries db-conn)
(->SqlAuthCodeStore (db/make-periodic 'cerber.db/clear-expired-authcodes 8000))))
(defn init-store
"Initializes authcode store according to given type and configuration."
[type config]
(reset! authcode-store (create-authcode-store type config)))
(defn find-authcode
[code]
(when-let [authcode (fetch-one @authcode-store [code])]
(when-not (helpers/expired? authcode)
(map->AuthCode authcode))))
(defn revoke-authcode
"Revokes previously generated authcode."
[authcode]
(revoke-one! @authcode-store [(:code authcode)]) nil)
(defn purge-authcodes
"Removes auth code from store."
[]
(purge! @authcode-store))
(defn create-authcode
"Creates and returns a new auth-code."
[client user scope redirect-uri & [ttl]]
(let [authcode (helpers/reset-ttl
{:client-id (:id client)
:login (:login user)
:scope scope
:code (helpers/generate-secret)
:redirect-uri redirect-uri
:created-at (helpers/now)}
(or ttl (settings/authcode-valid-for)))]
(if (store! @authcode-store [:code] authcode)
(map->AuthCode authcode)
(error/internal-error "Cannot store authcode"))))