Multiple access levels: How to get there

The plugins Quasi Access and Granular Access provide a couple ways to associate multiple ACLs with content. I have an internal plugin that does something similar (manages an ACL binding zero or more users and ACLs) and a design for how I think Elgg core would provide this flexibility.

My knowledge of Granular Access is limited. My reading of Quasi Access is that it builds a new "quasi" ACL (and object) for every possible combination of ACL and doesn't actually populate those ACL members. When it's time to build an access query, it looks up all the ACLs the current user should see and stuffs them into the existing list going into the SQL. This certainly seems better than giving each content its own ACL and linking all the right users to it (which requires rebuilding that list each time a user leaves/joins one of the groups, etc).

I'd like to know the longer-term scaling challenges with these approaches; where we think we'll hit pain and what we could do at that point.

I'm also wondering if there's a path for slowly integrating my preferred schema into the current system. What if Elgg wrote to both storage schemas, but required a switch to read from the new one?

Part of me thinks that getting from here to there is hopeless without fully rebuilding Elgg, in which case we should just endorse some plugin and pour all effort into optimizing it. Or what if we could add a table or two to hack this in in a way that was as fast as possible?

Where do we go from here?

  • Supporting custom SQL had never been a strong point of Elgg... But finding distance between entities or getting all entities of a certain distance from Elgg seems like another pretty standard graph query that Elgg could just support better out of the box.

    I do see the allure of the relationships table being flat, though. Keeping that denormalized might be a good idea. Something like:

    Lists:
    id from_guid name inverse

    Relationships
    from_guid name to_guid

    That way you can:
    * still have lists with ids that replace acls
    * keep relationships table intact

  • Anyhow, I am happy with Elgg relationships the way they are, and I am going to strongly object to them being transformed into something else. As demonstrated above, there are ways to improve the access system without rebuilding the current schema - if we are to redo the schema, we might as well work on DB abstraction and NoSQL support instead.

    As far as lists are concerned, I have a plugin that implements hierarchical ordered lists using just annotations (I can put it up on GitHub if anyone is interested), so I don't think schema alternations can be really justified, the way I see it. Things can be achieved with slight performance cost with the current API

     

     

  • I'm interested. We've been discussing this for like years. Where have you been? :)

  • Off to bed now, too much food for thought before sleep. Will upload the plugin to github tomorrow.

  • Yes we're getting off-topic, I'm cool with that. I expanded the relationship docs quite a bit. It still doesn't solve the problem of vague names that weakly--if at all--imply direction (core has: friend, reply, invited, notify, attached).

    Even having written those docs and worked on Elgg for years I still don't remember which "inverted" value to use when querying. I can't be the only one. Having the API ask instead for the correct term seems a whole lot more readable to me, but yes, this is a lower priority than expressive limitations of the system (access and ordered lists).

    Aside: I'd love to see the hierarchical part of that implementation. Joining a flat, ordered table (my API plugin uses relationships) with no access control seemed to me the best for performance and simplicity.

  • Agree with Steve that I've had a very tough time keeping the meaning of relationships straight. More explicit would be objectively better here, whether we use list-style names or sentence-style names:

    • "1 member 2" => "1 is_member_of 2" and "2 has_member" 1
    • "1 member 2" => "1 memberships 2" and "2 members 1"

    When using the API to check for a single relationship, the former is more readable:

    check_relationship(1, "is_member_of", 2);
    check_relationship(2, "has_member", 2);
    

    But when using the API to get a list of entities, the latter is more readable:

    $group->getEntitiesFromRelationships('members');
    $user->getEntitiesFromRelationship('memberships');

    It's this latter use-case that I've been mostly focused on, because I figure the former API can be refactored to something like:

    $group->getEntitiesFromRelationship('members')->contains($user);
  • I'm a bit late concurring on the confusion of inverse relationships - but I concur, I have to look it up every time.

    Back to the topic at hand though, where do we go from here re: access?
    This is definitely of interest to me, I had a PR in for some access changes for 2.0 that I ended up running out of time on.

    Would the proposed change automatically take care of the ACCESS_PRIVATE / ACCESS_FRIENDS inconsistency issues?

  • Would the proposed change automatically take care of the ACCESS_PRIVATE / ACCESS_FRIENDS inconsistency issues?

    That's the idea behind acl_grants_entity. A comment on a blog with ACCESS_FRIENDS would inherit that ACL, and add the owner of the original blog as a standalone ACL. 

    blog post 12 by user 23
    comment 34 by user 45

    Blog ACLs:
    /23/friends 

    Comment ACLs:
    /23/friends
    /23/user

     

Feedback and Planning

Feedback and Planning

Discussions about the past, present, and future of Elgg and this community site.