''' Serializers: User profile and Authorization. ''' from django.contrib.auth import authenticate from django.contrib.auth.password_validation import validate_password from rest_framework import serializers from apps.rsform.models import Subscription from . import messages as msg from . import models class NonFieldErrorSerializer(serializers.Serializer): ''' Serializer: list of non-field errors. ''' non_field_errors = serializers.ListField( child=serializers.CharField() ) class LoginSerializer(serializers.Serializer): ''' Serializer: User authentication by login/password. ''' username = serializers.CharField( label='Имя пользователя', write_only=True ) password = serializers.CharField( label='Пароль', style={'input_type': 'password'}, trim_whitespace=False, write_only=True ) def validate(self, attrs): username = attrs.get('username') password = attrs.get('password') user = authenticate( request=self.context.get('request'), username=username, password=password ) if not user: raise serializers.ValidationError( msg.passwordAuthFailed(), code='authorization' ) attrs['user'] = user return attrs class AuthSerializer(serializers.Serializer): ''' Serializer: Authorization data. ''' id = serializers.IntegerField() username = serializers.CharField() is_staff = serializers.BooleanField() subscriptions = serializers.ListField( child=serializers.IntegerField() ) def to_representation(self, instance: models.User) -> dict: if instance.is_anonymous: return { 'id': None, 'username': '', 'is_staff': False, 'subscriptions': [] } else: return { 'id': instance.pk, 'username': instance.username, 'is_staff': instance.is_staff, 'subscriptions': [sub.item.pk for sub in Subscription.objects.filter(user=instance)] } class UserInfoSerializer(serializers.ModelSerializer): ''' Serializer: User data. ''' class Meta: ''' serializer metadata. ''' model = models.User fields = [ 'id', 'first_name', 'last_name', ] class UserSerializer(serializers.ModelSerializer): ''' Serializer: User data. ''' id = serializers.IntegerField(read_only=True) class Meta: ''' serializer metadata. ''' model = models.User fields = [ 'id', 'username', 'email', 'first_name', 'last_name', ] class ChangePasswordSerializer(serializers.Serializer): ''' Serializer: Change password. ''' old_password = serializers.CharField(required=True) new_password = serializers.CharField(required=True) class SignupSerializer(serializers.ModelSerializer): ''' Serializer: Create user profile. ''' id = serializers.IntegerField(read_only=True) password = serializers.CharField(write_only=True, required=True, validators=[validate_password]) password2 = serializers.CharField(write_only=True, required=True) class Meta: ''' serializer metadata. ''' model = models.User fields = [ 'id', 'username', 'email', 'first_name', 'last_name', 'password', 'password2' ] def validate(self, attrs): if attrs['password'] != attrs['password2']: raise serializers.ValidationError({ 'password': msg.passwordsNotMatch() }) return attrs def create(self, validated_data): user = models.User.objects.create_user( validated_data['username'], validated_data['email'], validated_data['password'] ) user.first_name = validated_data['first_name'] user.last_name = validated_data['last_name'] user.save() return user