Update document signatures app

Add keyword arguments.

Remove source column functions and move their code to the model.

Use the FilteredSelectionForm for the key selection in the
document version signing view.

Update the field definition of the DetailForm subclasses
to use the new internface.

Update URL parameters to use the "_id" form.

Update views filtering to comply with MERC 6.

Move repeated test code to its own test mixin.

Update links to work with the new Link class interface.

Modernize tests.

Signed-off-by: Roberto Rosario <Roberto.Rosario@mayan-edms.com>
This commit is contained in:
Roberto Rosario
2019-01-25 01:32:05 -04:00
parent 890f872681
commit 4937d8b776
12 changed files with 450 additions and 641 deletions

View File

@@ -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(

View File

@@ -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

View File

@@ -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'
)

View File

@@ -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')),
)

View File

@@ -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)

View File

@@ -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 (

View File

@@ -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)
)

View File

@@ -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
}
)
)

View File

@@ -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
)

View File

@@ -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
)

View File

@@ -12,43 +12,43 @@ from .views import (
urlpatterns = [
url(
r'^(?P<pk>\d+)/details/$',
DocumentVersionSignatureDetailView.as_view(),
name='document_version_signature_details'
regex=r'^signatures/(?P<signature_id>\d+)/$',
name='document_version_signature_details',
view=DocumentVersionSignatureDetailView.as_view()
),
url(
r'^signature/(?P<pk>\d+)/download/$',
DocumentVersionSignatureDownloadView.as_view(),
name='document_version_signature_download'
regex=r'^signatures/(?P<signature_id>\d+)/download/$',
name='document_version_signature_download',
view=DocumentVersionSignatureDownloadView.as_view()
),
url(
r'^document/version/(?P<pk>\d+)/signatures/list/$',
DocumentVersionSignatureListView.as_view(),
name='document_version_signature_list'
regex=r'^signatures/(?P<signature_id>\d+)/delete/$',
name='document_version_signature_delete',
view=DocumentVersionSignatureDeleteView.as_view()
),
url(
r'^documents/version/(?P<pk>\d+)/signature/detached/upload/$',
DocumentVersionSignatureUploadView.as_view(),
name='document_version_signature_upload'
regex=r'^documents/versions/(?P<document_version_id>\d+)/signatures/$',
name='document_version_signature_list',
view=DocumentVersionSignatureListView.as_view()
),
url(
r'^documents/version/(?P<pk>\d+)/signature/detached/create/$',
DocumentVersionDetachedSignatureCreateView.as_view(),
name='document_version_signature_detached_create'
regex=r'^documents/versions/(?P<document_version_id>\d+)/signatures/detached/create/$',
name='document_version_signature_detached_create',
view=DocumentVersionDetachedSignatureCreateView.as_view()
),
url(
r'^documents/version/(?P<pk>\d+)/signature/embedded/create/$',
DocumentVersionEmbeddedSignatureCreateView.as_view(),
name='document_version_signature_embedded_create'
regex=r'^documents/versions/(?P<document_version_id>\d+)/signatures/detached/upload/$',
name='document_version_signature_upload',
view=DocumentVersionSignatureUploadView.as_view()
),
url(
r'^signature/(?P<pk>\d+)/delete/$',
DocumentVersionSignatureDeleteView.as_view(),
name='document_version_signature_delete'
regex=r'^documents/versions/(?P<document_version_id>\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()
)
]

View File

@@ -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
)