You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@deltaspike.apache.org by Shane Bryzak <sb...@redhat.com> on 2012/04/23 11:56:05 UTC

[DISCUSS] DELTASPIKE-79 Authorization API - Permission Management and ACLs

Following up to the recent outline of object permissions, I'd like to 
continue with a description of the permission management API.

At the centre of this API is the PermissionManager bean.  This bean 
provides all of the operations required to grant, deny and query object 
permissions.  Here's a description of the methods:

List<Permission> listPermissions(Object resource, String operation)

Returns a List of all the Permissions that have been granted for the 
specified resource and operation.

List<Permission> listPermissions(Object resource)

Returns a List of all the Permissions that have been granted for the 
specified resource

boolean grantPermission(Permission permission)

Grants the specified permission, returns true if successful.

boolean grantPermissions(List<Permission> permissions)

Grants all the permissions contained in the specified List, returns true 
if successful.

boolean revokePermission(Permission permission)

Revokes the specified permission, returns true if successful.

boolean revokePermissions(List<Permission> permissions)

Revokes the specified permissions, returns true if successful.

List<String> listAvailableOperations(Object resource)

Returns a list containing all the known allowed operations for the 
specified resource.

Each of these methods in turn will invoke a permission check to ensure 
that the current user has permission to invoke that particular 
permission management operation.

Behind the scenes, the PermissionManager uses a PermissionStore to do 
the actual work.  The PermissionStore interface is practically identical 
to the PermissionManager interface, in face we can possibly just have it 
extend it.  DeltaSpike should provide one PermissionStore implementation 
out of the box, JpaPermissionStore which allows the user to store their 
permissions in a database table.  We can use annotations to configure 
the entity that is used to store permissions:


@Entity
public class ObjectPermission
{
     private Long permissionId;
     @PermissionRecipient private String recipient;
     @PermissionResourceIdentifier private String resourceId;
     @PermissionOperation private String operation;
     @PermissionDiscriminator private String discriminator;
}

It should also be possible to use multiple tables to store permissions.  
Take for example the use case where a user might wish to query a table 
based on assigned permissions:

SELECT
   C.*
FROM
   CUSTOMER C,
   CUSTOMER_PERMISSION CP
WHERE
   C.CUSTOMER_ID = CP.CUSTOMER_ID
   AND CP.OPERATION CONTAINS '%READ%';


Re: [DISCUSS] DELTASPIKE-79 Authorization API - Permission Management and ACLs

Posted by Boleslaw Dawidowicz <bo...@gmail.com>.
On Apr 24, 2012, at 3:17 PM, Boleslaw Dawidowicz wrote:

> 
> On Apr 24, 2012, at 2:59 PM, Marek Posolda wrote:
> 
>> On 24.4.2012 14:41, Shane Bryzak wrote:
>>> On 24/04/12 18:56, Marek Posolda wrote:
>>>> Hi Shane,
>>>> 
>>>> If I understand correctly this PermissionManager would be used by PersistentPermissionResolver, which will be the default PermissionResolver implementation? As it will be good if people have flexibility to implement their own PermissionResolver and use some completely different security framework of their own, if they need it.
>>>> 
>>>> Some feedback for the PermissionManager itself:
>>>> 1) I think we should provide also methods for dealing with ResourceIdentifier case? So we should have also methods like:
>>>> List<Permission> listPermissions(ResourceIdentifier resource, String operation)
>>>> List<Permission> listPermissions(ResourceIdentifier resource)
>>>> etc.
>>> 
>>> Good point, we probably have to add these methods also.
>>>> 
>>>> 2) How about cover user identity in the API? For example: I want to know that user "john" has permission to READ customer "Mary Kelly". With current API I would need to call: listPermissions(maryKellyCustomer, "READ") and then iterate through all the Permission objects from result list and see if they are applicable for John. It does not seem to be good from usability and performance perspective.
>>>> 
>>>> So I guess we need also methods like:
>>>> List<Permission> listPermissions(Object resource, Identity String operation, User user)
>>>> 
>>>> When more thinking about it, I think the recipient of the Permission can be single user or also group? And IMO we should also think about roles to have things more complicated :)
>>>> 
>>>> So you can easily ask PermissionManager for questions like: Has "MANAGER" of group "PowerUsers" permissions to "READ" customer "Mary Kelly" ? This may be fine with method like:
>>>> 
>>>> List<Permission> listPermissions(Object resource, Identity String operation, String identityId, String identityType, String roleType);
>>>> 
>>>> Maybe instead of using Strings as last 3 arguments, we can encapsulate all recipient informations into single object.
>>>> 
>>>> WDYT?
>>>> 
>>>> 
>>>> 
>>>> 3) Another potentially missing thing is pagination. I assume that we can have thousands of users in DB and thousands of resource objects, which in next turn means that you can have millions of permissions. In large environments, invoking of PermissionManager.listPermissions(Object resource, String operation) could return like 10.000 records. So counting with this case and provide additional methods for pagination support may be good IMO. Something like:
>>>> 
>>>> List<Permission> listPermissions(Object resource, Identity String operation, int offset, int pageSize);
>>> 
>>> In response to both 2) and 3), I've been thinking quite a lot about how we retrieve permissions from the database, and yes when there are thousands or millions of records it would be useful to support some kind of pagination.  The idea that appeals to me the most would be to implement a Query API similar to what Bolek has proposed for IDM, except for permissions.  This would allow us much greater flexibility and allow us to support pagination, etc.
>> I agree that Query API would be definitely more flexible. I've introduced some code snippets with possibilities how can Query API look like in my previous mail. You can take a look in case that you missed it. Nothing final, just some possibilities how to proceed.
>> 
> 
> I think something aligned with my IDM proposal would look like this:
> 
> public interface PermissionQuery
> {
> 
>  // Operations
> 
>  PermissionQuery reset();
> 
>  PermissionQuery getImmutable();
> 
>  List<Permission> executeQuery();
> 
>  // Conditions
> 
>  PermissionQuery setIdentityType(IdentityType it);
>  
>  IdentityType getIdentityType();
> 
>  PermissionQuery setIdentityTypeKey(String key)
> 
>  String getIdentityTypeKey()
> 
>  PermissionQuery setResource(Object resource);
> 
>  Object getResource();
> 
>  PermissionQuery setResourceIdentifier(ResourceIdentifier resource);
>  
>  ResourceIdentifier getResourceIdentifier();
> 
>  PermissionQuery setOperation(String op);
> 
>  String getOperation();
>  
>  
>  RoleQuery sortByIdentityType(boolean ascending);
> 
>  RoleQuery sortByResource(boolean ascending);
> 
>  void setRange(Range range);
> 
>  Range getRange();
> 
> }
> 
> (not sure if sorting makes sense here) 
> 
> Usage like:
> 
> PermissionQuery x.createPermissionQuery().setIdentityType(it).setResource(res).setOperation("READ").setRange(0,10);
> 
> x.execute();
> x.getRange().next().execute(); 


Actually wrote it wrong:

PermissionQuery query = x.createPermissionQuery().setIdentityType(it).setResource(res).setOperation("READ").setRange(0,10);

query.execute();
query.getRange().next().execute();

> 
> 
> 
> 
> 
>> 
>>> 
>>>> 
>>>> Thanks,
>>>> Marek
>>>> 
>>>> On 23.4.2012 11:56, Shane Bryzak wrote:
>>>>> Following up to the recent outline of object permissions, I'd like to continue with a description of the permission management API.
>>>>> 
>>>>> At the centre of this API is the PermissionManager bean.  This bean provides all of the operations required to grant, deny and query object permissions.  Here's a description of the methods:
>>>>> 
>>>>> List<Permission> listPermissions(Object resource, String operation)
>>>>> 
>>>>> Returns a List of all the Permissions that have been granted for the specified resource and operation.
>>>>> 
>>>>> List<Permission> listPermissions(Object resource)
>>>>> 
>>>>> Returns a List of all the Permissions that have been granted for the specified resource
>>>>> 
>>>>> boolean grantPermission(Permission permission)
>>>>> 
>>>>> Grants the specified permission, returns true if successful.
>>>>> 
>>>>> boolean grantPermissions(List<Permission> permissions)
>>>>> 
>>>>> Grants all the permissions contained in the specified List, returns true if successful.
>>>>> 
>>>>> boolean revokePermission(Permission permission)
>>>>> 
>>>>> Revokes the specified permission, returns true if successful.
>>>>> 
>>>>> boolean revokePermissions(List<Permission> permissions)
>>>>> 
>>>>> Revokes the specified permissions, returns true if successful.
>>>>> 
>>>>> List<String> listAvailableOperations(Object resource)
>>>>> 
>>>>> Returns a list containing all the known allowed operations for the specified resource.
>>>>> 
>>>>> Each of these methods in turn will invoke a permission check to ensure that the current user has permission to invoke that particular permission management operation.
>>>>> 
>>>>> Behind the scenes, the PermissionManager uses a PermissionStore to do the actual work.  The PermissionStore interface is practically identical to the PermissionManager interface, in face we can possibly just have it extend it.  DeltaSpike should provide one PermissionStore implementation out of the box, JpaPermissionStore which allows the user to store their permissions in a database table.  We can use annotations to configure the entity that is used to store permissions:
>>>>> 
>>>>> 
>>>>> @Entity
>>>>> public class ObjectPermission
>>>>> {
>>>>>    private Long permissionId;
>>>>>    @PermissionRecipient private String recipient;
>>>>>    @PermissionResourceIdentifier private String resourceId;
>>>>>    @PermissionOperation private String operation;
>>>>>    @PermissionDiscriminator private String discriminator;
>>>>> }
>>>>> 
>>>>> It should also be possible to use multiple tables to store permissions.  Take for example the use case where a user might wish to query a table based on assigned permissions:
>>>>> 
>>>>> SELECT
>>>>>  C.*
>>>>> FROM
>>>>>  CUSTOMER C,
>>>>>  CUSTOMER_PERMISSION CP
>>>>> WHERE
>>>>>  C.CUSTOMER_ID = CP.CUSTOMER_ID
>>>>>  AND CP.OPERATION CONTAINS '%READ%';
>>>>> 
>>>>> 
>>>> 
>>> 
>>> 
>> 
> 


Re: [DISCUSS] DELTASPIKE-79 Authorization API - Permission Management and ACLs

Posted by Boleslaw Dawidowicz <bo...@gmail.com>.
On Apr 24, 2012, at 2:59 PM, Marek Posolda wrote:

> On 24.4.2012 14:41, Shane Bryzak wrote:
>> On 24/04/12 18:56, Marek Posolda wrote:
>>> Hi Shane,
>>> 
>>> If I understand correctly this PermissionManager would be used by PersistentPermissionResolver, which will be the default PermissionResolver implementation? As it will be good if people have flexibility to implement their own PermissionResolver and use some completely different security framework of their own, if they need it.
>>> 
>>> Some feedback for the PermissionManager itself:
>>> 1) I think we should provide also methods for dealing with ResourceIdentifier case? So we should have also methods like:
>>> List<Permission> listPermissions(ResourceIdentifier resource, String operation)
>>> List<Permission> listPermissions(ResourceIdentifier resource)
>>> etc.
>> 
>> Good point, we probably have to add these methods also.
>>> 
>>> 2) How about cover user identity in the API? For example: I want to know that user "john" has permission to READ customer "Mary Kelly". With current API I would need to call: listPermissions(maryKellyCustomer, "READ") and then iterate through all the Permission objects from result list and see if they are applicable for John. It does not seem to be good from usability and performance perspective.
>>> 
>>> So I guess we need also methods like:
>>> List<Permission> listPermissions(Object resource, Identity String operation, User user)
>>> 
>>> When more thinking about it, I think the recipient of the Permission can be single user or also group? And IMO we should also think about roles to have things more complicated :)
>>> 
>>> So you can easily ask PermissionManager for questions like: Has "MANAGER" of group "PowerUsers" permissions to "READ" customer "Mary Kelly" ? This may be fine with method like:
>>> 
>>> List<Permission> listPermissions(Object resource, Identity String operation, String identityId, String identityType, String roleType);
>>> 
>>> Maybe instead of using Strings as last 3 arguments, we can encapsulate all recipient informations into single object.
>>> 
>>> WDYT?
>>> 
>>> 
>>> 
>>> 3) Another potentially missing thing is pagination. I assume that we can have thousands of users in DB and thousands of resource objects, which in next turn means that you can have millions of permissions. In large environments, invoking of PermissionManager.listPermissions(Object resource, String operation) could return like 10.000 records. So counting with this case and provide additional methods for pagination support may be good IMO. Something like:
>>> 
>>> List<Permission> listPermissions(Object resource, Identity String operation, int offset, int pageSize);
>> 
>> In response to both 2) and 3), I've been thinking quite a lot about how we retrieve permissions from the database, and yes when there are thousands or millions of records it would be useful to support some kind of pagination.  The idea that appeals to me the most would be to implement a Query API similar to what Bolek has proposed for IDM, except for permissions.  This would allow us much greater flexibility and allow us to support pagination, etc.
> I agree that Query API would be definitely more flexible. I've introduced some code snippets with possibilities how can Query API look like in my previous mail. You can take a look in case that you missed it. Nothing final, just some possibilities how to proceed.
> 

I think something aligned with my IDM proposal would look like this:

public interface PermissionQuery
{

 // Operations

 PermissionQuery reset();

 PermissionQuery getImmutable();

 List<Permission> executeQuery();

 // Conditions

 PermissionQuery setIdentityType(IdentityType it);
 
 IdentityType getIdentityType();

 PermissionQuery setIdentityTypeKey(String key)

 String getIdentityTypeKey()

 PermissionQuery setResource(Object resource);

 Object getResource();

 PermissionQuery setResourceIdentifier(ResourceIdentifier resource);
 
 ResourceIdentifier getResourceIdentifier();

 PermissionQuery setOperation(String op);

 String getOperation();
 
 
 RoleQuery sortByIdentityType(boolean ascending);

 RoleQuery sortByResource(boolean ascending);

 void setRange(Range range);

 Range getRange();

}

(not sure if sorting makes sense here) 

Usage like:

PermissionQuery x.createPermissionQuery().setIdentityType(it).setResource(res).setOperation("READ").setRange(0,10);

x.execute();
x.getRange().next().execute(); 





> 
>> 
>>> 
>>> Thanks,
>>> Marek
>>> 
>>> On 23.4.2012 11:56, Shane Bryzak wrote:
>>>> Following up to the recent outline of object permissions, I'd like to continue with a description of the permission management API.
>>>> 
>>>> At the centre of this API is the PermissionManager bean.  This bean provides all of the operations required to grant, deny and query object permissions.  Here's a description of the methods:
>>>> 
>>>> List<Permission> listPermissions(Object resource, String operation)
>>>> 
>>>> Returns a List of all the Permissions that have been granted for the specified resource and operation.
>>>> 
>>>> List<Permission> listPermissions(Object resource)
>>>> 
>>>> Returns a List of all the Permissions that have been granted for the specified resource
>>>> 
>>>> boolean grantPermission(Permission permission)
>>>> 
>>>> Grants the specified permission, returns true if successful.
>>>> 
>>>> boolean grantPermissions(List<Permission> permissions)
>>>> 
>>>> Grants all the permissions contained in the specified List, returns true if successful.
>>>> 
>>>> boolean revokePermission(Permission permission)
>>>> 
>>>> Revokes the specified permission, returns true if successful.
>>>> 
>>>> boolean revokePermissions(List<Permission> permissions)
>>>> 
>>>> Revokes the specified permissions, returns true if successful.
>>>> 
>>>> List<String> listAvailableOperations(Object resource)
>>>> 
>>>> Returns a list containing all the known allowed operations for the specified resource.
>>>> 
>>>> Each of these methods in turn will invoke a permission check to ensure that the current user has permission to invoke that particular permission management operation.
>>>> 
>>>> Behind the scenes, the PermissionManager uses a PermissionStore to do the actual work.  The PermissionStore interface is practically identical to the PermissionManager interface, in face we can possibly just have it extend it.  DeltaSpike should provide one PermissionStore implementation out of the box, JpaPermissionStore which allows the user to store their permissions in a database table.  We can use annotations to configure the entity that is used to store permissions:
>>>> 
>>>> 
>>>> @Entity
>>>> public class ObjectPermission
>>>> {
>>>>    private Long permissionId;
>>>>    @PermissionRecipient private String recipient;
>>>>    @PermissionResourceIdentifier private String resourceId;
>>>>    @PermissionOperation private String operation;
>>>>    @PermissionDiscriminator private String discriminator;
>>>> }
>>>> 
>>>> It should also be possible to use multiple tables to store permissions.  Take for example the use case where a user might wish to query a table based on assigned permissions:
>>>> 
>>>> SELECT
>>>>  C.*
>>>> FROM
>>>>  CUSTOMER C,
>>>>  CUSTOMER_PERMISSION CP
>>>> WHERE
>>>>  C.CUSTOMER_ID = CP.CUSTOMER_ID
>>>>  AND CP.OPERATION CONTAINS '%READ%';
>>>> 
>>>> 
>>> 
>> 
>> 
> 


Re: [DISCUSS] DELTASPIKE-79 Authorization API - Permission Management and ACLs

Posted by Marek Posolda <mp...@redhat.com>.
On 24.4.2012 14:41, Shane Bryzak wrote:
> On 24/04/12 18:56, Marek Posolda wrote:
>> Hi Shane,
>>
>> If I understand correctly this PermissionManager would be used by 
>> PersistentPermissionResolver, which will be the default 
>> PermissionResolver implementation? As it will be good if people have 
>> flexibility to implement their own PermissionResolver and use some 
>> completely different security framework of their own, if they need it.
>>
>> Some feedback for the PermissionManager itself:
>> 1) I think we should provide also methods for dealing with 
>> ResourceIdentifier case? So we should have also methods like:
>> List<Permission> listPermissions(ResourceIdentifier resource, String 
>> operation)
>> List<Permission> listPermissions(ResourceIdentifier resource)
>> etc.
>
> Good point, we probably have to add these methods also.
>>
>> 2) How about cover user identity in the API? For example: I want to 
>> know that user "john" has permission to READ customer "Mary Kelly". 
>> With current API I would need to call: 
>> listPermissions(maryKellyCustomer, "READ") and then iterate through 
>> all the Permission objects from result list and see if they are 
>> applicable for John. It does not seem to be good from usability and 
>> performance perspective.
>>
>> So I guess we need also methods like:
>> List<Permission> listPermissions(Object resource, Identity String 
>> operation, User user)
>>
>> When more thinking about it, I think the recipient of the Permission 
>> can be single user or also group? And IMO we should also think about 
>> roles to have things more complicated :)
>>
>> So you can easily ask PermissionManager for questions like: Has 
>> "MANAGER" of group "PowerUsers" permissions to "READ" customer "Mary 
>> Kelly" ? This may be fine with method like:
>>
>> List<Permission> listPermissions(Object resource, Identity String 
>> operation, String identityId, String identityType, String roleType);
>>
>> Maybe instead of using Strings as last 3 arguments, we can 
>> encapsulate all recipient informations into single object.
>>
>> WDYT?
>>
>>
>>
>> 3) Another potentially missing thing is pagination. I assume that we 
>> can have thousands of users in DB and thousands of resource objects, 
>> which in next turn means that you can have millions of permissions. 
>> In large environments, invoking of 
>> PermissionManager.listPermissions(Object resource, String operation) 
>> could return like 10.000 records. So counting with this case and 
>> provide additional methods for pagination support may be good IMO. 
>> Something like:
>>
>> List<Permission> listPermissions(Object resource, Identity String 
>> operation, int offset, int pageSize);
>
> In response to both 2) and 3), I've been thinking quite a lot about 
> how we retrieve permissions from the database, and yes when there are 
> thousands or millions of records it would be useful to support some 
> kind of pagination.  The idea that appeals to me the most would be to 
> implement a Query API similar to what Bolek has proposed for IDM, 
> except for permissions.  This would allow us much greater flexibility 
> and allow us to support pagination, etc.
I agree that Query API would be definitely more flexible. I've 
introduced some code snippets with possibilities how can Query API look 
like in my previous mail. You can take a look in case that you missed 
it. Nothing final, just some possibilities how to proceed.


>
>>
>> Thanks,
>> Marek
>>
>> On 23.4.2012 11:56, Shane Bryzak wrote:
>>> Following up to the recent outline of object permissions, I'd like 
>>> to continue with a description of the permission management API.
>>>
>>> At the centre of this API is the PermissionManager bean.  This bean 
>>> provides all of the operations required to grant, deny and query 
>>> object permissions.  Here's a description of the methods:
>>>
>>> List<Permission> listPermissions(Object resource, String operation)
>>>
>>> Returns a List of all the Permissions that have been granted for the 
>>> specified resource and operation.
>>>
>>> List<Permission> listPermissions(Object resource)
>>>
>>> Returns a List of all the Permissions that have been granted for the 
>>> specified resource
>>>
>>> boolean grantPermission(Permission permission)
>>>
>>> Grants the specified permission, returns true if successful.
>>>
>>> boolean grantPermissions(List<Permission> permissions)
>>>
>>> Grants all the permissions contained in the specified List, returns 
>>> true if successful.
>>>
>>> boolean revokePermission(Permission permission)
>>>
>>> Revokes the specified permission, returns true if successful.
>>>
>>> boolean revokePermissions(List<Permission> permissions)
>>>
>>> Revokes the specified permissions, returns true if successful.
>>>
>>> List<String> listAvailableOperations(Object resource)
>>>
>>> Returns a list containing all the known allowed operations for the 
>>> specified resource.
>>>
>>> Each of these methods in turn will invoke a permission check to 
>>> ensure that the current user has permission to invoke that 
>>> particular permission management operation.
>>>
>>> Behind the scenes, the PermissionManager uses a PermissionStore to 
>>> do the actual work.  The PermissionStore interface is practically 
>>> identical to the PermissionManager interface, in face we can 
>>> possibly just have it extend it.  DeltaSpike should provide one 
>>> PermissionStore implementation out of the box, JpaPermissionStore 
>>> which allows the user to store their permissions in a database 
>>> table.  We can use annotations to configure the entity that is used 
>>> to store permissions:
>>>
>>>
>>> @Entity
>>> public class ObjectPermission
>>> {
>>>     private Long permissionId;
>>>     @PermissionRecipient private String recipient;
>>>     @PermissionResourceIdentifier private String resourceId;
>>>     @PermissionOperation private String operation;
>>>     @PermissionDiscriminator private String discriminator;
>>> }
>>>
>>> It should also be possible to use multiple tables to store 
>>> permissions.  Take for example the use case where a user might wish 
>>> to query a table based on assigned permissions:
>>>
>>> SELECT
>>>   C.*
>>> FROM
>>>   CUSTOMER C,
>>>   CUSTOMER_PERMISSION CP
>>> WHERE
>>>   C.CUSTOMER_ID = CP.CUSTOMER_ID
>>>   AND CP.OPERATION CONTAINS '%READ%';
>>>
>>>
>>
>
>


Re: [DISCUSS] DELTASPIKE-79 Authorization API - Permission Management and ACLs

Posted by Boleslaw Dawidowicz <bo...@gmail.com>.
On Apr 24, 2012, at 2:41 PM, Shane Bryzak wrote:

>> 
>> 2) How about cover user identity in the API? For example: I want to know that user "john" has permission to READ customer "Mary Kelly". With current API I would need to call: listPermissions(maryKellyCustomer, "READ") and then iterate through all the Permission objects from result list and see if they are applicable for John. It does not seem to be good from usability and performance perspective.
>> 
>> So I guess we need also methods like:
>> List<Permission> listPermissions(Object resource, Identity String operation, User user)
>> 
>> When more thinking about it, I think the recipient of the Permission can be single user or also group? And IMO we should also think about roles to have things more complicated :)
>> 
>> So you can easily ask PermissionManager for questions like: Has "MANAGER" of group "PowerUsers" permissions to "READ" customer "Mary Kelly" ? This may be fine with method like:
>> 
>> List<Permission> listPermissions(Object resource, Identity String operation, String identityId, String identityType, String roleType);
>> 
>> Maybe instead of using Strings as last 3 arguments, we can encapsulate all recipient informations into single object.
>> 
>> WDYT?
>> 
>> 
>> 
>> 3) Another potentially missing thing is pagination. I assume that we can have thousands of users in DB and thousands of resource objects, which in next turn means that you can have millions of permissions. In large environments, invoking of PermissionManager.listPermissions(Object resource, String operation) could return like 10.000 records. So counting with this case and provide additional methods for pagination support may be good IMO. Something like:
>> 
>> List<Permission> listPermissions(Object resource, Identity String operation, int offset, int pageSize);
> 
> In response to both 2) and 3), I've been thinking quite a lot about how we retrieve permissions from the database, and yes when there are thousands or millions of records it would be useful to support some kind of pagination.  The idea that appeals to me the most would be to implement a Query API similar to what Bolek has proposed for IDM, except for permissions.  This would allow us much greater flexibility and allow us to support pagination, etc.
> 

I was actually about to reply in similar way. Would be good to keep consistent pattern around pagination. Not forcing my design here but whatever we choose it is best to have similar Query API for both IDM and Permission. 

>> 
>> Thanks,
>> Marek
>> 
>> On 23.4.2012 11:56, Shane Bryzak wrote:
>>> Following up to the recent outline of object permissions, I'd like to continue with a description of the permission management API.
>>> 
>>> At the centre of this API is the PermissionManager bean.  This bean provides all of the operations required to grant, deny and query object permissions.  Here's a description of the methods:
>>> 
>>> List<Permission> listPermissions(Object resource, String operation)
>>> 
>>> Returns a List of all the Permissions that have been granted for the specified resource and operation.
>>> 
>>> List<Permission> listPermissions(Object resource)
>>> 
>>> Returns a List of all the Permissions that have been granted for the specified resource
>>> 
>>> boolean grantPermission(Permission permission)
>>> 
>>> Grants the specified permission, returns true if successful.
>>> 
>>> boolean grantPermissions(List<Permission> permissions)
>>> 
>>> Grants all the permissions contained in the specified List, returns true if successful.
>>> 
>>> boolean revokePermission(Permission permission)
>>> 
>>> Revokes the specified permission, returns true if successful.
>>> 
>>> boolean revokePermissions(List<Permission> permissions)
>>> 
>>> Revokes the specified permissions, returns true if successful.
>>> 
>>> List<String> listAvailableOperations(Object resource)
>>> 
>>> Returns a list containing all the known allowed operations for the specified resource.
>>> 
>>> Each of these methods in turn will invoke a permission check to ensure that the current user has permission to invoke that particular permission management operation.
>>> 
>>> Behind the scenes, the PermissionManager uses a PermissionStore to do the actual work.  The PermissionStore interface is practically identical to the PermissionManager interface, in face we can possibly just have it extend it.  DeltaSpike should provide one PermissionStore implementation out of the box, JpaPermissionStore which allows the user to store their permissions in a database table.  We can use annotations to configure the entity that is used to store permissions:
>>> 
>>> 
>>> @Entity
>>> public class ObjectPermission
>>> {
>>>    private Long permissionId;
>>>    @PermissionRecipient private String recipient;
>>>    @PermissionResourceIdentifier private String resourceId;
>>>    @PermissionOperation private String operation;
>>>    @PermissionDiscriminator private String discriminator;
>>> }
>>> 
>>> It should also be possible to use multiple tables to store permissions.  Take for example the use case where a user might wish to query a table based on assigned permissions:
>>> 
>>> SELECT
>>>  C.*
>>> FROM
>>>  CUSTOMER C,
>>>  CUSTOMER_PERMISSION CP
>>> WHERE
>>>  C.CUSTOMER_ID = CP.CUSTOMER_ID
>>>  AND CP.OPERATION CONTAINS '%READ%';
>>> 
>>> 
>> 
> 


Re: [DISCUSS] DELTASPIKE-79 Authorization API - Permission Management and ACLs

Posted by Shane Bryzak <sb...@redhat.com>.
On 24/04/12 18:56, Marek Posolda wrote:
> Hi Shane,
>
> If I understand correctly this PermissionManager would be used by 
> PersistentPermissionResolver, which will be the default 
> PermissionResolver implementation? As it will be good if people have 
> flexibility to implement their own PermissionResolver and use some 
> completely different security framework of their own, if they need it.
>
> Some feedback for the PermissionManager itself:
> 1) I think we should provide also methods for dealing with 
> ResourceIdentifier case? So we should have also methods like:
> List<Permission> listPermissions(ResourceIdentifier resource, String 
> operation)
> List<Permission> listPermissions(ResourceIdentifier resource)
> etc.

Good point, we probably have to add these methods also.
>
> 2) How about cover user identity in the API? For example: I want to 
> know that user "john" has permission to READ customer "Mary Kelly". 
> With current API I would need to call: 
> listPermissions(maryKellyCustomer, "READ") and then iterate through 
> all the Permission objects from result list and see if they are 
> applicable for John. It does not seem to be good from usability and 
> performance perspective.
>
> So I guess we need also methods like:
> List<Permission> listPermissions(Object resource, Identity String 
> operation, User user)
>
> When more thinking about it, I think the recipient of the Permission 
> can be single user or also group? And IMO we should also think about 
> roles to have things more complicated :)
>
> So you can easily ask PermissionManager for questions like: Has 
> "MANAGER" of group "PowerUsers" permissions to "READ" customer "Mary 
> Kelly" ? This may be fine with method like:
>
> List<Permission> listPermissions(Object resource, Identity String 
> operation, String identityId, String identityType, String roleType);
>
> Maybe instead of using Strings as last 3 arguments, we can encapsulate 
> all recipient informations into single object.
>
> WDYT?
>
>
>
> 3) Another potentially missing thing is pagination. I assume that we 
> can have thousands of users in DB and thousands of resource objects, 
> which in next turn means that you can have millions of permissions. In 
> large environments, invoking of 
> PermissionManager.listPermissions(Object resource, String operation) 
> could return like 10.000 records. So counting with this case and 
> provide additional methods for pagination support may be good IMO. 
> Something like:
>
> List<Permission> listPermissions(Object resource, Identity String 
> operation, int offset, int pageSize);

In response to both 2) and 3), I've been thinking quite a lot about how 
we retrieve permissions from the database, and yes when there are 
thousands or millions of records it would be useful to support some kind 
of pagination.  The idea that appeals to me the most would be to 
implement a Query API similar to what Bolek has proposed for IDM, except 
for permissions.  This would allow us much greater flexibility and allow 
us to support pagination, etc.

>
> Thanks,
> Marek
>
> On 23.4.2012 11:56, Shane Bryzak wrote:
>> Following up to the recent outline of object permissions, I'd like to 
>> continue with a description of the permission management API.
>>
>> At the centre of this API is the PermissionManager bean.  This bean 
>> provides all of the operations required to grant, deny and query 
>> object permissions.  Here's a description of the methods:
>>
>> List<Permission> listPermissions(Object resource, String operation)
>>
>> Returns a List of all the Permissions that have been granted for the 
>> specified resource and operation.
>>
>> List<Permission> listPermissions(Object resource)
>>
>> Returns a List of all the Permissions that have been granted for the 
>> specified resource
>>
>> boolean grantPermission(Permission permission)
>>
>> Grants the specified permission, returns true if successful.
>>
>> boolean grantPermissions(List<Permission> permissions)
>>
>> Grants all the permissions contained in the specified List, returns 
>> true if successful.
>>
>> boolean revokePermission(Permission permission)
>>
>> Revokes the specified permission, returns true if successful.
>>
>> boolean revokePermissions(List<Permission> permissions)
>>
>> Revokes the specified permissions, returns true if successful.
>>
>> List<String> listAvailableOperations(Object resource)
>>
>> Returns a list containing all the known allowed operations for the 
>> specified resource.
>>
>> Each of these methods in turn will invoke a permission check to 
>> ensure that the current user has permission to invoke that particular 
>> permission management operation.
>>
>> Behind the scenes, the PermissionManager uses a PermissionStore to do 
>> the actual work.  The PermissionStore interface is practically 
>> identical to the PermissionManager interface, in face we can possibly 
>> just have it extend it.  DeltaSpike should provide one 
>> PermissionStore implementation out of the box, JpaPermissionStore 
>> which allows the user to store their permissions in a database 
>> table.  We can use annotations to configure the entity that is used 
>> to store permissions:
>>
>>
>> @Entity
>> public class ObjectPermission
>> {
>>     private Long permissionId;
>>     @PermissionRecipient private String recipient;
>>     @PermissionResourceIdentifier private String resourceId;
>>     @PermissionOperation private String operation;
>>     @PermissionDiscriminator private String discriminator;
>> }
>>
>> It should also be possible to use multiple tables to store 
>> permissions.  Take for example the use case where a user might wish 
>> to query a table based on assigned permissions:
>>
>> SELECT
>>   C.*
>> FROM
>>   CUSTOMER C,
>>   CUSTOMER_PERMISSION CP
>> WHERE
>>   C.CUSTOMER_ID = CP.CUSTOMER_ID
>>   AND CP.OPERATION CONTAINS '%READ%';
>>
>>
>


Re: [DISCUSS] DELTASPIKE-79 Authorization API - Permission Management and ACLs

Posted by Shane Bryzak <sb...@redhat.com>.
On 24/04/12 20:19, Marek Posolda wrote:
> On 24.4.2012 11:17, Boleslaw Dawidowicz wrote:
>> On Apr 24, 2012, at 10:56 AM, Marek Posolda wrote:
>>> 3) Another potentially missing thing is pagination. I assume that we 
>>> can have thousands of users in DB and thousands of resource objects, 
>>> which in next turn means that you can have millions of permissions. 
>>> In large environments, invoking of 
>>> PermissionManager.listPermissions(Object resource, String operation) 
>>> could return like 10.000 records. So counting with this case and 
>>> provide additional methods for pagination support may be good IMO. 
>>> Something like:
>>>
>>> List<Permission>  listPermissions(Object resource, Identity String 
>>> operation, int offset, int pageSize);
>>>
>> For pagination I propose using something like Range object
>>
>> https://github.com/bdaw/DeltaSpikeMirror/blob/fc7752409f289b6dfbd577292b70a786a4fb62f4/deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/api/idm/Range.java 
>>
>>
>> List<Permission>  listPermissions(Object resource, Identity String 
>> operation, Range range);
>>
>> with usage like:
>>
>> listPermissions(customerRecord, READ, Range.of(10,20));
>>
>> or
>>
>> Range page = new Range(0, 10);
>> x.listPermissions(customerRecord, READ, page.next());
> yes, slightly better and more flexible than using only "int offset, 
> int pageSize".
>
> Maybe instead of providing more overloaded "listPermissions" methods 
> with different signatures, we can think about using query API and 
> create concept of PermissionQuery?
> So on PermissionManager having single method:
>
> List<Permission> listPermissions(PermissionQuery query);
>
>
>
> and having
>
> public interface PermissionQuery
> {
>    private final IdentityType;
>    private final String operation;
>    private final Object resource;
>    private final ResourceIdentifier resourceIdentifier;
>
>    private Range range;
>    private int countOfObjects = -1;
>
>    public PermissionQuery(IdentityType idType, String operation, 
> Object resource, ResourceIdentifier resourceIdentifier, Range range)
>    {
>        // snipet
>    }
>
>    public void setRange()
>    {
>        this.range = range;
>    }
>
>    public void nextPage()
>    {
>        range.next();
>    }
>
>    public boolean hasAvailableResultsOnCurrentPage()
>    {
>       if (countOfObjects == -1)
>       {
>           // compute total count of poermission objects from DB
>       }
>
>        return range.getLimit() < countOfObjects;
>    }
>
>    // getters
>
> }
>
>
>
> Now I want to obtain all available actions of user John for resource  
> object "maryCustomer":
>
> PermissionQuery permissionQuery = new PermissionQuery(new 
> User("john"), null, maryCustomer,null, Range.of(0,10));
>
> while (permissionQuery.hasAvailableResultsOnCurrentPage())
> {
>      List<Permission> currentPage = 
> permissionManager.listPermissions(permissionQuery);
>
>      // Do something with results
>      permissionQuery.nextPage();
> }
>
>
>
>
> I am not sure if methods related to pagination should be covered 
> directly in PermissionQuery as it won't be immutable then and method 
> hasAvailableResultsOnCurrentPage() will need to access DB to compute 
> total number of available results. Maybe we can have two separate 
> methods on PermissionManager. One for case without pagination and 
> second with pagination. And for pagination case, we will probably need 
> to count total number of results:
>
> List<Permission> listPermissions(PermissionQuery query);
> List<Permission> listPermissions(PermissionQuery query, Range page);
> int getPermissionsCount(PermissionQuery);
>
> WDYT?

Ah, I sent my previous response before I read this - yes, I think we're 
on the same wavelength here and a Query API for Permissions is a great 
idea.  +1.

>
> Marek
>
>> Bolek
>>
>>
>>
>>
>


Re: [DISCUSS] DELTASPIKE-79 Authorization API - Permission Management and ACLs

Posted by Marek Posolda <mp...@redhat.com>.
On 24.4.2012 11:17, Boleslaw Dawidowicz wrote:
> On Apr 24, 2012, at 10:56 AM, Marek Posolda wrote:
>> 3) Another potentially missing thing is pagination. I assume that we can have thousands of users in DB and thousands of resource objects, which in next turn means that you can have millions of permissions. In large environments, invoking of PermissionManager.listPermissions(Object resource, String operation) could return like 10.000 records. So counting with this case and provide additional methods for pagination support may be good IMO. Something like:
>>
>> List<Permission>  listPermissions(Object resource, Identity String operation, int offset, int pageSize);
>>
> For pagination I propose using something like Range object
>
> https://github.com/bdaw/DeltaSpikeMirror/blob/fc7752409f289b6dfbd577292b70a786a4fb62f4/deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/api/idm/Range.java
>
> List<Permission>  listPermissions(Object resource, Identity String operation, Range range);
>
> with usage like:
>
> listPermissions(customerRecord, READ, Range.of(10,20));
>
> or
>
> Range page = new Range(0, 10);
> x.listPermissions(customerRecord, READ, page.next());
yes, slightly better and more flexible than using only "int offset, int 
pageSize".

Maybe instead of providing more overloaded "listPermissions" methods 
with different signatures, we can think about using query API and create 
concept of PermissionQuery?
So on PermissionManager having single method:

List<Permission> listPermissions(PermissionQuery query);



and having

public interface PermissionQuery
{
    private final IdentityType;
    private final String operation;
    private final Object resource;
    private final ResourceIdentifier resourceIdentifier;

    private Range range;
    private int countOfObjects = -1;

    public PermissionQuery(IdentityType idType, String operation, Object 
resource, ResourceIdentifier resourceIdentifier, Range range)
    {
        // snipet
    }

    public void setRange()
    {
        this.range = range;
    }

    public void nextPage()
    {
        range.next();
    }

    public boolean hasAvailableResultsOnCurrentPage()
    {
       if (countOfObjects == -1)
       {
           // compute total count of poermission objects from DB
       }

        return range.getLimit() < countOfObjects;
    }

    // getters

}



Now I want to obtain all available actions of user John for resource  
object "maryCustomer":

PermissionQuery permissionQuery = new PermissionQuery(new User("john"), 
null, maryCustomer,null, Range.of(0,10));

while (permissionQuery.hasAvailableResultsOnCurrentPage())
{
      List<Permission> currentPage = 
permissionManager.listPermissions(permissionQuery);

      // Do something with results
      permissionQuery.nextPage();
}




I am not sure if methods related to pagination should be covered 
directly in PermissionQuery as it won't be immutable then and method 
hasAvailableResultsOnCurrentPage() will need to access DB to compute 
total number of available results. Maybe we can have two separate 
methods on PermissionManager. One for case without pagination and second 
with pagination. And for pagination case, we will probably need to count 
total number of results:

List<Permission> listPermissions(PermissionQuery query);
List<Permission> listPermissions(PermissionQuery query, Range page);
int getPermissionsCount(PermissionQuery);

WDYT?

Marek

> Bolek
>
>
>
>


Re: [DISCUSS] DELTASPIKE-79 Authorization API - Permission Management and ACLs

Posted by Boleslaw Dawidowicz <bo...@gmail.com>.
On Apr 24, 2012, at 10:56 AM, Marek Posolda wrote:
> 
> 3) Another potentially missing thing is pagination. I assume that we can have thousands of users in DB and thousands of resource objects, which in next turn means that you can have millions of permissions. In large environments, invoking of PermissionManager.listPermissions(Object resource, String operation) could return like 10.000 records. So counting with this case and provide additional methods for pagination support may be good IMO. Something like:
> 
> List<Permission> listPermissions(Object resource, Identity String operation, int offset, int pageSize);
> 

For pagination I propose using something like Range object

https://github.com/bdaw/DeltaSpikeMirror/blob/fc7752409f289b6dfbd577292b70a786a4fb62f4/deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/api/idm/Range.java

List<Permission> listPermissions(Object resource, Identity String operation, Range range);

with usage like:

listPermissions(customerRecord, READ, Range.of(10,20));

or 

Range page = new Range(0, 10);
x.listPermissions(customerRecord, READ, page.next());

Bolek 




Re: [DISCUSS] DELTASPIKE-79 Authorization API - Permission Management and ACLs

Posted by Shane Bryzak <sb...@redhat.com>.
On 24/04/12 18:56, Marek Posolda wrote:
> Hi Shane,
>
> If I understand correctly this PermissionManager would be used by 
> PersistentPermissionResolver, which will be the default 
> PermissionResolver implementation? As it will be good if people have 
> flexibility to implement their own PermissionResolver and use some 
> completely different security framework of their own, if they need it.
>
> Some feedback for the PermissionManager itself:
> 1) I think we should provide also methods for dealing with 
> ResourceIdentifier case? So we should have also methods like:
> List<Permission> listPermissions(ResourceIdentifier resource, String 
> operation)
> List<Permission> listPermissions(ResourceIdentifier resource)
> etc.

Good point, we probably have to add these methods also.
>
> 2) How about cover user identity in the API? For example: I want to 
> know that user "john" has permission to READ customer "Mary Kelly". 
> With current API I would need to call: 
> listPermissions(maryKellyCustomer, "READ") and then iterate through 
> all the Permission objects from result list and see if they are 
> applicable for John. It does not seem to be good from usability and 
> performance perspective.
>
> So I guess we need also methods like:
> List<Permission> listPermissions(Object resource, Identity String 
> operation, User user)
>
> When more thinking about it, I think the recipient of the Permission 
> can be single user or also group? And IMO we should also think about 
> roles to have things more complicated :)
>
> So you can easily ask PermissionManager for questions like: Has 
> "MANAGER" of group "PowerUsers" permissions to "READ" customer "Mary 
> Kelly" ? This may be fine with method like:
>
> List<Permission> listPermissions(Object resource, Identity String 
> operation, String identityId, String identityType, String roleType);
>
> Maybe instead of using Strings as last 3 arguments, we can encapsulate 
> all recipient informations into single object.
>
> WDYT?
>
>
>
> 3) Another potentially missing thing is pagination. I assume that we 
> can have thousands of users in DB and thousands of resource objects, 
> which in next turn means that you can have millions of permissions. In 
> large environments, invoking of 
> PermissionManager.listPermissions(Object resource, String operation) 
> could return like 10.000 records. So counting with this case and 
> provide additional methods for pagination support may be good IMO. 
> Something like:
>
> List<Permission> listPermissions(Object resource, Identity String 
> operation, int offset, int pageSize);

In response to both 2) and 3), I've been thinking quite a lot about how 
we retrieve permissions from the database, and yes when there are 
thousands or millions of records it would be useful to support some kind 
of pagination.  The idea that appeals to me the most would be to 
implement a Query API similar to what Bolek has proposed for IDM, except 
for permissions.  This would allow us much greater flexibility and allow 
us to support pagination, etc.

>
> Thanks,
> Marek
>
> On 23.4.2012 11:56, Shane Bryzak wrote:
>> Following up to the recent outline of object permissions, I'd like to 
>> continue with a description of the permission management API.
>>
>> At the centre of this API is the PermissionManager bean.  This bean 
>> provides all of the operations required to grant, deny and query 
>> object permissions.  Here's a description of the methods:
>>
>> List<Permission> listPermissions(Object resource, String operation)
>>
>> Returns a List of all the Permissions that have been granted for the 
>> specified resource and operation.
>>
>> List<Permission> listPermissions(Object resource)
>>
>> Returns a List of all the Permissions that have been granted for the 
>> specified resource
>>
>> boolean grantPermission(Permission permission)
>>
>> Grants the specified permission, returns true if successful.
>>
>> boolean grantPermissions(List<Permission> permissions)
>>
>> Grants all the permissions contained in the specified List, returns 
>> true if successful.
>>
>> boolean revokePermission(Permission permission)
>>
>> Revokes the specified permission, returns true if successful.
>>
>> boolean revokePermissions(List<Permission> permissions)
>>
>> Revokes the specified permissions, returns true if successful.
>>
>> List<String> listAvailableOperations(Object resource)
>>
>> Returns a list containing all the known allowed operations for the 
>> specified resource.
>>
>> Each of these methods in turn will invoke a permission check to 
>> ensure that the current user has permission to invoke that particular 
>> permission management operation.
>>
>> Behind the scenes, the PermissionManager uses a PermissionStore to do 
>> the actual work.  The PermissionStore interface is practically 
>> identical to the PermissionManager interface, in face we can possibly 
>> just have it extend it.  DeltaSpike should provide one 
>> PermissionStore implementation out of the box, JpaPermissionStore 
>> which allows the user to store their permissions in a database 
>> table.  We can use annotations to configure the entity that is used 
>> to store permissions:
>>
>>
>> @Entity
>> public class ObjectPermission
>> {
>>     private Long permissionId;
>>     @PermissionRecipient private String recipient;
>>     @PermissionResourceIdentifier private String resourceId;
>>     @PermissionOperation private String operation;
>>     @PermissionDiscriminator private String discriminator;
>> }
>>
>> It should also be possible to use multiple tables to store 
>> permissions.  Take for example the use case where a user might wish 
>> to query a table based on assigned permissions:
>>
>> SELECT
>>   C.*
>> FROM
>>   CUSTOMER C,
>>   CUSTOMER_PERMISSION CP
>> WHERE
>>   C.CUSTOMER_ID = CP.CUSTOMER_ID
>>   AND CP.OPERATION CONTAINS '%READ%';
>>
>>
>


Re: [DISCUSS] DELTASPIKE-79 Authorization API - Permission Management and ACLs

Posted by Gerhard Petracek <ge...@gmail.com>.
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 <bo...@gmail.com>

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

Re: [DISCUSS] DELTASPIKE-79 Authorization API - Permission Management and ACLs

Posted by Boleslaw Dawidowicz <bo...@gmail.com>.
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 




Re: [DISCUSS] DELTASPIKE-79 Authorization API - Permission Management and ACLs

Posted by Marek Posolda <mp...@redhat.com>.
>> 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

   }

}



Re: [DISCUSS] DELTASPIKE-79 Authorization API - Permission Management and ACLs

Posted by Shane Bryzak <sb...@redhat.com>.
On 24/04/12 19:03, Marek Posolda wrote:
> On 24.4.2012 10:56, Marek Posolda wrote:
>> Hi Shane,
>>
>> If I understand correctly this PermissionManager would be used by 
>> PersistentPermissionResolver, which will be the default 
>> PermissionResolver implementation? As it will be good if people have 
>> flexibility to implement their own PermissionResolver and use some 
>> completely different security framework of their own, if they need it.
>>
>> Some feedback for the PermissionManager itself:
>> 1) I think we should provide also methods for dealing with 
>> ResourceIdentifier case? So we should have also methods like:
>> List<Permission> listPermissions(ResourceIdentifier resource, String 
>> operation)
>> List<Permission> listPermissions(ResourceIdentifier resource)
>> etc.
>>
>> 2) How about cover user identity in the API? For example: I want to 
>> know that user "john" has permission to READ customer "Mary Kelly". 
>> With current API I would need to call: 
>> listPermissions(maryKellyCustomer, "READ") and then iterate through 
>> all the Permission objects from result list and see if they are 
>> applicable for John. It does not seem to be good from usability and 
>> performance perspective.
>>
>> So I guess we need also methods like:
>> List<Permission> listPermissions(Object resource, Identity String 
>> operation, User user)
>>
>> When more thinking about it, I think the recipient of the Permission 
>> can be single user or also group? And IMO we should also think about 
>> roles to have things more complicated :)
>>
>> So you can easily ask PermissionManager for questions like: Has 
>> "MANAGER" of group "PowerUsers" permissions to "READ" customer "Mary 
>> Kelly" ? This may be fine with method like:
>>
>> List<Permission> listPermissions(Object resource, Identity String 
>> operation, String identityId, String identityType, String roleType);
>>
>> Maybe instead of using Strings as last 3 arguments, we can 
>> encapsulate all recipient informations into single object.
>>
>> WDYT?
> 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.

>
>>
>>
>>
>> 3) Another potentially missing thing is pagination. I assume that we 
>> can have thousands of users in DB and thousands of resource objects, 
>> which in next turn means that you can have millions of permissions. 
>> In large environments, invoking of 
>> PermissionManager.listPermissions(Object resource, String operation) 
>> could return like 10.000 records. So counting with this case and 
>> provide additional methods for pagination support may be good IMO. 
>> Something like:
>>
>> List<Permission> listPermissions(Object resource, Identity String 
>> operation, int offset, int pageSize);
>>
>> Thanks,
>> Marek
>>
>> On 23.4.2012 11:56, Shane Bryzak wrote:
>>> Following up to the recent outline of object permissions, I'd like 
>>> to continue with a description of the permission management API.
>>>
>>> At the centre of this API is the PermissionManager bean.  This bean 
>>> provides all of the operations required to grant, deny and query 
>>> object permissions.  Here's a description of the methods:
>>>
>>> List<Permission> listPermissions(Object resource, String operation)
>>>
>>> Returns a List of all the Permissions that have been granted for the 
>>> specified resource and operation.
>>>
>>> List<Permission> listPermissions(Object resource)
>>>
>>> Returns a List of all the Permissions that have been granted for the 
>>> specified resource
>>>
>>> boolean grantPermission(Permission permission)
>>>
>>> Grants the specified permission, returns true if successful.
>>>
>>> boolean grantPermissions(List<Permission> permissions)
>>>
>>> Grants all the permissions contained in the specified List, returns 
>>> true if successful.
>>>
>>> boolean revokePermission(Permission permission)
>>>
>>> Revokes the specified permission, returns true if successful.
>>>
>>> boolean revokePermissions(List<Permission> permissions)
>>>
>>> Revokes the specified permissions, returns true if successful.
>>>
>>> List<String> listAvailableOperations(Object resource)
>>>
>>> Returns a list containing all the known allowed operations for the 
>>> specified resource.
>>>
>>> Each of these methods in turn will invoke a permission check to 
>>> ensure that the current user has permission to invoke that 
>>> particular permission management operation.
>>>
>>> Behind the scenes, the PermissionManager uses a PermissionStore to 
>>> do the actual work.  The PermissionStore interface is practically 
>>> identical to the PermissionManager interface, in face we can 
>>> possibly just have it extend it.  DeltaSpike should provide one 
>>> PermissionStore implementation out of the box, JpaPermissionStore 
>>> which allows the user to store their permissions in a database 
>>> table.  We can use annotations to configure the entity that is used 
>>> to store permissions:
>>>
>>>
>>> @Entity
>>> public class ObjectPermission
>>> {
>>>     private Long permissionId;
>>>     @PermissionRecipient private String recipient;
>>>     @PermissionResourceIdentifier private String resourceId;
>>>     @PermissionOperation private String operation;
>>>     @PermissionDiscriminator private String discriminator;
>>> }
>>>
>>> It should also be possible to use multiple tables to store 
>>> permissions.  Take for example the use case where a user might wish 
>>> to query a table based on assigned permissions:
>>>
>>> SELECT
>>>   C.*
>>> FROM
>>>   CUSTOMER C,
>>>   CUSTOMER_PERMISSION CP
>>> WHERE
>>>   C.CUSTOMER_ID = CP.CUSTOMER_ID
>>>   AND CP.OPERATION CONTAINS '%READ%';
>>>
>>>
>>
>>
>


Re: [DISCUSS] DELTASPIKE-79 Authorization API - Permission Management and ACLs

Posted by Marek Posolda <mp...@redhat.com>.
On 24.4.2012 10:56, Marek Posolda wrote:
> Hi Shane,
>
> If I understand correctly this PermissionManager would be used by 
> PersistentPermissionResolver, which will be the default 
> PermissionResolver implementation? As it will be good if people have 
> flexibility to implement their own PermissionResolver and use some 
> completely different security framework of their own, if they need it.
>
> Some feedback for the PermissionManager itself:
> 1) I think we should provide also methods for dealing with 
> ResourceIdentifier case? So we should have also methods like:
> List<Permission> listPermissions(ResourceIdentifier resource, String 
> operation)
> List<Permission> listPermissions(ResourceIdentifier resource)
> etc.
>
> 2) How about cover user identity in the API? For example: I want to 
> know that user "john" has permission to READ customer "Mary Kelly". 
> With current API I would need to call: 
> listPermissions(maryKellyCustomer, "READ") and then iterate through 
> all the Permission objects from result list and see if they are 
> applicable for John. It does not seem to be good from usability and 
> performance perspective.
>
> So I guess we need also methods like:
> List<Permission> listPermissions(Object resource, Identity String 
> operation, User user)
>
> When more thinking about it, I think the recipient of the Permission 
> can be single user or also group? And IMO we should also think about 
> roles to have things more complicated :)
>
> So you can easily ask PermissionManager for questions like: Has 
> "MANAGER" of group "PowerUsers" permissions to "READ" customer "Mary 
> Kelly" ? This may be fine with method like:
>
> List<Permission> listPermissions(Object resource, Identity String 
> operation, String identityId, String identityType, String roleType);
>
> Maybe instead of using Strings as last 3 arguments, we can encapsulate 
> all recipient informations into single object.
>
> WDYT?
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)

>
>
>
> 3) Another potentially missing thing is pagination. I assume that we 
> can have thousands of users in DB and thousands of resource objects, 
> which in next turn means that you can have millions of permissions. In 
> large environments, invoking of 
> PermissionManager.listPermissions(Object resource, String operation) 
> could return like 10.000 records. So counting with this case and 
> provide additional methods for pagination support may be good IMO. 
> Something like:
>
> List<Permission> listPermissions(Object resource, Identity String 
> operation, int offset, int pageSize);
>
> Thanks,
> Marek
>
> On 23.4.2012 11:56, Shane Bryzak wrote:
>> Following up to the recent outline of object permissions, I'd like to 
>> continue with a description of the permission management API.
>>
>> At the centre of this API is the PermissionManager bean.  This bean 
>> provides all of the operations required to grant, deny and query 
>> object permissions.  Here's a description of the methods:
>>
>> List<Permission> listPermissions(Object resource, String operation)
>>
>> Returns a List of all the Permissions that have been granted for the 
>> specified resource and operation.
>>
>> List<Permission> listPermissions(Object resource)
>>
>> Returns a List of all the Permissions that have been granted for the 
>> specified resource
>>
>> boolean grantPermission(Permission permission)
>>
>> Grants the specified permission, returns true if successful.
>>
>> boolean grantPermissions(List<Permission> permissions)
>>
>> Grants all the permissions contained in the specified List, returns 
>> true if successful.
>>
>> boolean revokePermission(Permission permission)
>>
>> Revokes the specified permission, returns true if successful.
>>
>> boolean revokePermissions(List<Permission> permissions)
>>
>> Revokes the specified permissions, returns true if successful.
>>
>> List<String> listAvailableOperations(Object resource)
>>
>> Returns a list containing all the known allowed operations for the 
>> specified resource.
>>
>> Each of these methods in turn will invoke a permission check to 
>> ensure that the current user has permission to invoke that particular 
>> permission management operation.
>>
>> Behind the scenes, the PermissionManager uses a PermissionStore to do 
>> the actual work.  The PermissionStore interface is practically 
>> identical to the PermissionManager interface, in face we can possibly 
>> just have it extend it.  DeltaSpike should provide one 
>> PermissionStore implementation out of the box, JpaPermissionStore 
>> which allows the user to store their permissions in a database 
>> table.  We can use annotations to configure the entity that is used 
>> to store permissions:
>>
>>
>> @Entity
>> public class ObjectPermission
>> {
>>     private Long permissionId;
>>     @PermissionRecipient private String recipient;
>>     @PermissionResourceIdentifier private String resourceId;
>>     @PermissionOperation private String operation;
>>     @PermissionDiscriminator private String discriminator;
>> }
>>
>> It should also be possible to use multiple tables to store 
>> permissions.  Take for example the use case where a user might wish 
>> to query a table based on assigned permissions:
>>
>> SELECT
>>   C.*
>> FROM
>>   CUSTOMER C,
>>   CUSTOMER_PERMISSION CP
>> WHERE
>>   C.CUSTOMER_ID = CP.CUSTOMER_ID
>>   AND CP.OPERATION CONTAINS '%READ%';
>>
>>
>
>


Re: [DISCUSS] DELTASPIKE-79 Authorization API - Permission Management and ACLs

Posted by Marek Posolda <mp...@redhat.com>.
Hi Shane,

If I understand correctly this PermissionManager would be used by 
PersistentPermissionResolver, which will be the default 
PermissionResolver implementation? As it will be good if people have 
flexibility to implement their own PermissionResolver and use some 
completely different security framework of their own, if they need it.

Some feedback for the PermissionManager itself:
1) I think we should provide also methods for dealing with 
ResourceIdentifier case? So we should have also methods like:
List<Permission> listPermissions(ResourceIdentifier resource, String 
operation)
List<Permission> listPermissions(ResourceIdentifier resource)
etc.

2) How about cover user identity in the API? For example: I want to know 
that user "john" has permission to READ customer "Mary Kelly". With 
current API I would need to call: listPermissions(maryKellyCustomer, 
"READ") and then iterate through all the Permission objects from result 
list and see if they are applicable for John. It does not seem to be 
good from usability and performance perspective.

So I guess we need also methods like:
List<Permission> listPermissions(Object resource, Identity String 
operation, User user)

When more thinking about it, I think the recipient of the Permission can 
be single user or also group? And IMO we should also think about roles 
to have things more complicated :)

So you can easily ask PermissionManager for questions like: Has 
"MANAGER" of group "PowerUsers" permissions to "READ" customer "Mary 
Kelly" ? This may be fine with method like:

List<Permission> listPermissions(Object resource, Identity String 
operation, String identityId, String identityType, String roleType);

Maybe instead of using Strings as last 3 arguments, we can encapsulate 
all recipient informations into single object.

WDYT?



3) Another potentially missing thing is pagination. I assume that we can 
have thousands of users in DB and thousands of resource objects, which 
in next turn means that you can have millions of permissions. In large 
environments, invoking of PermissionManager.listPermissions(Object 
resource, String operation) could return like 10.000 records. So 
counting with this case and provide additional methods for pagination 
support may be good IMO. Something like:

List<Permission> listPermissions(Object resource, Identity String 
operation, int offset, int pageSize);

Thanks,
Marek

On 23.4.2012 11:56, Shane Bryzak wrote:
> Following up to the recent outline of object permissions, I'd like to 
> continue with a description of the permission management API.
>
> At the centre of this API is the PermissionManager bean.  This bean 
> provides all of the operations required to grant, deny and query 
> object permissions.  Here's a description of the methods:
>
> List<Permission> listPermissions(Object resource, String operation)
>
> Returns a List of all the Permissions that have been granted for the 
> specified resource and operation.
>
> List<Permission> listPermissions(Object resource)
>
> Returns a List of all the Permissions that have been granted for the 
> specified resource
>
> boolean grantPermission(Permission permission)
>
> Grants the specified permission, returns true if successful.
>
> boolean grantPermissions(List<Permission> permissions)
>
> Grants all the permissions contained in the specified List, returns 
> true if successful.
>
> boolean revokePermission(Permission permission)
>
> Revokes the specified permission, returns true if successful.
>
> boolean revokePermissions(List<Permission> permissions)
>
> Revokes the specified permissions, returns true if successful.
>
> List<String> listAvailableOperations(Object resource)
>
> Returns a list containing all the known allowed operations for the 
> specified resource.
>
> Each of these methods in turn will invoke a permission check to ensure 
> that the current user has permission to invoke that particular 
> permission management operation.
>
> Behind the scenes, the PermissionManager uses a PermissionStore to do 
> the actual work.  The PermissionStore interface is practically 
> identical to the PermissionManager interface, in face we can possibly 
> just have it extend it.  DeltaSpike should provide one PermissionStore 
> implementation out of the box, JpaPermissionStore which allows the 
> user to store their permissions in a database table.  We can use 
> annotations to configure the entity that is used to store permissions:
>
>
> @Entity
> public class ObjectPermission
> {
>     private Long permissionId;
>     @PermissionRecipient private String recipient;
>     @PermissionResourceIdentifier private String resourceId;
>     @PermissionOperation private String operation;
>     @PermissionDiscriminator private String discriminator;
> }
>
> It should also be possible to use multiple tables to store 
> permissions.  Take for example the use case where a user might wish to 
> query a table based on assigned permissions:
>
> SELECT
>   C.*
> FROM
>   CUSTOMER C,
>   CUSTOMER_PERMISSION CP
> WHERE
>   C.CUSTOMER_ID = CP.CUSTOMER_ID
>   AND CP.OPERATION CONTAINS '%READ%';
>
>