from rest_framework import serializers from users.models import User from users import cons from tools.tools import decode_uid, encode_uid class UserSerializer(serializers.ModelSerializer): password = serializers.CharField( write_only=True, required=False, min_length=8, style={"input_type": "password"}, ) #todo # avatar = serializers.ImageField(allow_empty_file=True, source="profile.avatar", read_only=True) class Meta: model = User fields = ( "id", "email", "first_name", "last_name", "is_active", "password" ) class UserPasswordResetSerializer(serializers.Serializer): email = serializers.CharField() def validate(self, data): email = data.get("email") user = User.objects.filter(email__iexact=email) if not user: msg = {"detail": cons.USER_WITH_FOLLOWING_EMAIL_DOES_NOT_EXIST} raise serializers.ValidationError(msg) self.do_actions(data) return data def do_actions(self, validated_data): return User.objects.reset_password(validated_data) class UserPasswordResetConfirmSerializer(serializers.Serializer): uid = serializers.CharField() token = serializers.CharField() code = serializers.IntegerField() new_password = serializers.CharField(style={"input_type": "password"}) repeat_new_password = serializers.CharField(style={"input_type": "password"}) def validate_uid(self, value): try: uid = decode_uid(value) self.user = User.objects.get(pk=uid) except (User.DoesNotExist, ValueError, TypeError, OverflowError): raise serializers.ValidationError(cons.INVALID_UID) return value def validate_new_passwords(self, attrs): new_password = attrs["new_password"] repeat_new_password = attrs["repeat_new_password"] if new_password != repeat_new_password: raise serializers.ValidationError(cons.PASSWORDS_ARE_NOT_THE_SAME) return attrs def validate(self, attrs): token = attrs["token"] code = attrs["code"] if not self.context["view"].token_generator.check_token(self.user, token): raise serializers.ValidationError(cons.INVALID_TOKEN) if self.user.reset_code != code: raise serializers.ValidationError(cons.INVALID_CODE) self.validate_new_passwords(attrs) self.do_actions(attrs) return attrs def do_actions(self, validated_data): return User.objects.confirm_reset_password(**validated_data)