feat: add document management views, URLs, and permission unit tests
This commit is contained in:
parent
80f2956872
commit
061fb6dc62
3 changed files with 820 additions and 777 deletions
|
|
@ -8,7 +8,17 @@ from common.models import Role, UserConfig
|
||||||
from interventions.models import Intervention
|
from interventions.models import Intervention
|
||||||
from projects.models import Project
|
from projects.models import Project
|
||||||
|
|
||||||
from .models import DocumentAttachment, DocumentFolder, DocumentFolderShare, DocumentShare, ManagedDocument
|
from .models import (
|
||||||
|
DocumentAccessLink,
|
||||||
|
DocumentAttachment,
|
||||||
|
DocumentFolder,
|
||||||
|
DocumentFolderAccessLink,
|
||||||
|
DocumentFolderAttachment,
|
||||||
|
DocumentFolderShare,
|
||||||
|
DocumentShare,
|
||||||
|
DocumentVersion,
|
||||||
|
ManagedDocument,
|
||||||
|
)
|
||||||
from .views import ensure_document_deletable
|
from .views import ensure_document_deletable
|
||||||
from .permissions import (
|
from .permissions import (
|
||||||
filter_documents_for_user,
|
filter_documents_for_user,
|
||||||
|
|
@ -772,3 +782,30 @@ class DocumentGeoreferenceAutoZoomTests(TestCase):
|
||||||
from .views import _get_associated_asset_coords
|
from .views import _get_associated_asset_coords
|
||||||
coords = _get_associated_asset_coords(self.document)
|
coords = _get_associated_asset_coords(self.document)
|
||||||
self.assertEqual(coords, [4.3517, 50.8503])
|
self.assertEqual(coords, [4.3517, 50.8503])
|
||||||
|
|
||||||
|
|
||||||
|
class PublicAccessLinkTests(TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.owner = User.objects.create_user(username="link_owner", password="pwd")
|
||||||
|
self.document = ManagedDocument.objects.create(title="Public Test Doc", created_by=self.owner)
|
||||||
|
self.doc_link = DocumentAccessLink.objects.create(
|
||||||
|
document=self.document,
|
||||||
|
permission=ManagedDocument.PERMISSION_VIEW,
|
||||||
|
)
|
||||||
|
self.folder = DocumentFolder.objects.create(name="Public Folder", slug="public-folder", created_by=self.owner)
|
||||||
|
self.folder_link = DocumentFolderAccessLink.objects.create(
|
||||||
|
folder=self.folder,
|
||||||
|
permission=ManagedDocument.PERMISSION_VIEW,
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_anonymous_user_can_access_public_document_view(self):
|
||||||
|
url = reverse("documents:public_view", args=[self.doc_link.token])
|
||||||
|
response = self.client.get(url)
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
self.assertContains(response, "Public Test Doc")
|
||||||
|
|
||||||
|
def test_anonymous_user_can_access_public_folder_view(self):
|
||||||
|
url = reverse("documents:folder_public", args=[self.folder_link.token])
|
||||||
|
response = self.client.get(url)
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
self.assertContains(response, "Public Folder")
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
from django.contrib.auth.decorators import login_not_required
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
|
|
||||||
from . import views
|
from . import views
|
||||||
|
|
@ -60,11 +61,11 @@ urlpatterns = [
|
||||||
path("<int:pk>/remove-folder/<int:folder_id>/", views.RemoveFolderFromDocumentView.as_view(), name="remove_folder"),
|
path("<int:pk>/remove-folder/<int:folder_id>/", views.RemoveFolderFromDocumentView.as_view(), name="remove_folder"),
|
||||||
path("<int:pk>/add-tag/", views.AddTagToDocumentView.as_view(), name="add_tag"),
|
path("<int:pk>/add-tag/", views.AddTagToDocumentView.as_view(), name="add_tag"),
|
||||||
path("<int:pk>/remove-tag/<int:tag_id>/", views.RemoveTagFromDocumentView.as_view(), name="remove_tag"),
|
path("<int:pk>/remove-tag/<int:tag_id>/", views.RemoveTagFromDocumentView.as_view(), name="remove_tag"),
|
||||||
path("public/<str:token>/", views.PublicDocumentView.as_view(), name="public_view"),
|
path("public/<str:token>/", login_not_required(views.PublicDocumentView.as_view()), name="public_view"),
|
||||||
path("public/<str:token>/download/", views.PublicDocumentDownloadView.as_view(), name="public_download"),
|
path("public/<str:token>/download/", login_not_required(views.PublicDocumentDownloadView.as_view()), name="public_download"),
|
||||||
path(
|
path(
|
||||||
"folders/public/<str:token>/",
|
"folders/public/<str:token>/",
|
||||||
views.PublicFolderView.as_view(),
|
login_not_required(views.PublicFolderView.as_view()),
|
||||||
name="folder_public",
|
name="folder_public",
|
||||||
),
|
),
|
||||||
path("<int:pk>/georeference/", views.DocumentGeoreferenceView.as_view(), name="georeference"),
|
path("<int:pk>/georeference/", views.DocumentGeoreferenceView.as_view(), name="georeference"),
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import mimetypes
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
|
from django.contrib.auth.decorators import login_not_required
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
from django.core.exceptions import PermissionDenied
|
from django.core.exceptions import PermissionDenied
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
|
|
@ -11,6 +12,7 @@ from django.db.models.functions import Lower
|
||||||
from django.shortcuts import get_object_or_404, redirect, render
|
from django.shortcuts import get_object_or_404, redirect, render
|
||||||
from django.urls import reverse, reverse_lazy
|
from django.urls import reverse, reverse_lazy
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
from django.utils.decorators import method_decorator
|
||||||
from django.utils.encoding import smart_str
|
from django.utils.encoding import smart_str
|
||||||
from django.utils.http import url_has_allowed_host_and_scheme
|
from django.utils.http import url_has_allowed_host_and_scheme
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
@ -1352,6 +1354,7 @@ class RemoveTagFromDocumentView(LoginRequiredMixin, View):
|
||||||
return redirect(document.get_absolute_url())
|
return redirect(document.get_absolute_url())
|
||||||
|
|
||||||
|
|
||||||
|
@method_decorator(login_not_required, name="dispatch")
|
||||||
class PublicDocumentView(View):
|
class PublicDocumentView(View):
|
||||||
template_name = "documents/document_public.html"
|
template_name = "documents/document_public.html"
|
||||||
|
|
||||||
|
|
@ -1376,6 +1379,7 @@ class PublicDocumentView(View):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@method_decorator(login_not_required, name="dispatch")
|
||||||
class PublicDocumentDownloadView(View):
|
class PublicDocumentDownloadView(View):
|
||||||
def get(self, request, token):
|
def get(self, request, token):
|
||||||
link = get_object_or_404(
|
link = get_object_or_404(
|
||||||
|
|
@ -1409,6 +1413,7 @@ class PublicDocumentDownloadView(View):
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
@method_decorator(login_not_required, name="dispatch")
|
||||||
class PublicFolderView(View):
|
class PublicFolderView(View):
|
||||||
template_name = "documents/documentfolder_public.html"
|
template_name = "documents/documentfolder_public.html"
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue