old_console/users/serializers.py
2024-11-02 14:12:45 +03:00

142 lines
5.9 KiB
Python

from django.contrib.auth.hashers import check_password
from django.contrib.auth.models import User
from django.core.exceptions import ObjectDoesNotExist
from rest_framework.exceptions import ValidationError
from core import serializers
from users.models import UserInfo
from users.services.userinfo import UserStatusService
from users.services.validators import timezone_validation, password_validation, validate_expire_date, \
OnlyCharNumericValidator
"""The presence of 2 duplicate serilizers (UsersListSerializer,UserInfoListSerializer)
is made for the quick release of functionality. The reason is hiding the password from the output
of the list of users"""
class UserSerializers(serializers.ModelSerializer):
username = serializers.CharField(),
old_password = serializers.CharField(required=False)
def to_representation(self, instance):
return {
'id': instance.id,
'username': instance.username,
'first_name': instance.first_name,
"email": instance.email,
'is_active': instance.is_active
}
class Meta:
model = User
fields = ('id', 'username', 'first_name', 'is_active', "password", "email", "old_password")
extra_kwargs = {
'username': {
'validators': [],
'max_length': 131 # 150 chars in the model, but after deleting we added 19 chars
},
'first_name': {
'required': True,
'allow_blank': False
},
'email': {
'required': True,
'allow_blank': False
}
}
class UserInfoSerializer(serializers.ModelLocalizedSerializer):
user = UserSerializers(required=True, many=False)
user_status = serializers.SerializerMethodField()
def get_user_status(self, user_info: UserInfo) -> str:
return UserStatusService(user_info.user).get_status()
def create(self, validated_data):
"""TODO !!! Important !!!! Until the role model is developed, all created users are admins"""
if "password" in validated_data["user"]:
from django.contrib.auth.hashers import make_password
validated_data["user"]["password"] = make_password(validated_data["user"]["password"])
validated_data["user"]["is_staff"] = True
validated_data["user"]["is_superuser"] = True
new_user = User.objects.create(**validated_data["user"])
else:
new_user = User.objects.create(**validated_data["user"])
user_info = None
if new_user:
user_info = UserInfo.objects.create(user=new_user, comment=validated_data.get("comment"),
timezone=validated_data.get("timezone"),
expire_date=validated_data.get('expire_date'))
return user_info
def validate_user(self, user):
username = user['username']
OnlyCharNumericValidator.validate(username)
try:
user = User.objects.get(username=username)
raise ValidationError(f"User {username} already exists")
except ObjectDoesNotExist:
return user
def validate(self, data):
timezone_validation(data)
password_validation(data)
validate_expire_date(data)
return data
class Meta:
model = UserInfo
fields = "__all__"
class UserInfoUpdateSerializer(serializers.ModelLocalizedSerializer):
user = UserSerializers(required=False)
def update(self, instance, validated_data):
try:
users_data = validated_data.pop('user')
instance.comment = validated_data.get('comment', instance.comment)
instance.timezone = validated_data.get("timezone", instance.timezone)
instance.expire_date = validated_data.get("expire_date", instance.expire_date)
instance.save()
user = instance.user
user.username = users_data.get('username', user.username)
user.first_name = users_data.get("first_name", user.first_name)
user.is_active = users_data.get("is_active", user.is_active)
user.email = users_data.get("email", user.email)
user.save()
if users_data.get("password", None):
user.set_password(users_data.get("password"))
user.save()
except KeyError:
instance.comment = validated_data.get('comment', instance.comment)
instance.timezone = validated_data.get("timezone", instance.timezone)
instance.expire_date = validated_data.get("expire_date", instance.expire_date)
instance.save()
user = instance.user
user.save()
return instance
def validate(self, data):
"""validate data"""
timezone_validation(data)
password_validation(data)
validate_expire_date(data)
if 'user' not in data:
raise ValidationError({'status': 'error', 'detail': "Invalid request format"})
if 'password' in data['user']:
if check_password(data['user']['password'], self.instance.user.password):
raise ValidationError({'status': 'error', 'detail': 'The password must be different from '
'the previous one'})
if (self.instance.user == self.context['request'].user and
not check_password(data['user'].get('old_password', ''), self.instance.user.password)):
raise ValidationError({'status': 'error', 'detail': 'Provide correct old password'})
if 'is_active' in data['user']:
if self.context['request'].user == self.instance.user and not data['user']['is_active']:
raise ValidationError({'status': 'error', 'detail': "You can't disable your account"})
return data
class Meta:
model = UserInfo
fields = "__all__"