Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: portal backend 376 #150

Merged
merged 2 commits into from
Jan 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions codeforlife/user/signals/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
"""

# NOTE: Need to import signals so they are discoverable by Django.
from .auth_factor import auth_factor__post_delete
from .teacher import teacher_receiver
from .user import user_receiver
25 changes: 25 additions & 0 deletions codeforlife/user/signals/auth_factor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
"""
© Ocado Group
Created on 17/01/2025 at 15:55:22(+00:00).
"""

import pyotp
from django.db.models import signals
from django.dispatch import receiver

from ..models import AuthFactor

# pylint: disable=missing-function-docstring
# pylint: disable=unused-argument


@receiver(signals.post_delete, sender=AuthFactor)
def auth_factor__post_delete(sender, instance: AuthFactor, **kwargs):
# Create new secret to ensure secrets are not recycled.
if instance.type == AuthFactor.Type.OTP:
otp_secret = instance.user.userprofile.otp_secret
# Ensure the randomly generated new secret is different to the previous.
while otp_secret == instance.user.userprofile.otp_secret:
instance.user.userprofile.otp_secret = pyotp.random_base32()

instance.user.userprofile.save(update_fields=["otp_secret"])
28 changes: 28 additions & 0 deletions codeforlife/user/signals/auth_factor_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"""
© Ocado Group
Created on 17/01/2025 at 16:04:46(+00:00).
"""

from django.test import TestCase

from ..models import AuthFactor


# pylint: disable-next=missing-class-docstring
class TestAuthFactor(TestCase):
fixtures = ["school_2"]

def test_post_delete(self):
"""Deleting an otp-auth-factor assigns a new otp-secret to its user."""
auth_factor = AuthFactor.objects.filter(
type=AuthFactor.Type.OTP
).first()
assert auth_factor

userprofile = auth_factor.user.userprofile
otp_secret = userprofile.otp_secret

auth_factor.delete()

userprofile.refresh_from_db()
assert otp_secret != userprofile.otp_secret