deltaspike-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Boleslaw Dawidowicz <boleslaw.dawidow...@gmail.com>
Subject Re: [DISCUSS] DELTASPIKE-79 Authorization API - Permission Management and ACLs
Date Tue, 24 Apr 2012 13:54:33 GMT

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%';
>>>>> 
>>>>> 
>>>> 
>>> 
>>> 
>> 
> 


Mime
View raw message