Simple authentication for Clack-based Common Lisp web applications.
See the demo app for a complete example.
Available Password-Hashing Functions
To mitigate the risks of the NSA convincing people to hash passwords with things like SHA-256, only PBKDF2 (And eventually scrypt) is supported
Hermetic is not opinionated, doesn't integrate into an existing database or create any models. As such, it needs to be told how to find a user's information to provide authentication. This is what
setup is for:
(setup :user-p ;; str->bool, t if a username exists, nil otherwise :user-pass ;; str->str, maps a username to a password (hash, hopefully) :user-roles ;; str->(list sym), maps a username to a list of roles, ;; for example: (:user) (:user :tester :staff) (:user :admin) :session ;; the /expression/ for the session object. ningle:*session* on ;; Ningle <https://github.com/fukamachi/ningle>. :denied ;; A function that displays an "access denied" message )
For example, if your users are stored in a simple in-memory hash-table as in the demo app:
(defmacro get-user (username) `(gethash ,username *users*)) (setup :user-p #'(lambda (user) (get-user user)) :user-pass #'(lambda (user) (getf (get-user user) :pass)) :user-roles #'(lambda (user) (getf (get-user user) :roles)) :session *session*)
When creating your login view, the
login macro handles most of the work for you.
Grants access to a site only to users whose roles intersect with the roles in the first argument.
If an access denied page is not provided, the global one is used instead.
(setf (route *app* "/user/profile/:userid" :method :GET) (lambda (params (auth (:user) (render-template "templates/profile.html") (render-error "You have to log in to view user profiles.")))))
auth isn't enough to determine who gets to use what, Hermetic provides a few functions for accessing user data from inside a view.
logged-in-p: Exactly what it says on the tin.
user-name: Returns the username of the current user.
roles: Returns the list of roles of the current user.
role-p: Checks if a user has a role.
Logs the user out. Takes two expressions,
Copyright (c) 2013 Fernando Borretti (firstname.lastname@example.org).
Licensed under the MIT License.
- Fernando Borretti