malept/pyoath-toolkit

View on GitHub
examples/django/example/views.py

Summary

Maintainability
A
1 hr
Test Coverage
# -*- coding: utf-8 -*-

from django.conf import settings
from django.contrib.auth import REDIRECT_FIELD_NAME
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.http import Http404, HttpResponse, HttpResponseRedirect
from django.shortcuts import redirect, render, resolve_url
from django.utils.http import is_safe_url
from django.utils.translation import ugettext as u_, ugettext_lazy as ul_
from django_otp import devices_for_user, login as otp_login
from django_otp.decorators import otp_required
from django_otp.forms import OTPTokenForm
from oath_toolkit.django_otp.totp.models import (
    OToolkitTOTPDevice as TOTPDevice)
from .forms import DeviceValidationForm


def index(request):
    return render(request, 'index.html')


@otp_required
def protected(request):
    return render(request, 'protected.html')


@login_required
def otp_status(request):
    tfa_enabled = len(list(devices_for_user(request.user, True))) > 0
    if tfa_enabled:
        tfa_status = ul_(u'enabled')
        tfa_btn_name = 'disable'
        tfa_btn_value = ul_(u'Disable')
    else:
        tfa_status = ul_(u'disabled')
        tfa_btn_name = 'enable'
        tfa_btn_value = ul_(u'Enable')
    return render(request, 'otp_status.html', {
        'tfa_status': tfa_status,
        'tfa_button_name': tfa_btn_name,
        'tfa_button_value': tfa_btn_value,
    })


@login_required
def otp_setup(request):
    confirmed_devices = list(devices_for_user(request.user, True))
    tfa_enabled = len(confirmed_devices) > 0
    if request.method == 'GET' and not tfa_enabled:
        unconfirmed_devices = list(devices_for_user(request.user, False))
        device = unconfirmed_devices[0]
        form = DeviceValidationForm(device)
        return render(request, 'otp_setup.html', {
            'device': device,
            'form': form,
        })
    elif request.method == 'POST':
        if request.POST.get(u'enable') and not tfa_enabled:
            device = TOTPDevice.objects.create(user=request.user,
                                               name=u'TOTP',
                                               confirmed=False)
            form = DeviceValidationForm(device)
            return render(request, 'otp_setup.html', {
                'device': device,
                'form': form,
            })
        elif request.POST.get(u'disable') and tfa_enabled:
            for device in confirmed_devices:
                device.delete()
            messages.success(request, u_(
                u'Disabled two-factor authentication for this account.'))
        else:
            messages.error(request, u_(u'Unknown error.'))
    return redirect('otp_status')


@login_required
def otp_setup_verify(request):
    if request.method == 'POST':
        unconfirmed_devices = list(devices_for_user(request.user, False))
        device = unconfirmed_devices[0]
        form = DeviceValidationForm(device, request.POST)
        if form.is_valid():
            device.confirmed = True
            device.save()
            messages.success(request, u_(
                u'Enabled two-factor authentication for this account.'))
        else:
            return redirect('otp_setup')
    else:
        messages.error(request, u_(u'Unknown error.'))
    return redirect('otp_status')


@login_required
def otp_qrcode(request):
    response = None
    for device in devices_for_user(request.user, False):
        if not hasattr(device, 'secret_qrcode'):
            continue
        qrcode = device.secret_qrcode(request)
        response = HttpResponse(content_type='image/png')
        qrcode.save(response, 'PNG')
    if not response:
        raise Http404
    return response


@login_required
def otp_verify(request):
    if request.method == 'POST':
        redirect_to = request.POST.get(REDIRECT_FIELD_NAME,
                                       request.GET.get(REDIRECT_FIELD_NAME,
                                                       ''))
        form = OTPTokenForm(request.user, request, request.POST)
        if form.is_valid():
            otp_login(request, request.user.otp_device)
            # Ensure the user-originating redirection url is safe.
            # From django.contrib.auth.views.login
            if not is_safe_url(url=redirect_to, host=request.get_host()):
                redirect_to = resolve_url(settings.LOGIN_REDIRECT_URL)
            return HttpResponseRedirect(redirect_to)
    else:
        form = OTPTokenForm(request.user, request)
    return render(request, 'otp_verify.html', {
        'form': form,
    })