Update and re enable document_signature app
This commit is contained in:
@@ -1,85 +1 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
import logging
|
||||
|
||||
try:
|
||||
from cStringIO import StringIO
|
||||
except ImportError:
|
||||
from StringIO import StringIO
|
||||
|
||||
#from django.db.models.signals import post_save
|
||||
#from django.dispatch import receiver
|
||||
|
||||
from documents.models import Document, DocumentVersion
|
||||
from navigation.api import bind_links
|
||||
from django_gpg.runtime import gpg
|
||||
from django_gpg.exceptions import GPGDecryptionError
|
||||
from acls.api import class_permissions
|
||||
|
||||
from .models import DocumentVersionSignature
|
||||
from .permissions import (
|
||||
PERMISSION_DOCUMENT_VERIFY, PERMISSION_SIGNATURE_UPLOAD,
|
||||
PERMISSION_SIGNATURE_DOWNLOAD, PERMISSION_SIGNATURE_DELETE
|
||||
)
|
||||
from .links import (document_signature_upload, document_signature_download,
|
||||
document_signature_delete, document_verify)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def document_pre_open_hook(descriptor, instance):
|
||||
if DocumentVersionSignature.objects.has_embedded_signature(instance.document):
|
||||
# If it has an embedded signature decrypt
|
||||
try:
|
||||
result = gpg.decrypt_file(descriptor, close_descriptor=False)
|
||||
# gpg return a string, turn it into a file like object
|
||||
except GPGDecryptionError:
|
||||
# At least return the original raw content
|
||||
descriptor.seek(0)
|
||||
return descriptor
|
||||
else:
|
||||
descriptor.close()
|
||||
return StringIO(result.data)
|
||||
else:
|
||||
# It no embedded signature pass along
|
||||
# Doing this single DB lookup avoids trying to decrypt non signed
|
||||
# files always, which could result in slow down for big non signed
|
||||
# files
|
||||
#descriptor.seek(0)
|
||||
return descriptor
|
||||
|
||||
#try:
|
||||
# result = gpg.decrypt_file(descriptor, close_descriptor=False)
|
||||
# # gpg return a string, turn it into a file like object
|
||||
#except GPGDecryptionError:
|
||||
# # At least return the original raw content
|
||||
# descriptor.seek(0)
|
||||
# return descriptor
|
||||
#else:
|
||||
# descriptor.close()
|
||||
# return StringIO(result.data)
|
||||
|
||||
|
||||
def document_post_save_hook(instance):
|
||||
if not instance.pk:
|
||||
document_signature, created = DocumentVersionSignature.objects.get_or_create(
|
||||
document_version=instance.latest_version,
|
||||
)
|
||||
#DocumentVersionSignature.objects.update_signed_state(instance.document)
|
||||
|
||||
#@receiver(post_save, dispatch_uid='check_document_signature_state', sender=DocumentVersion)
|
||||
#def check_document_signature_state(sender, instance, **kwargs):
|
||||
# if kwargs.get('created', False):
|
||||
# DocumentVersionSignature.objects.signature_state(instance.document)
|
||||
|
||||
|
||||
bind_links([Document], [document_verify], menu_name='form_header')
|
||||
bind_links(['document_verify', 'document_signature_upload', 'document_signature_download', 'document_signature_delete'], [document_signature_upload, document_signature_download, document_signature_delete], menu_name='sidebar')
|
||||
|
||||
DocumentVersion.register_pre_open_hook(1, document_pre_open_hook)
|
||||
DocumentVersion.register_post_save_hook(1, document_post_save_hook)
|
||||
|
||||
class_permissions(Document, [
|
||||
PERMISSION_DOCUMENT_VERIFY, PERMISSION_SIGNATURE_UPLOAD,
|
||||
PERMISSION_SIGNATURE_DOWNLOAD, PERMISSION_SIGNATURE_DELETE
|
||||
])
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
from django import forms
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
#from django.utils.translation import ugettext
|
||||
#from django.core.urlresolvers import reverse
|
||||
#from django.utils.safestring import mark_safe
|
||||
#from django.conf import settings
|
||||
|
||||
|
||||
class DetachedSignatureForm(forms.Form):
|
||||
|
||||
9
apps/document_signatures/icons.py
Normal file
9
apps/document_signatures/icons.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
from icons.literals import PENCIL_ADD, DISK, PENCIL_DELETE, TEXT_SIGNATURE
|
||||
from icons import Icon
|
||||
|
||||
icon_document_signature_upload = Icon(PENCIL_ADD)
|
||||
icon_document_signature_download = Icon(DISK)
|
||||
icon_document_signature_delete = Icon(PENCIL_DELETE)
|
||||
icon_document_verify = Icon(TEXT_SIGNATURE)
|
||||
@@ -9,6 +9,8 @@ from .permissions import (
|
||||
PERMISSION_DOCUMENT_VERIFY, PERMISSION_SIGNATURE_UPLOAD,
|
||||
PERMISSION_SIGNATURE_DOWNLOAD, PERMISSION_SIGNATURE_DELETE
|
||||
)
|
||||
from .icons import (icon_document_signature_upload, icon_document_signature_download,
|
||||
icon_document_signature_delete, icon_document_verify)
|
||||
|
||||
|
||||
def has_embedded_signature(context):
|
||||
@@ -18,7 +20,8 @@ def has_embedded_signature(context):
|
||||
def doesnt_have_detached_signature(context):
|
||||
return DocumentVersionSignature.objects.has_detached_signature(context['object']) == False
|
||||
|
||||
document_signature_upload = Link(text=_(u'upload signature'), view='document_signature_upload', args='object.pk', sprite='pencil_add', permissions=[PERMISSION_SIGNATURE_UPLOAD], conditional_disable=has_embedded_signature)
|
||||
document_signature_download = Link(text=_(u'download signature'), view='document_signature_download', args='object.pk', sprite='disk', permissions=[PERMISSION_SIGNATURE_DOWNLOAD], conditional_disable=doesnt_have_detached_signature)
|
||||
document_signature_delete = Link(text=_(u'delete signature'), view='document_signature_delete', args='object.pk', sprite='pencil_delete', permissions=[PERMISSION_SIGNATURE_DELETE], conditional_disable=doesnt_have_detached_signature)
|
||||
document_verify = Link(text=_(u'signatures'), view='document_verify', args='object.pk', sprite='text_signature', permissions=[PERMISSION_DOCUMENT_VERIFY])
|
||||
|
||||
document_signature_upload = Link(text=_(u'upload signature'), view='document_signature_upload', args='object.pk', icon=icon_document_signature_upload, permissions=[PERMISSION_SIGNATURE_UPLOAD], conditional_disable=has_embedded_signature)
|
||||
document_signature_download = Link(text=_(u'download signature'), view='document_signature_download', args='object.pk', icon=icon_document_signature_download, permissions=[PERMISSION_SIGNATURE_DOWNLOAD], conditional_disable=doesnt_have_detached_signature)
|
||||
document_signature_delete = Link(text=_(u'delete signature'), view='document_signature_delete', args='object.pk', icon=icon_document_signature_delete, permissions=[PERMISSION_SIGNATURE_DELETE], conditional_disable=doesnt_have_detached_signature)
|
||||
document_verify = Link(text=_(u'signatures'), view='document_verify', args='object.pk', icon=icon_document_verify, permissions=[PERMISSION_DOCUMENT_VERIFY])
|
||||
|
||||
@@ -2,7 +2,6 @@ import logging
|
||||
|
||||
from django.db import models
|
||||
|
||||
from django_gpg.runtime import gpg
|
||||
from django_gpg.exceptions import GPGVerificationError
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -52,6 +51,8 @@ class DocumentVersionSignatureManager(models.Manager):
|
||||
return document_signature.signature_file.storage.open(document_signature.signature_file.path)
|
||||
|
||||
def verify_signature(self, document):
|
||||
from django_gpg.runtime import gpg
|
||||
|
||||
document_descriptor = document.open(raw=True)
|
||||
detached_signature = None
|
||||
if self.has_detached_signature(document):
|
||||
|
||||
@@ -5,8 +5,6 @@ from django.db import models
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from documents.models import DocumentVersion, get_filename_from_uuid
|
||||
from documents.conf.settings import STORAGE_BACKEND
|
||||
from django_gpg.runtime import gpg
|
||||
|
||||
from .managers import DocumentVersionSignatureManager
|
||||
|
||||
@@ -18,7 +16,7 @@ class DocumentVersionSignature(models.Model):
|
||||
Model that describes a document version signature properties
|
||||
"""
|
||||
document_version = models.ForeignKey(DocumentVersion, verbose_name=_(u'document version'), editable=False)
|
||||
signature_file = models.FileField(blank=True, null=True, upload_to=get_filename_from_uuid, storage=STORAGE_BACKEND(), verbose_name=_(u'signature file'), editable=False)
|
||||
signature_file = models.FileField(blank=True, null=True, upload_to=get_filename_from_uuid, verbose_name=_(u'signature file'), editable=False)
|
||||
has_embedded_signature = models.BooleanField(default=False, verbose_name=_(u'has embedded signature'), editable=False)
|
||||
|
||||
objects = DocumentVersionSignatureManager()
|
||||
@@ -27,6 +25,8 @@ class DocumentVersionSignature(models.Model):
|
||||
self.signature_file.storage.delete(self.signature_file.path)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
from django_gpg.runtime import gpg
|
||||
|
||||
if not self.pk:
|
||||
descriptor = self.document_version.open(raw=True)
|
||||
self.has_embedded_signature = gpg.has_embedded_signature(descriptor)
|
||||
|
||||
89
apps/document_signatures/post_init.py
Normal file
89
apps/document_signatures/post_init.py
Normal file
@@ -0,0 +1,89 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
import logging
|
||||
|
||||
try:
|
||||
from cStringIO import StringIO
|
||||
except ImportError:
|
||||
from StringIO import StringIO
|
||||
|
||||
#from django.db.models.signals import post_save
|
||||
#from django.dispatch import receiver
|
||||
|
||||
from documents.models import Document, DocumentVersion
|
||||
from navigation.api import bind_links
|
||||
from django_gpg.runtime import gpg
|
||||
from django_gpg.exceptions import GPGDecryptionError
|
||||
from acls.api import class_permissions
|
||||
from documents.settings import STORAGE_BACKEND
|
||||
|
||||
from .models import DocumentVersionSignature
|
||||
from .permissions import (
|
||||
PERMISSION_DOCUMENT_VERIFY, PERMISSION_SIGNATURE_UPLOAD,
|
||||
PERMISSION_SIGNATURE_DOWNLOAD, PERMISSION_SIGNATURE_DELETE
|
||||
)
|
||||
from .links import (document_signature_upload, document_signature_download,
|
||||
document_signature_delete, document_verify)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def document_pre_open_hook(descriptor, instance):
|
||||
if DocumentVersionSignature.objects.has_embedded_signature(instance.document):
|
||||
# If it has an embedded signature decrypt
|
||||
try:
|
||||
result = gpg.decrypt_file(descriptor, close_descriptor=False)
|
||||
# gpg return a string, turn it into a file like object
|
||||
except GPGDecryptionError:
|
||||
# At least return the original raw content
|
||||
descriptor.seek(0)
|
||||
return descriptor
|
||||
else:
|
||||
descriptor.close()
|
||||
return StringIO(result.data)
|
||||
else:
|
||||
# It no embedded signature pass along
|
||||
# Doing this single DB lookup avoids trying to decrypt non signed
|
||||
# files always, which could result in slow down for big non signed
|
||||
# files
|
||||
#descriptor.seek(0)
|
||||
return descriptor
|
||||
|
||||
#try:
|
||||
# result = gpg.decrypt_file(descriptor, close_descriptor=False)
|
||||
# # gpg return a string, turn it into a file like object
|
||||
#except GPGDecryptionError:
|
||||
# # At least return the original raw content
|
||||
# descriptor.seek(0)
|
||||
# return descriptor
|
||||
#else:
|
||||
# descriptor.close()
|
||||
# return StringIO(result.data)
|
||||
|
||||
|
||||
def document_post_save_hook(instance):
|
||||
if not instance.pk:
|
||||
document_signature, created = DocumentVersionSignature.objects.get_or_create(
|
||||
document_version=instance.latest_version,
|
||||
)
|
||||
#DocumentVersionSignature.objects.update_signed_state(instance.document)
|
||||
|
||||
#@receiver(post_save, dispatch_uid='check_document_signature_state', sender=DocumentVersion)
|
||||
#def check_document_signature_state(sender, instance, **kwargs):
|
||||
# if kwargs.get('created', False):
|
||||
# DocumentVersionSignature.objects.signature_state(instance.document)
|
||||
|
||||
def init_app():
|
||||
bind_links([Document], [document_verify], menu_name='form_header')
|
||||
bind_links(['document_verify', 'document_signature_upload', 'document_signature_download', 'document_signature_delete'], [document_signature_upload, document_signature_download, document_signature_delete], menu_name='sidebar')
|
||||
|
||||
DocumentVersion.register_pre_open_hook(1, document_pre_open_hook)
|
||||
DocumentVersion.register_post_save_hook(1, document_post_save_hook)
|
||||
|
||||
class_permissions(Document, [
|
||||
PERMISSION_DOCUMENT_VERIFY, PERMISSION_SIGNATURE_UPLOAD,
|
||||
PERMISSION_SIGNATURE_DOWNLOAD, PERMISSION_SIGNATURE_DELETE
|
||||
])
|
||||
|
||||
DocumentVersionSignature._meta.get_field('signature_file').storage=STORAGE_BACKEND()
|
||||
|
||||
10
apps/document_signatures/registry.py
Normal file
10
apps/document_signatures/registry.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from .icons import icon_document_verify
|
||||
|
||||
label = _(u'Document signatures')
|
||||
description = _(u'Handles document signatures.')
|
||||
dependencies = ['app_registry', 'icons', 'navigation', 'django_gpg', 'documents', 'permissions']
|
||||
icon = icon_document_verify
|
||||
@@ -20,7 +20,7 @@ from acls.models import AccessEntry
|
||||
|
||||
from django_gpg.api import SIGNATURE_STATES
|
||||
|
||||
from . import (PERMISSION_DOCUMENT_VERIFY, PERMISSION_SIGNATURE_UPLOAD,
|
||||
from .permissions import (PERMISSION_DOCUMENT_VERIFY, PERMISSION_SIGNATURE_UPLOAD,
|
||||
PERMISSION_SIGNATURE_DOWNLOAD, PERMISSION_SIGNATURE_DELETE)
|
||||
from .forms import DetachedSignatureForm
|
||||
from .models import DocumentVersionSignature
|
||||
@@ -42,10 +42,9 @@ def document_verify(request, document_pk):
|
||||
|
||||
signature_state = SIGNATURE_STATES.get(getattr(signature, 'status', None))
|
||||
|
||||
widget = (u'<img style="vertical-align: middle;" src="%simages/icons/%s" />' % (settings.STATIC_URL, signature_state['icon']))
|
||||
paragraphs = [
|
||||
_(u'Signature status: %(widget)s %(text)s') % {
|
||||
'widget': mark_safe(widget),
|
||||
_(u'Signature status: %(icon)s %(text)s') % {
|
||||
'icon': signature_state['icon'].display_big(),
|
||||
'text': signature_state['text']
|
||||
},
|
||||
]
|
||||
|
||||
@@ -21,7 +21,7 @@ class Icon(object):
|
||||
return IconSetBase.get_by_name(self.icon_set or ICON_SET).get_url(self, size)
|
||||
|
||||
def display(self, size): # TODO: move to widgets?
|
||||
return mark_safe('<img src="%sicons/%s" />' % (settings.STATIC_URL, self.get_url(size)))
|
||||
return mark_safe('<img style="vertical-align: middle;" src="%sicons/%s" />' % (settings.STATIC_URL, self.get_url(size)))
|
||||
|
||||
def display_small(self):
|
||||
return self.display(SIZE_SMALL)
|
||||
|
||||
@@ -39,6 +39,7 @@ class IconSet(IconSetBase):
|
||||
DATABASE_EDIT: 'database_edit.png',
|
||||
DATABASE_DELETE: 'database_delete.png',
|
||||
DELETE: 'delete.png',
|
||||
DISK: 'disk.png',
|
||||
DRAW_AIRBRUSH: 'draw_airbrush.png',
|
||||
DOCUMENT_SIGNATURE: 'document_signature.png',
|
||||
ERROR: 'error.png',
|
||||
@@ -99,6 +100,8 @@ class IconSet(IconSetBase):
|
||||
PAGE_WHITE_PICTURE: 'page_white_picture.png',
|
||||
PAGE_WHITE_TEXT: 'page_white_text.png',
|
||||
PAGE_WORLD: 'page_world.png',
|
||||
PENCIL_ADD: 'pencil_add.png',
|
||||
PENCIL_DELETE: 'pencil_delete.png',
|
||||
PICTURES: 'pictures.png',
|
||||
PILL: 'pill.png',
|
||||
PLUGIN: 'plugin.png',
|
||||
@@ -123,6 +126,7 @@ class IconSet(IconSetBase):
|
||||
TAG_BLUE_DELETE: 'tag_blue_delete.png',
|
||||
TAG_BLUE_EDIT: 'tag_blue_edit.png',
|
||||
TEXT_DROPCAPS: 'text_dropcaps.png',
|
||||
TEXT_SIGNATURE: 'text_signature.png',
|
||||
TEXT_STRIKETHROUGH: 'text_strikethrough.png',
|
||||
THEATER: 'theater.png',
|
||||
TICK: 'tick.png',
|
||||
@@ -132,6 +136,7 @@ class IconSet(IconSetBase):
|
||||
USER_ADD:'user_add.png',
|
||||
USER_EDIT: 'user_edit.png',
|
||||
USER_DELETE: 'user_delete.png',
|
||||
USER_SILHOUETTE: 'user_silhouette.png',
|
||||
VCARD: 'vcard.png',
|
||||
VCARD_EDIT: 'vcard_edit.png',
|
||||
WRENCH: 'wrench.png',
|
||||
|
||||
@@ -33,6 +33,7 @@ DATABASE_ADD = 'database_add'
|
||||
DATABASE_EDIT = 'database_edit'
|
||||
DATABASE_DELETE = 'database_delete'
|
||||
DELETE = 'delete'
|
||||
DISK = 'disk'
|
||||
DRAW_AIRBRUSH = 'draw_airbrush'
|
||||
DOCUMENT_SIGNATURE = 'document_signature'
|
||||
ERROR = 'error'
|
||||
@@ -95,6 +96,8 @@ PAGE_WHITE_EDIT = 'page_white_edit'
|
||||
PAGE_WHITE_PICTURE = 'page_white_picture'
|
||||
PAGE_WHITE_TEXT = 'page_white_text'
|
||||
PAGE_WORLD = 'page_world'
|
||||
PENCIL_ADD = 'pencil_add'
|
||||
PENCIL_DELETE = 'pencil_delete'
|
||||
PICTURES = 'pictures'
|
||||
PILL = 'pill'
|
||||
PLUGIN = 'plugin'
|
||||
@@ -119,6 +122,7 @@ TAG_BLUE_ADD = 'tag_blue_add'
|
||||
TAG_BLUE_DELETE = 'tag_blue_delete'
|
||||
TAG_BLUE_EDIT = 'tag_blue_edit'
|
||||
TEXT_DROPCAPS = 'text_dropcaps'
|
||||
TEXT_SIGNATURE = 'text_signature'
|
||||
TEXT_STRIKETHROUGH = 'text_strikethrough'
|
||||
THEATER = 'theater'
|
||||
TICK = 'tick'
|
||||
@@ -128,6 +132,7 @@ USER = 'user'
|
||||
USER_ADD = 'user_add'
|
||||
USER_EDIT = 'user_edit'
|
||||
USER_DELETE = 'user_delete'
|
||||
USER_SILHOUETTE = 'user_silhouette'
|
||||
VCARD = 'vcard'
|
||||
VCARD_EDIT = 'vcard_edit'
|
||||
WRENCH = 'wrench'
|
||||
|
||||
@@ -175,7 +175,7 @@ INSTALLED_APPS = (
|
||||
'folders',
|
||||
'dynamic_search',
|
||||
'document_comments',
|
||||
#'document_signatures',
|
||||
'document_signatures',
|
||||
'linking',
|
||||
'metadata',
|
||||
'ocr',
|
||||
|
||||
2
urls.py
2
urls.py
@@ -29,7 +29,7 @@ urlpatterns = patterns('',
|
||||
#(r'^document_acls/', include('document_acls.urls')),
|
||||
(r'^api/', include('rest_api.urls')),
|
||||
(r'^gpg/', include('django_gpg.urls')),
|
||||
#(r'^documents/signatures/', include('document_signatures.urls')),
|
||||
(r'^documents/signatures/', include('document_signatures.urls')),
|
||||
#(r'^mailer/', include('mailer.urls')),
|
||||
#(r'^workflows/', include('workflows.urls')),
|
||||
#(r'^checkouts/', include('checkouts.urls')),
|
||||
|
||||
Reference in New Issue
Block a user