Portal/rsconcept/backend/apps/users/serializers.py
2025-03-02 20:27:02 +03:00

168 lines
5.2 KiB
Python

''' 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.library.models import Editor
from shared 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['username']
if '@' in username:
user = models.User.objects.filter(email=username)
if not user.exists() or user.count() > 1:
raise serializers.ValidationError(
msg.passwordAuthFailed(),
code='authorization'
)
username = user.first().username
password = attrs['password']
authenticated = authenticate(
request=self.context.get('request'),
username=username,
password=password
)
if not authenticated:
raise serializers.ValidationError(
msg.passwordAuthFailed(),
code='authorization'
)
attrs['user'] = authenticated
return attrs
class AuthSerializer(serializers.Serializer):
''' Serializer: Authorization data. '''
id = serializers.IntegerField()
username = serializers.CharField()
is_staff = serializers.BooleanField()
def to_representation(self, instance: models.User) -> dict:
if instance.is_anonymous:
return {
'id': None,
'username': '',
'is_staff': False,
'editor': []
}
else:
return {
'id': instance.pk,
'username': instance.username,
'is_staff': instance.is_staff,
'editor': [edit.item.pk for edit in Editor.objects.filter(editor=instance)]
}
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',
]
read_only_fields = ('id', 'username')
def validate(self, attrs):
attrs = super().validate(attrs)
if 'email' in attrs:
maybe_user = models.User.objects.filter(email=attrs['email'])
if maybe_user.exists():
if maybe_user.count() > 1 or maybe_user.first().pk != self.context['request'].user.pk:
raise serializers.ValidationError({
'email': msg.emailAlreadyTaken()
})
return attrs
class UserInfoSerializer(serializers.ModelSerializer):
''' Serializer: User open information. '''
id = serializers.IntegerField(read_only=True)
class Meta:
''' serializer metadata. '''
model = models.User
fields = [
'id',
'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()
})
if models.User.objects.filter(email=attrs['email']).exists():
raise serializers.ValidationError({
'email': msg.emailAlreadyTaken()
})
return attrs
def create(self, validated_data):
user = models.User.objects.create_user(
username=validated_data['username'],
email=validated_data['email'],
password=validated_data['password']
)
user.first_name = validated_data['first_name']
user.last_name = validated_data['last_name']
user.save()
return user