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

  }

}


Reply via email to