1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
"""API utilities for modifying data via FreeIPA."""
from secrets import token_urlsafe
try:
from bonsai import LDAPDN
BONSAI_AVAILABLE = True
except ImportError:
BONSAI_AVAILABLE = False
from python_freeipa import ClientMeta
from arthur.config import CONFIG
from arthur.constants import LDAP_ROLE_MAPPING
PW_LENGTH = 20
def create_client() -> ClientMeta:
"""Create a new client and login to FreeIPA."""
username = LDAPDN(CONFIG.ldap_bind_user).rdns[0][0][1]
client = ClientMeta(
CONFIG.ldap_host.host, verify_ssl=CONFIG.ldap_certificate_location.as_posix()
)
client.login(username, CONFIG.ldap_bind_password.get_secret_value())
return client
def get_user(username: str) -> dict:
"""Fetch a user from FreeIPA."""
client = create_client()
return client.user_show(username)
def set_user_groups(username: str, groups: list[str]) -> None:
"""
Update a members groups to the provided list.
Any managed groups not specified will be removed from the user.
"""
user = get_user(username)
client = create_client()
memberof_groups = user.get("result", {}).get("memberof_group", [])
add_groups = [group for group in groups if group not in memberof_groups]
remove_groups = [
group for group in memberof_groups if group not in groups and group in LDAP_ROLE_MAPPING
]
for group in add_groups:
client.group_add_member(group, o_user=[username])
for group in remove_groups:
client.group_remove_member(group, o_user=[username])
def deactivate_user(username: str) -> None:
"""Deactivate a user in FreeIPA."""
client = create_client()
client.user_mod(username, o_nsaccountlock=True)
def create_user(username: str, display_name: str, groups: list[str], discord_id: int) -> str:
"""
Create a new user in FreeIPA. If the user exists, the password is reset and returned.
Returns the new user password on success.
"""
client = create_client()
pw = token_urlsafe(PW_LENGTH)
client.user_add(
username,
o_givenname=display_name,
o_cn=display_name,
o_sn=display_name,
o_displayname=display_name,
o_userpassword=pw,
o_employeenumber=discord_id,
)
for group in groups:
client.group_add_member(group, o_user=[username])
return pw
def delete_user(username: str) -> None:
"""Delete a user from FreeIPA."""
client = create_client()
client.user_del(username)
|