from typing import List from django.conf import settings from django.contrib.auth import get_user_model from django.contrib.auth.password_validation import get_password_validators, validate_password from rest_framework import serializers from rest_framework.exceptions import ValidationError from rest_framework_simplejwt.serializers import TokenObtainPairSerializer User = get_user_model() AUTH_PASSWORD_VALIDATORS = getattr(settings, 'AUTH_PASSWORD_VALIDATORS') class UserSerializer(serializers.ModelSerializer): permissions = serializers.SerializerMethodField() def get_permissions(self, obj: User) -> List[str]: group_permissions = obj.get_group_permissions() user_permissions = obj.get_user_permissions() return sorted(user_permissions.union(group_permissions)) class Meta: model = User fields = ( 'username', 'email', 'first_name', 'last_name', 'is_staff', 'is_superuser', 'permissions', ) read_only_fields = ('username', 'code', 'is_staff', 'is_superuser', 'permissions', ) class UpdatePasswordSerializer(serializers.ModelSerializer): old_password = serializers.CharField(write_only=True) new_password = serializers.CharField(write_only=True) new_password2 = serializers.CharField(write_only=True) def validate_old_password(self, password): user = self.context.get('request').user if not user.check_password(password): raise ValidationError('Wrong old password') return password def validate_new_password(self, password): old_password = self.context.get('request').data.get('old_password') if password == old_password: raise ValidationError('Password can\'t be the same as the old one') password2 = self.context.get('request').data.get('new_password2') if password != password2: raise ValidationError('Password mismatch') validate_password(password, password_validators=get_password_validators(AUTH_PASSWORD_VALIDATORS)) return password def save(self, *args, **kwargs): new_password = self.validated_data.get('new_password') self.instance.set_password(new_password) self.instance.save() class Meta: model = User fields = ('old_password', 'new_password', 'new_password2', )