100 lines
2.7 KiB
Python
100 lines
2.7 KiB
Python
from django.contrib.auth import get_user_model
|
||
from django.db import transaction
|
||
from django.utils import timezone
|
||
from rest_framework import serializers
|
||
|
||
from .models import Invitation
|
||
|
||
|
||
User = get_user_model()
|
||
|
||
|
||
class UserSerializer(serializers.ModelSerializer):
|
||
is_admin = serializers.SerializerMethodField()
|
||
|
||
class Meta:
|
||
model = User
|
||
fields = [
|
||
'id',
|
||
'username',
|
||
'first_name',
|
||
'last_name',
|
||
'email',
|
||
'is_active',
|
||
'is_staff',
|
||
'is_superuser',
|
||
'is_admin',
|
||
'date_joined',
|
||
'color',
|
||
]
|
||
read_only_fields = ['id', 'date_joined', 'is_admin']
|
||
|
||
def get_is_admin(self, obj):
|
||
return obj.is_superuser or obj.is_staff
|
||
|
||
|
||
class RegisterSerializer(serializers.ModelSerializer):
|
||
password = serializers.CharField(write_only=True)
|
||
password_confirm = serializers.CharField(write_only=True)
|
||
invite = serializers.UUIDField(write_only=True)
|
||
|
||
class Meta:
|
||
model = User
|
||
fields = [
|
||
'username',
|
||
'password',
|
||
'password_confirm',
|
||
'first_name',
|
||
'last_name',
|
||
'invite',
|
||
]
|
||
|
||
def validate(self, attrs):
|
||
if attrs['password'] != attrs['password_confirm']:
|
||
raise serializers.ValidationError({
|
||
'password_confirm': (
|
||
'Les mots de passe ne correspondent pas.'
|
||
)
|
||
})
|
||
|
||
return attrs
|
||
|
||
def validate_invite(self, value):
|
||
try:
|
||
invitation = Invitation.objects.get(token=value)
|
||
except Invitation.DoesNotExist as error:
|
||
raise serializers.ValidationError(
|
||
'Ce lien d’invitation est invalide.'
|
||
) from error
|
||
|
||
if not invitation.is_valid:
|
||
raise serializers.ValidationError(
|
||
'Ce lien d’invitation est expiré ou déjà utilisé.'
|
||
)
|
||
|
||
return value
|
||
|
||
def create(self, validated_data):
|
||
invitation_token = validated_data.pop('invite')
|
||
validated_data.pop('password_confirm')
|
||
|
||
with transaction.atomic():
|
||
invitation = (
|
||
Invitation.objects
|
||
.select_for_update()
|
||
.get(token=invitation_token)
|
||
)
|
||
|
||
if not invitation.is_valid:
|
||
raise serializers.ValidationError({
|
||
'invite': (
|
||
'Ce lien d’invitation est expiré ou déjà utilisé.'
|
||
)
|
||
})
|
||
|
||
user = User.objects.create_user(**validated_data)
|
||
|
||
invitation.used_at = timezone.now()
|
||
invitation.save(update_fields=['used_at'])
|
||
|
||
return user |