django-mfa3

multi factor authentication for django
git clone https://git.ce9e.org/django-mfa3.git

commit
7be4d3088d50c5ae6c23212b068bb20fb95800dd
parent
072e8db8f47a76c8c728ff472cb74e782b68e5b6
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2024-06-18 17:26
django 5.1: support LoginRequiredMiddleware

Diffstat

M mfa/admin.py 2 ++
M mfa/decorators.py 13 +++++++++++++
M mfa/views.py 11 ++++-------
M tests/settings.py 5 +++++

4 files changed, 24 insertions, 7 deletions


diff --git a/mfa/admin.py b/mfa/admin.py

@@ -3,9 +3,11 @@ from django.contrib.auth import REDIRECT_FIELD_NAME
    3     3 from django.contrib.auth.views import redirect_to_login
    4     4 from django.urls import reverse
    5     5 
   -1     6 from .decorators import login_not_required
    6     7 from .models import MFAKey
    7     8 
    8     9 
   -1    10 @login_not_required
    9    11 def custom_login(self, request, extra_context=None):
   10    12     next_url = (
   11    13         request.GET.get(REDIRECT_FIELD_NAME)

diff --git a/mfa/decorators.py b/mfa/decorators.py

@@ -1,3 +1,16 @@
   -1     1 try:
   -1     2     from stronghold.decorators import public as stronghold_login_not_required
   -1     3 except ImportError:
   -1     4     def stronghold_login_not_required(view_func):
   -1     5         return view_func
   -1     6 
   -1     7 try:
   -1     8     from django.contrib.auth.decorators import login_not_required
   -1     9 except ImportError:
   -1    10     def login_not_required(view_func):
   -1    11         return view_func
   -1    12 
   -1    13 
    1    14 def public(view_func):
    2    15     view_func.mfa_public = True
    3    16     return view_func

diff --git a/mfa/views.py b/mfa/views.py

@@ -15,18 +15,14 @@ from django.views.generic import DeleteView
   15    15 from django.views.generic import ListView
   16    16 
   17    17 from . import settings
   -1    18 from .decorators import login_not_required
   -1    19 from .decorators import stronghold_login_not_required
   18    20 from .forms import MFAAuthForm
   19    21 from .forms import MFACreateForm
   20    22 from .mail import send_mail
   21    23 from .mixins import MFAFormView
   22    24 from .models import MFAKey
   23    25 
   24    -1 try:
   25    -1     from stronghold.decorators import public as stronghold_public
   26    -1 except ImportError:
   27    -1     def stronghold_public(view_func):
   28    -1         return view_func
   29    -1 
   30    26 
   31    27 class LoginView(DjangoLoginView):
   32    28     def no_key_exists(self, form):
@@ -90,7 +86,8 @@ class MFACreateView(LoginRequiredMixin, MFAFormView):
   90    86         return super().form_valid(form)
   91    87 
   92    88 
   93    -1 @method_decorator(stronghold_public, name='dispatch')
   -1    89 @method_decorator(login_not_required, name='dispatch')
   -1    90 @method_decorator(stronghold_login_not_required, name='dispatch')
   94    91 class MFAAuthView(MFAFormView):
   95    92     form_class = MFAAuthForm
   96    93 

diff --git a/tests/settings.py b/tests/settings.py

@@ -1,5 +1,7 @@
    1     1 from pathlib import Path
    2     2 
   -1     3 import django
   -1     4 
    3     5 DATABASES = {
    4     6     'default': {
    5     7         'ENGINE': 'django.db.backends.sqlite3',
@@ -21,6 +23,9 @@ MIDDLEWARE = [
   21    23     'mfa.middleware.MFAEnforceMiddleware',
   22    24 ]
   23    25 
   -1    26 if django.VERSION >= (5, 1):
   -1    27     MIDDLEWARE.append('django.contrib.auth.middleware.LoginRequiredMiddleware')
   -1    28 
   24    29 AUTHENTICATION_BACKENDS = [
   25    30     'django.contrib.auth.backends.ModelBackend',
   26    31 ]