Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ ctrl/command/middle-mouse click #2170
- 🐛(y-provider) destroy Y.Doc instances after each convert request #2129
- 🐛(backend) remove deleted sub documents in favorite_list endpoint #2083

### Fixed

- 🐛(backend) create_for_owner: add accesses before saving doc content #2124

Comment thread
Ash-Crow marked this conversation as resolved.
## [v4.8.3] - 2026-03-23

### Changed
Expand Down
4 changes: 3 additions & 1 deletion src/backend/core/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,6 @@ def create(self, validated_data):

document = models.Document.add_root(
title=validated_data["title"],
content=document_content,
creator=user,
)

Expand All @@ -535,6 +534,9 @@ def create(self, validated_data):
role=models.RoleChoices.OWNER,
)

document.content = document_content
document.save()

self._send_email_notification(document, validated_data, email, language)
return document

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,44 @@ def test_api_documents_create_for_owner_with_converter_exception(
assert response.json() == {"content": ["Could not convert content"]}


@override_settings(SERVER_TO_SERVER_API_TOKENS=["DummyToken"])
@pytest.mark.usefixtures("mock_convert_md")
def test_api_documents_create_for_owner_access_before_content():
"""
Accesses must exist before content is saved to object storage so the owner
has access to the very first version of the document.
"""
user = factories.UserFactory()
accesses_at_save_time = []

original_save_content = Document.save_content

def capturing_save_content(self, content):
accesses_at_save_time.extend(
list(self.accesses.values_list("user__sub", "role"))
)
return original_save_content(self, content)

data = {
"title": "My Document",
"content": "Document content",
"sub": str(user.sub),
"email": user.email,
}

with patch.object(Document, "save_content", capturing_save_content):
response = APIClient().post(
"/api/v1.0/documents/create-for-owner/",
data,
format="json",
HTTP_AUTHORIZATION="Bearer DummyToken",
)

assert response.status_code == 201
# The owner access must already exist when save_content is called
assert (str(user.sub), "owner") in accesses_at_save_time
Comment thread
Ash-Crow marked this conversation as resolved.


@override_settings(SERVER_TO_SERVER_API_TOKENS=["DummyToken"])
def test_api_documents_create_for_owner_with_empty_content():
"""The content should not be empty or a 400 error should be raised."""
Expand Down
Loading