Fix: _validate_owner crashes on wrong-typed owner, not just missing id

Review caught that the previous fix only caught User.DoesNotExist,
but parameters is a bare DictField, so a list/dict/non-numeric-string
owner reaches User.objects.get(pk=owner) and raises an uncaught
TypeError/ValueError from Django's AutoField.get_prep_value instead.
This commit is contained in:
Trenton Holmes
2026-09-13 15:09:06 -07:00
parent f1b21628a9
commit 8ac8dd7a04
2 changed files with 33 additions and 1 deletions
+1 -1
View File
@@ -2039,7 +2039,7 @@ class BulkEditSerializer(
def _validate_owner(self, owner):
try:
return User.objects.get(pk=owner)
except User.DoesNotExist:
except (User.DoesNotExist, TypeError, ValueError):
raise serializers.ValidationError("Specified owner cannot be found")
def _validate_parameters_set_permissions(self, parameters) -> None:
+32
View File
@@ -1192,6 +1192,38 @@ class TestBulkEditAPI(DirectoriesMixin, APITestCase):
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
m.assert_not_called()
@mock.patch("documents.serialisers.bulk_edit.set_permissions")
def test_set_permissions_rejects_wrong_typed_owner(self, m) -> None:
"""
_validate_owner only caught User.DoesNotExist -- a wrong-typed
owner (list/dict/non-numeric string) reaches
User.objects.get(pk=owner) and raises an uncaught TypeError or
ValueError instead, since `parameters` is a bare DictField with
no type checking on "owner" at that level.
"""
self.setup_mock(m, "set_permissions")
for bad_owner in (["not", "an", "id"], {"nested": "dict"}, "not-a-number"):
with self.subTest(owner=bad_owner):
response = self.client.post(
"/api/documents/bulk_edit/",
json.dumps(
{
"documents": [self.doc2.id],
"method": "set_permissions",
"parameters": {
"set_permissions": {
"view": {"users": [self.user.id]},
},
"owner": bad_owner,
},
},
),
content_type="application/json",
)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
m.assert_not_called()
@mock.patch("documents.serialisers.bulk_edit.set_permissions")
def test_set_permissions_merge(self, m) -> None:
self.setup_mock(m, "set_permissions")