From 41350ba47f26222a8f6e3a86b8b37d385fd8c3a4 Mon Sep 17 00:00:00 2001 From: Jelle van der Waa Date: Tue, 23 Oct 2018 22:53:50 +0200 Subject: [PATCH] Add retire_user command --- devel/management/commands/retire_user.py | 72 ++++++++++++++++++++++++ devel/tests/test_retire_user.py | 68 ++++++++++++++++++++++ 2 files changed, 140 insertions(+) create mode 100644 devel/management/commands/retire_user.py create mode 100644 devel/tests/test_retire_user.py diff --git a/devel/management/commands/retire_user.py b/devel/management/commands/retire_user.py new file mode 100644 index 00000000..f68ad604 --- /dev/null +++ b/devel/management/commands/retire_user.py @@ -0,0 +1,72 @@ +# -*- coding: utf-8 -*- +""" +retire_user + +Retire a user by de-activing the account and moving the user to the retired +group. + +Usage ./manage.py retire_user user +""" + +import logging +import sys + +from django.contrib.auth.models import User, Group +from django.core.management.base import BaseCommand, CommandError + +from devel.models import UserProfile + + +logging.basicConfig( + level=logging.WARNING, + format=u'%(asctime)s -> %(levelname)s: %(message)s', + datefmt=u'%Y-%m-%d %H:%M:%S', + stream=sys.stderr) +logger = logging.getLogger() + +MAPPING = { + 'Developers': 'Retired Developers', + 'Trusted Users': 'Retired Trusted Users', + 'Support Staff': 'Retired Support Staff', +} + + +class Command(BaseCommand): + help = "Retires a user by deactiving the user and moving the group membership to retired groups." + missing_args_message = 'missing argument user.' + + def add_arguments(self, parser): + parser.add_argument('user', type=str) + + + def handle(self, *args, **options): + v = int(options.get('verbosity', 0)) + if v == 0: + logger.level = logging.ERROR + elif v == 1: + logger.level = logging.INFO + elif v >= 2: + logger.level = logging.DEBUG + + try: + user = User.objects.get(username=options['user']) + except User.DoesNotExist: + raise CommandError(u"Failed to find User '{}'".format(options['user'])) + + try: + profile = UserProfile.objects.get(user=user) + except UserProfile.DoesNotExist: + raise CommandError(u"Failed to find UserProfile") + + # Set user inactive + user.is_active = False + + # Clear allowed repos + profile.allowed_repos.clear() + + # Move Groups to Retired. + del_groups = list(user.groups.filter(name__in=MAPPING.keys())) + add_groups = [Group.objects.get(name=MAPPING.get(group.name)) for group in del_groups] + user.groups.remove(*del_groups) + user.groups.add(*add_groups) + user.save() diff --git a/devel/tests/test_retire_user.py b/devel/tests/test_retire_user.py new file mode 100644 index 00000000..4e1c3985 --- /dev/null +++ b/devel/tests/test_retire_user.py @@ -0,0 +1,68 @@ +from django.core.management import call_command +from django.core.management.base import CommandError +from django.contrib.auth.models import User, Group +from django.test import TransactionTestCase + +from main.models import Repo + +from devel.models import UserProfile + + +class RetireUsertest(TransactionTestCase): + fixtures = ['main/fixtures/arches.json', 'main/fixtures/repos.json'] + + + def setUp(self): + self.username = 'joe' + self.user = User.objects.create(username=self.username, first_name="Joe", + last_name="User", email="user1@example.com") + + self.profile = UserProfile.objects.create(user=self.user, + public_email="{}@awesome.com".format(self.user.username)) + for name in ['Developers', 'Retired Developers']: + Group.objects.create(name=name) + + def tearDown(self): + self.profile.delete() + self.user.delete() + + def test_invalid_args(self): + with self.assertRaises(CommandError) as e: + call_command('retire_user') + self.assertIn('missing argument user.', str(e.exception)) + + def test_user_not_found(self): + with self.assertRaises(CommandError) as e: + call_command('retire_user', 'user1') + self.assertIn("Failed to find User 'user1'", str(e.exception)) + + def test_userprofile_missing(self): + user = User.objects.create(username='user2', first_name="Jane", + last_name="User2", email="user2@example.com") + + with self.assertRaises(CommandError) as e: + call_command('retire_user', user.username) + self.assertIn("Failed to find UserProfile", str(e.exception)) + user.delete() + + def test_user_inactive(self): + call_command('retire_user', self.username) + user = User.objects.get(username=self.username) + self.assertEqual(user.is_active, False) + + def test_user_moved_groups(self): + self.user.groups.add(Group.objects.get(name='Developers')) + self.user.save() + + call_command('retire_user', self.username) + user = User.objects.get(username=self.username) + groups = [Group.objects.get(name='Retired Developers')] + self.assertEqual(list(user.groups.all()), groups) + + def test_user_repos(self): + self.profile.allowed_repos.add(Repo.objects.get(name='Core')) + self.profile.save() + + call_command('retire_user', self.username) + profile = UserProfile.objects.get(user=self.user) + self.assertEqual(len(profile.allowed_repos.all()), 0)