Add an alternative Ring session store that uses Clojure reader serialization
This way libraries like Friend, that use namespaced keywords (::identity) and other Clojure-specific data structures will work well with Monger. Current store will strip off namespace information from namespaced keywords because clojure.core/name work that way. For example: (name ::identity). Reported by Julio Barros.
This commit is contained in:
parent
828e7981f0
commit
43349f65ae
2 changed files with 97 additions and 0 deletions
|
|
@ -18,6 +18,49 @@
|
|||
;; API
|
||||
;;
|
||||
|
||||
;; this session store stores Clojure data structures using Clojure reader. It will correctly store every
|
||||
;; data structure Clojure reader can serialize and read but won't make the data useful to applications
|
||||
;; in other languages.
|
||||
|
||||
(defrecord ClojureReaderBasedMongoDBSessionStore [^String collection-name])
|
||||
|
||||
(extend-protocol ringstore/SessionStore
|
||||
ClojureReaderBasedMongoDBSessionStore
|
||||
|
||||
(read-session [store key]
|
||||
#_ (if-let [m (and key
|
||||
(mc/find-one-as-map (.collection-name store) {:_id key}))]
|
||||
m
|
||||
{})
|
||||
(if key
|
||||
(if-let [m (mc/find-one-as-map (.collection-name store) {:_id key})]
|
||||
(read-string (:value m))
|
||||
{})
|
||||
{}))
|
||||
|
||||
(write-session [store key data]
|
||||
(let [date (Date.)
|
||||
key (or key (str (UUID/randomUUID)))
|
||||
value (binding [*print-dup* true]
|
||||
(pr-str (assoc data :date date :_id key)))]
|
||||
(mc/save (.collection-name store) {:_id key :date date :value value})
|
||||
key))
|
||||
|
||||
(delete-session [store key]
|
||||
(mc/remove-by-id (.collection-name store) key)
|
||||
nil))
|
||||
|
||||
|
||||
(defn session-store
|
||||
([]
|
||||
(ClojureReaderBasedMongoDBSessionStore. default-session-store-collection))
|
||||
([^String s]
|
||||
(ClojureReaderBasedMongoDBSessionStore. s)))
|
||||
|
||||
|
||||
;; this session store won't store namespaced keywords correctly but stores results in a way
|
||||
;; that applications in other languages can read. DO NOT use it with Friend.
|
||||
|
||||
(defrecord MongoDBSessionStore [^String collection-name])
|
||||
|
||||
(extend-protocol ringstore/SessionStore
|
||||
|
|
|
|||
54
test/monger/test/ring/clojure_session_store_test.clj
Normal file
54
test/monger/test/ring/clojure_session_store_test.clj
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
(ns monger.test.ring.session-store-test
|
||||
(:require [monger core util]
|
||||
[monger.collection :as mc]
|
||||
[monger.test.helper :as helper])
|
||||
(:use clojure.test
|
||||
ring.middleware.session.store
|
||||
monger.ring.session-store))
|
||||
|
||||
|
||||
(helper/connect!)
|
||||
|
||||
(defn purge-sessions
|
||||
[f]
|
||||
(mc/remove "web_sessions")
|
||||
(mc/remove "sessions")
|
||||
(f)
|
||||
(mc/remove "web_sessions")
|
||||
(mc/remove "sessions"))
|
||||
|
||||
(use-fixtures :each purge-sessions)
|
||||
|
||||
|
||||
(deftest test-reading-a-session-that-does-not-exist
|
||||
(let [store (session-store)]
|
||||
(is (= {} (read-session store "a-missing-key-1228277")))))
|
||||
|
||||
|
||||
(deftest test-reading-a-session-that-does-exist
|
||||
(let [store (session-store)
|
||||
sk (write-session store nil {:library "Monger"})
|
||||
m (read-session store sk)]
|
||||
(is sk)
|
||||
(is (and (:_id m) (:date m)))
|
||||
(is (= (dissoc m :_id :date)
|
||||
{:library "Monger"}))))
|
||||
|
||||
|
||||
(deftest test-updating-a-session
|
||||
(let [store (session-store "sessions")
|
||||
sk1 (write-session store nil {:library "Monger"})
|
||||
sk2 (write-session store sk1 {:library "Ring"})
|
||||
m (read-session store sk2)]
|
||||
(is (and sk1 sk2))
|
||||
(is (and (:_id m) (:date m)))
|
||||
(is (= sk1 sk2))
|
||||
(is (= (dissoc m :_id :date)
|
||||
{:library "Ring"}))))
|
||||
|
||||
|
||||
(deftest test-deleting-a-session
|
||||
(let [store (session-store "sessions")
|
||||
sk (write-session store nil {:library "Monger"})]
|
||||
(is (nil? (delete-session store sk)))
|
||||
(is (= {} (read-session store sk)))))
|
||||
Loading…
Reference in a new issue