1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Closes #9074: Enable referencing the current user when evaluating permission constraints

This commit is contained in:
jeremystretch
2022-07-01 13:34:10 -04:00
parent c6dfdf10e5
commit 12c138b341
8 changed files with 48 additions and 8 deletions

View File

@@ -80,14 +80,25 @@ def permission_is_exempt(name):
return False
def qs_filter_from_constraints(constraints):
def qs_filter_from_constraints(constraints, tokens=None):
"""
Construct a Q filter object from an iterable of ObjectPermission constraints.
Args:
tokens: A dictionary mapping string tokens to be replaced with a value.
"""
if tokens is None:
tokens = {}
def _replace_tokens(value, tokens):
if type(value) is list:
return list(map(lambda v: tokens.get(v, v), value))
return tokens.get(value, value)
params = Q()
for constraint in constraints:
if constraint:
params |= Q(**constraint)
params |= Q(**{k: _replace_tokens(v, tokens) for k, v in constraint.items()})
else:
# Found null constraint; permit model-level access
return Q()

View File

@@ -1,5 +1,6 @@
from django.db.models import QuerySet
from users.constants import CONSTRAINT_TOKEN_USER
from utilities.permissions import permission_is_exempt, qs_filter_from_constraints
@@ -28,7 +29,10 @@ class RestrictedQuerySet(QuerySet):
# Filter the queryset to include only objects with allowed attributes
else:
attrs = qs_filter_from_constraints(user._object_perm_cache[permission_required])
tokens = {
CONSTRAINT_TOKEN_USER: user,
}
attrs = qs_filter_from_constraints(user._object_perm_cache[permission_required], tokens)
# #8715: Avoid duplicates when JOIN on many-to-many fields without using DISTINCT.
# DISTINCT acts globally on the entire request, which may not be desirable.
allowed_objects = self.model.objects.filter(attrs)