Convert the signature download view to CBV and add corresponding test.

This commit is contained in:
Roberto Rosario
2016-03-29 05:12:04 -04:00
parent 3b593e10fd
commit b9d75e525f
6 changed files with 93 additions and 48 deletions

View File

@@ -12,7 +12,6 @@ from acls import ModelPermission
from common import ( from common import (
MayanAppConfig, menu_object, menu_sidebar MayanAppConfig, menu_object, menu_sidebar
) )
from common.widgets import two_state_template
from mayan.celery import app from mayan.celery import app
from navigation import SourceColumn from navigation import SourceColumn
@@ -56,8 +55,6 @@ class DocumentSignaturesApp(MayanAppConfig):
app_label='django_gpg', model_name='Key' app_label='django_gpg', model_name='Key'
) )
DetachedSignature = self.get_model('DetachedSignature')
EmbeddedSignature = self.get_model('EmbeddedSignature') EmbeddedSignature = self.get_model('EmbeddedSignature')
SignatureBaseModel = self.get_model('SignatureBaseModel') SignatureBaseModel = self.get_model('SignatureBaseModel')

View File

@@ -9,12 +9,6 @@ from django_gpg.models import Key
from .models import SignatureBaseModel from .models import SignatureBaseModel
class DetachedSignatureForm(forms.Form):
file = forms.FileField(
label=_('Signature file'),
)
class DocumentVersionSignatureDetailForm(DetailForm): class DocumentVersionSignatureDetailForm(DetailForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
extra_fields = ( extra_fields = (
@@ -70,7 +64,9 @@ class DocumentVersionSignatureDetailForm(DetailForm):
) )
kwargs['extra_fields'] = extra_fields kwargs['extra_fields'] = extra_fields
super(DocumentVersionSignatureDetailForm, self).__init__(*args, **kwargs) super(
DocumentVersionSignatureDetailForm, self
).__init__(*args, **kwargs)
class Meta: class Meta:
fields = () fields = ()

View File

@@ -98,7 +98,9 @@ class EmbeddedSignature(SignatureBaseModel):
with self.document_version.open(raw=raw) as file_object: with self.document_version.open(raw=raw) as file_object:
try: try:
verify_result = Key.objects.verify_file(file_object=file_object) verify_result = Key.objects.verify_file(
file_object=file_object
)
except VerificationError as exception: except VerificationError as exception:
# Not signed # Not signed
logger.debug( logger.debug(
@@ -113,6 +115,7 @@ class EmbeddedSignature(SignatureBaseModel):
super(EmbeddedSignature, self).save(*args, **kwargs) super(EmbeddedSignature, self).save(*args, **kwargs)
@python_2_unicode_compatible
class DetachedSignature(SignatureBaseModel): class DetachedSignature(SignatureBaseModel):
signature_file = models.FileField( signature_file = models.FileField(
blank=True, null=True, storage=storage_backend, upload_to=upload_to, blank=True, null=True, storage=storage_backend, upload_to=upload_to,
@@ -123,6 +126,9 @@ class DetachedSignature(SignatureBaseModel):
verbose_name = _('Document version detached signature') verbose_name = _('Document version detached signature')
verbose_name_plural = _('Document version detached signatures') verbose_name_plural = _('Document version detached signatures')
def __str__(self):
return '{}-{}'.format(self.document_version, _('signature'))
def delete(self, *args, **kwargs): def delete(self, *args, **kwargs):
self.signature_file.storage.delete(self.signature_file.name) self.signature_file.storage.delete(self.signature_file.name)
super(DetachedSignature, self).delete(*args, **kwargs) super(DetachedSignature, self).delete(*args, **kwargs)

View File

@@ -2,8 +2,9 @@ from __future__ import absolute_import, unicode_literals
from django.core.files import File from django.core.files import File
from django_downloadview.test import assert_download_response
from django_gpg.models import Key from django_gpg.models import Key
from documents.permissions import permission_document_view
from documents.tests.literals import TEST_DOCUMENT_PATH from documents.tests.literals import TEST_DOCUMENT_PATH
from documents.tests.test_views import GenericDocumentViewTestCase from documents.tests.test_views import GenericDocumentViewTestCase
from user_management.tests import ( from user_management.tests import (
@@ -168,3 +169,51 @@ class SignaturesViewTestCase(GenericDocumentViewTestCase):
self.assertEqual(response.status_code, 302) self.assertEqual(response.status_code, 302)
self.assertEqual(DetachedSignature.objects.count(), 1) self.assertEqual(DetachedSignature.objects.count(), 1)
def test_signature_download_view_no_permission(self):
with open(TEST_DOCUMENT_PATH) as file_object:
document = self.document_type.new_document(
file_object=file_object
)
with open(TEST_SIGNATURE_FILE_PATH) as file_object:
signature = DetachedSignature.objects.create(
document_version=document.latest_version,
signature_file=File(file_object)
)
self.login(username=TEST_USER_USERNAME, password=TEST_USER_PASSWORD)
response = self.get(
'signatures:document_version_signature_download',
args=(signature.pk,),
)
self.assertEqual(response.status_code, 403)
def test_signature_download_view_with_permission(self):
with open(TEST_DOCUMENT_PATH) as file_object:
document = self.document_type.new_document(
file_object=file_object
)
with open(TEST_SIGNATURE_FILE_PATH) as file_object:
signature = DetachedSignature.objects.create(
document_version=document.latest_version,
signature_file=File(file_object)
)
self.login(username=TEST_USER_USERNAME, password=TEST_USER_PASSWORD)
self.role.permissions.add(
permission_document_version_signature_download.stored_permission
)
response = self.get(
'signatures:document_version_signature_download',
args=(signature.pk,),
)
assert_download_response(
self, response=response, content=signature.signature_file.read(),
)

View File

@@ -4,11 +4,12 @@ from django.conf.urls import patterns, url
from .views import ( from .views import (
DocumentVersionSignatureDeleteView, DocumentVersionSignatureDetailView, DocumentVersionSignatureDeleteView, DocumentVersionSignatureDetailView,
DocumentVersionSignatureListView, DocumentVersionSignatureUploadView DocumentSignatureDownloadView, DocumentVersionSignatureListView,
DocumentVersionSignatureUploadView
) )
urlpatterns = patterns( urlpatterns = patterns(
'document_signatures.views', '',
url( url(
r'^(?P<pk>\d+)/details/$', r'^(?P<pk>\d+)/details/$',
DocumentVersionSignatureDetailView.as_view(), DocumentVersionSignatureDetailView.as_view(),
@@ -16,7 +17,7 @@ urlpatterns = patterns(
), ),
url( url(
r'^signature/(?P<pk>\d+)/download/$', r'^signature/(?P<pk>\d+)/download/$',
'document_signature_download', DocumentSignatureDownloadView.as_view(),
name='document_version_signature_download' name='document_version_signature_download'
), ),
url( url(

View File

@@ -2,25 +2,20 @@ from __future__ import absolute_import, unicode_literals
import logging import logging
from django.conf import settings
from django.contrib import messages
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect from django.shortcuts import get_object_or_404
from django.shortcuts import get_object_or_404, render_to_response
from django.template import RequestContext
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from acls.models import AccessControlList from acls.models import AccessControlList
from common.generics import ( from common.generics import (
SingleObjectCreateView, SingleObjectDeleteView, SingleObjectDetailView, SingleObjectCreateView, SingleObjectDeleteView, SingleObjectDetailView,
SingleObjectListView SingleObjectDownloadView, SingleObjectListView
) )
from documents.models import DocumentVersion from documents.models import DocumentVersion
from filetransfers.api import serve_file
from permissions import Permission from permissions import Permission
from .forms import DetachedSignatureForm, DocumentVersionSignatureDetailForm from .forms import DocumentVersionSignatureDetailForm
from .models import DetachedSignature, SignatureBaseModel from .models import DetachedSignature, SignatureBaseModel
from .permissions import ( from .permissions import (
permission_document_version_signature_view, permission_document_version_signature_view,
@@ -34,12 +29,16 @@ logger = logging.getLogger(__name__)
class DocumentVersionSignatureDeleteView(SingleObjectDeleteView): class DocumentVersionSignatureDeleteView(SingleObjectDeleteView):
model = DetachedSignature model = DetachedSignature
object_permission = permission_document_version_signature_delete
object_permission_related = 'document_version.document'
def get_extra_context(self): def get_extra_context(self):
return { return {
'document': self.get_object().document_version.document, 'document': self.get_object().document_version.document,
'document_version': self.get_object().document_version, 'document_version': self.get_object().document_version,
'navigation_object_list': ('document', 'document_version', 'signature'), 'navigation_object_list': (
'document', 'document_version', 'signature'
),
'signature': self.get_object(), 'signature': self.get_object(),
'title': _('Delete detached signature: %s') % self.get_object() 'title': _('Delete detached signature: %s') % self.get_object()
} }
@@ -61,7 +60,9 @@ class DocumentVersionSignatureDetailView(SingleObjectDetailView):
'document': self.get_object().document_version.document, 'document': self.get_object().document_version.document,
'document_version': self.get_object().document_version, 'document_version': self.get_object().document_version,
'signature': self.get_object(), 'signature': self.get_object(),
'navigation_object_list': ('document', 'document_version', 'signature'), 'navigation_object_list': (
'document', 'document_version', 'signature'
),
'hide_object': True, 'hide_object': True,
'title': _( 'title': _(
'Details for signature: %s' 'Details for signature: %s'
@@ -72,6 +73,19 @@ class DocumentVersionSignatureDetailView(SingleObjectDetailView):
return SignatureBaseModel.objects.select_subclasses() return SignatureBaseModel.objects.select_subclasses()
class DocumentSignatureDownloadView(SingleObjectDownloadView):
model = DetachedSignature
object_permission = permission_document_version_signature_download
object_permission_related = 'document_version.document'
def get_file(self):
signature = self.get_object()
return DocumentSignatureDownloadView.VirtualFile(
signature.signature_file, name=unicode(signature)
)
class DocumentVersionSignatureListView(SingleObjectListView): class DocumentVersionSignatureListView(SingleObjectListView):
object_permission = permission_document_version_signature_view object_permission = permission_document_version_signature_view
object_permission_related = 'document_version.document' object_permission_related = 'document_version.document'
@@ -95,11 +109,14 @@ class DocumentVersionSignatureListView(SingleObjectListView):
try: try:
Permission.check_permissions( Permission.check_permissions(
self.request.user, (permission_document_version_signature_view,) self.request.user, (
permission_document_version_signature_view,
)
) )
except PermissionDenied: except PermissionDenied:
return AccessControlList.objects.filter_by_access( return AccessControlList.objects.filter_by_access(
permission_document_version_signature_view, self.request.user, queryset permission_document_version_signature_view, self.request.user,
queryset
) )
else: else:
return queryset return queryset
@@ -145,24 +162,3 @@ class DocumentVersionSignatureUploadView(SingleObjectCreateView):
'signatures:document_version_signature_list', 'signatures:document_version_signature_list',
args=(self.get_document_version().pk,) args=(self.get_document_version().pk,)
) )
def document_signature_download(request, pk):
signature = get_object_or_404(DetachedSignature, pk=pk)
try:
Permission.check_permissions(
request.user, (permission_document_version_signature_download,)
)
except PermissionDenied:
AccessControlList.objects.check_access(
permission_document_version_signature_download, request.user,
signature.document_version.signature
)
return serve_file(
request,
signature,
save_as='"%s.sig"' % signature.document_version.document,
content_type='application/octet-stream'
)