是否可以通过设置禁用Django双因素身份验证?

时间:2018-05-01 22:32:35

标签: django selenium two-factor-authentication

我正在尝试为LiveServerTestCase保护的网站撰写Django Two-Factor Authentication。到目前为止我所拥有的是:

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()

问题在于,此时,驱动程序到达双因素身份验证登录页面,在该页面中需要扫描QR码:

enter image description here

使用测试浏览器过于复杂,所以我想使用override_settings禁用双因素身份验证以进行测试。但是,查看Django双因素身份验证的General Settings,我无法找到禁用它的设置。

有什么办法可以禁用双因素身份验证来继续这个实时服务器测试用例吗?

1 个答案:

答案 0 :(得分:1)

没有内置功能可以执行此操作,但您可以通过扩展中间件轻松完成此操作。只需将您设置中的“OTPMiddleware”与完整的虚线路径交换,然后根据需要将DEBUG更改为其他变量。

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