Files
gitrusprusandCursor 4eb4c145b6 Add JWT auth with per-user data isolation and account settings.
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>
2026-06-28 21:10:16 +03:00

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