Source code for django_otp.plugins.otp_email.models
from __future__ import absolute_import, division, print_function, unicode_literals
from binascii import unhexlify
from django.core.mail import send_mail
from django.db import models
from django.template.loader import render_to_string
from django_otp.models import Device
from django_otp.oath import totp
from django_otp.util import hex_validator, random_hex
from .conf import settings
def default_key():
return random_hex(20)
def key_validator(value):
return hex_validator()(value)
[docs]class EmailDevice(Device):
"""
A :class:`~django_otp.models.Device` that delivers a token to the user's
registered email address (``user.email``). This is intended for
demonstration purposes; if you allow users to reset their passwords via
email, then this provides no security benefits.
.. attribute:: key
*CharField*: A hex-encoded secret key of up to 40 bytes. (Default: 20
random bytes)
"""
key = models.CharField(max_length=80,
validators=[key_validator],
default=default_key,
help_text='A hex-encoded secret key of up to 20 bytes.')
@property
def bin_key(self):
return unhexlify(self.key.encode())
def generate_challenge(self):
token = totp(self.bin_key)
body = render_to_string('otp/email/token.txt', {'token': token})
send_mail(settings.OTP_EMAIL_SUBJECT,
body,
settings.OTP_EMAIL_SENDER,
[self.user.email])
message = "sent by email"
return message
def verify_token(self, token):
try:
token = int(token)
except Exception:
verified = False
else:
verified = any(totp(self.bin_key, drift=drift) == token for drift in [0, -1])
return verified