PageRenderTime 68ms CodeModel.GetById 34ms RepoModel.GetById 0ms app.codeStats 0ms

/src/pusher/auth.clj

http://github.com/bblimke/clj-pusher
Clojure | 61 lines | 48 code | 13 blank | 0 comment | 0 complexity | f41fcc89762057f7ae5724344f9fed4c MD5 | raw file
  1. (ns pusher.auth
  2. (:require
  3. [uk.co.holygoat.util.md5 :as md5])
  4. (:use
  5. [clojure.string :only [join]])
  6. (:import
  7. (javax.crypto Mac)
  8. (javax.crypto.spec SecretKeySpec)
  9. (java.math BigInteger)))
  10. (defn ^{:dynamic true} *current-time-millis* []
  11. (long (System/currentTimeMillis)))
  12. (defn- current-timestamp []
  13. (let [millis (*current-time-millis*)
  14. now (long (/ millis 1000))]
  15. now))
  16. (defn- add-auth-params [key request]
  17. (assoc request
  18. :query (merge
  19. (request :query)
  20. {:auth_key key
  21. :auth_timestamp (current-timestamp)
  22. :auth_version "1.0"})))
  23. (defn- ljust [xs x y] (apply str (concat (replicate (- x (.length #^String xs)) y) xs)))
  24. (defn- byte-array-to-str [bytes]
  25. (let [big-integer (BigInteger. 1 bytes)
  26. hash (.toString big-integer 16)]
  27. (ljust hash 64 0)))
  28. (defn- hmac
  29. "Calculate HMAC signature for given data."
  30. [#^String key #^String data]
  31. (let [hmac-sha256 "HmacSHA256"
  32. signing-key (SecretKeySpec. (.getBytes key) hmac-sha256)
  33. mac (doto (Mac/getInstance hmac-sha256) (.init signing-key))]
  34. (byte-array-to-str (.doFinal mac (.getBytes data)))))
  35. (defn- parameter-string [params]
  36. (join "&"
  37. (map (fn [[key val]] (str (name key) "=" (str val)))
  38. (sort-by #(name (key %)) java.lang.String/CASE_INSENSITIVE_ORDER params))))
  39. (defn- signature-string [request]
  40. (join "\n" [(request :method) (request :path) (parameter-string (request :query))]))
  41. (defn- generate-signature [secret request]
  42. (hmac secret (signature-string request)))
  43. (defn- add-signature [secret request]
  44. (assoc-in request [:query :auth_signature] (generate-signature secret request)))
  45. (defn- add-body-md5-param [request]
  46. (assoc-in request [:query :body_md5] (md5/md5-sum (request :body))))
  47. (defn authenticated-request [key secret request]
  48. (add-signature secret (add-auth-params key (add-body-md5-param request))))