Расширение django-graphql-auth для ограничения имени пользователя, паролей и электронной почты

Я использую Django v 3.2 и django-graphql-auth v 0.3.16

У меня есть пользовательский пользователь (и менеджер пользователей), определенный следующим образом:

models.py

class CustomUser(AbstractUser):
    USERNAME_FIELD='username'
    EMAIL_FIELD='email'
    # ...

    objects = CustomUserManager()

managers.py

class CustomUserManager(BaseUserManager):
    # ...
    def create_user(self, email, password, **extra_fields):
        if not is_valid_email(email):
            raise ValueError(_('Bad email'))

        username = extra_fields.get('username')

        if not is_acceptable_username(username)):
            raise ValueError(_('You cannot use this username'))

        user = self.model(email=email, **extra_fields)
        user.set_password(password)
        user.save()

        return user       


    def create_superuser(self, email, password, **extra_fields):
        """
        Create and save a SuperUser with the given email and password.
        """
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        extra_fields.setdefault('is_active', True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError(_('Superuser must have is_staff=True.'))
        if extra_fields.get('is_superuser') is not True:
            raise ValueError(_('Superuser must have is_superuser=True.'))

        return self.create_user(email, password, **extra_fields)

settings.py

# ....
AUTH_USER_MODEL='myapp.CustomUser'

schema.py

import graphene
from graphql_auth import mutations
from graphql_auth.schema import MeQuery, UserQuery



class AuthMutation(graphene.ObjectType):
    register = mutations.Register.Field()
    verify_account = mutations.VerifyAccount.Field()


class Query(UserQuery, MeQuery, graphene.ObjectType):
    pass


class Mutation(AuthMutation, graphene.ObjectType):
    pass


schema = graphene.Schema(query=Query, mutation=Mutation)

Я пытаюсь зарегистрировать нового пользователя через следующую мутацию:

mutation {
  register(
        email: "memyself@somebad-domain.com",
      username: "badword1",
      password1: "1234",
      password2: "1234"
  ) {
    success
    errors
    token
  }
}

И я получаю следующий ответ:

{
  "data": {
    "register": {
      "success": true,
      "errors": null,
      "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImJhZHdvcmQxIiwiZXhwIjoxNjY5OTEzNDIzLCJvcmlnSWF0IjoxNjY5OTEzMTIzfQ.TZ-copVrhUUsuLpozi18THjprGMnAGsBwpnyWORc16M"
    }
  }
}

Ожидаемым результатом будет то, что мутация GraphQL вернет код отказа, основанный на электронной почте, имени пользователя и пароле - все они были указаны специально, чтобы быть отвергнутыми.

Почему django-graphql-auth не использует мой пользовательский менеджер для создания объектов - и как мне исправить это, чтобы я мог реализовать свои собственные валидации (например, для правильной проверки/валидации имени пользователя и email)?

Похоже, что вы определили свою собственную модель CustomUser и CustomUserManager, но не используете их в файле schema.py. Чтобы использовать пользовательскую модель пользователя и менеджер, вам нужно указать их при создании класса AuthMutation в файле schema.py.

Вот пример того, как можно указать пользовательскую модель и менеджера при создании класса AuthMutation:

import graphene
from graphql_auth import mutations
from graphql_auth.schema import MeQuery, UserQuery
from myapp.models import CustomUser
from myapp.managers import CustomUserManager

class AuthMutation(graphene.ObjectType):
    register = mutations.Register.Field(
        user_model=CustomUser,
        user_manager=CustomUserManager
    )
    verify_account = mutations.VerifyAccount.Field()

class Query(UserQuery, MeQuery, graphene.ObjectType):
    pass

class Mutation(AuthMutation, graphene.ObjectType):
    pass

schema = graphene.Schema(query=Query, mutation=Mutation)

Указав вашу пользовательскую модель пользователя и менеджера при создании класса AuthMutation, django-graphql-auth будет использовать вашу пользовательскую реализацию методов create_user и create_superuser при обработке мутации регистра. Это позволит применять вашу пользовательскую проверку при создании новых пользователей.

Надеюсь, это поможет! Дайте мне знать, если у вас возникнут другие вопросы.

Django и django-graphql-auth использует ваш CustomUserManager наверняка. Но, django-graphql-auth использует метод модели save(...) для создания объекта.

Вот как происходит выполнение -

  1. Инициирует Register и таким образом RegisterMixin
  2. Вызывает Register.resolve_mutation(...) и инициализирует RegisterForm
  3. Вызывает метод save() формы и вызывает метод save() модели и таким образом был создан новый User объект.

Как я могу проверить данные?

Я бы рассмотрел возможность создания подкласса Register и переопределения метода resolve_mutation(...).

import graphene
from graphql_auth import mutations


class CustomRegister(mutations.Register):
    @classmethod
    def resolve_mutation(cls, root, info, **kwargs):
        # do some validations here
        # Example -
        username = kwargs.get("username")
        if username == "admin":
            return cls(success=False, errors="Nice error message")

        return super().resolve_mutation(root, info, **kwargs)

и затем, я бы определил это CustomRegister в AuthMutation

class AuthMutation(graphene.ObjectType):
    register = CustomRegister.Field()
Вернуться на верх