Можно ли отключить двухфакторную аутентификацию Django с настройкой? - PullRequest
0 голосов
/ 02 мая 2018

Я пытаюсь написать LiveServerTestCase для веб-сайта, который защищен двухфакторной аутентификацией Django . То, что у меня пока есть:

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, я не смог найти параметр, который отключает его.

Можно ли как-нибудь отключить двухфакторную аутентификацию, чтобы продолжить этот тестовый пример с живым сервером?

1 Ответ

0 голосов
/ 02 мая 2018

Для этого нет встроенных функций, но вы можете легко сделать это, расширив промежуточное программное обеспечение. Просто замените «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
...