Skip to content

Commit fd46290

Browse files
committed
Add :duct.session-store/cookie component
Add a :duct.session-store/cookie component that implements the standard Ring cookie session store. Includes support for re-using the cookie store across resets, and for parsing the key from a hex-encoded string.
1 parent 0d8fddb commit fd46290

File tree

3 files changed

+57
-0
lines changed

3 files changed

+57
-0
lines changed

project.clj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
[org.duct-framework/handler "0.1.4"]
99
[org.duct-framework/server.http.jetty "0.3.4"]
1010
[org.duct-framework/router.reitit "0.5.2"]
11+
[commons-io "2.20.0"]
1112
[com.rpl/specter "1.1.6"]
1213
[integrant "1.0.1"]
1314
[hiccup "2.0.0"]

src/duct/session_store/cookie.clj

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
(ns duct.session-store.cookie
2+
(:require [integrant.core :as ig]
3+
[ring.middleware.session.cookie :as cookie])
4+
(:import [org.apache.commons.codec.binary Hex]))
5+
6+
(defmethod ig/assert-key :duct.session-store/cookie [_ {:keys [key]}]
7+
(assert (or (nil? key)
8+
(and (string? key) (re-matches #"[0-9a-fA-F]{32}" key)))
9+
":key should be nil or a randomly generated 16-byte hex string"))
10+
11+
(defmethod ig/init-key :duct.session-store/cookie [_ {:keys [key]}]
12+
(if (some? key)
13+
(cookie/cookie-store {:key (Hex/decodeHex ^String key)})
14+
(cookie/cookie-store)))
15+
16+
(defmethod ig/resume-key :duct.session-store/cookie
17+
[k opts old-opts old-store]
18+
(if (= opts old-opts)
19+
old-store
20+
(ig/init-key k opts)))
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
(ns duct.session-store.cookie-test
2+
(:require [clojure.test :refer [deftest is testing]]
3+
[duct.session-store.cookie]
4+
[integrant.core :as ig]
5+
[ring.middleware.session.store :as store]))
6+
7+
(deftest cookie-store-test
8+
(testing "bad :key option"
9+
(is (thrown? clojure.lang.ExceptionInfo
10+
(ig/init {:duct.session-store/cookie {:key "x"}}))))
11+
(testing "init produces session store"
12+
(let [system (ig/init {:duct.session-store/cookie {}})]
13+
(is (satisfies? store/SessionStore
14+
(:duct.session-store/cookie system))))
15+
(let [system (ig/init {:duct.session-store/cookie
16+
{:key "00112233445566778899aabbccddeeff"}})]
17+
(is (satisfies? store/SessionStore
18+
(:duct.session-store/cookie system)))))
19+
(testing "resume uses old store if options unchanged"
20+
(let [config {:duct.session-store/cookie {}}
21+
system (ig/init config)]
22+
(ig/suspend! system)
23+
(let [new-system (ig/resume config system)]
24+
(is (identical? (:duct.session-store/cookie system)
25+
(:duct.session-store/cookie new-system))))))
26+
(testing "resume uses new store if options changed"
27+
(let [config {:duct.session-store/cookie {}}
28+
system (ig/init config)]
29+
(ig/suspend! system)
30+
(let [new-config {:duct.session-store/cookie
31+
{:key "00112233445566778899aabbccddeeff"}}
32+
new-system (ig/resume new-config system)]
33+
(is (satisfies? store/SessionStore
34+
(:duct.session-store/cookie new-system)))
35+
(is (not (identical? (:duct.session-store/cookie system)
36+
(:duct.session-store/cookie new-system))))))))

0 commit comments

Comments
 (0)