diff --git a/pagure/cli/admin.py b/pagure/cli/admin.py index 7679b73..f3791a2 100644 --- a/pagure/cli/admin.py +++ b/pagure/cli/admin.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """ - (c) 2017 - Copyright Red Hat Inc + (c) 2017-2018 - Copyright Red Hat Inc Authors: Pierre-Yves Chibon @@ -17,6 +17,7 @@ import os import sys import arrow +from six.moves import input if 'PAGURE_CONFIG' not in os.environ \ and os.path.exists('/etc/pagure/pagure.cfg'): @@ -242,7 +243,7 @@ def _parser_update_watch(subparser): def _parser_read_only(subparser): - """ Set up the CLI argument parser for the refresh-gitolite action. + """ Set up the CLI argument parser for the read-only action. :arg subparser: an argparse subparser allowing to have action's specific arguments @@ -263,6 +264,28 @@ def _parser_read_only(subparser): local_parser.set_defaults(func=do_read_only) +def _parser_new_group(subparser): + """ Set up the CLI argument parser for the new-group action. + + :arg subparser: an argparse subparser allowing to have action's specific + arguments + + """ + local_parser = subparser.add_parser( + 'new-group', + help='Create a new group on this pagure instance') + local_parser.add_argument('group_name', help="Name of the group") + local_parser.add_argument( + 'username', + help="Name of the user creating the group " + "(will be added to the group once created)") + local_parser.add_argument( + '--display', help="Display name of the group") + local_parser.add_argument( + '--description', help="Short description of the group") + local_parser.set_defaults(func=do_new_group) + + def parse_arguments(args=None): """ Set-up the argument parsing. """ parser = argparse.ArgumentParser( @@ -299,6 +322,9 @@ def parse_arguments(args=None): # read-only _parser_read_only(subparser) + # new-group + _parser_new_group(subparser) + return parser.parse_args(args) @@ -676,6 +702,49 @@ def do_read_only(args): project.fullname, args.ro.lower() == 'true')) +def do_new_group(args): + """ Create a new group in this pagure instance. + + :arg args: the argparse object returned by ``parse_arguments()``. + + """ + + _log.debug('name: %s', args.group_name) + _log.debug('display-name: %s', args.display) + _log.debug('description: %s', args.description) + _log.debug('username: %s', args.username) + + # Validate user + pagure.lib.get_user(session, args.username) + + if not args.username: + raise pagure.exceptions.PagureException( + 'An username must be provided to associate with the group') + + if not args.display: + raise pagure.exceptions.PagureException( + 'A display name must be provided for the group') + + if pagure.config.config.get('ENABLE_GROUP_MNGT') is False: + print('Group management has been turned off for this pagure instance') + if not _ask_confirmation(): + return + + msg = pagure.lib.add_group( + session=session, + group_name=args.group_name, + display_name=args.display, + description=args.description, + group_type='user', + user=args.username, + is_admin=True, + blacklist=pagure.config.config['BLACKLISTED_GROUPS'], + ) + session.commit() + print('Group `%s` created.' % args.group_name) + print(msg) + + def main(): """ Start of the application. """ diff --git a/tests/test_pagure_admin.py b/tests/test_pagure_admin.py index 7aedbf0..6b6f14d 100644 --- a/tests/test_pagure_admin.py +++ b/tests/test_pagure_admin.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """ - (c) 2017 - Copyright Red Hat Inc + (c) 2017-2018 - Copyright Red Hat Inc Authors: Pierre-Yves Chibon @@ -53,7 +53,7 @@ class PagureAdminAdminTokenEmptytests(tests.Modeltests): with self.assertRaises(pagure.exceptions.PagureException) as cm: pagure.cli.admin.do_create_admin_token(args) self.assertEqual( - cm.exception.args[0], + cm.exception.args[0], 'No user "pingou" found' ) @@ -651,7 +651,7 @@ class PagureAdminGetWatchTests(tests.Modeltests): with self.assertRaises(pagure.exceptions.PagureException) as cm: pagure.cli.admin.do_get_watch_status(args) self.assertEqual( - cm.exception.args[0], + cm.exception.args[0], 'No project found with: foobar' ) @@ -666,7 +666,7 @@ class PagureAdminGetWatchTests(tests.Modeltests): with self.assertRaises(pagure.exceptions.PagureException) as cm: pagure.cli.admin.do_get_watch_status(args) self.assertEqual( - cm.exception.args[0], + cm.exception.args[0], 'Invalid project name, has more than one "/": fo/o/bar', ) @@ -680,7 +680,7 @@ class PagureAdminGetWatchTests(tests.Modeltests): with self.assertRaises(pagure.exceptions.PagureException) as cm: pagure.cli.admin.do_get_watch_status(args) self.assertEqual( - cm.exception.args[0], + cm.exception.args[0], 'No user "beebop" found' ) @@ -814,7 +814,7 @@ class PagureAdminUpdateWatchTests(tests.Modeltests): with self.assertRaises(pagure.exceptions.PagureException) as cm: pagure.cli.admin.do_update_watch_status(args) self.assertEqual( - cm.exception.args[0], + cm.exception.args[0], 'No project found with: foob' ) @@ -830,7 +830,7 @@ class PagureAdminUpdateWatchTests(tests.Modeltests): with self.assertRaises(pagure.exceptions.PagureException) as cm: pagure.cli.admin.do_update_watch_status(args) self.assertEqual( - cm.exception.args[0], + cm.exception.args[0], 'Invalid project name, has more than one "/": fo/o/b', ) @@ -845,7 +845,7 @@ class PagureAdminUpdateWatchTests(tests.Modeltests): with self.assertRaises(pagure.exceptions.PagureException) as cm: pagure.cli.admin.do_update_watch_status(args) self.assertEqual( - cm.exception.args[0], + cm.exception.args[0], 'No user "foob" found' ) @@ -861,7 +861,7 @@ class PagureAdminUpdateWatchTests(tests.Modeltests): with self.assertRaises(pagure.exceptions.PagureException) as cm: pagure.cli.admin.do_update_watch_status(args) self.assertEqual( - cm.exception.args[0], + cm.exception.args[0], 'Invalid status provided: 10 not in -1, 0, 1, 2, 3' ) @@ -965,7 +965,7 @@ class PagureAdminReadOnlyTests(tests.Modeltests): with self.assertRaises(pagure.exceptions.PagureException) as cm: pagure.cli.admin.do_read_only(args) self.assertEqual( - cm.exception.args[0], + cm.exception.args[0], 'No project found with: foob' ) @@ -982,7 +982,7 @@ class PagureAdminReadOnlyTests(tests.Modeltests): with self.assertRaises(pagure.exceptions.PagureException) as cm: pagure.cli.admin.do_read_only(args) self.assertEqual( - cm.exception.args[0], + cm.exception.args[0], 'Invalid project name, has more than one "/": fo/o/b' ) @@ -1107,5 +1107,163 @@ class PagureAdminReadOnlyTests(tests.Modeltests): 'is set to True\n', output) +class PagureNewGroupTests(tests.Modeltests): + """ Tests for pagure-admin new-group """ + + populate_db = False + + def setUp(self): + """ Set up the environnment, ran before every tests. """ + super(PagureNewGroupTests, self).setUp() + pagure.cli.admin.session = self.session + + # Create the user pingou + item = pagure.lib.model.User( + user='pingou', + fullname='PY C', + password='foo', + default_email='bar@pingou.com', + ) + self.session.add(item) + item = pagure.lib.model.UserEmail( + user_id=1, + email='bar@pingou.com') + self.session.add(item) + + self.session.commit() + + # Make the imported pagure use the correct db session + pagure.cli.admin.session = self.session + + groups = pagure.lib.search_groups(self.session) + self.assertEqual(len(groups), 0) + + def test_missing_display_name(self): + """ Test the new-group function of pagure-admin when the display name + is missing from the args. + """ + + args = munch.Munch({ + 'group_name': 'foob', + 'display': None, + 'description': None, + 'username': 'pingou', + }) + with self.assertRaises(pagure.exceptions.PagureException) as cm: + pagure.cli.admin.do_new_group(args) + self.assertEqual( + cm.exception.args[0], + 'A display name must be provided for the group' + ) + + groups = pagure.lib.search_groups(self.session) + self.assertEqual(len(groups), 0) + + def test_missing_username(self): + """ Test the new-group function of pagure-admin when the username + is missing from the args. + """ + + args = munch.Munch({ + 'group_name': 'foob', + 'display': 'foo group', + 'description': None, + 'username': None, + }) + + with self.assertRaises(pagure.exceptions.PagureException) as cm: + pagure.cli.admin.do_new_group(args) + + self.assertEqual( + cm.exception.args[0], + 'An username must be provided to associate with the group' + ) + + groups = pagure.lib.search_groups(self.session) + self.assertEqual(len(groups), 0) + + def test_new_group(self): + """ Test the new-group function of pagure-admin when all arguments + are provided. + """ + + args = munch.Munch({ + 'group_name': 'foob', + 'display': 'foo group', + 'description': None, + 'username': 'pingou', + }) + + pagure.cli.admin.do_new_group(args) + + groups = pagure.lib.search_groups(self.session) + self.assertEqual(len(groups), 1) + + @patch.dict('pagure.config.config', {'ENABLE_GROUP_MNGT': False}) + @patch('pagure.cli.admin._ask_confirmation') + def test_new_group_grp_mngt_off_no(self, conf): + """ Test the new-group function of pagure-admin when all arguments + are provided and ENABLE_GROUP_MNGT if off in the config and the user + replies no to the question. + """ + conf.return_value = False + + args = munch.Munch({ + 'group_name': 'foob', + 'display': 'foo group', + 'description': None, + 'username': 'pingou', + }) + + pagure.cli.admin.do_new_group(args) + + groups = pagure.lib.search_groups(self.session) + self.assertEqual(len(groups), 0) + + @patch.dict('pagure.config.config', {'ENABLE_GROUP_MNGT': False}) + @patch('pagure.cli.admin._ask_confirmation') + def test_new_group_grp_mngt_off_yes(self, conf): + """ Test the new-group function of pagure-admin when all arguments + are provided and ENABLE_GROUP_MNGT if off in the config and the user + replies yes to the question. + """ + conf.return_value = True + + args = munch.Munch({ + 'group_name': 'foob', + 'display': 'foo group', + 'description': None, + 'username': 'pingou', + }) + + pagure.cli.admin.do_new_group(args) + + groups = pagure.lib.search_groups(self.session) + self.assertEqual(len(groups), 1) + + @patch.dict('pagure.config.config', {'BLACKLISTED_GROUPS': ['foob']}) + def test_new_group_grp_mngt_off_yes(self): + """ Test the new-group function of pagure-admin when all arguments + are provided but the group is black listed. + """ + + args = munch.Munch({ + 'group_name': 'foob', + 'display': 'foo group', + 'description': None, + 'username': 'pingou', + }) + + with self.assertRaises(pagure.exceptions.PagureException) as cm: + pagure.cli.admin.do_new_group(args) + + self.assertEqual( + cm.exception.args[0], + 'This group name has been blacklisted, please choose another one' + ) + + groups = pagure.lib.search_groups(self.session) + self.assertEqual(len(groups), 0) + if __name__ == '__main__': unittest.main(verbosity=2)