# Source code for django_otp.views

    from __future__ import absolute_import, division, print_function, unicode_literals

    from functools import partial

    from django.contrib.auth import BACKEND_SESSION_KEY
    from django.contrib.auth.views import login as auth_login

    from django_otp import _user_is_anonymous
    from django_otp.forms import OTPAuthenticationForm, OTPTokenForm

    def login(request, **kwargs):
        """
        This is a replacement for :func:`django.contrib.auth.views.login` that
        requires two-factor authentication. It's slightly clever: if the user is
        already authenticated but not verified, it will only ask the user for their
        OTP token. If the user is anonymous or is already verified by an OTP
        device, it will use the full username/password/token form. In order to use
        this, you must supply a template that is compatible with both
        :class:`~django_otp.forms.OTPAuthenticationForm` and
        :class:`~django_otp.forms.OTPTokenForm`. This is a good view for
        :setting:`OTP_LOGIN_URL`.

        Parameters are the same as :func:`~django.contrib.auth.views.login` except
        that this view always overrides ``authentication_form``.
        """
        user = request.user

        if _user_is_anonymous(user) or user.is_verified():
            form = OTPAuthenticationForm
        else:
            form = partial(OTPTokenForm, user)

            # A minor hack to make django.contrib.auth.login happy
            user.backend = request.session[BACKEND_SESSION_KEY]

        kwargs['authentication_form'] = form

        return auth_login(request, **kwargs)