diff --git a/allianceauth/authentication/management/__init__.py b/allianceauth/authentication/management/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/allianceauth/authentication/management/commands/__init__.py b/allianceauth/authentication/management/commands/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/allianceauth/authentication/management/commands/checkmains.py b/allianceauth/authentication/management/commands/checkmains.py new file mode 100644 index 00000000..6c4b7fb2 --- /dev/null +++ b/allianceauth/authentication/management/commands/checkmains.py @@ -0,0 +1,20 @@ +from django.core.management.base import BaseCommand +from allianceauth.authentication.models import UserProfile + + +class Command(BaseCommand): + help = 'Ensures all main characters have an active ownership' + + def handle(self, *args, **options): + profiles = UserProfile.objects.filter(main_character__isnull=False).filter( + main_character__character_ownership__isnull=True) + if profiles.exists(): + for profile in profiles: + self.stdout.write(self.style.ERROR( + '{0} does not have an ownership. Resetting user {1} main character.'.format(profile.main_character, + profile.user))) + profile.main_character = None + profile.save() + self.stdout.write(self.style.WARNING('Reset {0} main characters.'.format(profiles.count()))) + else: + self.stdout.write(self.style.SUCCESS('All main characters have active ownership.')) diff --git a/allianceauth/authentication/tests.py b/allianceauth/authentication/tests.py index 2e235455..fc558f41 100644 --- a/allianceauth/authentication/tests.py +++ b/allianceauth/authentication/tests.py @@ -1,5 +1,5 @@ from unittest import mock - +from io import StringIO from django.test import TestCase from django.contrib.auth.models import User from allianceauth.tests.auth_utils import AuthUtils @@ -15,6 +15,7 @@ from django.http.response import HttpResponse from django.contrib.auth.models import AnonymousUser from django.conf import settings from django.shortcuts import reverse +from django.core.management import call_command from urllib import parse MODULE_PATH = 'allianceauth.authentication' @@ -372,3 +373,30 @@ class CharacterOwnershipCheckTestCase(TestCase): filter.return_value.exists.return_value = False check_character_ownership(self.ownership) self.assertTrue(filter.return_value.delete.called) + + +class ManagementCommandTestCase(TestCase): + @classmethod + def setUpTestData(cls): + cls.user = AuthUtils.create_user('test user', disconnect_signals=True) + AuthUtils.add_main_character(cls.user, 'test character', '1', '2', 'test corp', 'test') + character = UserProfile.objects.get(user=cls.user).main_character + CharacterOwnership.objects.create(user=cls.user, character=character, owner_hash='test') + + def setUp(self): + self.stdout = StringIO() + + def test_ownership(self): + call_command('checkmains', stdout=self.stdout) + self.assertFalse(UserProfile.objects.filter(main_character__isnull=True).count()) + self.assertNotIn(self.user.username, self.stdout.getvalue()) + self.assertIn('All main characters', self.stdout.getvalue()) + + def test_no_ownership(self): + user = AuthUtils.create_user('v1 user', disconnect_signals=True) + AuthUtils.add_main_character(user, 'v1 character', '10', '20', 'test corp', 'test') + self.assertFalse(UserProfile.objects.filter(main_character__isnull=True).count()) + + call_command('checkmains', stdout=self.stdout) + self.assertEqual(UserProfile.objects.filter(main_character__isnull=True).count(), 1) + self.assertIn(user.username, self.stdout.getvalue()) diff --git a/docs/installation/auth/upgradev1.md b/docs/installation/auth/upgradev1.md index 0e0640ed..ecb720b4 100644 --- a/docs/installation/auth/upgradev1.md +++ b/docs/installation/auth/upgradev1.md @@ -74,6 +74,12 @@ Once you have confirmed states are correctly configured (or adjusted them as nee It should now be safe to bring workers online (`supervisorctl start myauth:`) and invite users to use the site. +## Securing User Accounts + +After migration users will have main characters without a method to check for character sales. After a brief period to allow your users to log in (and provide a refreshable token to use), it's a good idea to clear main characters of users who haven't yet logged in. This can be achieved with an included command: `python manage.py checkmains` + +A similar process can be used to ensure users who may have lost service permissions during the migration do not have active service accounts. This is done using `python manage.py validate_service_accounts`. + ## Help If something goes wrong during the migration reach out for help on [Gitter](https://gitter.im/R4stl1n/allianceauth) or open an [issue](https://github.com/allianceauth/allianceauth/issues). \ No newline at end of file