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

Reply via email to