Views: move the base64 encoding to the renderers.
Hard-coding the serialization encoding in the serializers is wrong. This fix now enables us to change to easily change to msgpack as the transport layer.
This commit is contained in:
parent
2880673e27
commit
3dfceb63b1
18
django_etebase/renderers.py
Normal file
18
django_etebase/renderers.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
from rest_framework.utils.encoders import JSONEncoder as DRFJSONEncoder
|
||||||
|
from rest_framework.renderers import JSONRenderer as DRFJSONRenderer
|
||||||
|
|
||||||
|
from .serializers import b64encode
|
||||||
|
|
||||||
|
|
||||||
|
class JSONEncoder(DRFJSONEncoder):
|
||||||
|
def default(self, obj):
|
||||||
|
if isinstance(obj, bytes) or isinstance(obj, memoryview):
|
||||||
|
return b64encode(obj)
|
||||||
|
return super().default(obj)
|
||||||
|
|
||||||
|
|
||||||
|
class JSONRenderer(DRFJSONRenderer):
|
||||||
|
"""
|
||||||
|
Renderer which serializes to JSON with support for our base64
|
||||||
|
"""
|
||||||
|
encoder_class = JSONEncoder
|
@ -56,18 +56,19 @@ def b64decode(data):
|
|||||||
return base64.urlsafe_b64decode(data)
|
return base64.urlsafe_b64decode(data)
|
||||||
|
|
||||||
|
|
||||||
|
def b64decode_or_bytes(data):
|
||||||
|
if isinstance(data, bytes):
|
||||||
|
return data
|
||||||
|
else:
|
||||||
|
return b64decode(data)
|
||||||
|
|
||||||
|
|
||||||
class BinaryBase64Field(serializers.Field):
|
class BinaryBase64Field(serializers.Field):
|
||||||
def to_representation(self, value):
|
def to_representation(self, value):
|
||||||
if self.context.get('supports_binary', False):
|
return value
|
||||||
return value
|
|
||||||
else:
|
|
||||||
return b64encode(value)
|
|
||||||
|
|
||||||
def to_internal_value(self, data):
|
def to_internal_value(self, data):
|
||||||
if isinstance(data, bytes):
|
return b64decode_or_bytes(data)
|
||||||
return data
|
|
||||||
else:
|
|
||||||
return b64decode(data)
|
|
||||||
|
|
||||||
|
|
||||||
class CollectionEncryptionKeyField(BinaryBase64Field):
|
class CollectionEncryptionKeyField(BinaryBase64Field):
|
||||||
@ -91,14 +92,14 @@ class ChunksField(serializers.RelatedField):
|
|||||||
obj = obj.chunk
|
obj = obj.chunk
|
||||||
if self.context.get('prefetch'):
|
if self.context.get('prefetch'):
|
||||||
with open(obj.chunkFile.path, 'rb') as f:
|
with open(obj.chunkFile.path, 'rb') as f:
|
||||||
return (obj.uid, b64encode(f.read()))
|
return (obj.uid, f.read())
|
||||||
else:
|
else:
|
||||||
return (obj.uid, )
|
return (obj.uid, )
|
||||||
|
|
||||||
def to_internal_value(self, data):
|
def to_internal_value(self, data):
|
||||||
if data[0] is None or data[1] is None:
|
if data[0] is None or data[1] is None:
|
||||||
raise serializers.ValidationError('null is not allowed')
|
raise serializers.ValidationError('null is not allowed')
|
||||||
return (data[0], b64decode(data[1]))
|
return (data[0], b64decode_or_bytes(data[1]))
|
||||||
|
|
||||||
|
|
||||||
class CollectionItemChunkSerializer(serializers.ModelSerializer):
|
class CollectionItemChunkSerializer(serializers.ModelSerializer):
|
||||||
|
@ -29,7 +29,7 @@ from rest_framework import viewsets
|
|||||||
from rest_framework.decorators import action as action_decorator
|
from rest_framework.decorators import action as action_decorator
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework.parsers import JSONParser, FormParser, MultiPartParser
|
from rest_framework.parsers import JSONParser, FormParser, MultiPartParser
|
||||||
from rest_framework.renderers import JSONRenderer, BrowsableAPIRenderer
|
from rest_framework.renderers import BrowsableAPIRenderer
|
||||||
|
|
||||||
import nacl.encoding
|
import nacl.encoding
|
||||||
import nacl.signing
|
import nacl.signing
|
||||||
@ -42,6 +42,7 @@ from .drf_msgpack.parsers import MessagePackParser
|
|||||||
from .drf_msgpack.renderers import MessagePackRenderer
|
from .drf_msgpack.renderers import MessagePackRenderer
|
||||||
|
|
||||||
from . import app_settings, permissions
|
from . import app_settings, permissions
|
||||||
|
from .renderers import JSONRenderer
|
||||||
from .models import (
|
from .models import (
|
||||||
Collection,
|
Collection,
|
||||||
CollectionItem,
|
CollectionItem,
|
||||||
@ -53,7 +54,6 @@ from .models import (
|
|||||||
UserInfo,
|
UserInfo,
|
||||||
)
|
)
|
||||||
from .serializers import (
|
from .serializers import (
|
||||||
b64encode,
|
|
||||||
AuthenticationChangePasswordInnerSerializer,
|
AuthenticationChangePasswordInnerSerializer,
|
||||||
AuthenticationSignupSerializer,
|
AuthenticationSignupSerializer,
|
||||||
AuthenticationLoginChallengeSerializer,
|
AuthenticationLoginChallengeSerializer,
|
||||||
@ -700,8 +700,8 @@ class AuthenticationViewSet(viewsets.ViewSet):
|
|||||||
challenge = box.encrypt(msgpack_encode(challenge_data), encoder=nacl.encoding.RawEncoder)
|
challenge = box.encrypt(msgpack_encode(challenge_data), encoder=nacl.encoding.RawEncoder)
|
||||||
|
|
||||||
ret = {
|
ret = {
|
||||||
"salt": b64encode(salt),
|
"salt": salt,
|
||||||
"challenge": b64encode(challenge),
|
"challenge": challenge,
|
||||||
"version": user.userinfo.version,
|
"version": user.userinfo.version,
|
||||||
}
|
}
|
||||||
return Response(ret, status=status.HTTP_200_OK)
|
return Response(ret, status=status.HTTP_200_OK)
|
||||||
@ -717,7 +717,7 @@ class AuthenticationViewSet(viewsets.ViewSet):
|
|||||||
response = msgpack_decode(response_raw)
|
response = msgpack_decode(response_raw)
|
||||||
signature = outer_serializer.validated_data['signature']
|
signature = outer_serializer.validated_data['signature']
|
||||||
|
|
||||||
context = {'host': request.get_host(), 'supports_binary': True}
|
context = {'host': request.get_host()}
|
||||||
serializer = AuthenticationLoginInnerSerializer(data=response, context=context)
|
serializer = AuthenticationLoginInnerSerializer(data=response, context=context)
|
||||||
serializer.is_valid(raise_exception=True)
|
serializer.is_valid(raise_exception=True)
|
||||||
|
|
||||||
@ -750,7 +750,7 @@ class AuthenticationViewSet(viewsets.ViewSet):
|
|||||||
response = msgpack_decode(response_raw)
|
response = msgpack_decode(response_raw)
|
||||||
signature = outer_serializer.validated_data['signature']
|
signature = outer_serializer.validated_data['signature']
|
||||||
|
|
||||||
context = {'host': request.get_host(), 'supports_binary': True}
|
context = {'host': request.get_host()}
|
||||||
serializer = AuthenticationChangePasswordInnerSerializer(request.user.userinfo, data=response, context=context)
|
serializer = AuthenticationChangePasswordInnerSerializer(request.user.userinfo, data=response, context=context)
|
||||||
serializer.is_valid(raise_exception=True)
|
serializer.is_valid(raise_exception=True)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user