From ba3ad75ecc2fd9ccaa1976e99f8377f7df15b407 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Mon, 9 May 2022 16:00:46 +0200 Subject: [PATCH 8/9] rbac: add direct parameter to parents and children methods (#62013) It will limit the parents/children roles returned to those with a direct inheritance relation. --- src/django_rbac/managers.py | 34 ++++++++++++++++++++++++---------- src/django_rbac/models.py | 12 ++++++++---- 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/django_rbac/managers.py b/src/django_rbac/managers.py index 7aaf85f8..d7e66439 100644 --- a/src/django_rbac/managers.py +++ b/src/django_rbac/managers.py @@ -107,11 +107,18 @@ class RoleQuerySet(query.QuerySet): def for_user(self, user): return self.filter(members=user).parents().distinct() - def parents(self, include_self=True, annotate=False): - qs = self.model.objects.filter( - child_relation__deleted__isnull=True, - child_relation__child__in=self, - ) + def parents(self, include_self=True, annotate=False, direct=None): + if direct is None: + qs = self.model.objects.filter( + child_relation__deleted__isnull=True, + child_relation__child__in=self, + ) + else: + qs = self.model.objects.filter( + child_relation__deleted__isnull=True, + child_relation__child__in=self, + child_relation__direct=direct, + ) if include_self: qs = self | qs qs = qs.distinct() @@ -119,11 +126,18 @@ class RoleQuerySet(query.QuerySet): qs = qs.annotate(direct=models.Max(IntCast('child_relation__direct'))) return qs - def children(self, include_self=True, annotate=False): - qs = self.model.objects.filter( - parent_relation__deleted__isnull=True, - parent_relation__parent__in=self, - ) + def children(self, include_self=True, annotate=False, direct=None): + if direct is None: + qs = self.model.objects.filter( + parent_relation__deleted__isnull=True, + parent_relation__parent__in=self, + ) + else: + qs = self.model.objects.filter( + parent_relation__deleted__isnull=True, + parent_relation__parent__in=self, + parent_relation__direct=direct, + ) if include_self: qs = self | qs qs = qs.distinct() diff --git a/src/django_rbac/models.py b/src/django_rbac/models.py index 228c69d5..0931a89b 100644 --- a/src/django_rbac/models.py +++ b/src/django_rbac/models.py @@ -209,12 +209,16 @@ class RoleAbstractBase(AbstractOrganizationalUnitScopedBase, AbstractBase): RoleParenting = utils.get_role_parenting_model() RoleParenting.objects.soft_delete(parent, self) - def parents(self, include_self=True, annotate=False): - return self.__class__.objects.filter(pk=self.pk).parents(include_self=include_self, annotate=annotate) + def parents(self, include_self=True, annotate=False, direct=None): + return self.__class__.objects.filter(pk=self.pk).parents( + include_self=include_self, annotate=annotate, direct=None + ) - def children(self, include_self=True, annotate=False): + def children(self, include_self=True, annotate=False, direct=None): return self.__class__.objects.filter(pk=self.pk).children( - include_self=include_self, annotate=annotate + include_self=include_self, + annotate=annotate, + direct=direct, ) def all_members(self): -- 2.35.1