Тестовый вход пользователя DRF, ошибка неактивного пользователя

У меня есть вид для аутентификации:

class UserViewSet(viewsets.ViewSet):
    @method_decorator(sensitive_variables("password"))
    @action(url_path="sign-in", detail=False, methods=["POST"])
    def sign_in(self, request: HttpRequest) -> Response:
        if not request.user.is_anonymous:
            return Response({"status": "forbidden"}, status=403)

        form = AuthenticationForm(data=request.data)
        print(form.data)
        if form.is_valid():
            user = authenticate(request, **form.cleaned_data)
            login(request, user)
            return Response({"status": "ok"}, status=200)
        print(form.error_messages)
        raise ValidationError(form.errors)

Я пишу тест:

class UserTest(TestCase):
    @classmethod
    def setUpClass(cls):
        User.objects.create(username="admin", password="Qwerty1234", is_active=True)
        super().setUpClass()
        cls.client = Client()

    @classmethod
    def tearDownClass(cls):
        return super().tearDownClass()

    def test_sign_in(self):
        url = "/api/sign-in/"
        print(User.objects.get(username="admin").is_active)
        response = self.client.post(
            url,
            data={"username": "admin", "password": "Qwerty1234"},
            content_type="application/json",
        )

Но я получаю ошибки от form form_validator:

{'invalid_login': 'Please enter a correct %(username)s and password. Note that both fields may be case-sensitive.', 'inactive': 'This account is inactive.'} 

Что может быть проблемой?

P.S. Есть ли смысл в таком случае использовать sensitive_variables?

мне кажется, что проблема заключается в хэшировании пароля, когда вы создаете пользователя напрямую, используя метод User.objects.create(username="admin", password="Qwerty1234", is_active=True), пароль не хэшируется, django хранит пароли в хэшированном формате, поэтому пароль должен быть установлен с помощью метода set_password, поэтому нам нужно использовать set_password, чтобы правильно хэшировать пароль, а затем сохранить пользователя после установки пароля

поэтому ваш viwe-код должен выглядеть следующим образом:

class UserViewSet(viewsets.ViewSet):
    @method_decorator(sensitive_variables("password"))
    @action(url_path="sign-in", detail=False, methods=["POST"])
    def sign_in(self, request: HttpRequest) -> Response:
        if not request.user.is_anonymous:
            return Response({"status": "forbidden"}, status=403)

        form = AuthenticationForm(data=request.data)
        print(form.data)
        if form.is_valid():
            user = authenticate(request, **form.cleaned_data)
            if user is not None:
                login(request, user)
                return Response({"status": "ok"}, status=200)
        print(form.error_messages)
        raise ValidationError(form.errors)

и ваш тестовый код должен выглядеть следующим образом:

class UserTest(TestCase):
    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        user = User.objects.create(username="admin", is_active=True)
        user.set_password("Qwerty1234")
        user.save()
        cls.client = Client()

    @classmethod
    def tearDownClass(cls):
        return super().tearDownClass()

    def test_sign_in(self):
        url = "/api/sign-in/"
        print(User.objects.get(username="admin").is_active)
        response = self.client.post(
            url,
            data={"username": "admin", "password": "Qwerty1234"},
            content_type="application/json",
        )
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.json(), {"status": "ok"})

sensitive_variables используется для пометки определенных переменных как чувствительных, чтобы их значения не включались в отчеты об ошибках, что может быть полезно в производстве, чтобы избежать записи в журнал конфиденциальной информации, например паролей.

Надеюсь, это поможет вам.

Вернуться на верх