changeset 8121:2a4d0413bd20 permission-performance

When computing batch check class-permissions first
author Ralf Schlatterbeck <rsc@runtux.com>
date Fri, 18 Oct 2024 18:04:46 +0200
parents d4fa7a9c3a21
children b358da7c89e5
files roundup/cgi/templating.py roundup/security.py
diffstat 2 files changed, 11 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/roundup/cgi/templating.py	Fri Oct 18 16:54:24 2024 +0200
+++ b/roundup/cgi/templating.py	Fri Oct 18 18:04:46 2024 +0200
@@ -3453,9 +3453,12 @@
             matches = None
 
         # filter for visibility
-        allowed = [itemid for itemid in klass.filter(matches, filterspec,
-                                                     sort, group)
-                   if check(permission, userid, self.classname, itemid=itemid)]
+        item_ids = klass.filter(matches, filterspec, sort, group)
+        if check(permission, userid, self.classname, only_no_check = True):
+            allowed = item_ids
+        else:
+            allowed = [id for id in item_ids
+                       if check(permission, userid, self.classname, itemid=id)]
 
         # return the batch object, using IDs only
         return Batch(self.client, allowed, self.pagesize, self.startwith,
--- a/roundup/security.py	Fri Oct 18 16:54:24 2024 +0200
+++ b/roundup/security.py	Fri Oct 18 18:04:46 2024 +0200
@@ -310,7 +310,7 @@
                                                                   classname))
 
     def hasPermission(self, permission, userid, classname=None,
-                      property=None, itemid=None):
+                      property=None, itemid=None, only_no_check=False):
         '''Look through all the Roles, and hence Permissions, and
            see if "permission" exists given the constraints of
            classname, property, itemid, and props_only.
@@ -345,7 +345,10 @@
         # Note that checks with a check method are typically a lot more
         # expensive than the ones without. So we check the ones without
         # a check method first
-        for has_check in False, True:
+        checklist = (False, True)
+        if only_no_check:
+            checklist = (False,)
+        for has_check in checklist:
             for rolename in self.db.user.get_roles(userid):
                 if not rolename or (rolename not in self.role):
                     continue

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