Source code for django_otp.admin

from __future__ import absolute_import, division, print_function, unicode_literals

import django
from django import forms
from django.contrib.admin.forms import AdminAuthenticationForm
from django.contrib.admin.sites import AdminSite

from .forms import OTPAuthenticationFormMixin


def _admin_template_for_django_version():
    minor_django_version = django.VERSION[:2]

    if minor_django_version <= (1, 4):
        return 'otp/admin14/login.html'
    elif minor_django_version == (1, 5):
        return 'otp/admin15/login.html'
    elif minor_django_version == (1, 6):
        return 'otp/admin16/login.html'
    elif minor_django_version == (1, 7):
        return 'otp/admin17/login.html'
    elif minor_django_version == (1, 8):
        return 'otp/admin18/login.html'
    else:
        return 'otp/admin19/login.html'


[docs]class OTPAdminAuthenticationForm(AdminAuthenticationForm, OTPAuthenticationFormMixin): """ An :class:`~django.contrib.admin.forms.AdminAuthenticationForm` subclass that solicits an OTP token. This has the same behavior as :class:`~django_otp.forms.OTPAuthenticationForm`. """ otp_device = forms.CharField(required=False, widget=forms.Select) otp_token = forms.CharField(required=False) # This is a placeholder field that allows us to detect when the user clicks # the otp_challenge submit button. otp_challenge = forms.CharField(required=False) def __init__(self, *args, **kwargs): super(OTPAdminAuthenticationForm, self).__init__(*args, **kwargs) # A litle extra cheese to make it prettier. minor_django_version = django.VERSION[:2] if minor_django_version < (1, 6): self.fields['otp_token'].widget.attrs['style'] = 'width: 14em;' def clean(self): self.cleaned_data = super(OTPAdminAuthenticationForm, self).clean() self.clean_otp(self.get_user()) return self.cleaned_data
[docs]class OTPAdminSite(AdminSite): """ This is an :class:`~django.contrib.admin.AdminSite` subclass that requires two-factor authentication. Only users that can be verified by a registered OTP device will be authorized for this admin site. Unverified users will be treated as if :attr:`~django.contrib.auth.models.User.is_staff` is ``False``. """ #: The default instance name of this admin site. You should instantiate #: this class as ``OTPAdminSite(OTPAdminSite.name)`` to make sure the admin #: templates render the correct URLs. name = 'otpadmin' login_form = OTPAdminAuthenticationForm #: We automatically select a modified login template based on your Django #: version. If it doesn't look right, your version may not be supported, in #: which case feel free to replace it. login_template = _admin_template_for_django_version() def __init__(self, name='otpadmin'): super(OTPAdminSite, self).__init__(name)
[docs] def has_permission(self, request): """ In addition to the default requirements, this only allows access to users who have been verified by a registered OTP device. """ return super(OTPAdminSite, self).has_permission(request) and request.user.is_verified()