Django-oauth-toolkit : Тестирование пользовательского TokenView
Я пытаюсь написать модульный тест для пользовательской реализации django-oauth-toolkit TokenView
Причина наследования от TokenView заключается в том, чтобы потребовать токен 2FA перед генерацией токена доступа.
Ниже показано, как выглядит вид
class CustomTokenView(TokenView):
@method_decorator(sensitive_post_parameters("password"))
def post(self, request, *args, **kwargs):
meta = request.META
grant_type = urllib.parse.parse_qs(request.body.decode("utf-8")).get("grant_type")[0]
if grant_type == "password":
"""
Users trying to log in with email and password.
"""
try:
email = urllib.parse.parse_qs(request.body.decode("utf-8"))["username"][0]
except KeyError:
return JsonResponse(data={"message": "Email is required", "status": "0"}, status=400)
try:
token = urllib.parse.parse_qs(request.body.decode("utf-8"))["token"][0]
except KeyError:
return JsonResponse(data={"message": "Token is required", "status": "0"}, status=400)
email = simplefunctions.remove_unicode(email)
user_obj = CustomUser.objects.filter(
email=email, is_active=True,
is_staff=True,
is_account_disabled=False).first()
if user_obj is None:
return JsonResponse(data={"message": "Invalid Email", "status": "0"}, status=400)
else:
application_log.debug(f"User {user_obj.email} tried to login with password. Request header data {meta}")
if token:
if not services.UserService.is_valid_2fa_token(user_obj, token):
return JsonResponse(data={"message": "Invalid Token", "status": "0"}, status=400)
return super().post(request, *args, **kwargs)
return JsonResponse(data={"message": "Invalid grant type", "status": "0"}, status=400)
Я могу извлечь данные каждого запроса и выполнить их валидацию.
но возвращается ошибка, когда вызывается return super().post(request, *args, **kwargs).
Как выглядит мой тест
from oauth2_provider.settings import oauth2_settings
from oauth2_provider.models import get_access_token_model, get_application_model
from django.contrib.auth import get_user_model
from django.utils import timezone
Application = get_application_model()
AccessToken = get_access_token_model()
UserModel = get_user_model()
class AdminAuthTests(APITestCase):
def setUp(self):
self.admin_user = UserFactory()
self.admin_user.is_staff = True
# self.admin_user.set_password("test_password")
set_pin_hash(self.admin_user, "1234")
self.admin_user.save()
self.rogue_user = UserFactory()
SecurityQuestionFactory.create(question="Mother's maiden name")
SecurityQuestionFactory.create(question="Favorite Food")
oauth2_settings._SCOPES = ["read", "write", "scope1", "scope2", "resource1"]
self.application = Application.objects.create(
name="Test Application",
client_type="public",
authorization_grant_type="password"
)
@patch('users.views.admin_auth_views.services.UserService.is_valid_2fa_token')
def test_can_login_with_2fa(self, mock_is_valid_2fa_token):
"""
The user should be able to log in with 2fa
"""
mock_is_valid_2fa_token.return_value = True
self.url = reverse("api-v2:token")
payload = {
"client_id": self.application.client_id,
"username": self.admin_user.email,
"grant_type": "password",
"token": "123456",
"password": "test_password",
}
data = urllib.parse.urlencode(payload).encode()
res = self.client.post(self.url, data=data, format="json")
res_json = res.json()
print(data)
print(res_json)
mock_is_valid_2fa_token.assert_called_once()
self.assertEqual(res.status_code, status.HTTP_200_OK)
Сообщение об ошибке
{'error': 'unsupported_grant_type'}
Я занимаюсь этим уже несколько дней и буду благодарен, если кто-то сможет дать мне несколько советов.