From 9d8c8f48331b4488150da2c370afdea677360b29 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Sun, 13 Jan 2019 22:57:59 -0400 Subject: [PATCH] Optimize permission check Convert the user permission check from a double Python loop to a single ORM query. Add methods to the Role model to grant or revoke permissions. Rename the method requester_has_this to user_has_this for clarity. Signed-off-by: Roberto Rosario --- mayan/apps/permissions/models.py | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/mayan/apps/permissions/models.py b/mayan/apps/permissions/models.py index d0eb4a7b2f..503df464aa 100644 --- a/mayan/apps/permissions/models.py +++ b/mayan/apps/permissions/models.py @@ -59,7 +59,7 @@ class StoredPermission(models.Model): def natural_key(self): return (self.namespace, self.name) - def requester_has_this(self, user): + def user_has_this(self, user): """ Helper method to check if an user has been granted this permission. The check is done sequentially over all of the user's groups and @@ -73,20 +73,13 @@ class StoredPermission(models.Model): ) return True - # Request is one of the permission's holders? - for group in user.groups.all(): - for role in group.roles.all(): - if self in role.permissions.all(): - logger.debug( - 'Permission "%s" granted to user "%s" through role "%s"', - self, user, role - ) - return True - - logger.debug( - 'Fallthru: Permission "%s" not granted to user "%s"', self, user - ) - return False + if Role.objects.filter(groups__user=user, permissions=self).exists(): + return True + else: + logger.debug( + 'Fallthru: Permission "%s" not granted to user "%s"', self, user + ) + return False @python_2_unicode_compatible @@ -120,8 +113,14 @@ class Role(models.Model): return self.label def get_absolute_url(self): - return reverse('permissions:role_list') + return reverse(viewname='permissions:role_list') + + def grant(self, permission): + self.permissions.add(permission.stored_permission) def natural_key(self): return (self.label,) natural_key.dependencies = ['auth.Group', 'permissions.StoredPermission'] + + def revoke(self, permission): + self.permissions.remove(permission.stored_permission)