from rest_framework import serializers from django.contrib.auth import get_user_model from django.contrib.auth.password_validation import validate_password from django.core.exceptions import ValidationError from .models import PasswordResetToken User = get_user_model() class UserRegistrationSerializer(serializers.ModelSerializer): password = serializers.CharField(write_only=True, required=True, validators=[validate_password]) password2 = serializers.CharField(write_only=True, required=True) class Meta: model = User fields = ('username', 'password', 'password2', 'email', 'first_name', 'last_name', 'role') extra_kwargs = { 'first_name': {'required': True}, 'last_name': {'required': True}, 'email': {'required': True}, 'role': {'default': 'user'} } def validate(self, attrs): if attrs['password'] != attrs['password2']: raise serializers.ValidationError({"password": "Password fields didn't match."}) return attrs def create(self, validated_data): validated_data.pop('password2') user = User.objects.create_user(**validated_data) return user class UserSerializer(serializers.ModelSerializer): class Meta: model = User fields = ('id', 'username', 'email', 'first_name', 'last_name', 'role') read_only_fields = ('role', 'is_staff', 'is_active', 'is_superuser', 'date_joined', 'last_login', 'groups', 'user_permissions', 'id') class ResetPasswordSerializer(serializers.Serializer): email = serializers.EmailField(required=True) def validate_email(self, value): try: User.objects.get(email=value) except User.DoesNotExist: # Don't reveal that the email doesn't exist pass return value class ResetPasswordConfirmSerializer(serializers.Serializer): token = serializers.UUIDField(required=True) new_password = serializers.CharField(write_only=True, required=True, validators=[validate_password]) confirm_password = serializers.CharField(write_only=True, required=True) def validate(self, attrs): if attrs['new_password'] != attrs['confirm_password']: raise serializers.ValidationError({"new_password": "Password fields didn't match."}) try: reset_token = PasswordResetToken.objects.get(token=attrs['token']) if not reset_token.is_valid(): raise serializers.ValidationError({"token": "Invalid or expired token."}) except PasswordResetToken.DoesNotExist: raise serializers.ValidationError({"token": "Invalid token."}) return attrs