Skip to content

Commit a1518b4

Browse files
committed
feat(user): reactivate command
corollary of user deactivate command
1 parent a43c987 commit a1518b4

File tree

4 files changed

+114
-1
lines changed

4 files changed

+114
-1
lines changed

compiler_admin/commands/user/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from compiler_admin.commands.user.delete import delete
88
from compiler_admin.commands.user.offboard import offboard
99
from compiler_admin.commands.user.reset import reset
10+
from compiler_admin.commands.user.reactivate import reactivate
1011
from compiler_admin.commands.user.restore import restore
1112
from compiler_admin.commands.user.signout import signout
1213

@@ -25,6 +26,7 @@ def user():
2526
user.add_command(deactivate)
2627
user.add_command(delete)
2728
user.add_command(offboard)
29+
user.add_command(reactivate)
2830
user.add_command(reset)
2931
user.add_command(restore)
3032
user.add_command(signout)
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import click
2+
3+
from compiler_admin import RESULT_FAILURE, RESULT_SUCCESS
4+
from compiler_admin.commands.user.backupcodes import backupcodes
5+
from compiler_admin.commands.user.reset import reset
6+
from compiler_admin.services.google import (
7+
GROUP_STAFF,
8+
GROUP_TEAM,
9+
OU_CONTRACTORS,
10+
OU_STAFF,
11+
CallGAMCommand,
12+
add_user_to_group,
13+
move_user_ou,
14+
user_account_name,
15+
user_exists,
16+
user_is_deactivated,
17+
)
18+
19+
20+
@click.command()
21+
@click.option("-f", "--force", is_flag=True, help="Don't ask for confirmation.")
22+
@click.option("-n", "--notify", help="An email address to send the new password notification.")
23+
@click.option(
24+
"-e",
25+
"--recovery-email",
26+
default="",
27+
help="An email address to use as the new recovery email.",
28+
)
29+
@click.option(
30+
"-p",
31+
"--recovery-phone",
32+
default="",
33+
help="A phone number to use as the new recovery phone number.",
34+
)
35+
@click.option("-s", "--staff", is_flag=True, help="Reactivate the user as a staff member. The default is contractor.")
36+
@click.argument("username")
37+
@click.pass_context
38+
def reactivate(
39+
ctx: click.Context,
40+
username: str,
41+
force: bool = False,
42+
recovery_email: str = "",
43+
recovery_phone: str = "",
44+
staff: bool = False,
45+
**kwargs,
46+
):
47+
"""
48+
Reactivate a previously deactivated user.
49+
"""
50+
account = user_account_name(username)
51+
52+
if not user_exists(account):
53+
click.echo(f"User does not exist: {account}")
54+
raise SystemExit(RESULT_FAILURE)
55+
56+
if not user_is_deactivated(account):
57+
click.echo("User is not deactivated, cannot reactivate")
58+
raise SystemExit(RESULT_FAILURE)
59+
60+
if not force:
61+
cont = input(f"Reactivate account {account}? (Y/n): ")
62+
if not cont.lower().startswith("y"):
63+
click.echo("Aborting reactivation")
64+
raise SystemExit(RESULT_SUCCESS)
65+
66+
click.echo(f"User exists, reactivating: {account}")
67+
68+
click.echo(f"Adding to group: {GROUP_TEAM}")
69+
add_user_to_group(account, GROUP_TEAM)
70+
71+
if staff:
72+
click.echo(f"Moving to OU: {OU_STAFF}")
73+
move_user_ou(account, OU_STAFF)
74+
click.echo(f"Adding to group: {GROUP_STAFF}")
75+
add_user_to_group(account, GROUP_STAFF)
76+
else:
77+
click.echo(f"Moving to OU: {OU_CONTRACTORS}")
78+
move_user_ou(account, OU_CONTRACTORS)
79+
80+
# reset password, sign out
81+
ctx.forward(reset)
82+
83+
click.echo("Update user profile info")
84+
profile = dict(recoveryemail=recovery_email, recoveryphone=recovery_phone)
85+
profile = {k: v for k, v in profile.items() if v}
86+
for prop, val in profile.items():
87+
command = ("update", "user", account, prop, val)
88+
CallGAMCommand(command)
89+
90+
# get the user's backup codes
91+
ctx.forward(backupcodes)
92+
93+
click.echo(f"User is reactivated: {account}")

tests/commands/user/test_init.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,19 @@
44

55

66
@pytest.mark.parametrize(
7-
"command", ["backupcodes", "convert", "create", "deactivate", "delete", "offboard", "reset", "restore", "signout"]
7+
"command",
8+
[
9+
"backupcodes",
10+
"convert",
11+
"create",
12+
"deactivate",
13+
"delete",
14+
"offboard",
15+
"reactivate",
16+
"reset",
17+
"restore",
18+
"signout",
19+
],
820
)
921
def test_user_commands(command):
1022
assert command in user.commands

tests/conftest.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@ def __mock_command(module):
7676
return _mock_command
7777

7878

79+
@pytest.fixture
80+
def mock_commands_backupcodes(mock_command):
81+
"""Fixture returns a function that patches the backupcodes function in a given module."""
82+
return mock_command("backupcodes")
83+
84+
7985
@pytest.fixture
8086
def mock_commands_deactivate(mock_command):
8187
"""Fixture returns a function that patches the deactivate function in a given module."""

0 commit comments

Comments
 (0)