Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A few minor enhancements #60

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@ test/oauth/twitter_keys.clj
*.jar
pom.xml
.lein-*
/.idea
/*.iml
/.clj-kondo/.cache
5 changes: 5 additions & 0 deletions deps.edn
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{:deps {org.clojure/clojure {:mvn/version "1.10.3"}
org.bouncycastle/bcprov-jdk15on {:mvn/version "1.70"}
org.bouncycastle/bcpkix-jdk15on {:mvn/version "1.70"}
commons-codec/commons-codec {:mvn/version "1.15"}
com.cemerick/url {:mvn/version "0.1.1"}}}
7 changes: 4 additions & 3 deletions project.clj
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
(defproject clj-oauth "1.5.6-SNAPSHOT"
:url "https://github.com/drone-rites/clj-oauth"
:license {:name "Simplified BSD License"
:url "https://opensource.org/licenses/BSD-2-Clause"
:license {:name "Simplified BSD License"
:url "https://opensource.org/licenses/BSD-2-Clause"
:distribution :repo}
:description "OAuth support for Clojure"
:dependencies [[org.clojure/clojure "1.10.3"]
[commons-codec/commons-codec "1.15"]
[org.bouncycastle/bcprov-jdk15on "1.70"]
[org.bouncycastle/bcpkix-jdk15on "1.70"]
[clj-http "3.12.3"]])
[clj-http "3.12.3"]
[com.cemerick/url "0.1.1"]])
26 changes: 19 additions & 7 deletions src/oauth/client.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
#^{:author "Matt Revelle"
:doc "OAuth client library for Clojure."}
oauth.client
(:require [oauth.digest :as digest]
[oauth.signature :as sig]
[clj-http.client :as httpclient])
(:require [oauth.signature :as sig]
[clj-http.client :as httpclient]
[cemerick.url :refer [url]])
(:use [clojure.string :only [join split upper-case]]))

(defrecord #^{:doc "OAuth consumer"}
Expand Down Expand Up @@ -105,6 +105,18 @@ Authorization HTTP header or added as query parameters to the request."
oauth-params (assoc unsigned-oauth-params :oauth_signature signature)]
(build-request oauth-params extra-params))))

(defn override-host [original-url host]
(when original-url
(-> original-url
url
(assoc :host host)
str)))

(defn override-uri [consumer uri-key]
(if-let [host (:override-host consumer)]
(override-host (get consumer uri-key) host)
(get consumer uri-key)))

(defn request-token
"Fetch request token for the consumer."
([consumer]
Expand All @@ -116,7 +128,7 @@ Authorization HTTP header or added as query parameters to the request."
(sig/rand-str 30)
(sig/msecs->secs (System/currentTimeMillis)))
(assoc :oauth_callback callback-uri))]
(post-request-body-decoded (:request-uri consumer)
(post-request-body-decoded (override-uri consumer :request-uri)
(build-oauth-token-request consumer
(:request-uri consumer)
unsigned-params
Expand All @@ -141,7 +153,7 @@ Authorization HTTP header or added as query parameters to the request."
(:oauth_token
request-token)))
token-secret (:oauth_token_secret request-token)]
(post-request-body-decoded (:access-uri consumer)
(post-request-body-decoded (override-uri consumer :access-uri)
(build-oauth-token-request consumer
(:access-uri consumer)
unsigned-oauth-params
Expand Down Expand Up @@ -183,7 +195,7 @@ Authorization HTTP header or added as query parameters to the request."
(:oauth_token expired-token)))
unsigned-oauth-params (assoc base-oauth-params
:oauth_session_handle (:oauth_session_handle expired-token))]
(post-request-body-decoded (:access-uri consumer)
(post-request-body-decoded (override-uri consumer :access-uri)
(build-oauth-token-request consumer
(:access-uri consumer)
unsigned-oauth-params
Expand All @@ -193,7 +205,7 @@ Authorization HTTP header or added as query parameters to the request."
(defn xauth-access-token
"Request an access token with a username and password with xAuth."
[consumer username password]
(post-request-body-decoded (:access-uri consumer)
(post-request-body-decoded (override-uri consumer :access-uri)
(build-xauth-access-token-request consumer
username
password
Expand Down
12 changes: 6 additions & 6 deletions src/oauth/signature.clj
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@
(name a)
(str a)))

(def secure-random (java.security.SecureRandom/getInstance "SHA1PRNG"))
(def secure-random (delay (java.security.SecureRandom/getInstance "SHA1PRNG")))

(defn rand-str
"Random string for OAuth requests."
[length]
(. (new BigInteger (int (* 5 length)) ^java.util.Random secure-random) toString 32))
(. (new BigInteger (int (* 5 length)) ^java.util.Random @secure-random) toString 32))

(defn msecs->secs
"Convert milliseconds to seconds."
Expand Down Expand Up @@ -75,9 +75,9 @@
[c base-string & [token-secret]]
(str (url-encode (:secret c)) "&" (url-encode (or token-secret ""))))

(def ^:private pem-converter
(doto (JcaPEMKeyConverter.)
(.setProvider "BC")))
(def ^:private pem-converter (delay
(doto (JcaPEMKeyConverter.)
(.setProvider "BC"))))

(defmethod sign :rsa-sha1
[c ^String base-string & [token-secret]]
Expand All @@ -87,7 +87,7 @@
java.io.StringReader.
org.bouncycastle.openssl.PEMParser.
.readObject)
private-key (-> ^JcaPEMKeyConverter pem-converter
private-key (-> ^JcaPEMKeyConverter @pem-converter
(.getKeyPair key-pair)
.getPrivate)
signer (doto (java.security.Signature/getInstance "SHA1withRSA" "BC")
Expand Down
72 changes: 53 additions & 19 deletions test/oauth/client_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
(:require [oauth.client :as oc]
[oauth.signature :as sig]
:reload-all)
(:use clojure.test
[clojure.pprint :only [pprint]]))
(:use [clojure.pprint :only [pprint]]
[clojure.test]))

(deftest ^{:doc "Test creation of authorization header for request_token access."}
request-access-authorization-header
request-access-authorization-header
(let [c (oc/make-consumer "GDdmIQH6jhtmLUypg82g"
"MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98"
"https://api.twitter.com/oauth/request_token"
Expand All @@ -15,10 +15,10 @@
:hmac-sha1)
;; Ensure that the params from Twitter example are used.
unsigned-params (merge (sig/oauth-params c "QP70eNmVz8jvdPevU3oJD2AfF7R7odC2XJcn4XlZJqk" 1272323042)
{:oauth_callback "http://localhost:3005/the_dance/process_callback?service_provider_id=11"
:oauth_consumer_key "GDdmIQH6jhtmLUypg82g"
{:oauth_callback "http://localhost:3005/the_dance/process_callback?service_provider_id=11"
:oauth_consumer_key "GDdmIQH6jhtmLUypg82g"
:oauth_signature_method "HMAC-SHA1"
:oauth_version "1.0"})
:oauth_version "1.0"})
signature (sig/sign c (sig/base-string "POST"
(:request-uri c)
unsigned-params))
Expand All @@ -29,7 +29,7 @@
"OAuth oauth_callback=\"http%3A%2F%2Flocalhost%3A3005%2Fthe_dance%2Fprocess_callback%3Fservice_provider_id%3D11\", oauth_consumer_key=\"GDdmIQH6jhtmLUypg82g\", oauth_nonce=\"QP70eNmVz8jvdPevU3oJD2AfF7R7odC2XJcn4XlZJqk\", oauth_signature=\"8wUi7m5HFQy76nowoCThusfgB%2BQ%3D\", oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"1272323042\", oauth_version=\"1.0\""))))

(deftest ^{:doc "Test creation of authorization header for access_token request"}
access-token-authorization-header
access-token-authorization-header
(let [c (oc/make-consumer "GDdmIQH6jhtmLUypg82g"
"MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98"
"https://api.twitter.com/oauth/request_token"
Expand All @@ -38,23 +38,23 @@
:hmac-sha1)
;; Ensure that the params from Twitter example are used.
unsigned-params (merge (sig/oauth-params c "9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8" 1272323047)
{:oauth_consumer_key "GDdmIQH6jhtmLUypg82g"
{:oauth_consumer_key "GDdmIQH6jhtmLUypg82g"
:oauth_signature_method "HMAC-SHA1"
:oauth_token "8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc"
:oauth_verifier "pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY"
:oauth_version "1.0"})
:oauth_token "8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc"
:oauth_verifier "pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY"
:oauth_version "1.0"})
signature (sig/sign c
(sig/base-string "POST"
(:access-uri c)
unsigned-params)
"x6qpRnlEmW9JbQn4PQVVeVG8ZLPEx6A0TOebgwcuA") ;; token secret
"x6qpRnlEmW9JbQn4PQVVeVG8ZLPEx6A0TOebgwcuA") ;; token secret
params (assoc unsigned-params
:oauth_signature signature)]
(is (= (oc/authorization-header (sort params))
"OAuth oauth_consumer_key=\"GDdmIQH6jhtmLUypg82g\", oauth_nonce=\"9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8\", oauth_signature=\"PUw%2FdHA4fnlJYM6RhXk5IU%2F0fCc%3D\", oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"1272323047\", oauth_token=\"8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc\", oauth_verifier=\"pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY\", oauth_version=\"1.0\""))))

(deftest ^{:doc "Test creation of approval URL"}
user-approval-uri
user-approval-uri
(let [c (oc/make-consumer "GDdmIQH6jhtmLUypg82g"
"MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98"
"https://api.twitter.com/oauth/request_token"
Expand All @@ -69,20 +69,20 @@
(oc/user-approval-uri c t {:extra "foo"})))))

(deftest ^{:doc "Test creation of authorization header for refresh access_token request"}
refresh-token-authorization-header
refresh-token-authorization-header
(let [c (oc/make-consumer "GDdmIQH6jhtmLUypg82g"
"MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98"
"https://api.twitter.com/oauth/request_token"
"https://api.twitter.com/oauth/access_token"
"https://api.twitter.com/oauth/authorize"
:hmac-sha1)
unsigned-params (merge (sig/oauth-params c "9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8" 1272323047)
{:oauth_consumer_key "GDdmIQH6jhtmLUypg82g"
:oauth_nonce "9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8"
{:oauth_consumer_key "GDdmIQH6jhtmLUypg82g"
:oauth_nonce "9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8"
:oauth_signature_method "HMAC-SHA1"
:oauth_token "8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc"
:oauth_timestamp "1272323047"
:oauth_version "1.0"}
:oauth_token "8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc"
:oauth_timestamp "1272323047"
:oauth_version "1.0"}
{:oauth_session_handle "5a10ddsqoqo2rfi"})
signature (sig/sign c (sig/base-string "POST"
(:request-uri c)
Expand All @@ -91,3 +91,37 @@
:oauth_signature signature)]
(is (= (oc/authorization-header (sort params))
"OAuth oauth_consumer_key=\"GDdmIQH6jhtmLUypg82g\", oauth_nonce=\"9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8\", oauth_session_handle=\"5a10ddsqoqo2rfi\", oauth_signature=\"f15S84zVZ96f9PwAJrBHq28KIF4%3D\", oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"1272323047\", oauth_token=\"8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc\", oauth_version=\"1.0\""))))

(deftest override-host-test
(testing "override host"
(is (= (oc/override-host "https://magento2.mgt/index.php/oauth/token/request" "1234-180-123-89-218.eu.ngrok.io")
"https://1234-180-123-89-218.eu.ngrok.io/index.php/oauth/token/request"))))

(deftest override-uri-test
(testing "override uri"
(let [consumer (oc/make-consumer "GDdmIQH6jhtmLUypg82g"
"MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98"
"https://api.twitter.com/oauth/request_token"
"https://api.twitter.com/oauth/access_token"
"https://api.twitter.com/oauth/authorize"
:hmac-sha1)]
(testing "no host override"
(is (= (oc/override-uri consumer :request-uri)
"https://api.twitter.com/oauth/request_token")))

(testing "request-uri with override"
(is (= (oc/override-uri (assoc consumer :override-host "1234-180-123-89-218.eu.ngrok.io") :request-uri)
"https://1234-180-123-89-218.eu.ngrok.io/oauth/request_token")))

(testing "access-uri with override"
(is (= (oc/override-uri (assoc consumer :override-host "1234-180-123-89-218.eu.ngrok.io") :access-uri)
"https://1234-180-123-89-218.eu.ngrok.io/oauth/access_token")))

(testing "authorize with override"
(is (= (oc/override-uri (assoc consumer :override-host "1234-180-123-89-218.eu.ngrok.io") :authorize-uri)
"https://1234-180-123-89-218.eu.ngrok.io/oauth/authorize")))

(testing "nil URI with override"
(is (nil? (oc/override-uri (-> consumer
(assoc :override-host "1234-180-123-89-218.eu.ngrok.io"
:authorize-uri nil)) :authorize-uri)))))))