Initial mfa support (for internal users) #93591
86
bid_main/tests/test_mfa.py
Normal file
86
bid_main/tests/test_mfa.py
Normal file
@ -0,0 +1,86 @@
|
||||
from unittest.mock import patch
|
||||
import re
|
||||
|
||||
from django.test.client import Client
|
||||
from django.test import TestCase
|
||||
from django.utils import timezone
|
||||
|
||||
from bid_main.tests.factories import UserFactory
|
||||
from mfa.models import devices_for_user
|
||||
|
||||
|
||||
@patch(
|
||||
'django.contrib.auth.base_user.AbstractBaseUser.check_password',
|
||||
new=lambda _, pwd: pwd == 'hunter2',
|
||||
)
|
||||
@patch(
|
||||
'django_otp.oath.TOTP.verify',
|
||||
new=lambda _, token, *args, **kwargs: int(token) == 123456,
|
||||
)
|
||||
class TestMfaRequredIfConfigured(TestCase):
|
||||
def setUp(self):
|
||||
self.user = UserFactory(
|
||||
confirmed_email_at=timezone.now(),
|
||||
privacy_policy_agreed=timezone.now(),
|
||||
)
|
||||
|
||||
def test_no_mfa(self):
|
||||
client = Client()
|
||||
response = client.post(
|
||||
'/login',
|
||||
{'username': self.user.email, 'password': 'hunter2'},
|
||||
follow=True,
|
||||
)
|
||||
# showing account page, after a redirect
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertContains(response, '<h2>Account</h2>')
|
||||
|
||||
def test_setup_totp(self):
|
||||
client = Client()
|
||||
response = client.post(
|
||||
'/login',
|
||||
{'username': self.user.email, 'password': 'hunter2'},
|
||||
follow=True,
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
response = client.get('/mfa/totp/')
|
||||
match = re.search(
|
||||
r'input type="hidden" name="key" value="([^"]+)"', str(response.content)
|
||||
)
|
||||
key = match.group(1)
|
||||
match = re.search(
|
||||
r'input type="hidden" name="signature" value="([^"]+)"', str(response.content)
|
||||
)
|
||||
signature = match.group(1)
|
||||
response = client.post(
|
||||
'/mfa/totp/',
|
||||
{'name': 'test totp device', 'code': '123456', 'key': key, 'signature': signature},
|
||||
follow=True
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(devices_for_user(self.user)[0].name, 'test totp device')
|
||||
|
||||
# emulating a different browser
|
||||
client = Client()
|
||||
response = client.post(
|
||||
'/login',
|
||||
{'username': self.user.email, 'password': 'hunter2'},
|
||||
follow=True,
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
# haven't reached the account page
|
||||
self.assertNotContains(response, '<h2>Account</h2>')
|
||||
self.assertContains(response, 'autocomplete="one-time-code"')
|
||||
match = re.search(
|
||||
r'input type="hidden" name="otp_device" value="([^"]+)"', str(response.content)
|
||||
)
|
||||
otp_device = match.group(1)
|
||||
|
||||
response = client.post(
|
||||
'/login',
|
||||
{'otp_device': otp_device, 'otp_token': '123456'},
|
||||
follow=True,
|
||||
)
|
||||
# have reached the account page
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertContains(response, '<h2>Account</h2>')
|
Loading…
Reference in New Issue
Block a user