diff --git a/mayan/apps/document_signatures/apps.py b/mayan/apps/document_signatures/apps.py index ae6feff669..55dd1dfd57 100644 --- a/mayan/apps/document_signatures/apps.py +++ b/mayan/apps/document_signatures/apps.py @@ -63,15 +63,15 @@ class DocumentSignaturesApp(MayanAppConfig): app_label='django_gpg', model_name='Key' ) - EmbeddedSignature = self.get_model('EmbeddedSignature') + EmbeddedSignature = self.get_model(model_name='EmbeddedSignature') - SignatureBaseModel = self.get_model('SignatureBaseModel') + SignatureBaseModel = self.get_model(model_name='SignatureBaseModel') DocumentVersion.register_post_save_hook( - order=1, func=EmbeddedSignature.objects.create + func=EmbeddedSignature.objects.create, order=1 ) DocumentVersion.register_pre_open_hook( - order=1, func=EmbeddedSignature.objects.open_signed + func=EmbeddedSignature.objects.open_signed, order=1 ) ModelPermission.register( @@ -85,22 +85,15 @@ class DocumentSignaturesApp(MayanAppConfig): ) ) - SourceColumn( - source=SignatureBaseModel, label=_('Date'), attribute='date' + ModelPermission.register_inheritance( + model=SignatureBaseModel, related='document_version' ) + + SourceColumn(attribute='date', source=SignatureBaseModel) + SourceColumn(attribute='get_key_id', source=SignatureBaseModel) + SourceColumn(attribute='get_signature_id', source=SignatureBaseModel) SourceColumn( - source=SignatureBaseModel, label=_('Key ID'), - attribute='get_key_id' - ) - SourceColumn( - source=SignatureBaseModel, label=_('Signature ID'), - func=lambda context: context['object'].signature_id or _('None') - ) - SourceColumn( - source=SignatureBaseModel, label=_('Type'), - func=lambda context: SignatureBaseModel.objects.get_subclass( - pk=context['object'].pk - ).get_signature_type_display() + attribute='get_signature_type_display', source=SignatureBaseModel ) app.conf.task_queues.append( diff --git a/mayan/apps/document_signatures/forms.py b/mayan/apps/document_signatures/forms.py index e0403a23c9..dfcfb08858 100644 --- a/mayan/apps/document_signatures/forms.py +++ b/mayan/apps/document_signatures/forms.py @@ -5,8 +5,7 @@ import logging from django import forms from django.utils.translation import ugettext_lazy as _ -from mayan.apps.acls.models import AccessControlList -from mayan.apps.common.forms import DetailForm +from mayan.apps.common.forms import DetailForm, FilteredSelectionForm from mayan.apps.django_gpg.models import Key from mayan.apps.django_gpg.permissions import permission_key_sign @@ -15,44 +14,39 @@ from .models import SignatureBaseModel logger = logging.getLogger(__name__) -class DocumentVersionSignatureCreateForm(forms.Form): +class DocumentVersionSignatureCreateForm(FilteredSelectionForm): key = forms.ModelChoiceField( label=_('Key'), queryset=Key.objects.none() ) passphrase = forms.CharField( - label=_('Passphrase'), required=False, + help_text=_( + 'The passphrase to unlock the key and allow it to be used to ' + 'sign the document version.' + ), label=_('Passphrase'), required=False, widget=forms.widgets.PasswordInput ) - def __init__(self, *args, **kwargs): - user = kwargs.pop('user', None) - logger.debug('user: %s', user) - super( - DocumentVersionSignatureCreateForm, self - ).__init__(*args, **kwargs) - - queryset = AccessControlList.objects.filter_by_access( - permission_key_sign, user, queryset=Key.objects.private_keys() + class Meta: + allow_multiple = False + field_name = 'key' + label = _('Key') + help_text = _( + 'Private key that will be used to sign this document version.' ) - - self.fields['key'].queryset = queryset + permission = permission_key_sign + queryset = Key.objects.private_keys() + required = True + widget_attributes = {'class': 'select2'} class DocumentVersionSignatureDetailForm(DetailForm): def __init__(self, *args, **kwargs): - extra_fields = ( - {'label': _('Signature is embedded?'), 'field': 'is_embedded'}, - { - 'label': _('Signature date'), 'field': 'date', - 'widget': forms.widgets.DateInput - }, - {'label': _('Signature key ID'), 'field': 'key_id'}, - { - 'label': _('Signature key present?'), - 'field': lambda x: x.public_key_fingerprint is not None - }, - ) + super( + DocumentVersionSignatureDetailForm, self + ).__init__(*args, **kwargs) + + extra_fields = self.Meta.extra_fields if kwargs['instance'].public_key_fingerprint: key = Key.objects.get( @@ -60,44 +54,52 @@ class DocumentVersionSignatureDetailForm(DetailForm): ) extra_fields += ( - {'label': _('Signature ID'), 'field': 'signature_id'}, + {'field': 'signature_id'}, { - 'label': _('Key fingerprint'), - 'field': lambda x: key.fingerprint + 'field': 'fingerprint', + 'object': key }, { - 'label': _('Key creation date'), - 'field': lambda x: key.creation_date, + 'field': 'creation_date', + 'object': key, 'widget': forms.widgets.DateInput }, { - 'label': _('Key expiration date'), - 'field': lambda x: key.expiration_date or _('None'), + 'field': 'get_expiration_date_display', + 'object': key, 'widget': forms.widgets.DateInput }, { - 'label': _('Key length'), - 'field': lambda x: key.length + 'field': 'length', + 'object': key }, { - 'label': _('Key algorithm'), - 'field': lambda x: key.algorithm + 'field': 'algorithm', + 'object': key }, { - 'label': _('Key user ID'), - 'field': lambda x: key.user_id + 'field': 'get_escaped_user_id', + 'object': key }, { - 'label': _('Key type'), - 'field': lambda x: key.get_key_type_display() + 'field': 'get_key_type_display', + 'object': key }, ) - kwargs['extra_fields'] = extra_fields - super( - DocumentVersionSignatureDetailForm, self - ).__init__(*args, **kwargs) + self.Meta.extra_fields = extra_fields class Meta: + extra_fields = ( + {'field': 'get_signature_type_display'}, + { + 'field': 'date', + 'widget': forms.widgets.DateInput + }, + {'field': 'key_id'}, + { + 'field': 'get_key_available_display' + }, + ) fields = () model = SignatureBaseModel diff --git a/mayan/apps/document_signatures/icons.py b/mayan/apps/document_signatures/icons.py index cb7ea37e33..63803faeb6 100644 --- a/mayan/apps/document_signatures/icons.py +++ b/mayan/apps/document_signatures/icons.py @@ -17,3 +17,6 @@ icon_document_version_signature_embedded_create = Icon( icon_document_version_signature_list = Icon( driver_name='fontawesome', symbol='certificate' ) +icon_document_version_signature_upload = Icon( + driver_name='fontawesome', symbol='upload' +) diff --git a/mayan/apps/document_signatures/literals.py b/mayan/apps/document_signatures/literals.py index f27ca1f9d8..d8d11c4694 100644 --- a/mayan/apps/document_signatures/literals.py +++ b/mayan/apps/document_signatures/literals.py @@ -1,3 +1,10 @@ from __future__ import unicode_literals -RETRY_DELAY = 10 +from django.utils.translation import ugettext_lazy as _ + +SIGNATURE_TYPE_DETACHED = 1 +SIGNATURE_TYPE_EMBEDDED = 2 +SIGNATURE_TYPE_CHOICES = ( + (SIGNATURE_TYPE_DETACHED, _('Detached')), + (SIGNATURE_TYPE_EMBEDDED, _('Embedded')), +) diff --git a/mayan/apps/document_signatures/models.py b/mayan/apps/document_signatures/models.py index 47e226f5ed..17ea367035 100644 --- a/mayan/apps/document_signatures/models.py +++ b/mayan/apps/document_signatures/models.py @@ -14,12 +14,16 @@ from mayan.apps.django_gpg.exceptions import VerificationError from mayan.apps.django_gpg.models import Key from mayan.apps.documents.models import DocumentVersion +from .literals import ( + SIGNATURE_TYPE_CHOICES, SIGNATURE_TYPE_DETACHED, SIGNATURE_TYPE_EMBEDDED +) from .managers import EmbeddedSignatureManager from .storages import storage_detachedsignature logger = logging.getLogger(__name__) +# TODO: Move to an utils module or as a static class of DetachedSignature def upload_to(*args, **kwargs): return force_text(uuid.uuid4()) @@ -65,8 +69,8 @@ class SignatureBaseModel(models.Model): def get_absolute_url(self): return reverse( - 'document_signatures:document_version_signature_detail', - args=(self.pk,) + viewname='document_signatures:document_version_signature_detail', + kwargs={'document_version_id': self.pk} ) def get_key_id(self): @@ -74,20 +78,41 @@ class SignatureBaseModel(models.Model): return self.public_key_fingerprint[-16:] else: return self.key_id + get_key_id.short_description = _('Key ID') + + def get_signature_id(self): + return self.signature_id or _('None') + get_signature_id.short_description = _('Signature ID') def get_signature_type_display(self): - if self.is_detached: - return _('Detached') + if hasattr(self, 'signaturebasemodel_ptr'): + model = self else: - return _('Embedded') + model = self._meta.default_manager.get_subclass(pk=self.pk) + + return dict(SIGNATURE_TYPE_CHOICES).get( + model.signature_type, _('Unknown') + ) + get_signature_type_display.short_description = _('Type') + + def is_key_available(self): + return self.public_key_fingerprint is not None + + def get_key_available_display(self): + if self.is_key_available(): + return _('Yes') + else: + return _('No') + get_key_available_display.short_description = _('Signature key present?') @property - def is_detached(self): - return hasattr(self, 'signature_file') + def signature_type(self): + if hasattr(self, 'signaturebasemodel_ptr'): + model = self + else: + model = self._meta.default_manager.get_subclass(pk=self.pk) - @property - def is_embedded(self): - return not hasattr(self, 'signature_file') + return model._signature_type class EmbeddedSignature(SignatureBaseModel): @@ -97,6 +122,10 @@ class EmbeddedSignature(SignatureBaseModel): verbose_name = _('Document version embedded signature') verbose_name_plural = _('Document version embedded signatures') + @property + def _signature_type(self): + return SIGNATURE_TYPE_EMBEDDED + def save(self, *args, **kwargs): logger.debug('checking for embedded signature') @@ -141,6 +170,10 @@ class DetachedSignature(SignatureBaseModel): def __str__(self): return '{}-{}'.format(self.document_version, _('signature')) + @property + def _signature_type(self): + return SIGNATURE_TYPE_DETACHED + def delete(self, *args, **kwargs): if self.signature_file.name: self.signature_file.storage.delete(name=self.signature_file.name) diff --git a/mayan/apps/document_signatures/storages.py b/mayan/apps/document_signatures/storages.py index 03c959df5a..1b88c818ca 100644 --- a/mayan/apps/document_signatures/storages.py +++ b/mayan/apps/document_signatures/storages.py @@ -1,7 +1,5 @@ from __future__ import unicode_literals -from django.utils.module_loading import import_string - from mayan.apps.common.utils import get_storage_subclass from .settings import ( diff --git a/mayan/apps/document_signatures/tests/mixins.py b/mayan/apps/document_signatures/tests/mixins.py new file mode 100644 index 0000000000..4b057c395c --- /dev/null +++ b/mayan/apps/document_signatures/tests/mixins.py @@ -0,0 +1,22 @@ +from __future__ import absolute_import, unicode_literals + +from django.core.files import File + +from mayan.apps.django_gpg.models import Key + +from ..models import DetachedSignature + +from .literals import TEST_KEY_FILE, TEST_SIGNATURE_FILE_PATH + + +class SignaturesTestMixin(object): + def _create_test_key(self): + with open(TEST_KEY_FILE, mode='rb') as file_object: + self.test_key = Key.objects.create(key_data=file_object.read()) + + def _upload_test_signature(self): + with open(TEST_SIGNATURE_FILE_PATH, mode='rb') as file_object: + self.test_signature = DetachedSignature.objects.create( + document_version=self.test_document.latest_version, + signature_file=File(file_object) + ) diff --git a/mayan/apps/document_signatures/tests/test_links.py b/mayan/apps/document_signatures/tests/test_links.py index e11e5fe157..13a659b6e6 100644 --- a/mayan/apps/document_signatures/tests/test_links.py +++ b/mayan/apps/document_signatures/tests/test_links.py @@ -1,6 +1,5 @@ from __future__ import unicode_literals -from django.core.files import File from django.urls import reverse from mayan.apps.documents.tests import ( @@ -11,28 +10,24 @@ from ..links import ( link_document_version_signature_delete, link_document_version_signature_details ) -from ..models import DetachedSignature from ..permissions import ( permission_document_version_signature_delete, permission_document_version_signature_view ) -from .literals import TEST_SIGNATURE_FILE_PATH, TEST_SIGNED_DOCUMENT_PATH +from .literals import TEST_SIGNED_DOCUMENT_PATH +from .mixins import SignaturesTestMixin -class DocumentSignatureLinksTestCase(GenericDocumentViewTestCase): - def setUp(self): - super(DocumentSignatureLinksTestCase, self).setUp() - self.login_user() +class DocumentSignatureLinksTestCase(SignaturesTestMixin, GenericDocumentViewTestCase): + auto_upload_document = False def test_document_version_signature_detail_link_no_permission(self): - with open(TEST_SIGNED_DOCUMENT_PATH, mode='rb') as file_object: - document = self.document_type.new_document( - file_object=file_object - ) + self.test_document_path = TEST_SIGNED_DOCUMENT_PATH + self.test_document = self.upload_document() self.add_test_view( - test_object=document.latest_version.signatures.first() + test_object=self.test_document.latest_version.signatures.first() ) context = self.get_test_view() resolved_link = link_document_version_signature_details.resolve( @@ -41,18 +36,17 @@ class DocumentSignatureLinksTestCase(GenericDocumentViewTestCase): self.assertEqual(resolved_link, None) - def test_document_version_signature_detail_link_with_permission(self): - with open(TEST_SIGNED_DOCUMENT_PATH, mode='rb') as file_object: - document = self.document_type.new_document( - file_object=file_object - ) + def test_document_version_signature_detail_link_with_access(self): + self.test_document_path = TEST_SIGNED_DOCUMENT_PATH + self.test_document = self.upload_document() - self.role.permissions.add( - permission_document_version_signature_view.stored_permission + self.grant_access( + obj=self.test_document, + permission=permission_document_version_signature_view ) self.add_test_view( - test_object=document.latest_version.signatures.first() + test_object=self.test_document.latest_version.signatures.first() ) context = self.get_test_view() resolved_link = link_document_version_signature_details.resolve( @@ -63,25 +57,20 @@ class DocumentSignatureLinksTestCase(GenericDocumentViewTestCase): self.assertEqual( resolved_link.url, reverse( - 'signatures:document_version_signature_details', - args=(document.latest_version.signatures.first().pk,) + viewname='signatures:document_version_signature_details', + kwargs={ + 'signature_id': self.test_document.latest_version.signatures.first().pk + } ) ) def test_document_version_signature_delete_link_no_permission(self): - with open(TEST_DOCUMENT_PATH, mode='rb') as file_object: - document = self.document_type.new_document( - file_object=file_object - ) - - with open(TEST_SIGNATURE_FILE_PATH, mode='rb') as file_object: - DetachedSignature.objects.create( - document_version=document.latest_version, - signature_file=File(file_object) - ) + self.test_document_path = TEST_DOCUMENT_PATH + self.test_document = self.upload_document() + self._upload_test_signature() self.add_test_view( - test_object=document.latest_version.signatures.first() + test_object=self.test_document.latest_version.signatures.first() ) context = self.get_test_view() resolved_link = link_document_version_signature_delete.resolve( @@ -90,24 +79,18 @@ class DocumentSignatureLinksTestCase(GenericDocumentViewTestCase): self.assertEqual(resolved_link, None) - def test_document_version_signature_delete_link_with_permission(self): - with open(TEST_DOCUMENT_PATH, mode='rb') as file_object: - document = self.document_type.new_document( - file_object=file_object - ) + def test_document_version_signature_delete_link_with_access(self): + self.test_document_path = TEST_DOCUMENT_PATH + self.test_document = self.upload_document() + self._upload_test_signature() - with open(TEST_SIGNATURE_FILE_PATH, mode='rb') as file_object: - DetachedSignature.objects.create( - document_version=document.latest_version, - signature_file=File(file_object) - ) - - self.role.permissions.add( - permission_document_version_signature_delete.stored_permission + self.grant_access( + obj=self.test_document, + permission=permission_document_version_signature_delete ) self.add_test_view( - test_object=document.latest_version.signatures.first() + test_object=self.test_document.latest_version.signatures.first() ) context = self.get_test_view() resolved_link = link_document_version_signature_delete.resolve( @@ -118,7 +101,9 @@ class DocumentSignatureLinksTestCase(GenericDocumentViewTestCase): self.assertEqual( resolved_link.url, reverse( - 'signatures:document_version_signature_delete', - args=(document.latest_version.signatures.first().pk,) + viewname='signatures:document_version_signature_delete', + kwargs={ + 'signature_id': self.test_document.latest_version.signatures.first().pk + } ) ) diff --git a/mayan/apps/document_signatures/tests/test_models.py b/mayan/apps/document_signatures/tests/test_models.py index 87bce78057..09a287297e 100644 --- a/mayan/apps/document_signatures/tests/test_models.py +++ b/mayan/apps/document_signatures/tests/test_models.py @@ -4,110 +4,86 @@ import hashlib import logging import time -from django.core.files import File - -from mayan.apps.common.tests import BaseTestCase from mayan.apps.django_gpg.models import Key from mayan.apps.django_gpg.tests.literals import ( TEST_KEY_DATA, TEST_KEY_PASSPHRASE ) -from mayan.apps.documents.models import DocumentType, DocumentVersion +from mayan.apps.documents.models import DocumentVersion from mayan.apps.documents.tests import ( - TEST_DOCUMENT_PATH, TEST_DOCUMENT_TYPE_LABEL + GenericDocumentTestCase, TEST_DOCUMENT_PATH, ) from ..models import DetachedSignature, EmbeddedSignature from ..tasks import task_verify_missing_embedded_signature -from .literals import ( - TEST_KEY_FILE, TEST_KEY_ID, TEST_SIGNATURE_FILE_PATH, TEST_SIGNATURE_ID, - TEST_SIGNED_DOCUMENT_PATH -) +from .literals import TEST_KEY_ID, TEST_SIGNATURE_ID, TEST_SIGNED_DOCUMENT_PATH +from .mixins import SignaturesTestMixin -class DocumentSignaturesTestCase(BaseTestCase): - def setUp(self): - super(DocumentSignaturesTestCase, self).setUp() - self.document_type = DocumentType.objects.create( - label=TEST_DOCUMENT_TYPE_LABEL - ) - - def tearDown(self): - self.document_type.delete() - super(DocumentSignaturesTestCase, self).tearDown() +class DocumentSignaturesTestCase(SignaturesTestMixin, GenericDocumentTestCase): + auto_upload_document = False def test_embedded_signature_no_key(self): - with open(TEST_SIGNED_DOCUMENT_PATH, mode='rb') as file_object: - signed_document = self.document_type.new_document( - file_object=file_object - ) + self.test_document_path = TEST_SIGNED_DOCUMENT_PATH + self.test_signed_document = self.upload_document() self.assertEqual(EmbeddedSignature.objects.count(), 1) signature = EmbeddedSignature.objects.first() self.assertEqual( - signature.document_version, signed_document.latest_version + signature.document_version, self.test_signed_document.latest_version ) self.assertEqual(signature.key_id, TEST_KEY_ID) self.assertEqual(signature.signature_id, None) def test_embedded_signature_post_key_verify(self): - with open(TEST_SIGNED_DOCUMENT_PATH, mode='rb') as file_object: - signed_document = self.document_type.new_document( - file_object=file_object - ) + self.test_document_path = TEST_SIGNED_DOCUMENT_PATH + self.test_signed_document = self.upload_document() self.assertEqual(EmbeddedSignature.objects.count(), 1) signature = EmbeddedSignature.objects.first() self.assertEqual( - signature.document_version, signed_document.latest_version + signature.document_version, self.test_signed_document.latest_version ) self.assertEqual(signature.key_id, TEST_KEY_ID) self.assertEqual(signature.signature_id, None) - with open(TEST_KEY_FILE, mode='rb') as file_object: - Key.objects.create(key_data=file_object.read()) + self._create_test_key() signature = EmbeddedSignature.objects.first() self.assertEqual(signature.signature_id, TEST_SIGNATURE_ID) def test_embedded_signature_post_no_key_verify(self): - with open(TEST_KEY_FILE, mode='rb') as file_object: - key = Key.objects.create(key_data=file_object.read()) + self._create_test_key() - with open(TEST_SIGNED_DOCUMENT_PATH, mode='rb') as file_object: - signed_document = self.document_type.new_document( - file_object=file_object - ) + self.test_document_path = TEST_SIGNED_DOCUMENT_PATH + self.test_signed_document = self.upload_document() self.assertEqual(EmbeddedSignature.objects.count(), 1) signature = EmbeddedSignature.objects.first() self.assertEqual( - signature.document_version, signed_document.latest_version + signature.document_version, self.test_signed_document.latest_version ) self.assertEqual(signature.key_id, TEST_KEY_ID) self.assertEqual(signature.signature_id, TEST_SIGNATURE_ID) - key.delete() + self.test_key.delete() signature = EmbeddedSignature.objects.first() self.assertEqual(signature.signature_id, None) def test_embedded_signature_with_key(self): - with open(TEST_KEY_FILE, mode='rb') as file_object: - key = Key.objects.create(key_data=file_object.read()) + self._create_test_key() - with open(TEST_SIGNED_DOCUMENT_PATH, mode='rb') as file_object: - self.signed_document = self.document_type.new_document( - file_object=file_object - ) + self.test_document_path = TEST_SIGNED_DOCUMENT_PATH + self.test_signed_document = self.upload_document() self.assertEqual(EmbeddedSignature.objects.count(), 1) @@ -115,127 +91,109 @@ class DocumentSignaturesTestCase(BaseTestCase): self.assertEqual( signature.document_version, - self.signed_document.latest_version + self.test_signed_document.latest_version ) self.assertEqual(signature.key_id, TEST_KEY_ID) - self.assertEqual(signature.public_key_fingerprint, key.fingerprint) + self.assertEqual( + signature.public_key_fingerprint, self.test_key.fingerprint + ) self.assertEqual(signature.signature_id, TEST_SIGNATURE_ID) def test_detached_signature_no_key(self): - with open(TEST_DOCUMENT_PATH, mode='rb') as file_object: - document = self.document_type.new_document( - file_object=file_object - ) + self.test_document_path = TEST_DOCUMENT_PATH + self.test_document = self.upload_document() - with open(TEST_SIGNATURE_FILE_PATH, mode='rb') as file_object: - DetachedSignature.objects.create( - document_version=document.latest_version, - signature_file=File(file_object) - ) + self._upload_test_signature() self.assertEqual(DetachedSignature.objects.count(), 1) signature = DetachedSignature.objects.first() - self.assertEqual(signature.document_version, document.latest_version) + self.assertEqual( + signature.document_version, self.test_document.latest_version + ) self.assertEqual(signature.key_id, TEST_KEY_ID) self.assertEqual(signature.public_key_fingerprint, None) def test_detached_signature_with_key(self): - with open(TEST_KEY_FILE, mode='rb') as file_object: - key = Key.objects.create(key_data=file_object.read()) + self._create_test_key() - with open(TEST_DOCUMENT_PATH, mode='rb') as file_object: - document = self.document_type.new_document( - file_object=file_object - ) - - with open(TEST_SIGNATURE_FILE_PATH, mode='rb') as file_object: - DetachedSignature.objects.create( - document_version=document.latest_version, - signature_file=File(file_object) - ) + self.test_document_path = TEST_DOCUMENT_PATH + self.test_document = self.upload_document() + self._upload_test_signature() self.assertEqual(DetachedSignature.objects.count(), 1) signature = DetachedSignature.objects.first() - self.assertEqual(signature.document_version, document.latest_version) + self.assertEqual( + signature.document_version, self.test_document.latest_version + ) self.assertEqual(signature.key_id, TEST_KEY_ID) - self.assertEqual(signature.public_key_fingerprint, key.fingerprint) + self.assertEqual( + signature.public_key_fingerprint, self.test_key.fingerprint + ) def test_detached_signature_post_key_verify(self): - with open(TEST_DOCUMENT_PATH, mode='rb') as file_object: - document = self.document_type.new_document( - file_object=file_object - ) - - with open(TEST_SIGNATURE_FILE_PATH, mode='rb') as file_object: - DetachedSignature.objects.create( - document_version=document.latest_version, - signature_file=File(file_object) - ) + self.test_document_path = TEST_DOCUMENT_PATH + self.test_document = self.upload_document() + self._upload_test_signature() self.assertEqual(DetachedSignature.objects.count(), 1) signature = DetachedSignature.objects.first() - self.assertEqual(signature.document_version, document.latest_version) + self.assertEqual( + signature.document_version, self.test_document.latest_version + ) self.assertEqual(signature.key_id, TEST_KEY_ID) self.assertEqual(signature.public_key_fingerprint, None) - with open(TEST_KEY_FILE, mode='rb') as file_object: - key = Key.objects.create(key_data=file_object.read()) + self._create_test_key() signature = DetachedSignature.objects.first() - self.assertEqual(signature.public_key_fingerprint, key.fingerprint) + self.assertEqual( + signature.public_key_fingerprint, self.test_key.fingerprint + ) def test_detached_signature_post_no_key_verify(self): - with open(TEST_KEY_FILE, mode='rb') as file_object: - key = Key.objects.create(key_data=file_object.read()) + self._create_test_key() - with open(TEST_DOCUMENT_PATH, mode='rb') as file_object: - document = self.document_type.new_document( - file_object=file_object - ) - - with open(TEST_SIGNATURE_FILE_PATH, mode='rb') as file_object: - DetachedSignature.objects.create( - document_version=document.latest_version, - signature_file=File(file_object) - ) + self.test_document_path = TEST_DOCUMENT_PATH + self.test_document = self.upload_document() + self._upload_test_signature() self.assertEqual(DetachedSignature.objects.count(), 1) signature = DetachedSignature.objects.first() - self.assertEqual(signature.document_version, document.latest_version) + self.assertEqual( + signature.document_version, self.test_document.latest_version + ) self.assertEqual(signature.key_id, TEST_KEY_ID) - self.assertEqual(signature.public_key_fingerprint, key.fingerprint) + self.assertEqual( + signature.public_key_fingerprint, self.test_key.fingerprint + ) - key.delete() + self.test_key.delete() signature = DetachedSignature.objects.first() self.assertEqual(signature.public_key_fingerprint, None) def test_document_no_signature(self): - with open(TEST_DOCUMENT_PATH, mode='rb') as file_object: - self.document_type.new_document( - file_object=file_object - ) + self.test_document_path = TEST_DOCUMENT_PATH + self.upload_document() self.assertEqual(EmbeddedSignature.objects.count(), 0) def test_new_signed_version(self): - with open(TEST_DOCUMENT_PATH, mode='rb') as file_object: - document = self.document_type.new_document( - file_object=file_object - ) + self.test_document_path = TEST_DOCUMENT_PATH + self.test_document = self.upload_document() with open(TEST_SIGNED_DOCUMENT_PATH, mode='rb') as file_object: - signed_version = document.new_version( + signed_version = self.test_document.new_version( file_object=file_object, comment='test comment 1' ) @@ -252,33 +210,20 @@ class DocumentSignaturesTestCase(BaseTestCase): self.assertEqual(signature.key_id, TEST_KEY_ID) -class EmbeddedSignaturesTestCase(BaseTestCase): - def setUp(self): - super(EmbeddedSignaturesTestCase, self).setUp() - - self.document_type = DocumentType.objects.create( - label=TEST_DOCUMENT_TYPE_LABEL - ) - - def tearDown(self): - self.document_type.delete() - super(EmbeddedSignaturesTestCase, self).tearDown() +class EmbeddedSignaturesTestCase(GenericDocumentTestCase): + auto_upload_document = False def test_unsigned_document_version_method(self): TEST_UNSIGNED_DOCUMENT_COUNT = 2 TEST_SIGNED_DOCUMENT_COUNT = 2 for count in range(TEST_UNSIGNED_DOCUMENT_COUNT): - with open(TEST_DOCUMENT_PATH, mode='rb') as file_object: - self.document_type.new_document( - file_object=file_object - ) + self.test_document_path = TEST_DOCUMENT_PATH + self.upload_document() for count in range(TEST_SIGNED_DOCUMENT_COUNT): - with open(TEST_SIGNED_DOCUMENT_PATH, mode='rb') as file_object: - self.document_type.new_document( - file_object=file_object - ) + self.test_document_path = TEST_SIGNED_DOCUMENT_PATH + self.upload_document() self.assertEqual( EmbeddedSignature.objects.unsigned_document_versions().count(), @@ -299,16 +244,12 @@ class EmbeddedSignaturesTestCase(BaseTestCase): TEST_SIGNED_DOCUMENT_COUNT = 2 for count in range(TEST_UNSIGNED_DOCUMENT_COUNT): - with open(TEST_DOCUMENT_PATH, mode='rb') as file_object: - self.document_type.new_document( - file_object=file_object - ) + self.test_document_path = TEST_DOCUMENT_PATH + self.upload_document() for count in range(TEST_SIGNED_DOCUMENT_COUNT): - with open(TEST_SIGNED_DOCUMENT_PATH, mode='rb') as file_object: - self.document_type.new_document( - file_object=file_object - ) + self.test_document_path = TEST_SIGNED_DOCUMENT_PATH + self.upload_document() self.assertEqual( EmbeddedSignature.objects.unsigned_document_versions().count(), @@ -327,19 +268,17 @@ class EmbeddedSignaturesTestCase(BaseTestCase): def test_signing(self): key = Key.objects.create(key_data=TEST_KEY_DATA) - with open(TEST_DOCUMENT_PATH, mode='rb') as file_object: - document = self.document_type.new_document( - file_object=file_object - ) + self.test_document_path = TEST_DOCUMENT_PATH + self.test_document = self.upload_document() - with document.latest_version.open() as file_object: + with self.test_document.latest_version.open() as file_object: file_object.seek(0, 2) original_size = file_object.tell() file_object.seek(0) original_hash = hashlib.sha256(file_object.read()).hexdigest() new_version = EmbeddedSignature.objects.sign_document_version( - document_version=document.latest_version, key=key, + document_version=self.test_document.latest_version, key=key, passphrase=TEST_KEY_PASSPHRASE ) diff --git a/mayan/apps/document_signatures/tests/test_views.py b/mayan/apps/document_signatures/tests/test_views.py index 630f12f906..b60d2aa06a 100644 --- a/mayan/apps/document_signatures/tests/test_views.py +++ b/mayan/apps/document_signatures/tests/test_views.py @@ -2,11 +2,8 @@ from __future__ import absolute_import, unicode_literals import logging -from django.core.files import File - from django_downloadview.test import assert_download_response -from mayan.apps.django_gpg.models import Key from mayan.apps.documents.models import DocumentVersion from mayan.apps.documents.tests import ( TEST_DOCUMENT_PATH, GenericDocumentViewTestCase @@ -21,290 +18,172 @@ from ..permissions import ( permission_document_version_signature_view ) -from .literals import ( - TEST_KEY_FILE, TEST_SIGNATURE_FILE_PATH, TEST_SIGNED_DOCUMENT_PATH -) +from .literals import TEST_SIGNATURE_FILE_PATH, TEST_SIGNED_DOCUMENT_PATH +from .mixins import SignaturesTestMixin TEST_UNSIGNED_DOCUMENT_COUNT = 4 TEST_SIGNED_DOCUMENT_COUNT = 2 -class SignaturesViewTestCase(GenericDocumentViewTestCase): - def _request_document_version_signature_list_view(self, document): - return self.get( - viewname='signatures:document_version_signature_list', - args=(document.latest_version.pk,) +class SignaturesViewTestCase(SignaturesTestMixin, GenericDocumentViewTestCase): + def _request_document_version_signature_delete_view(self): + return self.post( + viewname='signatures:document_version_signature_delete', + kwargs={'signature_id': self.test_signature.pk} ) - def test_signature_list_view_no_permission(self): - with open(TEST_KEY_FILE, mode='rb') as file_object: - Key.objects.create(key_data=file_object.read()) + def test_signature_delete_view_no_permission(self): + self._create_test_key() + self.test_document_path = TEST_DOCUMENT_PATH + self.test_document = self.upload_document() + self._upload_test_signature() - with open(TEST_DOCUMENT_PATH, mode='rb') as file_object: - document = self.document_type.new_document( - file_object=file_object - ) + response = self._request_document_version_signature_delete_view() + self.assertEqual(response.status_code, 404) + self.assertEqual(DetachedSignature.objects.count(), 1) - with open(TEST_SIGNATURE_FILE_PATH, mode='rb') as file_object: - DetachedSignature.objects.create( - document_version=document.latest_version, - signature_file=File(file_object) - ) - - self.login_user() - - response = self._request_document_version_signature_list_view( - document=document - ) - self.assertEqual(response.status_code, 403) - - def test_signature_list_view_with_access(self): - with open(TEST_KEY_FILE, mode='rb') as file_object: - Key.objects.create(key_data=file_object.read()) - - with open(TEST_DOCUMENT_PATH, mode='rb') as file_object: - document = self.document_type.new_document( - file_object=file_object - ) - - with open(TEST_SIGNATURE_FILE_PATH, mode='rb') as file_object: - DetachedSignature.objects.create( - document_version=document.latest_version, - signature_file=File(file_object) - ) - - self.login_user() + def test_signature_delete_view_with_access(self): + self._create_test_key() + self.test_document_path = TEST_DOCUMENT_PATH + self.test_document = self.upload_document() + self._upload_test_signature() self.grant_access( - obj=document, - permission=permission_document_version_signature_view + obj=self.test_document, + permission=permission_document_version_signature_delete ) + response = self._request_document_version_signature_delete_view() + self.assertEqual(response.status_code, 302) + self.assertEqual(DetachedSignature.objects.count(), 0) - response = self._request_document_version_signature_list_view( - document=document - ) - self.assertEqual(response.status_code, 200) - self.assertEqual(response.context['object_list'].count(), 1) - - def _request_document_version_signature_details_view(self, signature): + def _request_document_version_signature_details_view(self): return self.get( viewname='signatures:document_version_signature_details', - args=(signature.pk,) + kwargs={'signature_id': self.test_signature.pk} ) def test_signature_detail_view_no_permission(self): - with open(TEST_KEY_FILE, mode='rb') as file_object: - Key.objects.create(key_data=file_object.read()) + self._create_test_key() + self.test_document_path = TEST_DOCUMENT_PATH + self.test_document = self.upload_document() + self._upload_test_signature() - with open(TEST_DOCUMENT_PATH, mode='rb') as file_object: - document = self.document_type.new_document( - file_object=file_object - ) - - with open(TEST_SIGNATURE_FILE_PATH, mode='rb') as file_object: - signature = DetachedSignature.objects.create( - document_version=document.latest_version, - signature_file=File(file_object) - ) - - self.login_user() - - response = self._request_document_version_signature_details_view( - signature=signature - ) - self.assertEqual(response.status_code, 403) + response = self._request_document_version_signature_details_view() + self.assertEqual(response.status_code, 404) def test_signature_detail_view_with_access(self): - with open(TEST_KEY_FILE, mode='rb') as file_object: - Key.objects.create(key_data=file_object.read()) - - with open(TEST_DOCUMENT_PATH, mode='rb') as file_object: - document = self.document_type.new_document( - file_object=file_object - ) - - with open(TEST_SIGNATURE_FILE_PATH, mode='rb') as file_object: - signature = DetachedSignature.objects.create( - document_version=document.latest_version, - signature_file=File(file_object) - ) - - self.login_user() - + self._create_test_key() + self.test_document_path = TEST_DOCUMENT_PATH + self.test_document = self.upload_document() + self._upload_test_signature() self.grant_access( - obj=document, + obj=self.test_document, permission=permission_document_version_signature_view ) - response = self._request_document_version_signature_details_view( - signature=signature - ) + response = self._request_document_version_signature_details_view() self.assertContains( - response=response, text=signature.signature_id, status_code=200 + response=response, text=self.test_signature.signature_id, + status_code=200 ) - def _request_document_version_signature_upload_view(self, document_version): - with open(TEST_SIGNATURE_FILE_PATH, mode='rb') as file_object: - return self.post( - viewname='signatures:document_version_signature_upload', - args=(document_version.pk,), - data={'signature_file': file_object} - ) - - def test_signature_upload_view_no_permission(self): - with open(TEST_DOCUMENT_PATH, mode='rb') as file_object: - document = self.document_type.new_document( - file_object=file_object - ) - - self.login_user() - - response = self._request_document_version_signature_upload_view( - document_version=document.latest_version - ) - self.assertEqual(response.status_code, 403) - self.assertEqual(DetachedSignature.objects.count(), 0) - - def test_signature_upload_view_with_access(self): - with open(TEST_DOCUMENT_PATH, mode='rb') as file_object: - document = self.document_type.new_document( - file_object=file_object - ) - - self.login_user() - - self.grant_access( - obj=document, - permission=permission_document_version_signature_upload - ) - - response = self._request_document_version_signature_upload_view( - document_version=document.latest_version - ) - self.assertEqual(response.status_code, 302) - self.assertEqual(DetachedSignature.objects.count(), 1) - - def _request_document_version_signature_download_view(self, signature): + def _request_document_version_signature_download_view(self): return self.get( viewname='signatures:document_version_signature_download', - args=(signature.pk,), + kwargs={'signature_id': self.test_signature.pk} ) def test_signature_download_view_no_permission(self): - with open(TEST_DOCUMENT_PATH, mode='rb') as file_object: - document = self.document_type.new_document( - file_object=file_object - ) + self.test_document_path = TEST_DOCUMENT_PATH + self.test_document = self.upload_document() + self._upload_test_signature() - with open(TEST_SIGNATURE_FILE_PATH, mode='rb') as file_object: - signature = DetachedSignature.objects.create( - document_version=document.latest_version, - signature_file=File(file_object) - ) - - self.login_user() - - response = self._request_document_version_signature_download_view( - signature=signature - ) - self.assertEqual(response.status_code, 403) + response = self._request_document_version_signature_download_view() + self.assertEqual(response.status_code, 404) def test_signature_download_view_with_access(self): - with open(TEST_DOCUMENT_PATH, mode='rb') as file_object: - document = self.document_type.new_document( - file_object=file_object - ) + self.test_document_path = TEST_DOCUMENT_PATH + self.test_document = self.upload_document() - with open(TEST_SIGNATURE_FILE_PATH, mode='rb') as file_object: - signature = DetachedSignature.objects.create( - document_version=document.latest_version, - signature_file=File(file_object) - ) - - self.login_user() + self._upload_test_signature() self.grant_access( - obj=document, + obj=self.test_document, permission=permission_document_version_signature_download ) self.expected_content_type = 'application/octet-stream; charset=utf-8' - response = self._request_document_version_signature_download_view( - signature=signature - ) + response = self._request_document_version_signature_download_view() - with signature.signature_file as file_object: + with self.test_signature.signature_file as file_object: assert_download_response( self, response=response, content=file_object.read(), ) - def _request_document_version_signature_delete_view(self, signature): - return self.post( - viewname='signatures:document_version_signature_delete', - args=(signature.pk,) + def _request_document_version_signature_list_view(self): + return self.get( + viewname='signatures:document_version_signature_list', + kwargs={'document_version_id': self.test_document.latest_version.pk} ) - def test_signature_delete_view_no_permission(self): - with open(TEST_KEY_FILE, mode='rb') as file_object: - Key.objects.create(key_data=file_object.read()) + def test_signature_list_view_no_permission(self): + self._create_test_key() - with open(TEST_DOCUMENT_PATH, mode='rb') as file_object: - document = self.document_type.new_document( - file_object=file_object - ) + self.test_document_path = TEST_DOCUMENT_PATH + self.test_document = self.upload_document() - with open(TEST_SIGNATURE_FILE_PATH, mode='rb') as file_object: - signature = DetachedSignature.objects.create( - document_version=document.latest_version, - signature_file=File(file_object) - ) + self._upload_test_signature() - self.login_user() + response = self._request_document_version_signature_list_view() + self.assertEqual(response.status_code, 404) + + def test_signature_list_view_with_access(self): + self._create_test_key() + + self.test_document_path = TEST_DOCUMENT_PATH + self.test_document = self.upload_document() + + self._upload_test_signature() self.grant_access( - obj=document, + obj=self.test_document, permission=permission_document_version_signature_view ) - response = self._request_document_version_signature_delete_view( - signature=signature - ) - self.assertEqual(response.status_code, 403) - self.assertEqual(DetachedSignature.objects.count(), 1) - - def test_signature_delete_view_with_access(self): - with open(TEST_KEY_FILE, mode='rb') as file_object: - Key.objects.create(key_data=file_object.read()) - - with open(TEST_DOCUMENT_PATH, mode='rb') as file_object: - document = self.document_type.new_document( - file_object=file_object - ) + response = self._request_document_version_signature_list_view() + self.assertEqual(response.status_code, 200) + self.assertEqual(response.context['object_list'].count(), 1) + def _request_document_version_signature_upload_view(self): with open(TEST_SIGNATURE_FILE_PATH, mode='rb') as file_object: - signature = DetachedSignature.objects.create( - document_version=document.latest_version, - signature_file=File(file_object) + return self.post( + viewname='signatures:document_version_signature_upload', + kwargs={'document_version_id': self.test_document.latest_version.pk}, + data={'signature_file': file_object} ) - self.login_user() + def test_signature_upload_view_no_permission(self): + self.test_document_path = TEST_DOCUMENT_PATH + self.test_document = self.upload_document() - self.grant_access( - obj=document, - permission=permission_document_version_signature_delete - ) - self.grant_access( - obj=document, - permission=permission_document_version_signature_view - ) - - response = self._request_document_version_signature_delete_view( - signature=signature - ) - self.assertEqual(response.status_code, 302) + response = self._request_document_version_signature_upload_view() + self.assertEqual(response.status_code, 404) self.assertEqual(DetachedSignature.objects.count(), 0) + def test_signature_upload_view_with_access(self): + self.test_document_path = TEST_DOCUMENT_PATH + self.test_document = self.upload_document() + + self.grant_access( + obj=self.test_document, + permission=permission_document_version_signature_upload + ) + + response = self._request_document_version_signature_upload_view() + self.assertEqual(response.status_code, 302) + self.assertEqual(DetachedSignature.objects.count(), 1) + def _request_all_document_version_signature_verify_view(self): return self.post( viewname='signatures:all_document_version_signature_verify' @@ -322,16 +201,12 @@ class SignaturesViewTestCase(GenericDocumentViewTestCase): old_hooks = DocumentVersion._post_save_hooks DocumentVersion._post_save_hooks = {} for count in range(TEST_UNSIGNED_DOCUMENT_COUNT): - with open(TEST_DOCUMENT_PATH, mode='rb') as file_object: - self.document_type.new_document( - file_object=file_object - ) + self.test_document_path = TEST_DOCUMENT_PATH + self.upload_document() for count in range(TEST_SIGNED_DOCUMENT_COUNT): - with open(TEST_SIGNED_DOCUMENT_PATH, mode='rb') as file_object: - self.document_type.new_document( - file_object=file_object - ) + self.test_document_path = TEST_SIGNED_DOCUMENT_PATH + self.upload_document() self.assertEqual( EmbeddedSignature.objects.unsigned_document_versions().count(), @@ -340,8 +215,6 @@ class SignaturesViewTestCase(GenericDocumentViewTestCase): DocumentVersion._post_save_hooks = old_hooks - self.login_user() - response = self._request_all_document_version_signature_verify_view() self.assertEqual(response.status_code, 403) @@ -362,16 +235,12 @@ class SignaturesViewTestCase(GenericDocumentViewTestCase): old_hooks = DocumentVersion._post_save_hooks DocumentVersion._post_save_hooks = {} for count in range(TEST_UNSIGNED_DOCUMENT_COUNT): - with open(TEST_DOCUMENT_PATH, mode='rb') as file_object: - self.document_type.new_document( - file_object=file_object - ) + self.test_document_path = TEST_DOCUMENT_PATH + self.upload_document() for count in range(TEST_SIGNED_DOCUMENT_COUNT): - with open(TEST_SIGNED_DOCUMENT_PATH, mode='rb') as file_object: - self.document_type.new_document( - file_object=file_object - ) + self.test_document_path = TEST_SIGNED_DOCUMENT_PATH + self.upload_document() self.assertEqual( EmbeddedSignature.objects.unsigned_document_versions().count(), @@ -380,8 +249,6 @@ class SignaturesViewTestCase(GenericDocumentViewTestCase): DocumentVersion._post_save_hooks = old_hooks - self.login_user() - self.grant_permission( permission=permission_document_version_signature_verify ) diff --git a/mayan/apps/document_signatures/urls.py b/mayan/apps/document_signatures/urls.py index 0756750877..5f2383ca70 100644 --- a/mayan/apps/document_signatures/urls.py +++ b/mayan/apps/document_signatures/urls.py @@ -12,43 +12,43 @@ from .views import ( urlpatterns = [ url( - r'^(?P\d+)/details/$', - DocumentVersionSignatureDetailView.as_view(), - name='document_version_signature_details' + regex=r'^signatures/(?P\d+)/$', + name='document_version_signature_details', + view=DocumentVersionSignatureDetailView.as_view() ), url( - r'^signature/(?P\d+)/download/$', - DocumentVersionSignatureDownloadView.as_view(), - name='document_version_signature_download' + regex=r'^signatures/(?P\d+)/download/$', + name='document_version_signature_download', + view=DocumentVersionSignatureDownloadView.as_view() ), url( - r'^document/version/(?P\d+)/signatures/list/$', - DocumentVersionSignatureListView.as_view(), - name='document_version_signature_list' + regex=r'^signatures/(?P\d+)/delete/$', + name='document_version_signature_delete', + view=DocumentVersionSignatureDeleteView.as_view() ), url( - r'^documents/version/(?P\d+)/signature/detached/upload/$', - DocumentVersionSignatureUploadView.as_view(), - name='document_version_signature_upload' + regex=r'^documents/versions/(?P\d+)/signatures/$', + name='document_version_signature_list', + view=DocumentVersionSignatureListView.as_view() ), url( - r'^documents/version/(?P\d+)/signature/detached/create/$', - DocumentVersionDetachedSignatureCreateView.as_view(), - name='document_version_signature_detached_create' + regex=r'^documents/versions/(?P\d+)/signatures/detached/create/$', + name='document_version_signature_detached_create', + view=DocumentVersionDetachedSignatureCreateView.as_view() ), url( - r'^documents/version/(?P\d+)/signature/embedded/create/$', - DocumentVersionEmbeddedSignatureCreateView.as_view(), - name='document_version_signature_embedded_create' + regex=r'^documents/versions/(?P\d+)/signatures/detached/upload/$', + name='document_version_signature_upload', + view=DocumentVersionSignatureUploadView.as_view() ), url( - r'^signature/(?P\d+)/delete/$', - DocumentVersionSignatureDeleteView.as_view(), - name='document_version_signature_delete' + regex=r'^documents/versions/(?P\d+)/signatures/embedded/create/$', + name='document_version_signature_embedded_create', + view=DocumentVersionEmbeddedSignatureCreateView.as_view() ), url( - r'^tools/all/document/version/signature/verify/$', - AllDocumentSignatureVerifyView.as_view(), - name='all_document_version_signature_verify' - ), + regex=r'^tools/documents/versions/signatures/verify/$', + name='all_document_version_signature_verify', + view=AllDocumentSignatureVerifyView.as_view() + ) ] diff --git a/mayan/apps/document_signatures/views.py b/mayan/apps/document_signatures/views.py index 4be6427c45..e77f4aa261 100644 --- a/mayan/apps/document_signatures/views.py +++ b/mayan/apps/document_signatures/views.py @@ -5,20 +5,18 @@ import logging from django.contrib import messages from django.core.files import File from django.http import HttpResponseRedirect -from django.shortcuts import get_object_or_404 from django.template import RequestContext from django.urls import reverse from django.utils.encoding import force_text from django.utils.translation import ugettext_lazy as _ -from mayan.apps.acls.models import AccessControlList from mayan.apps.common.generics import ( ConfirmView, FormView, SingleObjectCreateView, SingleObjectDeleteView, SingleObjectDetailView, SingleObjectDownloadView, SingleObjectListView ) +from mayan.apps.common.mixins import ExternalObjectMixin from mayan.apps.common.utils import TemporaryFile from mayan.apps.django_gpg.exceptions import NeedPassphrase, PassphraseError -from mayan.apps.django_gpg.permissions import permission_key_sign from mayan.apps.documents.models import DocumentVersion from .forms import ( @@ -45,17 +43,16 @@ from .tasks import task_verify_missing_embedded_signature logger = logging.getLogger(__name__) -class DocumentVersionDetachedSignatureCreateView(FormView): +class DocumentVersionDetachedSignatureCreateView(ExternalObjectMixin, FormView): + external_object_class = DocumentVersion + external_object_permission = permission_document_version_sign_detached + external_object_pk_url_kwarg = 'document_version_id' form_class = DocumentVersionSignatureCreateForm def form_valid(self, form): key = form.cleaned_data['key'] passphrase = form.cleaned_data['passphrase'] or None - AccessControlList.objects.check_access( - permissions=permission_key_sign, user=self.request.user, obj=key - ) - try: with self.get_document_version().open() as file_object: detached_signature = key.sign_file( @@ -64,22 +61,23 @@ class DocumentVersionDetachedSignatureCreateView(FormView): ) except NeedPassphrase: messages.error( - self.request, _('Passphrase is needed to unlock this key.') + message=_('Passphrase is needed to unlock this key.'), + request=self.request ) return HttpResponseRedirect( - reverse( - 'signatures:document_version_signature_detached_create', - args=(self.get_document_version().pk,) + redirect_to=reverse( + viewname='signatures:document_version_signature_detached_create', + kwargs={'document_version_id': self.get_document_version().pk} ) ) except PassphraseError: messages.error( - self.request, _('Passphrase is incorrect.') + message=_('Passphrase is incorrect.'), request=self.request ) return HttpResponseRedirect( - reverse( - 'signatures:document_version_signature_detached_create', - args=(self.get_document_version().pk,) + redirect_to=reverse( + viewname='signatures:document_version_signature_detached_create', + kwargs={'document_version_id': self.get_document_version().pk} ) ) else: @@ -95,25 +93,16 @@ class DocumentVersionDetachedSignatureCreateView(FormView): temporary_file_object.close() messages.success( - self.request, _('Document version signed successfully.') + message=_('Document version signed successfully.'), + request=self.request ) return super( DocumentVersionDetachedSignatureCreateView, self ).form_valid(form) - def dispatch(self, request, *args, **kwargs): - AccessControlList.objects.check_access( - permissions=permission_document_version_sign_detached, - user=request.user, obj=self.get_document_version().document - ) - - return super( - DocumentVersionDetachedSignatureCreateView, self - ).dispatch(request, *args, **kwargs) - def get_document_version(self): - return get_object_or_404(klass=DocumentVersion, pk=self.kwargs['pk']) + return self.get_external_object() def get_extra_context(self): return { @@ -123,33 +112,26 @@ class DocumentVersionDetachedSignatureCreateView(FormView): ) % self.get_document_version(), } - def get_form_kwargs(self): - result = super( - DocumentVersionDetachedSignatureCreateView, self - ).get_form_kwargs() - - result.update({'user': self.request.user}) - - return result + def get_form_extra_kwargs(self): + return {'user': self.request.user} def get_post_action_redirect(self): return reverse( - 'signatures:document_version_signature_list', - args=(self.get_document_version().pk,) + viewname='signatures:document_version_signature_list', + kwargs={'document_version_id': self.get_document_version().pk} ) class DocumentVersionEmbeddedSignatureCreateView(FormView): + external_object_class = DocumentVersion + external_object_permission = permission_document_version_sign_embedded + external_object_pk_url_kwarg = 'document_version_id' form_class = DocumentVersionSignatureCreateForm def form_valid(self, form): key = form.cleaned_data['key'] passphrase = form.cleaned_data['passphrase'] or None - AccessControlList.objects.check_access( - permissions=permission_key_sign, user=self.request.user, obj=key - ) - try: with self.get_document_version().open() as file_object: signature_result = key.sign_file( @@ -157,22 +139,23 @@ class DocumentVersionEmbeddedSignatureCreateView(FormView): ) except NeedPassphrase: messages.error( - self.request, _('Passphrase is needed to unlock this key.') + message=_('Passphrase is needed to unlock this key.'), + request=self.request ) return HttpResponseRedirect( - reverse( - 'signatures:document_version_signature_embedded_create', - args=(self.get_document_version().pk,) + redirect_to=reverse( + viewname='signatures:document_version_signature_embedded_create', + kwargs={'document_version_id': self.get_document_version().pk} ) ) except PassphraseError: messages.error( - self.request, _('Passphrase is incorrect.') + message=_('Passphrase is incorrect.'), request=self.request ) return HttpResponseRedirect( - reverse( - 'signatures:document_version_signature_embedded_create', - args=(self.get_document_version().pk,) + redirect_to=reverse( + viewname='signatures:document_version_signature_embedded_create', + kwargs={'document_version_id': self.get_document_version().pk} ) ) else: @@ -187,13 +170,14 @@ class DocumentVersionEmbeddedSignatureCreateView(FormView): temporary_file_object.close() messages.success( - self.request, _('Document version signed successfully.') + message=_('Document version signed successfully.'), + request=self.request ) return HttpResponseRedirect( - reverse( - 'signatures:document_version_signature_list', - args=(new_version.pk,) + redirect_to=reverse( + viewname='signatures:document_version_signature_list', + kwargs={'document_version_id': new_version.pk} ) ) @@ -201,18 +185,8 @@ class DocumentVersionEmbeddedSignatureCreateView(FormView): DocumentVersionEmbeddedSignatureCreateView, self ).form_valid(form) - def dispatch(self, request, *args, **kwargs): - AccessControlList.objects.check_access( - permissions=permission_document_version_sign_embedded, - user=request.user, obj=self.get_document_version().document - ) - - return super( - DocumentVersionEmbeddedSignatureCreateView, self - ).dispatch(request, *args, **kwargs) - def get_document_version(self): - return get_object_or_404(klass=DocumentVersion, pk=self.kwargs['pk']) + return self.get_external_object() def get_extra_context(self): return { @@ -222,20 +196,13 @@ class DocumentVersionEmbeddedSignatureCreateView(FormView): ) % self.get_document_version(), } - def get_form_kwargs(self): - result = super( - DocumentVersionEmbeddedSignatureCreateView, self - ).get_form_kwargs() - - result.update({'user': self.request.user}) - - return result + def get_form_extra_kwargs(self): + return {'user': self.request.user} class DocumentVersionSignatureDeleteView(SingleObjectDeleteView): - model = DetachedSignature object_permission = permission_document_version_signature_delete - object_permission_related = 'document_version.document' + pk_url_kwarg = 'signature_id' def get_extra_context(self): return { @@ -246,15 +213,18 @@ class DocumentVersionSignatureDeleteView(SingleObjectDeleteView): def get_post_action_redirect(self): return reverse( - 'signatures:document_version_signature_list', - args=(self.get_object().document_version.pk,) + viewname='signatures:document_version_signature_list', + kwargs={'document_version_id': self.get_object().document_version.pk} ) + def get_object_list(self): + return SignatureBaseModel.objects.select_subclasses() + class DocumentVersionSignatureDetailView(SingleObjectDetailView): form_class = DocumentVersionSignatureDetailForm object_permission = permission_document_version_signature_view - object_permission_related = 'document_version.document' + pk_url_kwarg = 'signature_id' def get_extra_context(self): return { @@ -266,14 +236,13 @@ class DocumentVersionSignatureDetailView(SingleObjectDetailView): ) % self.get_object(), } - def get_queryset(self): + def get_object_list(self): return SignatureBaseModel.objects.select_subclasses() class DocumentVersionSignatureDownloadView(SingleObjectDownloadView): - model = DetachedSignature object_permission = permission_document_version_signature_download - object_permission_related = 'document_version.document' + pk_url_kwarg = 'signature_id' def get_file(self): signature = self.get_object() @@ -282,20 +251,17 @@ class DocumentVersionSignatureDownloadView(SingleObjectDownloadView): signature.signature_file, name=force_text(signature) ) + def get_object_list(self): + return SignatureBaseModel.objects.select_subclasses() -class DocumentVersionSignatureListView(SingleObjectListView): - def dispatch(self, request, *args, **kwargs): - AccessControlList.objects.check_access( - permissions=permission_document_version_signature_view, - user=request.user, obj=self.get_document_version() - ) - return super( - DocumentVersionSignatureListView, self - ).dispatch(request, *args, **kwargs) +class DocumentVersionSignatureListView(ExternalObjectMixin, SingleObjectListView): + external_object_class = DocumentVersion + external_object_permission = permission_document_version_signature_view + external_object_pk_url_kwarg = 'document_version_id' def get_document_version(self): - return get_object_or_404(klass=DocumentVersion, pk=self.kwargs['pk']) + return self.get_external_object() def get_extra_context(self): return { @@ -335,22 +301,15 @@ class DocumentVersionSignatureListView(SingleObjectListView): return self.get_document_version().signatures.all() -class DocumentVersionSignatureUploadView(SingleObjectCreateView): +class DocumentVersionSignatureUploadView(ExternalObjectMixin, SingleObjectCreateView): + external_object_class = DocumentVersion + external_object_permission = permission_document_version_signature_upload + external_object_pk_url_kwarg = 'document_version_id' fields = ('signature_file',) model = DetachedSignature - def dispatch(self, request, *args, **kwargs): - AccessControlList.objects.check_access( - permissions=permission_document_version_signature_upload, - user=request.user, obj=self.get_document_version() - ) - - return super( - DocumentVersionSignatureUploadView, self - ).dispatch(request, *args, **kwargs) - def get_document_version(self): - return get_object_or_404(klass=DocumentVersion, pk=self.kwargs['pk']) + return self.get_external_object() def get_extra_context(self): return { @@ -365,8 +324,8 @@ class DocumentVersionSignatureUploadView(SingleObjectCreateView): def get_post_action_redirect(self): return reverse( - 'signatures:document_version_signature_list', - args=(self.get_document_version().pk,) + viewname='signatures:document_version_signature_list', + kwargs={'document_version_id': self.get_document_version().pk} ) @@ -379,10 +338,11 @@ class AllDocumentSignatureVerifyView(ConfirmView): view_permission = permission_document_version_signature_verify def get_post_action_redirect(self): - return reverse('common:tools_list') + return reverse(viewname='common:tools_list') def view_action(self): task_verify_missing_embedded_signature.delay() messages.success( - self.request, _('Signature verification queued successfully.') + message=_('Signature verification queued successfully.'), + request=self.request )