(backend) validate user-provided document id is a valid UUID

Reject client-supplied IDs that are not valid UUIDs
when creating a document

Signed-off-by: Mohamed El Amine BOUKERFA <boukerfa.ma@gmail.com>
This commit is contained in:
Amine BOUKERFA
2026-05-26 07:57:36 +00:00
committed by GitHub
parent 24d58a1aa5
commit 8d42f814b7
2 changed files with 39 additions and 1 deletions
+6 -1
View File
@@ -245,11 +245,16 @@ class DocumentSerializer(ListDocumentSerializer):
return fields
def validate_id(self, value):
"""Ensure the provided ID does not already exist when creating a new document."""
"""Ensure the provided ID is a valid UUID and not already taken."""
request = self.context.get("request")
# Only check this on POST (creation)
if request and request.method == "POST":
if value.version not in (1, 3, 4, 5):
raise serializers.ValidationError(
"The provided ID is not a valid UUID."
)
if models.Document.objects.filter(id=value).exists():
raise serializers.ValidationError(
"A document with this ID already exists. You cannot override it."
@@ -143,3 +143,36 @@ def test_api_documents_create_force_id_existing():
assert response.json() == {
"id": ["A document with this ID already exists. You cannot override it."]
}
@pytest.mark.parametrize(
"forced_id",
[
# Nil UUID: every bit is zero, including the version nibble.
"00000000-0000-0000-0000-000000000000",
# Max UUID: version nibble is 0xf, not in {1, 3, 4, 5}.
"ffffffff-ffff-ffff-ffff-ffffffffffff",
# Non-RFC-4122 variant (Microsoft GUID): `.version` returns None.
"f47ac10b-58cc-4372-c567-0e02b2c3d479",
# RFC-4122 v2 (DCE security): valid variant but version not in {1, 3, 4, 5}.
"f47ac10b-58cc-2372-a567-0e02b2c3d479",
],
)
def test_api_documents_create_force_id_invalid_uuid(forced_id):
"""Forcing an ID with a non-standard UUID (nil, wrong variant, wrong version) is refused."""
user = factories.UserFactory()
client = APIClient()
client.force_login(user)
response = client.post(
"/api/v1.0/documents/",
{
"id": forced_id,
"title": "my document",
},
format="json",
)
assert response.status_code == 400
assert response.json() == {"id": ["The provided ID is not a valid UUID."]}
assert not Document.objects.exists()