Skip to content

Commit

Permalink
Localized State, better refresh
Browse files Browse the repository at this point in the history
State is now localized just call(wake-token-retreiver)
Added a new config param for refresh percentage
  • Loading branch information
shvetsm committed Nov 1, 2018
1 parent b354f12 commit 9e3d1c6
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 32 deletions.
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,30 @@ A Clojure library designed to grab tokens from OAuth 2.0
## Usage


```clojure
(:require [funcade/core :as f])

...
(def token-store (f/wake-wake-token-retreiver "my-token-key" config))

This comment has been minimized.

Copy link
@tolitius

tolitius Nov 1, 2018

Contributor

wake wake

This comment has been minimized.

Copy link
@tolitius

tolitius Nov 1, 2018

Contributor

would wake-token-reader or wake-token-master (i.e. like a key master in matrix) be better?

This comment has been minimized.

Copy link
@shvetsm

shvetsm Nov 1, 2018

Author Owner

nooooo!!!!


...
(def token ((:next-token token-store)))

...
((:stop token-store))

```

where config is:
```clojure
{:token-url OAuth 2.0 server url
:grant-type OAuth 2.0 grant type (client_crdentials, implicit, etc)
:client-id OAuth 2.0 client id
:client-secret OAuth 2.0 secret (a hex string)
:scope OAuth 2.0 Scope
:token-headers a map of headers {"Cookie" "foo=bar"}
:refresh-percent (when less than x% of time between expires-at and issued-at remains, refresh the token)}
```
## License

Copyright © 2018 shvetsm
Expand Down
3 changes: 2 additions & 1 deletion project.clj
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
(defproject funcade "0.1.0-SNAPSHOT"
(defproject funcade "0.1.0"
:description "Gives you OAuth 2.0 tokens so you can play"
:url "https://github.com/shvetsm/funcade"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.9.0"]
[org.clojure/core.async "0.4.474"]
[http-kit "2.3.0"]
[org.clojure/tools.logging "0.4.1"]
[funcool/cuerdas "2.0.5"]
[metosin/jsonista "0.1.1"]
[com.rpl/specter "1.1.1"]
Expand Down
41 changes: 25 additions & 16 deletions src/funcade/core.clj
Original file line number Diff line number Diff line change
@@ -1,33 +1,42 @@
(ns funcade.core
(:require [clojure.core.async :as a]
[clojure.tools.logging :as log]
[funcade.state :refer [state]]
[funcade.tokens :as t]))

(defn init-token-channel!
"funcade-params are
{:token-url OAuth 2.0 server url
:grant-type OAuth 2.0 grant type (client_crdentials, implicit, etc)
:client-id OAuth 2.0 client id
:client-secret OAuth 2.0 secret (a hex string)
:scope OAuth 2.0 Scope
:token-headers a map of headers {\"Cookie\" \"foo=bar\"}"
[token-key funcade-params]
(defn- init-token-channel!
[token-key funcade-params token-store]
(let [stop-chan (a/chan 10)
[token err] (a/<!! (t/new-token! funcade-params))]
(if err
(do
(log/error "can't acquire token!" err)
(throw err))
(do
(swap! state (fn [s] (assoc s token-key token)))
(swap! token-store (fn [s] (assoc s token-key token)))
(t/schedule-token-renewal
(name token-key)
token-key
(partial t/renew-token? 1/24)
(partial t/renew-token? (/ (or (:refresh-percent funcade-params) 10) 100))
(fn [] (t/new-token! funcade-params))
stop-chan)
{:token-details (:body token) :stop-chan stop-chan}))))
stop-chan
token-store)
stop-chan))))

(defn- stop-token-channel! [stop-chan]
(a/put! stop-chan ::stop))

(defn wake-token-retreiver [token-name config]
"config is
{:token-url OAuth 2.0 server url
:grant-type OAuth 2.0 grant type (client_crdentials, implicit, etc)
:client-id OAuth 2.0 client id
:client-secret OAuth 2.0 secret (a hex string)
:scope OAuth 2.0 Scope
:token-headers a map of headers {\"Cookie\" \"foo=bar\"}
:refresh-percent (when less than x% of time between expires-at and issued-at remains, refresh the token)}"

(let [token-store (atom {})
stop-channel (init-token-channel! token-name config token-store)]
{:next-token #(:access-token (get @token-store token-name) )
:stop (partial stop-token-channel! stop-channel)}))

(defn stop-token-channel! [{:keys [stop-chan]}]
(a/put! stop-chan ::stop))
2 changes: 0 additions & 2 deletions src/funcade/state.clj

This file was deleted.

26 changes: 13 additions & 13 deletions src/funcade/tokens.clj
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
[org.httpkit.client :as http]
[jsonista.core :as json]
[cuerdas.core :as s]
[clojure.tools.logging :as log]
[funcade.codec :as codec]
[com.rpl.specter :as sp]
[funcade.state :refer [state]])
[com.rpl.specter :as sp])
(:import [java.time Instant]))

(defn in-open-interval? [begin end value] (< begin value end))

(defn token-in-interval? [{:keys [issued expires]} time-in-seconds]
(defn token-in-interval? [{:keys [expires]} time-in-seconds]
(when expires
(< time-in-seconds expires)))

Expand All @@ -21,7 +21,7 @@
p (/ delta (Math/abs (- expires issued)))]
(or (< delta 60)
(neg? diff)
(> p percentage))))
(< p percentage))))

(defn token-valid? [m]
(token-in-interval? m (.getEpochSecond (Instant/now))))
Expand All @@ -40,7 +40,7 @@
(if err
r
(let [data token
t (merge data {:issued (.toEpochMilli (Instant/now))} (parse-token-data data))]
t (merge data {:issued (.getEpochSecond (Instant/now))} (parse-token-data data))]
(if-not (token-valid? t)
[nil (ex-info "token has expired" t)]
[t nil]))))
Expand All @@ -58,19 +58,19 @@
(http/request {:url token-url :method :post :headers (sp/transform [sp/MAP-KEYS] name token-headers) :body payload} #(a/put! ch %))
ch))

(defn schedule-token-renewal [name-of-job token-key should-renew? new-token! stop-ch]
(println "Starting token refresh poll" "name-of-job" name-of-job "token-key" token-key)
(defn schedule-token-renewal [name-of-job token-key should-renew? new-token! stop-ch token-store]
(log/trace "Starting token refresh poll" "name-of-job" name-of-job "token-key" token-key)
(a/go-loop []
(println "running" name-of-job "token renewal..." token-key)
(log/trace "running" name-of-job "token renewal..." token-key)
(let [now (fn [] (.getEpochSecond (Instant/now)))
[_ ch] (a/alts! [stop-ch (a/timeout 60000)])]
(cond
(= ch stop-ch) (println "stopping" name-of-job "token poller...")
(should-renew? (get @state token-key) (now)) (let [[token err] (a/<! (new-token!))]
(= ch stop-ch) (log/trace "stopping" name-of-job "token poller...")
(should-renew? (get @token-store token-key) (now)) (let [[token err] (a/<! (new-token!))]
(if err
(println "couldn't renew token for" name-of-job err)
(log/trace "couldn't renew token for" name-of-job err)
(do
(println "renewing token:" token)
(swap! state (fn [s] (assoc s token-key token)))))
(log/trace "renewing token:" token)
(swap! token-store (fn [s] (assoc s token-key token)))))
(recur))
:else (recur)))))

0 comments on commit 9e3d1c6

Please sign in to comment.