Forum OpenACS Development: Re: Porting Project/Open (Intranet Module) to OpenACS 5.0

Collapse
Posted by Don Baccus on
One of the very nice things about the OpenACS 4.x/5.x permissioning system (designed by aD, made scalable by us) is that the question being asked is "can party P do action A on object O".

A "party" can be a user or a set of users (a group or relational segment, with the latter being much like a subgroup  of users in a particular role) ... or anything else derived from the "party" type.  For our purposes, though, the three I mention (user, group member, group member with particular role) are the useful ones ...

Now I'm just talking off the top of my head but in order to attack this part of the problem:

"Rules to access a CustomerViewPage: Allowed are:
- Administrators
- General Management
- The customer himself, but no other customer
- Employees can only see the name of the customer, but nothing more, except they are assigned to the customer as a key account manager
- The project managers of projects for this customer while the project is "open".
- No freelancers at all
- Accountants have access the financial information, but have no access to CRM and presales information"

I would probably define subgroup/role (relational segment) parties of the intranet members for "administrators", "general managers" etc.  The employee subgroups would have "read" privileges on customer objects.  The easiest way to do this would probably be to define a "employees" group and then define the subgroup/role relational segments within the "employees" group.  Then everytime a new customer object is created you'd just grant "read" for the "employees" group (party) on that customer object.

Your freelancers and customers would be handled individually  for permissions purposes - freelancers would have no "read" privilege, while a customer would have the "read" privilege on their own object.  You might make a group for each customer (assuming a "customer" is actually a set of "customer employees") and assign the "read" privilege to the customer employees group rather than each one individually.

Or you might have a "customers" group with a separate "customer FOO" subgroup for employees of each customer if you need to treat the union of all customer employees as a single set for some reason (say, to send them each a Christmas card :)

I'd define some custom privileges (easy to do) for things like "can_read_financial_data" or "can_read_customer_details" etc ... these could be assigned, then, to the subgroups of employees or individual employees (i.e. one assigned to a customer project).

This is just a sketch but I think it illustrates something interesting and nice about the permissions model/design:

1. In the page itself, I only need to check "can the current user read the customer object this page wants to display?" or "can the current user read the customer's financial data"? etc. This makes page implementation very, very easy. The individual pages do not need to have *any* knowledge about the various roles and groups ... making it easy, among other things, to customize the system for organizations with novel employee structures you've not thought of ahead of time.

2. In your overall design, it allows you to concentrate on how to partition your intranet members into meaningful sets of people, and then on what actions you'll allow people in the various sets to take.  In a system like you're talking about, I think the *hard* part is defining roles and relationships to be held by various users of the intranet so  it seems appropriate that the design effort should center around the groups and [sub]group/role definitions.  This not only drives the permission system but is how you'll generate lists like "show me all employees of customer Foo" and "show me all of my employees assigned to Project FUBAR'd" etc etc.

4. The "customer object" would probably just be your package - mount a new instance of your package for each customer.  The request processor ensures that a vistor has the "read" priv on a package before letting them visit it - much less prone to programmer error than having each page do the read check itself (it's easy to forget to do so).  Then the page programmer only has to worry about checking for the special stuff like "can_read_financial_data", which they presumably are less likely to forget since they'll remember that it's sensitive information.  This would make it easy to provide each customer intranet subsite a different look and feel, say to include their logo on the page.  Or you might center the design around the subsite and portal packages...

Anyway ... the above is how I'd attack the design problem: keep the permissions checks simple.  Define a "employee" group for the main subsite with roles matching your criteria for partitioning them.  Each customer package instance/subsite+portal instance or whatever could define groups like "customer employees", "assigned vendor employees" etc and you'd then add people as appropriate and those groups would have the proper permissions assigned them to give members the rights they need.

This would mean that by default registered users could do nothing, all vendor employees would have the basic "read" right (not able to view sensitive data), and ANY OTHER permission would require explicit action on the part of the site administer - add them to the group of vendor employees assigned to a customer, for instance.  This is the kind of safety you need for such an application.

Anyway ... I hope this entirely top-of-the-head sketch helps a bit.  Any other community members have comments to add?