Hi Mike,
Thanks for the pointer.

On 12 September 2013 14:58, Mike Müller <[email protected]> wrote:
> Hi
>
> The common way to solve such an access control for a provider like
> the Cassandra resource provider is the new ResourceAccessSecurity
> service. This is implemented in the bundle resourceaccesssecurity
> (at this time only read rights will be checked).

Incidentally, how will other rights be enforced ?
the update pattern is resource.adaptTo(ModifiableValueMap.class)

would the adapter factory check that the current user has write access
to the resource before they can get their hands on a
ModifiableValueMap ?

Best Regards
Ian


 All you have to do is to
> implement the SPI ResourceAccessGate for the Cassandra provider
> and set the provider.useResourceAccessSecurity property to true
> for your ResourceProvider.
> By time resourceaccesssecurity will also implement create, modify
> And delete rights.
>
> Best regards
> mike
>
>> -----Original Message-----
>> From: Dishara Wijewardana [mailto:[email protected]]
>> Sent: Thursday, September 12, 2013 2:25 PM
>> To: [email protected]
>> Subject: Re: [GSoC2013] Access Control for Cassandra ResourceProvider
>>
>> Hi Ian
>>
>>
>> On Thu, Sep 12, 2013 at 1:50 PM, Ian Boston <[email protected]> wrote:
>>
>> > Hi Dishara,
>> > To make the Cassandra Resource Provider really useful I think we need
>> > to add access control. I think the best way of doing this is to borrow
>> > some concepts from Jackrabbit access control.
>> >
>> >
>> The following algorithms, and etc does sling already have any
>> implementation of it. If so I can reuse them. Since sling has few providers
>> I believe they probably have some common interface.
>>
>>
>> > Take a deep breath, and you will see why I left this till last.
>> >
>> > I think we should provide path base access control, which inherits
>> > from parent resources in the path. At every level there is a an
>> > ordered list of access control entries each access control entry (ACE)
>> > being either an allow entry or a deny entry. What is allowed or denied
>> > is defined in a 32bit bitmap with each bit representing 1 permission,
>> > so we can have upto 32 permissions. Each ACE specifies a single
>> > principal. So an ACL consists of a ordered list of ACE's each one
>> > bound to a principal.
>> >
>> > A user has a set of principals, so to resolve the ACL at any one path
>> > for a user the global ACL is filtered to contain only the ACE's with
>> > principals that the user has.
>> >
>> > Computing a final access control bitmap for a user at a location
>> > requires ordered processing of all the ACEs relevant to the user at
>> > the current path and then all ancestors.
>> >
>> > The pseudo algorithm to calculate the a grant bitmap and a deny bitmap
>> > at any level is:
>> >
>> > function getCurrentLevelBitmaps(currentPath):
>> >       int grants = 0;
>> >       int denies = 0;
>> >       for all ACEs in the ACL at the currentPath:
>> >             if the user has the principal of the current ACE:
>> >                   int toGrant = 0;
>> >                   int toDeny = 0;
>> >                   if the ACE is a grant:
>> >                         toGrant = the ACE bitmap;
>> >                   else:
>> >                         toDeny = the ACE bitmap;
>> >                   toGrant = toGrant & ~denies;
>> >                   toDeny = toDeny & ~grants;
>> >                   grants = grants | toGrant;
>> >                   denied = denies | toDenies;
>> >       return (grants, denies);
>> >
>>
>> - Can you please tell me how to calculate the ACE bitmap ?
>> - Also I will be more clear if you can provide a sample value for the input
>> and output of this function ? i.e When currentPath=
>> /content/cassandra/foo/bar  it returns grants=? denies=? some actual values
>> just for my understanding.
>>
>>
>> > To combine what is granted at the child level with what is granted at
>> > a parent level we need to mask the parent level with the deny at the
>> > child level.
>> >
>> > eg
>> >          toGrant = grantedAtParent & ~denies;
>> >          toDeny = deniedAtParent & ~grants;
>> >          grants = grants | toGrant;
>> >          denied = denies | toDenies;
>> >
>> > The simplest way of achieving this is to use recursion again in pseudo
>> > code:
>> >
>> >    function buildAtLevel():
>> >             if not root level:
>> >                  (grantedAtParent, deniedAtParent) =
>> > buildAtLevel(getParentLevel(currentLevel));
>> >             (grants, denies) = getCurrentLevelBitmaps(currentLevel);
>> >             toGrant = grantedAtParent & ~denies;
>> >            toDeny = deniedAtParent & ~grants;
>> >            grants = grants | toGrant;
>> >            denied = denies | toDenies;
>> >            return (grants, denied);
>> >
>> >
>> > There are some optimisations you can apply here, and there are plenty
>> > of opportunities to cache intermediate bitmaps in memory. Just caching
>> > the ACL reduces resolution to bitwise operations.
>> >
>> > Principals
>> > ----------------
>> > Initially keep it simple.
>> >
>> > read = 0x01
>> > write = 0x02
>> > delete = 0x04
>> >
>> > Storage of ACLs.
>> > -------------------------
>> > I suggest you store ACLs in their own Column Family, where the rowID is
>> > base64(sha1(path)) or whatever path -> rowid encoding you have currently.
>> >
>> > IIRC Cassandra columns come out in the natural order of Strings
>> > <order>_<principal>_<allow|deny> and the value is the bitmap of
>> > permissions.
>> >
>> > - If I understand you correctly is   <order>_<principal>_<allow|deny> is
>> one ACE ? If per row there can be a ACL, there should be one additional
>> column by default called "ACL" and it will have a comma separated string
>> which are set of ACEs. Correct me if I am wrong.
>> - Who stores these ACEs ? any API?
>> - i.e <order> is a auto increment number we have to do a additional read
>> before storing ACE to check what is the last number for <order>.
>>
>> Where <order> is 000 to 999 ( I really doubt that a single ACL will
>> > have 1000 ACEs ever)
>> >
>> > Once you have this working, we can wire it into the ResourceProvider
>> > or another Sling API.
>> >
>> > Does that make sense ?
>> > Ian
>> >
>>
>>
>>
>> --
>> Thanks
>> /Dishara

Reply via email to