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
}
}