Skip to content

Commit 12349c5

Browse files
committed
feat(user): guard reset with --force flag
same as delete etc.
1 parent 7ed9933 commit 12349c5

File tree

4 files changed

+70
-6
lines changed

4 files changed

+70
-6
lines changed

compiler_admin/commands/user/reset.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ def reset(args: Namespace) -> int:
2626
print(f"User does not exist: {account}")
2727
return RESULT_FAILURE
2828

29+
if getattr(args, "force", False) is False:
30+
cont = input(f"Reset password for {account}? (Y/n)")
31+
if not cont.lower().startswith("y"):
32+
print("Aborting password reset.")
33+
return RESULT_SUCCESS
34+
2935
command = ("update", "user", account, "password", "random", "changepassword")
3036

3137
notify = getattr(args, "notify", None)

compiler_admin/main.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ def setup_user_command(cmd_parsers: _SubParsersAction):
151151
user_reset = add_sub_cmd_with_username_arg(
152152
user_subcmds, "reset", help="Reset a user's password to a randomly generated string."
153153
)
154+
user_reset.add_argument("--force", action="store_true", default=False, help="Don't ask for confirmation before reset.")
154155
user_reset.add_argument("--notify", help="An email address to send the newly generated password.")
155156

156157
add_sub_cmd_with_username_arg(user_subcmds, "restore", help="Restore an email backup from a prior offboarding.")

tests/commands/user/test_reset.py

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,29 @@
77

88

99
@pytest.fixture
10-
def mock_google_user_exists(mock_google_user_exists):
11-
return mock_google_user_exists(MODULE)
10+
def mock_input_yes(mock_input):
11+
fix = mock_input(MODULE)
12+
fix.return_value = "y"
13+
return fix
14+
15+
16+
@pytest.fixture
17+
def mock_input_no(mock_input):
18+
fix = mock_input(MODULE)
19+
fix.return_value = "n"
20+
return fix
1221

1322

1423
@pytest.fixture
1524
def mock_commands_signout(mock_commands_signout):
1625
return mock_commands_signout(MODULE)
1726

1827

28+
@pytest.fixture
29+
def mock_google_user_exists(mock_google_user_exists):
30+
return mock_google_user_exists(MODULE)
31+
32+
1933
@pytest.fixture
2034
def mock_google_CallGAMCommand(mock_google_CallGAMCommand):
2135
return mock_google_CallGAMCommand(MODULE)
@@ -37,10 +51,34 @@ def test_reset_user_does_not_exist(mock_google_user_exists):
3751
assert res == RESULT_FAILURE
3852

3953

54+
@pytest.mark.usefixtures("mock_input_yes")
55+
def test_reset_confirm_yes(mock_google_user_exists, mock_google_CallGAMCommand, mock_commands_signout):
56+
mock_google_user_exists.return_value = True
57+
58+
args = Namespace(username="username", force=False)
59+
res = reset(args)
60+
61+
assert res == RESULT_SUCCESS
62+
mock_google_CallGAMCommand.assert_called_once()
63+
mock_commands_signout.assert_called_once_with(args)
64+
65+
66+
@pytest.mark.usefixtures("mock_input_no")
67+
def test_reset_confirm_no(mock_google_user_exists, mock_google_CallGAMCommand, mock_commands_signout):
68+
mock_google_user_exists.return_value = True
69+
70+
args = Namespace(username="username", force=False)
71+
res = reset(args)
72+
73+
assert res == RESULT_SUCCESS
74+
mock_google_CallGAMCommand.assert_not_called()
75+
mock_commands_signout.assert_not_called()
76+
77+
4078
def test_reset_user_exists(mock_google_user_exists, mock_google_CallGAMCommand, mock_commands_signout):
4179
mock_google_user_exists.return_value = True
4280

43-
args = Namespace(username="username")
81+
args = Namespace(username="username", force=True)
4482
res = reset(args)
4583

4684
assert res == RESULT_SUCCESS
@@ -56,7 +94,7 @@ def test_reset_user_exists(mock_google_user_exists, mock_google_CallGAMCommand,
5694
def test_reset_notify(mock_google_user_exists, mock_google_CallGAMCommand, mock_commands_signout):
5795
mock_google_user_exists.return_value = True
5896

59-
args = Namespace(username="username", notify="notification@example.com")
97+
args = Namespace(username="username", notify="notification@example.com", force=True)
6098
res = reset(args)
6199

62100
assert res == RESULT_SUCCESS

tests/test_main.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,8 @@ def test_main_user_reset(mock_commands_user):
394394
mock_commands_user.assert_called_once()
395395
call_args = mock_commands_user.call_args.args
396396
assert (
397-
Namespace(func=mock_commands_user, command="user", subcommand="reset", username="username", notify=None) in call_args
397+
Namespace(func=mock_commands_user, command="user", subcommand="reset", username="username", force=False, notify=None)
398+
in call_args
398399
)
399400

400401

@@ -404,7 +405,25 @@ def test_main_user_reset_notify(mock_commands_user):
404405
mock_commands_user.assert_called_once()
405406
call_args = mock_commands_user.call_args.args
406407
assert (
407-
Namespace(func=mock_commands_user, command="user", subcommand="reset", username="username", notify="notification")
408+
Namespace(
409+
func=mock_commands_user,
410+
command="user",
411+
subcommand="reset",
412+
username="username",
413+
notify="notification",
414+
force=False,
415+
)
416+
in call_args
417+
)
418+
419+
420+
def test_main_user_reset_force(mock_commands_user):
421+
main(argv=["user", "reset", "username", "--force"])
422+
423+
mock_commands_user.assert_called_once()
424+
call_args = mock_commands_user.call_args.args
425+
assert (
426+
Namespace(func=mock_commands_user, command="user", subcommand="reset", username="username", force=True, notify=None)
408427
in call_args
409428
)
410429

0 commit comments

Comments
 (0)