Skip to content

Commit

Permalink
Set a single login.thml template for all versions
Browse files Browse the repository at this point in the history
  • Loading branch information
claudep authored and psagers committed Jan 2, 2020
1 parent 22447c1 commit 0878dcc
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 109 deletions.
10 changes: 3 additions & 7 deletions src/django_otp/admin.py
@@ -1,4 +1,3 @@
import django
from django import forms
from django.contrib.admin.forms import AdminAuthenticationForm
from django.contrib.admin.sites import AdminSite
Expand All @@ -11,13 +10,10 @@ def _admin_template_for_django_version():
Returns the most appropriate Django login template available.
In the past, we've had more version-specific templates. Perhaps this will
be true again in the future. For now, the Django 1.9 and 3.0 version are
the most recent available.
be true again in the future. For now, the Django 1.11 version is suitable
even with the most recent Django version.
"""
if django.VERSION[0] >= 3:
return 'otp/admin30/login.html'
else:
return 'otp/admin19/login.html'
return 'otp/admin111/login.html'


class OTPAdminAuthenticationForm(AdminAuthenticationForm, OTPAuthenticationFormMixin):
Expand Down
Expand Up @@ -70,11 +70,11 @@
<div class="form-row">
<label for="id_otp_device">{% trans 'OTP Device:' %}</label> {{ form.otp_device }}
</div>
{% endif %}
<div class="form-row">
{% if not form.this_is_the_login_form.errors %}{{ form.otp_token.errors }}{% endif %}
<label for="id_otp_token" class="required">{% trans 'OTP Token:' %}</label> {{ form.otp_token }}
</div>
{% endif %}
{% url 'admin_password_reset' as password_reset_url %}
{% if password_reset_url %}
<div class="password-reset-link">
Expand All @@ -84,7 +84,7 @@
<div class="submit-row">
<label>&nbsp;</label><input type="submit" value="{% trans 'Log in' %}" />
{% if form.get_user %}
<label>&nbsp;</label><input type=submit name="otp_challenge" value="{% trans 'Get OTP Challenge' %}" />
<label>&nbsp;</label><input type="submit" name="otp_challenge" value="{% trans 'Get OTP Challenge' %}" />
{% endif %}
</div>
</form>
Expand Down
96 changes: 0 additions & 96 deletions src/django_otp/templates/otp/admin19/login.html

This file was deleted.

33 changes: 30 additions & 3 deletions src/django_otp/tests.py
Expand Up @@ -5,6 +5,7 @@
from django.contrib.auth import get_user_model
from django.db import IntegrityError
from django.test import RequestFactory, TestCase as DjangoTestCase
from django.urls import reverse

from django_otp import DEVICE_ID_SESSION_KEY, oath, util
from django_otp.middleware import OTPMiddleware
Expand All @@ -31,14 +32,14 @@ def setUpClass(cls):
cls.User = get_user_model()
cls.USERNAME_FIELD = cls.User.USERNAME_FIELD

def create_user(self, username, password):
def create_user(self, username, password, **kwargs):
"""
Try to create a user, honoring the custom user model, if any.
This may raise an exception if the user model is too exotic for our
purposes.
"""
return self.User.objects.create_user(username, password=password)
return self.User.objects.create_user(username, password=password, **kwargs)


class OTPMiddlewareTestCase(TestCase):
Expand Down Expand Up @@ -143,14 +144,40 @@ class LoginViewTestCase(TestCase):
def setUp(self):
try:
self.alice = self.create_user('alice', 'password')
self.bob = self.create_user('bob', 'password')
self.bob = self.create_user('bob', 'password', is_staff=True)
except IntegrityError:
self.skipTest("Unable to create a test user.")
else:
for user in [self.alice, self.bob]:
device = user.staticdevice_set.create()
device.token_set.create(token=user.get_username())

def test_admin_login_template(self):
response = self.client.get(reverse('admin:login'))
self.assertContains(response, 'Username:')
self.assertContains(response, 'Password:')
self.assertNotContains(response, 'OTP Device:')
self.assertNotContains(response, 'OTP Token:')
response = self.client.post(reverse('admin:login'), data={
'username': self.bob.get_username(),
'password': 'password',
})
self.assertContains(response, 'Username:')
self.assertContains(response, 'Password:')
self.assertContains(response, 'OTP Device:')
self.assertContains(response, 'OTP Token:')

device = self.bob.staticdevice_set.get()
token = device.token_set.get()
response = self.client.post(reverse('admin:login'), data={
'username': self.bob.get_username(),
'password': 'password',
'otp_device': device.persistent_id,
'otp_token': token.token,
'next': '/',
})
self.assertRedirects(response, '/')

def test_authenticate(self):
device = self.alice.staticdevice_set.get()
token = device.token_set.get()
Expand Down
8 changes: 7 additions & 1 deletion test/test_project/urls.py
Expand Up @@ -5,6 +5,12 @@
from django.views.generic.base import View

import django_otp.views
from django_otp.admin import OTPAdminSite


otp_admin_site = OTPAdminSite(OTPAdminSite.name)
for model_cls, model_admin in admin.site._registry.items():
otp_admin_site.register(model_cls, model_admin.__class__)


class HomeView(View):
Expand All @@ -16,5 +22,5 @@ def get(self, request, *args, **kwargs):
url(r'^$', HomeView.as_view()),
url(r'^login/$', django_otp.views.LoginView.as_view()),
url(r'^logout/$', django.contrib.auth.views.LogoutView.as_view()),
url(r'^admin/', admin.site.urls),
url(r'^admin/', otp_admin_site.urls),
]

0 comments on commit 0878dcc

Please sign in to comment.