-
Notifications
You must be signed in to change notification settings - Fork 52
Expand file tree
/
Copy pathforms.py
More file actions
87 lines (68 loc) · 2.59 KB
/
forms.py
File metadata and controls
87 lines (68 loc) · 2.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import re
from django import forms
from django.contrib.auth import authenticate
from django.utils.translation import gettext_lazy as _
from django_otp.forms import OTPAuthenticationFormMixin
from django_otp.plugins.otp_totp.models import TOTPDevice
class TokenForm(OTPAuthenticationFormMixin, forms.Form):
otp_token = forms.CharField(required=True)
def __init__(self, user, *args, **kwargs):
self.user = user
super().__init__(*args, **kwargs)
self.fields["otp_token"].widget.attrs.update(
{"autofocus": "autofocus", "autocomplete": "off"}
)
def clean_otp_token(self):
'''Remove whitespace because authentication apps often present token
as "123 456". It is very confusing for user if this exact format
isn't supported.'''
return re.sub(r'\s', '', self.cleaned_data.get('otp_token', ''))
def clean(self):
self.clean_otp(self.user)
return self.cleaned_data
class DeviceForm(forms.ModelForm):
otp_token = forms.CharField(
label=_("OTP token"),
required=True,
help_text=_(
"Enter the numeric code displayed on your device after scanning the QR code"
),
)
name = forms.CharField(
label=_("Name"),
required=True,
help_text=_("The human-readable name of this device."),
)
password = forms.CharField(
label=_("Current password"),
help_text=_("As an extra security measure, we need your current password."),
widget=forms.PasswordInput(),
)
class Meta:
model = TOTPDevice
fields = ["name", "otp_token"]
def __init__(self, request, **kwargs):
super().__init__(**kwargs)
self.fields["otp_token"].widget.attrs.update(
{"autofocus": "autofocus", "autocomplete": "off"}
)
if self.instance.confirmed:
del self.fields["otp_token"]
self.request = request
def clean_otp_token(self):
token = self.cleaned_data.get("otp_token")
if token and self.instance.verify_token(token):
return token
raise forms.ValidationError(
_("Invalid token. Please make sure you have entered it correctly."),
code="invalid",
)
def clean_password(self):
password = self.cleaned_data.get("password")
if not authenticate(
self.request, username=self.request.user.get_username(), password=password
):
raise forms.ValidationError(_("Invalid password"))
def save(self):
self.instance.confirmed = True
self.instance.save()