Proposal
In the following, a Permission is defined as being some action or group of actions which are given a label (eg. "View", "Edit", "Web Registration") that have some scope. A Role groups Permissions under a second label (eg. "Admin", "User"). Users are assigned Roles.
There should be broadly three scopes in Permission declarations:
global -- Permission for all classes, items and properties (or none). Defined using security.addPermission(name, description), e.g. security.addPermission("Edit", "User may edit everthing").
classes -- Permission for all items of a given class, e.g. "issue". Defined using security.addPermission(name, description, class), e.g. security.addPermission("Edit", "User may edit issues", "issue").
properties -- Permission for a specific property of a class, eg. the "address" property of "user". Defined using security.addPermission(name, description, class, property), e.g. security.addPermission("View", "User may view user addresses", "user", "address") .
code -- Permission based on some code that determines whether a given user can take some action, possibly based on an item. Defined using an additional keyword argument to a regular addPermission call, e.g. security.addPermission(name, description{, class}{, property}, check=function) where the function takes three arguments, function(db, userid, itemid)(where itemid may be None) and returns True or False depending on wether the user has the permission. The security.hasPermission() method will need to be altered to optionally accept an item. Note that this proposal means that global Permissions like "Email Registration" may have code associated with them.
So, the addPermission signature now looks like:
1 addPermission(self, name="", description="", klass=None, property=None, check=None)
And the hasPermission signature now looks like:
1 hasPermission(self, permission, userid, classname=None, property=None, itemid=None)
... and it will invoke the *check* code when defined instead of just returning True.
Permissions checks are still invoked by the user interface code as they are at the moment. Having the hyperdb automatically perform those checks would be painful, as we'd need special methods that circumvent the security checks, and then make sure we catch all the places that need to perform unchecked data access or manipulation.
Migration
This proposal introduces the "Create" permission which is not currently defined and therefore not assigned to users in current trackers. This will need to be changed in tracker installations.
This change also changes the existing way we handle user registration. Both the Web Registration and Email Registration permissions go away, replaced by generic Create checks.