comparison roundup/cgi/templating.py @ 8126:f7bd22bdef9d permission-performance

Move permission check code to hyperdb Now the hyperdb has a method filter_with_permissions that performs the permission checks before (for filtering on sort/group/filterspec arguments) and after a call to hyperdb.filter. This also fixes possible problems on the unfiltered sort/group/filterspec arguments in roundup/rest.py and roundup/cgi/templating.py
author Ralf Schlatterbeck <rsc@runtux.com>
date Mon, 21 Oct 2024 18:12:03 +0200
parents b358da7c89e5
children 2a7c3eeaf167
comparison
equal deleted inserted replaced
8125:b358da7c89e5 8126:f7bd22bdef9d
3419 """ % (self._client.client_nonce, self.base) 3419 """ % (self._client.client_nonce, self.base)
3420 3420
3421 def batch(self, permission='View'): 3421 def batch(self, permission='View'):
3422 """ Return a batch object for results from the "current search" 3422 """ Return a batch object for results from the "current search"
3423 """ 3423 """
3424 sec = self._client.db.security 3424 check = self._client.db.security.hasPermission
3425 check = sec.hasPermission
3426 userid = self._client.userid 3425 userid = self._client.userid
3427 if not check('Web Access', userid): 3426 if not check('Web Access', userid):
3428 return Batch(self.client, [], self.pagesize, self.startwith, 3427 return Batch(self.client, [], self.pagesize, self.startwith,
3429 classname=self.classname) 3428 classname=self.classname)
3430 3429
3431 filterspec = self.filterspec 3430 fspec = self.filterspec
3432 sort = self.sort 3431 sort = self.sort
3433 group = self.group 3432 group = self.group
3434 3433
3435 # get the list of ids we're batching over 3434 # get the list of ids we're batching over
3436 klass = self.client.db.getclass(self.classname) 3435 klass = self.client.db.getclass(self.classname)
3452 )], klass) 3451 )], klass)
3453 else: 3452 else:
3454 matches = None 3453 matches = None
3455 3454
3456 # filter for visibility 3455 # filter for visibility
3457 item_ids = klass.filter(matches, filterspec, sort, group) 3456 allowed = klass.filter_with_permissions(
3458 cn = self.classname 3457 matches, fspec, sort, group, permission=permission, userid=userid
3459 if check(permission, userid, cn, only_no_check = True): 3458 )
3460 allowed = item_ids
3461 else:
3462 # Note that is_filterable returns True if no permissions are
3463 # found. This makes it fail early (with an empty allowed list)
3464 # instead of running through all ids with an empty
3465 # permission list.
3466 if sec.is_filterable(permission, userid, cn):
3467 new_ids = set(item_ids)
3468 confirmed = set()
3469 for perm in sec.filter_iter(permission, userid, cn):
3470 fargs = perm.filter(self._client.db, userid, klass)
3471 for farg in fargs:
3472 farg.update(sort=sort, group=group, retired=False)
3473 result = klass.filter(list(new_ids), **farg)
3474 new_ids.difference_update(result)
3475 confirmed.update(result)
3476 # all allowed?
3477 if not new_ids:
3478 break
3479 # all allowed?
3480 if not new_ids:
3481 break
3482 allowed = list(confirmed)
3483 else:
3484 allowed = [id for id in item_ids
3485 if check(permission, userid, cn, itemid=id)]
3486 3459
3487 # return the batch object, using IDs only 3460 # return the batch object, using IDs only
3488 return Batch(self.client, allowed, self.pagesize, self.startwith, 3461 return Batch(self.client, allowed, self.pagesize, self.startwith,
3489 classname=self.classname) 3462 classname=self.classname)
3490 3463

Roundup Issue Tracker: http://roundup-tracker.org/