ACLs and multi-org

Gepubliceerd
2008-10-27 05:44
Written by
lobo - member of the CiviCRM community - view blog guidelines
Implementing support for multiple organizations with hierarchy is one of the main themes of the phase 2 part of the CiviCRM / The Public Interest Network (PIN) project. PIN has a fairly complex structure. It is a federation of organizations which include US PIRG, Environment America and others. It is made up the National PIN organization and has a number of child organizations at the National Level. One of them is Environment America (EA). The org chart of EA can be found here. EA National has a few groups at the national level (EA National Members, All Online Activists, Other Aggregate Groups). It also has a lot of sub organizations ( EA California, EA Colorado and approx 30 other state organizations). Each State Chapter has a few groups at the state level (EA California Members, EA California Activists etc). Each State also has sub organizations for geographic regions (EA Bay Area, EA LA Area, EA Northern California etc). These regions could have more sub organizations ( EA San Francisco, EA UC Berkeley, EA Stanford etc). So basically we have a 4 level deep organization nesting level with groups at each level. At any intermediate level there can be Aggregate groups (i.e. All Online Activists, All Online Activists in EA California, All Online Activists in EA Bay Area) From a permissioning perspective, there are admins at all levels (with various permissioning granularities needed at each level). You also have permissioning attached to the aggregate groups, i.e. you want a few folks to be able to see/send email to contacts in online activists only (and not any other groups that they belong to). The green party of NZ implementation had the "voter feature" as a defining characteristic. Thus a contact could belong to one and only one voting district and it was a relatively nice tree hierarchy (for the most part). This made the ACL implementation pretty simple and quite efficient (check the blog post here and here for details) The PIN case on the other hand does not fit this model. A contact could belong to multiple organizations across the hierarchy and also to a few different aggregate groups. Permissioned users could also have access to different sets of the hierarchy based on various factors, i.e. we cannot model the permissioning relationship as a simple set of easily computable math equations There are two potential ways we can model the hierarchy and the permissioning.
  • Model everything as a group including organizations. This uses the hierarchical group concept (introduced in 2.1) and basically lays out the structure as it appears on the org chart. The permissioning model remains the same, i.e. at the group level and users will have read/write access to one or more groups. This creates a large number of static (and hierarchical groups). For the EA case, if we assume a 2 level hierarchy with 5 groups at each level, this creates 180-200 groups (depending on number of aggregate groups). If PIN has 10 different organizations like EA, this results in 2000 groups (assuming EA is a good sample)
  • We could also model everything as a relationship. So organizations are modeled as CiviCRM organizations and a contact belongs to an organization using a descriptive relationship type (like "member of" or "online activist for"). The organization hierarchy is also modeled as a relationship using a relationship type "Child Org / Parent Org". Permissioning is now a combination of group based permissioning and relationship based permissioning. An admin with permissioning for all contacts belonging to a org X, basically queries the relationship table to get all contacts that have a relationship with org X. If org X is a parent org, we need to include all the children orgs as part of the above query. All the "contacts" belonging to an organization are smart groups (based on relationship type id and organization id). This reduces the number of groups involved since all organization groups are now smart groups. We could make it even smarter if the system knows about the relationship type and can create a smart group on the fly (i.e. similar to tokenized smart groups which we've talked about). However to improve performance, we've started caching smart group members – so from a DB perspective, we probably have the same number of groups.
Either of the above solutions don't seem to be very scalable (IMO). Our next steps will be to construct a reasonable data set for the EA org chart and see performance of various mysql queries for the above two models. There are a fair number of usability / scalability issues we'll need to tackle to address this in a complete manner
Filed under

Comments

Don't forget the third way in which contacts can 'belong' to an organization: CiviMembership. This raises again the issue of the lack of clarity in the concepts of Relationships versus Memberships (as I've discussed in Forums and briefly at CiviCamp), and I would assert again that a better approach would be to merge the concepts, making Memberships either a subset of Relationships or a sub-set of Groups, rather than a separate entity.

From a user perspective, Organizations as Groups fits better with the exiting permissioning system. This is not necessarily a strength, as the existing permissioning system is relatively incomprehensible for many users, so a drastic re-design would likely be an improvement. Organizations as Organizations (per option two) does seem more intuitive at first glance.

I am very much in favor of abstracting the idea of 'groups' so that any set of contacts can be treated as a 'group.' (Therefore, available to CiviMail, Permissioning, Searching, etc.) It does seem the idea of 'everything as a smart group' is a way to accomplish this, though the scalability question is key. Every Relationship definition, Membership definition, Tag, etc, could have a corresponding Group.

In combination with Group<->Role sync, this opens some powerful possibilities for Drupal integration. For example, all Employees of OrganizationX could receive automatic access to a private Forum, or any given Drupal feature.

One factor in making option two widely useful will be adding improving the ability to create relationships on import. Currently, there does not appear to be a way in the UI to attach imported contacts to a selected pre-exisiting related contact, although a new contact and relationship can be created via imported data. I'd like to see something like the current 'Add contacts to Tag/Group' feature for relationships.

hey lobo - not sure our regional 'acl' is quite is linear as you describe. While in theory contacts are in an electorate that is within a province, there is nothing to stop us allocating a person to Province A and to Electorate B1.

Also we have both branches and electorates, both of which are second tier to Provinces! (The Electorates are the voter defined geographies, the Branches are Party defined boundaries - communities of participation for example). So in fact people can already be allocated to
- Province A

Also we can give permissions to people to have access to contacts in eg Province A, Electorates B1 and C2, and Branch D3.

Oh yes, and did I mention 'Pods'.

Furthermore, when I floated the idea of our Electorate field being changed to multiselect I don't recall Chris flagging that that would crash the 'acl' system. I will check.

I guess I am wondering whether our approach has really been tested to check that it will fail in the scenario you paint. Then again, even if it doesn't break you may have good reasons to need another approach.

pete davis : [i]fuzion[/i] : advocacy + strategy + communication

I am yet to play around much with 2.1 but I understand that the Groups functionality is hierarchical in the sense that a parent can have multiple children but each child can only have one parent.

In Australian politics, we have Federal, State and Local government elections. Consequently a Group of volunteers may be a member of Federal, State AND Local campaign teams (Groups). This Group of volunteers should therefore be a child of 3 parents, or perhaps more correctly, have a relationship with 3 other Groups. It seems to me that ideally the Groups should really have a relationship to each other (other than parent/child) and that on creating the relationship type you would set permissions as to how the members and administrators of each group could interact with members of the other. I haven't thought through how that interface might work or all the intricacies, but thought I should throw the concept out there in the context of this discussion as it would seem to fit in with what lobo is proposing at bullet 2 above.