diff --git a/src/objecttypes/accounts/tests/test_2fa.py b/src/objecttypes/accounts/tests/test_2fa.py new file mode 100644 index 00000000..730e7e99 --- /dev/null +++ b/src/objecttypes/accounts/tests/test_2fa.py @@ -0,0 +1,23 @@ +from django.contrib.sites.models import Site +from django.test import RequestFactory, TestCase, override_settings +from django.urls import resolve + + +@override_settings(ALLOWED_HOSTS=["some-domain.local"], DISABLE_2FA=False) +class TwoFactorQRGeneratorTestCase(TestCase): + def test_qr_code_generator_does_not_use_sites_framework(self): + """ + Regression test for https://github.com/maykinmedia/open-api-framework/issues/40 + Testing the actual QR code output is too much of a hassle, so instead retrieve + the view class based on the URL and check if `get_issuer` behaves as expected + """ + site = Site.objects.get_current() + site.domain = "testserver" + site.save() + + qr_generator_view_class = resolve("/admin/mfa/qrcode/").func.view_class + issuer = qr_generator_view_class( + request=RequestFactory().get("/", headers={"Host": "some-domain.local"}) + ).get_issuer() + + self.assertEqual(issuer, "some-domain.local") diff --git a/src/objecttypes/accounts/views.py b/src/objecttypes/accounts/views.py new file mode 100644 index 00000000..0d9ef35e --- /dev/null +++ b/src/objecttypes/accounts/views.py @@ -0,0 +1,8 @@ +from django.contrib.sites.requests import RequestSite + +from maykin_2fa.views import QRGeneratorView as _QRGeneratorView + + +class QRGeneratorView(_QRGeneratorView): + def get_issuer(self): + return RequestSite(self.request).name diff --git a/src/objecttypes/urls.py b/src/objecttypes/urls.py index 342de18e..5f6e6ce9 100644 --- a/src/objecttypes/urls.py +++ b/src/objecttypes/urls.py @@ -12,6 +12,8 @@ from mozilla_django_oidc_db.views import AdminLoginFailure from rest_framework.settings import api_settings +from objecttypes.accounts.views import QRGeneratorView + handler500 = "objecttypes.utils.views.server_error" admin.site.site_header = "objecttypes admin" admin.site.site_title = "objecttypes admin" @@ -31,6 +33,11 @@ name="password_reset_done", ), path("admin/login/failure/", AdminLoginFailure.as_view(), name="admin-oidc-error"), + # See https://github.com/maykinmedia/open-api-framework/issues/40 + # and https://github.com/maykinmedia/open-api-framework/issues/59 + # Temporary workaround to remove the dependency on `django.contrib.sites` when + # generating the app label for 2FA. This should be removed once `sites` are removed + path("admin/mfa/qrcode/", QRGeneratorView.as_view(), name="qr"), path("admin/", include((maykin_2fa_urlpatterns, "maykin_2fa"))), path("admin/", include((webauthn_urlpatterns, "two_factor"))), path("admin/", admin.site.urls),