from django.contrib.auth.password_validation import validate_password from rest_framework import serializers from desecapi.models import User, validate_domain_name from .captcha import CaptchaSolutionSerializer from .domains import DomainSerializer class EmailSerializer(serializers.Serializer): email = serializers.EmailField() class EmailPasswordSerializer(EmailSerializer): password = serializers.CharField() class ChangeEmailSerializer(serializers.Serializer): new_email = serializers.EmailField() def validate_new_email(self, value): if value == self.context["request"].user.email: raise serializers.ValidationError("Email address unchanged.") return value class ResetPasswordSerializer(EmailSerializer): captcha = CaptchaSolutionSerializer(required=True) class UserSerializer(serializers.ModelSerializer): class Meta: model = User fields = ( "created", "email", "id", "limit_domains", "outreach_preference", ) read_only_fields = ( "created", "email", "id", "limit_domains", ) def validate_password(self, value): if value is not None: validate_password(value) return value def create(self, validated_data): return User.objects.create_user(**validated_data) class RegisterAccountSerializer(UserSerializer): domain = serializers.CharField(required=False, validators=validate_domain_name) captcha = CaptchaSolutionSerializer(required=False) class Meta: model = UserSerializer.Meta.model fields = ( "email", "password", "domain", "captcha", "outreach_preference", ) extra_kwargs = { "password": { "write_only": True, # Do not expose password field "allow_null": True, } } def validate_domain(self, value): serializer = DomainSerializer(data=dict(name=value), context=self.context) try: serializer.is_valid(raise_exception=True) except serializers.ValidationError: raise serializers.ValidationError( serializer.default_error_messages["name_unavailable"], code="name_unavailable", ) return value def create(self, validated_data): validated_data.pop("domain", None) # If validated_data['captcha'] exists, the captcha was also validated, so we can set the user to verified if "captcha" in validated_data: validated_data.pop("captcha") validated_data["needs_captcha"] = False return super().create(validated_data)