50 lines
1.6 KiB
Python
50 lines
1.6 KiB
Python
|
from django import forms
|
||
|
from django.core.exceptions import PermissionDenied
|
||
|
|
||
|
from ..models.auth import OTPSession
|
||
|
|
||
|
|
||
|
class OTPForm(forms.Form):
|
||
|
otp = forms.IntegerField(widget=forms.TextInput(attrs={"autofocus": True}))
|
||
|
|
||
|
error_messages = {
|
||
|
"invalid_otp": (
|
||
|
"The one-time password you entered was incorrect. Please try again."
|
||
|
),
|
||
|
"session_expired": "Your session has expired, please try again."
|
||
|
}
|
||
|
|
||
|
def __init__(self, request=None, *args, **kwargs):
|
||
|
self.request = request
|
||
|
self.user_cache = None
|
||
|
super().__init__(*args, **kwargs)
|
||
|
|
||
|
# Set the max length and label for the "username" field.
|
||
|
otp_max_length = 8
|
||
|
self.fields["otp"].max_length = otp_max_length
|
||
|
self.fields["otp"].widget.attrs["maxlength"] = otp_max_length
|
||
|
|
||
|
if self.fields["otp"].label is None:
|
||
|
self.fields["otp"].label = "One-Time Password"
|
||
|
|
||
|
def clean(self):
|
||
|
otp = self.cleaned_data.get("otp")
|
||
|
session = self.get_session()
|
||
|
|
||
|
if not session.is_alive():
|
||
|
raise PermissionDenied(self.error_messages["session_expired"])
|
||
|
|
||
|
if otp is None or not session.validate_token(otp):
|
||
|
raise self.get_invalid_otp_error()
|
||
|
|
||
|
return self.cleaned_data
|
||
|
|
||
|
def get_session(self):
|
||
|
return OTPSession.objects.get(uuid=self.request.session["OTPSession"])
|
||
|
|
||
|
def get_invalid_otp_error(self):
|
||
|
return ValidationError(
|
||
|
self.error_messages["invalid_otp"],
|
||
|
code="invalid_otp",
|
||
|
params={"otp": "One-Time Password"},
|
||
|
)
|