Skip to content

Instantly share code, notes, and snippets.

@slyphon

slyphon/wtf.clj Secret

Created March 24, 2010 19:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save slyphon/b2f6b5577b32099e1062 to your computer and use it in GitHub Desktop.
Save slyphon/b2f6b5577b32099e1062 to your computer and use it in GitHub Desktop.
(ns mbox.harpo.mbx-signature
(:use
[clojure
[walk :only (keywordize-keys stringify-keys)]]
[clojure.contrib
[java-utils :only (as-str)]
[str-utils :only (chomp str-join)]
[except :only (throw-arg)]])
(:import
[java.security SignatureException]
[javax.crypto Mac]
[javax.crypto.spec SecretKeySpec]
[org.apache.commons.codec.binary Base64]
[java.util Date]
[java.text SimpleDateFormat FieldPosition]
[java.net URLEncoder]
))
(def *hmac-algo* "HmacSHA256")
(def *base64-url-safe* false)
(def *encoding* "UTF8")
(defonce *rfc3339-date-fmt* (SimpleDateFormat. "yyyy-MM-dd'T'HH:mm:ss'Z'"))
(defn- throw-arg-if-not [test & args]
(when-not test
(apply throw-arg args)))
(defn format-rfc-3339 [date]
(str (.format *rfc3339-date-fmt* date (StringBuffer.) (FieldPosition. 0))))
(defn urlescape [s]
(URLEncoder/encode (as-str s) *encoding*))
(defstruct mbx-signature :key :secret :verb :host :path :query-params :time :body)
(defn- date? [o]
(= (class o) Date))
(defn canonicalize-params [time key params]
(throw-arg-if-not (or (date? time) (string? time))
(str "time argument to canonicalize-params must be either "
"a java.util.Date or a formatted string, not %s") time)
(let [time-str (if (date? time)
(format-rfc-3339 time)
time)
pmap (merge (stringify-keys params)
{"ts" time-str "key" key})]
(str-join "&" (map #(str-join "=" %1 %2) (sort pmap)))))
(defn sign [{:keys [key secret verb host path query-params time body]
:or {time (Date.) query-params {}} }]
(let [time-str (format-rfc-3339 time)]))
(defn calculate [data secret]
(let [skey (SecretKeySpec. (.getBytes secret) *hmac-algo*)
mac (doto (Mac/getInstance *hmac-algo*)
(.init skey))
b64 (Base64. *base64-url-safe*)]
(->> (.doFinal mac (.getBytes data))
(.encodeToString b64)
(chomp))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment