I'd like to announce the first preview of "permissions"- a small library to 
handle role and permission based access control in web applications.

Github: https://github.com/tuhlmann/permissions
Clojars: https://clojars.org/agynamix/permissions

Permissions is heavily inspired and modeled after Apache Shiro's 
WildcardPermission: http://shiro.apache.org/permissions.html.

In a nutshell, you can define permissions based on a 

- domain: "users", "company", "admin", whatever the main areas of your 
application might be, 
- actions: "read", "edit", "delete", "upload" or however you like to name 
them,
- entities: "abcd1234", to limit access only to a resource with this 
specific ID

And you have the wildcard. You can grant access to all domains, all 
actions, all entities by applying the wildcard in the appropriate field.

Examples:

"*" would grant access to everything (internally this would be represented 
as "*:*:*", a wildcard for each
"users:*" would grant the user that holds the permission to everything that 
asks for a "users" permission
"users:read" would grant the user read access
"users:write:abcd1234" would grant write access to that specific resource

Roles:

The library also holds an implementation for roles and an easy to use API 
to check if a given user holds a permission or does not.

Roles are really just a container for a set of permissions. In order for 
the library to know which roles exist it has to be initialized with a map 
of roles.
The key is the name of the role, the value is a set of permissions. Such a 
definition could look like:

(def roles {:user/admin "user/*"
            :user/all   #{"user/read" "user/write"}
            :admin/all  "*"
            :company/super #{"company/read" "company/write" "company/edit" 
"company/delete"}
            }


In order to let the library check if a user "has-permission?" or 
"lacks-permission?" it expects a key ":roles" and/ or a key ":permissions" 
(you can override that default) inside the user map.

(def user {:roles #{:user/all :company/super}
           :permissions #{"library/read" "company/gibberish"}
           ... lots of other keys
           }


It would take the roles, flatten them to a list of permissions (through 
that mapping you initialized it with, remember?) and add the individual 
permissions to them.
It would then check if the permission required by the resource the user is 
trying to access is covered by one of the permissions of the user. How you 
handle granted or denied access is totally up to you.

I have used this role based access management in a number of different 
Scala projects (https://github.com/liftmodules/mapperauth, 
https://github.com/eltimn/lift-mongoauth) and found it quiet versatile. 
I'm using it now in a ClojureScript project and thought that might actually 
be a good candidate for a standalone library. Now here it is.

If you're interested in it please have a look at the tests and the code- 
I'm sure there is much room for improvement and interesting ideas I haven't 
thought about.
One thing that especially bugs me is the need to initialize the map of 
existing roles prior to using the library. If you come up with a better way 
I'm eager to hear it.

Please keep in mind that the code is merely a preview at the moment. 
Changes to the API should comes as no surprise.

Thanks,
Torsten.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to