Update Django GPG app
Add keyword arguments to all calls. Rename URL parameters to be
explicit ("key_id"). Add key delete view test. Update tests
to use a mixin for repeated key creation code. Grant permissions
and access the proper way using self.grant_permission and
self.grant_access.
Signed-off-by: Roberto Rosario <Roberto.Rosario@mayan-edms.com>
This commit is contained in:
@@ -31,6 +31,8 @@ class APIKeyView(generics.RetrieveDestroyAPIView):
|
||||
get: Return the details of the selected key.
|
||||
"""
|
||||
filter_backends = (MayanObjectPermissionsFilter,)
|
||||
lookup_field = 'pk'
|
||||
lookup_url_kwarg = 'key_id'
|
||||
mayan_object_permissions = {
|
||||
'DELETE': (permission_key_delete,),
|
||||
'GET': (permission_key_view,),
|
||||
|
||||
@@ -17,6 +17,24 @@ class GPGBackend(object):
|
||||
self.kwargs = kwargs
|
||||
|
||||
|
||||
class KeyStub(object):
|
||||
def __init__(self, raw):
|
||||
self.fingerprint = raw['keyid']
|
||||
self.key_type = raw['type']
|
||||
self.date = date.fromtimestamp(int(raw['date']))
|
||||
if raw['expires']:
|
||||
self.expires = date.fromtimestamp(int(raw['expires']))
|
||||
else:
|
||||
self.expires = None
|
||||
self.length = raw['length']
|
||||
self.user_id = raw['uids']
|
||||
|
||||
@property
|
||||
def key_id(self):
|
||||
return self.fingerprint[-8:]
|
||||
key_id.fget.short_description = _('Key ID')
|
||||
|
||||
|
||||
class PythonGNUPGBackend(GPGBackend):
|
||||
@staticmethod
|
||||
def _import_key(gpg, **kwargs):
|
||||
@@ -136,24 +154,6 @@ class PythonGNUPGBackend(GPGBackend):
|
||||
)
|
||||
|
||||
|
||||
class KeyStub(object):
|
||||
def __init__(self, raw):
|
||||
self.fingerprint = raw['keyid']
|
||||
self.key_type = raw['type']
|
||||
self.date = date.fromtimestamp(int(raw['date']))
|
||||
if raw['expires']:
|
||||
self.expires = date.fromtimestamp(int(raw['expires']))
|
||||
else:
|
||||
self.expires = None
|
||||
self.length = raw['length']
|
||||
self.user_id = raw['uids']
|
||||
|
||||
@property
|
||||
def key_id(self):
|
||||
return self.fingerprint[-8:]
|
||||
key_id.fget.short_description = _('Key ID')
|
||||
|
||||
|
||||
class SignatureVerification(object):
|
||||
def __init__(self, raw):
|
||||
self.user_id = raw['username']
|
||||
|
||||
@@ -44,6 +44,6 @@ class KeyDetailForm(DetailForm):
|
||||
|
||||
class KeySearchForm(forms.Form):
|
||||
term = forms.CharField(
|
||||
label=_('Term'),
|
||||
help_text=_('Name, e-mail, key ID or key fingerprint to look for.')
|
||||
help_text=_('Name, e-mail, key ID or key fingerprint to look for.'),
|
||||
label=_('Term')
|
||||
)
|
||||
|
||||
@@ -11,16 +11,18 @@ from .permissions import (
|
||||
)
|
||||
|
||||
link_key_delete = Link(
|
||||
args=('resolved_object.pk',), permissions=(permission_key_delete,),
|
||||
tags='dangerous', text=_('Delete'), view='django_gpg:key_delete',
|
||||
kwargs={'key_id': 'resolved_object.pk'},
|
||||
permissions=(permission_key_delete,), tags='dangerous', text=_('Delete'),
|
||||
view='django_gpg:key_delete'
|
||||
)
|
||||
link_key_detail = Link(
|
||||
args=('resolved_object.pk',), permissions=(permission_key_view,),
|
||||
text=_('Details'), view='django_gpg:key_detail',
|
||||
kwargs={'key_id': 'resolved_object.pk'}, permissions=(permission_key_view,),
|
||||
text=_('Details'), view='django_gpg:key_detail'
|
||||
)
|
||||
link_key_download = Link(
|
||||
args=('resolved_object.pk',), permissions=(permission_key_download,),
|
||||
text=_('Download'), view='django_gpg:key_download',
|
||||
kwargs={'key_id': 'resolved_object.pk'},
|
||||
permissions=(permission_key_download,), text=_('Download'),
|
||||
view='django_gpg:key_download'
|
||||
)
|
||||
link_key_query = Link(
|
||||
icon_class=icon_keyserver_search,
|
||||
@@ -28,7 +30,7 @@ link_key_query = Link(
|
||||
view='django_gpg:key_query'
|
||||
)
|
||||
link_key_receive = Link(
|
||||
args='object.key_id', keep_query=True,
|
||||
keep_query=True, kwargs={'key_id': 'object.key_id'},
|
||||
permissions=(permission_key_receive,), text=_('Import'),
|
||||
view='django_gpg:key_receive',
|
||||
)
|
||||
|
||||
@@ -9,6 +9,7 @@ if platform.system() == 'OpenBSD':
|
||||
else:
|
||||
DEFAULT_GPG_PATH = '/usr/bin/gpg1'
|
||||
|
||||
DEFAULT_KEYSERVER = 'pool.sks-keyservers.net'
|
||||
DEFAULT_SETTING_GPG_BACKEND = 'mayan.apps.django_gpg.classes.PythonGNUPGBackend'
|
||||
|
||||
ERROR_MSG_BAD_PASSPHRASE = 'BAD_PASSPHRASE'
|
||||
|
||||
@@ -77,7 +77,9 @@ class Key(models.Model):
|
||||
raise ValidationError(_('Key already exists.'))
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse('django_gpg:key_detail', args=(self.pk,))
|
||||
return reverse(
|
||||
viewname='django_gpg:key_detail', kwargs={'key_pk': self.pk}
|
||||
)
|
||||
|
||||
@property
|
||||
def key_id(self):
|
||||
|
||||
@@ -7,23 +7,23 @@ from mayan.apps.permissions import PermissionNamespace
|
||||
namespace = PermissionNamespace(label=_('Key management'), name='django_gpg')
|
||||
|
||||
permission_key_delete = namespace.add_permission(
|
||||
name='key_delete', label=_('Delete keys')
|
||||
label=_('Delete keys'), name='key_delete'
|
||||
)
|
||||
permission_key_download = namespace.add_permission(
|
||||
name='key_download', label=_('Download keys')
|
||||
label=_('Download keys'), name='key_download'
|
||||
)
|
||||
permission_key_receive = namespace.add_permission(
|
||||
name='key_receive', label=_('Import keys from keyservers')
|
||||
label=_('Import keys from keyservers'), name='key_receive'
|
||||
)
|
||||
permission_key_sign = namespace.add_permission(
|
||||
name='key_sign', label=_('Use keys to sign content')
|
||||
label=_('Use keys to sign content'), name='key_sign'
|
||||
)
|
||||
permission_key_upload = namespace.add_permission(
|
||||
name='key_upload', label=_('Upload keys')
|
||||
label=_('Upload keys'), name='key_upload'
|
||||
)
|
||||
permission_key_view = namespace.add_permission(
|
||||
name='key_view', label=_('View keys')
|
||||
label=_('View keys'), name='key_view'
|
||||
)
|
||||
permission_keyserver_query = namespace.add_permission(
|
||||
name='keyserver_query', label=_('Query keyservers')
|
||||
label=_('Query keyservers'), name='keyserver_query'
|
||||
)
|
||||
|
||||
@@ -8,6 +8,7 @@ from .models import Key
|
||||
class KeySerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
extra_kwargs = {
|
||||
'lookup_url_kwarg': 'key_id',
|
||||
'url': {'view_name': 'rest_api:key-detail'},
|
||||
}
|
||||
fields = (
|
||||
|
||||
@@ -4,7 +4,9 @@ from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from mayan.apps.smart_settings import Namespace
|
||||
|
||||
from .literals import DEFAULT_GPG_PATH, DEFAULT_SETTING_GPG_BACKEND
|
||||
from .literals import (
|
||||
DEFAULT_GPG_PATH, DEFAULT_KEYSERVER, DEFAULT_SETTING_GPG_BACKEND
|
||||
)
|
||||
|
||||
namespace = Namespace(name='django_gpg', label=_('Signatures'))
|
||||
|
||||
@@ -23,6 +25,6 @@ setting_gpg_backend_arguments = namespace.add_setting(
|
||||
)
|
||||
)
|
||||
setting_keyserver = namespace.add_setting(
|
||||
global_name='SIGNATURES_KEYSERVER', default='pool.sks-keyservers.net',
|
||||
global_name='SIGNATURES_KEYSERVER', default=DEFAULT_KEYSERVER,
|
||||
help_text=_('Keyserver used to query for keys.')
|
||||
)
|
||||
|
||||
@@ -4,6 +4,18 @@ import os
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
MOCK_SEARCH_KEYS_RESPONSE = [
|
||||
{
|
||||
'algo': u'1',
|
||||
'date': u'1311475606',
|
||||
'expires': u'1643601600',
|
||||
'keyid': u'607138F1AECC5A5CA31CB7715F3F7F75D210724D',
|
||||
'length': u'2048',
|
||||
'type': u'pub',
|
||||
'uids': [u'Roberto Rosario <roberto.rosario.gonzalez@gmail.com>']
|
||||
}
|
||||
]
|
||||
|
||||
TEST_DETACHED_SIGNATURE = os.path.join(
|
||||
settings.BASE_DIR, 'apps', 'django_gpg', 'tests', 'contrib',
|
||||
'test_files', 'test_file.txt.asc'
|
||||
|
||||
9
mayan/apps/django_gpg/tests/mixins.py
Normal file
9
mayan/apps/django_gpg/tests/mixins.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from ..models import Key
|
||||
|
||||
from .literals import TEST_KEY_DATA
|
||||
|
||||
|
||||
class KeyTestMixin(object):
|
||||
def _create_test_key(self):
|
||||
# Creating a Key instance is analogous to importing a key
|
||||
self.test_key = Key.objects.create(key_data=TEST_KEY_DATA)
|
||||
@@ -32,7 +32,7 @@ class KeyAPITestCase(BaseAPITestCase):
|
||||
def test_key_create_view_no_permission(self):
|
||||
response = self._request_key_create_view()
|
||||
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
||||
self.assertEqual(Key.objects.all().count(), 0)
|
||||
self.assertEqual(Key.objects.count(), 0)
|
||||
|
||||
def test_key_create_view_with_permission(self):
|
||||
self.grant_permission(permission=permission_key_upload)
|
||||
@@ -50,7 +50,7 @@ class KeyAPITestCase(BaseAPITestCase):
|
||||
|
||||
def _request_key_delete_view(self):
|
||||
return self.delete(
|
||||
viewname='rest_api:key-detail', args=(self.key.pk,)
|
||||
viewname='rest_api:key-detail', kwargs={'key_id': self.key.pk}
|
||||
)
|
||||
|
||||
def test_key_delete_view_no_access(self):
|
||||
@@ -72,7 +72,7 @@ class KeyAPITestCase(BaseAPITestCase):
|
||||
|
||||
def _request_key_detail_view(self):
|
||||
return self.get(
|
||||
viewname='rest_api:key-detail', args=(self.key.pk,)
|
||||
viewname='rest_api:key-detail', kwargs={'key_id': self.key.pk}
|
||||
)
|
||||
|
||||
def test_key_detail_view_no_access(self):
|
||||
|
||||
@@ -17,22 +17,12 @@ from ..exceptions import (
|
||||
from ..models import Key
|
||||
|
||||
from .literals import (
|
||||
TEST_DETACHED_SIGNATURE, TEST_FILE, TEST_KEY_DATA, TEST_KEY_FINGERPRINT,
|
||||
TEST_KEY_PASSPHRASE, TEST_RECEIVE_KEY, TEST_SEARCH_FINGERPRINT,
|
||||
TEST_SEARCH_UID, TEST_SIGNED_FILE, TEST_SIGNED_FILE_CONTENT
|
||||
MOCK_SEARCH_KEYS_RESPONSE, TEST_DETACHED_SIGNATURE, TEST_FILE,
|
||||
TEST_KEY_FINGERPRINT, TEST_KEY_PASSPHRASE, TEST_RECEIVE_KEY,
|
||||
TEST_SEARCH_FINGERPRINT, TEST_SEARCH_UID, TEST_SIGNED_FILE,
|
||||
TEST_SIGNED_FILE_CONTENT
|
||||
)
|
||||
|
||||
MOCK_SEARCH_KEYS_RESPONSE = [
|
||||
{
|
||||
'algo': u'1',
|
||||
'date': u'1311475606',
|
||||
'expires': u'1643601600',
|
||||
'keyid': u'607138F1AECC5A5CA31CB7715F3F7F75D210724D',
|
||||
'length': u'2048',
|
||||
'type': u'pub',
|
||||
'uids': [u'Roberto Rosario <roberto.rosario.gonzalez@gmail.com>']
|
||||
}
|
||||
]
|
||||
from .mixins import KeyTestMixin
|
||||
|
||||
|
||||
def mock_recv_keys(self, keyserver, *keyids):
|
||||
@@ -45,12 +35,11 @@ def mock_recv_keys(self, keyserver, *keyids):
|
||||
return ImportResult()
|
||||
|
||||
|
||||
class KeyTestCase(BaseTestCase):
|
||||
class KeyTestCase(KeyTestMixin, BaseTestCase):
|
||||
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._create_test_key()
|
||||
|
||||
self.assertEqual(key.fingerprint, TEST_KEY_FINGERPRINT)
|
||||
self.assertEqual(self.test_key.fingerprint, TEST_KEY_FINGERPRINT)
|
||||
|
||||
@mock.patch.object(gnupg.GPG, 'search_keys', autospec=True)
|
||||
def test_key_search(self, search_keys):
|
||||
@@ -92,7 +81,7 @@ class KeyTestCase(BaseTestCase):
|
||||
self.assertTrue(result.key_id in TEST_KEY_FINGERPRINT)
|
||||
|
||||
def test_embedded_verification_with_key(self):
|
||||
Key.objects.create(key_data=TEST_KEY_DATA)
|
||||
self._create_test_key()
|
||||
|
||||
with open(TEST_SIGNED_FILE, mode='rb') as signed_file:
|
||||
result = Key.objects.verify_file(signed_file)
|
||||
@@ -100,7 +89,7 @@ class KeyTestCase(BaseTestCase):
|
||||
self.assertEqual(result.fingerprint, TEST_KEY_FINGERPRINT)
|
||||
|
||||
def test_embedded_verification_with_correct_fingerprint(self):
|
||||
Key.objects.create(key_data=TEST_KEY_DATA)
|
||||
self._create_test_key()
|
||||
|
||||
with open(TEST_SIGNED_FILE, mode='rb') as signed_file:
|
||||
result = Key.objects.verify_file(
|
||||
@@ -111,14 +100,14 @@ class KeyTestCase(BaseTestCase):
|
||||
self.assertEqual(result.fingerprint, TEST_KEY_FINGERPRINT)
|
||||
|
||||
def test_embedded_verification_with_incorrect_fingerprint(self):
|
||||
Key.objects.create(key_data=TEST_KEY_DATA)
|
||||
self._create_test_key()
|
||||
|
||||
with open(TEST_SIGNED_FILE, mode='rb') 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)
|
||||
self._create_test_key()
|
||||
|
||||
with open(TEST_SIGNED_FILE, mode='rb') as signed_file:
|
||||
result = Key.objects.decrypt_file(file_object=signed_file)
|
||||
@@ -145,7 +134,7 @@ class KeyTestCase(BaseTestCase):
|
||||
self.assertTrue(result.key_id in TEST_KEY_FINGERPRINT)
|
||||
|
||||
def test_detached_verification_with_key(self):
|
||||
Key.objects.create(key_data=TEST_KEY_DATA)
|
||||
self._create_test_key()
|
||||
|
||||
with open(TEST_DETACHED_SIGNATURE, mode='rb') as signature_file:
|
||||
with open(TEST_FILE, mode='rb') as test_file:
|
||||
@@ -157,29 +146,29 @@ class KeyTestCase(BaseTestCase):
|
||||
self.assertEqual(result.fingerprint, TEST_KEY_FINGERPRINT)
|
||||
|
||||
def test_detached_signing_no_passphrase(self):
|
||||
key = Key.objects.create(key_data=TEST_KEY_DATA)
|
||||
self._create_test_key()
|
||||
|
||||
with self.assertRaises(NeedPassphrase):
|
||||
with open(TEST_FILE, mode='rb') as test_file:
|
||||
key.sign_file(
|
||||
self.test_key.sign_file(
|
||||
file_object=test_file, detached=True,
|
||||
)
|
||||
|
||||
def test_detached_signing_bad_passphrase(self):
|
||||
key = Key.objects.create(key_data=TEST_KEY_DATA)
|
||||
self._create_test_key()
|
||||
|
||||
with self.assertRaises(PassphraseError):
|
||||
with open(TEST_FILE, mode='rb') as test_file:
|
||||
key.sign_file(
|
||||
self.test_key.sign_file(
|
||||
file_object=test_file, detached=True,
|
||||
passphrase='bad passphrase'
|
||||
)
|
||||
|
||||
def test_detached_signing_with_passphrase(self):
|
||||
key = Key.objects.create(key_data=TEST_KEY_DATA)
|
||||
self._create_test_key()
|
||||
|
||||
with open(TEST_FILE, mode='rb') as test_file:
|
||||
detached_signature = key.sign_file(
|
||||
detached_signature = self.test_key.sign_file(
|
||||
file_object=test_file, detached=True,
|
||||
passphrase=TEST_KEY_PASSPHRASE
|
||||
)
|
||||
|
||||
@@ -5,62 +5,79 @@ from django_downloadview.test import assert_download_response
|
||||
from mayan.apps.common.tests import GenericViewTestCase
|
||||
|
||||
from ..models import Key
|
||||
from ..permissions import permission_key_download, permission_key_upload
|
||||
|
||||
from .literals import TEST_KEY_DATA, TEST_KEY_FINGERPRINT
|
||||
|
||||
|
||||
class KeyViewTestCase(GenericViewTestCase):
|
||||
def test_key_download_view_no_permission(self):
|
||||
key = Key.objects.create(key_data=TEST_KEY_DATA)
|
||||
|
||||
self.login_user()
|
||||
|
||||
response = self.get(
|
||||
viewname='django_gpg:key_download', args=(key.pk,)
|
||||
from ..permissions import (
|
||||
permission_key_delete, permission_key_download, permission_key_upload
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 403)
|
||||
from .literals import TEST_KEY_DATA, TEST_KEY_FINGERPRINT
|
||||
from .mixins import KeyTestMixin
|
||||
|
||||
|
||||
class KeyViewTestCase(KeyTestMixin, GenericViewTestCase):
|
||||
def _request_key_delete_view(self):
|
||||
return self.post(
|
||||
viewname='django_gpg:key_delete',
|
||||
kwargs={'key_id': self.test_key.pk}
|
||||
)
|
||||
|
||||
def test_key_delete_view_no_permission(self):
|
||||
self._create_test_key()
|
||||
|
||||
response = self._request_key_delete_view()
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
def test_key_delete_view_with_access(self):
|
||||
self._create_test_key()
|
||||
|
||||
self.grant_access(obj=self.test_key, permission=permission_key_delete)
|
||||
|
||||
response = self._request_key_delete_view()
|
||||
self.assertEqual(response.status_code, 302)
|
||||
|
||||
self.assertEqual(Key.objects.count(), 0)
|
||||
|
||||
def _request_key_download_view(self):
|
||||
return self.get(
|
||||
viewname='django_gpg:key_download',
|
||||
kwargs={'key_id': self.test_key.pk}
|
||||
)
|
||||
|
||||
def test_key_download_view_no_permission(self):
|
||||
self._create_test_key()
|
||||
|
||||
response = self._request_key_download_view()
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
def test_key_download_view_with_permission(self):
|
||||
key = Key.objects.create(key_data=TEST_KEY_DATA)
|
||||
self._create_test_key()
|
||||
|
||||
self.login_user()
|
||||
|
||||
self.role.permissions.add(permission_key_download.stored_permission)
|
||||
self.grant_access(obj=self.test_key, permission=permission_key_download)
|
||||
|
||||
self.expected_content_type = 'application/octet-stream; charset=utf-8'
|
||||
|
||||
response = self.get(
|
||||
viewname='django_gpg:key_download', args=(key.pk,)
|
||||
)
|
||||
response = self._request_key_download_view()
|
||||
|
||||
assert_download_response(
|
||||
self, response=response, content=key.key_data,
|
||||
basename=key.key_id,
|
||||
test_case=self, response=response, content=self.test_key.key_data,
|
||||
basename=self.test_key.key_id,
|
||||
)
|
||||
|
||||
def test_key_upload_view_no_permission(self):
|
||||
self.login_user()
|
||||
|
||||
response = self.post(
|
||||
def _request_key_upload_view(self):
|
||||
return self.post(
|
||||
viewname='django_gpg:key_upload', data={'key_data': TEST_KEY_DATA}
|
||||
)
|
||||
|
||||
def test_key_upload_view_no_permission(self):
|
||||
response = self._request_key_upload_view()
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
||||
self.assertEqual(Key.objects.count(), 0)
|
||||
|
||||
def test_key_upload_view_with_permission(self):
|
||||
self.login_user()
|
||||
self.grant_permission(permission=permission_key_upload)
|
||||
|
||||
self.role.permissions.add(permission_key_upload.stored_permission)
|
||||
|
||||
response = self.post(
|
||||
viewname='django_gpg:key_upload', data={'key_data': TEST_KEY_DATA},
|
||||
follow=True
|
||||
)
|
||||
|
||||
self.assertContains(response, 'created', status_code=200)
|
||||
response = self._request_key_upload_view()
|
||||
self.assertEqual(response.status_code, 302)
|
||||
|
||||
self.assertEqual(Key.objects.count(), 1)
|
||||
self.assertEqual(Key.objects.first().fingerprint, TEST_KEY_FINGERPRINT)
|
||||
|
||||
@@ -11,39 +11,44 @@ from .views import (
|
||||
|
||||
urlpatterns = [
|
||||
url(
|
||||
r'^(?P<pk>\d+)/$', KeyDetailView.as_view(), name='key_detail'
|
||||
regex=r'^keys/(?P<key_id>\d+)/$', name='key_detail',
|
||||
view=KeyDetailView.as_view()
|
||||
),
|
||||
url(
|
||||
r'^(?P<pk>\d+)/delete/$', KeyDeleteView.as_view(), name='key_delete'
|
||||
regex=r'^keys/(?P<key_id>\d+)/delete/$', name='key_delete',
|
||||
view=KeyDeleteView.as_view()
|
||||
),
|
||||
url(
|
||||
r'^(?P<pk>\d+)/download/$', KeyDownloadView.as_view(),
|
||||
name='key_download'
|
||||
regex=r'^keys/(?P<key_id>\d+)/download/$', name='key_download',
|
||||
view=KeyDownloadView.as_view()
|
||||
),
|
||||
url(
|
||||
r'^list/private/$', PrivateKeyListView.as_view(),
|
||||
name='key_private_list'
|
||||
regex=r'^keys/private/$', name='key_private_list',
|
||||
view=PrivateKeyListView.as_view()
|
||||
),
|
||||
url(
|
||||
r'^list/public/$', PublicKeyListView.as_view(), name='key_public_list'
|
||||
regex=r'^keys/public/$', name='key_public_list',
|
||||
view=PublicKeyListView.as_view()
|
||||
),
|
||||
url(
|
||||
r'^upload/$', KeyUploadView.as_view(), name='key_upload'
|
||||
regex=r'^keys/upload/$', name='key_upload',
|
||||
view=KeyUploadView.as_view()
|
||||
),
|
||||
url(r'^query/$', KeyQueryView.as_view(), name='key_query'),
|
||||
url(regex=r'^keys/query/$', name='key_query', view=KeyQueryView.as_view()),
|
||||
url(
|
||||
r'^query/results/$', KeyQueryResultView.as_view(),
|
||||
name='key_query_results'
|
||||
regex=r'^keys/query/results/$', name='key_query_results',
|
||||
view=KeyQueryResultView.as_view()
|
||||
),
|
||||
url(
|
||||
r'^receive/(?P<key_id>.+)/$', KeyReceive.as_view(), name='key_receive'
|
||||
),
|
||||
regex=r'^keys/receive/(?P<key_id>.+)/$', name='key_receive',
|
||||
view=KeyReceive.as_view()
|
||||
)
|
||||
]
|
||||
|
||||
api_urls = [
|
||||
url(
|
||||
r'^keys/(?P<pk>[0-9]+)/$', APIKeyView.as_view(),
|
||||
name='key-detail'
|
||||
regex=r'^keys/(?P<key_id>\d+)/$', name='key-detail',
|
||||
view=APIKeyView.as_view()
|
||||
),
|
||||
url(r'^keys/$', APIKeyListView.as_view(), name='key-list'),
|
||||
url(regex=r'^keys/$', name='key-list', view=APIKeyListView.as_view())
|
||||
]
|
||||
|
||||
@@ -30,12 +30,13 @@ logger = logging.getLogger(__name__)
|
||||
class KeyDeleteView(SingleObjectDeleteView):
|
||||
model = Key
|
||||
object_permission = permission_key_delete
|
||||
pk_url_kwarg = 'key_id'
|
||||
|
||||
def get_post_action_redirect(self):
|
||||
if self.get_object().key_type == KEY_TYPE_PUBLIC:
|
||||
return reverse_lazy('django_gpg:key_public_list')
|
||||
return reverse_lazy(viewname='django_gpg:key_public_list')
|
||||
else:
|
||||
return reverse_lazy('django_gpg:key_private_list')
|
||||
return reverse_lazy(viewname='django_gpg:key_private_list')
|
||||
|
||||
def get_extra_context(self):
|
||||
return {'title': _('Delete key: %s') % self.get_object()}
|
||||
@@ -45,6 +46,7 @@ class KeyDetailView(SingleObjectDetailView):
|
||||
form_class = KeyDetailForm
|
||||
model = Key
|
||||
object_permission = permission_key_view
|
||||
pk_url_kwarg = 'key_id'
|
||||
|
||||
def get_extra_context(self):
|
||||
return {
|
||||
@@ -55,6 +57,7 @@ class KeyDetailView(SingleObjectDetailView):
|
||||
class KeyDownloadView(SingleObjectDownloadView):
|
||||
model = Key
|
||||
object_permission = permission_key_download
|
||||
pk_url_kwarg = 'key_id'
|
||||
|
||||
def get_file(self):
|
||||
key = self.get_object()
|
||||
@@ -63,7 +66,7 @@ class KeyDownloadView(SingleObjectDownloadView):
|
||||
|
||||
|
||||
class KeyReceive(ConfirmView):
|
||||
post_action_redirect = reverse_lazy('django_gpg:key_public_list')
|
||||
post_action_redirect = reverse_lazy(viewname='django_gpg:key_public_list')
|
||||
view_permission = permission_key_receive
|
||||
|
||||
def get_extra_context(self):
|
||||
@@ -105,7 +108,7 @@ class KeyQueryView(SimpleView):
|
||||
def get_extra_context(self):
|
||||
return {
|
||||
'form': self.get_form(),
|
||||
'form_action': reverse('django_gpg:key_query_results'),
|
||||
'form_action': reverse(viewname='django_gpg:key_query_results'),
|
||||
'submit_icon_class': icon_keyserver_search,
|
||||
'submit_label': _('Search'),
|
||||
'submit_method': 'GET',
|
||||
@@ -144,7 +147,7 @@ class KeyQueryResultView(SingleObjectListView):
|
||||
class KeyUploadView(SingleObjectCreateView):
|
||||
fields = ('key_data',)
|
||||
model = Key
|
||||
post_action_redirect = reverse_lazy('django_gpg:key_public_list')
|
||||
post_action_redirect = reverse_lazy(viewname='django_gpg:key_public_list')
|
||||
view_permission = permission_key_upload
|
||||
|
||||
def get_extra_context(self):
|
||||
|
||||
Reference in New Issue
Block a user