You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

221 lines
7.2 KiB

from django.contrib.auth import get_user_model
from django.contrib.auth.password_validation import validate_password
from rest_framework import serializers
from rest_framework_simplejwt.tokens import RefreshToken
from phonenumber_field.serializerfields import PhoneNumberField
from apps.account.models.verification import VerificationDocument
User = get_user_model()
class RegisterRequestSerializer(serializers.Serializer):
email = serializers.EmailField(required=True)
password = serializers.CharField(write_only=True, required=True, min_length=6)
fullname = serializers.CharField(required=True, max_length=255)
phone_number = serializers.CharField(required=False, allow_blank=True, allow_null=True)
user_type = serializers.ChoiceField(
choices=User.UserType.choices,
default=User.UserType.CLIENT,
required=False
)
languages = serializers.ListField(
child=serializers.CharField(max_length=10),
required=False,
default=list
)
skills = serializers.ListField(
child=serializers.CharField(max_length=100),
required=False,
default=list
)
country = serializers.CharField(required=False, allow_blank=True, max_length=255)
city = serializers.CharField(required=False, allow_blank=True, max_length=255)
def validate_email(self, value):
normalized = value.strip().lower()
if User.objects.filter(email__iexact=normalized).exists():
raise serializers.ValidationError("A user with this email address already exists.")
return normalized
def validate_password(self, value):
validate_password(value)
return value
def create(self, validated_data):
email = validated_data.pop('email')
password = validated_data.pop('password')
fullname = validated_data.pop('fullname')
user_type = validated_data.pop('user_type', User.UserType.CLIENT)
user = User.objects.create_user(
email=email,
password=password,
fullname=fullname,
username=email,
user_type=user_type,
**validated_data
)
return user
class UserMeSerializer(serializers.ModelSerializer):
bio = serializers.CharField(source='info', allow_blank=True, required=False, allow_null=True)
roles = serializers.SerializerMethodField()
permissions = serializers.SerializerMethodField()
verification_status = serializers.SerializerMethodField()
is_verified = serializers.SerializerMethodField()
class Meta:
model = User
fields = [
'id',
'email',
'username',
'fullname',
'phone_number',
'user_type',
'avatar',
'bio',
'languages',
'skills',
'country',
'city',
'gender',
'birthdate',
'date_joined',
'is_active',
'is_staff',
'roles',
'permissions',
'verification_status',
'is_verified',
]
read_only_fields = [
'id',
'email',
'username',
'user_type',
'date_joined',
'is_active',
'is_staff',
'roles',
'permissions',
'verification_status',
'is_verified',
]
def get_roles(self, obj) -> list:
roles = [obj.user_type] if obj.user_type else []
for group in obj.groups.all():
roles.append(group.name)
return list(set(roles))
def get_permissions(self, obj) -> list:
perms = []
if obj.is_super_admin:
perms.extend(['super_admin', 'manage_all', 'manage_institutions', 'manage_users', 'manage_content', 'approve_verifications'])
elif obj.is_regional_admin:
perms.extend(['regional_admin', 'manage_regional_institutions', 'manage_content', 'approve_verifications'])
elif obj.is_institution_admin:
perms.extend(['institution_admin', 'manage_institution_profile', 'manage_team', 'manage_events', 'manage_projects'])
elif obj.is_editor:
perms.extend(['editor', 'create_posts', 'manage_events', 'edit_projects'])
else:
perms.extend(['client_access', 'view_courses', 'submit_tickets', 'attend_events'])
return perms
def get_verification_status(self, obj) -> str:
return obj.verification_status
def get_is_verified(self, obj) -> bool:
return obj.verification_status == VerificationDocument.Status.VERIFIED
class UserMeUpdateSerializer(serializers.ModelSerializer):
bio = serializers.CharField(source='info', allow_blank=True, required=False, allow_null=True)
class Meta:
model = User
fields = [
'fullname',
'phone_number',
'avatar',
'bio',
'languages',
'skills',
'country',
'city',
'gender',
'birthdate',
]
def update(self, instance, validated_data):
for attr, value in validated_data.items():
setattr(instance, attr, value)
instance.save()
return instance
class RegisterResponseSerializer(serializers.Serializer):
user = UserMeSerializer()
access = serializers.CharField()
refresh = serializers.CharField()
message = serializers.CharField()
class VerificationDocumentSerializer(serializers.ModelSerializer):
document_type_display = serializers.CharField(source='get_document_type_display', read_only=True)
status_display = serializers.CharField(source='get_status_display', read_only=True)
reviewed_by_email = serializers.EmailField(source='reviewed_by.email', read_only=True, allow_null=True)
class Meta:
model = VerificationDocument
fields = [
'id',
'user',
'document_type',
'document_type_display',
'title',
'document_file',
'status',
'status_display',
'admin_notes',
'reviewed_by_email',
'uploaded_at',
'reviewed_at',
]
read_only_fields = [
'id',
'user',
'document_type_display',
'status',
'status_display',
'admin_notes',
'reviewed_by_email',
'uploaded_at',
'reviewed_at',
]
class VerificationDocumentUploadSerializer(serializers.Serializer):
document_type = serializers.ChoiceField(
choices=VerificationDocument.DocumentType.choices,
default=VerificationDocument.DocumentType.NATIONAL_ID
)
title = serializers.CharField(required=False, allow_blank=True, max_length=255)
document_file = serializers.FileField(required=True)
class PasswordRecoverRequestSerializer(serializers.Serializer):
email = serializers.EmailField(required=True)
class PasswordResetRequestSerializer(serializers.Serializer):
email = serializers.EmailField(required=True)
token = serializers.CharField(required=True)
new_password = serializers.CharField(required=True, min_length=6)
def validate_new_password(self, value):
validate_password(value)
return value