Skip to content

Commit 025104f

Browse files
committed
integrating the new supplier permissions
1 parent a402488 commit 025104f

File tree

11 files changed

+214
-147
lines changed

11 files changed

+214
-147
lines changed

backend/src/fhir_controller.py

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -271,8 +271,10 @@ def update_immunization(self, aws_event):
271271

272272
# Check vaccine type permissions on the existing record - start
273273
try:
274-
vax_type_perms = self._parse_vaccine_permissions_controller(imms_vax_type_perms)
274+
vax_type_perms = self._expand_permissions(imms_vax_type_perms)
275+
print(f"vax_type_perms: {vax_type_perms}, imms_vax_type_perms: {imms_vax_type_perms}")
275276
vax_type_perm = self._vaccine_permission(existing_record["VaccineType"], "update")
277+
print(f"vax_type_perm(operation_perms): {vax_type_perm}, is subset of vax_type_perms (imms_vax): {vax_type_perms}")
276278
self._check_permission(vax_type_perm, vax_type_perms)
277279
except UnauthorizedVaxOnRecordError as unauthorized:
278280
return self.create_response(403, unauthorized.to_operation_outcome())
@@ -333,6 +335,7 @@ def update_immunization(self, aws_event):
333335

334336
# Check if the record is reinstated record - start
335337
if existing_record["Reinstated"] == True:
338+
print(f"imms_params_reinstate: {imms_vax_type_perms}, supplier_system: {supplier_system}")
336339
outcome, resource = self.fhir_service.update_reinstated_immunization(
337340
imms_id,
338341
imms,
@@ -341,6 +344,7 @@ def update_immunization(self, aws_event):
341344
supplier_system
342345
)
343346
else:
347+
print(f"imms_params: {imms_vax_type_perms}, supplier_system: {supplier_system}")
344348
outcome, resource = self.fhir_service.update_immunization(
345349
imms_id,
346350
imms,
@@ -428,8 +432,9 @@ def search_immunizations(self, aws_event: APIGatewayProxyEventV1) -> dict:
428432
return self.create_response(403, unauthorized.to_operation_outcome())
429433
# Check vaxx type permissions on the existing record - start
430434
try:
431-
vax_type_perms = self._parse_vaccine_permissions_controller(imms_vax_type_perms)
435+
vax_type_perms = self._expand_permissions(imms_vax_type_perms)
432436
vax_type_perm = self._new_vaccine_request(search_params.immunization_targets, "search", vax_type_perms)
437+
print(f"vax_type_perm: {vax_type_perm}, vax_type_perms: {vax_type_perms}")
433438
if not vax_type_perm:
434439
raise UnauthorizedVaxError
435440
except UnauthorizedVaxError as unauthorized:
@@ -661,29 +666,48 @@ def create_response(status_code, body=None, headers=None):
661666
**({"body": body} if body else {}),
662667
}
663668

664-
@staticmethod
665-
def _sendack(payload, file_name, message_id, created_at_formatted_string, local_id, operation_requested):
666-
payload["file_key"] = file_name
667-
payload["row_id"] = message_id
668-
payload["created_at_formatted_string"] = created_at_formatted_string
669-
payload["local_id"] = local_id
670-
payload["operation_requested"] = operation_requested
671-
sqs_client.send_message(QueueUrl=queue_url, MessageBody=json.dumps(payload), MessageGroupId=file_name)
672-
673669
@staticmethod
674670
def _vaccine_permission(vaccine_type, operation) -> set:
671+
mapped_operations = {
672+
"create": "c",
673+
"read": "r",
674+
"update": "u",
675+
"delete": "d",
676+
"search": "s"
677+
}
678+
679+
operation = mapped_operations.get(operation.lower())
680+
if not operation:
681+
raise ValueError(f"Unsupported operation: {operation}")
682+
675683
vaccine_permission = set()
676684
if isinstance(vaccine_type, list):
677685
for x in vaccine_type:
678-
vaccine_permission.add(str.lower(f"{x}:{operation}"))
686+
vaccine_permission.add(str.lower(f"{x}.{operation}"))
679687
return vaccine_permission
680688
else:
681-
vaccine_permission.add(str.lower(f"{vaccine_type}:{operation}"))
689+
vaccine_permission.add(str.lower(f"{vaccine_type}.{operation}"))
682690
return vaccine_permission
683691

684692
@staticmethod
685693
def _parse_vaccine_permissions_controller(imms_vax_type_perms) -> set:
686694
return {str(s).strip().lower() for s in imms_vax_type_perms}
695+
696+
@staticmethod
697+
def _expand_permissions(supplier_permissions: list[str]) -> set[str]:
698+
expanded = set()
699+
for permissions in supplier_permissions:
700+
if '.' not in permissions:
701+
continue # skip invalid format
702+
vaccineType, allowed_operations = permissions.split('.', 1)
703+
print(f"Vax_type: {vaccineType}, Ops: {allowed_operations}")
704+
vaccineType = vaccineType.lower()
705+
for operation in allowed_operations.lower():
706+
if operation not in {'c', 'r', 'u', 'd', 's'}:
707+
raise ValueError(f"Unknown operation code: {operation} in a permission {permissions}")
708+
expanded.add(f"{vaccineType}.{operation}")
709+
print(f"Expanded permissions: {expanded}")
710+
return expanded
687711

688712
@staticmethod
689713
def _check_permission(requested: set, allowed: set) -> set:
@@ -694,11 +718,20 @@ def _check_permission(requested: set, allowed: set) -> set:
694718

695719
@staticmethod
696720
def _new_vaccine_request(vaccine_type, operation, vaccine_type_permissions: None) -> Optional[list]:
721+
mapped_operations = {
722+
"create": "c",
723+
"read": "r",
724+
"update": "u",
725+
"delete": "d",
726+
"search": "s"
727+
}
728+
729+
operation = mapped_operations.get(operation.lower())
697730
vaccine_permission = list()
698731
if isinstance(vaccine_type, list):
699732
for x in vaccine_type:
700733
vaccs_prms = set()
701-
vaccs_prms.add(str.lower(f"{x}:{operation}"))
734+
vaccs_prms.add(str.lower(f"{x}.{operation}"))
702735
if vaccs_prms.issubset(vaccine_type_permissions):
703736
vaccine_permission.append(x)
704737
return vaccine_permission

backend/src/fhir_repository.py

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ def __init__(self, table: Table):
8585
self.table = table
8686

8787
def get_immunization_by_identifier(
88-
self, identifier_pk: str, imms_vax_type_perms: str
88+
self, identifier_pk: str, imms_vax_type_perms: list[str]
8989
) -> Optional[dict]:
9090
response = self.table.query(
9191
IndexName="IdentifierGSI", KeyConditionExpression=Key("IdentifierPK").eq(identifier_pk)
@@ -94,7 +94,7 @@ def get_immunization_by_identifier(
9494
item = response["Items"][0]
9595
resp = dict()
9696
vaccine_type = self._vaccine_type(item["PatientSK"])
97-
vax_type_perms = self._parse_vaccine_permissions(imms_vax_type_perms)
97+
vax_type_perms = self._expand_permissions(imms_vax_type_perms)
9898
vax_type_perm = self._vaccine_permission(vaccine_type, "search")
9999
self._check_permission(vax_type_perm, vax_type_perms)
100100
resource = json.loads(item["Resource"])
@@ -112,7 +112,7 @@ def get_immunization_by_id(self, imms_id: str, imms_vax_type_perms: str) -> Opti
112112
if "DeletedAt" in response["Item"]:
113113
if response["Item"]["DeletedAt"] == "reinstated":
114114
vaccine_type = self._vaccine_type(response["Item"]["PatientSK"])
115-
vax_type_perms = self._parse_vaccine_permissions(imms_vax_type_perms)
115+
vax_type_perms = self._expand_permissions(imms_vax_type_perms)
116116
vax_type_perm = self._vaccine_permission(vaccine_type, "read")
117117
self._check_permission(vax_type_perm, vax_type_perms)
118118
resp["Resource"] = json.loads(response["Item"]["Resource"])
@@ -122,7 +122,7 @@ def get_immunization_by_id(self, imms_id: str, imms_vax_type_perms: str) -> Opti
122122
return None
123123
else:
124124
vaccine_type = self._vaccine_type(response["Item"]["PatientSK"])
125-
vax_type_perms = self._parse_vaccine_permissions(imms_vax_type_perms)
125+
vax_type_perms = self._expand_permissions(imms_vax_type_perms)
126126
vax_type_perm = self._vaccine_permission(vaccine_type, "read")
127127
self._check_permission(vax_type_perm, vax_type_perms)
128128
resp["Resource"] = json.loads(response["Item"]["Resource"])
@@ -170,7 +170,7 @@ def create_immunization(
170170
new_id = str(uuid.uuid4())
171171
immunization["id"] = new_id
172172
attr = RecordAttributes(immunization, patient)
173-
vax_type_perms = self._parse_vaccine_permissions(imms_vax_type_perms)
173+
vax_type_perms = self._expand_permissions(imms_vax_type_perms)
174174
vax_type_perm = self._vaccine_permission(attr.vaccine_type, "create")
175175
self._check_permission(vax_type_perm, vax_type_perms)
176176
query_response = _query_identifier(self.table, "IdentifierGSI", "IdentifierPK", attr.identifier)
@@ -273,7 +273,7 @@ def update_reinstated_immunization(
273273
)
274274

275275
def _handle_permissions(self, imms_vax_type_perms: str, attr: RecordAttributes):
276-
vax_type_perms = self._parse_vaccine_permissions(imms_vax_type_perms)
276+
vax_type_perms = self._expand_permissions(imms_vax_type_perms)
277277
vax_type_perm = self._vaccine_permission(attr.vaccine_type, "update")
278278
self._check_permission(vax_type_perm, vax_type_perms)
279279

@@ -370,12 +370,12 @@ def delete_immunization(
370370
if "DeletedAt" in resp["Item"]:
371371
if resp["Item"]["DeletedAt"] == "reinstated":
372372
vaccine_type = self._vaccine_type(resp["Item"]["PatientSK"])
373-
vax_type_perms = self._parse_vaccine_permissions(imms_vax_type_perms)
373+
vax_type_perms = self._expand_permissions(imms_vax_type_perms)
374374
vax_type_perm = self._vaccine_permission(vaccine_type, "delete")
375375
self._check_permission(vax_type_perm, vax_type_perms)
376376
else:
377377
vaccine_type = self._vaccine_type(resp["Item"]["PatientSK"])
378-
vax_type_perms = self._parse_vaccine_permissions(imms_vax_type_perms)
378+
vax_type_perms = self._expand_permissions(imms_vax_type_perms)
379379
vax_type_perm = self._vaccine_permission(vaccine_type, "delete")
380380
self._check_permission(vax_type_perm, vax_type_perms)
381381

@@ -432,9 +432,26 @@ def _handle_dynamo_response(response):
432432

433433
@staticmethod
434434
def _vaccine_permission(vaccine_type, operation) -> set:
435+
mapped_operations = {
436+
"create": "c",
437+
"read": "r",
438+
"update": "u",
439+
"delete": "d",
440+
"search": "s"
441+
}
442+
443+
operation = mapped_operations.get(operation.lower())
444+
if not operation:
445+
raise ValueError(f"Unsupported operation: {operation}")
446+
435447
vaccine_permission = set()
436-
vaccine_permission.add(str.lower(f"{vaccine_type}:{operation}"))
437-
return vaccine_permission
448+
if isinstance(vaccine_type, list):
449+
for x in vaccine_type:
450+
vaccine_permission.add(str.lower(f"{x}.{operation}"))
451+
return vaccine_permission
452+
else:
453+
vaccine_permission.add(str.lower(f"{vaccine_type}.{operation}"))
454+
return vaccine_permission
438455

439456
@staticmethod
440457
def _parse_vaccine_permissions(imms_vax_type_perms) -> set:
@@ -443,6 +460,22 @@ def _parse_vaccine_permissions(imms_vax_type_perms) -> set:
443460
for s in parsed:
444461
vaccine_permissions.add(s)
445462
return vaccine_permissions
463+
464+
@staticmethod
465+
def _expand_permissions(supplier_permissions: list[str]) -> set[str]:
466+
expanded = set()
467+
for permissions in supplier_permissions:
468+
if '.' not in permissions:
469+
continue # skip invalid format
470+
vaccineType, allowed_operations = permissions.split('.', 1)
471+
print(f"Vax_type: {vaccineType}, Ops: {allowed_operations}")
472+
vaccineType = vaccineType.lower()
473+
for operation in allowed_operations.lower():
474+
if operation not in {'c', 'r', 'u', 'd', 's'}:
475+
raise ValueError(f"Unknown operation code: {operation} in a permission {permissions}")
476+
expanded.add(f"{vaccineType}.{operation}")
477+
print(f"Expanded permissions: {expanded}")
478+
return expanded
446479

447480
@staticmethod
448481
def _check_permission(requested: set, allowed: set) -> set:

backend/src/fhir_service.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ def update_immunization(
131131
imms_id: str,
132132
immunization: dict,
133133
existing_resource_version: int,
134-
imms_vax_type_perms: str,
134+
imms_vax_type_perms: list[str],
135135
supplier_system: str,
136136
) -> tuple[UpdateOutcome, Immunization]:
137137
immunization["id"] = imms_id

backend/tests/sample_data/permissions_config.py

Whitespace-only changes.

0 commit comments

Comments
 (0)