157 lines
5.3 KiB
Python
157 lines
5.3 KiB
Python
"""
|
|
Serializers for user-related models.
|
|
"""
|
|
from rest_framework import serializers
|
|
from django.contrib.auth import authenticate
|
|
from django.contrib.auth.password_validation import validate_password
|
|
from .models import User, UserProfile, APIKey
|
|
import secrets
|
|
|
|
|
|
class UserRegistrationSerializer(serializers.ModelSerializer):
|
|
"""Serializer for user registration."""
|
|
password = serializers.CharField(write_only=True, validators=[validate_password])
|
|
password_confirm = serializers.CharField(write_only=True)
|
|
|
|
class Meta:
|
|
model = User
|
|
fields = ('username', 'email', 'password', 'password_confirm', 'first_name', 'last_name', 'company_name', 'phone_number')
|
|
|
|
def validate(self, attrs):
|
|
if attrs['password'] != attrs['password_confirm']:
|
|
raise serializers.ValidationError("Passwords don't match.")
|
|
return attrs
|
|
|
|
def create(self, validated_data):
|
|
validated_data.pop('password_confirm')
|
|
user = User.objects.create_user(**validated_data)
|
|
return user
|
|
|
|
|
|
class UserLoginSerializer(serializers.Serializer):
|
|
"""Serializer for user login."""
|
|
email = serializers.EmailField()
|
|
password = serializers.CharField()
|
|
|
|
def validate(self, attrs):
|
|
email = attrs.get('email')
|
|
password = attrs.get('password')
|
|
|
|
if email and password:
|
|
user = authenticate(username=email, password=password)
|
|
if not user:
|
|
raise serializers.ValidationError('Invalid credentials.')
|
|
if not user.is_active:
|
|
raise serializers.ValidationError('User account is disabled.')
|
|
attrs['user'] = user
|
|
return attrs
|
|
else:
|
|
raise serializers.ValidationError('Must include email and password.')
|
|
|
|
|
|
class UserSerializer(serializers.ModelSerializer):
|
|
"""Serializer for user details."""
|
|
profile = serializers.SerializerMethodField()
|
|
usage_limits = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = User
|
|
fields = (
|
|
'id', 'username', 'email', 'first_name', 'last_name', 'subscription_type',
|
|
'is_api_enabled', 'company_name', 'phone_number', 'is_verified',
|
|
'date_joined', 'last_login', 'profile', 'usage_limits'
|
|
)
|
|
read_only_fields = ('id', 'date_joined', 'last_login')
|
|
|
|
def get_profile(self, obj):
|
|
try:
|
|
profile = obj.profile
|
|
return UserProfileSerializer(profile).data
|
|
except UserProfile.DoesNotExist:
|
|
return None
|
|
|
|
def get_usage_limits(self, obj):
|
|
return obj.get_usage_limits()
|
|
|
|
|
|
class UserProfileSerializer(serializers.ModelSerializer):
|
|
"""Serializer for user profile."""
|
|
class Meta:
|
|
model = UserProfile
|
|
fields = (
|
|
'avatar', 'bio', 'website', 'location', 'timezone', 'language',
|
|
'notification_preferences', 'created_at', 'updated_at'
|
|
)
|
|
read_only_fields = ('created_at', 'updated_at')
|
|
|
|
|
|
class UserUpdateSerializer(serializers.ModelSerializer):
|
|
"""Serializer for updating user information."""
|
|
class Meta:
|
|
model = User
|
|
fields = ('first_name', 'last_name', 'company_name', 'phone_number')
|
|
|
|
def update(self, instance, validated_data):
|
|
for attr, value in validated_data.items():
|
|
setattr(instance, attr, value)
|
|
instance.save()
|
|
return instance
|
|
|
|
|
|
class PasswordChangeSerializer(serializers.Serializer):
|
|
"""Serializer for password change."""
|
|
old_password = serializers.CharField()
|
|
new_password = serializers.CharField(validators=[validate_password])
|
|
new_password_confirm = serializers.CharField()
|
|
|
|
def validate(self, attrs):
|
|
if attrs['new_password'] != attrs['new_password_confirm']:
|
|
raise serializers.ValidationError("New passwords don't match.")
|
|
return attrs
|
|
|
|
def validate_old_password(self, value):
|
|
user = self.context['request'].user
|
|
if not user.check_password(value):
|
|
raise serializers.ValidationError('Old password is incorrect.')
|
|
return value
|
|
|
|
|
|
class APIKeySerializer(serializers.ModelSerializer):
|
|
"""Serializer for API keys."""
|
|
class Meta:
|
|
model = APIKey
|
|
fields = ('id', 'name', 'key', 'is_active', 'last_used', 'created_at', 'expires_at')
|
|
read_only_fields = ('id', 'key', 'last_used', 'created_at')
|
|
|
|
def create(self, validated_data):
|
|
validated_data['key'] = secrets.token_urlsafe(32)
|
|
return super().create(validated_data)
|
|
|
|
|
|
class APIKeyCreateSerializer(serializers.ModelSerializer):
|
|
"""Serializer for creating API keys."""
|
|
class Meta:
|
|
model = APIKey
|
|
fields = ('name', 'expires_at')
|
|
|
|
def create(self, validated_data):
|
|
validated_data['user'] = self.context['request'].user
|
|
validated_data['key'] = secrets.token_urlsafe(32)
|
|
return super().create(validated_data)
|
|
|
|
|
|
class SubscriptionUpdateSerializer(serializers.Serializer):
|
|
"""Serializer for updating user subscription."""
|
|
subscription_type = serializers.ChoiceField(choices=[
|
|
('free', 'Free'),
|
|
('paid', 'Paid'),
|
|
('premium', 'Premium'),
|
|
])
|
|
|
|
def validate_subscription_type(self, value):
|
|
user = self.context['request'].user
|
|
if user.subscription_type == value:
|
|
raise serializers.ValidationError('User already has this subscription type.')
|
|
return value
|
|
|