Files
mayan-edms/mayan/apps/document_signatures/serializers.py
Roberto Rosario f73dd28c92 Update signature API to support uploads
Signed-off-by: Roberto Rosario <roberto.rosario@mayan-edms.com>
2019-11-05 01:36:00 -04:00

208 lines
6.7 KiB
Python

from __future__ import absolute_import, unicode_literals
from django.utils.translation import ugettext_lazy as _
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from mayan.apps.acls.models import AccessControlList
from mayan.apps.django_gpg.models import Key
from mayan.apps.django_gpg.permissions import permission_key_sign
from mayan.apps.rest_api.relations import MultiKwargHyperlinkedIdentityField
from .models import DetachedSignature, EmbeddedSignature
class BaseSignatureSerializer(serializers.HyperlinkedModelSerializer):
document_version_url = MultiKwargHyperlinkedIdentityField(
view_kwargs=(
{
'lookup_field': 'document_version_id',
'lookup_url_kwarg': 'version_pk',
},
{
'lookup_field': 'document_version.document.pk',
'lookup_url_kwarg': 'pk',
}
),
view_name='rest_api:documentversion-detail'
)
class BaseSignSerializer(serializers.HyperlinkedModelSerializer):
passphrase = serializers.CharField(
help_text=_(
'The passphrase to unlock the key and allow it to be used to '
'sign the document version.'
),
required=False, write_only=True
)
class DetachedSignatureSerializer(BaseSignatureSerializer):
url = MultiKwargHyperlinkedIdentityField(
view_kwargs=(
{
'lookup_field': 'document_version.document.pk',
'lookup_url_kwarg': 'document_id',
},
{
'lookup_field': 'document_version_id',
'lookup_url_kwarg': 'document_version_id',
},
{
'lookup_field': 'pk',
'lookup_url_kwarg': 'detached_signature_id',
},
),
view_name='rest_api:detachedsignature-detail'
)
class Meta:
extra_kwargs = {
'signature_file': {'write_only': True},
}
fields = (
'date', 'document_version_url', 'key_id', 'signature_file',
'signature_id', 'public_key_fingerprint', 'url'
)
model = DetachedSignature
read_only_fields = ('key_id',)
def create(self, validated_data):
validated_data['document_version'] = self.context['document_version']
return super(DetachedSignatureSerializer, self).create(
validated_data=validated_data
)
class EmbeddedSignatureSerializer(serializers.HyperlinkedModelSerializer):
document_version_url = MultiKwargHyperlinkedIdentityField(
view_kwargs=(
{
'lookup_field': 'document_version_id',
'lookup_url_kwarg': 'version_pk',
},
{
'lookup_field': 'document_version.document.pk',
'lookup_url_kwarg': 'pk',
}
),
view_name='rest_api:documentversion-detail'
)
url = MultiKwargHyperlinkedIdentityField(
view_kwargs=(
{
'lookup_field': 'document_version.document.pk',
'lookup_url_kwarg': 'document_id',
},
{
'lookup_field': 'document_version_id',
'lookup_url_kwarg': 'document_version_id',
},
{
'lookup_field': 'pk',
'lookup_url_kwarg': 'embedded_signature_id',
},
),
view_name='rest_api:embeddedsignature-detail'
)
passphrase = serializers.CharField(required=False, write_only=True)
class Meta:
fields = (
'date', 'document_version_url', 'key_id', 'signature_id',
'passphrase', 'public_key_fingerprint', 'url'
)
model = EmbeddedSignature
def create(self, validated_data):
key_id = validated_data.pop('key_id')
passphrase = validated_data.pop('passphrase', None)
key_queryset = AccessControlList.objects.restrict_queryset(
permission=permission_key_sign, queryset=Key.objects.all(),
user=self.context['request'].user
)
try:
key = key_queryset.get(fingerprint__endswith=key_id)
except Key.DoesNotExist:
raise ValidationError(
{
'key_id': [
'Key "{}" not found.'.format(key_id)
]
}, code='invalid'
)
signature = EmbeddedSignature.objects.sign_document_version(
document_version=self.context['document_version'], key=key,
passphrase=passphrase, user=self.context['request'].user
)
return signature
class SignDetachedSerializer(BaseSignatureSerializer, BaseSignSerializer):
class Meta:
fields = (
'date', 'document_version_url', 'key_id', 'signature_id',
'passphrase', 'public_key_fingerprint', 'url'
)
model = DetachedSignature
def sign(self, key_id, passphrase):
key_queryset = AccessControlList.objects.restrict_queryset(
permission=permission_key_sign, queryset=Key.objects.all(),
user=self.context['request'].user
)
try:
key = key_queryset.get(fingerprint__endswith=key_id)
except Key.DoesNotExist:
raise ValidationError(
{
'key_id': [
'Key "{}" not found.'.format(key_id)
]
}, code='invalid'
)
return DetachedSignature.objects.sign_document_version(
document_version=self.context['document_version'], key=key,
passphrase=passphrase, user=self.context['request'].user
)
class SignEmbeddedSerializer(SignDetachedSerializer):
class Meta:
fields = (
'date', 'document_version_url', 'key_id', 'signature_id',
'passphrase', 'public_key_fingerprint', 'url'
)
model = EmbeddedSignature
def sign(self, key_id, passphrase):
key_queryset = AccessControlList.objects.restrict_queryset(
permission=permission_key_sign, queryset=Key.objects.all(),
user=self.context['request'].user
)
try:
key = key_queryset.get(fingerprint__endswith=key_id)
except Key.DoesNotExist:
raise ValidationError(
{
'key_id': [
'Key "{}" not found.'.format(key_id)
]
}, code='invalid'
)
return EmbeddedSignature.objects.sign_document_version(
document_version=self.context['document_version'], key=key,
passphrase=passphrase, user=self.context['request'].user
)