22Security Mechanisms
33===================
44
5- :Version: $Revision: 1.7 $
5+ :Version: $Revision: 1.8 $
66
77Current situation
88=================
@@ -108,15 +108,6 @@ are asked if the current user has permission. Since code must call the
108108check function to raise a denial, there is no possibility to have automatic
109109default of deny in this situation.
110110
111- In practice, this is implemented as:
112-
113- 1. there's a mapping of user -> role (in hyperdb)
114- 2. there's a mapping of role -> permission (in code)
115- 3. there's a set of permissions defined, possibly set against a specific class
116- (in code)
117- 4. there's a function that's available to all roundup code that can ask
118- whether a particular user has a particular permission.
119-
120111Pros:
121112
122113 - quite obvious what is going on
@@ -140,6 +131,11 @@ allow the multiple assignment of Roles to Users, and multiple Permissions to
140131Roles. These definitions will be stored in the hyperdb. They don't need to be
141132pushed to the actual database though.
142133
134+ There will be two levels of Permission. The Class level permissions define
135+ logical permissions associated with all nodes of a particular class (or all
136+ classes). The Node level permissions define logical permissions associated
137+ with specific nodes by way of their user-linked properties.
138+
143139A permission module defines::
144140
145141 class InMemoryImmutableClass(hyperdb.Class):
@@ -178,9 +174,25 @@ A permission module defines::
178174 - permissions (PermissionClass Multilink)
179175 '''
180176
181- def hasPermission (db, userid , permission, classname ):
177+ def hasClassPermission (db, classname , permission, userid ):
182178 ''' Look through all the Roles, and hence Permissions, and see if
183179 "permission" is there for the specified classname.
180+
181+ '''
182+
183+ def hasNodePermission(db, classname, nodeid, userid, properties):
184+ ''' Check the named properties of the given node to see if the userid
185+ appears in them. If it does, then the user is granted this
186+ permission check.
187+
188+ 'propspec' consists of a list of property names. The property
189+ names must be the name of a property of classname, or a
190+ KeyError is raised. That property must be a Link or Multilink
191+ property, or a TypeError is raised.
192+
193+ If the property is a Link, the userid must match the property
194+ value. If the property is a Multilink, the userid must appear
195+ in the Multilink list.
184196 '''
185197
186198The instance dbinit module then has in ``open()``::
@@ -229,7 +241,26 @@ in ``init()``::
229241 user.create(username="anonymous", roles=[r])
230242
231243Then in the code that matters, calls to ``hasPermission`` are made to
232- determine if the user has permission to perform some action.
244+ determine if the user has permission to perform some action::
245+
246+ if security.hasClassPermission('issue', 'Edit', self.user):
247+ # all ok
248+
249+ if security.hasNodePermission('issue', nodeid, self.user, ['assignedto']):
250+ # all ok
251+
252+ The htmltemplate will implement a new tag, <permission> which has the form::
253+
254+ <permission require=name,name,name node=assignedto>
255+ HTML to display if the user has the permission.
256+ <else>
257+ HTML to display if the user does not have the permission.
258+ </permission>
259+
260+ where the require attribute gives a comma-separated list of permission names
261+ which are required, and the node attribute gives a comma-separated list of
262+ node properties whose value must match the current user's id. Either of these
263+ tests must pass or the permission check will fail.
233264
234265
235266Authentication of Users
0 commit comments