diff --git a/arkindex/project/mixins.py b/arkindex/project/mixins.py index 31039e42c44a40b5f2f8cba22441fb15f125461f..c805ccd753702fdffae7a020be664382408aa056 100644 --- a/arkindex/project/mixins.py +++ b/arkindex/project/mixins.py @@ -34,21 +34,30 @@ class ACLMixin(object): """ if self.user.is_admin or self.user.is_internal: return model.objects.all() - filters = Q(max_level__gte=level) - if (public): - # Allow access to public instances if the public parameter is set - filters = filters | Q(public=True) - return model.objects \ + queryset = model.objects \ .filter( + # Filter instances with direct and groups rights for this user (They may be duplicated) Q(memberships__user=self.user) | Q(memberships__group__memberships__user=self.user) ) \ - .annotate(max_level=functions.Least( - 'memberships__level', - 'memberships__group__memberships__level' - )) \ - .filter(filters) \ - .distinct() + .annotate( + # Keep only the lowest level for each right via group + max_level=functions.Least( + # In case of direct right, group level will be skipped (Null value) + 'memberships__level', + 'memberships__group__memberships__level' + ) + ) \ + .filter( + # Ensure one of the right has an adequate level + max_level__gte=level + ) + + if (public): + # Allow access to public instances if the public parameter is set + queryset = queryset | model.objects.filter(public=True) + + return queryset.distinct() def has_access(self, instance, level): if self.user.is_admin or self.user.is_internal: