Users can register, log in, and manage profile/password in a personal account page; server data is scoped by owner across contacts, maps, tags, and import. Co-authored-by: Cursor <cursoragent@cursor.com>
95 lines
3.6 KiB
Python
95 lines
3.6 KiB
Python
from django.contrib.auth import get_user_model
|
|
from django.contrib.auth.password_validation import validate_password
|
|
from rest_framework import serializers
|
|
|
|
User = get_user_model()
|
|
|
|
|
|
class RegisterSerializer(serializers.Serializer):
|
|
username = serializers.CharField(max_length=150)
|
|
email = serializers.EmailField(required=False, allow_blank=True)
|
|
password = serializers.CharField(write_only=True, min_length=8)
|
|
|
|
def validate_username(self, value):
|
|
username = value.strip()
|
|
if not username:
|
|
raise serializers.ValidationError('Укажите имя пользователя.')
|
|
if User.objects.filter(username__iexact=username).exists():
|
|
raise serializers.ValidationError('Это имя пользователя уже занято.')
|
|
return username
|
|
|
|
def validate_password(self, value):
|
|
validate_password(value)
|
|
return value
|
|
|
|
def create(self, validated_data):
|
|
email = (validated_data.get('email') or '').strip()
|
|
return User.objects.create_user(
|
|
username=validated_data['username'],
|
|
email=email,
|
|
password=validated_data['password'],
|
|
)
|
|
|
|
|
|
class UserSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = User
|
|
fields = ['id', 'username', 'email']
|
|
read_only_fields = fields
|
|
|
|
|
|
class UpdateProfileSerializer(serializers.Serializer):
|
|
username = serializers.CharField(max_length=150, required=False)
|
|
email = serializers.EmailField(required=False, allow_blank=True)
|
|
current_password = serializers.CharField(write_only=True)
|
|
|
|
def validate_current_password(self, value):
|
|
user = self.context['request'].user
|
|
if not user.check_password(value):
|
|
raise serializers.ValidationError('Неверный текущий пароль.')
|
|
return value
|
|
|
|
def validate_username(self, value):
|
|
username = value.strip()
|
|
if not username:
|
|
raise serializers.ValidationError('Укажите имя пользователя.')
|
|
user = self.context['request'].user
|
|
if User.objects.filter(username__iexact=username).exclude(pk=user.pk).exists():
|
|
raise serializers.ValidationError('Это имя пользователя уже занято.')
|
|
return username
|
|
|
|
def validate(self, data):
|
|
if 'username' not in data and 'email' not in data:
|
|
raise serializers.ValidationError('Укажите новое имя пользователя или email.')
|
|
return data
|
|
|
|
def save(self):
|
|
user = self.context['request'].user
|
|
if 'username' in self.validated_data:
|
|
user.username = self.validated_data['username']
|
|
if 'email' in self.validated_data:
|
|
user.email = (self.validated_data.get('email') or '').strip()
|
|
user.save(update_fields=['username', 'email'])
|
|
return user
|
|
|
|
|
|
class ChangePasswordSerializer(serializers.Serializer):
|
|
current_password = serializers.CharField(write_only=True)
|
|
new_password = serializers.CharField(write_only=True, min_length=8)
|
|
|
|
def validate_current_password(self, value):
|
|
user = self.context['request'].user
|
|
if not user.check_password(value):
|
|
raise serializers.ValidationError('Неверный текущий пароль.')
|
|
return value
|
|
|
|
def validate_new_password(self, value):
|
|
validate_password(value, self.context['request'].user)
|
|
return value
|
|
|
|
def save(self):
|
|
user = self.context['request'].user
|
|
user.set_password(self.validated_data['new_password'])
|
|
user.save(update_fields=['password'])
|
|
return user
|