From 048ba4b5cdb55873a2a0296eeb805e3e6e37aea0 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Wed, 23 Mar 2016 19:47:41 -0400 Subject: [PATCH] Add file decryption support. --- mayan/apps/django_gpg/exceptions.py | 4 ++-- mayan/apps/django_gpg/managers.py | 22 +++++++++++++++++++- mayan/apps/django_gpg/tests/literals.py | 1 + mayan/apps/django_gpg/tests/test_models.py | 24 ++++++++++++++++++++-- 4 files changed, 46 insertions(+), 5 deletions(-) diff --git a/mayan/apps/django_gpg/exceptions.py b/mayan/apps/django_gpg/exceptions.py index 14dbe5ffa8..0afb08945a 100644 --- a/mayan/apps/django_gpg/exceptions.py +++ b/mayan/apps/django_gpg/exceptions.py @@ -9,7 +9,7 @@ class GPGException(Exception): pass -class GPGVerificationError(GPGException): +class VerificationError(GPGException): pass @@ -17,7 +17,7 @@ class GPGSigningError(GPGException): pass -class GPGDecryptionError(GPGException): +class DecryptionError(GPGException): pass diff --git a/mayan/apps/django_gpg/managers.py b/mayan/apps/django_gpg/managers.py index f99e703d01..e1435ca0dc 100644 --- a/mayan/apps/django_gpg/managers.py +++ b/mayan/apps/django_gpg/managers.py @@ -10,7 +10,7 @@ import gnupg from django.db import models from .classes import KeyStub, SignatureVerification -from .exceptions import KeyDoesNotExist, KeyFetchingError +from .exceptions import DecryptionError, KeyDoesNotExist, KeyFetchingError from .literals import KEY_TYPE_PUBLIC, KEY_TYPE_SECRET from .settings import setting_gpg_path, setting_keyserver @@ -18,6 +18,26 @@ logger = logging.getLogger(__name__) class KeyManager(models.Manager): + def decrypt_file(self, file_object): + temporary_directory = tempfile.mkdtemp() + + os.chmod(temporary_directory, 0x1C0) + + gpg = gnupg.GPG( + gnupghome=temporary_directory, gpgbinary=setting_gpg_path.value + ) + + decrypt_result = gpg.decrypt_file(file=file_object) + + shutil.rmtree(temporary_directory) + + logger.debug('decrypt_result.__dict__: %s', decrypt_result.__dict__) + + if not decrypt_result.status or decrypt_result.status == 'no data was provided': + raise DecryptionError('Unable to decrypt file') + + return str(decrypt_result) + def receive_key(self, key_id): temporary_directory = tempfile.mkdtemp() diff --git a/mayan/apps/django_gpg/tests/literals.py b/mayan/apps/django_gpg/tests/literals.py index d37e28ba1f..908181254a 100644 --- a/mayan/apps/django_gpg/tests/literals.py +++ b/mayan/apps/django_gpg/tests/literals.py @@ -77,3 +77,4 @@ TEST_SIGNED_FILE = os.path.join( settings.BASE_DIR, 'mayan', 'apps', 'django_gpg', 'tests', 'contrib', 'test_files', 'test_file.txt.gpg' ) +TEST_SIGNED_FILE_CONTENT = 'test_file.txt\n' diff --git a/mayan/apps/django_gpg/tests/test_models.py b/mayan/apps/django_gpg/tests/test_models.py index 484e8b64d9..fc098846bf 100644 --- a/mayan/apps/django_gpg/tests/test_models.py +++ b/mayan/apps/django_gpg/tests/test_models.py @@ -1,13 +1,15 @@ from __future__ import unicode_literals +import tempfile + from django.test import TestCase -from ..exceptions import KeyDoesNotExist +from ..exceptions import DecryptionError, KeyDoesNotExist from ..models import Key from .literals import ( TEST_KEY_DATA, TEST_KEY_FINGERPRINT, TEST_SEARCH_FINGERPRINT, - TEST_SEARCH_UID, TEST_SIGNED_FILE + TEST_SEARCH_UID, TEST_SIGNED_FILE, TEST_SIGNED_FILE_CONTENT ) @@ -62,3 +64,21 @@ class KeyTestCase(TestCase): with open(TEST_SIGNED_FILE) as signed_file: with self.assertRaises(KeyDoesNotExist): Key.objects.verify_file(signed_file, key_fingerprint='999') + + def test_signed_file_decryption(self): + Key.objects.create(key_data=TEST_KEY_DATA) + + with open(TEST_SIGNED_FILE) as signed_file: + result = Key.objects.decrypt_file(file_object=signed_file) + + self.assertEqual(result, TEST_SIGNED_FILE_CONTENT) + + def test_cleartext_file_decryption(self): + cleartext_file = tempfile.TemporaryFile() + cleartext_file.write('test') + cleartext_file.seek(0) + + with self.assertRaises(DecryptionError): + Key.objects.decrypt_file(file_object=cleartext_file) + + cleartext_file.close()