diff --git a/netbox/users/tests/test_models.py b/netbox/users/tests/test_models.py index fc59fe156..4e91ff289 100644 --- a/netbox/users/tests/test_models.py +++ b/netbox/users/tests/test_models.py @@ -232,3 +232,29 @@ class UserConfigTestCase(TestCase): # Clear a non-existing value; should fail silently userconfig.clear('invalid') + + +class RestrictedQuerySetTestCase(TestCase): + """ + Test the is_active handling of RestrictedQuerySet.restrict()'s superuser bypass. + """ + + @classmethod + def setUpTestData(cls): + # Token uses a plain RestrictedQuerySet manager, so its objects() exercises restrict() + # directly without requiring any object permissions to be configured. + cls.token = Token.objects.create(user=create_test_user('Token Owner')) + + def test_active_superuser_bypasses_restriction(self): + user = User.objects.create(username='active_su', is_superuser=True, is_active=True) + self.assertIn(self.token, Token.objects.restrict(user, 'view')) + + def test_inactive_superuser_does_not_bypass_restriction(self): + """ + A deactivated superuser must not bypass restrict(). Without an explicit + view permission they receive an empty queryset, mirroring the is_active + guard in ObjectPermissionMixin.has_perm. + """ + user = User.objects.create(username='inactive_su', is_superuser=True, is_active=False) + self.assertNotIn(self.token, Token.objects.restrict(user, 'view')) + self.assertEqual(Token.objects.restrict(user, 'view').count(), 0) diff --git a/netbox/utilities/api.py b/netbox/utilities/api.py index 4a4719418..e005cddef 100644 --- a/netbox/utilities/api.py +++ b/netbox/utilities/api.py @@ -44,7 +44,7 @@ class IsSuperuser(BasePermission): Allows access only to superusers. """ def has_permission(self, request, view): - return bool(request.user and request.user.is_superuser) + return bool(request.user and request.user.is_active and request.user.is_superuser) def get_serializer_for_model(model, prefix=''): diff --git a/netbox/utilities/querysets.py b/netbox/utilities/querysets.py index f3c838d27..b14fd8a85 100644 --- a/netbox/utilities/querysets.py +++ b/netbox/utilities/querysets.py @@ -49,7 +49,7 @@ class RestrictedQuerySet(QuerySet): permission_required = get_permission_for_model(self.model, action) # Bypass restriction for superusers and exempt views - if user and user.is_superuser or permission_is_exempt(permission_required): + if (user and user.is_active and user.is_superuser) or permission_is_exempt(permission_required): return self # User is anonymous or has not been granted the requisite permission