From fe356388a4f94fbe90ad236b8dc196ff5ce7a85b Mon Sep 17 00:00:00 2001
From: Valentin Deniaud <vdeniaud@entrouvert.com>
Date: Fri, 12 Jul 2019 15:42:00 +0200
Subject: [PATCH] webauthn: turn plugin into app

---
 .../auth2_multifactor/auth_webauthn/__init__.py | 15 ---------------
 .../auth2_multifactor/auth_webauthn/apps.py     |  8 --------
 .../templates/auth_webauthn/scripts.html        |  7 -------
 src/authentic2/settings.py                      |  2 ++
 src/authentic2/urls.py                          |  1 +
 .../__init__.py                                 |  0
 .../app_settings.py                             |  0
 src/authentic2_mfa_webauthn/apps.py             |  5 +++++
 .../authenticators.py                           |  0
 .../decorators.py                               |  0
 .../forms.py                                    |  0
 .../migrations/0001_initial.py                  |  0
 .../migrations/__init__.py                      |  0
 .../models.py                                   |  0
 .../authentic2_mfa_webauthn}/js/base64js.min.js |  0
 .../authentic2_mfa_webauthn}/js/webauthn.js     |  0
 .../authentic2_mfa_webauthn}/login.html         |  2 +-
 .../authentic2_mfa_webauthn}/profile.html       |  6 ++++--
 .../authentic2_mfa_webauthn/scripts.html        |  7 +++++++
 .../webauthncredential_confirm_delete.html      |  0
 .../urls.py                                     |  3 +--
 .../utils.py                                    |  0
 .../views.py                                    | 17 +++++++++++------
 23 files changed, 32 insertions(+), 41 deletions(-)
 delete mode 100644 src/authentic2/auth2_multifactor/auth_webauthn/__init__.py
 delete mode 100644 src/authentic2/auth2_multifactor/auth_webauthn/apps.py
 delete mode 100644 src/authentic2/auth2_multifactor/auth_webauthn/templates/auth_webauthn/scripts.html
 rename src/{authentic2/auth2_multifactor/auth_webauthn/migrations => authentic2_mfa_webauthn}/__init__.py (100%)
 rename src/{authentic2/auth2_multifactor/auth_webauthn => authentic2_mfa_webauthn}/app_settings.py (100%)
 create mode 100644 src/authentic2_mfa_webauthn/apps.py
 rename src/{authentic2/auth2_multifactor/auth_webauthn => authentic2_mfa_webauthn}/authenticators.py (100%)
 rename src/{authentic2/auth2_multifactor/auth_webauthn => authentic2_mfa_webauthn}/decorators.py (100%)
 rename src/{authentic2/auth2_multifactor/auth_webauthn => authentic2_mfa_webauthn}/forms.py (100%)
 rename src/{authentic2/auth2_multifactor/auth_webauthn => authentic2_mfa_webauthn}/migrations/0001_initial.py (100%)
 create mode 100644 src/authentic2_mfa_webauthn/migrations/__init__.py
 rename src/{authentic2/auth2_multifactor/auth_webauthn => authentic2_mfa_webauthn}/models.py (100%)
 rename src/{authentic2/auth2_multifactor/auth_webauthn/static/auth_webauthn => authentic2_mfa_webauthn/static/authentic2_mfa_webauthn}/js/base64js.min.js (100%)
 rename src/{authentic2/auth2_multifactor/auth_webauthn/static/auth_webauthn => authentic2_mfa_webauthn/static/authentic2_mfa_webauthn}/js/webauthn.js (100%)
 rename src/{authentic2/auth2_multifactor/auth_webauthn/templates/auth_webauthn => authentic2_mfa_webauthn/templates/authentic2_mfa_webauthn}/login.html (87%)
 rename src/{authentic2/auth2_multifactor/auth_webauthn/templates/auth_webauthn => authentic2_mfa_webauthn/templates/authentic2_mfa_webauthn}/profile.html (83%)
 create mode 100644 src/authentic2_mfa_webauthn/templates/authentic2_mfa_webauthn/scripts.html
 rename src/{authentic2/auth2_multifactor/auth_webauthn/templates/auth_webauthn => authentic2_mfa_webauthn/templates/authentic2_mfa_webauthn}/webauthncredential_confirm_delete.html (100%)
 rename src/{authentic2/auth2_multifactor/auth_webauthn => authentic2_mfa_webauthn}/urls.py (91%)
 rename src/{authentic2/auth2_multifactor/auth_webauthn => authentic2_mfa_webauthn}/utils.py (100%)
 rename src/{authentic2/auth2_multifactor/auth_webauthn => authentic2_mfa_webauthn}/views.py (94%)

diff --git a/src/authentic2/auth2_multifactor/auth_webauthn/__init__.py b/src/authentic2/auth2_multifactor/auth_webauthn/__init__.py
deleted file mode 100644
index 7c389328..00000000
--- a/src/authentic2/auth2_multifactor/auth_webauthn/__init__.py
+++ /dev/null
@@ -1,15 +0,0 @@
-class Plugin(object):
-    def get_before_urls(self):
-        from . import app_settings
-        from django.conf.urls import include, url
-        from authentic2.decorators import setting_enabled, required
-
-        return required(
-            setting_enabled('ENABLE', settings=app_settings),
-            [url(r'^accounts/authenticators/webauthn/', include(__name__ + '.urls'))])
-
-    def get_apps(self):
-        return [__name__]
-
-    def get_authenticators(self):
-        return ['authentic2.auth2_multifactor.auth_webauthn.authenticators.WebAuthnAuthenticator']
diff --git a/src/authentic2/auth2_multifactor/auth_webauthn/apps.py b/src/authentic2/auth2_multifactor/auth_webauthn/apps.py
deleted file mode 100644
index ff3f152b..00000000
--- a/src/authentic2/auth2_multifactor/auth_webauthn/apps.py
+++ /dev/null
@@ -1,8 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.apps import AppConfig
-
-
-class AuthWebauthnConfig(AppConfig):
-    name = 'auth_webauthn'
diff --git a/src/authentic2/auth2_multifactor/auth_webauthn/templates/auth_webauthn/scripts.html b/src/authentic2/auth2_multifactor/auth_webauthn/templates/auth_webauthn/scripts.html
deleted file mode 100644
index 3aa6e7f3..00000000
--- a/src/authentic2/auth2_multifactor/auth_webauthn/templates/auth_webauthn/scripts.html
+++ /dev/null
@@ -1,7 +0,0 @@
-{% load static %}
-
-<script type="text/javascript" src="{% static "auth_webauthn/js/webauthn.js" %}"></script>
-<script type="text/javascript" src="{% static "auth_webauthn/js/base64js.min.js" %}"></script>
-<script>
-  window.csrf_token = '{{ csrf_token }}';
-</script>
diff --git a/src/authentic2/settings.py b/src/authentic2/settings.py
index 9f48bd8a..ead7b18c 100644
--- a/src/authentic2/settings.py
+++ b/src/authentic2/settings.py
@@ -146,6 +146,7 @@ INSTALLED_APPS = (
     'xstatic.pkg.jquery_ui',
     'xstatic.pkg.select2',
     'authentic2_mfa_totp',
+    'authentic2_mfa_webauthn',
 )
 
 INSTALLED_APPS = tuple(plugins.register_plugins_installed_apps(INSTALLED_APPS))
@@ -177,6 +178,7 @@ ACCOUNT_ACTIVATION_DAYS = 2
 AUTH_USER_MODEL = 'custom_user.User'
 AUTH_FRONTENDS = [
     'authentic2_mfa_totp.authenticators.TOTPAuthenticator',
+    'authentic2_mfa_webauthn.authenticators.WebAuthnAuthenticator',
 ]
 AUTH_FRONTENDS.extend(plugins.register_plugins_authenticators((
     'authentic2.authenticators.LoginPasswordAuthenticator',
diff --git a/src/authentic2/urls.py b/src/authentic2/urls.py
index d202b84e..2eb64cd0 100644
--- a/src/authentic2/urls.py
+++ b/src/authentic2/urls.py
@@ -120,6 +120,7 @@ urlpatterns = [
     url(r'^manage/', include('authentic2.manager.urls')),
     url(r'^api/', include('authentic2.api_urls')),
     url(r'^totp/', include('authentic2_mfa_totp.urls')),
+    url(r'^webauthn/', include('authentic2_mfa_webauthn.urls')),
 ]
 
 try:
diff --git a/src/authentic2/auth2_multifactor/auth_webauthn/migrations/__init__.py b/src/authentic2_mfa_webauthn/__init__.py
similarity index 100%
rename from src/authentic2/auth2_multifactor/auth_webauthn/migrations/__init__.py
rename to src/authentic2_mfa_webauthn/__init__.py
diff --git a/src/authentic2/auth2_multifactor/auth_webauthn/app_settings.py b/src/authentic2_mfa_webauthn/app_settings.py
similarity index 100%
rename from src/authentic2/auth2_multifactor/auth_webauthn/app_settings.py
rename to src/authentic2_mfa_webauthn/app_settings.py
diff --git a/src/authentic2_mfa_webauthn/apps.py b/src/authentic2_mfa_webauthn/apps.py
new file mode 100644
index 00000000..72edee19
--- /dev/null
+++ b/src/authentic2_mfa_webauthn/apps.py
@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class AuthWebauthnConfig(AppConfig):
+    name = 'authentic2_mfa_webauthn'
diff --git a/src/authentic2/auth2_multifactor/auth_webauthn/authenticators.py b/src/authentic2_mfa_webauthn/authenticators.py
similarity index 100%
rename from src/authentic2/auth2_multifactor/auth_webauthn/authenticators.py
rename to src/authentic2_mfa_webauthn/authenticators.py
diff --git a/src/authentic2/auth2_multifactor/auth_webauthn/decorators.py b/src/authentic2_mfa_webauthn/decorators.py
similarity index 100%
rename from src/authentic2/auth2_multifactor/auth_webauthn/decorators.py
rename to src/authentic2_mfa_webauthn/decorators.py
diff --git a/src/authentic2/auth2_multifactor/auth_webauthn/forms.py b/src/authentic2_mfa_webauthn/forms.py
similarity index 100%
rename from src/authentic2/auth2_multifactor/auth_webauthn/forms.py
rename to src/authentic2_mfa_webauthn/forms.py
diff --git a/src/authentic2/auth2_multifactor/auth_webauthn/migrations/0001_initial.py b/src/authentic2_mfa_webauthn/migrations/0001_initial.py
similarity index 100%
rename from src/authentic2/auth2_multifactor/auth_webauthn/migrations/0001_initial.py
rename to src/authentic2_mfa_webauthn/migrations/0001_initial.py
diff --git a/src/authentic2_mfa_webauthn/migrations/__init__.py b/src/authentic2_mfa_webauthn/migrations/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/src/authentic2/auth2_multifactor/auth_webauthn/models.py b/src/authentic2_mfa_webauthn/models.py
similarity index 100%
rename from src/authentic2/auth2_multifactor/auth_webauthn/models.py
rename to src/authentic2_mfa_webauthn/models.py
diff --git a/src/authentic2/auth2_multifactor/auth_webauthn/static/auth_webauthn/js/base64js.min.js b/src/authentic2_mfa_webauthn/static/authentic2_mfa_webauthn/js/base64js.min.js
similarity index 100%
rename from src/authentic2/auth2_multifactor/auth_webauthn/static/auth_webauthn/js/base64js.min.js
rename to src/authentic2_mfa_webauthn/static/authentic2_mfa_webauthn/js/base64js.min.js
diff --git a/src/authentic2/auth2_multifactor/auth_webauthn/static/auth_webauthn/js/webauthn.js b/src/authentic2_mfa_webauthn/static/authentic2_mfa_webauthn/js/webauthn.js
similarity index 100%
rename from src/authentic2/auth2_multifactor/auth_webauthn/static/auth_webauthn/js/webauthn.js
rename to src/authentic2_mfa_webauthn/static/authentic2_mfa_webauthn/js/webauthn.js
diff --git a/src/authentic2/auth2_multifactor/auth_webauthn/templates/auth_webauthn/login.html b/src/authentic2_mfa_webauthn/templates/authentic2_mfa_webauthn/login.html
similarity index 87%
rename from src/authentic2/auth2_multifactor/auth_webauthn/templates/auth_webauthn/login.html
rename to src/authentic2_mfa_webauthn/templates/authentic2_mfa_webauthn/login.html
index 6f147cc3..f3b027f1 100644
--- a/src/authentic2/auth2_multifactor/auth_webauthn/templates/auth_webauthn/login.html
+++ b/src/authentic2_mfa_webauthn/templates/authentic2_mfa_webauthn/login.html
@@ -1,5 +1,5 @@
 {% load i18n %}
-{% include "auth_webauthn/scripts.html" %}
+{% include "authentic2_mfa_webauthn/scripts.html" %}
 
 <a hidden id="auth-proceed-url" href="{% url 'authenticate-proceed' %}"></a>
 
diff --git a/src/authentic2/auth2_multifactor/auth_webauthn/templates/auth_webauthn/profile.html b/src/authentic2_mfa_webauthn/templates/authentic2_mfa_webauthn/profile.html
similarity index 83%
rename from src/authentic2/auth2_multifactor/auth_webauthn/templates/auth_webauthn/profile.html
rename to src/authentic2_mfa_webauthn/templates/authentic2_mfa_webauthn/profile.html
index aa49d1ed..569cef9e 100644
--- a/src/authentic2/auth2_multifactor/auth_webauthn/templates/auth_webauthn/profile.html
+++ b/src/authentic2_mfa_webauthn/templates/authentic2_mfa_webauthn/profile.html
@@ -1,5 +1,5 @@
 {% load i18n static %}
-{% include "auth_webauthn/scripts.html" %}
+{% include "authentic2_mfa_webauthn/scripts.html" %}
 
 {% if insufficient_level_url %}
   <a href="{{ insufficient_level_url }}">
@@ -22,7 +22,9 @@
       <li>
         {{ credential.name }} -
         {% trans "Added on" %} {{ credential.date }} -
-        <a href="{% url 'webauthn-delete' credential.pk %}">{% trans "Delete" %}</a>
+        <a href="{% url 'webauthn-delete' credential.pk %}?next={{ next_url }}">
+          {% trans "Delete" %}
+        </a>
       </li>
     {% empty %}
       <li>{% trans "No credentials have been registered yet." %}</li>
diff --git a/src/authentic2_mfa_webauthn/templates/authentic2_mfa_webauthn/scripts.html b/src/authentic2_mfa_webauthn/templates/authentic2_mfa_webauthn/scripts.html
new file mode 100644
index 00000000..da023956
--- /dev/null
+++ b/src/authentic2_mfa_webauthn/templates/authentic2_mfa_webauthn/scripts.html
@@ -0,0 +1,7 @@
+{% load static %}
+
+<script type="text/javascript" src="{% static "authentic2_mfa_webauthn/js/webauthn.js" %}"></script>
+<script type="text/javascript" src="{% static "authentic2_mfa_webauthn/js/base64js.min.js" %}"></script>
+<script>
+  window.csrf_token = '{{ csrf_token }}';
+</script>
diff --git a/src/authentic2/auth2_multifactor/auth_webauthn/templates/auth_webauthn/webauthncredential_confirm_delete.html b/src/authentic2_mfa_webauthn/templates/authentic2_mfa_webauthn/webauthncredential_confirm_delete.html
similarity index 100%
rename from src/authentic2/auth2_multifactor/auth_webauthn/templates/auth_webauthn/webauthncredential_confirm_delete.html
rename to src/authentic2_mfa_webauthn/templates/authentic2_mfa_webauthn/webauthncredential_confirm_delete.html
diff --git a/src/authentic2/auth2_multifactor/auth_webauthn/urls.py b/src/authentic2_mfa_webauthn/urls.py
similarity index 91%
rename from src/authentic2/auth2_multifactor/auth_webauthn/urls.py
rename to src/authentic2_mfa_webauthn/urls.py
index 2943afe5..6e883405 100644
--- a/src/authentic2/auth2_multifactor/auth_webauthn/urls.py
+++ b/src/authentic2_mfa_webauthn/urls.py
@@ -3,8 +3,7 @@ from django.contrib.auth.decorators import login_required
 from django.views.decorators.csrf import requires_csrf_token
 from django.views.decorators.http import require_POST
 
-from authentic2.auth2_multifactor.decorators import auth_level_required
-from authentic2.decorators import required
+from authentic2.decorators import required, auth_level_required
 
 from . import views
 from .authenticators import WebAuthnAuthenticator
diff --git a/src/authentic2/auth2_multifactor/auth_webauthn/utils.py b/src/authentic2_mfa_webauthn/utils.py
similarity index 100%
rename from src/authentic2/auth2_multifactor/auth_webauthn/utils.py
rename to src/authentic2_mfa_webauthn/utils.py
diff --git a/src/authentic2/auth2_multifactor/auth_webauthn/views.py b/src/authentic2_mfa_webauthn/views.py
similarity index 94%
rename from src/authentic2/auth2_multifactor/auth_webauthn/views.py
rename to src/authentic2_mfa_webauthn/views.py
index 27995d39..7cb2ee00 100644
--- a/src/authentic2/auth2_multifactor/auth_webauthn/views.py
+++ b/src/authentic2_mfa_webauthn/views.py
@@ -10,7 +10,7 @@ from django.views.generic.base import TemplateView
 from django.views.generic.edit import FormMixin, FormView, DeleteView
 from django.views.generic.list import ListView
 
-from authentic2.utils import make_url
+from authentic2.utils import make_url, get_next_url
 
 from . import app_settings
 from .authenticators import WebAuthnAuthenticator
@@ -133,7 +133,7 @@ def authenticate_proceed(request):
 
 
 class Profile(FormMixin, ListView):
-    template_name = 'auth_webauthn/profile.html'
+    template_name = 'authentic2_mfa_webauthn/profile.html'
     form_class = CredentialForm
 
     def get_queryset(self):
@@ -146,12 +146,15 @@ class Profile(FormMixin, ListView):
         except self.request.user.enabled_auth_factors.model.DoesNotExist:
             pass
         else:
+            next_url = self.request.get_full_path()
             if self.request.session.get('auth_level', 1) < WebAuthnAuthenticator.auth_level:
                 params = {
-                    'next': self.request.get_full_path(),
-                    'auth_level': WebAuthnAuthenticator.auth_level,
+                    'next': next_url,
+                    'auth_level': WebAuthnAuthenticator.auth_level
                 }
                 kwargs['insufficient_level_url'] = make_url('auth_login', params=params)
+            else:
+                kwargs['next_url'] = next_url
         return super(Profile, self).get_context_data(**kwargs)
 
 
@@ -159,7 +162,7 @@ webauthn_profile = Profile.as_view()
 
 
 class Login(TemplateView):
-    template_name = 'auth_webauthn/login.html'
+    template_name = 'authentic2_mfa_webauthn/login.html'
 
 
 webauthn_login = Login.as_view()
@@ -167,7 +170,9 @@ webauthn_login = Login.as_view()
 
 class Delete(DeleteView):
     model = WebAuthnCredential
-    success_url = reverse('authenticators_profile')
+
+    def get_success_url(self):
+        return get_next_url(self.request.GET)
 
     def dispatch(self, request, *args, **kwargs):
         cred = self.get_object()
-- 
2.20.1

