Add model test. Finish file signing method. Add key signing exceptions.
This commit is contained in:
@@ -7,21 +7,9 @@ from .models import Key
|
||||
|
||||
@admin.register(Key)
|
||||
class KeyAdmin(admin.ModelAdmin):
|
||||
#date_hierarchy = 'datetime'
|
||||
list_display = ('key_id', 'user_id', 'key_type')
|
||||
#readonly_fields = list_display
|
||||
|
||||
"""
|
||||
key_id = models.CharField(
|
||||
max_length=16, unique=True, verbose_name=_('Key ID')
|
||||
list_display = (
|
||||
'key_id', 'user_id', 'creation_date', 'expiration_date', 'key_type'
|
||||
)
|
||||
creation_date = models.DateField(verbose_name=_('Creation date'))
|
||||
expiration_date = models.DateField(verbose_name=_('Expiration date'))
|
||||
fingerprint = models.CharField(
|
||||
max_length=40, verbose_name=_('Fingerprint')
|
||||
)
|
||||
length = models.PositiveIntegerField(verbose_name=_('Length'))
|
||||
algorithm = models.PositiveIntegerField(verbose_name=_('Algorithm'))
|
||||
user_id = models.TextField(verbose_name=_('User ID'))
|
||||
key_type = models.CharField(max_length=3, verbose_name=_('Type'))
|
||||
"""
|
||||
list_filter = ('key_type',)
|
||||
readonly_fields = list_display + ('fingerprint', 'length', 'algorithm')
|
||||
search_fields = ('key_id', 'user_id',)
|
||||
|
||||
@@ -39,3 +39,15 @@ class KeyDoesNotExist(GPGException):
|
||||
|
||||
class KeyImportError(GPGException):
|
||||
pass
|
||||
|
||||
|
||||
class NeedPassphrase(GPGException):
|
||||
"""
|
||||
Passphrase is needed but none was provided
|
||||
"""
|
||||
|
||||
|
||||
class PassphraseError(GPGException):
|
||||
"""
|
||||
Passphrase provided is incorrect
|
||||
"""
|
||||
|
||||
@@ -7,6 +7,14 @@ KEY_TYPES = {
|
||||
'sec': _('Secret'),
|
||||
}
|
||||
|
||||
KEY_TYPE_PUBLIC = 'pub'
|
||||
KEY_TYPE_SECRET = 'sec'
|
||||
|
||||
KEY_TYPE_CHOICES = (
|
||||
(KEY_TYPE_PUBLIC, _('Public')),
|
||||
(KEY_TYPE_SECRET, _('Secret')),
|
||||
)
|
||||
|
||||
KEY_CLASS_RSA = 'RSA'
|
||||
KEY_CLASS_DSA = 'DSA'
|
||||
KEY_CLASS_ELG = 'ELG-E'
|
||||
|
||||
24
mayan/apps/django_gpg/migrations/0002_auto_20160322_1756.py
Normal file
24
mayan/apps/django_gpg/migrations/0002_auto_20160322_1756.py
Normal file
@@ -0,0 +1,24 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('django_gpg', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='key',
|
||||
name='data',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='key',
|
||||
name='key_data',
|
||||
field=models.TextField(default='', verbose_name='Key data'),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
||||
59
mayan/apps/django_gpg/migrations/0003_auto_20160322_1810.py
Normal file
59
mayan/apps/django_gpg/migrations/0003_auto_20160322_1810.py
Normal file
@@ -0,0 +1,59 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('django_gpg', '0002_auto_20160322_1756'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='key',
|
||||
name='algorithm',
|
||||
field=models.PositiveIntegerField(verbose_name='Algorithm', editable=False),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='key',
|
||||
name='creation_date',
|
||||
field=models.DateField(verbose_name='Creation date', editable=False),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='key',
|
||||
name='expiration_date',
|
||||
field=models.DateField(verbose_name='Expiration date', null=True, editable=False, blank=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='key',
|
||||
name='fingerprint',
|
||||
field=models.CharField(verbose_name='Fingerprint', unique=True, max_length=40, editable=False),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='key',
|
||||
name='key_data',
|
||||
field=models.TextField(verbose_name='Key data', editable=False),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='key',
|
||||
name='key_id',
|
||||
field=models.CharField(verbose_name='Key ID', unique=True, max_length=16, editable=False),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='key',
|
||||
name='key_type',
|
||||
field=models.CharField(verbose_name='Type', max_length=3, editable=False),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='key',
|
||||
name='length',
|
||||
field=models.PositiveIntegerField(verbose_name='Length', editable=False),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='key',
|
||||
name='user_id',
|
||||
field=models.TextField(verbose_name='User ID', editable=False),
|
||||
),
|
||||
]
|
||||
24
mayan/apps/django_gpg/migrations/0004_auto_20160322_2202.py
Normal file
24
mayan/apps/django_gpg/migrations/0004_auto_20160322_2202.py
Normal file
@@ -0,0 +1,24 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('django_gpg', '0003_auto_20160322_1810'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='key',
|
||||
name='key_data',
|
||||
field=models.TextField(verbose_name='Key data'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='key',
|
||||
name='key_type',
|
||||
field=models.CharField(verbose_name='Type', max_length=3, editable=False, choices=[('pub', 'Public'), ('sec', 'Secret')]),
|
||||
),
|
||||
]
|
||||
@@ -1,10 +1,5 @@
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
try:
|
||||
from cStringIO import StringIO
|
||||
except ImportError:
|
||||
from StringIO import StringIO
|
||||
|
||||
from datetime import date
|
||||
import logging
|
||||
import os
|
||||
@@ -13,20 +8,37 @@ import tempfile
|
||||
|
||||
import gnupg
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.core.files import File
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.db import models, transaction
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.db import models
|
||||
from django.utils.encoding import python_2_unicode_compatible
|
||||
from django.utils.timezone import now
|
||||
from django.utils.translation import ugettext, ugettext_lazy as _
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from .settings import setting_gpg_path, setting_keyservers
|
||||
from .literals import KEY_TYPE_CHOICES, KEY_TYPE_SECRET
|
||||
from .exceptions import NeedPassphrase, PassphraseError
|
||||
from .settings import setting_gpg_path, setting_keyserver
|
||||
|
||||
ERROR_MSG_NEED_PASSPHRASE = 'NEED_PASSPHRASE'
|
||||
ERROR_MSG_BAD_PASSPHRASE = 'BAD_PASSPHRASE'
|
||||
ERROR_MSG_GOOD_PASSPHRASE = 'GOOD_PASSPHRASE'
|
||||
OUTPUT_MESSAGE_CONTAINS_PRIVATE_KEY = 'Contains private key'
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def gpg_command(function):
|
||||
temporary_directory = tempfile.mkdtemp()
|
||||
os.chmod(temporary_directory, 0x1C0)
|
||||
|
||||
gpg = gnupg.GPG(
|
||||
gnupghome=temporary_directory, gpgbinary=setting_gpg_path.value
|
||||
)
|
||||
|
||||
result = function(gpg=gpg)
|
||||
|
||||
shutil.rmtree(temporary_directory)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
class KeyManager(models.Manager):
|
||||
def receive_key(self, key_id):
|
||||
temporary_directory = tempfile.mkdtemp()
|
||||
@@ -37,7 +49,7 @@ class KeyManager(models.Manager):
|
||||
gnupghome=temporary_directory, gpgbinary=setting_gpg_path.value
|
||||
)
|
||||
|
||||
import_results = gpg.recv_keys(setting_keyservers.value[0], key_id)
|
||||
import_results = gpg.recv_keys(setting_keyserver.value, key_id)
|
||||
|
||||
key_data = gpg.export_keys(import_results.fingerprints[0])
|
||||
|
||||
@@ -52,29 +64,48 @@ class KeyManager(models.Manager):
|
||||
gnupghome=temporary_directory, gpgbinary=setting_gpg_path.value
|
||||
)
|
||||
|
||||
result = gpg.search_keys(query=query, keyserver=setting_keyservers.value[0])
|
||||
result = gpg.search_keys(
|
||||
query=query, keyserver=setting_keyserver.value
|
||||
)
|
||||
shutil.rmtree(temporary_directory)
|
||||
|
||||
return result
|
||||
|
||||
def public_keys(self):
|
||||
return self.filter(key_type='pub')
|
||||
|
||||
def private_keys(self):
|
||||
return self.filter(key_type='')
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class Key(models.Model):
|
||||
data = models.TextField(verbose_name=_('Data'))
|
||||
key_data = models.TextField(verbose_name=_('Key data'))
|
||||
key_id = models.CharField(
|
||||
max_length=16, unique=True, verbose_name=_('Key ID')
|
||||
editable=False, max_length=16, unique=True, verbose_name=_('Key ID')
|
||||
)
|
||||
creation_date = models.DateField(
|
||||
editable=False, verbose_name=_('Creation date')
|
||||
)
|
||||
creation_date = models.DateField(verbose_name=_('Creation date'))
|
||||
expiration_date = models.DateField(
|
||||
blank=True, null=True, verbose_name=_('Expiration date')
|
||||
blank=True, editable=False, null=True,
|
||||
verbose_name=_('Expiration date')
|
||||
)
|
||||
fingerprint = models.CharField(
|
||||
max_length=40, unique=True, verbose_name=_('Fingerprint')
|
||||
editable=False, max_length=40, unique=True,
|
||||
verbose_name=_('Fingerprint')
|
||||
)
|
||||
length = models.PositiveIntegerField(
|
||||
editable=False, verbose_name=_('Length')
|
||||
)
|
||||
algorithm = models.PositiveIntegerField(
|
||||
editable=False, verbose_name=_('Algorithm')
|
||||
)
|
||||
user_id = models.TextField(editable=False, verbose_name=_('User ID'))
|
||||
key_type = models.CharField(
|
||||
choices=KEY_TYPE_CHOICES, editable=False, max_length=3,
|
||||
verbose_name=_('Type')
|
||||
)
|
||||
length = models.PositiveIntegerField(verbose_name=_('Length'))
|
||||
algorithm = models.PositiveIntegerField(verbose_name=_('Algorithm'))
|
||||
user_id = models.TextField(verbose_name=_('User ID'))
|
||||
key_type = models.CharField(max_length=3, verbose_name=_('Type'))
|
||||
|
||||
objects = KeyManager()
|
||||
|
||||
@@ -82,44 +113,49 @@ class Key(models.Model):
|
||||
verbose_name = _('Key')
|
||||
verbose_name_plural = _('Keys')
|
||||
|
||||
def clean(self):
|
||||
def import_key(gpg):
|
||||
return gpg.import_keys(key_data=self.key_data)
|
||||
|
||||
import_results = gpg_command(function=import_key)
|
||||
|
||||
if not import_results.count:
|
||||
raise ValidationError('Invalid key data')
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
temporary_directory = tempfile.mkdtemp()
|
||||
|
||||
logger.debug('temporary_directory: %s', temporary_directory)
|
||||
|
||||
gpg = gnupg.GPG(
|
||||
gnupghome=temporary_directory, gpgbinary=setting_gpg_path.value
|
||||
)
|
||||
|
||||
import_results = gpg.import_keys(key_data=self.data)
|
||||
import_results = gpg.import_keys(key_data=self.key_data)
|
||||
|
||||
logger.debug('import_results.results: %s', import_results.results)
|
||||
logger.debug('import_results.fingerprints: %s', import_results.fingerprints)
|
||||
key_info = gpg.list_keys(keys=import_results.fingerprints[0])[0]
|
||||
|
||||
key_data = gpg.list_keys(keys=import_results.fingerprints[0])[0]
|
||||
|
||||
logger.debug('key_data: %s', key_data)
|
||||
logger.debug('key_info: %s', key_info)
|
||||
|
||||
shutil.rmtree(temporary_directory)
|
||||
|
||||
self.key_id = key_data['keyid']
|
||||
self.algorithm = key_data['algo']
|
||||
self.creation_date = date.fromtimestamp(int(key_data['date']))
|
||||
if key_data['expires']:
|
||||
self.expiration_date = date.fromtimestamp(int(key_data['expires']))
|
||||
self.fingerprint = key_data['fingerprint']
|
||||
self.length = int(key_data['length'])
|
||||
self.user_id = key_data['uids'][0]
|
||||
self.key_type = key_data['type']
|
||||
self.key_id = key_info['keyid']
|
||||
self.algorithm = key_info['algo']
|
||||
self.creation_date = date.fromtimestamp(int(key_info['date']))
|
||||
if key_info['expires']:
|
||||
self.expiration_date = date.fromtimestamp(int(key_info['expires']))
|
||||
self.fingerprint = key_info['fingerprint']
|
||||
self.length = int(key_info['length'])
|
||||
self.user_id = key_info['uids'][0]
|
||||
if OUTPUT_MESSAGE_CONTAINS_PRIVATE_KEY in import_results.results[0]['text']:
|
||||
self.key_type = KEY_TYPE_SECRET
|
||||
else:
|
||||
self.key_type = key_info['type']
|
||||
|
||||
super(Key, self).save(*args, **kwargs)
|
||||
|
||||
def __str__(self):
|
||||
return self.key_id
|
||||
|
||||
def sign_file(self, file_object, passphrase=None, clearsign=True, detach=False, binary=False):
|
||||
output = StringIO()
|
||||
|
||||
def sign_file(self, file_object, passphrase=None, clearsign=True, detached=False, binary=False, output=None):
|
||||
temporary_directory = tempfile.mkdtemp()
|
||||
|
||||
gpg = gnupg.GPG(
|
||||
@@ -128,3 +164,20 @@ class Key(models.Model):
|
||||
|
||||
import_results = gpg.import_keys(key_data=self.data)
|
||||
|
||||
file_sign_results = gpg.sign_file(
|
||||
file=file_object, keyid=import_results.fingerprints[0],
|
||||
passphrase=passphrase, clearsign=clearsign, detach=detached,
|
||||
binary=binary, output=output
|
||||
)
|
||||
|
||||
shutil.rmtree(temporary_directory)
|
||||
|
||||
logger.debug('file_sign_results.stderr: %s', file_sign_results.stderr)
|
||||
|
||||
if ERROR_MSG_NEED_PASSPHRASE in file_sign_results.stderr:
|
||||
if ERROR_MSG_BAD_PASSPHRASE in file_sign_results.stderr:
|
||||
raise PassphraseError
|
||||
elif ERROR_MSG_GOOD_PASSPHRASE not in file_sign_results.stderr:
|
||||
raise NeedPassphrase
|
||||
|
||||
return file_sign_results
|
||||
|
||||
@@ -8,10 +8,6 @@ from django.utils.translation import ugettext_lazy as _
|
||||
from smart_settings import Namespace
|
||||
|
||||
namespace = Namespace(name='django_gpg', label=_('Signatures'))
|
||||
setting_keyservers = namespace.add_setting(
|
||||
global_name='SIGNATURES_KEYSERVERS', default=['pool.sks-keyservers.net'],
|
||||
help_text=_('List of keyservers to be queried for unknown keys.')
|
||||
)
|
||||
setting_gpg_home = namespace.add_setting(
|
||||
global_name='SIGNATURES_GPG_HOME',
|
||||
default=os.path.join(settings.MEDIA_ROOT, 'gpg_home'),
|
||||
@@ -24,3 +20,11 @@ setting_gpg_path = namespace.add_setting(
|
||||
global_name='SIGNATURES_GPG_PATH', default='/usr/bin/gpg',
|
||||
help_text=_('Path to the GPG binary.'), is_path=True
|
||||
)
|
||||
setting_keyserver = namespace.add_setting(
|
||||
global_name='SIGNATURES_KEYSERVER', default='pool.sks-keyservers.net',
|
||||
help_text=_('Keyserver used to query for keys.')
|
||||
)
|
||||
setting_keyservers = namespace.add_setting(
|
||||
global_name='SIGNATURES_KEYSERVERS', default=['pool.sks-keyservers.net'],
|
||||
help_text=_('List of keyservers to be queried for unknown keys.')
|
||||
)
|
||||
|
||||
@@ -4,3 +4,66 @@ TEST_GPG_HOME = '/tmp/test_gpg_home'
|
||||
TEST_KEY_ID = '607138F1AECC5A5CA31CB7715F3F7F75D210724D'
|
||||
TEST_KEYSERVERS = ['pool.sks-keyservers.net']
|
||||
TEST_UIDS = 'Roberto Rosario'
|
||||
|
||||
TEST_KEY_DATA = '''-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||
Version: GnuPG v1
|
||||
|
||||
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
|
||||
8aeg3z/W+YctdRt81bi5isgM+oML9LAQ
|
||||
=JZ5G
|
||||
-----END PGP PRIVATE KEY BLOCK-----'''
|
||||
|
||||
TEST_KEY_ID = '4125E9C571F378AC'
|
||||
TEST_KEY_FINGERPRINT = '6A24574E0A35004CDDFD22704125E9C571F378AC'
|
||||
|
||||
16
mayan/apps/django_gpg/tests/test_models.py
Normal file
16
mayan/apps/django_gpg/tests/test_models.py
Normal file
@@ -0,0 +1,16 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.test import TestCase
|
||||
|
||||
from ..models import Key
|
||||
|
||||
from .literals import TEST_KEY_DATA, TEST_KEY_FINGERPRINT, TEST_KEY_ID
|
||||
|
||||
|
||||
class KeyTestCase(TestCase):
|
||||
def test_key_instance_creation(self):
|
||||
# Creating a Key instance is analogous to importing a key
|
||||
key = Key.objects.create(key_data=TEST_KEY_DATA)
|
||||
|
||||
self.assertEqual(key.key_id, TEST_KEY_ID)
|
||||
self.assertEqual(key.fingerprint, TEST_KEY_FINGERPRINT)
|
||||
Reference in New Issue
Block a user