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). 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:ddwijeward...@gmail.com]
> Sent: Thursday, September 12, 2013 2:25 PM
> To: dev@sling.apache.org
> Subject: Re: [GSoC2013] Access Control for Cassandra ResourceProvider
> 
> Hi Ian
> 
> 
> On Thu, Sep 12, 2013 at 1:50 PM, Ian Boston <i...@tfd.co.uk> 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