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 



Reply via email to