Sandbar is a web application library which is designed to be used with Compojure and/or Ring. It builds on these projects providing the following additional features:
- Session and flash as a global map
- Authorization and authentication, including built-in support for form-based authentication
- Forms and form validation
More documentation is located in the Sandbar Wiki.
You may also be interested in joining the Sandbar Google Group.
Replace wrap-session
with wrap-stateful-session
and downstream from any wrapped handler you may access the session through a map interface.
(defn form-authentication [request]
(do (session-put! :auth-redirect-uri (:uri request))
(redirect "/login")))
(defn get-auth-success-redirect []
(or (session-get :auth-redirect-uri)
(property-lookup adapter :login-page)))
Flash is supported as well with flash-put!
and flash-get
.
For more detailed documentation see the Stateful Sessions page in the Sandbar Wiki.
Create a simple form with one textfield and validate its input.
(defform user-form "/user/edit"
:fields [(hidden :id)
(textfield "Username" :username)]
:load #(db/find-user %)
:on-cancel "/"
:on-success
#(do
(db/store-user %)
(set-flash-value! :user-message "User has been saved.")
"/")
:validator
#(if (< (count (:username %)) 5)
(add-validation-error % :username "Username must have at least 5 chars.")
%))
(defroutes routes
(user-form (fn [request form] (layout form))))
For more detailed documentation see the Forms or Form Validation pages in the Sandbar Wiki.
Create a security policy…
(def security-policy
[#"/admin.*" :admin
#"/permission-denied.*" :any
#"/login.*" :any
#".*\.(css|js|png|jpg|gif)$" :any
#".*" #{:admin :user}])
…and an authenticator.
(defauth form-auth
:type :form
:load (fn [username password]
(merge (database/find-user username) {:login-password password}))
:validator #(if (= (:password %) (:login-password %))
%
(add-validation-error % "Incorrect username or password!")))
Add the authenticator to your routes.
(defroutes routes
(form-auth (fn [request content] (layout content)))
(ANY "*" [] (layout (home-view))))
Add the with-security
wrapper, passing it the security policy and the authenticator.
(def app
(-> routes
(with-security security-policy form-auth)
wrap-stateful-session))
Use it!
(ensure-any-role #{:user :admin}
(disintegrate "something"))
For more detailed documentation see the Authentication and Authorization page in the Sandbar Wiki.
Within Sandbar are some working examples which may be helpful. The Sandbar Examples project contains other examples of Sandbar usage. You may also want to take a look at the Clojure Web project which uses Sandbar in the Authentication examples.
Add [sandbar/sandbar "0.4.0-SNAPSHOT"]
to your :dependencies in project.clj.
Add the following dependency:
<dependency>
<groupId>sandbar</groupId>
<artifactId>sandbar</artifactId>
<version>0.4.0-SNAPSHOT</version>
</dependency>
which comes from Clojars…
<repository>
<id>clojars.org</id>
<url>http://clojars.org/repo</url>
</repository>
Please note that any code with a namespace prefix of sandbar.dev
is very pre-alpha. It will change often and may not work.
Copyright © 2010 Brenton Ashworth
Thanks to Allen Rohner for his help with this project.
Distributed under the Eclipse Public License, the same as Clojure uses. See the file COPYING.