Forum OpenACS Development: Re: Permission system in needs of revisit?

Collapse
Posted by Malte Sussdorff on
Okay, maybe my statement was misleading. Obviously you can have functional permissions as you can have things like general_comments_create "functional permission", in addition to "read", "write", "delete" aso. But you caught my intention correctly when I asked about generalization.

With the listbuilder example given above, this is solved if Dave's changes with regards to listbuilder views (or stored settings) makes these objects as planned. Then you can easily work around the "has permission to see column XYZ" by giving him access to the view. Which probably covers most szenarios (as you usually want to limit certain columns or group of columns for access).

For other functional permissions I am only curious about a naming convention then, which makes it easy for the admin interface to assign new types of permissions.

Profile based permissions I will first dig deeper into query rewriter to be able to understand the posting. Hopefully at the end I can come up with a document on how to use permissions effectively.

Now, Don, as per your comment, sadly I am usually confronted with websites that have these many objects and parties, if not even more. Add to that the fact that people do not understand the permission system correctly and you suddenly end up with 750.000 entries into acs_permissions per day. This being said, it is still remarkable how fast the permission querying works (okay, up to 1.5 seconds for the query, but what do we have permission caching for). It is only slow on delete (when you remove a permission). Therefore, in my opinion, the goal should be to limit the entries to the permissions table as good as possible (in the 750.000 example I did this by "correct" inheritance) and I will take a look at the approaches suggested by Tom for the above mentioned howto / best practice, permissions for dummies text.

Collapse
Posted by Tom Jackson on
I have a habit of using query-writer as an example of how some tiny detail can be handled. For instance, the name is query-writer, but here we are talking about roles. In general, query-writer specifies an interface to database objects, such as tables or functions. But this primary interface covers everything which can be done, what is needed is a user-interface. This is where roles come in. Roles expose a subset of the functionality provided by the primary interface. Usually there is an admin role and a user role (btw, query-writer uses the term 'group' for role, because the concept is that there are a group of possible things you can do, spanning all objects) Beyond the built in roles, you can add new ones using a rel_segment. Making sure that users don't do any more than they are allowed is the usual goal of permissions, for instance this is why we have admin pages, so we can provide the concept of a role. This isn't fully handled by permissions, so you require an admin directory and admin pages which might allow more functionality. That is okay for the simple case, but what if you have two user roles, neither admin? Do you need two sets of pages? How can you ensure that users with one role will not subvert the system and use the wrong set of pages?

In query-writer you can use the same set of pages and only show what a user in a particular role can do. This is possible because query-writer can produce a set of flags for each possible element in the role. These flags can be used to construct the UI, even as far as showing only select options which are allowed for the role. This particular functionality is completely independent of the query-writing functions, you could use it to construct roles and use the flags to determine if a particular set of columns was viewable by a role. Since the query-writer objects don't have to point to a database table or anything else, the object could just be a placeholder for defining roles. Since roles span objects (and objects sometimes span tables), you can construct join queries based upon the allowed columns in the different objects.

The comments found in the query-writer data model, are helpful:
http://rmadilo.com/files/query-writer/source/query-writer/

under sql/postgresql. Comments for qw_attrs is in a separate file from the table def.

Also interesting is the data which goes into the tables, this is usually called bootstrap data in the tcl directory for a package. Bootstrap data allows package developers to move query-writer data around once it has been created via the UI. But this data is so hard to read in bootstrap format, it might be interesting to see it in a slightly easier to read form (only slightly easier!):

http://whogeenie.com/qw/twist/

You can check out the WSDL to get a list of object types in the enumeration:

http://whogeenie.com/qw/twist/?WSDL

(The TWiST config is at index.txt)

I've also put a listing of the nsv arrays at:

http://whogeenie.com/qw/twist/nsv.html

The nsv arrays contain all of the information needed to run query-writer, none of the data in the query-writer tables are used during runtime, just loaded at startup.