Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<AssignMessage async="false" continueOnError="false" enabled="true" name="AssignMessage.AuthenticationOperationOutcomeErrorResponse">
<AssignMessage async="false" continueOnError="false" enabled="true" name="AssignMessage.OperationOutcomeErrorResponse">
<Set>
<StatusCode>401</StatusCode>
<StatusCode>{status_code}</StatusCode>
<ReasonPhrase>Unauthorized</ReasonPhrase>
<Payload contentType="application/fhir+json" variablePrefix="%" variableSuffix="#">{ "resourceType": "OperationOutcome", "meta": { "lastUpdated": "%current_timestamp#", "profile" : [ "%op_outcome_fhir_profile#" ] }, "issue": [ { "severity": "error", "code": "%op_outcome_issue_code#", "details": { "coding": [ { "system": "%op_outcome_issue_details_coding_system#", "code": "%op_outcome_issue_details_coding_code#" } ] }, "diagnostics": "%faultstring#" } ] }</Payload>
</Set>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
<AssignMessage enabled="true" name="AssignMessage.SetOperationOutcomeIssueCodeLogin">
<AssignVariable>
<Name>status_code</Name>
<Value>401</Value>
</AssignVariable>
<AssignVariable>
<Name>op_outcome_issue_code</Name>
<Value>login</Value>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
<AssignMessage enabled="true" name="AssignMessage.SetOperationOutcomeIssueIal">
<AssignVariable>
<Name>status_code</Name>
<Value>401</Value>
</AssignVariable>
<AssignVariable>
<Name>op_outcome_issue_code</Name>
<Value>forbidden</Value>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<AssignMessage enabled="true" name="AssignMessage.SetOperationOutcomeMissingAsid">
<AssignVariable>
<Name>op_outcome_issue_code</Name>
<Value>forbidden</Value>
</AssignVariable>
<AssignVariable>
<Name>faultstring</Name>
<Value>ASID is not configured in the application</Value>
</AssignVariable>
<AssignVariable>
<Name>status_code</Name>
<Value>403</Value>
</AssignVariable>
</AssignMessage>
10 changes: 10 additions & 0 deletions proxies/live/apiproxy/policies/RaiseFault.MissingAsid.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<RaiseFault async="false" continueOnError="false" enabled="true" name="RaiseFault.MissingAsid">
<FaultResponse>
<Set>
<Payload contentType="text/plain"/>
<StatusCode>403</StatusCode>
<ReasonPhrase>Forbidden</ReasonPhrase>
</Set>
</FaultResponse>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</RaiseFault>
27 changes: 24 additions & 3 deletions proxies/live/apiproxy/targets/ers-target.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<Name>AssignMessage.SetOperationOutcomeIssueCodeLogin</Name>
</Step>
<Step>
<Name>AssignMessage.AuthenticationOperationOutcomeErrorResponse</Name>
<Name>AssignMessage.OperationOutcomeErrorResponse</Name>
</Step>
<Condition>(oauthV2.OauthV2.VerifyAccessToken.failed = true) and (isFhirR4Path = true)</Condition>
</FaultRule>
Expand Down Expand Up @@ -43,7 +43,7 @@
<Condition>aalError != true</Condition>
</Step>
<Step>
<Name>AssignMessage.AuthenticationOperationOutcomeErrorResponse</Name>
<Name>AssignMessage.OperationOutcomeErrorResponse</Name>
<Condition>aalError = true</Condition>
</Step>
<Condition>(oauthV2.OauthV2.VerifyAccessToken.failed = true) and (isFhirR4Path = false)</Condition>
Expand Down Expand Up @@ -85,10 +85,27 @@
<Name>AssignMessage.SetOperationOutcomeIssueIal</Name>
</Step>
<Step>
<Name>AssignMessage.AuthenticationOperationOutcomeErrorResponse</Name>
<Name>AssignMessage.OperationOutcomeErrorResponse</Name>
</Step>
<Condition>(raisefault.RaiseFault.401InsufficientIal.failed = true)</Condition>
</FaultRule>
<FaultRule name="missing_asid">
<Step>
<Condition>(isFhirR4Path = true)</Condition>
<Name>AssignMessage.SetOperationOutcomeVariablesR4</Name>
</Step>
<Step>
<Condition>(isFhirR4Path = false)</Condition>
<Name>AssignMessage.SetOperationOutcomeVariablesPreR4</Name>
</Step>
<Step>
<Name>AssignMessage.SetOperationOutcomeMissingAsid</Name>
</Step>
<Step>
<Name>AssignMessage.OperationOutcomeErrorResponse</Name>
</Step>
<Condition>(raisefault.RaiseFault.MissingAsid.failed = true)</Condition>
</FaultRule>
</FaultRules>
<PreFlow>
<Request>
Expand All @@ -101,6 +118,10 @@
<Step>
<Name>OauthV2.VerifyAccessToken</Name>
</Step>
<Step>
<Name>RaiseFault.MissingAsid</Name>
<Condition>(app.asid == null) Or (app.asid == "")</Condition>
</Step>
<Step>
<Name>AssignMessage.PopulateAsidFromApp</Name>
</Step>
Expand Down
23 changes: 23 additions & 0 deletions sandbox/src/mocks/stu3/STU3-Unauthorised.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"meta": {
"profile": [
"https://fhir.nhs.uk/STU3/StructureDefinition/eRS-OperationOutcome-1"
]
},
"resourceType": "OperationOutcome",
"issue": [
{
"severity": "error",
"code": "login",
"details": {
"coding": [
{
"system": "https://fhir.nhs.uk/STU3/CodeSystem/eRS-APIErrorCode-1",
"code": "NO_ACCESS"
}
]
},
"diagnostics": "Example diagnostics message."
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ description: |
| issue.details.coding.code | issue.code | Coding System | Description |
| ------------------------- | ---------- | ------------------------------------------------------------------ | ---------------------------------------------------------------------------------- |
| REC_FORBIDDEN | forbidden | [BaRS Error Code](https://fhir.nhs.uk/CodeSystem/http-error-codes) | A call attempts to access or operate upon a resource without proper authorisation. |
| ACCESS_DENIED | forbidden | [APIM Error Code](https://fhir.nhs.uk/CodeSystem/NHSD-API-ErrorOrWarningCode) | The request could not be authenticated due to insufficient credentials being provided. |

headers:
X-Correlation-ID:
Expand All @@ -18,4 +19,4 @@ content:
schema:
$ref: '../NHSDigital-OperationOutcome.yaml'
example:
$ref: '../../examples/NHSDigital-OperationOutcome-403.json'
$ref: '../../examples/NHSDigital-OperationOutcome-403.json'
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: |

| issue.details.coding.code | issue.code | Coding System | Description |
| ------------------------- | ---------------- | ----------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ACCESS_DENIED | login | [APIM Error Code](https://fhir.nhs.uk/CodeSystem/NHSD-API-ErrorOrWarningCode) | The request could not be authenticated due to either no credentials being provided or the provided credentials no longer being valid. Callers receiving this code should reauthenticate. |
| ACCESS_DENIED | <ul><li>login</li><li>forbidden</li></ul> | [APIM Error Code](https://fhir.nhs.uk/CodeSystem/NHSD-API-ErrorOrWarningCode) | The request could not be authenticated due to either no credentials being provided or the provided credentials no longer being valid. Callers receiving this code should reauthenticate. |
headers:
X-Correlation-ID:
$ref: '../headers/response/CorrelationID.yaml'
Expand All @@ -15,4 +15,4 @@ content:
schema:
$ref: '../NHSDigital-OperationOutcome.yaml'
example:
$ref: '../../examples/NHSDigital-OperationOutcome-401.json'
$ref: '../../examples/NHSDigital-OperationOutcome-401.json'
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ description: |
Where status code 403 (Forbidden) is returned then an eRS-OperationOutcome-1 will be included in the body, as detailed below.
Check diagnostics property for specific information regarding the error.

| Error code | Description |
| ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| FORBIDDEN | Access Forbidden. |
| issue.details.coding.code | issue.code | Coding System | Description |
| ------------------------- | ---------- | ------------------------------------------------------------------ | ---------------------------------------------------------------------------------- |
| FORBIDDEN | forbidden | [eRS Error Code](https://fhir.nhs.uk/CodeSystem/ers-error-codes) | A call attempts to access or operate upon a resource without proper authorisation. |
| NO_ACCESS | forbidden | [eRS Error Code](https://fhir.nhs.uk/CodeSystem/ers-error-codes) | The request could not be authenticated due to insufficient credentials being provided. |
headers:
X-Correlation-ID:
$ref: '../headers/response/CorrelationID.yaml'
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,20 @@
description: Unauthorized
description: |
Where status code 401 (Unauthorised) is returned then an eRS-OperationOutcome-1 will be included in the body, as detailed below.
Check diagnostics property for specific information regarding the error.

| issue.details.coding.code | issue.code | Coding System | Description |
| ------------------------- | ---------- | ------------------------------------------------------------------ | ---------------------------------------------------------------------------------- |
| NO_ACCESS | <ul><li>login</li><li>forbidden</li></ul> | [eRS Error Code](https://fhir.nhs.uk/CodeSystem/ers-error-codes) | The request could not be authenticated due to either no credentials being provided or the provided credentials no longer being valid. Callers receiving this code should reauthenticate. |
headers:
X-Correlation-ID:
$ref: '../headers/response/CorrelationID.yaml'
X-Request-ID:
$ref: '../headers/response/RequestID.yaml'
Content-Type:
$ref: '../headers/response/ContentTypeFhirJson.yaml'
content:
application/fhir+json:
schema:
$ref: '../STU3-OperationOutcome.yaml'
example:
$ref: '../../examples/STU3-Unauthorised.json'
71 changes: 71 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,77 @@ def _update_function(append_scopes: Collection[str]):
return _update_function


@pytest.fixture
def delete_user_restricted_app_attr(
user_restricted_app, client: ApigeeClient
) -> Callable[[Collection[str]], Generator[Dict[str, str], None, None]]:
@contextmanager
def _update_function(attr):
app_api = DeveloperAppsAPI(client=client)
app = app_api.get_app_by_name(
email="apm-testing-internal-dev@nhs.net",
app_name=user_restricted_app["name"],
)

warnings.warn(f"Existing app = {app}")

existing_attributes = app_api.get_app_attributes(
email="apm-testing-internal-dev@nhs.net", app_name=app["name"]
)

yield app_api.delete_app_attribute_by_name(
email="apm-testing-internal-dev@nhs.net",
app_name=app["name"],
attribute_name=attr,
)

# reset the product once the context manager has been closed.

app_api.post_app_attributes(
email="apm-testing-internal-dev@nhs.net",
app_name=app["name"],
body=existing_attributes,
)

return _update_function


@pytest.fixture
def update_user_restricted_app_attr(
user_restricted_app, client: ApigeeClient
) -> Callable[[Collection[str]], Generator[Dict[str, str], None, None]]:
@contextmanager
def _update_function(attr, value):
app_api = DeveloperAppsAPI(client=client)
app = app_api.get_app_by_name(
email="apm-testing-internal-dev@nhs.net",
app_name=user_restricted_app["name"],
)

warnings.warn(f"Existing app = {app}")

existing_attributes = app_api.get_app_attributes(
email="apm-testing-internal-dev@nhs.net", app_name=app["name"]
)

yield app_api.post_app_attribute_by_name(
email="apm-testing-internal-dev@nhs.net",
app_name=app["name"],
attribute_name=attr,
body={"value": value},
)

# reset the product once the context manager has been closed.

app_api.post_app_attributes(
email="apm-testing-internal-dev@nhs.net",
app_name=app["name"],
body=existing_attributes,
)

return _update_function


@pytest.fixture
def make_product(client, environment, service_name):
async def _make_product(product_scopes):
Expand Down
Loading