>That would only get 64 states into a 64 bit Long, but was always enough.
The bitmask idea is good. I agree there are always tradeoffs. A number is less readable, but more efficient. I would be happy if there was a small library that did just (roles/permissions), and which I could compose with my own auth schemes (because I have often been frustrated with the heaviness of Friend). On Tuesday, October 11, 2016 at 10:16:51 AM UTC-4, Torsten Uhlmann wrote: > > Thanks for the comments! > > @larry I was reminded by your comment at how I used to use bitmasks > before, like @adrian commented. > That would only get 64 states into a 64 bit Long, but was always enough. I > have no performance data on prime number sieves but I suspect that would > take longer than checking set bits of a long. > > Anyway, I was thinking about your suggestion, and there might be away to > integrate such a scheme without totally warping the current implementation. > > So, we would still need a definition of all existing permissions, the one > you initialize the library with at the start of your application. That > receives a map with the role keyword and a single or set of permissions. > > Instead of making the role name a keyword we could also allow a number as > key. That number would then be a number by the power of 2 (if using the > bitmask approach). The value is still one or more permissions. > > The user would then be added inside the :roles key a number like 5, which > would indicate the roles 1 and 4 are given. > If the library detects a number instead of a set of roles it would try to > destructure it against the global role map. > > The same with the resource that asks for the permission- it could have a > permission attached or a number. That number would then map against the > roles the same way destructuring was done for the user. > > I acknowledge that using the number would be limiting compared to using > the list of permission strings (because a set bit would represent one role > and not a single permission)- so it's the users obligation to create a sane > set of roles or to create basically a one-to-one relationship between a > number (a role) and a permission. > > Kind Regards, > Torsten. > > <adrian...@mail.yu.edu <javascript:>> schrieb am Di., 11. Okt. 2016 um > 14:04 Uhr: > >> If you wanted to do something more efficient, why not just use a bitmask? >> That is far more efficient than prime factorization. >> >> >> On Tuesday, October 11, 2016 at 12:06:19 AM UTC-4, larry google groups >> wrote: >>> >>> A minor pet peeve of mine, but is it possible to attach prime numbers to >>> the roles, and to then decipher the roles from the factors of the total? >>> Using strings or keywords for permissions often strikes me as inefficient. >>> Assuming: >>> >>> create -- 2 >>> >>> read -- 3 >>> >>> update -- 5 >>> >>> delete -- 7 >>> >>> bulk-erase -- 11 >>> >>> delete-others -- 13 >>> >>> So given a permissions value of 330, we can factor 330 and find 2, 3, 5 >>> and 11. And it seems more efficient (though less readable) to carry around >>> "330" rather than [:create :read :update :bulk-erase] >>> >>> I would very much like to see a small library that does this for me, >>> rather than always writing this code for myself. >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> On Monday, October 10, 2016 at 6:51:14 AM UTC-4, Torsten Uhlmann wrote: >>>> >>>> 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 clo...@googlegroups.com >> <javascript:> >> Note that posts from new members are moderated - please be patient with >> your first post. >> To unsubscribe from this group, send email to >> clojure+u...@googlegroups.com <javascript:> >> 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+u...@googlegroups.com <javascript:>. >> For more options, visit https://groups.google.com/d/optout. >> > -- 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.