hi @ all, fyi: we will discuss a thin query layer which supports pagination,... soon. -> imo the security-jpa module should use it.
regards, gerhard 2012/4/25 Boleslaw Dawidowicz <[email protected]> > On Apr 25, 2012, at 12:52 AM, Marek Posolda wrote: > > > > >>> Based on your last mail with subject "[DISCUSS] DELTASPIKE-79 > Authorization API - Identity Model" I assume that best case would be to > cover IdentityType in the API, which will allow possibility to cover > users/groups/roles. So having method like: > >>> > >>> List<Permission> listPermissions(Object resource, Identity String > operation, IdentityType identityType) > >> > >> Actually, this is quite a challenge because we have Role and Group > memberships for users (not to mention that groups can be members of other > groups). So a particular IdentityObject might indirectly inherit > permissions via its memberships, making it tricky for the PermissionStore > to know exactly which permissions should be granted for any single > IdentityObject. My gut feeling is that this complex logic belongs at a > higher level of abstraction, simply because of the limited scope of > PermissionStore/PermissionManager which don't have access to the User/Group > hierarchy needed to make a determination whether the IdentityType is > actually granted a particular Permission. I need some more time to think > on this problem, and if you can describe some use cases that require this > functionality it would be greatly helpful in finding a suitable solution. > > One of the good reasons is performance. If we have only this on > PermissionManager: > > > > listPermissions(Object resource, String action) > > > > without possibility to specify IdentityType as argument (actually I am > omitting query API for simplicity), then we would need to obtain whole list > of Permission objects for this resource and then manually iterating in Java > code through the whole list and check if some permission is appropriate for > current Identity. It seems to be ineffective from the performance > perspective. > > > > I am assuming that IdentityType means only that single object with it's > type (user/group/role). > > > > Example: I have user "john" and he has role "MEMBER" in group "/foo" and > role "MANAGER" in group "/bar". > > I configured in my permission DB, that customer "maryCustomer" can be > READ by members of group "/foo". > > > > In this case: > > listPermission(maryCustomer, "READ", new User("john") - will return false > > listPermission(maryCustomer, "READ", new Role(new Group("/foo"), > "MEMBER") - will return true > > > > Overally user "john" can read object "maryCustomer". But these > permission is granted indirectly to him because he is member of group > "/foo". Permissions are not granted directly to user "john" but to his role > "MEMBER" of group "/foo". > > > > > > > > > > > > Now integration with query API. If we want to obtain all permissions > with single DB query, we may want to add list of IdentityType instead of > single IdentityType. So maybe PermisisonQuery can look like this: > > > > > > public class PermissionQuery > > { > > private final Object resource; > > private final String action; > > private final List<IdentityType> identityTypes; > > > > // snipet > > > > > > } > > > > and possible PersistentPermissionResolver implementation like: > > > > public class PersistentPermissionResolver > > { > > @Inject Identity identity; > > @Inject IdentityManager identityManager; > > > > public boolean hasPermission(Object resource, String action) > > { > > User user = identity.getUser(); > > List<Role> roles = identityManager.getRoles(user); // assuming that > roles of user john will be obtained this way > > > > List<IdentityType> identityTypes = new ArrayList<IdentityType>(); > > > > identityTypes.add(user); > > identityTypes.add(roles); > > > > // In our example case, we have 3 objects in the list. > > // 1) IdentityType representing user "john" > > // 2) Role "MEMBER" of group "/foo" > > // 3) Role "MANAGER" of group "/bar" > > PermissionQuery query = > x.createPermissionQuery().setIdentityTypes(identityTypes).setResource(resource).setAction(action).setRange(0, > 10); > > > > // execute query and return true if some objects are returned > > > > } > > > > } > > > I think it is reaching the point where it would be easier to follow and > discuss some real code prototype on github. > > > On additional note there is different notion of Role between what I > proposed for IDM API and to what Shane and Marek refers too. > > 1) In my case it was (simplified version) > > public interface Role extends IdentityType > { > String getName(); > boolean exists(User user, Group group); > void add(User user, Group group); > Collection<User> getUsers(Group group); > Collection<Group> getGroups(User user); > } > > So Role is a matching between Role name (think RoleType) User and Group > > In Shane's proposal it is just a Name/Group relation. > > public interface Role extends IdentityType > { > Group getGroup(); > String getRoleName(); > } > > And this one makes more sense in context of Permissions like in code > snippets presented by Marek: > > listPermission(maryCustomer, "READ", new Role(new Group("/foo"), "MEMBER") > > where permission will be indirectly granted to all users with such role. > > Other way is to keep what Shane proposed and then use altered Membership > interface that I initially proposed as just a helper to do queries. > > public interface Membership > { > User getUser(); > Role getRole(); > } > > Or to avoid confusion use different interface in authorization API like: > > listPermission(maryCustomer, "READ", new RoleMatch(new Group("/foo"), > "MEMBER") > > Still I think we are hitting a point where we start to discuss 2 more > complex APIs that overlap and it would be better to try put more consistent > prototype on github to discuss. > > Bolek > > > >
