Is it possible to disable Django two-factor authentication with a setting?

I'm trying to write a LiveServerTestCase for a website which is protected with Django Two-Factor Authentication. What I have so far is:

import os from urllib.parse import urljoin from django.urls import reverse from django.conf import settings from lucy_web.test_factories import UserFactory from django.contrib.staticfiles.testing import StaticLiveServerTestCase from selenium import webdriver chromedriver_path = os.path.join(os.path.dirname(os.path.dirname(settings.BASE_DIR)), 'chromedriver') assert os.path.isfile(chromedriver_path), f"There should be a chromedriver executable at {chromedriver_path}" class SeleniumTest(StaticLiveServerTestCase): @classmethod def setUpClass(cls): super().setUpClass() cls.driver = webdriver.Chrome(chromedriver_path) cls.password = 'foobar' # Set the password here to avoid using the hashed attribute cls.user = UserFactory(password=cls.password, is_superuser=True) def test_login(self): url = urljoin(self.live_server_url, reverse('dashboard:families')) self.driver.get(url) self.driver.find_element_by_name('auth-username').send_keys(self.user.username) self.driver.find_element_by_name('auth-password').send_keys(self.password) self.driver.find_element_by_xpath('//input[@value="Next"]').click()

The problem is that at this point, the driver arrives at a two-factor authentication login page in which it is required to scan a QR code:

<img src=https://www.e-learn.cn/content/wangluowenzhang/"https://i.stack.imgur.com/TXp33.jpg" alt="enter image description here">

This is too involved to do using the test browser, so I'd like to use override_settings to disable the two-factor authentication for testing purposes. However, looking at the General Settings of Django two-factor authentication, I wasn't able to find a setting which disables it.

Is there any way I could disable two-factor authentication to continue with this live server test case?

Answer1:

There is no built-in functionality to do this, but you can easily accomplish it by extending the middleware. Just swap "OTPMiddleware" in your settings with the full dotted path to this one, and change DEBUG to some other variable if you like.

from django_otp import DEVICE_ID_SESSION_KEY, _user_is_authenticated from django_otp.models import Device from django_otp.middleware import OTPMiddleware, is_verified from django.conf import settings class ToggleableOTPMiddleware(OTPMiddleware): def _verify_user(self, request, user): """ Sets OTP-related fields on an authenticated user. """ user.otp_device = None # START CHANGE if settings.DEBUG: user.is_verified = lambda: True else: user.is_verified = functools.partial(is_verified, user) # END CHANGE if _user_is_authenticated(user): persistent_id = request.session.get(DEVICE_ID_SESSION_KEY) device = self._device_from_persistent_id(persistent_id) if persistent_id else None if (device is not None) and (device.user_id != user.id): device = None if (device is None) and (DEVICE_ID_SESSION_KEY in request.session): del request.session[DEVICE_ID_SESSION_KEY] user.otp_device = device return user

人吐槽 人点赞

Recommend

Comment

用户名: 密码:
验证码: 匿名发表

你可以使用这些语言

查看评论:Is it possible to disable Django two-factor authentication with a setting?