diff --git a/pagure/cli/admin.py b/pagure/cli/admin.py index 583e591..1c64290 100644 --- a/pagure/cli/admin.py +++ b/pagure/cli/admin.py @@ -346,13 +346,22 @@ def _parser_block_user(subparser): help="Prevents an user to interact with this pagure instance until " "the specified date", ) - local_parser.add_argument("username", help="Name of the user to block") + local_parser.add_argument( + "username", default=None, nargs="?", help="Name of the user to block" + ) local_parser.add_argument( "date", + nargs="?", default=None, help="Date before which the user is not welcome on this pagure " "instance", ) + local_parser.add_argument( + "--list", + default=False, + action="store_true", + help="List all blocked users", + ) local_parser.set_defaults(func=do_block_user) @@ -969,6 +978,41 @@ def do_list_groups(args): print("No groups found in this pagure instance.") +def do_list_blocked_users(args): + """ List all the blocked users. + + :arg args: the argparse object returned by ``parse_arguments()``. + + """ + date = None + if args.date: + try: + date = arrow.get(args.date, "YYYY-MM-DD").replace(tzinfo="UTC") + date = date.datetime + except Exception as err: + _log.exception(err) + raise pagure.exceptions.PagureException( + "Invalid date submitted: %s, not of the format " + "YYYY-MM-DD" % args.date + ) + + blocked_users = pagure.lib.query.get_blocked_users( + session, username=args.username or None, date=date + ) + if blocked_users: + print("Users blocked:") + for user in blocked_users: + print( + " %s - %s" + % ( + user.user.ljust(20), + user.refuse_sessions_before.isoformat(), + ) + ) + else: + print("No users are currently blocked") + + def do_block_user(args): """ Block the specified user from all interactions with pagure until the specified date. @@ -979,6 +1023,10 @@ def do_block_user(args): _log.debug("username: %s", args.username) _log.debug("date: %s", args.date) + _log.debug("list: %s", args.list) + + if args.list: + return do_list_blocked_users(args) if not args.username: raise pagure.exceptions.PagureException( @@ -999,9 +1047,7 @@ def do_block_user(args): print( "The user `%s` will be blocked from all interaction with this " - "pagure instance until: %s.", - user.username, - date.isoformat(), + "pagure instance until: %s." % (user.username, date.isoformat()) ) if not _ask_confirmation(): return diff --git a/pagure/lib/query.py b/pagure/lib/query.py index 571024b..137c868 100644 --- a/pagure/lib/query.py +++ b/pagure/lib/query.py @@ -142,6 +142,23 @@ def get_user_by_id(session, userid): return query.first() +def get_blocked_users(session, username=None, date=None): + """ Returns all the users that are blocked in this pagure instance. + """ + now = datetime.datetime.utcnow() + query = session.query(model.User).filter( + model.User.refuse_sessions_before >= (date or now) + ) + if username: + if "*" in username: + username = username.replace("*", "%") + query = query.filter(model.User.user.ilike(username)) + else: + query = query.filter(model.User.user == username) + + return query.all() + + def get_next_id(session, projectid): """ Returns the next identifier of a project ticket or pull-request based on the identifier already in the database. diff --git a/tests/test_pagure_admin.py b/tests/test_pagure_admin.py index ec2890c..6f8acfb 100644 --- a/tests/test_pagure_admin.py +++ b/tests/test_pagure_admin.py @@ -1475,7 +1475,7 @@ class PagureBlockUserTests(tests.Modeltests): provided. """ - args = munch.Munch({"username": "pingou", "date": None}) + args = munch.Munch({"username": "pingou", "date": None, "list": False}) with self.assertRaises(pagure.exceptions.PagureException) as cm: pagure.cli.admin.do_block_user(args) self.assertEqual( @@ -1491,7 +1491,9 @@ class PagureBlockUserTests(tests.Modeltests): is missing from the args. """ - args = munch.Munch({"date": "2018-06-11", "username": None}) + args = munch.Munch( + {"date": "2018-06-11", "username": None, "list": False} + ) with self.assertRaises(pagure.exceptions.PagureException) as cm: pagure.cli.admin.do_block_user(args) @@ -1506,7 +1508,9 @@ class PagureBlockUserTests(tests.Modeltests): provided does correspond to any user in the DB. """ - args = munch.Munch({"date": "2018-06-11", "username": "invalid"}) + args = munch.Munch( + {"date": "2018-06-11", "username": "invalid", "list": False} + ) with self.assertRaises(pagure.exceptions.PagureException) as cm: pagure.cli.admin.do_block_user(args) @@ -1521,7 +1525,9 @@ class PagureBlockUserTests(tests.Modeltests): date is incorrect. """ - args = munch.Munch({"date": "2018-14-05", "username": "pingou"}) + args = munch.Munch( + {"date": "2018-14-05", "username": "pingou", "list": False} + ) with self.assertRaises(pagure.exceptions.PagureException) as cm: pagure.cli.admin.do_block_user(args) @@ -1540,13 +1546,128 @@ class PagureBlockUserTests(tests.Modeltests): are provided correctly. """ - args = munch.Munch({"date": "2050-12-31", "username": "pingou"}) + args = munch.Munch( + {"date": "2050-12-31", "username": "pingou", "list": False} + ) pagure.cli.admin.do_block_user(args) user = pagure.lib.query.get_user(self.session, "pingou") self.assertIsNotNone(user.refuse_sessions_before) + def test_list_blocked_user(self): + """ Test the block-user function of pagure-admin when all arguments + are provided correctly. + """ + + args = munch.Munch({"list": True, "username": None, "date": None}) + + with tests.capture_output() as output: + pagure.cli.admin.do_block_user(args) + + output = output.getvalue() + self.assertEqual("No users are currently blocked\n", output) + + @patch("pagure.cli.admin._ask_confirmation", MagicMock(return_value=True)) + def test_list_blocked_user_with_data(self): + """ Test the block-user function of pagure-admin when all arguments + are provided correctly. + """ + args = munch.Munch( + {"date": "2050-12-31", "username": "pingou", "list": False} + ) + pagure.cli.admin.do_block_user(args) + + args = munch.Munch({"list": True, "username": None, "date": None}) + + with tests.capture_output() as output: + pagure.cli.admin.do_block_user(args) + + output = output.getvalue() + self.assertEqual( + "Users blocked:\n" + " pingou - 2050-12-31T00:00:00\n", + output, + ) + + @patch("pagure.cli.admin._ask_confirmation", MagicMock(return_value=True)) + def test_list_blocked_user_with_username_data(self): + """ Test the block-user function of pagure-admin when all arguments + are provided correctly. + """ + args = munch.Munch( + {"date": "2050-12-31", "username": "pingou", "list": False} + ) + pagure.cli.admin.do_block_user(args) + + args = munch.Munch({"list": True, "username": "ralph", "date": None}) + + with tests.capture_output() as output: + pagure.cli.admin.do_block_user(args) + + output = output.getvalue() + self.assertEqual("No users are currently blocked\n", output) + + args = munch.Munch({"list": True, "username": "pin*", "date": None}) + + with tests.capture_output() as output: + pagure.cli.admin.do_block_user(args) + output = output.getvalue() + self.assertEqual( + "Users blocked:\n" + " pingou - 2050-12-31T00:00:00\n", + output, + ) + + @patch("pagure.cli.admin._ask_confirmation", MagicMock(return_value=True)) + def test_list_blocked_user_with_date(self): + """ Test the block-user function of pagure-admin when all arguments + are provided correctly. + """ + args = munch.Munch( + {"list": True, "username": None, "date": "2050-12-31"} + ) + + with tests.capture_output() as output: + pagure.cli.admin.do_block_user(args) + + output = output.getvalue() + self.assertEqual("No users are currently blocked\n", output) + + @patch("pagure.cli.admin._ask_confirmation", MagicMock(return_value=True)) + def test_list_blocked_user_with_date_and_data(self): + """ Test the block-user function of pagure-admin when all arguments + are provided correctly. + """ + args = munch.Munch( + {"date": "2050-12-31", "username": "pingou", "list": False} + ) + pagure.cli.admin.do_block_user(args) + + args = munch.Munch( + {"list": True, "username": None, "date": "2050-12-31"} + ) + + with tests.capture_output() as output: + pagure.cli.admin.do_block_user(args) + + output = output.getvalue() + self.assertEqual( + "Users blocked:\n" + " pingou - 2050-12-31T00:00:00\n", + output, + ) + + args = munch.Munch( + {"list": True, "username": None, "date": "2051-01-01"} + ) + + with tests.capture_output() as output: + pagure.cli.admin.do_block_user(args) + + output = output.getvalue() + self.assertEqual("No users are currently blocked\n", output) + class PagureAdminDeleteProjectTests(tests.Modeltests): """ Tests for pagure-admin delete-project """