Forum OpenACS Development: Group membership

Collapse
Posted by Malte Sussdorff on
I have a couple of issues with the fact that only persons can be members of a group and not parties. But before I TIP this change, I was wondering what implications this might have.

My main idea would be to allow organizations to be members of a group, which, as you might have guessed, comes from contacts.

But in addition to that, groups could be members of a group as well. Which would allow for nice permission inheritance which is currently done with components (I think, I never really understood the whole concept and why it was developed like that).

Collapse
2: Re: Group membership (response to 1)
Posted by Dave Bauer on
I think this is an interesting idea, but I am not sure the composition model for groups is compatible and I would need to see some good research into these changes, and how they would affect existing permissions. I don't have a good explanation for why it was modeled that way, I am sure there is a mathematical explanation somewhere.

I think the problem you are having is that Group/composition cannot model a hierarchy. What you might want is a separate hierarchy that does not affect the permissions.

I have built this before. A simple mapping table with a tree_sortkey is all that is required to create a hierarchy of groups.

Collapse
3: Re: Group membership (response to 1)
Posted by Matthew Geddert on

Contacts currently uses the acs-core groups mechanism to group person and organization objects, via a acs_rels workaround in the membership_rels table. This is not a clean solution and I'd like advice on the correct way to proceed with this problem. Or, is my assumptions that parties other than person/users objects should be able to grouped together flawed?

Here are some possible solutions:

  1. Keep contacts as is using the work around in the contacts tcl api to "cheat" the model of groups set up by core (i.e. to directly insert organization relationships into the database without using the tcl api). This has the advantaged that it works flawlessly (and has for two years) though it does not fit the overarching model well set up in OpenACS well at all.
  2. Change the membership_rels object_type to enforce group -> party relationships, which would enable organizations to have group membership. This however has the problem that it would allow groups and other non person/organization objects to be members of groups which could easily wreak havoc with permissions (not sure about other potential implications?)
  3. Enable group membership for organizations by some other means, like creating a shell "person" for that organization to hold group membership (which defeats the whole point of having various object subtypes of parties in the first place).
  4. Abandon group membership for organizations and persons because non person/user parties are not supported by the core group membership system and instead use some other mechanism to do this... and lose the ability to have contacts groups use the core permissions system (which is a not-insignificant loss).
Collapse
4: Re: Group membership (response to 1)
Posted by Dave Bauer on
Offhand. since the model you are building on is the permissions model for members of the web site, it makes sense to use it the way it was designed.

There is nothing stopping the contacts package from modeling, for example, a company org chart hierarchy, and the "groups" within the company.

I created a custom application for this. I created a simple mapping table with a tree sortkey and was able to simply model the hierarchy.

I think you might want to see if contacts should rely so directly on the permissions data model for things that don't fit.

re: #
# Abandon group membership for organizations and persons because non person/user parties are not supported by the core group membership system and instead use some other mechanism to do this... and lose the ability to have contacts groups use the core permissions system (which is a not-insignificant loss).

You should be able to do both! There is no reason you can't subtype group and model your hierarchy outside the permissions data model while still using the permissions data model to define permissions.

Collapse
5: Re: Group membership (response to 4)
Posted by Malte Sussdorff on
I think the issue here is not so much contacts, though that is where things come from, but for me asking the question why a thing (e.g. group membership) is designed in a certain way where it does not make much sense.

We already had at least one example where OpenACS arbitrarily restricts to users instead of parties. This is another example. My question is why?

We do have the concept of parties. Why do we still have so many foreign key constraints on users (where persons would do for natural persons, not all persons need to be users of the system, otherwise, why the distinction) or persons (where the assumption was made only a person would be able to do something where it actually is a party, permissions being a prime example for me).

Therefore, if we do the research into the toolkit we should be aware of the goals. And my goal is to make sure to only restrict to users / persons where it makes a lot of sense to only allow users / persons. Otherwise use parties.

Here is a small list only on acs-core after a quick look into the toolkit:

a) user_preferences table. Should be party_preferences as this definitely refers to a party with a locale, timezone, email_type and dont_spam_me flag. Remember a party can be any of "person" "organization" "group".

b) email_images. E-Mail belongs to a party! Why people are still limiting things related to e-mail to users is a total mystery to me. But I agree at that point in time I did not have enough experience to recognize the significance of it.

c) I would prefer party_portraits (after all an organization has a logo and a person has a portrait as well), but that is maybe only my taste

d) group membership on persons instead of parties (see above)

Again, there is absolutely no need to make this about contacts. For contacts we have 1) and if 1) is not enough we can just overwrite existing procedures (in contacts-init.tcl).

Collapse
6: Re: Group membership (response to 1)
Posted by Dave Bauer on
Malte,

Maybe you are right. I haven't run into these issues myself. I don't have any applications that have been signifiganted affected by these issues.

All of the changes you suggest make sense. The only one that requires a signifigant change is allowing groups to be members of other groups. I think if it is possible it would make it easier to use groups for most developers. The only problem I see is that it would require a huge amount of work and testing for what may be a small benefit.

That is, I don't understand the permissions issue you are trying to solve so I can't suggest an alternative solution, which may be less intuitive, but not require rewriting the entire permissions system.

Collapse
7: Re: Group membership (response to 6)
Posted by Tom Jackson on
The main problem is that ACS chose to use a hierarchical model for objects. Once a bad choice is made, you are stuck with it for eternity. It all sounds great, modeling objects like in an oo language, but every subtype then requires an additional join, and you can't add new functionality to every object, something added to a subtype is unavailable to parent types.

But this code (user/group/relations/permissions/etc.) is a huge can of worms. It isn't necessarily bad code, but it is much more difficult to understand than it seems like it should be. It is also very difficult to use it.

I did an experiment with this code about four years ago. I think you can add groups to other groups, but not via a web interface. Maybe that have changed, but the problem that I found is that you have to create a relational segment or a new rel type to do the mapping.

The example code is here:

http://rmadilo.com/files/unicycle/sql/postgresql/unicyclist-create.sql

The code adds a unicycle club (group) to a unicyclist group.

I just noticed there was some interesting code in the drop script which helps drop an entire package. This was easy because it only dropped users and objects created via the package, but it illustrates the method to really nuke packages, at least during development.

Code is in here:

http://rmadilo.com/files/unicycle/sql/postgresql/unicyclist-drop.sql

Collapse
8: Re: Group membership (response to 1)
Posted by russ m on
are you saying that having a membership_rel between 2 groups does not work? according to the docs this is part of the core design of the ACS groups system...

Consider an example to make this less abstract: Pretend that the Sierra Club is a member of Greenpeace. The Sierra Club has chapters; each chapter is a component of the Sierra Club. If Eddie Environmentalist is a member of the Massachusetts Chapter of the Sierra Club, Eddie is automatically a member of the Sierra Club, but being a Sierra Club member does not make Eddie a member of Greenpeace.

In the OpenACS, Greenpeace, Sierra Club, and the Sierra Club chapters would be modeled as groups, and Eddie would be a user. There would be a composition relationship between each Sierra Club chapter and the Sierra Club. Membership relationships would exist between Eddie and the Massachusetts Chapter, between Eddie and the Sierra Club (due to Eddie's membership in the Massachusetts chapter), and between the Sierra Club and Greenpeace.

and I'm just now starting on a project based on the assumption that the groups system can be made to work as described...

so what's the problem? composition_rel relationships work between groups but not membership_rel relationships? permissions don't propagate correctly to end-user parties?

Collapse
9: Re: Group membership (response to 1)
Posted by Dave Bauer on
In the link provided it says

"We start with Groups, which contain members; the member can be either a person or another group (i.e. a member is a party)."

So the problem is what does "contain" mean here.

I think most folks would think if members can be groups than a group can have a membership relationship to another group. I guess the question is whether the membership relationship is inherited by the groups members or not.

Aha here is the mathematical descripton of the Sierra Club example.

A group Gc can be a member and/or a component of another group Gp; the difference is in the way the members of Gc are related to Gp:

*

If a party P is a member (or a component) of Gc and if Gc is a component of Gp, then P is also a member (or a component) of Gp
*

If a party P is a member (or a component) of Gc and if Gc is a member of Gp, then no relationship between P and Gp exists as a result of the relationship between Gp and Gp.

According to the design doc it IS possible to model what I said it was impossible to model. I wonder if it works or not.

We see:
openacs-5-3=# select membership_rel__new(1030,1036);
ERROR: -20001: membership_rel violation: Invalid object types. Object 1030 (group) must be of type group Object 1036 (group) must be of type person
CONTEXT: SQL statement "insert into acs_rels (rel_id, rel_type, object_id_one, object_id_two) values ( $1 , $2 , $3 , $4 )"
PL/pgSQL function "acs_rel__new" line 25 at SQL statement
PL/pgSQL function "membership_rel__new" line 11 at assignment
PL/pgSQL function "membership_rel__new" line 5 at return

It does not work. IT says ONLY persons may be members of groups, which is what Malte has been trying to fix. Its clear the original design document says any party may be a member of a group. This may have changed when relational_segments were added to the data model.

Its not clear, I checked the earliest code OpenACS has and membership rel always required a group and a person.
attr_id := acs_rel_type__create_type (
''membership_rel'',
''Membership Relation'',
''Membership Relationships'',
''membership_rels'',
''rel_id'',
''membership_rel'',
''group'',
null,
0,
null,
''person'',
''member'',
0,
null
);

To change that now we'd need a comprehensive test suite to prove correctness of security and memebership inheritance. I think it would be cool if it was fixed because it would be much simpler for end users as composition rels are quite hard for people to understand.

Collapse
10: Re: Group membership (response to 9)
Posted by Malte Sussdorff on
Thanks Dave for looking into this. Great to know that it actually seems to be a bug or outdated design docs.

Russell, what we (meaning you, Matthew and myself) can do is play around with it when we change the constraint from persons to parties.

For our stuff it will work 100%, but we are not relying on permissions, so maybe you can test that one and between the three of us we figure out how to get it to work.

Collapse
11: Re: Group membership (response to 1)
Posted by Dave Bauer on
Malte,

Sounds reasonable. I think just changing the object_type_two in membership_rel to party will allow you to try to see if the memberships are maintained correctly through your groups.

This is all maintained by triggers so you'd have to analyze the behavior of the triggers and test what actually happens.

Collapse
12: Re: Group membership (response to 11)
Posted by Tom Jackson on
Is anyone listening?

There is nothing wrong with the code, there is no bug. You simply do not understand how it works. I provided a few links to some code which clearly shows that one group can be a member of another group. You may need a new rel_type, but this is by design, not due to some oversite. I think I made a statement here or on another thread that you could spend a few weeks on this code to figure it out, then you would decide nothing needs changing. Ignorance of design is not a bug. At any rate, at some point you will have to understand a relational segment, and write a few pl statements to set things up. This is what customization is all about. That is why we have a package system, etc.

In case it hasn't sunk in yet: how do you expect a group to have the exact same relationship type to another group as a person would have? You can't, so you need a new type of relationship.

Collapse
13: Re: Group membership (response to 1)
Posted by Dave Bauer on
Tom,

Thanks! I apologize for missing your point earlier. I guess I didn't believe it until I saw the code! Thanks for the explanation. It makes perfect sense to have a group membership rel which is simple and doesn't require and changes to the existing code! (Unless we decide we need to add a group_membership_rel to the core).

Collapse
14: Re: Group membership (response to 13)
Posted by Tom Jackson on
Dave,

The point is that you can add new relationship types. You need to model the type of relationship. If the current rel is changed, it changes for everyone, every application, etc. The point of this data model is to provide specific models of the relationships, so if there you relax the specification.

Here is an example:

Types of users (Not using subtypes):
Cyclists
Parents
Coaches

Group Subtypes:
Cyclist_Group
Cycle_Club

Goal:

Cyclists, usually kids, join this community and maintain data on their training, etc. Parents need to login and view this data, they may have several kids. Cyclists may have a coach. A coach may coach several cyclists. Coaches also need to view the data for their students.

Cyclists may join one or more clubs. If they do, their parents and coaches remain the same.

Relationship:

Cycling person to Cyclist Group -- each cyclist is created with a corresponding group, with their name as the group name. They are given a cyclist_rel to this group so we can tell who the cyclist is later on.

Parent Rel -- users who are parents can get a parent_rel to the cyclist_group of their kids. Now a parent can easily find their kids using this rel_type.

Coach Rel -- users who are coaches can be given the coach_rel by their cyclists to the cyclist_group. Coaches can now find all their students.

Club Rel -- Cyclist Group (one cyclist + parents + coach) can join to a Cycle Club using a club_rel. (Group to Group). Now a student can find all the clubs s/he belongs to.

Clubs are probably run by other users who might have a direct membership or admin relationship to the group. Each club can easily find their cyclists, parents, coaches.

Objects can be attached to each of these relational segments, and permissions can be granted, as needed to the members of the rel_segments.

Collapse
15: Re: Group membership (response to 14)
Posted by Tom Jackson on
Oops, bad editing of my previous post, last sentence of first para should have been removed. But I think a more relaxed relationship could be added, not changing the ones we have now, and overall I think that rel_types can apply between any object type, not just parties and party subtypes.

Also, I left out one final relationship: coach_rel could be applied between a coach and an club, or a new rel_type could be used for this.

Maybe it is worth noting that this setup is very similar to RDF (subject --predicate--> object), where you have typed relationships, which is more than mapping.