diff --git a/src/backend/InvenTree/users/migrations/0011_auto_20240119_1659.py b/src/backend/InvenTree/users/migrations/0011_auto_20240119_1659.py index 9e8d71ccd2..df72a83dd4 100644 --- a/src/backend/InvenTree/users/migrations/0011_auto_20240119_1659.py +++ b/src/backend/InvenTree/users/migrations/0011_auto_20240119_1659.py @@ -1,52 +1,18 @@ # Generated by Django 3.2.23 on 2024-01-19 16:59 -import base64 - -from django.db import OperationalError, migrations - -from allauth.mfa.adapter import get_adapter -from allauth.mfa.models import Authenticator -from django_otp.plugins.otp_static.models import StaticDevice -from django_otp.plugins.otp_totp.models import TOTPDevice - - -def move_mfa(apps, schema_editor): - """Data migration to switch to django-allauth's new built-in MFA.""" - adapter = get_adapter() - try: - TOTPDevice.objects.all().count() - except OperationalError: - # The table may not exist - print('Skipping totp migration as model does not exist') - return - - authenticators = [] - for totp in TOTPDevice.objects.filter(confirmed=True).iterator(): - recovery_codes = set() - for sdevice in StaticDevice.objects.filter( - confirmed=True, user_id=totp.user_id - ).iterator(): - recovery_codes.update(sdevice.token_set.values_list('token', flat=True)) - secret = base64.b32encode(bytes.fromhex(totp.key)).decode('ascii') - totp_authenticator = Authenticator( - user_id=totp.user_id, - type=Authenticator.Type.TOTP, - data={'secret': adapter.encrypt(secret)}, - ) - authenticators.append(totp_authenticator) - authenticators.append( - Authenticator( - user_id=totp.user_id, - type=Authenticator.Type.RECOVERY_CODES, - data={'migrated_codes': [adapter.encrypt(c) for c in recovery_codes]}, - ) - ) - Authenticator.objects.bulk_create(authenticators) +from django.db import migrations class Migration(migrations.Migration): - dependencies = [('users', '0010_alter_apitoken_key'), ('otp_static', '0002_throttling'), ('otp_totp', '0002_auto_20190420_0723')] + dependencies = [ + ('users', '0010_alter_apitoken_key'), + ('otp_static', '0002_throttling'), + ('otp_totp', '0002_auto_20190420_0723'), + ('mfa', '0002_authenticator_timestamps'), + ] operations = [ - migrations.RunPython(move_mfa, reverse_code=migrations.RunPython.noop) + migrations.RunPython( + migrations.RunPython.noop, reverse_code=migrations.RunPython.noop + ) ] diff --git a/src/backend/InvenTree/users/migrations/0012_migrate_mfa_20240408_1659.py b/src/backend/InvenTree/users/migrations/0012_migrate_mfa_20240408_1659.py new file mode 100644 index 0000000000..f6dbb12a07 --- /dev/null +++ b/src/backend/InvenTree/users/migrations/0012_migrate_mfa_20240408_1659.py @@ -0,0 +1,52 @@ +# Generated by Django 3.2.23 on 2024-01-19 16:59 + +import base64 + +from django.db import OperationalError, migrations + +from allauth.mfa.adapter import get_adapter +from allauth.mfa.models import Authenticator +from django_otp.plugins.otp_static.models import StaticDevice +from django_otp.plugins.otp_totp.models import TOTPDevice + + +def move_mfa(apps, schema_editor): + """Data migration to switch to django-allauth's new built-in MFA.""" + adapter = get_adapter() + try: + TOTPDevice.objects.all().count() + except OperationalError: + # The table may not exist + print('Skipping totp migration as model does not exist') + return + + authenticators = [] + for totp in TOTPDevice.objects.filter(confirmed=True).iterator(): + recovery_codes = set() + for sdevice in StaticDevice.objects.filter( + confirmed=True, user_id=totp.user_id + ).iterator(): + recovery_codes.update(sdevice.token_set.values_list('token', flat=True)) + secret = base64.b32encode(bytes.fromhex(totp.key)).decode('ascii') + totp_authenticator = Authenticator( + user_id=totp.user_id, + type=Authenticator.Type.TOTP, + data={'secret': adapter.encrypt(secret)}, + ) + authenticators.append(totp_authenticator) + authenticators.append( + Authenticator( + user_id=totp.user_id, + type=Authenticator.Type.RECOVERY_CODES, + data={'migrated_codes': [adapter.encrypt(c) for c in recovery_codes]}, + ) + ) + Authenticator.objects.bulk_create(authenticators) + + +class Migration(migrations.Migration): + dependencies = [('users', '0011_auto_20240119_1659')] + + operations = [ + migrations.RunPython(move_mfa, reverse_code=migrations.RunPython.noop) + ]