mirror of
https://github.com/suitenumerique/docs.git
synced 2026-09-10 03:37:52 +02:00
✨(backend) create a dedicated endpoint to update document content
We want a dedicated endpoint to update a document content. Previously, updating the content was made on the update action shared with all other document's properties. When the title is updated, the response contains the content, so a call to the s3 storage is made and we don't want this. Isolating the content update will allow us in the next commit to remove the content from the Document serializer.
This commit is contained in:
@@ -776,17 +776,15 @@ class DocumentViewSet(
|
||||
def perform_update(self, serializer):
|
||||
"""Check rules about collaboration."""
|
||||
if (
|
||||
serializer.validated_data.get("websocket", False)
|
||||
or not settings.COLLABORATION_WS_NOT_CONNECTED_READY_ONLY
|
||||
not serializer.validated_data.get("websocket", False)
|
||||
and settings.COLLABORATION_WS_NOT_CONNECTED_READY_ONLY
|
||||
and not self._can_user_edit_document(serializer.instance.id, set_cache=True)
|
||||
):
|
||||
return super().perform_update(serializer)
|
||||
raise drf.exceptions.PermissionDenied(
|
||||
"You are not allowed to edit this document."
|
||||
)
|
||||
|
||||
if self._can_user_edit_document(serializer.instance.id, set_cache=True):
|
||||
return super().perform_update(serializer)
|
||||
|
||||
raise drf.exceptions.PermissionDenied(
|
||||
"You are not allowed to edit this document."
|
||||
)
|
||||
return super().perform_update(serializer)
|
||||
|
||||
@drf.decorators.action(
|
||||
detail=True,
|
||||
@@ -1851,6 +1849,68 @@ class DocumentViewSet(
|
||||
|
||||
return drf.response.Response("authorized", headers=request.headers, status=200)
|
||||
|
||||
@drf.decorators.action(detail=True, methods=["patch"], url_path="content")
|
||||
def content(self, request, *args, **kwargs):
|
||||
"""Update the raw Yjs content of a document stored in S3."""
|
||||
document = self.get_object()
|
||||
serializer = serializers.DocumentContentSerializer(data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
|
||||
if (
|
||||
not serializer.validated_data.get("websocket", False)
|
||||
and settings.COLLABORATION_WS_NOT_CONNECTED_READY_ONLY
|
||||
and not self._can_user_edit_document(document.id, set_cache=True)
|
||||
):
|
||||
raise drf.exceptions.PermissionDenied(
|
||||
"You are not allowed to edit this document."
|
||||
)
|
||||
|
||||
content = serializer.validated_data["content"]
|
||||
try:
|
||||
extracted_attachments = set(extract_attachments(content))
|
||||
except ValueError:
|
||||
return drf_response.Response(
|
||||
"invalid yjs document", status=status.HTTP_400_BAD_REQUEST
|
||||
)
|
||||
|
||||
existing_attachments = set(document.attachments or [])
|
||||
new_attachments = extracted_attachments - existing_attachments
|
||||
if new_attachments:
|
||||
attachments_documents = (
|
||||
models.Document.objects.filter(
|
||||
attachments__overlap=list(new_attachments)
|
||||
)
|
||||
.only("path", "attachments")
|
||||
.order_by("path")
|
||||
)
|
||||
|
||||
user = self.request.user
|
||||
readable_per_se_paths = (
|
||||
models.Document.objects.readable_per_se(user)
|
||||
.order_by("path")
|
||||
.values_list("path", flat=True)
|
||||
)
|
||||
readable_attachments_paths = filter_descendants(
|
||||
[doc.path for doc in attachments_documents],
|
||||
readable_per_se_paths,
|
||||
skip_sorting=True,
|
||||
)
|
||||
|
||||
readable_attachments = set()
|
||||
for attachments_document in attachments_documents:
|
||||
if attachments_document.path not in readable_attachments_paths:
|
||||
continue
|
||||
readable_attachments.update(
|
||||
set(attachments_document.attachments) & new_attachments
|
||||
)
|
||||
|
||||
# Update attachments with readable keys
|
||||
document.attachments = list(existing_attachments | readable_attachments)
|
||||
document.content = content
|
||||
document.save()
|
||||
|
||||
return drf_response.Response(status=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
@drf.decorators.action(detail=True, methods=["get"], url_path="media-check")
|
||||
def media_check(self, request, *args, **kwargs):
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user