Example #1
0
def otp_config(request):
    """View to manage two-factor (OTP) auth.

    - Show QR code if the device is not confirmed.
    - Allow user to confirm their code, if it not confirmed.  Then
      mark the device as confirmed.
    - If device is already confirmed, then don't show the QR code
      since that would risk it being lost.  However, do show it if the
      user has logged in using OTP (user.is_verified) and you have
      just verified your token.
    """
    if request.user.is_anonymous():
        return HttpResponse("Forbidden: must be logged in", status=403)
    context = c = {}
    # Get devices
    devices = list(django_otp.devices_for_user(request.user,
                                               confirmed=None))  # conf
    # and unconf If there is more than one device, log an error.
    # FIXME: this does not support one-time passwords and multiple
    # devices yet.
    if len(devices) > 1:
        logger.critical("User has more than one OTP device: %s",
                        request.user.id)
    # If the user has no devices, create one now.
    if len(devices) == 0:
        from django_otp.plugins.otp_totp.models import TOTPDevice
        device = TOTPDevice(user=request.user,
                            confirmed=False,
                            name='Auto device')
        device.save()
    # If everything is normal, then select the user's device.
    else:
        device = devices[0]
        c['confirmed'] = device.confirmed

    # Attempt to verify code or confirm the unconfirmed device.
    if request.method == 'POST':
        form = c['otp_form'] = OTPVerifyForm(request.POST)
        form.is_valid()  # validate form - validation is null op.
        success = c['success'] = device.verify_token(
            form.cleaned_data['otp_token'])
        # Success: if the device is unconfirmed, then confirm it.  It
        # can then be used for logging in, etc.
        if success:
            # Do device confirmation
            if not device.confirmed:
                device.confirmed = True
                device.save()
                c['confirmed'] = device.confirmed
            message = c['message'] = 'Code verified.'
        else:
            message = c['message'] = 'Code not successful.'
        # Note that there is no other special action on success.

        # Reset the form - don't display code again or anything.
        form = c['otp_form'] = OTPVerifyForm()
    else:
        form = c['otp_form'] = OTPVerifyForm()

    return TemplateResponse(request, 'koota/otp.html', context)
Example #2
0
    def save(self, user):
        totp_device = TOTPDevice(name=self.cleaned_data["name"], user=user)
        totp_device.confirmed = False
        totp_device.save()

        return totp_device