- Use modified port of Django 2.2 FileResponse. - Remove Django DownloadView library. Signed-off-by: Roberto Rosario <roberto.rosario@mayan-edms.com>
367 lines
13 KiB
Python
367 lines
13 KiB
Python
from __future__ import absolute_import, unicode_literals
|
|
|
|
import logging
|
|
|
|
from django.contrib import messages
|
|
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.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 (
|
|
DocumentVersionSignatureCreateForm,
|
|
DocumentVersionSignatureDetailForm
|
|
)
|
|
from .icons import (
|
|
icon_document_signature_list,
|
|
icon_document_version_signature_detached_create,
|
|
icon_document_version_signature_embedded_create
|
|
)
|
|
from .links import (
|
|
link_document_version_signature_detached_create,
|
|
link_document_version_signature_embedded_create,
|
|
link_document_version_signature_upload
|
|
)
|
|
from .models import DetachedSignature, EmbeddedSignature, 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(
|
|
obj=key, permissions=(permission_key_sign,), user=self.request.user
|
|
)
|
|
|
|
try:
|
|
DetachedSignature.objects.sign_document_version(
|
|
document_version=self.get_document_version(),
|
|
key=key, passphrase=passphrase, user=self.request.user
|
|
)
|
|
except NeedPassphrase:
|
|
messages.error(
|
|
message=_('Passphrase is needed to unlock this key.'),
|
|
request=self.request
|
|
)
|
|
return HttpResponseRedirect(
|
|
redirect_to=reverse(
|
|
viewname='signatures:document_version_signature_detached_create',
|
|
kwargs={'pk': self.get_document_version().pk}
|
|
)
|
|
)
|
|
except PassphraseError:
|
|
messages.error(
|
|
message=_('Passphrase is incorrect.'),
|
|
request=self.request
|
|
)
|
|
return HttpResponseRedirect(
|
|
redirect_to=reverse(
|
|
viewname='signatures:document_version_signature_detached_create',
|
|
kwargs={'pk': self.get_document_version().pk}
|
|
)
|
|
)
|
|
else:
|
|
messages.success(
|
|
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(
|
|
obj=self.get_document_version().document,
|
|
permissions=(permission_document_version_sign_detached,),
|
|
user=request.user
|
|
)
|
|
|
|
return super(
|
|
DocumentVersionDetachedSignatureCreateView, self
|
|
).dispatch(request, *args, **kwargs)
|
|
|
|
def get_document_version(self):
|
|
return get_object_or_404(klass=DocumentVersion, pk=self.kwargs['pk'])
|
|
|
|
def get_extra_context(self):
|
|
return {
|
|
'object': self.get_document_version(),
|
|
'submit_icon_class': icon_document_version_signature_detached_create,
|
|
'submit_label': _('Sign'),
|
|
'title': _(
|
|
'Sign document version "%s" with a detached signature'
|
|
) % self.get_document_version(),
|
|
}
|
|
|
|
def get_form_extra_kwargs(self):
|
|
return {'user': self.request.user}
|
|
|
|
def get_post_action_redirect(self):
|
|
return reverse(
|
|
viewname='signatures:document_version_signature_list',
|
|
kwargs={'pk': 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(
|
|
obj=key, permissions=(permission_key_sign,), user=self.request.user
|
|
)
|
|
|
|
try:
|
|
new_version = EmbeddedSignature.objects.sign_document_version(
|
|
document_version=self.get_document_version(),
|
|
key=key, passphrase=passphrase, user=self.request.user
|
|
)
|
|
except NeedPassphrase:
|
|
messages.error(
|
|
message=_('Passphrase is needed to unlock this key.'),
|
|
request=self.request
|
|
)
|
|
return HttpResponseRedirect(
|
|
redirect_to=reverse(
|
|
viewname='signatures:document_version_signature_embedded_create',
|
|
kwargs={'pk': self.get_document_version().pk}
|
|
)
|
|
)
|
|
except PassphraseError:
|
|
messages.error(
|
|
message=_('Passphrase is incorrect.'),
|
|
request=self.request
|
|
)
|
|
return HttpResponseRedirect(
|
|
redirect_to=reverse(
|
|
viewname='signatures:document_version_signature_embedded_create',
|
|
kwargs={'pk': self.get_document_version().pk}
|
|
)
|
|
)
|
|
else:
|
|
messages.success(
|
|
message=_('Document version signed successfully.'),
|
|
request=self.request
|
|
)
|
|
|
|
return HttpResponseRedirect(
|
|
redirect_to=reverse(
|
|
viewname='signatures:document_version_signature_list',
|
|
kwargs={'pk': new_version.pk}
|
|
)
|
|
)
|
|
|
|
return super(
|
|
DocumentVersionEmbeddedSignatureCreateView, self
|
|
).form_valid(form)
|
|
|
|
def dispatch(self, request, *args, **kwargs):
|
|
AccessControlList.objects.check_access(
|
|
obj=self.get_document_version().document,
|
|
permissions=(permission_document_version_sign_embedded,),
|
|
user=request.user
|
|
)
|
|
|
|
return super(
|
|
DocumentVersionEmbeddedSignatureCreateView, self
|
|
).dispatch(request, *args, **kwargs)
|
|
|
|
def get_document_version(self):
|
|
return get_object_or_404(klass=DocumentVersion, pk=self.kwargs['pk'])
|
|
|
|
def get_extra_context(self):
|
|
return {
|
|
'object': self.get_document_version(),
|
|
'submit_icon_class': icon_document_version_signature_embedded_create,
|
|
'submit_label': _('Sign'),
|
|
'title': _(
|
|
'Sign document version "%s" with a embedded signature'
|
|
) % self.get_document_version(),
|
|
}
|
|
|
|
def get_form_extra_kwargs(self):
|
|
return {'user': self.request.user}
|
|
|
|
|
|
class DocumentVersionSignatureDeleteView(SingleObjectDeleteView):
|
|
model = DetachedSignature
|
|
object_permission = permission_document_version_signature_delete
|
|
|
|
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(
|
|
viewname='signatures:document_version_signature_list',
|
|
kwargs={'pk': self.get_object().document_version.pk}
|
|
)
|
|
|
|
|
|
class DocumentVersionSignatureDetailView(SingleObjectDetailView):
|
|
form_class = DocumentVersionSignatureDetailForm
|
|
object_permission = permission_document_version_signature_view
|
|
|
|
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_source_queryset(self):
|
|
return SignatureBaseModel.objects.select_subclasses()
|
|
|
|
|
|
class DocumentVersionSignatureDownloadView(SingleObjectDownloadView):
|
|
model = DetachedSignature
|
|
object_permission = permission_document_version_signature_download
|
|
|
|
def get_download_file_object(self):
|
|
return self.object.signature_file
|
|
|
|
def get_download_filename(self):
|
|
return force_text(self.object)
|
|
|
|
|
|
class DocumentVersionSignatureListView(
|
|
ExternalObjectMixin, SingleObjectListView
|
|
):
|
|
external_object_class = DocumentVersion
|
|
external_object_permission = permission_document_version_signature_view
|
|
|
|
def get_extra_context(self):
|
|
return {
|
|
'hide_object': True,
|
|
'no_results_icon': icon_document_signature_list,
|
|
'no_results_text': _(
|
|
'Signatures help provide authorship evidence and tamper '
|
|
'detection. They are very secure and hard to '
|
|
'forge. A signature can be embedded as part of the document '
|
|
'itself or uploaded as a separate file.'
|
|
),
|
|
'no_results_secondary_links': [
|
|
link_document_version_signature_detached_create.resolve(
|
|
RequestContext(
|
|
request=self.request, dict_={
|
|
'object': self.external_object
|
|
}
|
|
)
|
|
),
|
|
link_document_version_signature_embedded_create.resolve(
|
|
RequestContext(
|
|
request=self.request, dict_={
|
|
'object': self.external_object
|
|
}
|
|
)
|
|
),
|
|
link_document_version_signature_upload.resolve(
|
|
RequestContext(
|
|
request=self.request, dict_={
|
|
'object': self.external_object
|
|
}
|
|
)
|
|
),
|
|
],
|
|
'no_results_title': _('There are no signatures for this document.'),
|
|
'object': self.external_object,
|
|
'title': _(
|
|
'Signatures for document version: %s'
|
|
) % self.external_object,
|
|
}
|
|
|
|
def get_source_queryset(self):
|
|
return self.external_object.signatures.all()
|
|
|
|
|
|
class DocumentVersionSignatureUploadView(SingleObjectCreateView):
|
|
fields = ('signature_file',)
|
|
model = DetachedSignature
|
|
|
|
def dispatch(self, request, *args, **kwargs):
|
|
AccessControlList.objects.check_access(
|
|
obj=self.get_document_version(),
|
|
permissions=(permission_document_version_signature_upload,),
|
|
user=request.user
|
|
)
|
|
|
|
return super(
|
|
DocumentVersionSignatureUploadView, self
|
|
).dispatch(request, *args, **kwargs)
|
|
|
|
def get_document_version(self):
|
|
return get_object_or_404(klass=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(
|
|
viewname='signatures:document_version_signature_list',
|
|
kwargs={'pk': 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(viewname='common:tools_list')
|
|
|
|
def view_action(self):
|
|
task_verify_missing_embedded_signature.delay()
|
|
messages.success(
|
|
message=_('Signature verification queued successfully.'),
|
|
request=self.request
|
|
)
|