Skip to content

Commit 0eab8a3

Browse files
committed
fixup!: mfa
1 parent a711a32 commit 0eab8a3

File tree

2 files changed

+49
-15
lines changed

2 files changed

+49
-15
lines changed

kobo/apps/audit_log/tests/test_models.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
@patch('kobo.apps.audit_log.models.get_human_readable_client_user_agent', return_value='source')
1919
@patch('kobo.apps.audit_log.models.get_client_ip', return_value='127.0.0.1')
20-
class AuditLogTestCase(BaseTestCase):
20+
class AuditLogModelTestCase(BaseTestCase):
2121

2222
@classmethod
2323
def setUpClass(cls):
@@ -47,16 +47,16 @@ def _check_common_fields(self, audit_log: AuditLog, user):
4747

4848
def test_basic_create_auth_log_from_request(self, patched_ip, patched_source):
4949
request = self._create_request(
50-
'/accounts/login/', AnonymousUser(), AuditLogTestCase.super_user
50+
'/accounts/login/', AnonymousUser(), AuditLogModelTestCase.super_user
5151
)
5252
log: AuditLog = AuditLog.create_access_log_for_request(request)
53-
self._check_common_fields(log, AuditLogTestCase.super_user)
53+
self._check_common_fields(log, AuditLogModelTestCase.super_user)
5454
self.assertDictEqual(
5555
log.metadata,
5656
{
5757
'ip_address': '127.0.0.1',
5858
'source': 'source',
59-
'auth_type': AuditLogTestCase.super_user.backend,
59+
'auth_type': AuditLogModelTestCase.super_user.backend,
6060
},
6161
)
6262

@@ -67,7 +67,7 @@ def test_create_auth_log_from_loginas_request(self, patched_ip, patched_source):
6767
second_user.save()
6868
request = self._create_request(
6969
f'/admin/login/user/{second_user.id}/',
70-
AuditLogTestCase.super_user,
70+
AuditLogModelTestCase.super_user,
7171
second_user,
7272
)
7373
log: AuditLog = AuditLog.create_access_log_for_request(request)
@@ -78,19 +78,19 @@ def test_create_auth_log_from_loginas_request(self, patched_ip, patched_source):
7878
'ip_address': '127.0.0.1',
7979
'source': 'source',
8080
'auth_type': LOGINAS_AUTH_TYPE,
81-
'initial_user_uid': AuditLogTestCase.super_user.extra_details.uid,
82-
'initial_user_username': AuditLogTestCase.super_user.username,
81+
'initial_user_uid': AuditLogModelTestCase.super_user.extra_details.uid,
82+
'initial_user_username': AuditLogModelTestCase.super_user.username,
8383
},
8484
)
8585

8686
def test_create_auth_log_with_different_auth_type(self, patched_ip, patched_source):
8787
request = self._create_request(
88-
'/api/v2/assets/', AnonymousUser(), AuditLogTestCase.super_user
88+
'/api/v2/assets/', AnonymousUser(), AuditLogModelTestCase.super_user
8989
)
9090
log: AuditLog = AuditLog.create_access_log_for_request(
9191
request, authentication_type='Token'
9292
)
93-
self._check_common_fields(log, AuditLogTestCase.super_user)
93+
self._check_common_fields(log, AuditLogModelTestCase.super_user)
9494
self.assertDictEqual(
9595
log.metadata,
9696
{
@@ -107,7 +107,7 @@ def test_create_auth_log_unknown_authenticator(self, patched_ip, patched_source)
107107
)
108108
second_user.save()
109109
request = self._create_request(
110-
f'/api/v2/assets/', AuditLogTestCase.super_user, second_user
110+
f'/api/v2/assets/', AuditLogModelTestCase.super_user, second_user
111111
)
112112
log: AuditLog = AuditLog.create_access_log_for_request(request)
113113
self._check_common_fields(log, second_user)

kobo/apps/audit_log/tests/test_signals.py

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,20 @@
33
from allauth.account.models import EmailAddress
44
from django.contrib.auth import get_user_model
55
from django.urls import resolve, reverse
6+
from trench.utils import get_mfa_model
67

8+
from kobo.apps.accounts.mfa.forms import MfaTokenForm
79
from kobo.apps.audit_log.models import AuditAction, AuditLog
810
from kpi.tests.base_test_case import BaseTestCase
911

1012

11-
class AuditLogTestCase(BaseTestCase):
13+
class AuditLogSignalsTestCase(BaseTestCase):
1214
"""
1315
Class for testing that logins produce AuditLogs.
1416
1517
Here we just test that AuditLogs are produced, not necessarily what they contain. More tests for what they contain
16-
are in test_models.py. Also, AuditLogs for more complicated login flows are tested as part of the tests for those
17-
flows to avoid copying lots of complicated setup.
18+
are in test_models.py. Also, AuditLogs for SSO logins are tested as part of the SSO tests
19+
to avoid copying lots of complicated setup.
1820
"""
1921

2022
@classmethod
@@ -37,7 +39,7 @@ def test_audit_log_created_on_login(self, patched_create):
3739
def test_simple_login(self):
3840
count = AuditLog.objects.count()
3941
self.assertEqual(count, 0)
40-
user = AuditLogTestCase.user
42+
user = AuditLogSignalsTestCase.user
4143
data = {
4244
'login': 'user',
4345
'password': 'pass',
@@ -52,7 +54,7 @@ def test_simple_login(self):
5254
self.assertEqual(audit_log.action, AuditAction.AUTH)
5355

5456
def test_login_with_email_verification(self):
55-
user = AuditLogTestCase.user
57+
user = AuditLogSignalsTestCase.user
5658
data = {
5759
'login': 'user',
5860
'password': 'pass',
@@ -68,3 +70,35 @@ def test_login_with_email_verification(self):
6870
audit_log = AuditLog.objects.first()
6971
self.assertEqual(audit_log.user.id, user.id)
7072
self.assertEqual(audit_log.action, AuditAction.AUTH)
73+
74+
def test_mfa_login(self):
75+
mfa_object = get_mfa_model().objects.create(
76+
user=AuditLogSignalsTestCase.user,
77+
secret='dummy_mfa_secret',
78+
name='app',
79+
is_primary=True,
80+
is_active=True,
81+
_backup_codes='dummy_encoded_codes',
82+
)
83+
mfa_object.save()
84+
email_address, _ = EmailAddress.objects.get_or_create(
85+
user=AuditLogSignalsTestCase.user
86+
)
87+
email_address.primary = True
88+
email_address.verified = True
89+
email_address.save()
90+
data = {
91+
'login': 'user',
92+
'password': 'pass',
93+
}
94+
self.client.post(reverse('kobo_login'), data=data, follow=True)
95+
# no audit log should be created yet because the MFA code hasn't been entered
96+
self.assertEqual(AuditLog.objects.count(), 0)
97+
98+
with patch('kobo.apps.accounts.mfa.forms.authenticate_second_step_command',
99+
return_value=AuditLogSignalsTestCase.user):
100+
self.client.post(reverse('mfa_token'), data={'code': '123456', 'ephemeral_token': 'dummy'}, follow=True)
101+
self.assertEqual(AuditLog.objects.count(), 1)
102+
audit_log = AuditLog.objects.first()
103+
self.assertEqual(audit_log.user.id, AuditLogSignalsTestCase.user.id)
104+
self.assertEqual(audit_log.action, AuditAction.AUTH)

0 commit comments

Comments
 (0)