File tree 3 files changed +54
-0
lines changed
3 files changed +54
-0
lines changed Original file line number Diff line number Diff line change 4
4
"""
5
5
6
6
# NOTE: Need to import signals so they are discoverable by Django.
7
+ from .auth_factor import auth_factor__post_delete
7
8
from .teacher import teacher_receiver
8
9
from .user import user_receiver
Original file line number Diff line number Diff line change
1
+ """
2
+ © Ocado Group
3
+ Created on 17/01/2025 at 15:55:22(+00:00).
4
+ """
5
+
6
+ import pyotp
7
+ from django .db .models import signals
8
+ from django .dispatch import receiver
9
+
10
+ from ..models import AuthFactor
11
+
12
+ # pylint: disable=missing-function-docstring
13
+ # pylint: disable=unused-argument
14
+
15
+
16
+ @receiver (signals .post_delete , sender = AuthFactor )
17
+ def auth_factor__post_delete (sender , instance : AuthFactor , ** kwargs ):
18
+ # Create new secret to ensure secrets are not recycled.
19
+ if instance .type == AuthFactor .Type .OTP :
20
+ otp_secret = instance .user .userprofile .otp_secret
21
+ # Ensure the randomly generated new secret is different to the previous.
22
+ while otp_secret == instance .user .userprofile .otp_secret :
23
+ instance .user .userprofile .otp_secret = pyotp .random_base32 ()
24
+
25
+ instance .user .userprofile .save (update_fields = ["otp_secret" ])
Original file line number Diff line number Diff line change
1
+ """
2
+ © Ocado Group
3
+ Created on 17/01/2025 at 16:04:46(+00:00).
4
+ """
5
+
6
+ from django .test import TestCase
7
+
8
+ from ..models import AuthFactor
9
+
10
+
11
+ # pylint: disable-next=missing-class-docstring
12
+ class TestAuthFactor (TestCase ):
13
+ fixtures = ["school_2" ]
14
+
15
+ def test_post_delete (self ):
16
+ """Deleting an otp-auth-factor assigns a new otp-secret to its user."""
17
+ auth_factor = AuthFactor .objects .filter (
18
+ type = AuthFactor .Type .OTP
19
+ ).first ()
20
+ assert auth_factor
21
+
22
+ userprofile = auth_factor .user .userprofile
23
+ otp_secret = userprofile .otp_secret
24
+
25
+ auth_factor .delete ()
26
+
27
+ userprofile .refresh_from_db ()
28
+ assert otp_secret != userprofile .otp_secret
You can’t perform that action at this time.
0 commit comments