Skip to content

Commit a561c93

Browse files
committed
[NRL-1351] Finish off CLI script to manage NRL pointer-type permissions
1 parent 4d2f591 commit a561c93

File tree

1 file changed

+101
-21
lines changed

1 file changed

+101
-21
lines changed

scripts/manage_permissions.py

Lines changed: 101 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,15 @@
1313
"NRL_AUTH_BUCKET_NAME", f"nhsd-nrlf--{nrl_env}-authorization-store"
1414
)
1515

16+
COMPARE_AND_CONFIRM = (
17+
True
18+
if nrl_env == "prod"
19+
else os.getenv("COMPARE_AND_CONFIRM", "false").lower() == "true"
20+
)
21+
1622
print(f"Using NRL environment: {nrl_env}")
1723
print(f"Using NRL auth bucket: {nrl_auth_bucket_name}")
24+
print(f"Compare and confirm mode: {COMPARE_AND_CONFIRM}")
1825
print()
1926

2027

@@ -33,7 +40,7 @@ def _list_s3_keys(file_key_prefix: str) -> list[str]:
3340
}
3441

3542
page_iterator = paginator.paginate(**params)
36-
keys = []
43+
keys: list[str] = []
3744
for page in page_iterator:
3845
if "Contents" in page:
3946
keys.extend([item["Key"] for item in page["Contents"]])
@@ -61,19 +68,26 @@ def _get_perms_from_s3(file_key: str) -> str | None:
6168
return item["Body"].read().decode("utf-8")
6269

6370

64-
def list_apps() -> list[str]:
71+
def list_apps() -> None:
72+
"""
73+
List all applications in the NRL environment.
74+
"""
6575
keys = _list_s3_keys("")
66-
apps = [key.split("/")[0] for key in keys]
76+
apps = set([key.split("/")[0] for key in keys])
6777

6878
if not apps:
6979
print("No applications found in the bucket.")
7080
return []
7181

72-
print(f"Listing all {len(apps)} apps in bucket...")
73-
return apps
82+
print(f"There are {len(apps)} apps in {nrl_env} env:")
83+
for app in apps:
84+
print(f"- {app}")
7485

7586

76-
def list_orgs(app_id: str) -> list[str]:
87+
def list_orgs(app_id: str) -> None:
88+
"""
89+
List all organizations for a specific application.
90+
"""
7791
keys = _list_s3_keys(f"{app_id}/")
7892
orgs = [
7993
key.split("/", maxsplit=2)[1].removesuffix(".json")
@@ -83,23 +97,36 @@ def list_orgs(app_id: str) -> list[str]:
8397

8498
if not orgs:
8599
print(f"No organizations found for app {app_id}.")
86-
return []
87100

88-
print(f"Listing {len(orgs)} organizations for {app_id}...")
89-
return orgs
101+
print(f"There are {len(orgs)} organizations for app {app_id}:")
102+
for org in orgs:
103+
print(f"- {org}")
104+
105+
106+
def list_allowed_types() -> None:
107+
"""
108+
List all pointer types that can be used in permissions.
109+
"""
110+
print("The following pointer-types are allowed:")
111+
112+
for pointer_type, attributes in TYPE_ATTRIBUTES.items():
113+
print(f"- %-45s (%s)" % (pointer_type, attributes["display"][:45]))
90114

91115

92-
def get(app_id: str, org_ods: str) -> list[str]:
116+
def show_perms(app_id: str, org_ods: str) -> None:
117+
"""
118+
Show the permissions for a specific application and organization.
119+
"""
93120
perms = _get_perms_from_s3(f"{app_id}/{org_ods}.json")
94121

95122
if not perms:
96123
print(f"No permissions file found for {app_id}/{org_ods}.")
97-
return []
124+
return
98125

99126
pointertype_perms = json.loads(perms)
100127
if not pointertype_perms:
101128
print(f"No pointer-types found in permission file for {app_id}/{org_ods}.")
102-
return []
129+
return
103130

104131
type_data = {
105132
pointertype_perm: TYPE_ATTRIBUTES.get(
@@ -108,27 +135,63 @@ def get(app_id: str, org_ods: str) -> list[str]:
108135
for pointertype_perm in pointertype_perms
109136
}
110137
types = [
111-
f"{type_data[pointertype_perm]['display']} ({pointertype_perm})"
138+
"%-45s (%s)" % (type_data[pointertype_perm]["display"][:44], pointertype_perm)
112139
for pointertype_perm in pointertype_perms
113140
]
114141

115-
print(f"The current permissions for {app_id}/{org_ods} are:")
116-
return types
142+
print(f"{app_id}/{org_ods} is allowed to access these pointer-types:")
143+
for type_display in types:
144+
print(f"- {type_display}")
117145

118146

119-
def set(app_id: str, org_ods: str, *pointer_types: str) -> list[str]:
147+
def set_perms(app_id: str, org_ods: str, *pointer_types: str) -> None:
148+
"""
149+
Set permissions for an application and organization to access specific pointer types.
150+
"""
120151
if not pointer_types:
121152
print(
122153
"No pointer types provided. Please specify at least one pointer type or use clear_perms command."
123154
)
124-
return []
155+
return
156+
157+
if len(pointer_types) == 1 and pointer_types[0] == "all":
158+
print("Setting permissions for access to all pointer types.")
159+
pointer_types = tuple(TYPE_ATTRIBUTES.keys())
125160

126161
unknown_types = [pt for pt in pointer_types if pt not in TYPE_ATTRIBUTES]
127162
if unknown_types:
128-
print(f"Warning: Unknown pointer types provided: {', '.join(unknown_types)}")
163+
print(f"Error: Unknown pointer types provided: {', '.join(unknown_types)}")
129164
print()
165+
return
130166

131167
permissions_content = json.dumps(pointer_types, indent=4)
168+
169+
if COMPARE_AND_CONFIRM:
170+
current_perms = _get_perms_from_s3(f"{app_id}/{org_ods}.json")
171+
if current_perms == permissions_content:
172+
print(
173+
f"No changes needed for {app_id}/{org_ods}. Current permissions match the new ones."
174+
)
175+
return
176+
177+
print()
178+
print(f"Current permissions for {app_id}/{org_ods}:")
179+
print(current_perms if current_perms else "No permissions set.")
180+
181+
print()
182+
print("New permissions to be set to:")
183+
print(f"{permissions_content}")
184+
185+
print()
186+
confirm = (
187+
input("Do you want to proceed with these changes? (yes/NO): ")
188+
.strip()
189+
.lower()
190+
)
191+
if confirm != "yes":
192+
print("Operation cancelled at user request.")
193+
return
194+
132195
s3 = _get_s3_client()
133196
s3.put_object(
134197
Bucket=nrl_auth_bucket_name,
@@ -137,10 +200,18 @@ def set(app_id: str, org_ods: str, *pointer_types: str) -> list[str]:
137200
ContentType="application/json",
138201
)
139202

140-
return get(app_id, org_ods)
203+
print()
204+
print(f"Set permissions for {app_id}/{org_ods}")
141205

206+
print()
207+
show_perms(app_id, org_ods)
142208

143-
def clear(app_id: str, org_ods: str) -> None:
209+
210+
def clear_perms(app_id: str, org_ods: str) -> None:
211+
"""
212+
Clear permissions for an application and organization.
213+
This will remove all permissions for the specified app and org.
214+
"""
144215
s3 = _get_s3_client()
145216
s3.put_object(
146217
Bucket=nrl_auth_bucket_name,
@@ -152,4 +223,13 @@ def clear(app_id: str, org_ods: str) -> None:
152223

153224

154225
if __name__ == "__main__":
155-
fire.Fire()
226+
fire.Fire(
227+
{
228+
"list_apps": list_apps,
229+
"list_orgs": list_orgs,
230+
"list_allowed_types": list_allowed_types,
231+
"show_perms": show_perms,
232+
"set_perms": set_perms,
233+
"clear_perms": clear_perms,
234+
}
235+
)

0 commit comments

Comments
 (0)