47 lines
2.1 KiB
Python
47 lines
2.1 KiB
Python
|
from django.conf import settings
|
||
|
from django.contrib.auth import REDIRECT_FIELD_NAME
|
||
|
from django.contrib.auth.views import redirect_to_login
|
||
|
from django.http import HttpResponseRedirect
|
||
|
from django.shortcuts import resolve_url
|
||
|
from django.urls import reverse
|
||
|
from django.utils.http import url_has_allowed_host_and_scheme # renamed Dj^3.*
|
||
|
from two_factor.admin import AdminSiteOTPRequired, AdminSiteOTPRequiredMixin
|
||
|
|
||
|
|
||
|
# https://stackoverflow.com/questions/48600737/django-two-factor-auth-cant-access-admin-site
|
||
|
class AdminSiteOTPRequiredMixinRedirectSetup(AdminSiteOTPRequired):
|
||
|
"""
|
||
|
Fixes the current implementation of django-two-factor-auth = 1.15.3
|
||
|
when admin page is patched for 2fa
|
||
|
(circular redirect - super user created with manage.py
|
||
|
and cannot log in because he does not have a device configured).
|
||
|
The class redirects to the setup page.
|
||
|
After that, you can log in as usual.
|
||
|
"""
|
||
|
def login(self, request, extra_context=None):
|
||
|
redirect_to = request.POST.get(
|
||
|
REDIRECT_FIELD_NAME, request.GET.get(REDIRECT_FIELD_NAME)
|
||
|
)
|
||
|
# For users not yet verified the AdminSiteOTPRequired.has_permission
|
||
|
# will fail. So use the standard admin has_permission check:
|
||
|
# (is_active and is_staff) and then check for verification.
|
||
|
# Go to index if they pass, otherwise make them setup OTP device.
|
||
|
if request.method == "GET" and super(
|
||
|
AdminSiteOTPRequiredMixin, self
|
||
|
).has_permission(request):
|
||
|
# Already logged-in and verified by OTP
|
||
|
if request.user.is_verified():
|
||
|
# User has permission
|
||
|
index_path = reverse("admin:index", current_app=self.name)
|
||
|
else:
|
||
|
# User has permission but no OTP set:
|
||
|
index_path = reverse("two_factor:setup", current_app=self.name)
|
||
|
return HttpResponseRedirect(index_path)
|
||
|
|
||
|
if not redirect_to or not url_has_allowed_host_and_scheme(
|
||
|
url=redirect_to, allowed_hosts=[request.get_host()]
|
||
|
):
|
||
|
redirect_to = resolve_url(settings.LOGIN_REDIRECT_URL)
|
||
|
|
||
|
return redirect_to_login(redirect_to)
|