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.
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); 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. 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