summaryrefslogtreecommitdiff
path: root/src/cookie_login.clj
diff options
context:
space:
mode:
Diffstat (limited to 'src/cookie_login.clj')
-rwxr-xr-xsrc/cookie_login.clj74
1 files changed, 74 insertions, 0 deletions
diff --git a/src/cookie_login.clj b/src/cookie_login.clj
new file mode 100755
index 0000000..6ac1f6c
--- /dev/null
+++ b/src/cookie_login.clj
@@ -0,0 +1,74 @@
+(ns cookie-login
+ (:use compojure))
+
+(defn clear-login-token [token-key]
+ "Creates an expiration cookie for a given cookie name."
+ (set-cookie token-key "dummy"
+ :expires "Thu, 01-Jan-1970 00:00:01 GMT"))
+
+(defn handle-request-with-login-token
+ "Validates login token, handles request, and updates cookies and session
+ repository. If token is invalid or an exception is raised while reading it,
+ the token cookie is expired."
+ [handler request expiry token-key token-maker token-reader]
+ (if-let [session-info (token-reader (get-in request [:cookies token-key]))]
+ (let [response (handler (merge-with merge
+ request
+ {:session session-info}))
+ ; Session variable priority:
+ ; 1) variables set by handler
+ ; 2) session variables from token-reader
+ ; 3) variables from repository
+ session-map (merge (request :session)
+ session-info
+ (response :session))]
+ (merge-with merge
+ response
+ {:session session-map}
+ (token-maker session-info expiry)))
+ (merge (handler request)
+ (clear-login-token token-key))))
+
+; Default expiration is a week.
+(def *default-login-token-expiry* (* 1000 60 60 24 7))
+(def *default-login-token-key* :login-token)
+
+(defn with-cookie-login
+ "Middleware to support automatic cookie login. Must be placed after
+ the with-session middleware!
+
+ Accepts five configuration options:
+ - token-key:
+ The cookie name to store the login-token under.
+ Defaults to 'login-token'.
+ - expiry:
+ The number of milliseconds a login token is valid for.
+ Defaults to one week.
+ - is-logged-in?:
+ Function to apply to request's session map to determine whether to
+ process login token or not. If a truthy value is returned,
+ then the next handler is called.
+ - token-maker:
+ Function to generate new login token from session map and
+ milliseconds until login token expiry.
+ - token-reader:
+ Function to generate session map from login token. Should return nil
+ if login token is invalid.
+"
+ [handler options]
+ (let [token-key (or (options :default-token-key) *default-login-token-key*)
+ expiry (or (options :expiry) *default-login-token-expiry*)
+ is-logged-in? (options :is-logged-in?)
+ token-maker (options :token-maker)
+ token-reader (options :token-reader)]
+ (fn [request]
+ (if (or (is-logged-in? (request :session))
+ (not (get-in request [:cookies token-key])))
+ (handler request)
+ (handle-request-with-login-token
+ handler
+ request
+ expiry
+ token-key
+ token-maker
+ token-reader))))) \ No newline at end of file