✨(documents) allow retrieving versions (list and detail)
Versions are retrieved directly from object storage and served on API endpoints. We make sure a user who is given access to a document will only see versions that were created after s.he gained access.
This commit is contained in:
committed by
Anthony LC
parent
8e262da8f5
commit
130e7a8c99
@@ -1,4 +1,5 @@
|
||||
"""API endpoints"""
|
||||
import json
|
||||
from io import BytesIO
|
||||
|
||||
from django.contrib.postgres.aggregates import ArrayAgg
|
||||
@@ -7,8 +8,9 @@ from django.db.models import (
|
||||
Q,
|
||||
Subquery,
|
||||
)
|
||||
from django.http import FileResponse
|
||||
from django.http import FileResponse, Http404
|
||||
|
||||
from botocore.exceptions import ClientError
|
||||
from rest_framework import (
|
||||
decorators,
|
||||
exceptions,
|
||||
@@ -291,6 +293,62 @@ class DocumentViewSet(
|
||||
resource_field_name = "document"
|
||||
queryset = models.Document.objects.all()
|
||||
|
||||
@decorators.action(detail=True, methods=["get"], url_path="versions")
|
||||
def versions_list(self, request, *args, **kwargs):
|
||||
"""
|
||||
Return the document's versions but only those created after the user got access
|
||||
to the document
|
||||
"""
|
||||
document = self.get_object()
|
||||
from_datetime = min(
|
||||
access.created_at
|
||||
for access in document.accesses.filter(
|
||||
Q(user=request.user) | Q(team__in=request.user.get_teams()),
|
||||
)
|
||||
)
|
||||
return drf_response.Response(
|
||||
document.get_versions_slice(from_datetime=from_datetime)
|
||||
)
|
||||
|
||||
@decorators.action(
|
||||
detail=True,
|
||||
methods=["get", "delete"],
|
||||
url_path="versions/(?P<version_id>[0-9a-f-]{36})",
|
||||
)
|
||||
# pylint: disable=unused-argument
|
||||
def versions_detail(self, request, pk, version_id, *args, **kwargs):
|
||||
"""Custom action to retrieve a specific version of a document"""
|
||||
document = self.get_object()
|
||||
|
||||
try:
|
||||
response = document.get_content_response(version_id=version_id)
|
||||
except (FileNotFoundError, ClientError) as err:
|
||||
raise Http404 from err
|
||||
|
||||
# Don't let users access versions that were created before they were given access
|
||||
# to the document
|
||||
from_datetime = min(
|
||||
access.created_at
|
||||
for access in document.accesses.filter(
|
||||
Q(user=request.user) | Q(team__in=request.user.get_teams()),
|
||||
)
|
||||
)
|
||||
if response["LastModified"] < from_datetime:
|
||||
raise Http404
|
||||
|
||||
if request.method == "DELETE":
|
||||
response = document.delete_version(version_id)
|
||||
return drf_response.Response(
|
||||
status=response["ResponseMetadata"]["HTTPStatusCode"]
|
||||
)
|
||||
|
||||
return drf_response.Response(
|
||||
{
|
||||
"content": json.loads(response["Body"].read()),
|
||||
"last_modified": response["LastModified"],
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
class DocumentAccessViewSet(
|
||||
ResourceAccessViewsetMixin,
|
||||
|
||||
Reference in New Issue
Block a user