@@ -18,6 +18,20 @@ class Permission:
18
18
- properties (optional)
19
19
- check function (optional)
20
20
- props_only (optional, internal field is limit_perm_to_props_only)
21
+ - filter function (optional) returns filter arguments for
22
+ determining which records are visible by the user. The filter
23
+ function comes into play when determining if a set of nodes
24
+ found via a filter call of a class can be seen by the user --
25
+ the normal way would be to call the permissions for each item
26
+ found, the filter call performs this on the database for all
27
+ nodes.
28
+ Signature of the filter function:
29
+ filter(db, userid, klass)
30
+ The filter must return a list of dictionaries with filter parameters.
31
+ Note that sort and group parameters of the filter call should
32
+ not be set by filter method (they will be overwritten) and the
33
+ parameter search_matches must not be set.
34
+ An empty list returned means no access for this filter method.
21
35
22
36
The klass may be unset, indicating that this permission is not
23
37
locked to a particular class. That means there may be multiple
@@ -47,14 +61,15 @@ class Permission:
47
61
limit_perm_to_props_only = False
48
62
49
63
def __init__ (self , name = '' , description = '' , klass = None ,
50
- properties = None , check = None , props_only = None ):
64
+ properties = None , check = None , props_only = None , filter = None ):
51
65
from roundup .anypy import findargspec
52
66
self .name = name
53
67
self .description = description
54
68
self .klass = klass
55
69
self .properties = properties
56
70
self ._properties_dict = support .TruthDict (properties )
57
71
self .check = check
72
+ self .filter = filter
58
73
if properties is not None :
59
74
# Set to None unless properties are defined.
60
75
# This means that:
@@ -211,6 +226,21 @@ def addPermission (self, *permissions):
211
226
self ._permissions [pn ][cn ] = dict (((False , []), (True , [])))
212
227
self ._permissions [pn ][cn ][bool (p .check )].append (p )
213
228
229
+ def filter_iter (self , permission , classname ):
230
+ """ Loop over all permissions for the current role on the class
231
+ with a check method (and props_only False).
232
+ """
233
+ if permission not in self ._permissions :
234
+ return
235
+ for c in (None , classname ):
236
+ if c not in self ._permissions [permission ]:
237
+ continue
238
+ perms = self ._permissions [permission ][c ][True ]
239
+ for p in perms :
240
+ if p .limit_perm_to_props_only and p .properties :
241
+ continue
242
+ yield p
243
+
214
244
def hasPermission (self , db , perm , uid , classname , property , itemid , chk ):
215
245
# if itemid is given a classname must, too, checked in caller
216
246
assert not itemid or classname
@@ -283,6 +313,17 @@ def __init__(self, db):
283
313
from roundup import mailgw
284
314
mailgw .initialiseSecurity (self )
285
315
316
+ def filter_iter (self , permission , userid , classname ):
317
+ """ Loop over all permissions for the current user on the class
318
+ with a check method (and props_only False).
319
+ """
320
+ for rolename in self .db .user .get_roles (userid ):
321
+ if not rolename or (rolename not in self .role ):
322
+ continue
323
+ r = self .role [rolename ]
324
+ for perm in r .filter_iter (permission , classname ):
325
+ yield perm
326
+
286
327
def getPermission (self , permission , classname = None , properties = None ,
287
328
check = None , props_only = None ):
288
329
''' Find the Permission matching the name and for the class, if the
@@ -359,6 +400,19 @@ def hasPermission(self, permission, userid, classname=None,
359
400
return v
360
401
return False
361
402
403
+ def is_filterable (self , permission , userid , classname ):
404
+ """ Check if all permissions for the current user on the class
405
+ with a check method (and props_only False) also have a
406
+ filter method. We only consider permissions with props_only
407
+ set to False. Note that this will return True if there are
408
+ no permissions with a check method found, the performed
409
+ checks later will find no matching records.
410
+ """
411
+ for perm in self .filter_iter (permission , userid , classname ):
412
+ if not perm .filter :
413
+ return False
414
+ return True
415
+
362
416
def roleHasSearchPermission (self , classname , property , * rolenames ):
363
417
""" For each of the given roles, check the permissions.
364
418
Property can be a transitive property.
0 commit comments