Navigation Menu

Skip to content

Hendrick/avenue

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Avenue

Avenue is small set of macros for web apps that use Compojure. Primarily, it provides a simple mechanism for authorization.

Installation

Add the following dependency to your project.clj file:

[com.hendrick/avenue "0.1.0"]

What is it?

In a web app, most requests fall into one of a few categories. You have pages...

  (page
    "/admin/user-permissions"
    [:user.role/superAdmin]
    user-permissions-view/show)

You've got Ajax requests...

  (xhr
    POST "/admin/update-account"
    [:user.role/superAdmin]
    actions/update-account)

And you might have some form posts...

  (form-post
    "/admin/create-account"
    [:user.role/superAdmin]
    actions/create-account)

All Avenue does is provide a little shorthand for these common cases. You can mix and match Avenue-style routes with regular Compojure routes.

Usage / Arguments

Each of the page, xhr, and form-post macros require the same arguments, with the exception that for xhr calls, you must specify the request's HTTP method.

A call looks like this

(page|xhr|form-post
  http-method ;; xhr only
  url
  auth-data
  actions) ;; variable

The http-method and url arguments are just forwarded to Compojure/ring. auth-data is any data structure that identifies who is allowed to access this route. The contents of auth-data are not used by Avenue. Avenue will pass the contents of auth-data to your :auth-fn

For example, you might have several routes that are only accessible by admin users, you can indicate this with a keyword.

(page
  "/admin/do-secret-stuff"
  :adminOnly
  view/show-secret-page)

You might have some other routes that are accessible to everyone.

(page
  "/welcome"
  :allowEveryone
  view/welcome-page)

The keywords you choose are actually opaque to avenue, you specify their meaning in an :auth-fn.

(defn -main [& {:as args}]
  (let [app (-> routes
                (av/wrap-auth {:auth-fn (fn [auth-data req]
                                          (condp = auth-data
                                            :allowEveryone true
                                            :adminOnly (:is-admin (db/find-user (:user-id (:session req))))
                                            false))
                               :authorized-page-fn show-page
                               :unauthorized-page-fn redirect-to-welcome-page})
                (handler/site {:session {:store (cookie/cookie-store {:key "this is a secret"})}}))]
    (web/run app args)))

If you find keywords aren't sufficient to express your auth requirements, you can use any arbitrarily complex Clojure data structure. It's up to you to find the :auth-fn and route data-structure that best suits your needs.

For a working example, check out the sample app.

Configuration

To use Avenue, you must include av/wrap-auth in your middleware stack. It takes a few options:

:auth-fn is a function that returns a truthy or falsey value indicating whether a user is allowed access. As parameters, we'll pass the data structure that's specified along with the route, and the request itself.

The data structure that gets passed to the auth-fn is exactly what's specified in the route definition. It is the second argument of the page or form-post macro, and the third argument of the xhr macro. Avenue does nothing with this data except to pass it to the auth-fn.

:authorized-page-fn is a function that the page macro will call with the result of the route's actions. It's ignored by the xhr and form-post macros.

:unauthorized-page-fn is a function that any macro will call when the :auth-fn returns a falsey value.

If you don't care much about auth, you can omit :auth-fn and :unauthorized-page-fn from the configuration that's passed to av/wrap-auth, and also drop the auth data structures from your routes.

License

Copyright 2015 Hendrick Automotive Group

Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.

Releases

No releases published

Packages

No packages published