gault-millau/apps/account/serializers/common.py
2019-08-30 17:56:35 +03:00

146 lines
4.5 KiB
Python

"""Common account serializers"""
from fcm_django.models import FCMDevice
from rest_framework import serializers, exceptions
from account import models
from utils import exceptions as utils_exceptions
from rest_framework_simplejwt import tokens
from django.conf import settings
from account import tasks
# User serializers
class UserSerializer(serializers.ModelSerializer):
"""User serializer."""
class Meta:
model = models.User
fields = [
'first_name',
'last_name',
]
# Firebase Cloud Messaging serializers
class FCMDeviceSerializer(serializers.ModelSerializer):
"""FCM Device model serializer"""
class Meta:
model = FCMDevice
fields = ('id', 'name', 'registration_id', 'device_id',
'active', 'date_created', 'type')
read_only_fields = ('id', 'date_created',)
extra_kwargs = {'active': {'default': True}}
def validate(self, attrs):
regid = attrs.get('registration_id')
dtype = attrs.get('type')
if regid and dtype and self.Meta.model.objects.filter(
registration_id=regid).exclude(type=dtype).count():
raise exceptions.ValidationError(
{'registration_id': 'This field must be unique.'})
return attrs
def __init__(self, *args, **kwargs):
super(FCMDeviceSerializer, self).__init__(*args, **kwargs)
self.fields['type'].help_text = (
'Should be one of ["%s"]' %
'", "'.join([i for i in self.fields['type'].choices]))
def create(self, validated_data):
user = self.context['request'].user
if not user.is_anonymous:
validated_data['user'] = user
device = FCMDevice.objects.create(**validated_data)
return device
def update(self, instance, validated_data):
user = self.context['request'].user
if not user.is_anonymous:
instance.user = user
instance.save()
else:
instance.user = None
instance.save()
return instance
class RefreshTokenSerializer(serializers.Serializer):
"""Serializer for refresh token view"""
refresh_token = serializers.CharField(read_only=True)
access_token = serializers.CharField(read_only=True)
def get_request(self):
"""Return request"""
return self.context.get('request')
def validate(self, attrs):
"""Override validate method"""
refresh_token = self.get_request().COOKIES.get('refresh_token')
if not refresh_token:
raise utils_exceptions.NotValidRefreshTokenError()
token = tokens.RefreshToken(token=refresh_token)
data = {'access_token': str(token.access_token)}
if settings.SIMPLE_JWT.get('ROTATE_REFRESH_TOKENS'):
if settings.SIMPLE_JWT.get('BLACKLIST_AFTER_ROTATION'):
try:
# Attempt to blacklist the given refresh token
token.blacklist()
except AttributeError:
# If blacklist app not installed, `blacklist` method will
# not be present
pass
token.set_jti()
token.set_exp()
data['refresh_token'] = str(token)
return data
class ChangeEmailSerializer(serializers.ModelSerializer):
"""Change user email serializer"""
class Meta:
"""Meta class"""
model = models.User
fields = (
'id',
'email',
)
read_only_fields = (
'id',
)
def validate_email(self, value):
"""Validate email value"""
if value == self.instance.email:
# todo: added custom exception
raise serializers.ValidationError()
return value
def validate(self, attrs):
"""Override validate method"""
email_confirmed = self.instance.email_confirmed
if not email_confirmed:
# todo: added custom exception
raise serializers.ValidationError()
return attrs
def update(self, instance, validated_data):
"""
Override update method
"""
instance.email = validated_data.get('email')
instance.email_confirmed = False
instance.save()
# Send verification link on user email for change email address
if settings.USE_CELERY:
tasks.confirm_new_email_address.delay(instance.id)
else:
tasks.confirm_new_email_address(instance.id)
return instance