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