Skip to content

Commit

Permalink
Added token refresh
Browse files Browse the repository at this point in the history
  • Loading branch information
Pat Patterson committed Sep 15, 2011
1 parent c4a1180 commit ab33b4c
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 24 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Expand Up @@ -3,4 +3,5 @@ classes
lib
*.keystore
.DS_Store
vars.sh
vars.sh
localvars.sh
62 changes: 49 additions & 13 deletions src/treajure/core.clj
Expand Up @@ -16,9 +16,28 @@
"&client_id=" (:client-id oauth-params)
"&redirect_uri=" (codec/url-encode (:redirect-uri oauth-params))))

(defn- refresh-oauth
"Do the OAuth refresh flow and return a map comprising a merge of the new
access token etc with the old client id, secret etc"
[oauth]
(when (:trace-messages oauth)
(println (str "Sending OAuth request for refresh token " (:refresh-token oauth))))
(let [response
(json/read-json (http-agent/string
(http-agent/http-agent (str (:login-uri oauth) "/services/oauth2/token")
:method "POST"
:body (str
"grant_type=refresh_token"
"&client_id=" (:client-id oauth)
"&client_secret=" (:client-secret oauth)
"&refresh_token=" (:refresh_token oauth)))))]
(when (:trace-messages oauth)
(println (str "OAuth GET response is " response)))
(merge oauth response)))

(defn- get-oauth
"Exchange an OAuth authorization code for an OAuth response containing the
instance url/access token etc"
instance url, access token etc and the incoming configuration parameters"
[oauth-params code]
(when (:trace-messages oauth-params)
(println (str "Sending OAuth request for code " code)))
Expand All @@ -34,30 +53,45 @@
"&redirect_uri=" (:redirect-uri oauth-params)))))]
(when (:trace-messages oauth-params)
(println (str "OAuth GET response is " response)))
response))
(merge oauth-params response)))

(defn oauth-request
(defn raw-oauth-request
"Low level OAuth request function"
([oauth url] (oauth-request oauth url "GET" nil))
([oauth url method] (oauth-request oauth url method nil))
([oauth url method body]
(when (:trace-messages oauth)
([oauth url] (raw-oauth-request oauth url "GET" nil false))
([oauth url method] (raw-oauth-request oauth url method nil false))
([oauth url method body] (raw-oauth-request oauth url method nil false))
([oauth url method body retry]
(when (:trace-messages @oauth)
(println (str "Sending OAuth " method
" Access token " (:access_token oauth)
" Access token " (:access_token @oauth)
" url " url
(if (nil? body) " no body" (str " body " body)))))
(let [http-agnt (http-agent/http-agent url
:method method
:headers {"Authorization" (str "OAuth " (:access_token oauth)) "Content-Type" "application/json"}
:headers {"Authorization" (str "OAuth " (:access_token @oauth)) "Content-Type" "application/json"}
:body (if (nil? body)
nil
(json/json-str body)))
json-response (http-agent/string http-agnt)
status (http-agent/status http-agnt)
response (if (or (nil? json-response) (== (count json-response) 0)) nil (json/read-json json-response))]
(when (:trace-messages oauth)
(println (str "OAuth " method " status is " status (when (not (nil? response)) (str " response is " response)))))
response)))
(if (and (= status 401) (not retry))
(do
(when (:trace-messages @oauth)
(println "Refreshing token"))
(swap! oauth refresh-oauth)
; Try again, setting retry to true
(raw-oauth-request oauth url method body true))
(do
(when (:trace-messages @oauth)
(println (str "OAuth " method " status is " status (when (not (nil? response)) (str " response is " response)))))
response)))))

(defn oauth-request
"Low level OAuth request function - prepends instance URL"
([oauth url] (raw-oauth-request oauth (str (:instance_url @oauth) url) "GET" nil))
([oauth url method] (raw-oauth-request oauth (str (:instance_url @oauth) url) method nil))
([oauth url method body] (raw-oauth-request oauth (str (:instance_url @oauth) url) method body)))

(defn wrap-oauth
"Handles the OAuth protocol."
Expand All @@ -73,7 +107,9 @@
{:status 302
:headers {"Location" "/"}
:session (let [oauth (get-oauth oauth-params ((:params request) "code"))]
{::oauth (merge oauth {:trace-messages (:trace-messages oauth-params)})})}
; ::oauth is an atom so we can modify it when we
; refresh the access token
{::oauth (atom oauth)})}
(let [oauth (::oauth (:session request))]
(if (nil? oauth)
; Redirect to OAuth authentication/authorization
Expand Down
36 changes: 26 additions & 10 deletions src/treajure/force.clj
Expand Up @@ -13,9 +13,9 @@
(defn id-helper
"Given an OAuth response, return the id"
[oauth]
(oauth-request
(raw-oauth-request
oauth
(:id oauth)))
(:id @oauth)))

(defmacro describe
[obj-type]
Expand All @@ -26,7 +26,7 @@
[oauth obj-type]
(oauth-request
oauth
(str (:instance_url oauth) "/services/data/v21.0/sobjects/" obj-type "/describe/")))
(str "/services/data/v22.0/sobjects/" obj-type "/describe/")))

(defmacro query
[query]
Expand All @@ -37,7 +37,7 @@
[oauth query]
(oauth-request
oauth
(str (:instance_url oauth) "/services/data/v21.0/query?q=" (codec/url-encode query))))
(str "/services/data/v22.0/query?q=" (codec/url-encode query))))

(defmacro create
[obj-type fields]
Expand All @@ -48,7 +48,7 @@
[oauth obj-type fields]
(oauth-request
oauth
(str (:instance_url oauth) "/services/data/v21.0/sobjects/" obj-type)
(str "/services/data/v22.0/sobjects/" obj-type)
"POST"
fields))

Expand All @@ -63,12 +63,12 @@
([oauth obj-type id]
(oauth-request
oauth
(str (:instance_url oauth) "/services/data/v21.0/sobjects/" obj-type "/" id)))
(str "/services/data/v22.0/sobjects/" obj-type "/" id)))
; TODO - make field list a vector?
([oauth obj-type id field-list]
(oauth-request
oauth
(str (:instance_url oauth) "/services/data/v21.0/sobjects/" obj-type "/" id "?fields=" field-list))))
(str "/services/data/v22.0/sobjects/" obj-type "/" id "?fields=" field-list))))

(defmacro update
[obj-type id fields]
Expand All @@ -81,7 +81,23 @@
[oauth obj-type id fields]
(oauth-request
oauth
(str (:instance_url oauth) "/services/data/v21.0/sobjects/" obj-type "/" id "?_HttpMethod=PATCH")
(str "/services/data/v22.0/sobjects/" obj-type "/" id "?_HttpMethod=PATCH")
"POST"
fields))

(defmacro upsert
[obj-type externalIdField externalId fields]
`(upsert-helper ~'oauth ~obj-type ~externalIdField ~externalId ~fields))

(defn upsert-helper
"Given an OAuth response, object type, external id field, external id and
fields, upsert the sobject"
; Note - Java HttpURLConnection does not support PATCH (at least as of
; Java SE 6), so use the _HttpMethod workaround
[oauth obj-type externalIdField externalId fields]
(oauth-request
oauth
(str "/services/data/v22.0/sobjects/" obj-type "/" externalIdField "/" externalId "?_HttpMethod=PATCH")
"POST"
fields))

Expand All @@ -94,5 +110,5 @@
[oauth obj-type id]
(oauth-request
oauth
(str (:instance_url oauth) "/services/data/v21.0/sobjects/" obj-type "/" id)
"DELETE"))
(str "/services/data/v22.0/sobjects/" obj-type "/" id)
"DELETE"))

0 comments on commit ab33b4c

Please sign in to comment.