Initial mfa support (for internal users) #93591

Merged
Oleg-Komarov merged 46 commits from mfa into main 2024-08-29 11:44:06 +02:00
2 changed files with 9 additions and 6 deletions
Showing only changes of commit 2d22c25536 - Show all commits

View File

@ -96,7 +96,6 @@ class TotpView(mixins.MfaRequiredIfConfiguredMixin, FormView):
kwargs = self.get_form_kwargs()
key = self.request.POST.get('key', random_hex(20))
Oleg-Komarov marked this conversation as resolved Outdated

same as above

same as above
kwargs['initial']['key'] = key
kwargs['initial']['signature'] = TotpMfaForm.sign(kwargs['user'], key)
return TotpMfaForm(**kwargs)
def get_form_kwargs(self):

View File

@ -95,6 +95,9 @@ class TotpMfaForm(forms.Form):
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user', None)
kwargs['initial']['signature'] = self.sign(
f"{self.user.email}_{kwargs['initial']['key']}"
)
super().__init__(*args, **kwargs)
def clean(self):
@ -102,7 +105,7 @@ class TotpMfaForm(forms.Form):
code = self.data.get('code')
key = self.data.get('key')
signature = self.cleaned_data.get('signature')
if not self.verify_signature(self.user, key, signature):
if not self.verify_signature(f'{self.user.email}_{key}', signature):
raise forms.ValidationError(_('Invalid signature'))
self.cleaned_data['key'] = key
if not TOTP(unhexlify(key)).verify(int(code), tolerance=1):
@ -115,14 +118,15 @@ class TotpMfaForm(forms.Form):
EncryptedTOTPDevice.objects.create(encrypted_key=key, key='', name=name, user=self.user)
@classmethod
def sign(cls, user, key):
def sign(cls, payload):
signer = TimestampSigner()
return signer.sign(f'{user.email}_{key}')
return signer.sign(payload)
@classmethod
def verify_signature(cls, user, key, signature, max_age=3600):
def verify_signature(cls, payload, signature, max_age=3600):
signer = TimestampSigner()
try:
return f'{user.email}_{key}' == signer.unsign(signature, max_age=max_age)
return payload == signer.unsign(signature, max_age=max_age)
except BadSignature:
return False