Cleanup document version argument handling by making sure it is by document version and not by document instance

This commit is contained in:
Roberto Rosario
2015-06-05 00:58:55 -04:00
parent 1e02b4dadf
commit 97f68ea158
4 changed files with 47 additions and 42 deletions

View File

@@ -30,8 +30,8 @@ logger = logging.getLogger(__name__)
def document_pre_open_hook(descriptor, instance): def document_pre_open_hook(descriptor, instance):
if DocumentVersionSignature.objects.has_embedded_signature(instance.document): if DocumentVersionSignature.objects.has_embedded_signature(document_version=instance):
# If it has an embedded signature decrypt # If it has an embedded signature, decrypt
try: try:
result = gpg.decrypt_file(descriptor, close_descriptor=False) result = gpg.decrypt_file(descriptor, close_descriptor=False)
# gpg return a string, turn it into a file like object # gpg return a string, turn it into a file like object
@@ -46,11 +46,14 @@ def document_pre_open_hook(descriptor, instance):
return descriptor return descriptor
def document_post_save_hook(instance): def document_version_post_save_hook(instance):
if not instance.pk: logger.debug('instance: %s', instance)
document_signature, created = DocumentVersionSignature.objects.get_or_create(
document_version=instance.latest_version, try:
) document_signature = DocumentVersionSignature.objects.get(document_version=instance)
except DocumentVersionSignature.DoesNotExist:
document_signature = DocumentVersionSignature.objects.create(document_version=instance)
document_signature.check_for_embedded_signature()
class DocumentSignaturesApp(apps.AppConfig): class DocumentSignaturesApp(apps.AppConfig):
@@ -58,7 +61,7 @@ class DocumentSignaturesApp(apps.AppConfig):
verbose_name = _('Document signatures') verbose_name = _('Document signatures')
def ready(self): def ready(self):
DocumentVersion.register_post_save_hook(1, document_post_save_hook) DocumentVersion.register_post_save_hook(1, document_version_post_save_hook)
DocumentVersion.register_pre_open_hook(1, document_pre_open_hook) DocumentVersion.register_pre_open_hook(1, document_pre_open_hook)
class_permissions(Document, [ class_permissions(Document, [

View File

@@ -11,18 +11,20 @@ logger = logging.getLogger(__name__)
class DocumentVersionSignatureManager(models.Manager): class DocumentVersionSignatureManager(models.Manager):
def get_document_signature(self, document): def get_document_signature(self, document_version):
document_signature, created = self.model.objects.get_or_create( document_signature, created = self.model.objects.get_or_create(
document_version=document.latest_version, document_version=document_version,
) )
return document_signature return document_signature
def add_detached_signature(self, document, detached_signature): def add_detached_signature(self, document_version, detached_signature):
document_signature = self.get_document_signature(document) document_signature = self.get_document_signature(
document_version=document_version
)
if document_signature.has_embedded_signature: if document_signature.has_embedded_signature:
raise Exception('document already has an embedded signature') raise Exception('Document version already has an embedded signature')
else: else:
if document_signature.signature_file: if document_signature.signature_file:
logger.debug('Existing detached signature') logger.debug('Existing detached signature')
@@ -33,9 +35,9 @@ class DocumentVersionSignatureManager(models.Manager):
document_signature.signature_file = detached_signature document_signature.signature_file = detached_signature
document_signature.save() document_signature.save()
def has_detached_signature(self, document): def has_detached_signature(self, document_version):
try: try:
document_signature = self.get_document_signature(document) document_signature = self.get_document_signature(document_version=document_version)
except ValueError: except ValueError:
return False return False
else: else:
@@ -44,42 +46,42 @@ class DocumentVersionSignatureManager(models.Manager):
else: else:
return False return False
def has_embedded_signature(self, document): def has_embedded_signature(self, document_version):
logger.debug('document: %s', document) logger.debug('document_version: %s', document_version)
try: try:
document_signature = self.get_document_signature(document) document_signature = self.get_document_signature(document_version=document_version)
except ValueError: except ValueError:
return False return False
else: else:
return document_signature.has_embedded_signature return document_signature.has_embedded_signature
def detached_signature(self, document): def detached_signature(self, document_version):
document_signature = self.get_document_signature(document) document_signature = self.get_document_signature(document_version=document_version)
return document_signature.signature_file.storage.open(document_signature.signature_file.path) return document_signature.signature_file.storage.open(document_signature.signature_file.path)
def verify_signature(self, document): def verify_signature(self, document_version):
document_descriptor = document.open(raw=True) document_version_descriptor = document_version.open(raw=True)
detached_signature = None detached_signature = None
if self.has_detached_signature(document): if self.has_detached_signature(document_version=document_version):
logger.debug('has detached signature') logger.debug('has detached signature')
detached_signature = self.detached_signature(document) detached_signature = self.detached_signature(document_version=document_version)
args = (document_descriptor, detached_signature) args = (document_version_descriptor, detached_signature)
else: else:
args = (document_descriptor,) args = (document_version_descriptor,)
try: try:
return gpg.verify_file(*args, fetch_key=False) return gpg.verify_file(*args, fetch_key=False)
except GPGVerificationError: except GPGVerificationError:
return None return None
finally: finally:
document_descriptor.close() document_version_descriptor.close()
if detached_signature: if detached_signature:
detached_signature.close() detached_signature.close()
def clear_detached_signature(self, document): def clear_detached_signature(self, document_version):
document_signature = self.get_document_signature(document) document_signature = self.get_document_signature(document_version=document_version)
if not document_signature.signature_file: if not document_signature.signature_file:
raise Exception('document doesn\'t have a detached signature') raise Exception('document doesn\'t have a detached signature')

View File

@@ -36,7 +36,7 @@ class DocumentTestCase(TestCase):
gpg.import_key(file_object.read()) gpg.import_key(file_object.read())
def test_document_no_signature(self): def test_document_no_signature(self):
self.failUnlessEqual(DocumentVersionSignature.objects.has_detached_signature(self.document), False) self.failUnlessEqual(DocumentVersionSignature.objects.has_detached_signature(self.document.latest_version), False)
def test_new_document_version_signed(self): def test_new_document_version_signed(self):
with open(TEST_SIGNED_DOCUMENT_PATH) as file_object: with open(TEST_SIGNED_DOCUMENT_PATH) as file_object:
@@ -46,8 +46,8 @@ class DocumentTestCase(TestCase):
self.document.new_version(file_object=File(file_object, name='mayan_11_1.pdf.gpg'), **new_version_data) self.document.new_version(file_object=File(file_object, name='mayan_11_1.pdf.gpg'), **new_version_data)
self.failUnlessEqual(DocumentVersionSignature.objects.has_detached_signature(self.document), False) self.failUnlessEqual(DocumentVersionSignature.objects.has_detached_signature(self.document.latest_version), False)
self.failUnlessEqual(DocumentVersionSignature.objects.verify_signature(self.document).status, SIGNATURE_STATE_VALID) self.failUnlessEqual(DocumentVersionSignature.objects.verify_signature(self.document.latest_version).status, SIGNATURE_STATE_VALID)
def test_detached_signatures(self): def test_detached_signatures(self):
new_version_data = { new_version_data = {
@@ -57,13 +57,13 @@ class DocumentTestCase(TestCase):
self.document.new_version(file_object=File(file_object), **new_version_data) self.document.new_version(file_object=File(file_object), **new_version_data)
# GPGVerificationError # GPGVerificationError
self.failUnlessEqual(DocumentVersionSignature.objects.verify_signature(self.document), None) self.failUnlessEqual(DocumentVersionSignature.objects.verify_signature(self.document.latest_version), None)
with open(TEST_SIGNATURE_FILE_PATH, 'rb') as file_object: with open(TEST_SIGNATURE_FILE_PATH, 'rb') as file_object:
DocumentVersionSignature.objects.add_detached_signature(self.document, File(file_object)) DocumentVersionSignature.objects.add_detached_signature(self.document.latest_version, File(file_object))
self.failUnlessEqual(DocumentVersionSignature.objects.has_detached_signature(self.document), True) self.failUnlessEqual(DocumentVersionSignature.objects.has_detached_signature(self.document.latest_version), True)
self.failUnlessEqual(DocumentVersionSignature.objects.verify_signature(self.document).status, SIGNATURE_STATE_VALID) self.failUnlessEqual(DocumentVersionSignature.objects.verify_signature(self.document.latest_version).status, SIGNATURE_STATE_VALID)
def tearDown(self): def tearDown(self):
self.document.delete() self.document.delete()

View File

@@ -40,7 +40,7 @@ def document_verify(request, document_pk):
document.add_as_recent_document_for_user(request.user) document.add_as_recent_document_for_user(request.user)
try: try:
signature = DocumentVersionSignature.objects.verify_signature(document) signature = DocumentVersionSignature.objects.verify_signature(document.latest_version)
except AttributeError: except AttributeError:
signature_state = SIGNATURE_STATES.get(SIGNATURE_STATE_NONE) signature_state = SIGNATURE_STATES.get(SIGNATURE_STATE_NONE)
signature = None signature = None
@@ -50,7 +50,7 @@ def document_verify(request, document_pk):
paragraphs = [_('Signature status: %s') % signature_state['text']] paragraphs = [_('Signature status: %s') % signature_state['text']]
try: try:
if DocumentVersionSignature.objects.has_embedded_signature(document): if DocumentVersionSignature.objects.has_embedded_signature(document.latest_version):
signature_type = _('Embedded') signature_type = _('Embedded')
else: else:
signature_type = _('Detached') signature_type = _('Detached')
@@ -94,7 +94,7 @@ def document_signature_upload(request, document_pk):
form = DetachedSignatureForm(request.POST, request.FILES) form = DetachedSignatureForm(request.POST, request.FILES)
if form.is_valid(): if form.is_valid():
try: try:
DocumentVersionSignature.objects.add_detached_signature(document, request.FILES['file']) DocumentVersionSignature.objects.add_detached_signature(document.latest_version, request.FILES['file'])
messages.success(request, _('Detached signature uploaded successfully.')) messages.success(request, _('Detached signature uploaded successfully.'))
return HttpResponseRedirect(next) return HttpResponseRedirect(next)
except Exception as exception: except Exception as exception:
@@ -121,8 +121,8 @@ def document_signature_download(request, document_pk):
AccessEntry.objects.check_access(PERMISSION_SIGNATURE_DOWNLOAD, request.user, document) AccessEntry.objects.check_access(PERMISSION_SIGNATURE_DOWNLOAD, request.user, document)
try: try:
if DocumentVersionSignature.objects.has_detached_signature(document): if DocumentVersionSignature.objects.has_detached_signature(document.latest_version):
signature = DocumentVersionSignature.objects.detached_signature(document) signature = DocumentVersionSignature.objects.detached_signature(document.latest_version)
return serve_file( return serve_file(
request, request,
signature, signature,
@@ -152,7 +152,7 @@ def document_signature_delete(request, document_pk):
if request.method == 'POST': if request.method == 'POST':
try: try:
DocumentVersionSignature.objects.clear_detached_signature(document) DocumentVersionSignature.objects.clear_detached_signature(document.latest_version)
messages.success(request, _('Detached signature deleted successfully.')) messages.success(request, _('Detached signature deleted successfully.'))
return HttpResponseRedirect(next) return HttpResponseRedirect(next)
except Exception as exception: except Exception as exception: