0002-webauthn-turn-plugin-into-app.patch
src/authentic2/auth2_multifactor/auth_webauthn/__init__.py | ||
---|---|---|
1 |
class Plugin(object): |
|
2 |
def get_before_urls(self): |
|
3 |
from . import app_settings |
|
4 |
from django.conf.urls import include, url |
|
5 |
from authentic2.decorators import setting_enabled, required |
|
6 | ||
7 |
return required( |
|
8 |
setting_enabled('ENABLE', settings=app_settings), |
|
9 |
[url(r'^accounts/authenticators/webauthn/', include(__name__ + '.urls'))]) |
|
10 | ||
11 |
def get_apps(self): |
|
12 |
return [__name__] |
|
13 | ||
14 |
def get_authenticators(self): |
|
15 |
return ['authentic2.auth2_multifactor.auth_webauthn.authenticators.WebAuthnAuthenticator'] |
src/authentic2/auth2_multifactor/auth_webauthn/apps.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
from __future__ import unicode_literals |
|
3 | ||
4 |
from django.apps import AppConfig |
|
5 | ||
6 | ||
7 |
class AuthWebauthnConfig(AppConfig): |
|
8 |
name = 'auth_webauthn' |
src/authentic2/auth2_multifactor/auth_webauthn/templates/auth_webauthn/scripts.html | ||
---|---|---|
1 |
{% load static %} |
|
2 | ||
3 |
<script type="text/javascript" src="{% static "auth_webauthn/js/webauthn.js" %}"></script> |
|
4 |
<script type="text/javascript" src="{% static "auth_webauthn/js/base64js.min.js" %}"></script> |
|
5 |
<script> |
|
6 |
window.csrf_token = '{{ csrf_token }}'; |
|
7 |
</script> |
src/authentic2/settings.py | ||
---|---|---|
146 | 146 |
'xstatic.pkg.jquery_ui', |
147 | 147 |
'xstatic.pkg.select2', |
148 | 148 |
'authentic2_mfa_totp', |
149 |
'authentic2_mfa_webauthn', |
|
149 | 150 |
) |
150 | 151 | |
151 | 152 |
INSTALLED_APPS = tuple(plugins.register_plugins_installed_apps(INSTALLED_APPS)) |
... | ... | |
177 | 178 |
AUTH_USER_MODEL = 'custom_user.User' |
178 | 179 |
AUTH_FRONTENDS = [ |
179 | 180 |
'authentic2_mfa_totp.authenticators.TOTPAuthenticator', |
181 |
'authentic2_mfa_webauthn.authenticators.WebAuthnAuthenticator', |
|
180 | 182 |
] |
181 | 183 |
AUTH_FRONTENDS.extend(plugins.register_plugins_authenticators(( |
182 | 184 |
'authentic2.authenticators.LoginPasswordAuthenticator', |
src/authentic2/urls.py | ||
---|---|---|
120 | 120 |
url(r'^manage/', include('authentic2.manager.urls')), |
121 | 121 |
url(r'^api/', include('authentic2.api_urls')), |
122 | 122 |
url(r'^totp/', include('authentic2_mfa_totp.urls')), |
123 |
url(r'^webauthn/', include('authentic2_mfa_webauthn.urls')), |
|
123 | 124 |
] |
124 | 125 | |
125 | 126 |
try: |
src/authentic2_mfa_webauthn/apps.py | ||
---|---|---|
1 |
from django.apps import AppConfig |
|
2 | ||
3 | ||
4 |
class AuthWebauthnConfig(AppConfig): |
|
5 |
name = 'authentic2_mfa_webauthn' |
src/authentic2/auth2_multifactor/auth_webauthn/templates/auth_webauthn/login.html → src/authentic2_mfa_webauthn/templates/authentic2_mfa_webauthn/login.html | ||
---|---|---|
1 | 1 |
{% load i18n %} |
2 |
{% include "auth_webauthn/scripts.html" %} |
|
2 |
{% include "authentic2_mfa_webauthn/scripts.html" %}
|
|
3 | 3 | |
4 | 4 |
<a hidden id="auth-proceed-url" href="{% url 'authenticate-proceed' %}"></a> |
5 | 5 |
src/authentic2/auth2_multifactor/auth_webauthn/templates/auth_webauthn/profile.html → src/authentic2_mfa_webauthn/templates/authentic2_mfa_webauthn/profile.html | ||
---|---|---|
1 | 1 |
{% load i18n static %} |
2 |
{% include "auth_webauthn/scripts.html" %} |
|
2 |
{% include "authentic2_mfa_webauthn/scripts.html" %}
|
|
3 | 3 | |
4 | 4 |
{% if insufficient_level_url %} |
5 | 5 |
<a href="{{ insufficient_level_url }}"> |
... | ... | |
22 | 22 |
<li> |
23 | 23 |
{{ credential.name }} - |
24 | 24 |
{% trans "Added on" %} {{ credential.date }} - |
25 |
<a href="{% url 'webauthn-delete' credential.pk %}">{% trans "Delete" %}</a> |
|
25 |
<a href="{% url 'webauthn-delete' credential.pk %}?next={{ next_url }}"> |
|
26 |
{% trans "Delete" %} |
|
27 |
</a> |
|
26 | 28 |
</li> |
27 | 29 |
{% empty %} |
28 | 30 |
<li>{% trans "No credentials have been registered yet." %}</li> |
src/authentic2_mfa_webauthn/templates/authentic2_mfa_webauthn/scripts.html | ||
---|---|---|
1 |
{% load static %} |
|
2 | ||
3 |
<script type="text/javascript" src="{% static "authentic2_mfa_webauthn/js/webauthn.js" %}"></script> |
|
4 |
<script type="text/javascript" src="{% static "authentic2_mfa_webauthn/js/base64js.min.js" %}"></script> |
|
5 |
<script> |
|
6 |
window.csrf_token = '{{ csrf_token }}'; |
|
7 |
</script> |
src/authentic2/auth2_multifactor/auth_webauthn/urls.py → src/authentic2_mfa_webauthn/urls.py | ||
---|---|---|
3 | 3 |
from django.views.decorators.csrf import requires_csrf_token |
4 | 4 |
from django.views.decorators.http import require_POST |
5 | 5 | |
6 |
from authentic2.auth2_multifactor.decorators import auth_level_required |
|
7 |
from authentic2.decorators import required |
|
6 |
from authentic2.decorators import required, auth_level_required |
|
8 | 7 | |
9 | 8 |
from . import views |
10 | 9 |
from .authenticators import WebAuthnAuthenticator |
src/authentic2/auth2_multifactor/auth_webauthn/views.py → src/authentic2_mfa_webauthn/views.py | ||
---|---|---|
10 | 10 |
from django.views.generic.edit import FormMixin, FormView, DeleteView |
11 | 11 |
from django.views.generic.list import ListView |
12 | 12 | |
13 |
from authentic2.utils import make_url |
|
13 |
from authentic2.utils import make_url, get_next_url
|
|
14 | 14 | |
15 | 15 |
from . import app_settings |
16 | 16 |
from .authenticators import WebAuthnAuthenticator |
... | ... | |
133 | 133 | |
134 | 134 | |
135 | 135 |
class Profile(FormMixin, ListView): |
136 |
template_name = 'auth_webauthn/profile.html' |
|
136 |
template_name = 'authentic2_mfa_webauthn/profile.html'
|
|
137 | 137 |
form_class = CredentialForm |
138 | 138 | |
139 | 139 |
def get_queryset(self): |
... | ... | |
146 | 146 |
except self.request.user.enabled_auth_factors.model.DoesNotExist: |
147 | 147 |
pass |
148 | 148 |
else: |
149 |
next_url = self.request.get_full_path() |
|
149 | 150 |
if self.request.session.get('auth_level', 1) < WebAuthnAuthenticator.auth_level: |
150 | 151 |
params = { |
151 |
'next': self.request.get_full_path(),
|
|
152 |
'auth_level': WebAuthnAuthenticator.auth_level,
|
|
152 |
'next': next_url,
|
|
153 |
'auth_level': WebAuthnAuthenticator.auth_level |
|
153 | 154 |
} |
154 | 155 |
kwargs['insufficient_level_url'] = make_url('auth_login', params=params) |
156 |
else: |
|
157 |
kwargs['next_url'] = next_url |
|
155 | 158 |
return super(Profile, self).get_context_data(**kwargs) |
156 | 159 | |
157 | 160 | |
... | ... | |
159 | 162 | |
160 | 163 | |
161 | 164 |
class Login(TemplateView): |
162 |
template_name = 'auth_webauthn/login.html' |
|
165 |
template_name = 'authentic2_mfa_webauthn/login.html'
|
|
163 | 166 | |
164 | 167 | |
165 | 168 |
webauthn_login = Login.as_view() |
... | ... | |
167 | 170 | |
168 | 171 |
class Delete(DeleteView): |
169 | 172 |
model = WebAuthnCredential |
170 |
success_url = reverse('authenticators_profile') |
|
173 | ||
174 |
def get_success_url(self): |
|
175 |
return get_next_url(self.request.GET) |
|
171 | 176 | |
172 | 177 |
def dispatch(self, request, *args, **kwargs): |
173 | 178 |
cred = self.get_object() |
174 |
- |