Forum OpenACS Development: Permissions Administrator Package

Posted by Ryan Gallimore on
I'm pleased to announce the release of a small package to make administering permissions a little easier. It is a beta and still in testing. Any comments or feedback are welcome.

Wiki page and download:

Posted by Tom Jackson on
It isn't clear if your package adds a new concept (role) or if it is purely administrative.

My understanding is that OpenACS does not support roles in general. In OpenACS a person's role is defined as the combination of everything they can do under their login. So the number of roles is potentially equal to the number of logins. Site-wide admins can do anything, so these are all considered the same from the perspective of a role.

A role us usually something which is independent of the person or login performing the role. It also exists independent of particular objects. The best match I have found to a role is a relational segment, which can be used as a context_id for objects and/or as a proxy object for permissions checking and also as a membership container.

Given the potential for confusion, what do you consider to be a role and how is this defined in the datamodel?

Posted by Ryan Gallimore on
In my package "role" is an administrative structure stored in the p_admin_roles table. It's simple a way of containing and representing a set of instructions associated with that role.
Instructions for each role are stored in p_admin_instructions.
See my sql file for more info.

For example, the Role Builder feature in the package creates a role named "News Admin" and then you add permissions like "Admin on the /news package" or "Join Site News Admins Group".

Once the role is created, you map users to the role so they inherit the same permissions above.

The general idea is to make complex administration by non-SWAs easier.

Posted by Tom Jackson on
Right, the OpenACS privilege/permission/user/group system is pretty big with lots of moving parts. Usually roles (or what permissions to require) are defined by the package writers and is pretty domain specific.

You are reporting that your package adds new functionality that may or may not relate to the permissions system, and appears to go around the existing methods of determining object access, but you also say it just helps administer permissions. If you can break down the relationship between your package and the existing permissions system in terms of the data model and existing permission functions, that would help evaluate your package.

Since this is a developers forums, we all understand, or should, the current code and data model. Just relate your package to what we already know.

Role and instructions are unknowns. Also unknown is what data is involved and how it is to be used, can the new system only be used with AJAX? My thought is that the behind the scenes action is more important for evaluation than the UI, considering that the general idea is to turn over an administrative task to non-SWAs. Overall I sense this is a backdoor to existing package data. Hopefully not.

Posted by Ryan Gallimore on
Hi Tom,

You can think of the package as a frontend for permissions. Instead of being object based, as it is currently, it is user based.

Instructions are either an implementation of a direct permission or a join group call.
ie. either permission::grant or group::add_member

So p_admin_instructions represents the arguments required to execute these procs.

                                        Table "public.p_admin_instructions"
     Column     |         Type         |                                    Modifiers
 instruction_id | integer              | not null default nextval('public.p_admin_instructions_instruction_id_seq'::text)
 role_id        | integer              |
 object_id      | integer              |
 privilege      | character varying(6) |
    "p_admin_instructions_pkey" PRIMARY KEY, btree (instruction_id)
    "p_admin_instructions_inst_idx" UNIQUE, btree (role_id, object_id, privilege)
    "p_admin_instructions_role_id_idx" btree (role_id)
Check constraints:
    "invalid_privilege" CHECK (privilege::text = 'read'::text OR privilege::text = 'write'::text OR privilege::text = 'create'::text OR privilege::text = 'admin'::text OR privilege::text = 'none'::text)
Foreign-key constraints:
    "p_admin_instructions_role_id_fkey" FOREIGN KEY (role_id) REFERENCES p_admin_roles(role_id)
    "p_admin_instructions_object_id_fkey" FOREIGN KEY (object_id) REFERENCES acs_objects(object_id)
Roles are then a container for these instructions.
And Roles can be attached to users.

AJAX is currently required just as a way of making object and user selection easier.

I'm not sure what you mean as a "backdoor to existing package data". It is more of an improved interface for modifying many permissions and group memberships at once.

Posted by Gustaf Neumann on
ryan, i am as well a little confused about your terminology. is your implementation user-based or role-based? what is an "instruction"?

Are you able to express what you did in the terminology of RBAC? Here is a good introduction of RBAC:
You might check as well we did on implementing RBAC in:

Posted by Andrew Piskorski on
"Roles" are very easy to implement in OpenACS. I do it just be creating groups, and assigning sets of permissions to each group, only. Then I move users in and out of groups as necessary. OpenACS users can be members of any number of groups, from zero to infinity, so this usually works well.

In fact, I'd say it's generally bad practice to ever assign permissions directly to users. If you do, how are you going to keep them all straight?

Relational segments, er, what the heck are those for again? Ah, I see that you and Don more or less explained it back in 2003, Tom. A "relational segment" is either "membership", "composition", or some specialized flavor of those, and is said to be lighter weight (more efficient) than using an OpenACS group.

I still don't see how or why I'd ever actually use relational segments. That's probably just because I never tried very hard to figure them out, but they're certainly rather esoteric and undocumented. Groups, on the other hand, are pretty simple and easy to understand, and they're documented.

Posted by Ryan Gallimore on
Groups are indispensible, I agree, and I've used them in this package. You can join users to a group when you assign them to a role. The trouble with groups is, there's no easy interface for granting object permissions to a group. That is one of the things this package can do.

Or perhaps I've reinvented the wheel? Is there already a way for a non-technical user to:

  1. Create a group called News Admins
  2. Grant admin permissions to all members of the News Admin group on the News package mounted at /mysite/news
  3. Grant read permissions on the /mysite/ subsite
  4. Join Joe User to the News Admin group

My package is designed for non-technical client admins to grant access to many regular members for granular access. This is in production on a large non-profit site with a lot of member governance.

Thank you for your comments.

Posted by Ryan Gallimore on
Of course, it's possible to accomplish the above steps by navigating to each permissions screen for the news and subsite applications, but if you have 30 or 40 packages you want the News Admins to control, it becomes very, very tedious.

What do other sites with an extensive site map use to control permissions for many users and groups?

Posted by Don Baccus on
Well, in a site I'm working on I ...

1. created a relseg called "content editors" on the membership group for my subsite.

2. granted write permissions on the subsite to members of that relseg.

3. added my content editors to that relseg

All using the existing groups and permissions admin UI.


1. That UI really sucks, and if I didn't know how things work under the hood I probably couldn't use it.

2. The acs-subsite/www/members membership management pages are sorely lacking.

You can think of a relseg as being a lightweight mechanism for making subgroups, for slicing groups into pieces in other words. You can think of the name of a relseg as being a role ... or you can use the role capability of the underlying acs-rels datamodel if you want (the membership management pages might work better if you do, by coincidence I'll be looking into this for some admin pages I'm doing for a client over the next week or two).

This is one area where .LRN actually got things more or less right, using relsegs to define professors, students, etc.

Rocael just posted a suggestion for dotlrn-specific permissions templates which boils down to saying "the subsite ones are insufficient". Dave and I have both suggested that the right thing to do is to fix acs-subsite.

Likewise I think an enhanced UI such as Ryan describes should be built into acs-subsite rather than exist as a separate package.

And, Ryan, I suspect that what you want to do can probably be done with the existing datamodel.

If I have some time I'll try your UI in the next few weeks I hope. I think for now I like the idea of trying to get the UI right, to see what a user-friendly UI might look like, than to worry if you've created some unneeded datamodel bits. If the UI's right, perhaps a couple of us (dave and I, perhaps?) can help figure out how to map that UI to the existing datamodel if it's possible to do so ...

I'd love to see this UI improve.

Posted by Dave Bauer on

I was thinking the same thing, that is, that the UI is the problem, the data model can pretty much model any situation but there is really no usable interface to it.

I'll also try to check out Ryan's code in the next week or two.

Posted by Ryan Gallimore on
Thanks for the input and offer to help refine the UI, Don and Dave!


Posted by Ryan Gallimore on
I've re-worked the concept behind my original package.

The package now tries to improve upon the existing UI. Its capabilities are limited to basic group creation, user assignment, and group permissioning, but I think it will be useful in many cases. There is some support for relational segment assignment.

Comments are welcome.