Require view permissions for tag and document
Signed-off-by: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>
This commit is contained in:
@@ -247,6 +247,8 @@
|
||||
* Move the user set password views to the authentication app.
|
||||
* All views redirect to common's home view instead of the
|
||||
REDIRECT_URL setting.
|
||||
* Update tag document list and the document tag list
|
||||
views to require the view permissions for both objects.
|
||||
|
||||
3.1.11 (2019-04-XX)
|
||||
===================
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -68,9 +68,7 @@ class TagsApp(MayanAppConfig):
|
||||
DocumentTag = self.get_model(model_name='DocumentTag')
|
||||
Tag = self.get_model(model_name='Tag')
|
||||
|
||||
Document.add_to_class(
|
||||
name='attached_tags', value=method_document_get_tags
|
||||
)
|
||||
Document.add_to_class(name='get_tags', value=method_document_get_tags)
|
||||
|
||||
ModelEventType.register(
|
||||
model=Tag, event_types=(
|
||||
|
||||
@@ -4,12 +4,19 @@ from django.apps import apps
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
|
||||
def method_document_get_tags(self):
|
||||
def method_document_get_tags(self, permission, user):
|
||||
AccessControlList = apps.get_model(
|
||||
app_label='acls', model_name='AccessControlList'
|
||||
)
|
||||
DocumentTag = apps.get_model(app_label='tags', model_name='DocumentTag')
|
||||
|
||||
return DocumentTag.objects.filter(documents=self)
|
||||
return AccessControlList.objects.restrict_queryset(
|
||||
permission=permission,
|
||||
queryset=DocumentTag.objects.filter(documents=self), user=user
|
||||
)
|
||||
|
||||
|
||||
method_document_get_tags.help_text = _(
|
||||
'Return a the tags attached to the document.'
|
||||
)
|
||||
method_document_get_tags.short_description = _('get_tags()')
|
||||
|
||||
@@ -64,11 +64,21 @@ class Tag(models.Model):
|
||||
The count if filtered by access.
|
||||
"""
|
||||
queryset = AccessControlList.objects.restrict_queryset(
|
||||
permission_document_view, user, queryset=self.documents
|
||||
permission=permission_document_view, queryset=self.documents,
|
||||
user=user
|
||||
)
|
||||
|
||||
return queryset.count()
|
||||
|
||||
def get_documents(self, user):
|
||||
"""
|
||||
Return a filtered queryset documents that have this tag attached.
|
||||
"""
|
||||
return AccessControlList.objects.restrict_queryset(
|
||||
permission=permission_document_view, queryset=self.documents.all(),
|
||||
user=user
|
||||
)
|
||||
|
||||
def get_preview_widget(self):
|
||||
return widget_single_tag(tag=self)
|
||||
get_preview_widget.short_description = _('Preview')
|
||||
|
||||
@@ -110,8 +110,13 @@ class TagViewTestMixin(object):
|
||||
}
|
||||
)
|
||||
|
||||
def _request_test_tag_list_view(self):
|
||||
return self.get(viewname='tags:tag_list')
|
||||
|
||||
def _request_test_tag_document_list_view(self):
|
||||
return self.get(viewname='documents:document_list')
|
||||
return self.get(
|
||||
viewname='tags:tag_document_list', kwargs={'pk': self.test_tag.pk}
|
||||
)
|
||||
|
||||
def _request_test_document_tag_attach_view(self):
|
||||
return self.post(
|
||||
@@ -146,3 +151,10 @@ class TagViewTestMixin(object):
|
||||
'tags': self.test_tag.pk,
|
||||
}
|
||||
)
|
||||
|
||||
def _request_test_document_tag_list_view(self):
|
||||
return self.get(
|
||||
viewname='tags:document_tag_list', kwargs={
|
||||
'pk': self.test_document.pk
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.utils.encoding import force_text
|
||||
|
||||
from mayan.apps.common.tests import GenericViewTestCase
|
||||
from mayan.apps.documents.permissions import permission_document_view
|
||||
from mayan.apps.documents.tests import GenericDocumentViewTestCase
|
||||
@@ -100,8 +102,27 @@ class TagViewTestCase(TagTestMixin, TagViewTestMixin, GenericViewTestCase):
|
||||
self.test_tag.refresh_from_db()
|
||||
self.assertNotEqual(self.test_tag.label, tag_label)
|
||||
|
||||
def test_tag_list_view_with_no_permission(self):
|
||||
self._create_test_tag()
|
||||
|
||||
response = self._request_test_tag_list_view()
|
||||
self.assertNotContains(
|
||||
response=response, text=self.test_tag.label, status_code=200
|
||||
)
|
||||
|
||||
def test_tag_list_view_with_access(self):
|
||||
self._create_test_tag()
|
||||
|
||||
self.grant_access(obj=self.test_tag, permission=permission_tag_view)
|
||||
|
||||
response = self._request_test_tag_list_view()
|
||||
self.assertContains(
|
||||
response=response, text=self.test_tag.label, status_code=200
|
||||
)
|
||||
|
||||
|
||||
class TagDocumentViewTestCase(TagTestMixin, TagViewTestMixin, GenericDocumentViewTestCase):
|
||||
"""
|
||||
def test_document_tags_widget_no_permissions(self):
|
||||
self._create_test_tag()
|
||||
|
||||
@@ -126,6 +147,58 @@ class TagDocumentViewTestCase(TagTestMixin, TagViewTestMixin, GenericDocumentVie
|
||||
self.assertContains(
|
||||
response=response, text=self.test_tag.label, status_code=200
|
||||
)
|
||||
"""
|
||||
def test_document_tags_list_no_permissions(self):
|
||||
self._create_test_tag()
|
||||
|
||||
self.test_tag.documents.add(self.test_document)
|
||||
|
||||
response = self._request_test_document_tag_list_view()
|
||||
self.assertNotContains(
|
||||
response=response, text=force_text(self.test_tag), status_code=404
|
||||
)
|
||||
|
||||
def test_document_tags_list_with_document_access(self):
|
||||
self._create_test_tag()
|
||||
|
||||
self.test_tag.documents.add(self.test_document)
|
||||
|
||||
self.grant_access(
|
||||
obj=self.test_document, permission=permission_tag_view
|
||||
)
|
||||
|
||||
response = self._request_test_document_tag_list_view()
|
||||
self.assertNotContains(
|
||||
response=response, text=force_text(self.test_tag), status_code=200
|
||||
)
|
||||
|
||||
def test_document_tags_list_with_tag_access(self):
|
||||
self._create_test_tag()
|
||||
|
||||
self.test_tag.documents.add(self.test_document)
|
||||
|
||||
self.grant_access(obj=self.test_tag, permission=permission_tag_view)
|
||||
|
||||
response = self._request_test_document_tag_list_view()
|
||||
self.assertNotContains(
|
||||
response=response, text=force_text(self.test_tag), status_code=404
|
||||
)
|
||||
|
||||
def test_document_tags_list_with_full_access(self):
|
||||
self._create_test_tag()
|
||||
|
||||
self.test_tag.documents.add(self.test_document)
|
||||
|
||||
self.grant_access(obj=self.test_tag, permission=permission_tag_view)
|
||||
self.grant_access(
|
||||
obj=self.test_document, permission=permission_tag_view
|
||||
)
|
||||
|
||||
response = self._request_test_document_tag_list_view()
|
||||
self.assertContains(
|
||||
response=response, text=force_text(self.test_tag), status_code=200
|
||||
)
|
||||
|
||||
|
||||
def test_document_attach_tag_view_no_permission(self):
|
||||
self._create_test_tag()
|
||||
|
||||
@@ -13,6 +13,7 @@ from mayan.apps.common.generics import (
|
||||
MultipleObjectFormActionView, MultipleObjectConfirmActionView,
|
||||
SingleObjectCreateView, SingleObjectEditView, SingleObjectListView
|
||||
)
|
||||
from mayan.apps.common.mixins import ExternalObjectMixin
|
||||
from mayan.apps.documents.models import Document
|
||||
from mayan.apps.documents.views import DocumentListView
|
||||
from mayan.apps.documents.permissions import permission_document_view
|
||||
@@ -96,7 +97,9 @@ class TagAttachActionView(MultipleObjectFormActionView):
|
||||
return super(TagAttachActionView, self).get_post_action_redirect()
|
||||
|
||||
def object_action(self, form, instance):
|
||||
attached_tags = instance.attached_tags()
|
||||
attached_tags = instance.get_tags(
|
||||
permission=permission_tag_attach, user=self.request.user
|
||||
)
|
||||
|
||||
for tag in form.cleaned_data['tags']:
|
||||
AccessControlList.objects.check_access(
|
||||
@@ -227,12 +230,13 @@ class TagListView(SingleObjectListView):
|
||||
return Tag.objects.all()
|
||||
|
||||
|
||||
class TagDocumentListView(DocumentListView):
|
||||
def get_tag(self):
|
||||
return get_object_or_404(klass=Tag, pk=self.kwargs['pk'])
|
||||
class TagDocumentListView(ExternalObjectMixin, DocumentListView):
|
||||
external_object_class = Tag
|
||||
external_object_permission = permission_tag_view
|
||||
external_object_pk_url_kwarg = 'pk'
|
||||
|
||||
def get_document_queryset(self):
|
||||
return self.get_tag().documents.all()
|
||||
return self.get_tag().get_documents(user=self.request.user).all()
|
||||
|
||||
def get_extra_context(self):
|
||||
context = super(TagDocumentListView, self).get_extra_context()
|
||||
@@ -244,39 +248,38 @@ class TagDocumentListView(DocumentListView):
|
||||
)
|
||||
return context
|
||||
|
||||
def get_tag(self):
|
||||
return self.get_external_object()
|
||||
|
||||
class DocumentTagListView(TagListView):
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
self.document = get_object_or_404(klass=Document, pk=self.kwargs['pk'])
|
||||
|
||||
AccessControlList.objects.check_access(
|
||||
obj=self.document, permissions=(permission_document_view,),
|
||||
user=request.user,
|
||||
)
|
||||
|
||||
return super(DocumentTagListView, self).dispatch(
|
||||
request, *args, **kwargs
|
||||
)
|
||||
class DocumentTagListView(ExternalObjectMixin, TagListView):
|
||||
external_object_class = Document
|
||||
external_object_permission = permission_tag_view
|
||||
external_object_pk_url_kwarg = 'pk'
|
||||
|
||||
def get_extra_context(self):
|
||||
context = super(DocumentTagListView, self).get_extra_context()
|
||||
context.update(
|
||||
{
|
||||
'hide_link': True,
|
||||
'no_results_title': _('Document has no tags attached'),
|
||||
'no_results_main_link': link_document_tag_multiple_attach.resolve(
|
||||
context=RequestContext(
|
||||
request=self.request, dict_={'object': self.document}
|
||||
self.request, {'object': self.get_external_object()}
|
||||
)
|
||||
),
|
||||
'object': self.document,
|
||||
'title': _('Tags for document: %s') % self.document,
|
||||
'no_results_title': _('Document has no tags attached'),
|
||||
'object': self.get_external_object(),
|
||||
'title': _(
|
||||
'Tags for document: %s'
|
||||
) % self.get_external_object(),
|
||||
}
|
||||
)
|
||||
return context
|
||||
|
||||
def get_tag_queryset(self):
|
||||
return self.document.attached_tags().all()
|
||||
def get_source_queryset(self):
|
||||
return self.get_external_object().get_tags(
|
||||
permission=permission_tag_view, user=self.request.user
|
||||
).all()
|
||||
|
||||
|
||||
class TagRemoveActionView(MultipleObjectFormActionView):
|
||||
@@ -343,7 +346,9 @@ class TagRemoveActionView(MultipleObjectFormActionView):
|
||||
return super(TagRemoveActionView, self).get_post_action_redirect()
|
||||
|
||||
def object_action(self, form, instance):
|
||||
attached_tags = instance.attached_tags()
|
||||
attached_tags = instance.get_tags(
|
||||
permission=permission_tag_remove, user=self.request.user
|
||||
)
|
||||
|
||||
for tag in form.cleaned_data['tags']:
|
||||
AccessControlList.objects.check_access(
|
||||
|
||||
Reference in New Issue
Block a user