Skip to content

Commit 51230fe

Browse files
[ERSSUP-89806]-[]-[Added body to invalid business function response]-[JW]
1 parent c97b516 commit 51230fe

File tree

5 files changed

+107
-9
lines changed

5 files changed

+107
-9
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<RaiseFault async="false" continueOnError="false" enabled="true" name="RaiseFault.InvalidBusinessFunction">
2+
<FaultResponse>
3+
<Set>
4+
<Payload contentType="text/plain"/>
5+
<StatusCode>403</StatusCode>
6+
<ReasonPhrase>Forbidden</ReasonPhrase>
7+
</Set>
8+
</FaultResponse>
9+
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
10+
</RaiseFault>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<AssignMessage enabled="true" name="AssignMessage.SetOperationOutcomeInvalidBusinessFunction">
2+
<AssignVariable>
3+
<Name>op_outcome_issue_code</Name>
4+
<Value>forbidden</Value>
5+
</AssignVariable>
6+
<AssignVariable>
7+
<Name>faultstring</Name>
8+
<Value>User does not have the required Business Function and the specified Organisation.</Value>
9+
</AssignVariable>
10+
<AssignVariable>
11+
<Name>status_code</Name>
12+
<Value>403</Value>
13+
</AssignVariable>
14+
</AssignMessage>

proxies/live/apiproxy/targets/ers-target.xml

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,23 @@
106106
</Step>
107107
<Condition>(raisefault.RaiseFault.MissingAsid.failed = true)</Condition>
108108
</FaultRule>
109+
<FaultRule>
110+
<Step>
111+
<Condition>(isFhirR4Path = true)</Condition>
112+
<Name>AssignMessage.setOperationOutcomeVariables</Name>
113+
</Step>
114+
<Step>
115+
<Condition>(isFhirR4Path = false)</Condition>
116+
<Name>AssignMessage.setOperationOutcomeVariablesPreR4</Name>
117+
</Step>
118+
<Step>
119+
<Name>AssignMessage.SetOperationOutcomeInvalidBusinessFunction</Name>
120+
</Step>
121+
<Step>
122+
<Name>AssignMessage.OperationOutcomeErrorResponse</Name>
123+
</Step>
124+
<Condition>(raisefault.RaiseFault.InvalidBusinessFunction.failed = true)</Condition>
125+
</FaultRule>
109126
</FaultRules>
110127
<PreFlow>
111128
<Request>
@@ -155,7 +172,7 @@
155172
<Flow name="user-restricted-flow">
156173
<Condition>(accesstoken.auth_type == "user")</Condition>
157174
<Request><!--AUTHORISED_APPLICATION business functions are not supported in user restricted flow --><Step>
158-
<Name>RaiseFault.403Forbidden</Name>
175+
<Name>RaiseFault.InvalidBusinessFunction</Name>
159176
<Condition>(request.header.nhsd-ers-business-function == "PROVIDER_AUTHORISED_APPLICATION") or (request.header.nhsd-ers-business-function == "REFERRER_AUTHORISED_APPLICATION") or (request.header.nhsd-ers-business-function == "AUTHORISED_APPLICATION")</Condition>
160177
</Step> <Step>
161178
<Name>AssignMessage.Set.x-ers-access-mode-header-user-restricted</Name>

tests/integration/test_app_restricted.py

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,6 @@ async def test_authorised_application_not_supported_for_user_restricted(
5151
+ response.status_code
5252
)
5353

54-
assert response.text == ""
55-
5654
assert (
5755
response.headers[RenamedHeader.CORRELATION_ID.original]
5856
== _EXPECTED_CORRELATION_ID
@@ -61,6 +59,30 @@ async def test_authorised_application_not_supported_for_user_restricted(
6159
for renamed_header in RenamedHeader:
6260
assert renamed_header.renamed not in response.headers
6361

62+
# Verify the OperationOutcome payload
63+
response_data = response.json()
64+
assert response_data["resourceType"] == "OperationOutcome"
65+
assert response_data["meta"]["lastUpdated"] is not None
66+
assert len(response_data["meta"]["profile"]) == 1
67+
assert (
68+
response_data["meta"]["profile"][0]
69+
== "https://fhir.nhs.uk/STU3/StructureDefinition/eRS-OperationOutcome-1"
70+
)
71+
assert len(response_data["issue"]) == 1
72+
issue = response_data["issue"][0]
73+
assert issue["severity"] == "error"
74+
assert issue["code"] == "forbidden"
75+
assert issue["diagnostics"] == (
76+
"User does not have the required Business Function and the specified Organisation."
77+
)
78+
assert len(issue["details"]["coding"]) == 1
79+
issue_details = issue["details"]["coding"][0]
80+
assert (
81+
issue_details["system"]
82+
== "https://fhir.nhs.uk/STU3/CodeSystem/eRS-APIErrorCode-1"
83+
)
84+
assert issue_details["code"] == "NO_ACCESS"
85+
6486
def test_authorised_application_supported_for_app_restricted(
6587
self, app_restricted_access_code, service_url
6688
):

tests/integration/test_headers.py

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,15 +75,21 @@ async def test_headers_on_echo_target(
7575

7676
@pytest.mark.asyncio
7777
@pytest.mark.parametrize(
78-
"business_function",
78+
"business_function,endpoint_url,is_r4",
7979
[
80-
"PROVIDER_AUTHORISED_APPLICATION",
81-
"REFERRER_AUTHORISED_APPLICATION",
82-
"AUTHORISED_APPLICATION",
80+
("PROVIDER_AUTHORISED_APPLICATION", "", False),
81+
("REFERRER_AUTHORISED_APPLICATION", "", False),
82+
("AUTHORISED_APPLICATION", "", False),
83+
("PROVIDER_AUTHORISED_APPLICATION", "/FHIR/STU3/", False),
84+
("REFERRER_AUTHORISED_APPLICATION", "/FHIR/STU3/", False),
85+
("AUTHORISED_APPLICATION", "/FHIR/STU3/", False),
86+
("PROVIDER_AUTHORISED_APPLICATION", "/FHIR/R4/", True),
87+
("REFERRER_AUTHORISED_APPLICATION", "/FHIR/R4/", True),
88+
("AUTHORISED_APPLICATION", "/FHIR/R4/", True),
8389
],
8490
)
8591
async def test_headers_on_echo_target_with_app_restricted_business_function(
86-
self, business_function, authenticate_user, service_url
92+
self, business_function, endpoint_url, is_r4, authenticate_user, service_url
8793
):
8894
user = Actor.RC
8995
access_code = await authenticate_user(user)
@@ -101,7 +107,9 @@ async def test_headers_on_echo_target_with_app_restricted_business_function(
101107
}
102108

103109
# Make the API call
104-
response = requests.get(service_url, headers=client_request_headers)
110+
response = requests.get(
111+
service_url + endpoint_url, headers=client_request_headers
112+
)
105113

106114
assert response.status_code == 403, (
107115
"Expected a 403 response when attempting to call the endpoint, but instead received a "
@@ -114,6 +122,33 @@ async def test_headers_on_echo_target_with_app_restricted_business_function(
114122
+ response_body
115123
)
116124

125+
# Verify the OperationOutcome payload
126+
response_data = response.json()
127+
assert response_data["resourceType"] == "OperationOutcome"
128+
assert response_data["meta"]["lastUpdated"] is not None
129+
assert len(response_data["meta"]["profile"]) == 1
130+
assert response_data["meta"]["profile"][0] == (
131+
"https://www.hl7.org/fhir/R4/operationoutcome.html"
132+
if is_r4
133+
else "https://fhir.nhs.uk/STU3/StructureDefinition/eRS-OperationOutcome-1"
134+
)
135+
assert len(response_data["issue"]) == 1
136+
issue = response_data["issue"][0]
137+
assert issue["severity"] == "error"
138+
assert issue["code"] == "forbidden"
139+
assert issue["diagnostics"] == (
140+
"User does not have the required Business Function and the specified Organisation."
141+
)
142+
assert len(issue["details"]["coding"]) == 1
143+
issue_details = issue["details"]["coding"][0]
144+
assert (
145+
issue_details["system"]
146+
== "https://fhir.nhs.uk/CodeSystem/NHSD-API-ErrorOrWarningCode"
147+
if is_r4
148+
else "https://fhir.nhs.uk/STU3/CodeSystem/eRS-APIErrorCode-1"
149+
)
150+
assert issue_details["code"] == "ACCESS_DENIED" if is_r4 else "NO_ACCESS"
151+
117152
@pytest.mark.asyncio
118153
@pytest.mark.parametrize(
119154
"endpoint_url,is_r4",

0 commit comments

Comments
 (0)