Files
mayan-edms/mayan/apps/document_signatures/views.py
Roberto Rosario 48fc36d54e Convert the document version list view to item view mode.
Add document version preview and thumbnail widgets.
Update the new version upload event have the version
as the target and the document as the action object.

Signed-off-by: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>
2017-08-02 04:10:09 -04:00

358 lines
12 KiB
Python

from __future__ import absolute_import, unicode_literals
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.urls import reverse
from django.utils.encoding import force_text
from django.utils.translation import ugettext_lazy as _
from acls.models import AccessControlList
from common.generics import (
ConfirmView, FormView, SingleObjectCreateView, SingleObjectDeleteView,
SingleObjectDetailView, SingleObjectDownloadView, SingleObjectListView
)
from common.utils import TemporaryFile
from django_gpg.exceptions import NeedPassphrase, PassphraseError
from django_gpg.permissions import permission_key_sign
from documents.models import DocumentVersion
from .forms import (
DocumentVersionSignatureCreateForm,
DocumentVersionSignatureDetailForm
)
from .models import DetachedSignature, SignatureBaseModel
from .permissions import (
permission_document_version_sign_detached,
permission_document_version_sign_embedded,
permission_document_version_signature_delete,
permission_document_version_signature_download,
permission_document_version_signature_upload,
permission_document_version_signature_verify,
permission_document_version_signature_view,
)
from .tasks import task_verify_missing_embedded_signature
logger = logging.getLogger(__name__)
class DocumentVersionDetachedSignatureCreateView(FormView):
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(
file_object=file_object, detached=True,
passphrase=passphrase
)
except NeedPassphrase:
messages.error(
self.request, _('Passphrase is needed to unlock this key.')
)
return HttpResponseRedirect(
reverse(
'signatures:document_version_signature_detached_create',
args=(self.get_document_version().pk,)
)
)
except PassphraseError:
messages.error(
self.request, _('Passphrase is incorrect.')
)
return HttpResponseRedirect(
reverse(
'signatures:document_version_signature_detached_create',
args=(self.get_document_version().pk,)
)
)
else:
temporary_file_object = TemporaryFile()
temporary_file_object.write(detached_signature.data)
temporary_file_object.seek(0)
DetachedSignature.objects.create(
document_version=self.get_document_version(),
signature_file=File(temporary_file_object)
)
temporary_file_object.close()
messages.success(
self.request, _('Document version signed successfully.')
)
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(DocumentVersion, pk=self.kwargs['pk'])
def get_extra_context(self):
return {
'object': self.get_document_version(),
'title': _(
'Sign document version "%s" with a detached signature'
) % 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_post_action_redirect(self):
return reverse(
'signatures:document_version_signature_list',
args=(self.get_document_version().pk,)
)
class DocumentVersionEmbeddedSignatureCreateView(FormView):
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(
binary=True, file_object=file_object, passphrase=passphrase
)
except NeedPassphrase:
messages.error(
self.request, _('Passphrase is needed to unlock this key.')
)
return HttpResponseRedirect(
reverse(
'signatures:document_version_signature_embedded_create',
args=(self.get_document_version().pk,)
)
)
except PassphraseError:
messages.error(
self.request, _('Passphrase is incorrect.')
)
return HttpResponseRedirect(
reverse(
'signatures:document_version_signature_embedded_create',
args=(self.get_document_version().pk,)
)
)
else:
temporary_file_object = TemporaryFile()
temporary_file_object.write(signature_result.data)
temporary_file_object.seek(0)
new_version = self.get_document_version().document.new_version(
file_object=temporary_file_object, _user=self.request.user
)
temporary_file_object.close()
messages.success(
self.request, _('Document version signed successfully.')
)
return HttpResponseRedirect(
reverse(
'signatures:document_version_signature_list',
args=(new_version.pk,)
)
)
return super(
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(DocumentVersion, pk=self.kwargs['pk'])
def get_extra_context(self):
return {
'object': self.get_document_version(),
'title': _(
'Sign document version "%s" with a embedded signature'
) % self.get_document_version(),
}
def get_form_kwargs(self):
result = super(
DocumentVersionEmbeddedSignatureCreateView, self
).get_form_kwargs()
result.update({'user': self.request.user})
return result
class DocumentVersionSignatureDeleteView(SingleObjectDeleteView):
model = DetachedSignature
object_permission = permission_document_version_signature_delete
object_permission_related = 'document_version.document'
def get_extra_context(self):
return {
'object': self.get_object().document_version,
'signature': self.get_object(),
'title': _('Delete detached signature: %s') % self.get_object()
}
def get_post_action_redirect(self):
return reverse(
'signatures:document_version_signature_list',
args=(self.get_object().document_version.pk,)
)
class DocumentVersionSignatureDetailView(SingleObjectDetailView):
form_class = DocumentVersionSignatureDetailForm
object_permission = permission_document_version_signature_view
object_permission_related = 'document_version.document'
def get_extra_context(self):
return {
'hide_object': True,
'object': self.get_object().document_version,
'signature': self.get_object(),
'title': _(
'Details for signature: %s'
) % self.get_object(),
}
def get_queryset(self):
return SignatureBaseModel.objects.select_subclasses()
class DocumentVersionSignatureDownloadView(SingleObjectDownloadView):
model = DetachedSignature
object_permission = permission_document_version_signature_download
object_permission_related = 'document_version.document'
def get_file(self):
signature = self.get_object()
return DocumentVersionSignatureDownloadView.VirtualFile(
signature.signature_file, name=force_text(signature)
)
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)
def get_document_version(self):
return get_object_or_404(DocumentVersion, pk=self.kwargs['pk'])
def get_extra_context(self):
return {
'hide_object': True,
'object': self.get_document_version(),
'title': _(
'Signatures for document version: %s'
) % self.get_document_version(),
}
def get_queryset(self):
return self.get_document_version().signatures.all()
class DocumentVersionSignatureUploadView(SingleObjectCreateView):
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(DocumentVersion, pk=self.kwargs['pk'])
def get_extra_context(self):
return {
'object': self.get_document_version(),
'title': _(
'Upload detached signature for document version: %s'
) % self.get_document_version(),
}
def get_instance_extra_data(self):
return {'document_version': self.get_document_version()}
def get_post_action_redirect(self):
return reverse(
'signatures:document_version_signature_list',
args=(self.get_document_version().pk,)
)
class AllDocumentSignatureVerifyView(ConfirmView):
extra_context = {
'message': _(
'On large databases this operation may take some time to execute.'
), 'title': _('Verify all document for signatures?'),
}
view_permission = permission_document_version_signature_verify
def get_post_action_redirect(self):
return reverse('common:tools_list')
def view_action(self):
task_verify_missing_embedded_signature.delay()
messages.success(
self.request, _('Signature verification queued successfully.')
)