diff --git a/apps/django_gpg/__init__.py b/apps/django_gpg/__init__.py index e45ae78165..a69efbab8e 100644 --- a/apps/django_gpg/__init__.py +++ b/apps/django_gpg/__init__.py @@ -11,29 +11,30 @@ from hkp import Key as KeyServerKey from django_gpg.api import Key -PERMISSION_DOCUMENT_VERIFY = {'namespace': 'django_gpg', 'name': 'document_verify', 'label': _(u'Verify document signatures')} PERMISSION_KEY_VIEW = {'namespace': 'django_gpg', 'name': 'key_view', 'label': _(u'View keys')} PERMISSION_KEY_DELETE = {'namespace': 'django_gpg', 'name': 'key_delete', 'label': _(u'Delete keys')} PERMISSION_KEYSERVER_QUERY = {'namespace': 'django_gpg', 'name': 'keyserver_query', 'label': _(u'Query keyservers')} PERMISSION_KEY_RECEIVE = {'namespace': 'django_gpg', 'name': 'key_receive', 'label': _(u'Import key from keyservers')} -PERMISSION_SIGNATURE_UPLOAD = {'namespace': 'django_gpg', 'name': 'signature_upload', 'label': _(u'Upload detached signatures')} -PERMISSION_SIGNATURE_DOWNLOAD = {'namespace': 'django_gpg', 'name': 'key_receive', 'label': _(u'Download detached signatures')} +#PERMISSION_DOCUMENT_VERIFY = {'namespace': 'django_gpg', 'name': 'document_verify', 'label': _(u'Verify document signatures')} +#PERMISSION_SIGNATURE_UPLOAD = {'namespace': 'django_gpg', 'name': 'signature_upload', 'label': _(u'Upload detached signatures')} +#PERMISSION_SIGNATURE_DOWNLOAD = {'namespace': 'django_gpg', 'name': 'key_receive', 'label': _(u'Download detached signatures')} # Permission setup set_namespace_title('django_gpg', _(u'Signatures')) -register_permission(PERMISSION_DOCUMENT_VERIFY) register_permission(PERMISSION_KEY_VIEW) register_permission(PERMISSION_KEY_DELETE) register_permission(PERMISSION_KEYSERVER_QUERY) register_permission(PERMISSION_KEY_RECEIVE) -register_permission(PERMISSION_SIGNATURE_UPLOAD) -register_permission(PERMISSION_SIGNATURE_DOWNLOAD) -def has_embedded_signature(context): - return context['object'].signature_state +#register_permission(PERMISSION_DOCUMENT_VERIFY) +#register_permission(PERMISSION_SIGNATURE_UPLOAD) +#register_permission(PERMISSION_SIGNATURE_DOWNLOAD) + +#def has_embedded_signature(context): +# return context['object'].signature_state -def doesnt_have_detached_signature(context): - return context['object'].has_detached_signature() == False +#def doesnt_have_detached_signature(context): +# return context['object'].has_detached_signature() == False # Setup views private_keys = {'text': _(u'private keys'), 'view': 'key_private_list', 'args': 'object.pk', 'famfam': 'key', 'icon': 'key.png', 'permissions': [PERMISSION_KEY_VIEW]} @@ -41,16 +42,16 @@ public_keys = {'text': _(u'public keys'), 'view': 'key_public_list', 'args': 'ob key_delete = {'text': _(u'delete'), 'view': 'key_delete', 'args': ['object.fingerprint', 'object.type'], 'famfam': 'key_delete', 'permissions': [PERMISSION_KEY_DELETE]} key_query = {'text': _(u'query keyservers'), 'view': 'key_query', 'famfam': 'zoom', 'permissions': [PERMISSION_KEYSERVER_QUERY]} key_receive = {'text': _(u'import'), 'view': 'key_receive', 'args': 'object.keyid', 'famfam': 'key_add', 'keep_query': True, 'permissions': [PERMISSION_KEY_RECEIVE]} -document_signature_upload = {'text': _(u'upload signature'), 'view': 'document_signature_upload', 'args': 'object.pk', 'famfam': 'pencil_add', 'permissions': [PERMISSION_SIGNATURE_UPLOAD], 'conditional_disable': has_embedded_signature} -document_signature_download = {'text': _(u'download signature'), 'view': 'document_signature_download', 'args': 'object.pk', 'famfam': 'disk', 'permissions': [PERMISSION_SIGNATURE_DOWNLOAD], 'conditional_disable': doesnt_have_detached_signature} key_setup = {'text': _(u'key management'), 'view': 'key_public_list', 'args': 'object.pk', 'famfam': 'key', 'icon': 'key.png', 'permissions': [PERMISSION_KEY_VIEW]} # Document views -document_verify = {'text': _(u'signatures'), 'view': 'document_verify', 'args': 'object.pk', 'famfam': 'text_signature', 'permissions': [PERMISSION_DOCUMENT_VERIFY]} +#document_verify = {'text': _(u'signatures'), 'view': 'document_verify', 'args': 'object.pk', 'famfam': 'text_signature', 'permissions': [PERMISSION_DOCUMENT_VERIFY]} +#document_signature_upload = {'text': _(u'upload signature'), 'view': 'document_signature_upload', 'args': 'object.pk', 'famfam': 'pencil_add', 'permissions': [PERMISSION_SIGNATURE_UPLOAD], 'conditional_disable': has_embedded_signature} +#document_signature_download = {'text': _(u'download signature'), 'view': 'document_signature_download', 'args': 'object.pk', 'famfam': 'disk', 'permissions': [PERMISSION_SIGNATURE_DOWNLOAD], 'conditional_disable': doesnt_have_detached_signature} -register_links(Document, [document_verify], menu_name='form_header') +#register_links(Document, [document_verify], menu_name='form_header') +#register_links(['document_verify', 'document_signature_upload', 'document_signature_download'], [document_signature_upload, document_signature_download], menu_name='sidebar') -register_links(['document_verify', 'document_signature_upload', 'document_signature_download'], [document_signature_upload, document_signature_download], menu_name='sidebar') #register_links(['key_delete', 'key_private_list', 'key_public_list', 'key_query'], [private_keys, public_keys, key_query], menu_name='sidebar') register_links(['key_delete', 'key_public_list', 'key_query'], [public_keys, key_query], menu_name='sidebar') diff --git a/apps/django_gpg/forms.py b/apps/django_gpg/forms.py index b961daf037..619035fd5d 100644 --- a/apps/django_gpg/forms.py +++ b/apps/django_gpg/forms.py @@ -11,9 +11,3 @@ class KeySearchForm(forms.Form): label=_(u'Term'), help_text=_(u'Name, e-mail, key ID or key fingerprint to look for.') ) - - -class DetachedSignatureForm(forms.Form): - file = forms.FileField( - label=_(u'Signature file'), - ) diff --git a/apps/django_gpg/urls.py b/apps/django_gpg/urls.py index 4a22882d06..04ef8af89c 100644 --- a/apps/django_gpg/urls.py +++ b/apps/django_gpg/urls.py @@ -4,9 +4,6 @@ urlpatterns = patterns('django_gpg.views', url(r'^delete/(?P.+)/(?P\w+)/$', 'key_delete', (), 'key_delete'), url(r'^list/private/$', 'key_list', {'secret': True}, 'key_private_list'), url(r'^list/public/$', 'key_list', {'secret': False}, 'key_public_list'), - url(r'^verify/(?P\d+)/$', 'document_verify', (), 'document_verify'), - url(r'^upload/signature/(?P\d+)/$', 'document_signature_upload', (), 'document_signature_upload'), - url(r'^download/signature/(?P\d+)/$', 'document_signature_download', (), 'document_signature_download'), url(r'^query/$', 'key_query', (), 'key_query'), url(r'^receive/(?P.+)/$', 'key_receive', (), 'key_receive'), ) diff --git a/apps/django_gpg/views.py b/apps/django_gpg/views.py index 6fe629dbe8..7129246887 100644 --- a/apps/django_gpg/views.py +++ b/apps/django_gpg/views.py @@ -11,21 +11,17 @@ from django.utils.safestring import mark_safe from django.conf import settings from django.template.defaultfilters import force_escape -from documents.models import Document, RecentDocument from permissions.api import check_permissions from common.utils import pretty_size, parse_range, urlquote, \ return_diff, encapsulate -from filetransfers.api import serve_file from django_gpg.api import Key, SIGNATURE_STATES from django_gpg.runtime import gpg from django_gpg.exceptions import (GPGVerificationError, KeyFetchingError, KeyImportError) -from django_gpg import (PERMISSION_DOCUMENT_VERIFY, PERMISSION_KEY_VIEW, - PERMISSION_KEY_DELETE, PERMISSION_KEYSERVER_QUERY, - PERMISSION_KEY_RECEIVE, PERMISSION_SIGNATURE_UPLOAD, - PERMISSION_SIGNATURE_DOWNLOAD) -from django_gpg.forms import KeySearchForm, DetachedSignatureForm +from django_gpg import (PERMISSION_KEY_VIEW, PERMISSION_KEY_DELETE, + PERMISSION_KEYSERVER_QUERY, PERMISSION_KEY_RECEIVE) +from django_gpg.forms import KeySearchForm logger = logging.getLogger(__name__) @@ -189,98 +185,3 @@ def key_query(request): return render_to_response('generic_form.html', { 'subtemplates_list': subtemplates_list, }, context_instance=RequestContext(request)) - - -def document_verify(request, document_pk): - check_permissions(request.user, [PERMISSION_DOCUMENT_VERIFY]) - document = get_object_or_404(Document, pk=document_pk) - - RecentDocument.objects.add_document_for_user(request.user, document) - - signature = document.verify_signature() - - signature_state = SIGNATURE_STATES.get(getattr(signature, 'status', None)) - - widget = (u'' % (settings.STATIC_URL, signature_state['icon'])) - paragraphs = [ - _(u'Signature status: %(widget)s %(text)s') % { - 'widget': mark_safe(widget), - 'text': signature_state['text'] - }, - ] - - if document.signature_state: - signature_type = _(u'embedded') - else: - signature_type = _(u'detached') - - if signature: - paragraphs.extend( - [ - _(u'Signature ID: %s') % signature.signature_id, - _(u'Signature type: %s') % signature_type, - _(u'Key ID: %s') % signature.key_id, - _(u'Timestamp: %s') % datetime.fromtimestamp(int(signature.sig_timestamp)), - _(u'Signee: %s') % force_escape(getattr(signature, 'username', u'')), - ] - ) - - return render_to_response('generic_template.html', { - 'title': _(u'signature properties for: %s') % document, - 'object': document, - 'document': document, - 'paragraphs': paragraphs, - }, context_instance=RequestContext(request)) - - -def document_signature_upload(request, document_pk): - check_permissions(request.user, [PERMISSION_SIGNATURE_UPLOAD]) - document = get_object_or_404(Document, pk=document_pk) - - RecentDocument.objects.add_document_for_user(request.user, document) - - post_action_redirect = None - previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', '/'))) - next = request.POST.get('next', request.GET.get('next', post_action_redirect if post_action_redirect else request.META.get('HTTP_REFERER', '/'))) - - if request.method == 'POST': - form = DetachedSignatureForm(request.POST, request.FILES) - if form.is_valid(): - try: - document.add_detached_signature(request.FILES['file']) - messages.success(request, _(u'Detached signature uploaded successfully.')) - return HttpResponseRedirect(next) - except Exception, msg: - messages.error(request, msg) - return HttpResponseRedirect(previous) - else: - form = DetachedSignatureForm() - - return render_to_response('generic_form.html', { - 'title': _(u'Upload detached signature for: %s') % document, - 'form_icon': 'key_delete.png', - 'next': next, - 'form': form, - 'previous': previous, - 'object': document, - }, context_instance=RequestContext(request)) - - -def document_signature_download(request, document_pk): - check_permissions(request.user, [PERMISSION_SIGNATURE_DOWNLOAD]) - document = get_object_or_404(Document, pk=document_pk) - - try: - if document.has_detached_signature(): - signature = document.detached_signature() - return serve_file( - request, - signature, - save_as=u'"%s.sig"' % document.filename, - content_type=u'application/octet-stream' - ) - except Exception, e: - messages.error(request, e) - return HttpResponseRedirect(request.META['HTTP_REFERER']) - - return HttpResponseRedirect(request.META['HTTP_REFERER']) diff --git a/apps/documents/models.py b/apps/documents/models.py index d05737632a..b5366934e2 100644 --- a/apps/documents/models.py +++ b/apps/documents/models.py @@ -288,7 +288,9 @@ class Document(models.Model): return version.save() filename = property(_get_filename, _set_filename) - + + #TODO: remove after migration + """ def add_detached_signature(self, *args, **kwargs): return self.latest_version.add_detached_signature(*args, **kwargs) @@ -300,12 +302,14 @@ class Document(models.Model): def verify_signature(self): return self.latest_version.verify_signature() - + """ class DocumentVersion(models.Model): ''' Model that describes a document version and its properties ''' + _pre_open_hooks = {} + @staticmethod def get_version_update_choices(document_version): return ( @@ -314,6 +318,10 @@ class DocumentVersion(models.Model): (VERSION_UPDATE_MICRO, _(u'Micro %(major)i.%(minor)i.%(micro)i, (fixes)') % document_version.get_new_version_dict(VERSION_UPDATE_MICRO)) ) + @classmethod + def register_pre_open_hook(cls, order, func): + cls._pre_open_hooks[order] = func + document = models.ForeignKey(Document, verbose_name=_(u'document'), editable=False) major = models.PositiveIntegerField(verbose_name=_(u'mayor'), default=1, editable=False) minor = models.PositiveIntegerField(verbose_name=_(u'minor'), default=0, editable=False) @@ -329,6 +337,8 @@ class DocumentVersion(models.Model): encoding = models.CharField(max_length=64, default='', editable=False) filename = models.CharField(max_length=255, default=u'', editable=False, db_index=True) checksum = models.TextField(blank=True, null=True, verbose_name=_(u'checksum'), editable=False) + + #TODO: to be removed after migration signature_state = models.CharField(blank=True, null=True, max_length=16, verbose_name=_(u'signature state'), 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) @@ -393,7 +403,9 @@ class DocumentVersion(models.Model): if new_document: #Only do this for new documents - self.update_signed_state(save=False) + #Only do this for new documents + # TODO: remove after migration + #self.update_signed_state(save=False) self.update_checksum(save=False) self.update_mimetype(save=False) self.save() @@ -467,6 +479,8 @@ class DocumentVersion(models.Model): for version in self.document.versions.filter(timestamp__gt=self.timestamp): version.delete() + #TODO: remove after migration + """ def update_signed_state(self, save=True): if self.exists(): try: @@ -478,7 +492,8 @@ class DocumentVersion(models.Model): if save: self.save() - + """ + def update_mimetype(self, save=True): ''' Read a document verions's file and determine the mimetype by calling the @@ -510,6 +525,16 @@ class DocumentVersion(models.Model): Return a file descriptor to a document version's file irrespective of the storage backend ''' + if raw: + return self.file.storage.open(self.file.path) + else: + result = self.file.storage.open(self.file.path) + for key in sorted(DocumentVersion._pre_open_hooks): + result = DocumentVersion._pre_open_hooks[key](result) + + return result + #TODO: remove after migration + """ if self.signature_state and not raw: try: result = gpg.decrypt_file(self.file.storage.open(self.file.path)) @@ -520,6 +545,7 @@ class DocumentVersion(models.Model): return self.file.storage.open(self.file.path) else: return self.file.storage.open(self.file.path) + """ def save_to_file(self, filepath, buffer_size=1024 * 1024): ''' @@ -545,7 +571,8 @@ class DocumentVersion(models.Model): return self.file.storage.size(self.file.path) else: return None - + #TODO: remove after migration + """ def add_detached_signature(self, detached_signature): if not self.signature_state: self.signature_file = detached_signature @@ -573,6 +600,7 @@ class DocumentVersion(models.Model): signature = None return signature + """ class DocumentTypeFilename(models.Model):