"""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