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"}, )