From 4c02aa1ef8b3be6508492dc198d4c44b66281dba Mon Sep 17 00:00:00 2001 From: oliveregger Date: Mon, 16 Sep 2024 22:29:16 +0200 Subject: [PATCH] dd support for 401 error code [#182](https://github.com/i4mi/MobileAccessGateway/issues/182) --- .vscode/launch.json | 11 +++-------- .vscode/settings.json | 4 +++- angular/package-lock.json | 4 ++-- docs/changelog.md | 1 + example-config/README-docker.md | 7 +++++++ example-config/application.yml | 8 +++++++- example-config/test.http | 19 ++++++++++--------- src/main/java/ch/bfh/ti/i4mi/mag/Config.java | 6 ++++++ .../mag/common/RequestHeadersForwarder.java | 12 ++++++++++++ .../i4mi/mag/mhd/iti65/Iti65RouteBuilder.java | 1 + .../i4mi/mag/mhd/iti66/Iti66RouteBuilder.java | 1 + .../i4mi/mag/mhd/iti67/Iti67RouteBuilder.java | 1 + .../i4mi/mag/mhd/iti68/Iti68RouteBuilder.java | 1 + .../mag/mhd/pharm5/Pharm5RouteBuilder.java | 1 + .../mag/pmir/iti104/Iti104RouteBuilder.java | 1 + .../mag/pmir/iti78/Iti78RouteBuilder.java | 1 + .../mag/pmir/iti83/Iti83RouteBuilder.java | 1 + .../mag/pmir/iti93/Iti93RouteBuilder.java | 1 + .../ti/i4mi/mag/ppqm/Ppq5RouteBuilder.java | 1 + .../i4mi/mag/ppqm/PpqmFeedRouteBuilder.java | 2 ++ 20 files changed, 63 insertions(+), 21 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index cdfd47aa..297b4257 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -6,17 +6,12 @@ "configurations": [ { "type": "java", - "name": "Debug (Launch) - Current File", - "request": "launch", - "mainClass": "${file}" - }, - { - "type": "java", - "name": "Debug Mobile Access Gateway pmp", + "name": "Debug Mobile Access Gateway local", "request": "launch", "mainClass": "ch.bfh.ti.i4mi.mag.MobileAccessGateway", "projectName": "mobile-access-gateway", - "vmArgs": "-Dspring.config.additional-location=file:/Users/oliveregger/Documents/github/k8s-fhir.ch/configurations/mag-pmp2/application.yml", + "vmArgs": "-Dspring.config.additional-location=file:example-config/application.yml", + "cwd": "${workspaceFolder}" } ] } diff --git a/.vscode/settings.json b/.vscode/settings.json index e0f15db2..01648338 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,5 @@ { - "java.configuration.updateBuildConfiguration": "automatic" + "java.configuration.updateBuildConfiguration": "automatic", + "java.debug.settings.onBuildFailureProceed": true, + "java.compile.nullAnalysis.mode": "automatic" } \ No newline at end of file diff --git a/angular/package-lock.json b/angular/package-lock.json index cccf7f9e..6f90cd37 100644 --- a/angular/package-lock.json +++ b/angular/package-lock.json @@ -1,12 +1,12 @@ { "name": "mag-client", - "version": "2.5.68", + "version": "2.5.70", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "mag-client", - "version": "2.5.68", + "version": "2.5.70", "license": "MIT", "dependencies": { "@angular/animations": "^16.1.7", diff --git a/docs/changelog.md b/docs/changelog.md index db805eaa..0d99b7a8 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -3,6 +3,7 @@ - Fixed an NPE in the assertion route - capability statement validation issues [#177](https://github.com/i4mi/MobileAccessGateway/issues/177) - Add CH PIXm ITI-83 constraints for sourceIdentifier and targetSystem [#170](https://github.com/i4mi/MobileAccessGateway/issues/170) +- add support for 401 error code [#182](https://github.com/i4mi/MobileAccessGateway/issues/182) ## 2024/05/15 v070 diff --git a/example-config/README-docker.md b/example-config/README-docker.md index df590d4d..800fec4d 100644 --- a/example-config/README-docker.md +++ b/example-config/README-docker.md @@ -25,6 +25,13 @@ docker container run -p 127.0.0.1:9090:9090/tcp -p 127.0.0.1:9091:9091/tcp \ mag:local1 ``` + +docker container run -p 127.0.0.1:9090:9090/tcp -p 127.0.0.1:9091:9091/tcp \ +-v /Users/oegger/Documents/github/MobileAccessGateway/example-config:/config \ +-v /Users/oegger/Documents/github/MobileAccessGateway/example-config:/secret \ +-v /Users/oegger/Documents/github/MobileAccessGateway/example-config/logs:/logs \ +europe-west6-docker.pkg.dev/ahdis-ch/ahdis/mag:v1.0.0-pat2024-001 + This will run the image, expose the ports 9090-9091 and mount the _example-config_ directory as /config and /secret in the container. diff --git a/example-config/application.yml b/example-config/application.yml index 66ee3465..39b86e43 100644 --- a/example-config/application.yml +++ b/example-config/application.yml @@ -71,6 +71,8 @@ mag: #audit-repository-transport: TLS ch-epr-fhir: + ch-mhd: true + ch-ppqm: true ch-pixm-constraints: true ch-pdqm-constraints: true epr-spid-as-patientid: true @@ -84,4 +86,8 @@ server: key-store: secret/server.p12 key-store-password: magpat client-auth: NEED -ipf.fhir.servlet.logging: true \ No newline at end of file +ipf: + fhir: + servlet: + logging: true + highlight: false \ No newline at end of file diff --git a/example-config/test.http b/example-config/test.http index 3271b087..34cb6ab7 100644 --- a/example-config/test.http +++ b/example-config/test.http @@ -6,10 +6,10 @@ GET http://localhost:9090/fhir/metadata HTTP/1.1 Accept: application/fhir+json ### Responding Gateway configured -GET https://wswh3064-9090.euw.devtunnels.ms/fhir/metadata HTTP/1.1 +GET https://44dpzvq5-9090.euw.devtunnels.ms/fhir/metadata HTTP/1.1 Accept: application/fhir+json -### +###xw GET https://localhost:9091/fhir/metadata HTTP/1.1 Accept: application/fhir+json @@ -37,6 +37,7 @@ Accept: application/fhir+json GET http://localhost:9090/fhir/Patient/761337610411265304 HTTP/1.1 Accept: application/fhir+json + ### HL7v3 Responders Receiver device id.root OID 2.16.756.5.30.1.145.2024.1 ### HL7v3 Responders Organizationt OID 2.16.756.5.30.1.145.2024 ### assuming ahdis has for testing an assiging authority of 2.16.756.5.30.1.145.1.1.1 (root id is 2.16.756.5.30.1.145), and we need to proivde the organization provider @@ -95,7 +96,7 @@ Content-Type: application/fhir+json ### try a new one -PUT http://localhost:9090/fhir/Patient?identifier=urn:oid:2.16.756.5.30.1.145.2024.1|MAGMED006 HTTP/1.1 +PUT http://localhost:9090/fhir/Patient?identifier=urn:oid:1.3.6.1.4.1.12559.11.1.4.1.2|DDS-72619 HTTP/1.1 Accept: application/fhir+json Content-Type: application/fhir+json @@ -104,23 +105,23 @@ Content-Type: application/fhir+json "identifier": [ { "system": "urn:oid:2.16.756.5.30.1.127.3.10.3", - "value": "761337615758291048" + "value": "761337610067311311" }, { - "system": "urn:oid:2.16.756.5.30.1.145.2024.1", - "value": "MAGMED006" + "system": "urn:oid:1.3.6.1.4.1.12559.11.1.4.1.2", + "value": "DDS-72619" } ], "active": true, "name": [ { - "family": "Sesztáková", + "family": "PUTOD", "given": [ - "Jett Flynn" + "Elvira" ] } ], - "gender": "male", + "gender": "female", "birthDate": "1993-01-27", "managingOrganization" : { "identifier" : { diff --git a/src/main/java/ch/bfh/ti/i4mi/mag/Config.java b/src/main/java/ch/bfh/ti/i4mi/mag/Config.java index 57cb95a8..6f916321 100644 --- a/src/main/java/ch/bfh/ti/i4mi/mag/Config.java +++ b/src/main/java/ch/bfh/ti/i4mi/mag/Config.java @@ -198,6 +198,12 @@ public class Config { @Value("${mag.ch-epr-fhir.epr-spid-as-patientid:false}") private boolean chEprspidAsPatientId; + @Value("${mag.ch-epr-fhir.ch-mhd:false}") + private boolean chMhd; + + @Value("${mag.ch-epr-fhir.ch-ppqm:false}") + private boolean chPpqm; + /** * baseurl of gateway diff --git a/src/main/java/ch/bfh/ti/i4mi/mag/common/RequestHeadersForwarder.java b/src/main/java/ch/bfh/ti/i4mi/mag/common/RequestHeadersForwarder.java index a72ef089..e283eb70 100644 --- a/src/main/java/ch/bfh/ti/i4mi/mag/common/RequestHeadersForwarder.java +++ b/src/main/java/ch/bfh/ti/i4mi/mag/common/RequestHeadersForwarder.java @@ -12,6 +12,8 @@ import org.w3c.dom.Node; import org.w3c.dom.NodeList; +import ca.uhn.fhir.rest.server.exceptions.AuthenticationException; + import javax.xml.namespace.QName; import javax.xml.stream.XMLStreamException; import java.io.StringReader; @@ -42,6 +44,16 @@ public static Processor forward() { }; } + public static Processor checkAuthorization(boolean check) { + return exchange -> { + final var authorizationHeader = FhirExchanges.readRequestHttpHeader(AUTHORIZATION_HEADER, exchange, true); + if (check && authorizationHeader == null) { + throw new AuthenticationException(); + } + // TODO verify if the token is valid + }; + } + /** * Forwards the Authorization header to the next hop. *

diff --git a/src/main/java/ch/bfh/ti/i4mi/mag/mhd/iti65/Iti65RouteBuilder.java b/src/main/java/ch/bfh/ti/i4mi/mag/mhd/iti65/Iti65RouteBuilder.java index a0c26ade..044717cc 100644 --- a/src/main/java/ch/bfh/ti/i4mi/mag/mhd/iti65/Iti65RouteBuilder.java +++ b/src/main/java/ch/bfh/ti/i4mi/mag/mhd/iti65/Iti65RouteBuilder.java @@ -66,6 +66,7 @@ public void configure() throws Exception { // pass back errors to the endpoint .errorHandler(noErrorHandler()) //.process(itiRequestValidator()) + .process(RequestHeadersForwarder.checkAuthorization(config.isChMhd())) .process(RequestHeadersForwarder.forward()) // translate, forward, translate back .process(Utils.keepBody()) diff --git a/src/main/java/ch/bfh/ti/i4mi/mag/mhd/iti66/Iti66RouteBuilder.java b/src/main/java/ch/bfh/ti/i4mi/mag/mhd/iti66/Iti66RouteBuilder.java index a5d45696..19807b23 100644 --- a/src/main/java/ch/bfh/ti/i4mi/mag/mhd/iti66/Iti66RouteBuilder.java +++ b/src/main/java/ch/bfh/ti/i4mi/mag/mhd/iti66/Iti66RouteBuilder.java @@ -66,6 +66,7 @@ public void configure() throws Exception { from("mhd-iti66-v401:translation?audit=true&auditContext=#myAuditContext").routeId("mdh-documentmanifest-adapter") // pass back errors to the endpoint .errorHandler(noErrorHandler()) + .process(RequestHeadersForwarder.checkAuthorization(config.isChMhd())) .process(RequestHeadersForwarder.forward()).choice() .when(header(Constants.FHIR_REQUEST_PARAMETERS).isNotNull()) .bean(Utils.class,"searchParameterToBody") diff --git a/src/main/java/ch/bfh/ti/i4mi/mag/mhd/iti67/Iti67RouteBuilder.java b/src/main/java/ch/bfh/ti/i4mi/mag/mhd/iti67/Iti67RouteBuilder.java index d96f9406..c4b4ea84 100644 --- a/src/main/java/ch/bfh/ti/i4mi/mag/mhd/iti67/Iti67RouteBuilder.java +++ b/src/main/java/ch/bfh/ti/i4mi/mag/mhd/iti67/Iti67RouteBuilder.java @@ -89,6 +89,7 @@ public void configure() throws Exception { from("mhd-iti67-v401:translation?audit=true&auditContext=#myAuditContext").routeId("mdh-documentreference-adapter") // pass back errors to the endpoint .errorHandler(noErrorHandler()) + .process(RequestHeadersForwarder.checkAuthorization(config.isChMhd())) .process(RequestHeadersForwarder.forward()) .choice() .when(header(Constants.FHIR_REQUEST_PARAMETERS).isNotNull()) diff --git a/src/main/java/ch/bfh/ti/i4mi/mag/mhd/iti68/Iti68RouteBuilder.java b/src/main/java/ch/bfh/ti/i4mi/mag/mhd/iti68/Iti68RouteBuilder.java index 86492190..02c90d4b 100644 --- a/src/main/java/ch/bfh/ti/i4mi/mag/mhd/iti68/Iti68RouteBuilder.java +++ b/src/main/java/ch/bfh/ti/i4mi/mag/mhd/iti68/Iti68RouteBuilder.java @@ -62,6 +62,7 @@ public void configure() throws Exception { from("mhd-iti68:camel/xdsretrieve?audit=true&auditContext=#myAuditContext").routeId("ddh-retrievedoc-adapter") // pass back errors to the endpoint .errorHandler(noErrorHandler()) + .process(RequestHeadersForwarder.checkAuthorization(config.isChMhd())) .process(RequestHeadersForwarder.forward()) // translate, forward, translate back diff --git a/src/main/java/ch/bfh/ti/i4mi/mag/mhd/pharm5/Pharm5RouteBuilder.java b/src/main/java/ch/bfh/ti/i4mi/mag/mhd/pharm5/Pharm5RouteBuilder.java index 52f4b5cd..2e0dfeff 100644 --- a/src/main/java/ch/bfh/ti/i4mi/mag/mhd/pharm5/Pharm5RouteBuilder.java +++ b/src/main/java/ch/bfh/ti/i4mi/mag/mhd/pharm5/Pharm5RouteBuilder.java @@ -61,6 +61,7 @@ public void configure() throws Exception { from("mhd-pharm5:translation?audit=true&auditContext=#myAuditContext").routeId("mdh-documentreference-findmedicationlist-adapter") // pass back errors to the endpoint .errorHandler(noErrorHandler()) + .process(RequestHeadersForwarder.checkAuthorization(config.isChMhd())) .process(RequestHeadersForwarder.forward()) .bean(Pharm5RequestConverter.class) .to(endpoint) diff --git a/src/main/java/ch/bfh/ti/i4mi/mag/pmir/iti104/Iti104RouteBuilder.java b/src/main/java/ch/bfh/ti/i4mi/mag/pmir/iti104/Iti104RouteBuilder.java index d1b4d006..73ae96b9 100644 --- a/src/main/java/ch/bfh/ti/i4mi/mag/pmir/iti104/Iti104RouteBuilder.java +++ b/src/main/java/ch/bfh/ti/i4mi/mag/pmir/iti104/Iti104RouteBuilder.java @@ -87,6 +87,7 @@ public void configure() throws Exception { from("pmir-iti104:stub?audit=true&auditContext=#myAuditContext").routeId("iti104-feed") // pass back errors to the endpoint .errorHandler(noErrorHandler()) + .process(RequestHeadersForwarder.checkAuthorization(config.isChPdqmConstraints())) .process(RequestHeadersForwarder.forward()) .process(Utils.keepBody()) .bean(Iti104RequestConverter.class) diff --git a/src/main/java/ch/bfh/ti/i4mi/mag/pmir/iti78/Iti78RouteBuilder.java b/src/main/java/ch/bfh/ti/i4mi/mag/pmir/iti78/Iti78RouteBuilder.java index f7e1f4f8..1f63e31f 100644 --- a/src/main/java/ch/bfh/ti/i4mi/mag/pmir/iti78/Iti78RouteBuilder.java +++ b/src/main/java/ch/bfh/ti/i4mi/mag/pmir/iti78/Iti78RouteBuilder.java @@ -67,6 +67,7 @@ public void configure() throws Exception { from("pdqm-iti78:translation?audit=true&auditContext=#myAuditContext").routeId("pdqm-adapter") // pass back errors to the endpoint .errorHandler(noErrorHandler()) + .process(RequestHeadersForwarder.checkAuthorization(config.isChPdqmConstraints())) .process(RequestHeadersForwarder.forward()) .choice() .when(header(Constants.FHIR_REQUEST_PARAMETERS).isNotNull()) diff --git a/src/main/java/ch/bfh/ti/i4mi/mag/pmir/iti83/Iti83RouteBuilder.java b/src/main/java/ch/bfh/ti/i4mi/mag/pmir/iti83/Iti83RouteBuilder.java index b4e3a53a..33934a72 100644 --- a/src/main/java/ch/bfh/ti/i4mi/mag/pmir/iti83/Iti83RouteBuilder.java +++ b/src/main/java/ch/bfh/ti/i4mi/mag/pmir/iti83/Iti83RouteBuilder.java @@ -67,6 +67,7 @@ public void configure() throws Exception { from("pixm-iti83:translation?audit=true&auditContext=#myAuditContext").routeId("pixm-adapter") // pass back errors to the endpoint .errorHandler(noErrorHandler()) + .process(RequestHeadersForwarder.checkAuthorization(config.isChPixmConstraints())) .process(RequestHeadersForwarder.forward()) .process(Utils.keepBody()) .bean(Iti83RequestConverter.class) diff --git a/src/main/java/ch/bfh/ti/i4mi/mag/pmir/iti93/Iti93RouteBuilder.java b/src/main/java/ch/bfh/ti/i4mi/mag/pmir/iti93/Iti93RouteBuilder.java index 6ec4ae79..959118f7 100644 --- a/src/main/java/ch/bfh/ti/i4mi/mag/pmir/iti93/Iti93RouteBuilder.java +++ b/src/main/java/ch/bfh/ti/i4mi/mag/pmir/iti93/Iti93RouteBuilder.java @@ -70,6 +70,7 @@ public void configure() throws Exception { from("pmir-iti93:stub?audit=true&auditContext=#myAuditContext").routeId("pmir-feed") // pass back errors to the endpoint .errorHandler(noErrorHandler()) + .process(RequestHeadersForwarder.checkAuthorization(config.isChMhd())) .process(RequestHeadersForwarder.forward()) .process(Utils.keepBody()) .bean(Iti93RequestConverter.class) diff --git a/src/main/java/ch/bfh/ti/i4mi/mag/ppqm/Ppq5RouteBuilder.java b/src/main/java/ch/bfh/ti/i4mi/mag/ppqm/Ppq5RouteBuilder.java index f3bdfe46..311f6970 100644 --- a/src/main/java/ch/bfh/ti/i4mi/mag/ppqm/Ppq5RouteBuilder.java +++ b/src/main/java/ch/bfh/ti/i4mi/mag/ppqm/Ppq5RouteBuilder.java @@ -43,6 +43,7 @@ public void configure() throws Exception { from("ch-ppq5:stub") .setHeader(FhirCamelValidators.VALIDATION_MODE, constant(FhirCamelValidators.MODEL)) .process(FhirCamelValidators.itiRequestValidator()) + .process(RequestHeadersForwarder.checkAuthorization(config.isChPpqm())) .process(RequestHeadersForwarder.forward()) .process(exchange -> { String ppq5Request = exchange.getMessage().getHeader(Constants.HTTP_QUERY, String.class); diff --git a/src/main/java/ch/bfh/ti/i4mi/mag/ppqm/PpqmFeedRouteBuilder.java b/src/main/java/ch/bfh/ti/i4mi/mag/ppqm/PpqmFeedRouteBuilder.java index f1b6bda9..38ed7bc1 100644 --- a/src/main/java/ch/bfh/ti/i4mi/mag/ppqm/PpqmFeedRouteBuilder.java +++ b/src/main/java/ch/bfh/ti/i4mi/mag/ppqm/PpqmFeedRouteBuilder.java @@ -87,6 +87,7 @@ public void configure() throws Exception { from(getUriSchema() + ":stub") .setHeader(FhirCamelValidators.VALIDATION_MODE, constant(FhirCamelValidators.MODEL)) .process(FhirCamelValidators.itiRequestValidator()) + .process(RequestHeadersForwarder.checkAuthorization(config.isChPpqm())) .process(RequestHeadersForwarder.forward()) .process(exchange -> { Object body = exchange.getMessage().getBody(); @@ -128,6 +129,7 @@ public void configure() throws Exception { exchange.getMessage().setBody(ppqMessageCreator.createPolicyQuery(policySetIds)); log.info("Created PPQ-2 request for {} policy set(s)", policySetIds.size()); }) + .process(RequestHeadersForwarder.checkAuthorization(config.isChPpqm())) .process(RequestHeadersForwarder.forward()) .to("ch-ppq2://" + config.getPpq2HostUrl()) .process(TraceparentHandler.updateHeaderForFhir())