Change: restrict superuser modifications to superusers only

This commit is contained in:
shamoon 2025-10-24 16:25:59 -07:00
parent 276dc31abe
commit 63dab0ab09
No known key found for this signature in database
2 changed files with 39 additions and 0 deletions

View File

@ -2,9 +2,11 @@ import types
from unittest.mock import patch from unittest.mock import patch
from django.contrib.admin.sites import AdminSite from django.contrib.admin.sites import AdminSite
from django.contrib.auth.models import Permission
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.test import TestCase from django.test import TestCase
from django.utils import timezone from django.utils import timezone
from rest_framework import status
from documents import index from documents import index
from documents.admin import DocumentAdmin from documents.admin import DocumentAdmin
@ -125,3 +127,36 @@ class TestPaperlessAdmin(DirectoriesMixin, TestCase):
form.request = types.SimpleNamespace(user=superuser) form.request = types.SimpleNamespace(user=superuser)
self.assertTrue(form.is_valid()) self.assertTrue(form.is_valid())
self.assertEqual({}, form.errors) self.assertEqual({}, form.errors)
def test_superuser_can_only_be_modified_by_superuser(self):
superuser = User.objects.create_superuser(username="superuser", password="test")
user = User.objects.create(
username="test",
is_superuser=False,
is_staff=True,
)
change_user_perm = Permission.objects.get(codename="change_user")
user.user_permissions.add(change_user_perm)
self.client.force_login(user)
response = self.client.patch(
f"/api/users/{superuser.pk}/",
{"first_name": "Updated"},
content_type="application/json",
)
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
self.assertEqual(
response.content.decode(),
"Superusers can only be modified by other superusers",
)
self.client.logout()
self.client.force_login(superuser)
response = self.client.patch(
f"/api/users/{superuser.pk}/",
{"first_name": "Updated"},
content_type="application/json",
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
superuser.refresh_from_db()
self.assertEqual(superuser.first_name, "Updated")

View File

@ -125,6 +125,10 @@ class UserViewSet(ModelViewSet):
def update(self, request, *args, **kwargs): def update(self, request, *args, **kwargs):
user_to_update: User = self.get_object() user_to_update: User = self.get_object()
if not request.user.is_superuser and user_to_update.is_superuser:
return HttpResponseForbidden(
"Superusers can only be modified by other superusers",
)
if ( if (
not request.user.is_superuser not request.user.is_superuser
and request.data.get("is_superuser") is not None and request.data.get("is_superuser") is not None