Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Allow :roles to be a function, which will be executed with no args an…

…d assumed to return a collection of roles each time user authorizations are checked.

This allows, e.g., promoting a user to a new role without forcing a logout+login.

Closes #21.
  • Loading branch information...
commit 683bacc2e6e09f6852af668677d06c00b97626b8 1 parent 2bb8807
@lynaghk lynaghk authored
View
2  README.md
@@ -305,7 +305,7 @@ to the application, but two entries are priviliged:
form or HTTP Basic authentication, an oAuth token, etc.; this value
_must_ be unique across all users within the application
* `:roles`, an optional collection of values enumerating the roles for
-which the user is authorized.
+which the user is authorized, or a function returning the same.
_If a map of credentials is found to be invalid, the credential function must
return nil._
View
9 src/cemerick/friend.clj
@@ -248,9 +248,14 @@ Equivalent to (complement current-authentication)."}
"Returns the first value in the :roles of the current authentication
in the given identity map that isa? one of the required roles.
Returns nil otherwise, indicating that the identity is not authorized
- for the set of required roles."
+ for the set of required roles. If :roles is a fn, it will be executed
+ with no args and assumed to return a collection of roles."
[roles identity]
- (let [granted-roles (-> identity current-authentication :roles)]
+ (let [granted-roles (-> identity current-authentication :roles)
+ granted-roles (if (fn? granted-roles)
+ (granted-roles)
+ granted-roles)]
+
(first (for [granted granted-roles
required roles
:when (isa? granted required)]
View
5 test/test_friend/functional.clj
@@ -141,6 +141,11 @@
(check-user-role-access)
(is (= {:roles ["test-friend.mock-app/admin"]} (:body (http/get (url "/echo-roles") {:as :json}))))))
+(deftest admin-login-fn-role
+ (binding [clj-http.core/*cookie-store* (clj-http.cookies/cookie-store)]
+ (http/post (url "/login") {:form-params {:username "root-fn-role" :password "admin_password"}})
+ (check-user-role-access)))
+
(deftest logout-only-on-correct-uri
;; logout middleware was previously being applied eagerly
(binding [clj-http.core/*cookie-store* (clj-http.cookies/cookie-store)]
View
4 test/test_friend/mock_app.clj
@@ -101,6 +101,10 @@
(def users {"root" {:username "root"
:password (creds/hash-bcrypt "admin_password")
:roles #{::admin}}
+
+ "root-fn-role" {:username "root-fn-role"
+ :password (creds/hash-bcrypt "admin_password")
+ :roles (constantly #{::admin})}
"jane" {:username "jane"
:password (creds/hash-bcrypt "user_password")
:roles #{::user}}})
Please sign in to comment.
Something went wrong with that request. Please try again.