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
