From f196c91ada89570645b5f91fd61743d8172658e9 Mon Sep 17 00:00:00 2001 From: Dmitry Tulba Date: Wed, 9 Aug 2023 15:07:20 +0300 Subject: [PATCH 01/53] fix the location --- .../java/org/ehrbase/rest/admin/AdminCompositionController.java | 2 +- .../org/ehrbase/rest/openehr/OpenehrCompositionController.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminCompositionController.java b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminCompositionController.java index 46001e33d..78dc733f9 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminCompositionController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminCompositionController.java @@ -110,7 +110,7 @@ public ResponseEntity deleteComposition( .setEhrIds(ehrId) .setCompositionId(compositionId) .setTemplateId(compositionService.retrieveTemplateId(compositionUid)) - .setLocation(UriComponentsBuilder.fromPath("/{ehr_id}/composition/{composition_id}") + .setLocation(UriComponentsBuilder.fromPath("/ehr/{ehr_id}/composition/{composition_id}") .build(ehrId, compositionId) .toString()); diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrCompositionController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrCompositionController.java index 16eccf126..59dbf3633 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrCompositionController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrCompositionController.java @@ -404,7 +404,7 @@ private String getLocationUrl(UUID versionedObjectUid, UUID ehrId, int version) version = compositionService.getLastVersionNumber(versionedObjectUid); } - return fromPath("{ehrSegment}/{ehrId}/{compositionSegment}/{compositionId}::{nodeName}::{version}") + return fromPath("/{ehrSegment}/{ehrId}/{compositionSegment}/{compositionId}::{nodeName}::{version}") .build( EHR, ehrId.toString(), From 88a063775eef9e3761c649b93783c6fccc136f61 Mon Sep 17 00:00:00 2001 From: Dmitry Tulba Date: Wed, 9 Aug 2023 15:20:58 +0300 Subject: [PATCH 02/53] update CHANGELOG.md --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ab6c9797..badacac34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,8 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [unreleased] ### Added ### Changed - ### Fixed + ### Fixed + - fix atna location ([#1160](https://github.com/ehrbase/ehrbase/pull/1160)) ## [0.29.0] ### Added From e97c5ad91f0d34288d841777bbe7bdb8a3fc2294 Mon Sep 17 00:00:00 2001 From: MBA Date: Thu, 20 Apr 2023 11:33:13 +0200 Subject: [PATCH 03/53] XACML stuff --- .../src/main/resources/application-xacml.yml | 8 ++++++++ .../rest/openehr/OpenehrQueryController.java | 19 +++++++++++++++++-- .../openehr/OpenehrTemplateController.java | 6 ++++++ 3 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 application/src/main/resources/application-xacml.yml diff --git a/application/src/main/resources/application-xacml.yml b/application/src/main/resources/application-xacml.yml new file mode 100644 index 000000000..31eae4c27 --- /dev/null +++ b/application/src/main/resources/application-xacml.yml @@ -0,0 +1,8 @@ +xacml.persistence: + hibernate.dialect: org.hibernate.dialect.PostgreSQLDialect + hibernate.hbm2ddl.auto: update + hibernate.default_schema: ehr + javax.persistence.jdbc.driver: org.postgresql.Driver + javax.persistence.jdbc.url: jdbc:postgresql://localhost:5432/ehrbase + javax.persistence.jdbc.user: ehrbase_restricted + javax.persistence.jdbc.password: ehrbase_restricted diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java index 1a11e1b9d..e3d1d6d26 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java @@ -24,6 +24,9 @@ import java.util.Map; import java.util.Optional; import java.util.Set; + +import javax.servlet.http.HttpServletRequest; + import org.apache.commons.collections4.MapUtils; import org.ehrbase.api.annotations.TenantAware; import org.ehrbase.api.audit.msg.AuditMsgBuilder; @@ -37,6 +40,11 @@ import org.ehrbase.openehr.sdk.response.dto.ehrscape.QueryResultDto; import org.ehrbase.rest.BaseController; import org.ehrbase.rest.openehr.specification.QueryApiSpecification; +import org.ehrbase.security.annotation.Action; +import org.ehrbase.security.annotation.ResourceId; +import org.ehrbase.security.annotation.TenantPolicyLookup; +import org.ehrbase.security.annotation.XacmlAuthorization; +import org.ehrbase.security.annotation.XacmlParam; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -62,6 +70,7 @@ * @since 1.0 */ @TenantAware +@TenantPolicyLookup @RestController @RequestMapping(path = BaseController.API_CONTEXT_PATH_WITH_VERSION + "/query") public class OpenehrQueryController extends BaseController implements QueryApiSpecification { @@ -84,12 +93,15 @@ public OpenehrQueryController(QueryService queryService) { /** * {@inheritDoc} */ + @XacmlAuthorization + @ResourceId(resourceId = "OpenehrQueryController") + @Action(action = "query_aql") @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_QUERY_SEARCH_AD_HOC) @Override @GetMapping(path = "/aql") @PostAuthorize("checkAbacPostQuery(@requestAwareAuditResultMapHolder.getAuditResultMap())") public ResponseEntity executeAdHocQuery( - @RequestParam(name = "q") String query, + @XacmlParam @RequestParam(name = "q") String query, @RequestParam(name = "offset", required = false) Integer offset, @RequestParam(name = "fetch", required = false) Integer fetch, @RequestParam(name = "query_parameters", required = false) Map queryParameters, @@ -119,13 +131,16 @@ public ResponseEntity executeAdHocQuery( /** * {@inheritDoc} */ + @XacmlAuthorization + @ResourceId(resourceId = "OpenehrQueryController") + @Action(action = "query_aql") @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_QUERY_SEARCH_AD_HOC) @Override @PostMapping(path = "/aql") @PostAuthorize("checkAbacPostQuery(@requestAwareAuditResultMapHolder.getAuditResultMap())") @SuppressWarnings("unchecked") public ResponseEntity executeAdHocQuery( - @RequestBody Map queryRequest, + @XacmlParam @RequestBody Map queryRequest, @RequestHeader(name = ACCEPT, required = false) String accept, @RequestHeader(name = CONTENT_TYPE) String contentType) { diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrTemplateController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrTemplateController.java index 745f6cdc4..9cf198f67 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrTemplateController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrTemplateController.java @@ -50,6 +50,9 @@ import org.ehrbase.rest.BaseController; import org.ehrbase.rest.openehr.specification.TemplateApiSpecification; import org.ehrbase.rest.util.InternalResponse; +import org.ehrbase.security.annotation.Action; +import org.ehrbase.security.annotation.ResourceId; +import org.ehrbase.security.annotation.XacmlAuthorization; import org.openehr.schemas.v1.TemplateDocument; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; @@ -156,6 +159,9 @@ public ResponseEntity createTemplateClassic( // significantly @Override @GetMapping("/adl1.4") + @XacmlAuthorization + @Action(action = "method:call:getTemplatesClassic") + @ResourceId(resourceId = "OpenehrTemplateController") @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_TEMPLATE_READ) public ResponseEntity getTemplatesClassic( @RequestHeader(value = "openEHR-VERSION", required = false) String openehrVersion, // TODO, see EHR-267 From bcfd09f7e97695ac76c97f698240962a4d01a3a0 Mon Sep 17 00:00:00 2001 From: Alex Vidrean Date: Tue, 2 May 2023 09:52:27 +0300 Subject: [PATCH 04/53] Add XACML auth for create ehr --- .../java/org/ehrbase/rest/openehr/OpenehrEhrController.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrController.java index 515b968fc..dc9431aed 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrController.java @@ -40,6 +40,7 @@ import org.ehrbase.rest.BaseController; import org.ehrbase.rest.openehr.specification.EhrApiSpecification; import org.ehrbase.rest.util.InternalResponse; +import org.ehrbase.security.annotation.XacmlAuthorization; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -75,6 +76,7 @@ public OpenehrEhrController(EhrService ehrService) { } @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_EHR_CREATE) + @XacmlAuthorization @PostMapping // (consumes = {"application/xml", "application/json"}) @ResponseStatus(value = HttpStatus.CREATED) // TODO auditing headers (openehr*) ignored until auditing is implemented @@ -98,6 +100,7 @@ public ResponseEntity createEhr( } @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_EHR_CREATE) + @XacmlAuthorization @PutMapping(path = "/{ehr_id}") @ResponseStatus(value = HttpStatus.CREATED) @Override From 37420e1220782d68b05cbf2423d385d65768a0e4 Mon Sep 17 00:00:00 2001 From: Alex Vidrean Date: Tue, 2 May 2023 10:07:49 +0300 Subject: [PATCH 05/53] Add XACML action and resource id --- .../java/org/ehrbase/rest/openehr/OpenehrEhrController.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrController.java index dc9431aed..2931bd7b9 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrController.java @@ -40,6 +40,8 @@ import org.ehrbase.rest.BaseController; import org.ehrbase.rest.openehr.specification.EhrApiSpecification; import org.ehrbase.rest.util.InternalResponse; +import org.ehrbase.security.annotation.Action; +import org.ehrbase.security.annotation.ResourceId; import org.ehrbase.security.annotation.XacmlAuthorization; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; @@ -77,6 +79,8 @@ public OpenehrEhrController(EhrService ehrService) { @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_EHR_CREATE) @XacmlAuthorization + @Action(action = "method:call:createEhr") + @ResourceId(resourceId = "OpenehrEhrController") @PostMapping // (consumes = {"application/xml", "application/json"}) @ResponseStatus(value = HttpStatus.CREATED) // TODO auditing headers (openehr*) ignored until auditing is implemented @@ -101,6 +105,8 @@ public ResponseEntity createEhr( @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_EHR_CREATE) @XacmlAuthorization + @Action(action = "method:call:createEhrWithId") + @ResourceId(resourceId = "OpenehrEhrController") @PutMapping(path = "/{ehr_id}") @ResponseStatus(value = HttpStatus.CREATED) @Override From 5203cf95e6a9836c534bde3ec0c68357631e24d4 Mon Sep 17 00:00:00 2001 From: Alex Vidrean Date: Tue, 2 May 2023 13:41:03 +0300 Subject: [PATCH 06/53] CDR-790 Add packaging as jar --- application/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/application/pom.xml b/application/pom.xml index 007c3d788..ea3586977 100644 --- a/application/pom.xml +++ b/application/pom.xml @@ -30,6 +30,7 @@ application + jar vitasystems/hip-openehr From 0a182bd21d7e6230621c5f1bd0f7b3dbcefadf79 Mon Sep 17 00:00:00 2001 From: Alex Vidrean Date: Wed, 3 May 2023 14:32:13 +0300 Subject: [PATCH 07/53] Add tenant policy lookup to EHR Controller --- .../java/org/ehrbase/rest/openehr/OpenehrEhrController.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrController.java index 2931bd7b9..d009a1b63 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrController.java @@ -42,6 +42,7 @@ import org.ehrbase.rest.util.InternalResponse; import org.ehrbase.security.annotation.Action; import org.ehrbase.security.annotation.ResourceId; +import org.ehrbase.security.annotation.TenantPolicyLookup; import org.ehrbase.security.annotation.XacmlAuthorization; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; @@ -64,6 +65,7 @@ * Controller for /ehr resource of openEHR REST API */ @TenantAware +@TenantPolicyLookup @RestController @RequestMapping( path = BaseController.API_CONTEXT_PATH_WITH_VERSION + "/ehr", From 0b855b713cebc31a1be361cfe7d74b62d6324935 Mon Sep 17 00:00:00 2001 From: MBA Date: Tue, 9 May 2023 11:37:42 +0200 Subject: [PATCH 08/53] Rebased on Dev --- .../application-trigger.yml | 9 +++++++++ .../multi-tenant-plugin-1.2.0-SNAPSHOT.jar | Bin 0 -> 18266 bytes application/pom.xml | 11 +++++++++++ .../application-authorization.properties | 12 ++++++++++++ .../src/main/resources/application-local.yml | 2 +- application/src/main/resources/application.yml | 2 +- rest-openehr/pom.xml | 6 ++++++ .../rest/openehr/OpenehrQueryController.java | 3 +++ 8 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 application/plugin_config_dir/ehrbase_event_trigger_v1/application-trigger.yml create mode 100644 application/plugin_dir/multi-tenant-plugin-1.2.0-SNAPSHOT.jar create mode 100644 application/src/main/resources/application-authorization.properties diff --git a/application/plugin_config_dir/ehrbase_event_trigger_v1/application-trigger.yml b/application/plugin_config_dir/ehrbase_event_trigger_v1/application-trigger.yml new file mode 100644 index 000000000..253195334 --- /dev/null +++ b/application/plugin_config_dir/ehrbase_event_trigger_v1/application-trigger.yml @@ -0,0 +1,9 @@ +spring: + rabbitmq: + host: 127.0.0.1 + port: 5672 + username: guest + password: guest + +eventtrigger: + workers: 1 diff --git a/application/plugin_dir/multi-tenant-plugin-1.2.0-SNAPSHOT.jar b/application/plugin_dir/multi-tenant-plugin-1.2.0-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..56e3b56d4ad7a1c2aaa9554d128224d18101eb28 GIT binary patch literal 18266 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 + + org.ehrbase + xacml-authorization + 1.0.0-SNAPSHOT + + + org.ops4j.pax.logging + pax-logging-api + + + org.springframework.boot spring-boot-starter-web diff --git a/application/src/main/resources/application-authorization.properties b/application/src/main/resources/application-authorization.properties new file mode 100644 index 000000000..f7b6d0d77 --- /dev/null +++ b/application/src/main/resources/application-authorization.properties @@ -0,0 +1,12 @@ +authorization.service.rpt.token-expiry-skew=PT3M +authorization.service.disable.for.ehrbase_multi_tenant_v1=true + +authorization.service.config[0].tenantId=1234-abc +authorization.service.config[0].host=http://localhost:8081 +authorization.service.config[0].realm=Sacred Heart +authorization.service.config[0].client-id=ehrbase + +#authorization.service.config[1].tenantId=1234-abc +#authorization.service.config[1].host=http://localhost:8081 +#authorization.service.config[1].realm=Sacred Heart +#authorization.service.config[1].client-id=ehrbase diff --git a/application/src/main/resources/application-local.yml b/application/src/main/resources/application-local.yml index 3711ff92a..c03e30db4 100644 --- a/application/src/main/resources/application-local.yml +++ b/application/src/main/resources/application-local.yml @@ -55,7 +55,7 @@ server: iterationScanDepth: 20 security: - authType: NONE + authType: oauth #use admin for cleaning up the db during tests admin-api: diff --git a/application/src/main/resources/application.yml b/application/src/main/resources/application.yml index 4a8eb86f7..93902e1db 100644 --- a/application/src/main/resources/application.yml +++ b/application/src/main/resources/application.yml @@ -45,7 +45,7 @@ spring: oauth2: resourceserver: jwt: - issuer-uri: # http://localhost:8081/auth/realms/ehrbase # Example issuer URI - or set via env var + issuer-uri: http://localhost:8081/auth/realms/myTestRealm-c76fe4ff-28a4-4b24-9550-d34a324a836d profiles: active: local datasource: diff --git a/rest-openehr/pom.xml b/rest-openehr/pom.xml index c9bdac112..a0180841e 100644 --- a/rest-openehr/pom.xml +++ b/rest-openehr/pom.xml @@ -38,6 +38,12 @@ + + org.ehrbase + xacml-authorization-api + 1.0.0-SNAPSHOT + + org.springframework.boot spring-boot-starter-web diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java index e3d1d6d26..d8453314a 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java @@ -41,6 +41,7 @@ import org.ehrbase.rest.BaseController; import org.ehrbase.rest.openehr.specification.QueryApiSpecification; import org.ehrbase.security.annotation.Action; +import org.ehrbase.security.annotation.ConstrainAql; import org.ehrbase.security.annotation.ResourceId; import org.ehrbase.security.annotation.TenantPolicyLookup; import org.ehrbase.security.annotation.XacmlAuthorization; @@ -96,6 +97,7 @@ public OpenehrQueryController(QueryService queryService) { @XacmlAuthorization @ResourceId(resourceId = "OpenehrQueryController") @Action(action = "query_aql") + @ConstrainAql(constraint = "constraint") @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_QUERY_SEARCH_AD_HOC) @Override @GetMapping(path = "/aql") @@ -134,6 +136,7 @@ public ResponseEntity executeAdHocQuery( @XacmlAuthorization @ResourceId(resourceId = "OpenehrQueryController") @Action(action = "query_aql") + @ConstrainAql(constraint = "constraint") @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_QUERY_SEARCH_AD_HOC) @Override @PostMapping(path = "/aql") From 3c158fd36cc7bc6d508940ce978af62b460313c7 Mon Sep 17 00:00:00 2001 From: MBA Date: Mon, 22 May 2023 11:30:58 +0200 Subject: [PATCH 09/53] changed constraint name --- application/src/main/resources/application-local.yml | 1 + .../java/org/ehrbase/rest/openehr/OpenehrQueryController.java | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/application/src/main/resources/application-local.yml b/application/src/main/resources/application-local.yml index c03e30db4..0ebe8a85d 100644 --- a/application/src/main/resources/application-local.yml +++ b/application/src/main/resources/application-local.yml @@ -56,6 +56,7 @@ server: security: authType: oauth +# authType: none #use admin for cleaning up the db during tests admin-api: diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java index d8453314a..c8fa52db7 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java @@ -97,7 +97,7 @@ public OpenehrQueryController(QueryService queryService) { @XacmlAuthorization @ResourceId(resourceId = "OpenehrQueryController") @Action(action = "query_aql") - @ConstrainAql(constraint = "constraint") + @ConstrainAql(constraint = "LimitByFacilityName") @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_QUERY_SEARCH_AD_HOC) @Override @GetMapping(path = "/aql") @@ -136,7 +136,7 @@ public ResponseEntity executeAdHocQuery( @XacmlAuthorization @ResourceId(resourceId = "OpenehrQueryController") @Action(action = "query_aql") - @ConstrainAql(constraint = "constraint") + @ConstrainAql(constraint = "LimitByFacilityName") @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_QUERY_SEARCH_AD_HOC) @Override @PostMapping(path = "/aql") From 61fc83cad595b65d514af1d9a2e3ff70e0896d56 Mon Sep 17 00:00:00 2001 From: MBA Date: Tue, 20 Jun 2023 11:13:03 +0200 Subject: [PATCH 10/53] Adapted to cdr-xaml-authorization-lib --- application/pom.xml | 8 +++-- .../java/org/ehrbase/application/EhrBase.java | 3 ++ rest-openehr/pom.xml | 6 ++-- .../rest/openehr/OpenehrEhrController.java | 34 +++++++++--------- .../rest/openehr/OpenehrQueryController.java | 35 ++++++++----------- .../openehr/OpenehrTemplateController.java | 30 ++++++++-------- 6 files changed, 57 insertions(+), 59 deletions(-) diff --git a/application/pom.xml b/application/pom.xml index ad0e02555..84fc6e2e4 100644 --- a/application/pom.xml +++ b/application/pom.xml @@ -38,15 +38,17 @@ - org.ehrbase - xacml-authorization - 1.0.0-SNAPSHOT + ag.vitagroup.hip.cdr.authorization + cdr-xacml-authorization-lib + 1.1.1-SNAPSHOT + org.springframework.boot diff --git a/application/src/main/java/org/ehrbase/application/EhrBase.java b/application/src/main/java/org/ehrbase/application/EhrBase.java index 9810a4ec4..1f598ea2a 100644 --- a/application/src/main/java/org/ehrbase/application/EhrBase.java +++ b/application/src/main/java/org/ehrbase/application/EhrBase.java @@ -27,6 +27,8 @@ import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; import org.springframework.context.annotation.Import; +import ag.vitagroup.hip.cdr.authorization.EnableXacmlAuthorization; + /** * @author Stefan Spiska * @since 1.0 @@ -37,6 +39,7 @@ R2dbcAutoConfiguration.class, SecurityAutoConfiguration.class }) +@EnableXacmlAuthorization @Import({ServiceModuleConfiguration.class, RestEHRScapeModuleConfiguration.class, RestModuleConfiguration.class}) public class EhrBase { diff --git a/rest-openehr/pom.xml b/rest-openehr/pom.xml index a0180841e..3e4e06a02 100644 --- a/rest-openehr/pom.xml +++ b/rest-openehr/pom.xml @@ -39,9 +39,9 @@ - org.ehrbase - xacml-authorization-api - 1.0.0-SNAPSHOT + ag.vitagroup.hip.cdr.authorization + cdr-xacml-authorization-lib + 1.1.1-SNAPSHOT diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrController.java index d009a1b63..ed6e8545e 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrController.java @@ -17,9 +17,6 @@ */ package org.ehrbase.rest.openehr; -import com.nedap.archie.rm.datavalues.quantity.datetime.DvDateTime; -import com.nedap.archie.rm.ehr.EhrStatus; -import com.nedap.archie.rm.support.identification.HierObjectId; import java.net.URI; import java.util.Arrays; import java.util.List; @@ -27,9 +24,10 @@ import java.util.Optional; import java.util.UUID; import java.util.function.Supplier; + +import javax.servlet.http.HttpServletRequest; + import org.ehrbase.api.annotations.TenantAware; -import org.ehrbase.api.audit.msg.AuditMsgBuilder; -import org.ehrbase.api.authorization.EhrbaseAuthorization; import org.ehrbase.api.authorization.EhrbasePermission; import org.ehrbase.api.exception.InternalServerException; import org.ehrbase.api.exception.InvalidApiParameterException; @@ -40,10 +38,6 @@ import org.ehrbase.rest.BaseController; import org.ehrbase.rest.openehr.specification.EhrApiSpecification; import org.ehrbase.rest.util.InternalResponse; -import org.ehrbase.security.annotation.Action; -import org.ehrbase.security.annotation.ResourceId; -import org.ehrbase.security.annotation.TenantPolicyLookup; -import org.ehrbase.security.annotation.XacmlAuthorization; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -61,6 +55,16 @@ import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; +import com.nedap.archie.rm.datavalues.quantity.datetime.DvDateTime; +import com.nedap.archie.rm.ehr.EhrStatus; +import com.nedap.archie.rm.support.identification.HierObjectId; + +import ag.vitagroup.hip.cdr.authorization.annotation.Action; +import ag.vitagroup.hip.cdr.authorization.annotation.ResourceId; +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; +import ag.vitagroup.hip.cdr.authorization.annotation.TenantPolicyLookup; +import ag.vitagroup.hip.cdr.authorization.annotation.XacmlAuthorization; + /** * Controller for /ehr resource of openEHR REST API */ @@ -79,14 +83,13 @@ public OpenehrEhrController(EhrService ehrService) { this.ehrService = Objects.requireNonNull(ehrService); } - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_EHR_CREATE) + @Scope(scope = EhrbasePermission.EHRBASE_EHR_CREATE) @XacmlAuthorization @Action(action = "method:call:createEhr") @ResourceId(resourceId = "OpenehrEhrController") @PostMapping // (consumes = {"application/xml", "application/json"}) @ResponseStatus(value = HttpStatus.CREATED) // TODO auditing headers (openehr*) ignored until auditing is implemented - @Override public ResponseEntity createEhr( @RequestHeader(value = "openEHR-VERSION", required = false) String openehrVersion, @RequestHeader(value = "openEHR-AUDIT_DETAILS", required = false) String openehrAuditDetails, @@ -105,13 +108,12 @@ public ResponseEntity createEhr( return internalPostEhrProcessing(accept, prefer, ehrId); } - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_EHR_CREATE) + @Scope(scope = EhrbasePermission.EHRBASE_EHR_CREATE) @XacmlAuthorization @Action(action = "method:call:createEhrWithId") @ResourceId(resourceId = "OpenehrEhrController") @PutMapping(path = "/{ehr_id}") @ResponseStatus(value = HttpStatus.CREATED) - @Override public ResponseEntity createEhrWithId( @RequestHeader(value = "openEHR-VERSION", required = false) String openehrVersion, @RequestHeader(value = "openEHR-AUDIT_DETAILS", required = false) String openehrAuditDetails, @@ -183,10 +185,9 @@ private void createAuditLogsMsgBuilder(UUID resultEhrId) { /** * Returns EHR by ID */ - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_EHR_READ) + @Scope(scope = EhrbasePermission.EHRBASE_EHR_READ) @GetMapping(path = "/{ehr_id}") @PreAuthorize("checkAbacPre(@openehrEhrController.EHR, @ehrService.getSubjectExtRef(#ehrIdString))") - @Override public ResponseEntity retrieveEhrById( @RequestHeader(value = HttpHeaders.ACCEPT, required = false) String accept, @PathVariable(value = "ehr_id") String ehrIdString) { @@ -203,10 +204,9 @@ public ResponseEntity retrieveEhrById( /** * Returns EHR by subject (id and namespace) */ - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_EHR_READ) + @Scope(scope = EhrbasePermission.EHRBASE_EHR_READ) @GetMapping(params = {"subject_id", "subject_namespace"}) @PreAuthorize("checkAbacPre(@openehrEhrController.EHR, #subjectId)") - @Override public ResponseEntity retrieveEhrBySubject( @RequestHeader(value = HttpHeaders.ACCEPT, required = false) String accept, @RequestParam(value = "subject_id") String subjectId, diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java index c8fa52db7..360d1868a 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java @@ -29,8 +29,6 @@ import org.apache.commons.collections4.MapUtils; import org.ehrbase.api.annotations.TenantAware; -import org.ehrbase.api.audit.msg.AuditMsgBuilder; -import org.ehrbase.api.authorization.EhrbaseAuthorization; import org.ehrbase.api.authorization.EhrbasePermission; import org.ehrbase.api.exception.InvalidApiParameterException; import org.ehrbase.api.exception.ObjectNotFoundException; @@ -40,12 +38,6 @@ import org.ehrbase.openehr.sdk.response.dto.ehrscape.QueryResultDto; import org.ehrbase.rest.BaseController; import org.ehrbase.rest.openehr.specification.QueryApiSpecification; -import org.ehrbase.security.annotation.Action; -import org.ehrbase.security.annotation.ConstrainAql; -import org.ehrbase.security.annotation.ResourceId; -import org.ehrbase.security.annotation.TenantPolicyLookup; -import org.ehrbase.security.annotation.XacmlAuthorization; -import org.ehrbase.security.annotation.XacmlParam; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -63,6 +55,13 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import ag.vitagroup.hip.cdr.authorization.annotation.Action; +import ag.vitagroup.hip.cdr.authorization.annotation.ResourceId; +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; +import ag.vitagroup.hip.cdr.authorization.annotation.TenantPolicyLookup; +import ag.vitagroup.hip.cdr.authorization.annotation.XacmlAuthorization; +import ag.vitagroup.hip.cdr.authorization.annotation.XacmlUrlRequestParameter; + /** * Controller for openEHR REST API QUERY resource. * @@ -97,13 +96,12 @@ public OpenehrQueryController(QueryService queryService) { @XacmlAuthorization @ResourceId(resourceId = "OpenehrQueryController") @Action(action = "query_aql") - @ConstrainAql(constraint = "LimitByFacilityName") - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_QUERY_SEARCH_AD_HOC) - @Override + /*@ConstrainAql(constraint = "LimitByFacilityName")*/ + @Scope(scope = EhrbasePermission.EHRBASE_QUERY_SEARCH_AD_HOC) @GetMapping(path = "/aql") @PostAuthorize("checkAbacPostQuery(@requestAwareAuditResultMapHolder.getAuditResultMap())") public ResponseEntity executeAdHocQuery( - @XacmlParam @RequestParam(name = "q") String query, + @XacmlUrlRequestParameter("q") @RequestParam(name = "q") String query, @RequestParam(name = "offset", required = false) Integer offset, @RequestParam(name = "fetch", required = false) Integer fetch, @RequestParam(name = "query_parameters", required = false) Map queryParameters, @@ -136,14 +134,13 @@ public ResponseEntity executeAdHocQuery( @XacmlAuthorization @ResourceId(resourceId = "OpenehrQueryController") @Action(action = "query_aql") - @ConstrainAql(constraint = "LimitByFacilityName") - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_QUERY_SEARCH_AD_HOC) - @Override + /*@ConstrainAql(constraint = "LimitByFacilityName")*/ + @Scope(scope = EhrbasePermission.EHRBASE_QUERY_SEARCH_AD_HOC) @PostMapping(path = "/aql") @PostAuthorize("checkAbacPostQuery(@requestAwareAuditResultMapHolder.getAuditResultMap())") @SuppressWarnings("unchecked") public ResponseEntity executeAdHocQuery( - @XacmlParam @RequestBody Map queryRequest, + @XacmlUrlRequestParameter("q") @RequestBody Map queryRequest, @RequestHeader(name = ACCEPT, required = false) String accept, @RequestHeader(name = CONTENT_TYPE) String contentType) { @@ -167,8 +164,7 @@ public ResponseEntity executeAdHocQuery( /** * {@inheritDoc} */ - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_QUERY_SEARCH) - @Override + @Scope(scope = EhrbasePermission.EHRBASE_QUERY_SEARCH) @GetMapping(path = {"/{qualified_query_name}", "/{qualified_query_name}/{version}"}) @PostAuthorize("checkAbacPostQuery(@requestAwareAuditResultMapHolder.getAuditResultMap())") public ResponseEntity executeStoredQuery( @@ -215,8 +211,7 @@ public ResponseEntity executeStoredQuery( /** * {@inheritDoc} */ - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_QUERY_SEARCH) - @Override + @Scope(scope = EhrbasePermission.EHRBASE_QUERY_SEARCH) @PostMapping(path = {"/{qualified_query_name}", "/{qualified_query_name}/{version}"}) @PostAuthorize("checkAbacPostQuery(@requestAwareAuditResultMapHolder.getAuditResultMap())") @SuppressWarnings("unchecked") diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrTemplateController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrTemplateController.java index 9cf198f67..035cb0cf3 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrTemplateController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrTemplateController.java @@ -20,7 +20,6 @@ import static org.springframework.http.MediaType.APPLICATION_JSON; import static org.springframework.http.MediaType.APPLICATION_XML; -import com.nedap.archie.rm.composition.Composition; import java.io.ByteArrayInputStream; import java.io.IOException; import java.net.URI; @@ -31,9 +30,9 @@ import java.util.Objects; import java.util.Optional; import java.util.function.Supplier; + import org.apache.xmlbeans.XmlException; import org.ehrbase.api.annotations.TenantAware; -import org.ehrbase.api.authorization.EhrbaseAuthorization; import org.ehrbase.api.authorization.EhrbasePermission; import org.ehrbase.api.definitions.OperationalTemplateFormat; import org.ehrbase.api.exception.InternalServerException; @@ -50,9 +49,6 @@ import org.ehrbase.rest.BaseController; import org.ehrbase.rest.openehr.specification.TemplateApiSpecification; import org.ehrbase.rest.util.InternalResponse; -import org.ehrbase.security.annotation.Action; -import org.ehrbase.security.annotation.ResourceId; -import org.ehrbase.security.annotation.XacmlAuthorization; import org.openehr.schemas.v1.TemplateDocument; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; @@ -69,6 +65,13 @@ import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; +import com.nedap.archie.rm.composition.Composition; + +import ag.vitagroup.hip.cdr.authorization.annotation.Action; +import ag.vitagroup.hip.cdr.authorization.annotation.ResourceId; +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; +import ag.vitagroup.hip.cdr.authorization.annotation.XacmlAuthorization; + /** * Controller for /template resource as part of the Definitions sub-API of the openEHR REST API */ @@ -92,12 +95,11 @@ public OpenehrTemplateController(TemplateService templateService, CompositionSer /* ADL 1.4 */ - @Override @PostMapping( path = "/adl1.4", produces = {MediaType.APPLICATION_XML_VALUE}) @ResponseStatus(value = HttpStatus.CREATED) - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_TEMPLATE_CREATE) + @Scope(scope = EhrbasePermission.EHRBASE_TEMPLATE_CREATE) public ResponseEntity createTemplateClassic( @RequestHeader(value = "openEHR-VERSION", required = false) String openehrVersion, // TODO, see EHR-267 @RequestHeader(value = "openEHR-AUDIT_DETAILS", required = false) @@ -157,12 +159,11 @@ public ResponseEntity createTemplateClassic( // Note: based on latest-branch of 1.1.0 release of openEHR REST API, because this endpoint was changed // significantly - @Override @GetMapping("/adl1.4") @XacmlAuthorization @Action(action = "method:call:getTemplatesClassic") @ResourceId(resourceId = "OpenehrTemplateController") - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_TEMPLATE_READ) + @Scope(scope = EhrbasePermission.EHRBASE_TEMPLATE_READ) public ResponseEntity getTemplatesClassic( @RequestHeader(value = "openEHR-VERSION", required = false) String openehrVersion, // TODO, see EHR-267 @RequestHeader(value = "openEHR-AUDIT_DETAILS", required = false) @@ -188,9 +189,8 @@ public ResponseEntity getTemplatesClassic( // Note: based on latest-branch of 1.1.0 release of openEHR REST API, because this endpoint was changed // significantly - @Override @GetMapping("/adl1.4/{template_id}") - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_TEMPLATE_READ) + @Scope(scope = EhrbasePermission.EHRBASE_TEMPLATE_READ) public ResponseEntity getTemplateClassic( @RequestHeader(value = "openEHR-VERSION", required = false) String openehrVersion, // TODO, see EHR-267 @RequestHeader(value = "openEHR-AUDIT_DETAILS", required = false) @@ -216,7 +216,7 @@ public ResponseEntity getTemplateClassic( } @GetMapping(path = "/adl1.4/{template_id}/example") - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_TEMPLATE_EXAMPLE) + @Scope(scope = EhrbasePermission.EHRBASE_TEMPLATE_READ) public ResponseEntity getTemplateExample( @RequestHeader(value = ACCEPT, required = false) String accept, @PathVariable(value = "template_id") String templateId) { @@ -242,10 +242,9 @@ public ResponseEntity getTemplateExample( ADL 2 TODO WIP state only implements endpoints from outer server side, everything else is a stub. Also with a lot of duplication at the moment, which should be reduced when implementing functionality. */ - @Override @PostMapping("/adl2") @ResponseStatus(value = HttpStatus.CREATED) - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_TEMPLATE_CREATE) + @Scope(scope = EhrbasePermission.EHRBASE_TEMPLATE_CREATE) public ResponseEntity createTemplateNew( @RequestHeader(value = "openEHR-VERSION", required = false) String openehrVersion, // TODO, see EHR-267 @RequestHeader(value = "openEHR-AUDIT_DETAILS", required = false) @@ -279,9 +278,8 @@ public ResponseEntity createTemplateNew( // significantly // also, this endpoint combines what is listed as two endpoints: // https://specifications.openehr.org/releases/ITS-REST/latest/definitions.html#definitions-adl-2-template-get - @Override @GetMapping("/adl2/{template_id}/{version_pattern}") - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_TEMPLATE_READ) + @Scope(scope = EhrbasePermission.EHRBASE_TEMPLATE_READ) public ResponseEntity getTemplateNew( @RequestHeader(value = "openEHR-VERSION", required = false) String openehrVersion, // TODO, see EHR-267 @RequestHeader(value = "openEHR-AUDIT_DETAILS", required = false) From 1384ee1eb1d52bf133758a4f998886f27f88c045 Mon Sep 17 00:00:00 2001 From: MBA Date: Tue, 20 Jun 2023 11:27:13 +0200 Subject: [PATCH 11/53] Rebased on Dev --- .../java/org/ehrbase/application/EhrBase.java | 3 +-- .../rest/openehr/OpenehrEhrController.java | 22 ++++++++----------- .../rest/openehr/OpenehrQueryController.java | 19 ++++++---------- .../openehr/OpenehrTemplateController.java | 13 +++++------ 4 files changed, 22 insertions(+), 35 deletions(-) diff --git a/application/src/main/java/org/ehrbase/application/EhrBase.java b/application/src/main/java/org/ehrbase/application/EhrBase.java index 1f598ea2a..dd4c7e0a9 100644 --- a/application/src/main/java/org/ehrbase/application/EhrBase.java +++ b/application/src/main/java/org/ehrbase/application/EhrBase.java @@ -17,6 +17,7 @@ */ package org.ehrbase.application; +import ag.vitagroup.hip.cdr.authorization.EnableXacmlAuthorization; import org.ehrbase.ServiceModuleConfiguration; import org.ehrbase.rest.RestModuleConfiguration; import org.ehrbase.rest.ehrscape.RestEHRScapeModuleConfiguration; @@ -27,8 +28,6 @@ import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; import org.springframework.context.annotation.Import; -import ag.vitagroup.hip.cdr.authorization.EnableXacmlAuthorization; - /** * @author Stefan Spiska * @since 1.0 diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrController.java index ed6e8545e..5e5f26100 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrController.java @@ -17,6 +17,14 @@ */ package org.ehrbase.rest.openehr; +import ag.vitagroup.hip.cdr.authorization.annotation.Action; +import ag.vitagroup.hip.cdr.authorization.annotation.ResourceId; +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; +import ag.vitagroup.hip.cdr.authorization.annotation.TenantPolicyLookup; +import ag.vitagroup.hip.cdr.authorization.annotation.XacmlAuthorization; +import com.nedap.archie.rm.datavalues.quantity.datetime.DvDateTime; +import com.nedap.archie.rm.ehr.EhrStatus; +import com.nedap.archie.rm.support.identification.HierObjectId; import java.net.URI; import java.util.Arrays; import java.util.List; @@ -24,10 +32,8 @@ import java.util.Optional; import java.util.UUID; import java.util.function.Supplier; - -import javax.servlet.http.HttpServletRequest; - import org.ehrbase.api.annotations.TenantAware; +import org.ehrbase.api.audit.msg.AuditMsgBuilder; import org.ehrbase.api.authorization.EhrbasePermission; import org.ehrbase.api.exception.InternalServerException; import org.ehrbase.api.exception.InvalidApiParameterException; @@ -55,16 +61,6 @@ import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; -import com.nedap.archie.rm.datavalues.quantity.datetime.DvDateTime; -import com.nedap.archie.rm.ehr.EhrStatus; -import com.nedap.archie.rm.support.identification.HierObjectId; - -import ag.vitagroup.hip.cdr.authorization.annotation.Action; -import ag.vitagroup.hip.cdr.authorization.annotation.ResourceId; -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; -import ag.vitagroup.hip.cdr.authorization.annotation.TenantPolicyLookup; -import ag.vitagroup.hip.cdr.authorization.annotation.XacmlAuthorization; - /** * Controller for /ehr resource of openEHR REST API */ diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java index 360d1868a..a45c866d4 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java @@ -17,18 +17,20 @@ */ package org.ehrbase.rest.openehr; -import static org.springframework.web.util.UriComponentsBuilder.fromPath; - +import ag.vitagroup.hip.cdr.authorization.annotation.Action; +import ag.vitagroup.hip.cdr.authorization.annotation.ResourceId; +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; +import ag.vitagroup.hip.cdr.authorization.annotation.TenantPolicyLookup; +import ag.vitagroup.hip.cdr.authorization.annotation.XacmlAuthorization; +import ag.vitagroup.hip.cdr.authorization.annotation.XacmlUrlRequestParameter; import java.text.MessageFormat; import java.util.HashMap; import java.util.Map; import java.util.Optional; import java.util.Set; - -import javax.servlet.http.HttpServletRequest; - import org.apache.commons.collections4.MapUtils; import org.ehrbase.api.annotations.TenantAware; +import org.ehrbase.api.audit.msg.AuditMsgBuilder; import org.ehrbase.api.authorization.EhrbasePermission; import org.ehrbase.api.exception.InvalidApiParameterException; import org.ehrbase.api.exception.ObjectNotFoundException; @@ -55,13 +57,6 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import ag.vitagroup.hip.cdr.authorization.annotation.Action; -import ag.vitagroup.hip.cdr.authorization.annotation.ResourceId; -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; -import ag.vitagroup.hip.cdr.authorization.annotation.TenantPolicyLookup; -import ag.vitagroup.hip.cdr.authorization.annotation.XacmlAuthorization; -import ag.vitagroup.hip.cdr.authorization.annotation.XacmlUrlRequestParameter; - /** * Controller for openEHR REST API QUERY resource. * diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrTemplateController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrTemplateController.java index 035cb0cf3..9136376eb 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrTemplateController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrTemplateController.java @@ -20,6 +20,11 @@ import static org.springframework.http.MediaType.APPLICATION_JSON; import static org.springframework.http.MediaType.APPLICATION_XML; +import ag.vitagroup.hip.cdr.authorization.annotation.Action; +import ag.vitagroup.hip.cdr.authorization.annotation.ResourceId; +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; +import ag.vitagroup.hip.cdr.authorization.annotation.XacmlAuthorization; +import com.nedap.archie.rm.composition.Composition; import java.io.ByteArrayInputStream; import java.io.IOException; import java.net.URI; @@ -30,7 +35,6 @@ import java.util.Objects; import java.util.Optional; import java.util.function.Supplier; - import org.apache.xmlbeans.XmlException; import org.ehrbase.api.annotations.TenantAware; import org.ehrbase.api.authorization.EhrbasePermission; @@ -65,13 +69,6 @@ import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; -import com.nedap.archie.rm.composition.Composition; - -import ag.vitagroup.hip.cdr.authorization.annotation.Action; -import ag.vitagroup.hip.cdr.authorization.annotation.ResourceId; -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; -import ag.vitagroup.hip.cdr.authorization.annotation.XacmlAuthorization; - /** * Controller for /template resource as part of the Definitions sub-API of the openEHR REST API */ From fbacf6b87af1eacea3d822b4b289c28710e5074e Mon Sep 17 00:00:00 2001 From: Alex Vidrean Date: Mon, 26 Jun 2023 10:10:34 +0300 Subject: [PATCH 12/53] Remove libraries --- application/pom.xml | 13 ------------- rest-openehr/pom.xml | 6 ------ 2 files changed, 19 deletions(-) diff --git a/application/pom.xml b/application/pom.xml index 84fc6e2e4..ea3586977 100644 --- a/application/pom.xml +++ b/application/pom.xml @@ -37,19 +37,6 @@ - - ag.vitagroup.hip.cdr.authorization - cdr-xacml-authorization-lib - 1.1.1-SNAPSHOT - - org.springframework.boot spring-boot-starter-web diff --git a/rest-openehr/pom.xml b/rest-openehr/pom.xml index 3e4e06a02..c9bdac112 100644 --- a/rest-openehr/pom.xml +++ b/rest-openehr/pom.xml @@ -38,12 +38,6 @@ - - ag.vitagroup.hip.cdr.authorization - cdr-xacml-authorization-lib - 1.1.1-SNAPSHOT - - org.springframework.boot spring-boot-starter-web From 4e2a0e7bc81e7114bf913bba4824120c23a0f900 Mon Sep 17 00:00:00 2001 From: Alex Vidrean Date: Wed, 5 Jul 2023 10:33:56 +0300 Subject: [PATCH 13/53] Add missing import --- .../java/org/ehrbase/rest/openehr/OpenehrTemplateController.java | 1 + 1 file changed, 1 insertion(+) diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrTemplateController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrTemplateController.java index 9136376eb..c3430e011 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrTemplateController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrTemplateController.java @@ -37,6 +37,7 @@ import java.util.function.Supplier; import org.apache.xmlbeans.XmlException; import org.ehrbase.api.annotations.TenantAware; +import org.ehrbase.api.authorization.EhrbaseAuthorization; import org.ehrbase.api.authorization.EhrbasePermission; import org.ehrbase.api.definitions.OperationalTemplateFormat; import org.ehrbase.api.exception.InternalServerException; From 92cfb5d546c349a993aaafcb5dfaff8a85a72d9f Mon Sep 17 00:00:00 2001 From: Alex Vidrean Date: Thu, 13 Jul 2023 09:55:41 +0300 Subject: [PATCH 14/53] Rename xacml url param for query controller --- .../java/org/ehrbase/rest/openehr/OpenehrQueryController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java index a45c866d4..510bc198b 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java @@ -96,7 +96,7 @@ public OpenehrQueryController(QueryService queryService) { @GetMapping(path = "/aql") @PostAuthorize("checkAbacPostQuery(@requestAwareAuditResultMapHolder.getAuditResultMap())") public ResponseEntity executeAdHocQuery( - @XacmlUrlRequestParameter("q") @RequestParam(name = "q") String query, + @XacmlUrlRequestParameter("aql_query") @RequestParam(name = "q") String query, @RequestParam(name = "offset", required = false) Integer offset, @RequestParam(name = "fetch", required = false) Integer fetch, @RequestParam(name = "query_parameters", required = false) Map queryParameters, @@ -135,7 +135,7 @@ public ResponseEntity executeAdHocQuery( @PostAuthorize("checkAbacPostQuery(@requestAwareAuditResultMapHolder.getAuditResultMap())") @SuppressWarnings("unchecked") public ResponseEntity executeAdHocQuery( - @XacmlUrlRequestParameter("q") @RequestBody Map queryRequest, + @XacmlUrlRequestParameter("aql_query") @RequestBody Map queryRequest, @RequestHeader(name = ACCEPT, required = false) String accept, @RequestHeader(name = CONTENT_TYPE) String contentType) { From e7d8b91622303d5be33b2b560d204da44445091d Mon Sep 17 00:00:00 2001 From: Alex Vidrean Date: Thu, 13 Jul 2023 12:27:13 +0300 Subject: [PATCH 15/53] Change annotations order --- .../java/org/ehrbase/rest/openehr/OpenehrQueryController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java index 510bc198b..5937f2ad5 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java @@ -89,8 +89,8 @@ public OpenehrQueryController(QueryService queryService) { * {@inheritDoc} */ @XacmlAuthorization - @ResourceId(resourceId = "OpenehrQueryController") @Action(action = "query_aql") + @ResourceId(resourceId = "OpenehrQueryController") /*@ConstrainAql(constraint = "LimitByFacilityName")*/ @Scope(scope = EhrbasePermission.EHRBASE_QUERY_SEARCH_AD_HOC) @GetMapping(path = "/aql") @@ -127,8 +127,8 @@ public ResponseEntity executeAdHocQuery( * {@inheritDoc} */ @XacmlAuthorization - @ResourceId(resourceId = "OpenehrQueryController") @Action(action = "query_aql") + @ResourceId(resourceId = "OpenehrQueryController") /*@ConstrainAql(constraint = "LimitByFacilityName")*/ @Scope(scope = EhrbasePermission.EHRBASE_QUERY_SEARCH_AD_HOC) @PostMapping(path = "/aql") From 484634af1a042f5ef75ce37ece35598d0e289ea0 Mon Sep 17 00:00:00 2001 From: Alex Vidrean Date: Thu, 13 Jul 2023 16:12:04 +0300 Subject: [PATCH 16/53] Add AccessCtrlException handling --- .../java/org/ehrbase/rest/DefaultExceptionHandler.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/DefaultExceptionHandler.java b/rest-openehr/src/main/java/org/ehrbase/rest/DefaultExceptionHandler.java index be3f86b7e..e4f309256 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/DefaultExceptionHandler.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/DefaultExceptionHandler.java @@ -20,6 +20,8 @@ import java.net.URI; import java.util.HashMap; import java.util.Map; + +import ag.vitagroup.hip.cdr.authorization.xacml.eval.AccessCtrlException; import org.ehrbase.api.exception.GeneralRequestProcessingException; import org.ehrbase.api.exception.InvalidApiParameterException; import org.ehrbase.api.exception.NotAcceptableException; @@ -79,7 +81,10 @@ public ResponseEntity handleBadRequestExceptions(Exception ex) { return handleExceptionInternal(ex, ex.getMessage(), new HttpHeaders(), HttpStatus.BAD_REQUEST); } - @ExceptionHandler(AccessDeniedException.class) + @ExceptionHandler({ + AccessDeniedException.class, + AccessCtrlException.class + }) public ResponseEntity handleObjectNotFoundException(AccessDeniedException ex) { return handleExceptionInternal(ex, ex.getMessage(), new HttpHeaders(), HttpStatus.FORBIDDEN); } From 64565edd4625942f2cb86246d45132820f2b4fd5 Mon Sep 17 00:00:00 2001 From: Alex Vidrean Date: Thu, 13 Jul 2023 16:27:10 +0300 Subject: [PATCH 17/53] Add AccessCtrlException handling --- .../src/main/java/org/ehrbase/rest/DefaultExceptionHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/DefaultExceptionHandler.java b/rest-openehr/src/main/java/org/ehrbase/rest/DefaultExceptionHandler.java index e4f309256..2dd4182bb 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/DefaultExceptionHandler.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/DefaultExceptionHandler.java @@ -85,7 +85,7 @@ public ResponseEntity handleBadRequestExceptions(Exception ex) { AccessDeniedException.class, AccessCtrlException.class }) - public ResponseEntity handleObjectNotFoundException(AccessDeniedException ex) { + public ResponseEntity handleObjectNotFoundException(Exception ex) { return handleExceptionInternal(ex, ex.getMessage(), new HttpHeaders(), HttpStatus.FORBIDDEN); } From 50d8e60830ae5688df07bdef35fd7f2d71897cd5 Mon Sep 17 00:00:00 2001 From: MBA Date: Wed, 26 Jul 2023 14:22:03 +0200 Subject: [PATCH 18/53] Tmp. commit --- .../authorization/EhrbaseAuthorization.java | 34 ------------------ .../authorization/EhrbaseAuthorizations.java | 32 ----------------- .../multi-tenant-plugin-1.2.0-SNAPSHOT.jar | Bin 18266 -> 0 bytes .../multi-tenant-plugin-1.5.1-SNAPSHOT.jar | Bin 0 -> 18889 bytes application/pom.xml | 14 ++++++++ .../java/org/ehrbase/application/EhrBase.java | 2 +- .../application-authorization.properties | 2 +- .../src/main/resources/application-xacml.yml | 24 +++++++++++++ plugin/pom.xml | 8 +++++ .../security/PluginSecurityConfiguration.java | 15 +++++--- rest-ehr-scape/pom.xml | 8 +++++ .../controller/CompositionController.java | 16 +++++---- .../ehrscape/controller/EhrController.java | 27 +++++++------- .../ehrscape/controller/QueryController.java | 6 ++-- .../controller/TemplateController.java | 16 +++++---- rest-openehr/pom.xml | 10 ++++++ .../org/ehrbase/rest/StatusController.java | 22 ++++++------ .../admin/AdminCompositionController.java | 21 +++++------ .../admin/AdminContributionController.java | 25 ++++++------- .../ehrbase/rest/admin/AdminController.java | 18 +++++----- .../rest/admin/AdminDirectoryController.java | 13 +++++-- .../rest/admin/AdminEhrController.java | 25 ++++++------- .../rest/admin/AdminTemplateController.java | 28 +++++++-------- .../openehr/OpenehrCompositionController.java | 19 +++++----- .../OpenehrContributionController.java | 15 ++++---- .../OpenehrDefinitionQueryController.java | 18 ++++++---- .../openehr/OpenehrDirectoryController.java | 18 ++++++---- .../rest/openehr/OpenehrEhrController.java | 8 ++--- .../openehr/OpenehrEhrStatusController.java | 15 ++++---- .../rest/openehr/OpenehrQueryController.java | 28 ++++++++------- .../openehr/OpenehrTemplateController.java | 26 +++++++------- ...OpenehrVersionedCompositionController.java | 23 ++++++------ .../OpenehrVersionedEhrStatusController.java | 21 ++++++----- 33 files changed, 306 insertions(+), 251 deletions(-) delete mode 100644 api/src/main/java/org/ehrbase/api/authorization/EhrbaseAuthorization.java delete mode 100644 api/src/main/java/org/ehrbase/api/authorization/EhrbaseAuthorizations.java delete mode 100644 application/plugin_dir/multi-tenant-plugin-1.2.0-SNAPSHOT.jar create mode 100644 application/plugin_dir/multi-tenant-plugin-1.5.1-SNAPSHOT.jar diff --git a/api/src/main/java/org/ehrbase/api/authorization/EhrbaseAuthorization.java b/api/src/main/java/org/ehrbase/api/authorization/EhrbaseAuthorization.java deleted file mode 100644 index b7e27105c..000000000 --- a/api/src/main/java/org/ehrbase/api/authorization/EhrbaseAuthorization.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2022 vitasystems GmbH and Hannover Medical School. - * - * This file is part of project EHRbase - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.ehrbase.api.authorization; - -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Repeatable; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - -@Inherited -@Retention(RUNTIME) -@Repeatable(EhrbaseAuthorizations.class) -@Target(ElementType.METHOD) -public @interface EhrbaseAuthorization { - EhrbasePermission permission(); -} diff --git a/api/src/main/java/org/ehrbase/api/authorization/EhrbaseAuthorizations.java b/api/src/main/java/org/ehrbase/api/authorization/EhrbaseAuthorizations.java deleted file mode 100644 index d2894cb88..000000000 --- a/api/src/main/java/org/ehrbase/api/authorization/EhrbaseAuthorizations.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2022 vitasystems GmbH and Hannover Medical School. - * - * This file is part of project EHRbase - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.ehrbase.api.authorization; - -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - -@Inherited -@Retention(RUNTIME) -@Target(ElementType.METHOD) -public @interface EhrbaseAuthorizations { - EhrbaseAuthorization[] value(); -} diff --git a/application/plugin_dir/multi-tenant-plugin-1.2.0-SNAPSHOT.jar b/application/plugin_dir/multi-tenant-plugin-1.2.0-SNAPSHOT.jar deleted file mode 100644 index 56e3b56d4ad7a1c2aaa9554d128224d18101eb28..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18266 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 literal 0 HcmV?d00001 diff --git a/application/pom.xml b/application/pom.xml index ea3586977..5985bdfe6 100644 --- a/application/pom.xml +++ b/application/pom.xml @@ -37,6 +37,20 @@ + + + org.ehrbase + ehrbase-custom-xacml-authorization + 1.1.0-SNAPSHOT + + + org.springframework.boot spring-boot-starter-web diff --git a/application/src/main/java/org/ehrbase/application/EhrBase.java b/application/src/main/java/org/ehrbase/application/EhrBase.java index dd4c7e0a9..dbc3dc56f 100644 --- a/application/src/main/java/org/ehrbase/application/EhrBase.java +++ b/application/src/main/java/org/ehrbase/application/EhrBase.java @@ -38,7 +38,7 @@ R2dbcAutoConfiguration.class, SecurityAutoConfiguration.class }) -@EnableXacmlAuthorization +//@EnableXacmlAuthorization @Import({ServiceModuleConfiguration.class, RestEHRScapeModuleConfiguration.class, RestModuleConfiguration.class}) public class EhrBase { diff --git a/application/src/main/resources/application-authorization.properties b/application/src/main/resources/application-authorization.properties index f7b6d0d77..0272faf75 100644 --- a/application/src/main/resources/application-authorization.properties +++ b/application/src/main/resources/application-authorization.properties @@ -1,5 +1,5 @@ authorization.service.rpt.token-expiry-skew=PT3M -authorization.service.disable.for.ehrbase_multi_tenant_v1=true +authorization.service.disable.for.ehrbase_multi_tenant_v1=false authorization.service.config[0].tenantId=1234-abc authorization.service.config[0].host=http://localhost:8081 diff --git a/application/src/main/resources/application-xacml.yml b/application/src/main/resources/application-xacml.yml index 31eae4c27..1dcd03314 100644 --- a/application/src/main/resources/application-xacml.yml +++ b/application/src/main/resources/application-xacml.yml @@ -1,3 +1,27 @@ +#spring: +# rabbitmq: +# virtual-host: authorization + + + + +#hip.pdp.rabbitmq.virtual-host:/ +hip.pdp.rabbitmq.host: localhost +hip.pdp.rabbitmq.username: guest +hip.pdp.rabbitmq.password: guest + + + + + + + + + + + +policyChangeQueueName: policy.changes + xacml.persistence: hibernate.dialect: org.hibernate.dialect.PostgreSQLDialect hibernate.hbm2ddl.auto: update diff --git a/plugin/pom.xml b/plugin/pom.xml index 4eb44c23d..041ca6006 100644 --- a/plugin/pom.xml +++ b/plugin/pom.xml @@ -16,6 +16,14 @@ + + + org.ehrbase + ehrbase-custom-xacml-authorization + 1.1.0-SNAPSHOT + provided + + com.nedap.healthcare.archie openehr-rm diff --git a/plugin/src/main/java/org/ehrbase/plugin/security/PluginSecurityConfiguration.java b/plugin/src/main/java/org/ehrbase/plugin/security/PluginSecurityConfiguration.java index df62f628f..7e13c4562 100644 --- a/plugin/src/main/java/org/ehrbase/plugin/security/PluginSecurityConfiguration.java +++ b/plugin/src/main/java/org/ehrbase/plugin/security/PluginSecurityConfiguration.java @@ -17,9 +17,11 @@ */ package org.ehrbase.plugin.security; +import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.List; import java.util.Objects; + import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.aspectj.lang.ProceedingJoinPoint; @@ -30,7 +32,7 @@ import org.ehrbase.api.aspect.AnnotationAspect; import org.ehrbase.api.aspect.AuthorizationAspect; import org.ehrbase.api.aspect.TenantAspect; -import org.ehrbase.api.authorization.EhrbaseAuthorization; +import org.ehrbase.plugin.security.AuthorizationInfo.AuthorizationEnabled; import org.springframework.aop.Advisor; import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; import org.springframework.aop.support.DefaultPointcutAdvisor; @@ -43,6 +45,8 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; +import ag.vitagroup.hip.cdr.authorization.annotation.XacmlAuthorization; + public class PluginSecurityConfiguration implements ApplicationContextAware { // @format:off @SuppressWarnings("rawtypes") @@ -124,15 +128,18 @@ public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() { } @Bean - @ConditionalOnBean(value = {AuthorizationAspect.class, AuthorizationInfo.AuthorizationEnabled.class}) + @ConditionalOnBean(value = {AuthorizationAspect.class, AuthorizationEnabled.class}) public Advisor authorizationAspect() { ApplicationContext parentCtx = applicationContext.getParent(); AuthorizationAspect theAspect = parentCtx.getBean(AuthorizationAspect.class); return new DefaultPointcutAdvisor( - new AnnotationMatchingPointcut(null, EhrbaseAuthorization.class, true), new AspectAdapter(theAspect) { + new AnnotationMatchingPointcut(null, XacmlAuthorization.class, true), new AspectAdapter(theAspect) { public Object invoke(MethodInvocation invocation) throws Throwable { - return getAspect().action(new ProceedingJoinPointAdapter(invocation), null); + Method method = invocation.getMethod(); + XacmlAuthorization annotation = method.getAnnotation(XacmlAuthorization.class); + + return getAspect().action(new ProceedingJoinPointAdapter(invocation), List.of(annotation)); } }); } diff --git a/rest-ehr-scape/pom.xml b/rest-ehr-scape/pom.xml index 66bec62e6..4562197dd 100644 --- a/rest-ehr-scape/pom.xml +++ b/rest-ehr-scape/pom.xml @@ -38,6 +38,14 @@ + + + org.ehrbase + ehrbase-custom-xacml-authorization + 1.1.0-SNAPSHOT + provided + + org.springframework.boot spring-boot-starter-web diff --git a/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/CompositionController.java b/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/CompositionController.java index f5fe3c6e8..1b8dc9288 100644 --- a/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/CompositionController.java +++ b/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/CompositionController.java @@ -19,15 +19,13 @@ import static org.ehrbase.rest.ehrscape.controller.BaseController.API_ECIS_CONTEXT_PATH_WITH_VERSION; -import com.nedap.archie.rm.support.identification.ObjectVersionId; import java.net.URI; import java.util.Objects; import java.util.Optional; import java.util.UUID; + import org.apache.commons.lang3.StringUtils; import org.ehrbase.api.annotations.TenantAware; -import org.ehrbase.api.authorization.EhrbaseAuthorization; -import org.ehrbase.api.authorization.EhrbasePermission; import org.ehrbase.api.exception.InternalServerException; import org.ehrbase.api.exception.InvalidApiParameterException; import org.ehrbase.api.service.CompositionService; @@ -52,6 +50,10 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import com.nedap.archie.rm.support.identification.ObjectVersionId; + +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; + @TenantAware @RestController @RequestMapping( @@ -65,7 +67,7 @@ public CompositionController(CompositionService compositionService) { this.compositionService = Objects.requireNonNull(compositionService); } - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_COMPOSITION_CREATE) + @Scope(scope = "ehrbase:composition:create") @PostMapping public ResponseEntity createComposition( @RequestParam(value = "format", defaultValue = "XML") CompositionFormat format, @@ -97,7 +99,7 @@ public ResponseEntity createComposition( .body(responseData); } - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_COMPOSITION_READ) + @Scope(scope = "ehrbase:composition:read") @GetMapping(path = "/{uid}") public ResponseEntity getComposition( @PathVariable("uid") String compositionUid, @@ -136,7 +138,7 @@ public ResponseEntity getComposition( } } - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_COMPOSITION_UPDATE) + @Scope(scope = "ehrbase:composition:update") @PutMapping(path = "/{uid}") public ResponseEntity update( @PathVariable("uid") String compositionUid, @@ -170,7 +172,7 @@ public ResponseEntity update( return ResponseEntity.ok(responseData); } - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_COMPOSITION_DELETE) + @Scope(scope = "ehrbase:composition:delete") @DeleteMapping(path = "/{uid}") public ResponseEntity delete(@PathVariable("uid") String compositionUid) { diff --git a/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/EhrController.java b/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/EhrController.java index b2b6f7596..69744e276 100644 --- a/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/EhrController.java +++ b/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/EhrController.java @@ -19,21 +19,14 @@ import static org.ehrbase.rest.ehrscape.controller.BaseController.API_ECIS_CONTEXT_PATH_WITH_VERSION; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.nedap.archie.rm.datavalues.DvText; -import com.nedap.archie.rm.ehr.EhrStatus; -import com.nedap.archie.rm.generic.PartySelf; -import com.nedap.archie.rm.support.identification.HierObjectId; -import com.nedap.archie.rm.support.identification.PartyRef; import java.net.URI; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.UUID; + import org.apache.commons.lang3.StringUtils; import org.ehrbase.api.annotations.TenantAware; -import org.ehrbase.api.authorization.EhrbaseAuthorization; import org.ehrbase.api.authorization.EhrbasePermission; import org.ehrbase.api.exception.GeneralRequestProcessingException; import org.ehrbase.api.exception.InvalidApiParameterException; @@ -58,6 +51,16 @@ import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.nedap.archie.rm.datavalues.DvText; +import com.nedap.archie.rm.ehr.EhrStatus; +import com.nedap.archie.rm.generic.PartySelf; +import com.nedap.archie.rm.support.identification.HierObjectId; +import com.nedap.archie.rm.support.identification.PartyRef; + +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; + /** * Controller for /ehr resource of EhrScape REST API * @@ -79,7 +82,7 @@ public EhrController(EhrService ehrService) { this.ehrService = Objects.requireNonNull(ehrService); } - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_EHR_CREATE) + @Scope(scope = "ehrbase:ehr:create") @PostMapping @ResponseStatus(value = HttpStatus.CREATED) // overwrites default 200, fixes the wrong listing of 200 in swagger-ui (EHR-56) @@ -115,7 +118,7 @@ public ResponseEntity createEhr( .orElse(ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build()); } - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_EHR_READ) + @Scope(scope = "ehrbase:ehr:read") @GetMapping public ResponseEntity getEhr( @RequestParam(value = "subjectId") String subjectId, @@ -128,7 +131,7 @@ public ResponseEntity getEhr( .orElse(ResponseEntity.noContent().build()); } - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_EHR_READ) + @Scope(scope = "ehrbase:ehr:read") @GetMapping(path = "/{uuid}") public ResponseEntity getEhr( @PathVariable("uuid") UUID ehrId, @@ -140,7 +143,7 @@ public ResponseEntity getEhr( .orElse(ResponseEntity.notFound().build()); } - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_EHR_UPDATE_STATUS) + @Scope(scope = "ehrbase:ehr:update_status") @PutMapping(path = "/{uuid}/status") public ResponseEntity updateStatus( @PathVariable("uuid") UUID ehrId, diff --git a/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/QueryController.java b/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/QueryController.java index 45cd2da4e..b853b7820 100644 --- a/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/QueryController.java +++ b/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/QueryController.java @@ -21,8 +21,8 @@ import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; + import org.ehrbase.api.annotations.TenantAware; -import org.ehrbase.api.authorization.EhrbaseAuthorization; import org.ehrbase.api.authorization.EhrbasePermission; import org.ehrbase.api.exception.InvalidApiParameterException; import org.ehrbase.api.service.QueryService; @@ -37,6 +37,8 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; + @TenantAware @RestController @RequestMapping( @@ -51,7 +53,7 @@ public QueryController(QueryService queryService) { this.queryService = Objects.requireNonNull(queryService); } - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_QUERY_SEARCH_AD_HOC) + @Scope(scope = "ehrbase:query:search_ad_hoc") @PostMapping public ResponseEntity query( @RequestParam(value = "explain", defaultValue = "false") Boolean explain, @RequestBody String content) { diff --git a/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/TemplateController.java b/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/TemplateController.java index 99d766d6b..8f09d66ef 100644 --- a/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/TemplateController.java +++ b/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/TemplateController.java @@ -20,15 +20,13 @@ import static org.ehrbase.rest.ehrscape.controller.BaseController.API_ECIS_CONTEXT_PATH_WITH_VERSION; import static org.ehrbase.rest.ehrscape.controller.BaseController.TEMPLATE; -import com.nedap.archie.rm.composition.Composition; import java.io.ByteArrayInputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.Objects; + import org.apache.xmlbeans.XmlException; import org.ehrbase.api.annotations.TenantAware; -import org.ehrbase.api.authorization.EhrbaseAuthorization; -import org.ehrbase.api.authorization.EhrbasePermission; import org.ehrbase.api.exception.InvalidApiParameterException; import org.ehrbase.api.service.CompositionService; import org.ehrbase.api.service.TemplateService; @@ -53,6 +51,10 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import com.nedap.archie.rm.composition.Composition; + +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; + @TenantAware @RestController @RequestMapping( @@ -69,7 +71,7 @@ public TemplateController(TemplateService templateService, CompositionService co this.compositionService = Objects.requireNonNull(compositionService); } - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_TEMPLATE_READ) + @Scope(scope = "ehrbase:template:read") @GetMapping() public ResponseEntity getTemplate() { TemplatesResponseData responseData = new TemplatesResponseData(); @@ -78,7 +80,7 @@ public ResponseEntity getTemplate() { return ResponseEntity.ok(responseData); } - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_TEMPLATE_CREATE) + @Scope(scope = "ehrbase:template:create") @PostMapping() public ResponseEntity createTemplate(@RequestBody() String content) { @@ -97,7 +99,7 @@ public ResponseEntity createTemplate(@RequestBody() Strin return ResponseEntity.ok(responseData); } - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_TEMPLATE_EXAMPLE) + @Scope(scope = "ehrbase:template:example") @GetMapping(path = "/{templateId}/example") public ResponseEntity getTemplateExample( @PathVariable(value = "templateId") String templateId, @@ -118,7 +120,7 @@ public ResponseEntity getTemplateExample( return ResponseEntity.ok().contentType(contentType).body(serialized.getValue()); } - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_TEMPLATE_READ) + @Scope(scope = "ehrbase:template:read") @GetMapping(path = "/{templateId}") public ResponseEntity getTemplate(@PathVariable(value = "templateId") String templateId) { TemplateResponseData responseData = new TemplateResponseData(); diff --git a/rest-openehr/pom.xml b/rest-openehr/pom.xml index c9bdac112..6f97e473a 100644 --- a/rest-openehr/pom.xml +++ b/rest-openehr/pom.xml @@ -38,6 +38,16 @@ + + + + org.ehrbase + ehrbase-custom-xacml-authorization + 1.1.0-SNAPSHOT + provided + + + org.springframework.boot spring-boot-starter-web diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/StatusController.java b/rest-openehr/src/main/java/org/ehrbase/rest/StatusController.java index f8bcfbc5c..9105283ff 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/StatusController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/StatusController.java @@ -17,16 +17,8 @@ */ package org.ehrbase.rest; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.headers.Header; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.responses.ApiResponses; -import io.swagger.v3.oas.annotations.tags.Tag; import java.util.Objects; -import org.ehrbase.api.authorization.EhrbaseAuthorization; + import org.ehrbase.api.authorization.EhrbasePermission; import org.ehrbase.api.service.StatusService; import org.ehrbase.openehr.sdk.response.dto.StatusResponseData; @@ -41,6 +33,16 @@ import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.headers.Header; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; + /** * API endpoint to get status of EHRbase and version information on used dependencies as archie or openEHR_sdk as well * as the current used JVM version or target PostgreSQL server version. @@ -59,7 +61,7 @@ public StatusController(StatusService statusService) { this.statusService = Objects.requireNonNull(statusService); } - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_SYSTEM_STATUS) + @Scope(scope = "ehrbase:system:read") @GetMapping(path = "/status") @Operation(summary = "Get status information on running EHRbase server instance") @ApiResponses( diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminCompositionController.java b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminCompositionController.java index 46001e33d..ca26e35f6 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminCompositionController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminCompositionController.java @@ -17,18 +17,11 @@ */ package org.ehrbase.rest.admin; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.headers.Header; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.responses.ApiResponses; -import io.swagger.v3.oas.annotations.tags.Tag; import java.util.Objects; import java.util.UUID; + import org.ehrbase.api.annotations.TenantAware; import org.ehrbase.api.audit.msg.AuditMsgBuilder; -import org.ehrbase.api.authorization.EhrbaseAuthorization; -import org.ehrbase.api.authorization.EhrbasePermission; import org.ehrbase.api.exception.ObjectNotFoundException; import org.ehrbase.api.service.CompositionService; import org.ehrbase.api.service.EhrService; @@ -44,6 +37,14 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.util.UriComponentsBuilder; +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.headers.Header; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; + /** * Admin API controller for Composition related data. Provides endpoint to remove compositions physically from database. */ @@ -65,8 +66,8 @@ public AdminCompositionController(EhrService ehrService, CompositionService comp this.compositionService = Objects.requireNonNull(compositionService); } - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_ADMIN_ACCESS) - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_COMPOSITION_DELETE) + @Scope(scope = "ehrbase:admin:access") + @Scope(scope = "ehrbase:composition:delete") @DeleteMapping(path = "/{ehr_id}/composition/{composition_id}") @ApiResponses( value = { diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminContributionController.java b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminContributionController.java index 474692931..00a994c9b 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminContributionController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminContributionController.java @@ -20,17 +20,10 @@ import static org.apache.commons.lang3.StringUtils.EMPTY; import static org.springframework.web.util.UriComponentsBuilder.fromPath; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.headers.Header; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.responses.ApiResponses; -import io.swagger.v3.oas.annotations.tags.Tag; import java.util.UUID; + import org.ehrbase.api.annotations.TenantAware; import org.ehrbase.api.audit.msg.AuditMsgBuilder; -import org.ehrbase.api.authorization.EhrbaseAuthorization; -import org.ehrbase.api.authorization.EhrbasePermission; import org.ehrbase.api.exception.ObjectNotFoundException; import org.ehrbase.api.service.ContributionService; import org.ehrbase.api.service.EhrService; @@ -47,6 +40,14 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.headers.Header; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; + /** * Admin API controller for Contribution related data. Provides endpoints to update and remove Contributions in * database physically. @@ -69,8 +70,8 @@ public AdminContributionController(EhrService ehrService, ContributionService co this.contributionService = contributionService; } - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_ADMIN_ACCESS) - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_CONTRIBUTION_UPDATE) + @Scope(scope = "ehrbase:admin:access") + @Scope(scope = "ehrbase:contribution:update") @PutMapping( path = "/{ehr_id}/contribution/{contribution_id}", consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE}) @@ -116,8 +117,8 @@ public ResponseEntity updateContribution( return ResponseEntity.ok().body(new AdminUpdateResponseData(0)); } - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_ADMIN_ACCESS) - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_CONTRIBUTION_DELETE) + @Scope(scope = "ehrbase:admin:access") + @Scope(scope = "ehrbase:contribution:delete") @DeleteMapping(path = "/{ehr_id}/contribution/{contribution_id}") @ApiResponses( value = { diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminController.java b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminController.java index 48f6ddc61..d2197a613 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminController.java @@ -17,14 +17,7 @@ */ package org.ehrbase.rest.admin; -import io.swagger.v3.oas.annotations.headers.Header; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.responses.ApiResponses; -import io.swagger.v3.oas.annotations.tags.Tag; import org.ehrbase.api.annotations.TenantAware; -import org.ehrbase.api.authorization.EhrbaseAuthorization; -import org.ehrbase.api.authorization.EhrbasePermission; import org.ehrbase.openehr.sdk.response.dto.admin.AdminStatusResponseData; import org.ehrbase.rest.BaseController; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -34,6 +27,13 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; +import io.swagger.v3.oas.annotations.headers.Header; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; + @TenantAware @Tag(name = "Admin - Heartbeat") @ConditionalOnProperty(prefix = "admin-api", name = "active") @@ -43,8 +43,8 @@ produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE}) public class AdminController extends BaseController { - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_ADMIN_ACCESS) - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_SYSTEM_STATUS) + @Scope(scope = "ehrbase:admin:access") + @Scope(scope = "ehrbase:system:read") @GetMapping(path = "/status") @ApiResponses( value = { diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminDirectoryController.java b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminDirectoryController.java index 3bd4f1509..ab56e7bd4 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminDirectoryController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminDirectoryController.java @@ -26,6 +26,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; import java.util.UUID; + import org.ehrbase.api.annotations.TenantAware; import org.ehrbase.api.audit.msg.AuditMsgBuilder; import org.ehrbase.api.authorization.EhrbaseAuthorization; @@ -42,6 +43,14 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.headers.Header; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; + /** * Admin API controller for directories. Provides endpoint to remove complete directory trees from database physically. */ @@ -62,8 +71,8 @@ public AdminDirectoryController(DirectoryService directoryService) { this.directoryService = directoryService; } - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_ADMIN_ACCESS) - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_DIRECTORY_DELETE) + @Scope(scope = "ehrbase:admin:access") + @Scope(scope = "ehrbase:directory:delete") @DeleteMapping(path = "/{ehr_id}/directory/{directory_id}") @ApiResponses( value = { diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminEhrController.java b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminEhrController.java index fe17c03cc..c27a4188d 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminEhrController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminEhrController.java @@ -17,20 +17,13 @@ */ package org.ehrbase.rest.admin; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.headers.Header; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.responses.ApiResponses; -import io.swagger.v3.oas.annotations.tags.Tag; import java.util.Arrays; import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; + import org.ehrbase.api.annotations.TenantAware; import org.ehrbase.api.audit.msg.AuditMsgBuilder; -import org.ehrbase.api.authorization.EhrbaseAuthorization; -import org.ehrbase.api.authorization.EhrbasePermission; import org.ehrbase.api.exception.ObjectNotFoundException; import org.ehrbase.api.service.EhrService; import org.ehrbase.openehr.sdk.response.dto.admin.AdminDeleteResponseData; @@ -48,6 +41,14 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.headers.Header; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; + /** * Admin API controller for EHR related endpoints. Provides methods to update and delete EHRs physically in the DB. */ @@ -67,8 +68,8 @@ public AdminEhrController(EhrService ehrService) { this.ehrService = ehrService; } - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_ADMIN_ACCESS) - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_EHR_UPDATE) + @Scope(scope = "ehrbase:admin:access") + @Scope(scope = "ehrbase:ehr:update") @PutMapping( path = "/{ehr_id}", consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE}) @@ -112,8 +113,8 @@ public ResponseEntity updateEhr( return ResponseEntity.ok().body(new AdminUpdateResponseData(0)); } - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_ADMIN_ACCESS) - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_EHR_DELETE) + @Scope(scope = "ehrbase:admin:access") + @Scope(scope = "ehrbase:ehr:delete") @DeleteMapping(path = "/{ehr_id}") @ApiResponses( value = { diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminTemplateController.java b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminTemplateController.java index 9c7c75a7c..a510b9363 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminTemplateController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminTemplateController.java @@ -17,15 +17,7 @@ */ package org.ehrbase.rest.admin; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.headers.Header; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.responses.ApiResponses; -import io.swagger.v3.oas.annotations.tags.Tag; import org.ehrbase.api.annotations.TenantAware; -import org.ehrbase.api.authorization.EhrbaseAuthorization; -import org.ehrbase.api.authorization.EhrbasePermission; import org.ehrbase.api.service.TemplateService; import org.ehrbase.openehr.sdk.response.dto.admin.AdminDeleteResponseData; import org.ehrbase.openehr.sdk.response.dto.admin.AdminStatusResponseData; @@ -44,6 +36,14 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.headers.Header; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; + /** * Admin API controller for Templates. Provides endpoints to update (replace) and delete templates. */ @@ -66,8 +66,8 @@ public class AdminTemplateController extends BaseController { @Autowired AdminApiConfiguration adminApiConfiguration; - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_ADMIN_ACCESS) - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_TEMPLATE_UPDATE) + @Scope(scope = "ehrbase:admin:access") + @Scope(scope = "ehrbase:template:update") @PutMapping( path = "/{template_id}", consumes = {MediaType.APPLICATION_XML_VALUE}, @@ -111,8 +111,8 @@ public ResponseEntity updateTemplate( return ResponseEntity.ok().headers(headers).body(updatedTemplate); } - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_ADMIN_ACCESS) - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_TEMPLATE_DELETE) + @Scope(scope = "ehrbase:admin:access") + @Scope(scope = "ehrbase:template:delete") @DeleteMapping(path = "/{template_id}") @ApiResponses( value = { @@ -136,8 +136,8 @@ public ResponseEntity deleteTemplate( return ResponseEntity.ok().body(new AdminDeleteResponseData(deleted)); } - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_ADMIN_ACCESS) - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_TEMPLATE_DELETE) + @Scope(scope = "ehrbase:admin:access") + @Scope(scope = "ehrbase:template:delete") @DeleteMapping(path = "/all") @ApiResponses( value = { diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrCompositionController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrCompositionController.java index 16eccf126..a7f6b6996 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrCompositionController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrCompositionController.java @@ -20,9 +20,6 @@ import static org.apache.commons.lang3.StringUtils.unwrap; import static org.springframework.web.util.UriComponentsBuilder.fromPath; -import com.nedap.archie.rm.composition.Composition; -import com.nedap.archie.rm.support.identification.ObjectId; -import com.nedap.archie.rm.support.identification.ObjectVersionId; import java.net.URI; import java.time.LocalDateTime; import java.time.OffsetDateTime; @@ -34,9 +31,9 @@ import java.util.Optional; import java.util.UUID; import java.util.function.Supplier; + import org.ehrbase.api.annotations.TenantAware; import org.ehrbase.api.audit.msg.AuditMsgBuilder; -import org.ehrbase.api.authorization.EhrbaseAuthorization; import org.ehrbase.api.authorization.EhrbasePermission; import org.ehrbase.api.exception.InternalServerException; import org.ehrbase.api.exception.ObjectNotFoundException; @@ -69,6 +66,12 @@ import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; +import com.nedap.archie.rm.composition.Composition; +import com.nedap.archie.rm.support.identification.ObjectId; +import com.nedap.archie.rm.support.identification.ObjectVersionId; + +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; + /** * Controller for /composition resource as part of the EHR sub-API of the openEHR REST API * @@ -90,7 +93,7 @@ public OpenehrCompositionController(CompositionService compositionService) { this.compositionService = Objects.requireNonNull(compositionService); } - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_COMPOSITION_CREATE) + @Scope(scope = "ehrbase:composition:create") @PostMapping( value = "/{ehr_id}/composition", consumes = {"application/xml", "application/json"}) @@ -156,7 +159,7 @@ public ResponseEntity createComposition( .orElse(ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build()); } - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_COMPOSITION_UPDATE) + @Scope(scope = "ehrbase:composition:create") @PutMapping("/{ehr_id}/composition/{versioned_object_uid}") // checkAbacPre /-Post attributes (type, subject, payload, content type) @PreAuthorize("checkAbacPre(@openehrCompositionController.COMPOSITION, " @@ -252,7 +255,7 @@ public ResponseEntity updateComposition( .orElse(ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build()); } - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_COMPOSITION_DELETE) + @Scope(scope = "ehrbase:composition:delete") @DeleteMapping("/{ehr_id}/composition/{preceding_version_uid}") // checkAbacPre /-Post attributes (type, subject, payload, content type) @PreAuthorize("checkAbacPre(@openehrCompositionController.COMPOSITION, " @@ -331,7 +334,7 @@ public ResponseEntity deleteComposition( * because of the overlapping paths. Both mappings are specified to behave almost the same, so * this solution works in this case. */ - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_COMPOSITION_READ) + @Scope(scope = "ehrbase:composition:read") @GetMapping("/{ehr_id}/composition/{versioned_object_uid}") // checkAbacPre /-Post attributes (type, subject, payload, content type) @PostAuthorize("checkAbacPost(@openehrCompositionController.COMPOSITION, " diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrContributionController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrContributionController.java index 51f40c252..cddb3b7a9 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrContributionController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrContributionController.java @@ -20,9 +20,6 @@ import static org.apache.commons.lang3.StringUtils.EMPTY; import static org.springframework.web.util.UriComponentsBuilder.fromPath; -import com.nedap.archie.rm.support.identification.HierObjectId; -import com.nedap.archie.rm.support.identification.ObjectRef; -import com.nedap.archie.rm.support.identification.ObjectVersionId; import java.net.URI; import java.util.Arrays; import java.util.LinkedList; @@ -31,9 +28,9 @@ import java.util.Optional; import java.util.UUID; import java.util.function.Supplier; + import org.ehrbase.api.annotations.TenantAware; import org.ehrbase.api.audit.msg.AuditMsgBuilder; -import org.ehrbase.api.authorization.EhrbaseAuthorization; import org.ehrbase.api.authorization.EhrbasePermission; import org.ehrbase.api.exception.NotAcceptableException; import org.ehrbase.api.service.ContributionService; @@ -58,6 +55,12 @@ import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; +import com.nedap.archie.rm.support.identification.HierObjectId; +import com.nedap.archie.rm.support.identification.ObjectRef; +import com.nedap.archie.rm.support.identification.ObjectVersionId; + +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; + @TenantAware @RestController @RequestMapping( @@ -72,7 +75,7 @@ public OpenehrContributionController(ContributionService contributionService) { this.contributionService = Objects.requireNonNull(contributionService); } - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_CONTRIBUTION_CREATE) + @Scope(scope = "ehrbase:contribution:create") @PostMapping( value = "/{ehr_id}/contribution", consumes = {"application/xml", "application/json"}) @@ -133,7 +136,7 @@ public ResponseEntity createContribution( .orElse(ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build()); } - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_CONTRIBUTION_READ) + @Scope(scope = "ehrbase:contribution:read") @GetMapping(value = "/{ehr_id}/contribution/{contribution_uid}") @Override public ResponseEntity getContribution( diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDefinitionQueryController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDefinitionQueryController.java index 25704fe50..0500ceb5d 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDefinitionQueryController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDefinitionQueryController.java @@ -21,11 +21,9 @@ import static org.springframework.http.MediaType.*; import static org.springframework.web.util.UriComponentsBuilder.fromPath; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import java.util.Objects; import java.util.Optional; + import org.ehrbase.api.annotations.TenantAware; import org.ehrbase.api.audit.msg.AuditMsgBuilder; import org.ehrbase.api.authorization.EhrbaseAuthorization; @@ -58,6 +56,12 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; + @TenantAware @RestController @RequestMapping( @@ -88,7 +92,7 @@ public OpenehrDefinitionQueryController(QueryService queryService) { */ @Override @GetMapping(value = {"/{qualified_query_name}", ""}) - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_QUERY_READ) + @Scope(scope = "ehrbase:query:read") public ResponseEntity getStoredQueryList( @RequestHeader(value = ACCEPT, required = false) String accept, @PathVariable(value = "qualified_query_name", required = false) String qualifiedQueryName) { @@ -105,7 +109,7 @@ public ResponseEntity getStoredQueryList( @Override @GetMapping(value = {"/{qualified_query_name}/{version}"}) - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_QUERY_READ) + @Scope(scope = "ehrbase:query:read") public ResponseEntity getStoredQueryVersion( @RequestHeader(value = ACCEPT, required = false) String accept, @PathVariable(value = "qualified_query_name") String qualifiedQueryName, @@ -124,7 +128,7 @@ public ResponseEntity getStoredQueryVersion( } @Override - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_QUERY_CREATE) + @Scope(scope = "ehrbase:query:create") @PutMapping( value = {"/{qualified_query_name}/{version}", "/{qualified_query_name}"}, consumes = {TEXT_PLAIN_VALUE, APPLICATION_JSON_VALUE}, @@ -190,7 +194,7 @@ public ResponseEntity putStoredQuery( @Override @DeleteMapping(value = {"/{qualified_query_name}/{version}"}) - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_QUERY_DELETE) + @Scope(scope = "ehrbase:query:delete") public ResponseEntity deleteStoredQuery( @RequestHeader(value = ACCEPT, required = false) String accept, @PathVariable(value = "qualified_query_name") String qualifiedQueryName, diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDirectoryController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDirectoryController.java index f74aa9995..a3683aab3 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDirectoryController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDirectoryController.java @@ -20,13 +20,12 @@ import static org.apache.commons.lang3.StringUtils.unwrap; import static org.springframework.web.util.UriComponentsBuilder.fromPath; -import com.nedap.archie.rm.directory.Folder; -import com.nedap.archie.rm.support.identification.ObjectVersionId; import java.nio.file.InvalidPathException; import java.nio.file.Paths; import java.time.OffsetDateTime; import java.util.Optional; import java.util.UUID; + import org.apache.commons.lang3.StringUtils; import org.ehrbase.api.annotations.TenantAware; import org.ehrbase.api.audit.msg.AuditMsgBuilder; @@ -55,6 +54,11 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import com.nedap.archie.rm.directory.Folder; +import com.nedap.archie.rm.support.identification.ObjectVersionId; + +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; + /** * Controller for openEHR /directory endpoints * @@ -77,7 +81,7 @@ public OpenehrDirectoryController(DirectoryService directoryService) { /** * {@inheritDoc} */ - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_DIRECTORY_CREATE) + @Scope(scope = "ehrbase:directory:create") @Override @PostMapping(path = "/{ehr_id}/directory") public ResponseEntity createDirectory( @@ -97,7 +101,7 @@ public ResponseEntity createDirectory( /** * {@inheritDoc} */ - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_DIRECTORY_UPDATE) + @Scope(scope = "ehrbase:directory:update") @Override @PutMapping(path = "/{ehr_id}/directory") public ResponseEntity updateDirectory( @@ -121,7 +125,7 @@ public ResponseEntity updateDirectory( /** * {@inheritDoc} */ - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_DIRECTORY_DELETE) + @Scope(scope = "ehrbase:directory:delete") @Override @DeleteMapping(path = "/{ehr_id}/directory") public ResponseEntity deleteDirectory( @@ -142,7 +146,7 @@ public ResponseEntity deleteDirectory( /** * {@inheritDoc} */ - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_DIRECTORY_READ) + @Scope(scope = "ehrbase:directory:read") @Override @GetMapping(path = "/{ehr_id}/directory/{version_uid}") public ResponseEntity getFolderInDirectory( @@ -183,7 +187,7 @@ private void validateVersionUid(ObjectVersionId versionUid) { } } - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_DIRECTORY_READ) + @Scope(scope = "ehrbase:directory:read") @Override @GetMapping(path = "/{ehr_id}/directory") public ResponseEntity getFolderInDirectoryVersionAtTime( diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrController.java index 5e5f26100..52a249f66 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrController.java @@ -79,7 +79,7 @@ public OpenehrEhrController(EhrService ehrService) { this.ehrService = Objects.requireNonNull(ehrService); } - @Scope(scope = EhrbasePermission.EHRBASE_EHR_CREATE) + @Scope(scope = "ehrbase:ehr:create") @XacmlAuthorization @Action(action = "method:call:createEhr") @ResourceId(resourceId = "OpenehrEhrController") @@ -104,7 +104,7 @@ public ResponseEntity createEhr( return internalPostEhrProcessing(accept, prefer, ehrId); } - @Scope(scope = EhrbasePermission.EHRBASE_EHR_CREATE) + @Scope(scope = "ehrbase:ehr:create") @XacmlAuthorization @Action(action = "method:call:createEhrWithId") @ResourceId(resourceId = "OpenehrEhrController") @@ -181,7 +181,7 @@ private void createAuditLogsMsgBuilder(UUID resultEhrId) { /** * Returns EHR by ID */ - @Scope(scope = EhrbasePermission.EHRBASE_EHR_READ) + @Scope(scope = "ehrbase:ehr:read") @GetMapping(path = "/{ehr_id}") @PreAuthorize("checkAbacPre(@openehrEhrController.EHR, @ehrService.getSubjectExtRef(#ehrIdString))") public ResponseEntity retrieveEhrById( @@ -200,7 +200,7 @@ public ResponseEntity retrieveEhrById( /** * Returns EHR by subject (id and namespace) */ - @Scope(scope = EhrbasePermission.EHRBASE_EHR_READ) + @Scope(scope = "ehrbase:ehr:read") @GetMapping(params = {"subject_id", "subject_namespace"}) @PreAuthorize("checkAbacPre(@openehrEhrController.EHR, #subjectId)") public ResponseEntity retrieveEhrBySubject( diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrStatusController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrStatusController.java index ca71b2978..02225dc66 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrStatusController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrStatusController.java @@ -19,8 +19,6 @@ import static org.apache.commons.lang3.StringUtils.unwrap; -import com.nedap.archie.rm.changecontrol.OriginalVersion; -import com.nedap.archie.rm.ehr.EhrStatus; import java.net.URI; import java.sql.Timestamp; import java.time.OffsetDateTime; @@ -29,9 +27,9 @@ import java.util.Optional; import java.util.UUID; import java.util.function.Supplier; + import org.ehrbase.api.annotations.TenantAware; import org.ehrbase.api.audit.msg.AuditMsgBuilder; -import org.ehrbase.api.authorization.EhrbaseAuthorization; import org.ehrbase.api.authorization.EhrbasePermission; import org.ehrbase.api.exception.InternalServerException; import org.ehrbase.api.exception.InvalidApiParameterException; @@ -56,6 +54,11 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import com.nedap.archie.rm.changecontrol.OriginalVersion; +import com.nedap.archie.rm.ehr.EhrStatus; + +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; + /** * Controller for /ehr/{ehrId}/ehr_status resource of openEHR REST API * @@ -79,7 +82,7 @@ public OpenehrEhrStatusController(EhrService ehrService) { */ @Override @GetMapping - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_EHR_READ_STATUS) + @Scope(scope = "ehrbase:ehr:read_status") @PreAuthorize("checkAbacPre(@openehrEhrStatusController.EHR_STATUS, @ehrService.getSubjectExtRef(#ehrId))") public ResponseEntity getEhrStatusVersionByTime( @PathVariable(name = "ehr_id") UUID ehrId, @@ -109,7 +112,7 @@ public ResponseEntity getEhrStatusVersionByTime( */ @Override @GetMapping(path = "/{version_uid}") - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_EHR_READ_STATUS) + @Scope(scope = "ehrbase:ehr:read_status") @PreAuthorize("checkAbacPre(@openehrEhrStatusController.EHR_STATUS, @ehrService.getSubjectExtRef(#ehrId))") public ResponseEntity getEhrStatusByVersionId( @PathVariable(name = "ehr_id") UUID ehrId, @@ -137,7 +140,7 @@ public ResponseEntity getEhrStatusByVersionId( */ @Override @PutMapping - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_EHR_UPDATE_STATUS) + @Scope(scope = "ehrbase:ehr:update_status") @PreAuthorize("checkAbacPre(@openehrEhrStatusController.EHR_STATUS, @ehrService.getSubjectExtRef(#ehrId))") public ResponseEntity updateEhrStatus( @PathVariable("ehr_id") UUID ehrId, diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java index 5937f2ad5..65687604f 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java @@ -17,21 +17,15 @@ */ package org.ehrbase.rest.openehr; -import ag.vitagroup.hip.cdr.authorization.annotation.Action; -import ag.vitagroup.hip.cdr.authorization.annotation.ResourceId; -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; -import ag.vitagroup.hip.cdr.authorization.annotation.TenantPolicyLookup; -import ag.vitagroup.hip.cdr.authorization.annotation.XacmlAuthorization; -import ag.vitagroup.hip.cdr.authorization.annotation.XacmlUrlRequestParameter; import java.text.MessageFormat; import java.util.HashMap; import java.util.Map; import java.util.Optional; import java.util.Set; + import org.apache.commons.collections4.MapUtils; import org.ehrbase.api.annotations.TenantAware; import org.ehrbase.api.audit.msg.AuditMsgBuilder; -import org.ehrbase.api.authorization.EhrbasePermission; import org.ehrbase.api.exception.InvalidApiParameterException; import org.ehrbase.api.exception.ObjectNotFoundException; import org.ehrbase.api.service.QueryService; @@ -57,6 +51,14 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import ag.vitagroup.hip.cdr.authorization.annotation.Action; +import ag.vitagroup.hip.cdr.authorization.annotation.ResourceId; +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; +import ag.vitagroup.hip.cdr.authorization.annotation.TenantPolicyLookup; +import ag.vitagroup.hip.cdr.authorization.annotation.XacmlAuthorization; +import ag.vitagroup.hip.cdr.authorization.annotation.XacmlAuthorization.Version; +import ag.vitagroup.hip.cdr.authorization.annotation.XacmlUrlRequestParameter; + /** * Controller for openEHR REST API QUERY resource. * @@ -88,11 +90,11 @@ public OpenehrQueryController(QueryService queryService) { /** * {@inheritDoc} */ - @XacmlAuthorization + @XacmlAuthorization(version = Version.V2) @Action(action = "query_aql") @ResourceId(resourceId = "OpenehrQueryController") /*@ConstrainAql(constraint = "LimitByFacilityName")*/ - @Scope(scope = EhrbasePermission.EHRBASE_QUERY_SEARCH_AD_HOC) + @Scope(scope = "ehrbase:query:search_ad_hoc") @GetMapping(path = "/aql") @PostAuthorize("checkAbacPostQuery(@requestAwareAuditResultMapHolder.getAuditResultMap())") public ResponseEntity executeAdHocQuery( @@ -126,11 +128,11 @@ public ResponseEntity executeAdHocQuery( /** * {@inheritDoc} */ - @XacmlAuthorization + @XacmlAuthorization(version = Version.V2) @Action(action = "query_aql") @ResourceId(resourceId = "OpenehrQueryController") /*@ConstrainAql(constraint = "LimitByFacilityName")*/ - @Scope(scope = EhrbasePermission.EHRBASE_QUERY_SEARCH_AD_HOC) + @Scope(scope = "ehrbase:query:search_ad_hoc") @PostMapping(path = "/aql") @PostAuthorize("checkAbacPostQuery(@requestAwareAuditResultMapHolder.getAuditResultMap())") @SuppressWarnings("unchecked") @@ -159,7 +161,7 @@ public ResponseEntity executeAdHocQuery( /** * {@inheritDoc} */ - @Scope(scope = EhrbasePermission.EHRBASE_QUERY_SEARCH) + @Scope(scope = "ehrbase:query:search") @GetMapping(path = {"/{qualified_query_name}", "/{qualified_query_name}/{version}"}) @PostAuthorize("checkAbacPostQuery(@requestAwareAuditResultMapHolder.getAuditResultMap())") public ResponseEntity executeStoredQuery( @@ -206,7 +208,7 @@ public ResponseEntity executeStoredQuery( /** * {@inheritDoc} */ - @Scope(scope = EhrbasePermission.EHRBASE_QUERY_SEARCH) + @Scope(scope = "ehrbase:query:search") @PostMapping(path = {"/{qualified_query_name}", "/{qualified_query_name}/{version}"}) @PostAuthorize("checkAbacPostQuery(@requestAwareAuditResultMapHolder.getAuditResultMap())") @SuppressWarnings("unchecked") diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrTemplateController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrTemplateController.java index c3430e011..bbf30ba15 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrTemplateController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrTemplateController.java @@ -20,11 +20,6 @@ import static org.springframework.http.MediaType.APPLICATION_JSON; import static org.springframework.http.MediaType.APPLICATION_XML; -import ag.vitagroup.hip.cdr.authorization.annotation.Action; -import ag.vitagroup.hip.cdr.authorization.annotation.ResourceId; -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; -import ag.vitagroup.hip.cdr.authorization.annotation.XacmlAuthorization; -import com.nedap.archie.rm.composition.Composition; import java.io.ByteArrayInputStream; import java.io.IOException; import java.net.URI; @@ -35,9 +30,9 @@ import java.util.Objects; import java.util.Optional; import java.util.function.Supplier; + import org.apache.xmlbeans.XmlException; import org.ehrbase.api.annotations.TenantAware; -import org.ehrbase.api.authorization.EhrbaseAuthorization; import org.ehrbase.api.authorization.EhrbasePermission; import org.ehrbase.api.definitions.OperationalTemplateFormat; import org.ehrbase.api.exception.InternalServerException; @@ -70,6 +65,13 @@ import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; +import com.nedap.archie.rm.composition.Composition; + +import ag.vitagroup.hip.cdr.authorization.annotation.Action; +import ag.vitagroup.hip.cdr.authorization.annotation.ResourceId; +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; +import ag.vitagroup.hip.cdr.authorization.annotation.XacmlAuthorization; + /** * Controller for /template resource as part of the Definitions sub-API of the openEHR REST API */ @@ -97,7 +99,7 @@ public OpenehrTemplateController(TemplateService templateService, CompositionSer path = "/adl1.4", produces = {MediaType.APPLICATION_XML_VALUE}) @ResponseStatus(value = HttpStatus.CREATED) - @Scope(scope = EhrbasePermission.EHRBASE_TEMPLATE_CREATE) + @Scope(scope = "ehrbase:template:create") public ResponseEntity createTemplateClassic( @RequestHeader(value = "openEHR-VERSION", required = false) String openehrVersion, // TODO, see EHR-267 @RequestHeader(value = "openEHR-AUDIT_DETAILS", required = false) @@ -161,7 +163,7 @@ public ResponseEntity createTemplateClassic( @XacmlAuthorization @Action(action = "method:call:getTemplatesClassic") @ResourceId(resourceId = "OpenehrTemplateController") - @Scope(scope = EhrbasePermission.EHRBASE_TEMPLATE_READ) + @Scope(scope = "ehrbase:template:read") public ResponseEntity getTemplatesClassic( @RequestHeader(value = "openEHR-VERSION", required = false) String openehrVersion, // TODO, see EHR-267 @RequestHeader(value = "openEHR-AUDIT_DETAILS", required = false) @@ -188,7 +190,7 @@ public ResponseEntity getTemplatesClassic( // Note: based on latest-branch of 1.1.0 release of openEHR REST API, because this endpoint was changed // significantly @GetMapping("/adl1.4/{template_id}") - @Scope(scope = EhrbasePermission.EHRBASE_TEMPLATE_READ) + @Scope(scope = "ehrbase:template:read") public ResponseEntity getTemplateClassic( @RequestHeader(value = "openEHR-VERSION", required = false) String openehrVersion, // TODO, see EHR-267 @RequestHeader(value = "openEHR-AUDIT_DETAILS", required = false) @@ -214,7 +216,7 @@ public ResponseEntity getTemplateClassic( } @GetMapping(path = "/adl1.4/{template_id}/example") - @Scope(scope = EhrbasePermission.EHRBASE_TEMPLATE_READ) + @Scope(scope = "ehrbase:template:example") public ResponseEntity getTemplateExample( @RequestHeader(value = ACCEPT, required = false) String accept, @PathVariable(value = "template_id") String templateId) { @@ -242,7 +244,7 @@ public ResponseEntity getTemplateExample( */ @PostMapping("/adl2") @ResponseStatus(value = HttpStatus.CREATED) - @Scope(scope = EhrbasePermission.EHRBASE_TEMPLATE_CREATE) + @Scope(scope = "ehrbase:template:create") public ResponseEntity createTemplateNew( @RequestHeader(value = "openEHR-VERSION", required = false) String openehrVersion, // TODO, see EHR-267 @RequestHeader(value = "openEHR-AUDIT_DETAILS", required = false) @@ -277,7 +279,7 @@ public ResponseEntity createTemplateNew( // also, this endpoint combines what is listed as two endpoints: // https://specifications.openehr.org/releases/ITS-REST/latest/definitions.html#definitions-adl-2-template-get @GetMapping("/adl2/{template_id}/{version_pattern}") - @Scope(scope = EhrbasePermission.EHRBASE_TEMPLATE_READ) + @Scope(scope = "ehrbase:template:read") public ResponseEntity getTemplateNew( @RequestHeader(value = "openEHR-VERSION", required = false) String openehrVersion, // TODO, see EHR-267 @RequestHeader(value = "openEHR-AUDIT_DETAILS", required = false) diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrVersionedCompositionController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrVersionedCompositionController.java index 9a58e4543..39a7e7813 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrVersionedCompositionController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrVersionedCompositionController.java @@ -21,18 +21,13 @@ import static org.ehrbase.rest.BaseController.VERSIONED_COMPOSITION; import static org.springframework.web.util.UriComponentsBuilder.fromPath; -import com.nedap.archie.rm.changecontrol.OriginalVersion; -import com.nedap.archie.rm.composition.Composition; -import com.nedap.archie.rm.ehr.VersionedComposition; -import com.nedap.archie.rm.generic.RevisionHistory; -import com.nedap.archie.rm.support.identification.ObjectVersionId; import java.time.LocalDateTime; import java.util.Objects; import java.util.Optional; import java.util.UUID; + import org.ehrbase.api.annotations.TenantAware; import org.ehrbase.api.audit.msg.AuditMsgBuilder; -import org.ehrbase.api.authorization.EhrbaseAuthorization; import org.ehrbase.api.authorization.EhrbasePermission; import org.ehrbase.api.exception.InternalServerException; import org.ehrbase.api.exception.InvalidApiParameterException; @@ -60,6 +55,14 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.util.UriComponentsBuilder; +import com.nedap.archie.rm.changecontrol.OriginalVersion; +import com.nedap.archie.rm.composition.Composition; +import com.nedap.archie.rm.ehr.VersionedComposition; +import com.nedap.archie.rm.generic.RevisionHistory; +import com.nedap.archie.rm.support.identification.ObjectVersionId; + +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; + /** * Controller for /ehr/{ehrId}/versioned_composition resource of openEHR REST API */ @@ -83,7 +86,7 @@ public OpenehrVersionedCompositionController( this.contributionService = Objects.requireNonNull(contributionService); } - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_COMPOSITION_READ) + @Scope(scope = "ehrbase:composition:read") @GetMapping(path = "/{versioned_object_uid}") @Override public ResponseEntity> retrieveVersionedCompositionByVersionedObjectUid( @@ -111,7 +114,7 @@ public ResponseEntity> retrieveVersione return ResponseEntity.ok().headers(respHeaders).body(response); } - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_COMPOSITION_READ) + @Scope(scope = "ehrbase:composition:read") @GetMapping(path = "/{versioned_object_uid}/revision_history") @Override public ResponseEntity retrieveVersionedCompositionRevisionHistoryByEhr( @@ -139,7 +142,7 @@ public ResponseEntity retrieveVersionedCompositionR return ResponseEntity.ok().headers(respHeaders).body(response); } - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_COMPOSITION_READ) + @Scope(scope = "ehrbase:composition:read") @GetMapping(path = "/{versioned_object_uid}/version/{version_uid}") // checkAbacPre /-Post attributes (type, subject, payload, content type) @PostAuthorize("checkAbacPost(@openehrVersionedCompositionController.COMPOSITION, " @@ -180,7 +183,7 @@ public ResponseEntity> retrieveVersionO return getOriginalVersionResponseDataResponseEntity(accept, ehrId, versionedObjectId, version); } - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_COMPOSITION_READ) + @Scope(scope = "ehrbase:composition:read") @GetMapping(path = "/{versioned_object_uid}/version") // checkAbacPre /-Post attributes (type, subject, payload, content type) @PostAuthorize("checkAbacPost(@openehrVersionedCompositionController.COMPOSITION, " diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrVersionedEhrStatusController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrVersionedEhrStatusController.java index 8b80fee02..02aa04861 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrVersionedEhrStatusController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrVersionedEhrStatusController.java @@ -17,18 +17,14 @@ */ package org.ehrbase.rest.openehr; -import com.nedap.archie.rm.changecontrol.OriginalVersion; -import com.nedap.archie.rm.ehr.EhrStatus; -import com.nedap.archie.rm.ehr.VersionedEhrStatus; -import com.nedap.archie.rm.generic.RevisionHistory; import java.sql.Timestamp; import java.time.LocalDateTime; import java.util.Objects; import java.util.Optional; import java.util.UUID; + import org.ehrbase.api.annotations.TenantAware; import org.ehrbase.api.audit.msg.AuditMsgBuilder; -import org.ehrbase.api.authorization.EhrbaseAuthorization; import org.ehrbase.api.authorization.EhrbasePermission; import org.ehrbase.api.exception.InternalServerException; import org.ehrbase.api.exception.InvalidApiParameterException; @@ -53,6 +49,13 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import com.nedap.archie.rm.changecontrol.OriginalVersion; +import com.nedap.archie.rm.ehr.EhrStatus; +import com.nedap.archie.rm.ehr.VersionedEhrStatus; +import com.nedap.archie.rm.generic.RevisionHistory; + +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; + /** * Controller for /ehr/{ehrId}/versioned_ehr_status resource of openEHR REST API */ @@ -72,7 +75,7 @@ public OpenehrVersionedEhrStatusController(EhrService ehrService, ContributionSe this.contributionService = Objects.requireNonNull(contributionService); } - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_EHR_READ_STATUS) + @Scope(scope = "ehrbase:ehr:read_status") @GetMapping @Override public ResponseEntity> retrieveVersionedEhrStatusByEhr( @@ -98,7 +101,7 @@ public ResponseEntity> retrieveVersionedE return ResponseEntity.ok().headers(respHeaders).body(response); } - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_EHR_READ_STATUS) + @Scope(scope = "ehrbase:ehr:read_status") @GetMapping(path = "/revision_history") @Override public ResponseEntity retrieveVersionedEhrStatusRevisionHistoryByEhr( @@ -124,7 +127,7 @@ public ResponseEntity retrieveVersionedEhrStatusRev return ResponseEntity.ok().headers(respHeaders).body(response); } - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_EHR_READ_STATUS) + @Scope(scope = "ehrbase:ehr:read_status") @GetMapping(path = "/version") // checkAbacPre /-Post attributes (type, subject, payload, content type) @PreAuthorize("checkAbacPre(@openehrVersionedEhrStatusController.EHR_STATUS, " @@ -175,7 +178,7 @@ public ResponseEntity> retrieveVersionOfE return ResponseEntity.ok().headers(respHeaders).body(originalVersionResponseData); } - @EhrbaseAuthorization(permission = EhrbasePermission.EHRBASE_EHR_READ_STATUS) + @Scope(scope = "ehrbase:ehr:read_status") @GetMapping(path = "/version/{version_uid}") // checkAbacPre /-Post attributes (type, subject, payload, content type) @PreAuthorize("checkAbacPre(@openehrVersionedEhrStatusController.EHR_STATUS, " From 142a306ac463791c8b2cac7003d90422ee0510cb Mon Sep 17 00:00:00 2001 From: MBA Date: Wed, 26 Jul 2023 15:14:42 +0200 Subject: [PATCH 19/53] Rebased on dev --- .../org/ehrbase/rest/admin/AdminDirectoryController.java | 8 -------- .../rest/openehr/OpenehrDefinitionQueryController.java | 1 - .../ehrbase/rest/openehr/OpenehrDirectoryController.java | 1 - .../org/ehrbase/rest/openehr/OpenehrQueryController.java | 2 ++ 4 files changed, 2 insertions(+), 10 deletions(-) diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminDirectoryController.java b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminDirectoryController.java index ab56e7bd4..5cedd5608 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminDirectoryController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminDirectoryController.java @@ -19,18 +19,10 @@ import static org.springframework.web.util.UriComponentsBuilder.fromPath; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.headers.Header; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.responses.ApiResponses; -import io.swagger.v3.oas.annotations.tags.Tag; import java.util.UUID; import org.ehrbase.api.annotations.TenantAware; import org.ehrbase.api.audit.msg.AuditMsgBuilder; -import org.ehrbase.api.authorization.EhrbaseAuthorization; -import org.ehrbase.api.authorization.EhrbasePermission; import org.ehrbase.api.service.DirectoryService; import org.ehrbase.openehr.sdk.response.dto.admin.AdminDeleteResponseData; import org.ehrbase.rest.BaseController; diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDefinitionQueryController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDefinitionQueryController.java index 0500ceb5d..647c3ea22 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDefinitionQueryController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDefinitionQueryController.java @@ -26,7 +26,6 @@ import org.ehrbase.api.annotations.TenantAware; import org.ehrbase.api.audit.msg.AuditMsgBuilder; -import org.ehrbase.api.authorization.EhrbaseAuthorization; import org.ehrbase.api.authorization.EhrbasePermission; import org.ehrbase.api.exception.GeneralRequestProcessingException; import org.ehrbase.api.exception.UnexpectedSwitchCaseException; diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDirectoryController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDirectoryController.java index a3683aab3..909ac6f78 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDirectoryController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDirectoryController.java @@ -29,7 +29,6 @@ import org.apache.commons.lang3.StringUtils; import org.ehrbase.api.annotations.TenantAware; import org.ehrbase.api.audit.msg.AuditMsgBuilder; -import org.ehrbase.api.authorization.EhrbaseAuthorization; import org.ehrbase.api.authorization.EhrbasePermission; import org.ehrbase.api.exception.InvalidApiParameterException; import org.ehrbase.api.exception.ObjectNotFoundException; diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java index 65687604f..39b96b84a 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java @@ -17,6 +17,8 @@ */ package org.ehrbase.rest.openehr; +import static org.springframework.web.util.UriComponentsBuilder.fromPath; + import java.text.MessageFormat; import java.util.HashMap; import java.util.Map; From f078dcfb70d37bfbd9b131ca7fc387b9efc8f8e5 Mon Sep 17 00:00:00 2001 From: MBA Date: Wed, 26 Jul 2023 15:16:20 +0200 Subject: [PATCH 20/53] Spotless --- .../java/org/ehrbase/application/EhrBase.java | 3 +-- .../security/PluginSecurityConfiguration.java | 9 +++----- .../controller/CompositionController.java | 7 ++----- .../ehrscape/controller/EhrController.java | 20 +++++++----------- .../ehrscape/controller/QueryController.java | 5 +---- .../controller/TemplateController.java | 7 ++----- .../ehrbase/rest/DefaultExceptionHandler.java | 8 ++----- .../org/ehrbase/rest/StatusController.java | 21 ++++++++----------- .../admin/AdminCompositionController.java | 16 +++++++------- .../admin/AdminContributionController.java | 16 +++++++------- .../ehrbase/rest/admin/AdminController.java | 13 ++++++------ .../rest/admin/AdminDirectoryController.java | 16 +++++++------- .../rest/admin/AdminEhrController.java | 16 +++++++------- .../rest/admin/AdminTemplateController.java | 15 +++++++------ .../openehr/OpenehrCompositionController.java | 12 ++++------- .../OpenehrContributionController.java | 12 ++++------- .../OpenehrDefinitionQueryController.java | 12 ++++------- .../openehr/OpenehrDirectoryController.java | 10 +++------ .../rest/openehr/OpenehrEhrController.java | 1 - .../openehr/OpenehrEhrStatusController.java | 10 +++------ .../rest/openehr/OpenehrQueryController.java | 16 +++++++------- .../openehr/OpenehrTemplateController.java | 14 +++++-------- ...OpenehrVersionedCompositionController.java | 16 ++++++-------- .../OpenehrVersionedEhrStatusController.java | 14 +++++-------- 24 files changed, 110 insertions(+), 179 deletions(-) diff --git a/application/src/main/java/org/ehrbase/application/EhrBase.java b/application/src/main/java/org/ehrbase/application/EhrBase.java index dbc3dc56f..ca2c0cc58 100644 --- a/application/src/main/java/org/ehrbase/application/EhrBase.java +++ b/application/src/main/java/org/ehrbase/application/EhrBase.java @@ -17,7 +17,6 @@ */ package org.ehrbase.application; -import ag.vitagroup.hip.cdr.authorization.EnableXacmlAuthorization; import org.ehrbase.ServiceModuleConfiguration; import org.ehrbase.rest.RestModuleConfiguration; import org.ehrbase.rest.ehrscape.RestEHRScapeModuleConfiguration; @@ -38,7 +37,7 @@ R2dbcAutoConfiguration.class, SecurityAutoConfiguration.class }) -//@EnableXacmlAuthorization +// @EnableXacmlAuthorization @Import({ServiceModuleConfiguration.class, RestEHRScapeModuleConfiguration.class, RestModuleConfiguration.class}) public class EhrBase { diff --git a/plugin/src/main/java/org/ehrbase/plugin/security/PluginSecurityConfiguration.java b/plugin/src/main/java/org/ehrbase/plugin/security/PluginSecurityConfiguration.java index 7e13c4562..ecc5d00f6 100644 --- a/plugin/src/main/java/org/ehrbase/plugin/security/PluginSecurityConfiguration.java +++ b/plugin/src/main/java/org/ehrbase/plugin/security/PluginSecurityConfiguration.java @@ -17,11 +17,10 @@ */ package org.ehrbase.plugin.security; -import java.lang.annotation.Annotation; +import ag.vitagroup.hip.cdr.authorization.annotation.XacmlAuthorization; import java.lang.reflect.Method; import java.util.List; import java.util.Objects; - import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.aspectj.lang.ProceedingJoinPoint; @@ -45,8 +44,6 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; -import ag.vitagroup.hip.cdr.authorization.annotation.XacmlAuthorization; - public class PluginSecurityConfiguration implements ApplicationContextAware { // @format:off @SuppressWarnings("rawtypes") @@ -137,8 +134,8 @@ public Advisor authorizationAspect() { new AnnotationMatchingPointcut(null, XacmlAuthorization.class, true), new AspectAdapter(theAspect) { public Object invoke(MethodInvocation invocation) throws Throwable { Method method = invocation.getMethod(); - XacmlAuthorization annotation = method.getAnnotation(XacmlAuthorization.class); - + XacmlAuthorization annotation = method.getAnnotation(XacmlAuthorization.class); + return getAspect().action(new ProceedingJoinPointAdapter(invocation), List.of(annotation)); } }); diff --git a/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/CompositionController.java b/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/CompositionController.java index 1b8dc9288..63009af36 100644 --- a/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/CompositionController.java +++ b/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/CompositionController.java @@ -19,11 +19,12 @@ import static org.ehrbase.rest.ehrscape.controller.BaseController.API_ECIS_CONTEXT_PATH_WITH_VERSION; +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; +import com.nedap.archie.rm.support.identification.ObjectVersionId; import java.net.URI; import java.util.Objects; import java.util.Optional; import java.util.UUID; - import org.apache.commons.lang3.StringUtils; import org.ehrbase.api.annotations.TenantAware; import org.ehrbase.api.exception.InternalServerException; @@ -50,10 +51,6 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import com.nedap.archie.rm.support.identification.ObjectVersionId; - -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; - @TenantAware @RestController @RequestMapping( diff --git a/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/EhrController.java b/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/EhrController.java index 69744e276..0dbd600ed 100644 --- a/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/EhrController.java +++ b/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/EhrController.java @@ -19,15 +19,21 @@ import static org.ehrbase.rest.ehrscape.controller.BaseController.API_ECIS_CONTEXT_PATH_WITH_VERSION; +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.nedap.archie.rm.datavalues.DvText; +import com.nedap.archie.rm.ehr.EhrStatus; +import com.nedap.archie.rm.generic.PartySelf; +import com.nedap.archie.rm.support.identification.HierObjectId; +import com.nedap.archie.rm.support.identification.PartyRef; import java.net.URI; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.UUID; - import org.apache.commons.lang3.StringUtils; import org.ehrbase.api.annotations.TenantAware; -import org.ehrbase.api.authorization.EhrbasePermission; import org.ehrbase.api.exception.GeneralRequestProcessingException; import org.ehrbase.api.exception.InvalidApiParameterException; import org.ehrbase.api.service.EhrService; @@ -51,16 +57,6 @@ import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.nedap.archie.rm.datavalues.DvText; -import com.nedap.archie.rm.ehr.EhrStatus; -import com.nedap.archie.rm.generic.PartySelf; -import com.nedap.archie.rm.support.identification.HierObjectId; -import com.nedap.archie.rm.support.identification.PartyRef; - -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; - /** * Controller for /ehr resource of EhrScape REST API * diff --git a/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/QueryController.java b/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/QueryController.java index b853b7820..432d15141 100644 --- a/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/QueryController.java +++ b/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/QueryController.java @@ -17,13 +17,12 @@ */ package org.ehrbase.rest.ehrscape.controller; +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; import java.util.HashMap; import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; - import org.ehrbase.api.annotations.TenantAware; -import org.ehrbase.api.authorization.EhrbasePermission; import org.ehrbase.api.exception.InvalidApiParameterException; import org.ehrbase.api.service.QueryService; import org.ehrbase.rest.ehrscape.responsedata.Action; @@ -37,8 +36,6 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; - @TenantAware @RestController @RequestMapping( diff --git a/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/TemplateController.java b/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/TemplateController.java index 8f09d66ef..ad4027d54 100644 --- a/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/TemplateController.java +++ b/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/TemplateController.java @@ -20,11 +20,12 @@ import static org.ehrbase.rest.ehrscape.controller.BaseController.API_ECIS_CONTEXT_PATH_WITH_VERSION; import static org.ehrbase.rest.ehrscape.controller.BaseController.TEMPLATE; +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; +import com.nedap.archie.rm.composition.Composition; import java.io.ByteArrayInputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.Objects; - import org.apache.xmlbeans.XmlException; import org.ehrbase.api.annotations.TenantAware; import org.ehrbase.api.exception.InvalidApiParameterException; @@ -51,10 +52,6 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import com.nedap.archie.rm.composition.Composition; - -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; - @TenantAware @RestController @RequestMapping( diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/DefaultExceptionHandler.java b/rest-openehr/src/main/java/org/ehrbase/rest/DefaultExceptionHandler.java index 2dd4182bb..a893786ae 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/DefaultExceptionHandler.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/DefaultExceptionHandler.java @@ -17,11 +17,10 @@ */ package org.ehrbase.rest; +import ag.vitagroup.hip.cdr.authorization.xacml.eval.AccessCtrlException; import java.net.URI; import java.util.HashMap; import java.util.Map; - -import ag.vitagroup.hip.cdr.authorization.xacml.eval.AccessCtrlException; import org.ehrbase.api.exception.GeneralRequestProcessingException; import org.ehrbase.api.exception.InvalidApiParameterException; import org.ehrbase.api.exception.NotAcceptableException; @@ -81,10 +80,7 @@ public ResponseEntity handleBadRequestExceptions(Exception ex) { return handleExceptionInternal(ex, ex.getMessage(), new HttpHeaders(), HttpStatus.BAD_REQUEST); } - @ExceptionHandler({ - AccessDeniedException.class, - AccessCtrlException.class - }) + @ExceptionHandler({AccessDeniedException.class, AccessCtrlException.class}) public ResponseEntity handleObjectNotFoundException(Exception ex) { return handleExceptionInternal(ex, ex.getMessage(), new HttpHeaders(), HttpStatus.FORBIDDEN); } diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/StatusController.java b/rest-openehr/src/main/java/org/ehrbase/rest/StatusController.java index 9105283ff..122457f04 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/StatusController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/StatusController.java @@ -17,9 +17,16 @@ */ package org.ehrbase.rest; +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.headers.Header; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; import java.util.Objects; - -import org.ehrbase.api.authorization.EhrbasePermission; import org.ehrbase.api.service.StatusService; import org.ehrbase.openehr.sdk.response.dto.StatusResponseData; import org.springframework.beans.factory.annotation.Autowired; @@ -33,16 +40,6 @@ import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.headers.Header; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.responses.ApiResponses; -import io.swagger.v3.oas.annotations.tags.Tag; - /** * API endpoint to get status of EHRbase and version information on used dependencies as archie or openEHR_sdk as well * as the current used JVM version or target PostgreSQL server version. diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminCompositionController.java b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminCompositionController.java index ca26e35f6..1e614b86f 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminCompositionController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminCompositionController.java @@ -17,9 +17,15 @@ */ package org.ehrbase.rest.admin; +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.headers.Header; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; import java.util.Objects; import java.util.UUID; - import org.ehrbase.api.annotations.TenantAware; import org.ehrbase.api.audit.msg.AuditMsgBuilder; import org.ehrbase.api.exception.ObjectNotFoundException; @@ -37,14 +43,6 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.util.UriComponentsBuilder; -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.headers.Header; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.responses.ApiResponses; -import io.swagger.v3.oas.annotations.tags.Tag; - /** * Admin API controller for Composition related data. Provides endpoint to remove compositions physically from database. */ diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminContributionController.java b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminContributionController.java index 00a994c9b..9646d7b26 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminContributionController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminContributionController.java @@ -20,8 +20,14 @@ import static org.apache.commons.lang3.StringUtils.EMPTY; import static org.springframework.web.util.UriComponentsBuilder.fromPath; +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.headers.Header; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; import java.util.UUID; - import org.ehrbase.api.annotations.TenantAware; import org.ehrbase.api.audit.msg.AuditMsgBuilder; import org.ehrbase.api.exception.ObjectNotFoundException; @@ -40,14 +46,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.headers.Header; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.responses.ApiResponses; -import io.swagger.v3.oas.annotations.tags.Tag; - /** * Admin API controller for Contribution related data. Provides endpoints to update and remove Contributions in * database physically. diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminController.java b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminController.java index d2197a613..14e515a8b 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminController.java @@ -17,6 +17,12 @@ */ package org.ehrbase.rest.admin; +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; +import io.swagger.v3.oas.annotations.headers.Header; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; import org.ehrbase.api.annotations.TenantAware; import org.ehrbase.openehr.sdk.response.dto.admin.AdminStatusResponseData; import org.ehrbase.rest.BaseController; @@ -27,13 +33,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; -import io.swagger.v3.oas.annotations.headers.Header; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.responses.ApiResponses; -import io.swagger.v3.oas.annotations.tags.Tag; - @TenantAware @Tag(name = "Admin - Heartbeat") @ConditionalOnProperty(prefix = "admin-api", name = "active") diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminDirectoryController.java b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminDirectoryController.java index 5cedd5608..f9af8f8b5 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminDirectoryController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminDirectoryController.java @@ -19,8 +19,14 @@ import static org.springframework.web.util.UriComponentsBuilder.fromPath; +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.headers.Header; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; import java.util.UUID; - import org.ehrbase.api.annotations.TenantAware; import org.ehrbase.api.audit.msg.AuditMsgBuilder; import org.ehrbase.api.service.DirectoryService; @@ -35,14 +41,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.headers.Header; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.responses.ApiResponses; -import io.swagger.v3.oas.annotations.tags.Tag; - /** * Admin API controller for directories. Provides endpoint to remove complete directory trees from database physically. */ diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminEhrController.java b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminEhrController.java index c27a4188d..462ac6042 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminEhrController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminEhrController.java @@ -17,11 +17,17 @@ */ package org.ehrbase.rest.admin; +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.headers.Header; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; import java.util.Arrays; import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; - import org.ehrbase.api.annotations.TenantAware; import org.ehrbase.api.audit.msg.AuditMsgBuilder; import org.ehrbase.api.exception.ObjectNotFoundException; @@ -41,14 +47,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.headers.Header; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.responses.ApiResponses; -import io.swagger.v3.oas.annotations.tags.Tag; - /** * Admin API controller for EHR related endpoints. Provides methods to update and delete EHRs physically in the DB. */ diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminTemplateController.java b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminTemplateController.java index a510b9363..49ad3f6f4 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminTemplateController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminTemplateController.java @@ -17,6 +17,13 @@ */ package org.ehrbase.rest.admin; +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.headers.Header; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; import org.ehrbase.api.annotations.TenantAware; import org.ehrbase.api.service.TemplateService; import org.ehrbase.openehr.sdk.response.dto.admin.AdminDeleteResponseData; @@ -36,14 +43,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.headers.Header; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.responses.ApiResponses; -import io.swagger.v3.oas.annotations.tags.Tag; - /** * Admin API controller for Templates. Provides endpoints to update (replace) and delete templates. */ diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrCompositionController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrCompositionController.java index a7f6b6996..0945eb997 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrCompositionController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrCompositionController.java @@ -20,6 +20,10 @@ import static org.apache.commons.lang3.StringUtils.unwrap; import static org.springframework.web.util.UriComponentsBuilder.fromPath; +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; +import com.nedap.archie.rm.composition.Composition; +import com.nedap.archie.rm.support.identification.ObjectId; +import com.nedap.archie.rm.support.identification.ObjectVersionId; import java.net.URI; import java.time.LocalDateTime; import java.time.OffsetDateTime; @@ -31,10 +35,8 @@ import java.util.Optional; import java.util.UUID; import java.util.function.Supplier; - import org.ehrbase.api.annotations.TenantAware; import org.ehrbase.api.audit.msg.AuditMsgBuilder; -import org.ehrbase.api.authorization.EhrbasePermission; import org.ehrbase.api.exception.InternalServerException; import org.ehrbase.api.exception.ObjectNotFoundException; import org.ehrbase.api.exception.PreconditionFailedException; @@ -66,12 +68,6 @@ import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; -import com.nedap.archie.rm.composition.Composition; -import com.nedap.archie.rm.support.identification.ObjectId; -import com.nedap.archie.rm.support.identification.ObjectVersionId; - -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; - /** * Controller for /composition resource as part of the EHR sub-API of the openEHR REST API * diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrContributionController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrContributionController.java index cddb3b7a9..5b95738c9 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrContributionController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrContributionController.java @@ -20,6 +20,10 @@ import static org.apache.commons.lang3.StringUtils.EMPTY; import static org.springframework.web.util.UriComponentsBuilder.fromPath; +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; +import com.nedap.archie.rm.support.identification.HierObjectId; +import com.nedap.archie.rm.support.identification.ObjectRef; +import com.nedap.archie.rm.support.identification.ObjectVersionId; import java.net.URI; import java.util.Arrays; import java.util.LinkedList; @@ -28,10 +32,8 @@ import java.util.Optional; import java.util.UUID; import java.util.function.Supplier; - import org.ehrbase.api.annotations.TenantAware; import org.ehrbase.api.audit.msg.AuditMsgBuilder; -import org.ehrbase.api.authorization.EhrbasePermission; import org.ehrbase.api.exception.NotAcceptableException; import org.ehrbase.api.service.ContributionService; import org.ehrbase.openehr.sdk.response.dto.ContributionResponseData; @@ -55,12 +57,6 @@ import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; -import com.nedap.archie.rm.support.identification.HierObjectId; -import com.nedap.archie.rm.support.identification.ObjectRef; -import com.nedap.archie.rm.support.identification.ObjectVersionId; - -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; - @TenantAware @RestController @RequestMapping( diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDefinitionQueryController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDefinitionQueryController.java index 647c3ea22..702b5e5fc 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDefinitionQueryController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDefinitionQueryController.java @@ -21,12 +21,14 @@ import static org.springframework.http.MediaType.*; import static org.springframework.web.util.UriComponentsBuilder.fromPath; +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import java.util.Objects; import java.util.Optional; - import org.ehrbase.api.annotations.TenantAware; import org.ehrbase.api.audit.msg.AuditMsgBuilder; -import org.ehrbase.api.authorization.EhrbasePermission; import org.ehrbase.api.exception.GeneralRequestProcessingException; import org.ehrbase.api.exception.UnexpectedSwitchCaseException; import org.ehrbase.api.exception.UnsupportedMediaTypeException; @@ -55,12 +57,6 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; - -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; - @TenantAware @RestController @RequestMapping( diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDirectoryController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDirectoryController.java index 909ac6f78..802d4deb4 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDirectoryController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDirectoryController.java @@ -20,16 +20,17 @@ import static org.apache.commons.lang3.StringUtils.unwrap; import static org.springframework.web.util.UriComponentsBuilder.fromPath; +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; +import com.nedap.archie.rm.directory.Folder; +import com.nedap.archie.rm.support.identification.ObjectVersionId; import java.nio.file.InvalidPathException; import java.nio.file.Paths; import java.time.OffsetDateTime; import java.util.Optional; import java.util.UUID; - import org.apache.commons.lang3.StringUtils; import org.ehrbase.api.annotations.TenantAware; import org.ehrbase.api.audit.msg.AuditMsgBuilder; -import org.ehrbase.api.authorization.EhrbasePermission; import org.ehrbase.api.exception.InvalidApiParameterException; import org.ehrbase.api.exception.ObjectNotFoundException; import org.ehrbase.api.service.DirectoryService; @@ -53,11 +54,6 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import com.nedap.archie.rm.directory.Folder; -import com.nedap.archie.rm.support.identification.ObjectVersionId; - -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; - /** * Controller for openEHR /directory endpoints * diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrController.java index 52a249f66..27590d6be 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrController.java @@ -34,7 +34,6 @@ import java.util.function.Supplier; import org.ehrbase.api.annotations.TenantAware; import org.ehrbase.api.audit.msg.AuditMsgBuilder; -import org.ehrbase.api.authorization.EhrbasePermission; import org.ehrbase.api.exception.InternalServerException; import org.ehrbase.api.exception.InvalidApiParameterException; import org.ehrbase.api.exception.ObjectNotFoundException; diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrStatusController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrStatusController.java index 02225dc66..91ea4e7bc 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrStatusController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrStatusController.java @@ -19,6 +19,9 @@ import static org.apache.commons.lang3.StringUtils.unwrap; +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; +import com.nedap.archie.rm.changecontrol.OriginalVersion; +import com.nedap.archie.rm.ehr.EhrStatus; import java.net.URI; import java.sql.Timestamp; import java.time.OffsetDateTime; @@ -27,10 +30,8 @@ import java.util.Optional; import java.util.UUID; import java.util.function.Supplier; - import org.ehrbase.api.annotations.TenantAware; import org.ehrbase.api.audit.msg.AuditMsgBuilder; -import org.ehrbase.api.authorization.EhrbasePermission; import org.ehrbase.api.exception.InternalServerException; import org.ehrbase.api.exception.InvalidApiParameterException; import org.ehrbase.api.exception.ObjectNotFoundException; @@ -54,11 +55,6 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import com.nedap.archie.rm.changecontrol.OriginalVersion; -import com.nedap.archie.rm.ehr.EhrStatus; - -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; - /** * Controller for /ehr/{ehrId}/ehr_status resource of openEHR REST API * diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java index 39b96b84a..d7d0627c8 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java @@ -19,12 +19,18 @@ import static org.springframework.web.util.UriComponentsBuilder.fromPath; +import ag.vitagroup.hip.cdr.authorization.annotation.Action; +import ag.vitagroup.hip.cdr.authorization.annotation.ResourceId; +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; +import ag.vitagroup.hip.cdr.authorization.annotation.TenantPolicyLookup; +import ag.vitagroup.hip.cdr.authorization.annotation.XacmlAuthorization; +import ag.vitagroup.hip.cdr.authorization.annotation.XacmlAuthorization.Version; +import ag.vitagroup.hip.cdr.authorization.annotation.XacmlUrlRequestParameter; import java.text.MessageFormat; import java.util.HashMap; import java.util.Map; import java.util.Optional; import java.util.Set; - import org.apache.commons.collections4.MapUtils; import org.ehrbase.api.annotations.TenantAware; import org.ehrbase.api.audit.msg.AuditMsgBuilder; @@ -53,14 +59,6 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import ag.vitagroup.hip.cdr.authorization.annotation.Action; -import ag.vitagroup.hip.cdr.authorization.annotation.ResourceId; -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; -import ag.vitagroup.hip.cdr.authorization.annotation.TenantPolicyLookup; -import ag.vitagroup.hip.cdr.authorization.annotation.XacmlAuthorization; -import ag.vitagroup.hip.cdr.authorization.annotation.XacmlAuthorization.Version; -import ag.vitagroup.hip.cdr.authorization.annotation.XacmlUrlRequestParameter; - /** * Controller for openEHR REST API QUERY resource. * diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrTemplateController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrTemplateController.java index bbf30ba15..b65b6b6b3 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrTemplateController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrTemplateController.java @@ -20,6 +20,11 @@ import static org.springframework.http.MediaType.APPLICATION_JSON; import static org.springframework.http.MediaType.APPLICATION_XML; +import ag.vitagroup.hip.cdr.authorization.annotation.Action; +import ag.vitagroup.hip.cdr.authorization.annotation.ResourceId; +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; +import ag.vitagroup.hip.cdr.authorization.annotation.XacmlAuthorization; +import com.nedap.archie.rm.composition.Composition; import java.io.ByteArrayInputStream; import java.io.IOException; import java.net.URI; @@ -30,10 +35,8 @@ import java.util.Objects; import java.util.Optional; import java.util.function.Supplier; - import org.apache.xmlbeans.XmlException; import org.ehrbase.api.annotations.TenantAware; -import org.ehrbase.api.authorization.EhrbasePermission; import org.ehrbase.api.definitions.OperationalTemplateFormat; import org.ehrbase.api.exception.InternalServerException; import org.ehrbase.api.exception.InvalidApiParameterException; @@ -65,13 +68,6 @@ import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; -import com.nedap.archie.rm.composition.Composition; - -import ag.vitagroup.hip.cdr.authorization.annotation.Action; -import ag.vitagroup.hip.cdr.authorization.annotation.ResourceId; -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; -import ag.vitagroup.hip.cdr.authorization.annotation.XacmlAuthorization; - /** * Controller for /template resource as part of the Definitions sub-API of the openEHR REST API */ diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrVersionedCompositionController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrVersionedCompositionController.java index 39a7e7813..f949b8c2a 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrVersionedCompositionController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrVersionedCompositionController.java @@ -21,14 +21,18 @@ import static org.ehrbase.rest.BaseController.VERSIONED_COMPOSITION; import static org.springframework.web.util.UriComponentsBuilder.fromPath; +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; +import com.nedap.archie.rm.changecontrol.OriginalVersion; +import com.nedap.archie.rm.composition.Composition; +import com.nedap.archie.rm.ehr.VersionedComposition; +import com.nedap.archie.rm.generic.RevisionHistory; +import com.nedap.archie.rm.support.identification.ObjectVersionId; import java.time.LocalDateTime; import java.util.Objects; import java.util.Optional; import java.util.UUID; - import org.ehrbase.api.annotations.TenantAware; import org.ehrbase.api.audit.msg.AuditMsgBuilder; -import org.ehrbase.api.authorization.EhrbasePermission; import org.ehrbase.api.exception.InternalServerException; import org.ehrbase.api.exception.InvalidApiParameterException; import org.ehrbase.api.exception.ObjectNotFoundException; @@ -55,14 +59,6 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.util.UriComponentsBuilder; -import com.nedap.archie.rm.changecontrol.OriginalVersion; -import com.nedap.archie.rm.composition.Composition; -import com.nedap.archie.rm.ehr.VersionedComposition; -import com.nedap.archie.rm.generic.RevisionHistory; -import com.nedap.archie.rm.support.identification.ObjectVersionId; - -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; - /** * Controller for /ehr/{ehrId}/versioned_composition resource of openEHR REST API */ diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrVersionedEhrStatusController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrVersionedEhrStatusController.java index 02aa04861..18e30797d 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrVersionedEhrStatusController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrVersionedEhrStatusController.java @@ -17,15 +17,18 @@ */ package org.ehrbase.rest.openehr; +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; +import com.nedap.archie.rm.changecontrol.OriginalVersion; +import com.nedap.archie.rm.ehr.EhrStatus; +import com.nedap.archie.rm.ehr.VersionedEhrStatus; +import com.nedap.archie.rm.generic.RevisionHistory; import java.sql.Timestamp; import java.time.LocalDateTime; import java.util.Objects; import java.util.Optional; import java.util.UUID; - import org.ehrbase.api.annotations.TenantAware; import org.ehrbase.api.audit.msg.AuditMsgBuilder; -import org.ehrbase.api.authorization.EhrbasePermission; import org.ehrbase.api.exception.InternalServerException; import org.ehrbase.api.exception.InvalidApiParameterException; import org.ehrbase.api.exception.ObjectNotFoundException; @@ -49,13 +52,6 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import com.nedap.archie.rm.changecontrol.OriginalVersion; -import com.nedap.archie.rm.ehr.EhrStatus; -import com.nedap.archie.rm.ehr.VersionedEhrStatus; -import com.nedap.archie.rm.generic.RevisionHistory; - -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; - /** * Controller for /ehr/{ehrId}/versioned_ehr_status resource of openEHR REST API */ From 949a9605b11d7080bf76cdb8984ce98a951af486 Mon Sep 17 00:00:00 2001 From: MBA Date: Wed, 26 Jul 2023 15:41:13 +0200 Subject: [PATCH 21/53] Tmp. commit --- .../rest/openehr/OpenehrQueryController.java | 25 +++---------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java index d7d0627c8..396a5ed25 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java @@ -19,18 +19,12 @@ import static org.springframework.web.util.UriComponentsBuilder.fromPath; -import ag.vitagroup.hip.cdr.authorization.annotation.Action; -import ag.vitagroup.hip.cdr.authorization.annotation.ResourceId; -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; -import ag.vitagroup.hip.cdr.authorization.annotation.TenantPolicyLookup; -import ag.vitagroup.hip.cdr.authorization.annotation.XacmlAuthorization; -import ag.vitagroup.hip.cdr.authorization.annotation.XacmlAuthorization.Version; -import ag.vitagroup.hip.cdr.authorization.annotation.XacmlUrlRequestParameter; import java.text.MessageFormat; import java.util.HashMap; import java.util.Map; import java.util.Optional; import java.util.Set; + import org.apache.commons.collections4.MapUtils; import org.ehrbase.api.annotations.TenantAware; import org.ehrbase.api.audit.msg.AuditMsgBuilder; @@ -67,7 +61,6 @@ * @since 1.0 */ @TenantAware -@TenantPolicyLookup @RestController @RequestMapping(path = BaseController.API_CONTEXT_PATH_WITH_VERSION + "/query") public class OpenehrQueryController extends BaseController implements QueryApiSpecification { @@ -90,15 +83,10 @@ public OpenehrQueryController(QueryService queryService) { /** * {@inheritDoc} */ - @XacmlAuthorization(version = Version.V2) - @Action(action = "query_aql") - @ResourceId(resourceId = "OpenehrQueryController") - /*@ConstrainAql(constraint = "LimitByFacilityName")*/ - @Scope(scope = "ehrbase:query:search_ad_hoc") @GetMapping(path = "/aql") @PostAuthorize("checkAbacPostQuery(@requestAwareAuditResultMapHolder.getAuditResultMap())") public ResponseEntity executeAdHocQuery( - @XacmlUrlRequestParameter("aql_query") @RequestParam(name = "q") String query, + @RequestParam(name = "q") String query, @RequestParam(name = "offset", required = false) Integer offset, @RequestParam(name = "fetch", required = false) Integer fetch, @RequestParam(name = "query_parameters", required = false) Map queryParameters, @@ -128,16 +116,11 @@ public ResponseEntity executeAdHocQuery( /** * {@inheritDoc} */ - @XacmlAuthorization(version = Version.V2) - @Action(action = "query_aql") - @ResourceId(resourceId = "OpenehrQueryController") - /*@ConstrainAql(constraint = "LimitByFacilityName")*/ - @Scope(scope = "ehrbase:query:search_ad_hoc") @PostMapping(path = "/aql") @PostAuthorize("checkAbacPostQuery(@requestAwareAuditResultMapHolder.getAuditResultMap())") @SuppressWarnings("unchecked") public ResponseEntity executeAdHocQuery( - @XacmlUrlRequestParameter("aql_query") @RequestBody Map queryRequest, + @RequestBody Map queryRequest, @RequestHeader(name = ACCEPT, required = false) String accept, @RequestHeader(name = CONTENT_TYPE) String contentType) { @@ -161,7 +144,6 @@ public ResponseEntity executeAdHocQuery( /** * {@inheritDoc} */ - @Scope(scope = "ehrbase:query:search") @GetMapping(path = {"/{qualified_query_name}", "/{qualified_query_name}/{version}"}) @PostAuthorize("checkAbacPostQuery(@requestAwareAuditResultMapHolder.getAuditResultMap())") public ResponseEntity executeStoredQuery( @@ -208,7 +190,6 @@ public ResponseEntity executeStoredQuery( /** * {@inheritDoc} */ - @Scope(scope = "ehrbase:query:search") @PostMapping(path = {"/{qualified_query_name}", "/{qualified_query_name}/{version}"}) @PostAuthorize("checkAbacPostQuery(@requestAwareAuditResultMapHolder.getAuditResultMap())") @SuppressWarnings("unchecked") From 802a2ca7d2a16d299c608c746eccac9ee40a3e48 Mon Sep 17 00:00:00 2001 From: MBA Date: Wed, 26 Jul 2023 16:57:31 +0200 Subject: [PATCH 22/53] Revert "Tmp. commit" This reverts commit 5f070e40551405c8e6298fab2a0c7d2c6fe1531f. --- .../rest/openehr/OpenehrQueryController.java | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java index 396a5ed25..d7d0627c8 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java @@ -19,12 +19,18 @@ import static org.springframework.web.util.UriComponentsBuilder.fromPath; +import ag.vitagroup.hip.cdr.authorization.annotation.Action; +import ag.vitagroup.hip.cdr.authorization.annotation.ResourceId; +import ag.vitagroup.hip.cdr.authorization.annotation.Scope; +import ag.vitagroup.hip.cdr.authorization.annotation.TenantPolicyLookup; +import ag.vitagroup.hip.cdr.authorization.annotation.XacmlAuthorization; +import ag.vitagroup.hip.cdr.authorization.annotation.XacmlAuthorization.Version; +import ag.vitagroup.hip.cdr.authorization.annotation.XacmlUrlRequestParameter; import java.text.MessageFormat; import java.util.HashMap; import java.util.Map; import java.util.Optional; import java.util.Set; - import org.apache.commons.collections4.MapUtils; import org.ehrbase.api.annotations.TenantAware; import org.ehrbase.api.audit.msg.AuditMsgBuilder; @@ -61,6 +67,7 @@ * @since 1.0 */ @TenantAware +@TenantPolicyLookup @RestController @RequestMapping(path = BaseController.API_CONTEXT_PATH_WITH_VERSION + "/query") public class OpenehrQueryController extends BaseController implements QueryApiSpecification { @@ -83,10 +90,15 @@ public OpenehrQueryController(QueryService queryService) { /** * {@inheritDoc} */ + @XacmlAuthorization(version = Version.V2) + @Action(action = "query_aql") + @ResourceId(resourceId = "OpenehrQueryController") + /*@ConstrainAql(constraint = "LimitByFacilityName")*/ + @Scope(scope = "ehrbase:query:search_ad_hoc") @GetMapping(path = "/aql") @PostAuthorize("checkAbacPostQuery(@requestAwareAuditResultMapHolder.getAuditResultMap())") public ResponseEntity executeAdHocQuery( - @RequestParam(name = "q") String query, + @XacmlUrlRequestParameter("aql_query") @RequestParam(name = "q") String query, @RequestParam(name = "offset", required = false) Integer offset, @RequestParam(name = "fetch", required = false) Integer fetch, @RequestParam(name = "query_parameters", required = false) Map queryParameters, @@ -116,11 +128,16 @@ public ResponseEntity executeAdHocQuery( /** * {@inheritDoc} */ + @XacmlAuthorization(version = Version.V2) + @Action(action = "query_aql") + @ResourceId(resourceId = "OpenehrQueryController") + /*@ConstrainAql(constraint = "LimitByFacilityName")*/ + @Scope(scope = "ehrbase:query:search_ad_hoc") @PostMapping(path = "/aql") @PostAuthorize("checkAbacPostQuery(@requestAwareAuditResultMapHolder.getAuditResultMap())") @SuppressWarnings("unchecked") public ResponseEntity executeAdHocQuery( - @RequestBody Map queryRequest, + @XacmlUrlRequestParameter("aql_query") @RequestBody Map queryRequest, @RequestHeader(name = ACCEPT, required = false) String accept, @RequestHeader(name = CONTENT_TYPE) String contentType) { @@ -144,6 +161,7 @@ public ResponseEntity executeAdHocQuery( /** * {@inheritDoc} */ + @Scope(scope = "ehrbase:query:search") @GetMapping(path = {"/{qualified_query_name}", "/{qualified_query_name}/{version}"}) @PostAuthorize("checkAbacPostQuery(@requestAwareAuditResultMapHolder.getAuditResultMap())") public ResponseEntity executeStoredQuery( @@ -190,6 +208,7 @@ public ResponseEntity executeStoredQuery( /** * {@inheritDoc} */ + @Scope(scope = "ehrbase:query:search") @PostMapping(path = {"/{qualified_query_name}", "/{qualified_query_name}/{version}"}) @PostAuthorize("checkAbacPostQuery(@requestAwareAuditResultMapHolder.getAuditResultMap())") @SuppressWarnings("unchecked") From 62119d6c30d6cc420735f0bcdfe0b2b9f9c9ebeb Mon Sep 17 00:00:00 2001 From: MBA Date: Mon, 31 Jul 2023 13:10:47 +0200 Subject: [PATCH 23/53] Removed all XACML/Security logic --- rest-ehr-scape/pom.xml | 8 ------ .../controller/CompositionController.java | 7 ++--- .../ehrscape/controller/EhrController.java | 7 ++--- .../ehrscape/controller/QueryController.java | 4 +-- .../controller/TemplateController.java | 7 ++--- rest-openehr/pom.xml | 9 ------- .../ehrbase/rest/DefaultExceptionHandler.java | 10 +++---- .../org/ehrbase/rest/StatusController.java | 4 +-- .../admin/AdminCompositionController.java | 7 +++-- .../admin/AdminContributionController.java | 9 +++---- .../ehrbase/rest/admin/AdminController.java | 7 +++-- .../rest/admin/AdminDirectoryController.java | 7 +++-- .../rest/admin/AdminEhrController.java | 9 +++---- .../rest/admin/AdminTemplateController.java | 13 +++------- .../openehr/OpenehrCompositionController.java | 7 ++--- .../OpenehrContributionController.java | 5 ++-- .../OpenehrDefinitionQueryController.java | 13 +++++----- .../openehr/OpenehrDirectoryController.java | 8 ++---- .../rest/openehr/OpenehrEhrController.java | 18 ++----------- .../openehr/OpenehrEhrStatusController.java | 6 ++--- .../rest/openehr/OpenehrQueryController.java | 26 +++---------------- .../openehr/OpenehrTemplateController.java | 15 ++--------- ...OpenehrVersionedCompositionController.java | 8 +++--- .../OpenehrVersionedEhrStatusController.java | 7 ++--- 24 files changed, 61 insertions(+), 160 deletions(-) diff --git a/rest-ehr-scape/pom.xml b/rest-ehr-scape/pom.xml index 4562197dd..66bec62e6 100644 --- a/rest-ehr-scape/pom.xml +++ b/rest-ehr-scape/pom.xml @@ -38,14 +38,6 @@ - - - org.ehrbase - ehrbase-custom-xacml-authorization - 1.1.0-SNAPSHOT - provided - - org.springframework.boot spring-boot-starter-web diff --git a/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/CompositionController.java b/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/CompositionController.java index 63009af36..81a97e3fe 100644 --- a/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/CompositionController.java +++ b/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/CompositionController.java @@ -19,7 +19,6 @@ import static org.ehrbase.rest.ehrscape.controller.BaseController.API_ECIS_CONTEXT_PATH_WITH_VERSION; -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; import com.nedap.archie.rm.support.identification.ObjectVersionId; import java.net.URI; import java.util.Objects; @@ -39,6 +38,7 @@ import org.ehrbase.rest.ehrscape.responsedata.CompositionWriteRestResponseData; import org.ehrbase.rest.ehrscape.responsedata.Meta; import org.ehrbase.rest.ehrscape.responsedata.RestHref; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; @@ -51,6 +51,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +@ConditionalOnMissingBean(value = {CompositionController.class}) @TenantAware @RestController @RequestMapping( @@ -64,7 +65,6 @@ public CompositionController(CompositionService compositionService) { this.compositionService = Objects.requireNonNull(compositionService); } - @Scope(scope = "ehrbase:composition:create") @PostMapping public ResponseEntity createComposition( @RequestParam(value = "format", defaultValue = "XML") CompositionFormat format, @@ -96,7 +96,6 @@ public ResponseEntity createComposition( .body(responseData); } - @Scope(scope = "ehrbase:composition:read") @GetMapping(path = "/{uid}") public ResponseEntity getComposition( @PathVariable("uid") String compositionUid, @@ -135,7 +134,6 @@ public ResponseEntity getComposition( } } - @Scope(scope = "ehrbase:composition:update") @PutMapping(path = "/{uid}") public ResponseEntity update( @PathVariable("uid") String compositionUid, @@ -169,7 +167,6 @@ public ResponseEntity update( return ResponseEntity.ok(responseData); } - @Scope(scope = "ehrbase:composition:delete") @DeleteMapping(path = "/{uid}") public ResponseEntity delete(@PathVariable("uid") String compositionUid) { diff --git a/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/EhrController.java b/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/EhrController.java index 0dbd600ed..1bc552e40 100644 --- a/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/EhrController.java +++ b/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/EhrController.java @@ -19,7 +19,6 @@ import static org.ehrbase.rest.ehrscape.controller.BaseController.API_ECIS_CONTEXT_PATH_WITH_VERSION; -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.nedap.archie.rm.datavalues.DvText; @@ -43,6 +42,7 @@ import org.ehrbase.rest.ehrscape.responsedata.EhrResponseData; import org.ehrbase.rest.ehrscape.responsedata.Meta; import org.ehrbase.rest.ehrscape.responsedata.RestHref; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -63,6 +63,7 @@ * @author Stefan Spiska * @author Jake Smolka */ +@ConditionalOnMissingBean(value = {EhrController.class}) @TenantAware @RestController @RequestMapping(path = API_ECIS_CONTEXT_PATH_WITH_VERSION + "/ehr") @@ -78,7 +79,6 @@ public EhrController(EhrService ehrService) { this.ehrService = Objects.requireNonNull(ehrService); } - @Scope(scope = "ehrbase:ehr:create") @PostMapping @ResponseStatus(value = HttpStatus.CREATED) // overwrites default 200, fixes the wrong listing of 200 in swagger-ui (EHR-56) @@ -114,7 +114,6 @@ public ResponseEntity createEhr( .orElse(ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build()); } - @Scope(scope = "ehrbase:ehr:read") @GetMapping public ResponseEntity getEhr( @RequestParam(value = "subjectId") String subjectId, @@ -127,7 +126,6 @@ public ResponseEntity getEhr( .orElse(ResponseEntity.noContent().build()); } - @Scope(scope = "ehrbase:ehr:read") @GetMapping(path = "/{uuid}") public ResponseEntity getEhr( @PathVariable("uuid") UUID ehrId, @@ -139,7 +137,6 @@ public ResponseEntity getEhr( .orElse(ResponseEntity.notFound().build()); } - @Scope(scope = "ehrbase:ehr:update_status") @PutMapping(path = "/{uuid}/status") public ResponseEntity updateStatus( @PathVariable("uuid") UUID ehrId, diff --git a/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/QueryController.java b/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/QueryController.java index 432d15141..b58203cd3 100644 --- a/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/QueryController.java +++ b/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/QueryController.java @@ -17,7 +17,6 @@ */ package org.ehrbase.rest.ehrscape.controller; -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; import java.util.HashMap; import java.util.Objects; import java.util.regex.Matcher; @@ -28,6 +27,7 @@ import org.ehrbase.rest.ehrscape.responsedata.Action; import org.ehrbase.rest.ehrscape.responsedata.QueryResponseData; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; @@ -36,6 +36,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +@ConditionalOnMissingBean(value = {QueryController.class}) @TenantAware @RestController @RequestMapping( @@ -50,7 +51,6 @@ public QueryController(QueryService queryService) { this.queryService = Objects.requireNonNull(queryService); } - @Scope(scope = "ehrbase:query:search_ad_hoc") @PostMapping public ResponseEntity query( @RequestParam(value = "explain", defaultValue = "false") Boolean explain, @RequestBody String content) { diff --git a/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/TemplateController.java b/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/TemplateController.java index ad4027d54..422099e15 100644 --- a/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/TemplateController.java +++ b/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/TemplateController.java @@ -20,7 +20,6 @@ import static org.ehrbase.rest.ehrscape.controller.BaseController.API_ECIS_CONTEXT_PATH_WITH_VERSION; import static org.ehrbase.rest.ehrscape.controller.BaseController.TEMPLATE; -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; import com.nedap.archie.rm.composition.Composition; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -42,6 +41,7 @@ import org.ehrbase.rest.ehrscape.responsedata.TemplatesResponseData; import org.openehr.schemas.v1.TemplateDocument; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; @@ -52,6 +52,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +@ConditionalOnMissingBean(value = {TemplateController.class}) @TenantAware @RestController @RequestMapping( @@ -68,7 +69,6 @@ public TemplateController(TemplateService templateService, CompositionService co this.compositionService = Objects.requireNonNull(compositionService); } - @Scope(scope = "ehrbase:template:read") @GetMapping() public ResponseEntity getTemplate() { TemplatesResponseData responseData = new TemplatesResponseData(); @@ -77,7 +77,6 @@ public ResponseEntity getTemplate() { return ResponseEntity.ok(responseData); } - @Scope(scope = "ehrbase:template:create") @PostMapping() public ResponseEntity createTemplate(@RequestBody() String content) { @@ -96,7 +95,6 @@ public ResponseEntity createTemplate(@RequestBody() Strin return ResponseEntity.ok(responseData); } - @Scope(scope = "ehrbase:template:example") @GetMapping(path = "/{templateId}/example") public ResponseEntity getTemplateExample( @PathVariable(value = "templateId") String templateId, @@ -117,7 +115,6 @@ public ResponseEntity getTemplateExample( return ResponseEntity.ok().contentType(contentType).body(serialized.getValue()); } - @Scope(scope = "ehrbase:template:read") @GetMapping(path = "/{templateId}") public ResponseEntity getTemplate(@PathVariable(value = "templateId") String templateId) { TemplateResponseData responseData = new TemplateResponseData(); diff --git a/rest-openehr/pom.xml b/rest-openehr/pom.xml index 6f97e473a..706bf243b 100644 --- a/rest-openehr/pom.xml +++ b/rest-openehr/pom.xml @@ -39,15 +39,6 @@ - - - org.ehrbase - ehrbase-custom-xacml-authorization - 1.1.0-SNAPSHOT - provided - - - org.springframework.boot spring-boot-starter-web diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/DefaultExceptionHandler.java b/rest-openehr/src/main/java/org/ehrbase/rest/DefaultExceptionHandler.java index a893786ae..d17ecc8af 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/DefaultExceptionHandler.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/DefaultExceptionHandler.java @@ -17,7 +17,6 @@ */ package org.ehrbase.rest; -import ag.vitagroup.hip.cdr.authorization.xacml.eval.AccessCtrlException; import java.net.URI; import java.util.HashMap; import java.util.Map; @@ -37,7 +36,6 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.http.converter.HttpMessageNotReadableException; -import org.springframework.security.access.AccessDeniedException; import org.springframework.validation.BindException; import org.springframework.web.HttpMediaTypeNotAcceptableException; import org.springframework.web.HttpMediaTypeNotSupportedException; @@ -80,10 +78,10 @@ public ResponseEntity handleBadRequestExceptions(Exception ex) { return handleExceptionInternal(ex, ex.getMessage(), new HttpHeaders(), HttpStatus.BAD_REQUEST); } - @ExceptionHandler({AccessDeniedException.class, AccessCtrlException.class}) - public ResponseEntity handleObjectNotFoundException(Exception ex) { - return handleExceptionInternal(ex, ex.getMessage(), new HttpHeaders(), HttpStatus.FORBIDDEN); - } + // @ExceptionHandler({AccessDeniedException.class, AccessCtrlException.class}) + // public ResponseEntity handleObjectNotFoundException(Exception ex) { + // return handleExceptionInternal(ex, ex.getMessage(), new HttpHeaders(), HttpStatus.FORBIDDEN); + // } // 404 @ExceptionHandler(ObjectNotFoundException.class) diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/StatusController.java b/rest-openehr/src/main/java/org/ehrbase/rest/StatusController.java index 122457f04..5c56c6573 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/StatusController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/StatusController.java @@ -17,7 +17,6 @@ */ package org.ehrbase.rest; -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.headers.Header; @@ -30,6 +29,7 @@ import org.ehrbase.api.service.StatusService; import org.ehrbase.openehr.sdk.response.dto.StatusResponseData; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -44,6 +44,7 @@ * API endpoint to get status of EHRbase and version information on used dependencies as archie or openEHR_sdk as well * as the current used JVM version or target PostgreSQL server version. */ +@ConditionalOnMissingBean(value = {StatusController.class}) @Tag(name = "Status", description = "Heartbeat, Version info, Status") @RestController @RequestMapping( @@ -58,7 +59,6 @@ public StatusController(StatusService statusService) { this.statusService = Objects.requireNonNull(statusService); } - @Scope(scope = "ehrbase:system:read") @GetMapping(path = "/status") @Operation(summary = "Get status information on running EHRbase server instance") @ApiResponses( diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminCompositionController.java b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminCompositionController.java index 1e614b86f..d840a1eda 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminCompositionController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminCompositionController.java @@ -17,7 +17,6 @@ */ package org.ehrbase.rest.admin; -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.headers.Header; import io.swagger.v3.oas.annotations.media.Schema; @@ -34,6 +33,7 @@ import org.ehrbase.openehr.sdk.response.dto.admin.AdminDeleteResponseData; import org.ehrbase.rest.BaseController; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -46,9 +46,10 @@ /** * Admin API controller for Composition related data. Provides endpoint to remove compositions physically from database. */ +@ConditionalOnMissingBean(value = {AdminCompositionController.class}) +@ConditionalOnProperty(prefix = "admin-api", name = "active") @TenantAware @Tag(name = "Admin - Composition") -@ConditionalOnProperty(prefix = "admin-api", name = "active") @RestController @RequestMapping( path = BaseController.ADMIN_API_CONTEXT_PATH + "/ehr", @@ -64,8 +65,6 @@ public AdminCompositionController(EhrService ehrService, CompositionService comp this.compositionService = Objects.requireNonNull(compositionService); } - @Scope(scope = "ehrbase:admin:access") - @Scope(scope = "ehrbase:composition:delete") @DeleteMapping(path = "/{ehr_id}/composition/{composition_id}") @ApiResponses( value = { diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminContributionController.java b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminContributionController.java index 9646d7b26..84ebd6a8f 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminContributionController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminContributionController.java @@ -20,7 +20,6 @@ import static org.apache.commons.lang3.StringUtils.EMPTY; import static org.springframework.web.util.UriComponentsBuilder.fromPath; -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.headers.Header; import io.swagger.v3.oas.annotations.media.Schema; @@ -37,6 +36,7 @@ import org.ehrbase.openehr.sdk.response.dto.admin.AdminUpdateResponseData; import org.ehrbase.rest.BaseController; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -50,9 +50,10 @@ * Admin API controller for Contribution related data. Provides endpoints to update and remove Contributions in * database physically. */ +@ConditionalOnMissingBean(value = {AdminContributionController.class}) +@ConditionalOnProperty(prefix = "admin-api", name = "active") @TenantAware @Tag(name = "Admin - Contribution") -@ConditionalOnProperty(prefix = "admin-api", name = "active") @RestController @RequestMapping( path = "${admin-api.context-path:/rest/admin}/ehr", @@ -68,8 +69,6 @@ public AdminContributionController(EhrService ehrService, ContributionService co this.contributionService = contributionService; } - @Scope(scope = "ehrbase:admin:access") - @Scope(scope = "ehrbase:contribution:update") @PutMapping( path = "/{ehr_id}/contribution/{contribution_id}", consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE}) @@ -115,8 +114,6 @@ public ResponseEntity updateContribution( return ResponseEntity.ok().body(new AdminUpdateResponseData(0)); } - @Scope(scope = "ehrbase:admin:access") - @Scope(scope = "ehrbase:contribution:delete") @DeleteMapping(path = "/{ehr_id}/contribution/{contribution_id}") @ApiResponses( value = { diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminController.java b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminController.java index 14e515a8b..6d7e1eb97 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminController.java @@ -17,7 +17,6 @@ */ package org.ehrbase.rest.admin; -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; import io.swagger.v3.oas.annotations.headers.Header; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; @@ -26,6 +25,7 @@ import org.ehrbase.api.annotations.TenantAware; import org.ehrbase.openehr.sdk.response.dto.admin.AdminStatusResponseData; import org.ehrbase.rest.BaseController; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -33,17 +33,16 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +@ConditionalOnMissingBean(value = {AdminController.class}) +@ConditionalOnProperty(prefix = "admin-api", name = "active") @TenantAware @Tag(name = "Admin - Heartbeat") -@ConditionalOnProperty(prefix = "admin-api", name = "active") @RestController @RequestMapping( path = "${admin-api.context-path:/rest/admin}", produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE}) public class AdminController extends BaseController { - @Scope(scope = "ehrbase:admin:access") - @Scope(scope = "ehrbase:system:read") @GetMapping(path = "/status") @ApiResponses( value = { diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminDirectoryController.java b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminDirectoryController.java index f9af8f8b5..84761dc13 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminDirectoryController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminDirectoryController.java @@ -19,7 +19,6 @@ import static org.springframework.web.util.UriComponentsBuilder.fromPath; -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.headers.Header; import io.swagger.v3.oas.annotations.media.Schema; @@ -33,6 +32,7 @@ import org.ehrbase.openehr.sdk.response.dto.admin.AdminDeleteResponseData; import org.ehrbase.rest.BaseController; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -44,9 +44,10 @@ /** * Admin API controller for directories. Provides endpoint to remove complete directory trees from database physically. */ +@ConditionalOnMissingBean(value = {AdminDirectoryController.class}) +@ConditionalOnProperty(prefix = "admin-api", name = "active") @TenantAware @Tag(name = "Admin - Directory") -@ConditionalOnProperty(prefix = "admin-api", name = "active") @RestController @RequestMapping( path = "${admin-api.context-path:/rest/admin}/ehr", @@ -61,8 +62,6 @@ public AdminDirectoryController(DirectoryService directoryService) { this.directoryService = directoryService; } - @Scope(scope = "ehrbase:admin:access") - @Scope(scope = "ehrbase:directory:delete") @DeleteMapping(path = "/{ehr_id}/directory/{directory_id}") @ApiResponses( value = { diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminEhrController.java b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminEhrController.java index 462ac6042..4870c468d 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminEhrController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminEhrController.java @@ -17,7 +17,6 @@ */ package org.ehrbase.rest.admin; -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.headers.Header; import io.swagger.v3.oas.annotations.media.Schema; @@ -36,6 +35,7 @@ import org.ehrbase.openehr.sdk.response.dto.admin.AdminUpdateResponseData; import org.ehrbase.rest.BaseController; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; @@ -50,9 +50,10 @@ /** * Admin API controller for EHR related endpoints. Provides methods to update and delete EHRs physically in the DB. */ +@ConditionalOnMissingBean(value = {AdminEhrController.class}) +@ConditionalOnProperty(prefix = "admin-api", name = "active") @TenantAware @Tag(name = "Admin - EHR") -@ConditionalOnProperty(prefix = "admin-api", name = "active") @RestController @RequestMapping( path = BaseController.ADMIN_API_CONTEXT_PATH + "/ehr", @@ -66,8 +67,6 @@ public AdminEhrController(EhrService ehrService) { this.ehrService = ehrService; } - @Scope(scope = "ehrbase:admin:access") - @Scope(scope = "ehrbase:ehr:update") @PutMapping( path = "/{ehr_id}", consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE}) @@ -111,8 +110,6 @@ public ResponseEntity updateEhr( return ResponseEntity.ok().body(new AdminUpdateResponseData(0)); } - @Scope(scope = "ehrbase:admin:access") - @Scope(scope = "ehrbase:ehr:delete") @DeleteMapping(path = "/{ehr_id}") @ApiResponses( value = { diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminTemplateController.java b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminTemplateController.java index 49ad3f6f4..bc34581c6 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminTemplateController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminTemplateController.java @@ -17,7 +17,6 @@ */ package org.ehrbase.rest.admin; -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.headers.Header; import io.swagger.v3.oas.annotations.media.Schema; @@ -30,6 +29,7 @@ import org.ehrbase.openehr.sdk.response.dto.admin.AdminStatusResponseData; import org.ehrbase.rest.BaseController; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -46,9 +46,10 @@ /** * Admin API controller for Templates. Provides endpoints to update (replace) and delete templates. */ +@ConditionalOnMissingBean(value = {AdminTemplateController.class}) +@ConditionalOnProperty(prefix = "admin-api", name = "active") @TenantAware @Tag(name = "Admin - Template") -@ConditionalOnProperty(prefix = "admin-api", name = "active") @RestController @RequestMapping( path = "${admin-api.context-path:/rest/admin}/template", @@ -58,15 +59,13 @@ public class AdminTemplateController extends BaseController { TemplateService templateService; @Autowired - AdminTemplateController(TemplateService templateService) { + public AdminTemplateController(TemplateService templateService) { this.templateService = templateService; } @Autowired AdminApiConfiguration adminApiConfiguration; - @Scope(scope = "ehrbase:admin:access") - @Scope(scope = "ehrbase:template:update") @PutMapping( path = "/{template_id}", consumes = {MediaType.APPLICATION_XML_VALUE}, @@ -110,8 +109,6 @@ public ResponseEntity updateTemplate( return ResponseEntity.ok().headers(headers).body(updatedTemplate); } - @Scope(scope = "ehrbase:admin:access") - @Scope(scope = "ehrbase:template:delete") @DeleteMapping(path = "/{template_id}") @ApiResponses( value = { @@ -135,8 +132,6 @@ public ResponseEntity deleteTemplate( return ResponseEntity.ok().body(new AdminDeleteResponseData(deleted)); } - @Scope(scope = "ehrbase:admin:access") - @Scope(scope = "ehrbase:template:delete") @DeleteMapping(path = "/all") @ApiResponses( value = { diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrCompositionController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrCompositionController.java index 0945eb997..e1c3532e4 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrCompositionController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrCompositionController.java @@ -20,7 +20,6 @@ import static org.apache.commons.lang3.StringUtils.unwrap; import static org.springframework.web.util.UriComponentsBuilder.fromPath; -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; import com.nedap.archie.rm.composition.Composition; import com.nedap.archie.rm.support.identification.ObjectId; import com.nedap.archie.rm.support.identification.ObjectVersionId; @@ -50,6 +49,7 @@ import org.ehrbase.rest.openehr.specification.CompositionApiSpecification; import org.ehrbase.rest.util.InternalResponse; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -75,6 +75,7 @@ * @author Jake Smolka * @since 1.0.0 */ +@ConditionalOnMissingBean(value = {OpenehrCompositionController.class, CompositionApiSpecification.class}) @TenantAware @RestController @RequestMapping( @@ -89,7 +90,6 @@ public OpenehrCompositionController(CompositionService compositionService) { this.compositionService = Objects.requireNonNull(compositionService); } - @Scope(scope = "ehrbase:composition:create") @PostMapping( value = "/{ehr_id}/composition", consumes = {"application/xml", "application/json"}) @@ -155,7 +155,6 @@ public ResponseEntity createComposition( .orElse(ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build()); } - @Scope(scope = "ehrbase:composition:create") @PutMapping("/{ehr_id}/composition/{versioned_object_uid}") // checkAbacPre /-Post attributes (type, subject, payload, content type) @PreAuthorize("checkAbacPre(@openehrCompositionController.COMPOSITION, " @@ -251,7 +250,6 @@ public ResponseEntity updateComposition( .orElse(ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build()); } - @Scope(scope = "ehrbase:composition:delete") @DeleteMapping("/{ehr_id}/composition/{preceding_version_uid}") // checkAbacPre /-Post attributes (type, subject, payload, content type) @PreAuthorize("checkAbacPre(@openehrCompositionController.COMPOSITION, " @@ -330,7 +328,6 @@ public ResponseEntity deleteComposition( * because of the overlapping paths. Both mappings are specified to behave almost the same, so * this solution works in this case. */ - @Scope(scope = "ehrbase:composition:read") @GetMapping("/{ehr_id}/composition/{versioned_object_uid}") // checkAbacPre /-Post attributes (type, subject, payload, content type) @PostAuthorize("checkAbacPost(@openehrCompositionController.COMPOSITION, " diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrContributionController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrContributionController.java index 5b95738c9..cd6ce4fb0 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrContributionController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrContributionController.java @@ -20,7 +20,6 @@ import static org.apache.commons.lang3.StringUtils.EMPTY; import static org.springframework.web.util.UriComponentsBuilder.fromPath; -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; import com.nedap.archie.rm.support.identification.HierObjectId; import com.nedap.archie.rm.support.identification.ObjectRef; import com.nedap.archie.rm.support.identification.ObjectVersionId; @@ -43,6 +42,7 @@ import org.ehrbase.rest.openehr.specification.ContributionApiSpecification; import org.ehrbase.rest.util.InternalResponse; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -57,6 +57,7 @@ import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; +@ConditionalOnMissingBean(value = {OpenehrContributionController.class, ContributionApiSpecification.class}) @TenantAware @RestController @RequestMapping( @@ -71,7 +72,6 @@ public OpenehrContributionController(ContributionService contributionService) { this.contributionService = Objects.requireNonNull(contributionService); } - @Scope(scope = "ehrbase:contribution:create") @PostMapping( value = "/{ehr_id}/contribution", consumes = {"application/xml", "application/json"}) @@ -132,7 +132,6 @@ public ResponseEntity createContribution( .orElse(ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build()); } - @Scope(scope = "ehrbase:contribution:read") @GetMapping(value = "/{ehr_id}/contribution/{contribution_uid}") @Override public ResponseEntity getContribution( diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDefinitionQueryController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDefinitionQueryController.java index 702b5e5fc..0ad0c2afd 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDefinitionQueryController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDefinitionQueryController.java @@ -18,10 +18,13 @@ package org.ehrbase.rest.openehr; import static org.apache.commons.lang3.StringUtils.isBlank; -import static org.springframework.http.MediaType.*; +import static org.springframework.http.MediaType.APPLICATION_JSON; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; +import static org.springframework.http.MediaType.APPLICATION_XML_VALUE; +import static org.springframework.http.MediaType.TEXT_PLAIN; +import static org.springframework.http.MediaType.TEXT_PLAIN_VALUE; import static org.springframework.web.util.UriComponentsBuilder.fromPath; -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; @@ -42,6 +45,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -57,6 +61,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +@ConditionalOnMissingBean(value = {OpenehrDefinitionQueryController.class, DefinitionQueryApiSpecification.class}) @TenantAware @RestController @RequestMapping( @@ -87,7 +92,6 @@ public OpenehrDefinitionQueryController(QueryService queryService) { */ @Override @GetMapping(value = {"/{qualified_query_name}", ""}) - @Scope(scope = "ehrbase:query:read") public ResponseEntity getStoredQueryList( @RequestHeader(value = ACCEPT, required = false) String accept, @PathVariable(value = "qualified_query_name", required = false) String qualifiedQueryName) { @@ -104,7 +108,6 @@ public ResponseEntity getStoredQueryList( @Override @GetMapping(value = {"/{qualified_query_name}/{version}"}) - @Scope(scope = "ehrbase:query:read") public ResponseEntity getStoredQueryVersion( @RequestHeader(value = ACCEPT, required = false) String accept, @PathVariable(value = "qualified_query_name") String qualifiedQueryName, @@ -123,7 +126,6 @@ public ResponseEntity getStoredQueryVersion( } @Override - @Scope(scope = "ehrbase:query:create") @PutMapping( value = {"/{qualified_query_name}/{version}", "/{qualified_query_name}"}, consumes = {TEXT_PLAIN_VALUE, APPLICATION_JSON_VALUE}, @@ -189,7 +191,6 @@ public ResponseEntity putStoredQuery( @Override @DeleteMapping(value = {"/{qualified_query_name}/{version}"}) - @Scope(scope = "ehrbase:query:delete") public ResponseEntity deleteStoredQuery( @RequestHeader(value = ACCEPT, required = false) String accept, @PathVariable(value = "qualified_query_name") String qualifiedQueryName, diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDirectoryController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDirectoryController.java index 802d4deb4..e58fdc8ce 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDirectoryController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDirectoryController.java @@ -20,7 +20,6 @@ import static org.apache.commons.lang3.StringUtils.unwrap; import static org.springframework.web.util.UriComponentsBuilder.fromPath; -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; import com.nedap.archie.rm.directory.Folder; import com.nedap.archie.rm.support.identification.ObjectVersionId; import java.nio.file.InvalidPathException; @@ -38,6 +37,7 @@ import org.ehrbase.rest.BaseController; import org.ehrbase.rest.openehr.specification.DirectoryApiSpecification; import org.joda.time.DateTime; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; @@ -62,6 +62,7 @@ * @author Renaud Subiger * @since 1.0 */ +@ConditionalOnMissingBean(value = {OpenehrDirectoryController.class, DirectoryApiSpecification.class}) @TenantAware @RestController @RequestMapping(path = BaseController.API_CONTEXT_PATH_WITH_VERSION + "/ehr") @@ -76,7 +77,6 @@ public OpenehrDirectoryController(DirectoryService directoryService) { /** * {@inheritDoc} */ - @Scope(scope = "ehrbase:directory:create") @Override @PostMapping(path = "/{ehr_id}/directory") public ResponseEntity createDirectory( @@ -96,7 +96,6 @@ public ResponseEntity createDirectory( /** * {@inheritDoc} */ - @Scope(scope = "ehrbase:directory:update") @Override @PutMapping(path = "/{ehr_id}/directory") public ResponseEntity updateDirectory( @@ -120,7 +119,6 @@ public ResponseEntity updateDirectory( /** * {@inheritDoc} */ - @Scope(scope = "ehrbase:directory:delete") @Override @DeleteMapping(path = "/{ehr_id}/directory") public ResponseEntity deleteDirectory( @@ -141,7 +139,6 @@ public ResponseEntity deleteDirectory( /** * {@inheritDoc} */ - @Scope(scope = "ehrbase:directory:read") @Override @GetMapping(path = "/{ehr_id}/directory/{version_uid}") public ResponseEntity getFolderInDirectory( @@ -182,7 +179,6 @@ private void validateVersionUid(ObjectVersionId versionUid) { } } - @Scope(scope = "ehrbase:directory:read") @Override @GetMapping(path = "/{ehr_id}/directory") public ResponseEntity getFolderInDirectoryVersionAtTime( diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrController.java index 27590d6be..bcaf40431 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrController.java @@ -17,11 +17,6 @@ */ package org.ehrbase.rest.openehr; -import ag.vitagroup.hip.cdr.authorization.annotation.Action; -import ag.vitagroup.hip.cdr.authorization.annotation.ResourceId; -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; -import ag.vitagroup.hip.cdr.authorization.annotation.TenantPolicyLookup; -import ag.vitagroup.hip.cdr.authorization.annotation.XacmlAuthorization; import com.nedap.archie.rm.datavalues.quantity.datetime.DvDateTime; import com.nedap.archie.rm.ehr.EhrStatus; import com.nedap.archie.rm.support.identification.HierObjectId; @@ -44,6 +39,7 @@ import org.ehrbase.rest.openehr.specification.EhrApiSpecification; import org.ehrbase.rest.util.InternalResponse; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -63,8 +59,8 @@ /** * Controller for /ehr resource of openEHR REST API */ +@ConditionalOnMissingBean(value = {OpenehrEhrController.class, EhrApiSpecification.class}) @TenantAware -@TenantPolicyLookup @RestController @RequestMapping( path = BaseController.API_CONTEXT_PATH_WITH_VERSION + "/ehr", @@ -78,10 +74,6 @@ public OpenehrEhrController(EhrService ehrService) { this.ehrService = Objects.requireNonNull(ehrService); } - @Scope(scope = "ehrbase:ehr:create") - @XacmlAuthorization - @Action(action = "method:call:createEhr") - @ResourceId(resourceId = "OpenehrEhrController") @PostMapping // (consumes = {"application/xml", "application/json"}) @ResponseStatus(value = HttpStatus.CREATED) // TODO auditing headers (openehr*) ignored until auditing is implemented @@ -103,10 +95,6 @@ public ResponseEntity createEhr( return internalPostEhrProcessing(accept, prefer, ehrId); } - @Scope(scope = "ehrbase:ehr:create") - @XacmlAuthorization - @Action(action = "method:call:createEhrWithId") - @ResourceId(resourceId = "OpenehrEhrController") @PutMapping(path = "/{ehr_id}") @ResponseStatus(value = HttpStatus.CREATED) public ResponseEntity createEhrWithId( @@ -180,7 +168,6 @@ private void createAuditLogsMsgBuilder(UUID resultEhrId) { /** * Returns EHR by ID */ - @Scope(scope = "ehrbase:ehr:read") @GetMapping(path = "/{ehr_id}") @PreAuthorize("checkAbacPre(@openehrEhrController.EHR, @ehrService.getSubjectExtRef(#ehrIdString))") public ResponseEntity retrieveEhrById( @@ -199,7 +186,6 @@ public ResponseEntity retrieveEhrById( /** * Returns EHR by subject (id and namespace) */ - @Scope(scope = "ehrbase:ehr:read") @GetMapping(params = {"subject_id", "subject_namespace"}) @PreAuthorize("checkAbacPre(@openehrEhrController.EHR, #subjectId)") public ResponseEntity retrieveEhrBySubject( diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrStatusController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrStatusController.java index 91ea4e7bc..58b796124 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrStatusController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrStatusController.java @@ -19,7 +19,6 @@ import static org.apache.commons.lang3.StringUtils.unwrap; -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; import com.nedap.archie.rm.changecontrol.OriginalVersion; import com.nedap.archie.rm.ehr.EhrStatus; import java.net.URI; @@ -41,6 +40,7 @@ import org.ehrbase.rest.BaseController; import org.ehrbase.rest.openehr.specification.EhrStatusApiSpecification; import org.ehrbase.rest.util.InternalResponse; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -62,6 +62,7 @@ * @author Renaud Subiger * @since 1.0 */ +@ConditionalOnMissingBean(value = {OpenehrEhrStatusController.class, EhrStatusApiSpecification.class}) @TenantAware @RestController @RequestMapping(path = BaseController.API_CONTEXT_PATH_WITH_VERSION + "/ehr/{ehr_id}/ehr_status") @@ -78,7 +79,6 @@ public OpenehrEhrStatusController(EhrService ehrService) { */ @Override @GetMapping - @Scope(scope = "ehrbase:ehr:read_status") @PreAuthorize("checkAbacPre(@openehrEhrStatusController.EHR_STATUS, @ehrService.getSubjectExtRef(#ehrId))") public ResponseEntity getEhrStatusVersionByTime( @PathVariable(name = "ehr_id") UUID ehrId, @@ -108,7 +108,6 @@ public ResponseEntity getEhrStatusVersionByTime( */ @Override @GetMapping(path = "/{version_uid}") - @Scope(scope = "ehrbase:ehr:read_status") @PreAuthorize("checkAbacPre(@openehrEhrStatusController.EHR_STATUS, @ehrService.getSubjectExtRef(#ehrId))") public ResponseEntity getEhrStatusByVersionId( @PathVariable(name = "ehr_id") UUID ehrId, @@ -136,7 +135,6 @@ public ResponseEntity getEhrStatusByVersionId( */ @Override @PutMapping - @Scope(scope = "ehrbase:ehr:update_status") @PreAuthorize("checkAbacPre(@openehrEhrStatusController.EHR_STATUS, @ehrService.getSubjectExtRef(#ehrId))") public ResponseEntity updateEhrStatus( @PathVariable("ehr_id") UUID ehrId, diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java index d7d0627c8..76640bf6b 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java @@ -19,13 +19,6 @@ import static org.springframework.web.util.UriComponentsBuilder.fromPath; -import ag.vitagroup.hip.cdr.authorization.annotation.Action; -import ag.vitagroup.hip.cdr.authorization.annotation.ResourceId; -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; -import ag.vitagroup.hip.cdr.authorization.annotation.TenantPolicyLookup; -import ag.vitagroup.hip.cdr.authorization.annotation.XacmlAuthorization; -import ag.vitagroup.hip.cdr.authorization.annotation.XacmlAuthorization.Version; -import ag.vitagroup.hip.cdr.authorization.annotation.XacmlUrlRequestParameter; import java.text.MessageFormat; import java.util.HashMap; import java.util.Map; @@ -46,6 +39,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.http.ResponseEntity; import org.springframework.lang.Nullable; import org.springframework.security.access.prepost.PostAuthorize; @@ -66,8 +60,8 @@ * @author Renaud Subiger * @since 1.0 */ +@ConditionalOnMissingBean(value = {OpenehrQueryController.class, QueryApiSpecification.class}) @TenantAware -@TenantPolicyLookup @RestController @RequestMapping(path = BaseController.API_CONTEXT_PATH_WITH_VERSION + "/query") public class OpenehrQueryController extends BaseController implements QueryApiSpecification { @@ -90,15 +84,10 @@ public OpenehrQueryController(QueryService queryService) { /** * {@inheritDoc} */ - @XacmlAuthorization(version = Version.V2) - @Action(action = "query_aql") - @ResourceId(resourceId = "OpenehrQueryController") - /*@ConstrainAql(constraint = "LimitByFacilityName")*/ - @Scope(scope = "ehrbase:query:search_ad_hoc") @GetMapping(path = "/aql") @PostAuthorize("checkAbacPostQuery(@requestAwareAuditResultMapHolder.getAuditResultMap())") public ResponseEntity executeAdHocQuery( - @XacmlUrlRequestParameter("aql_query") @RequestParam(name = "q") String query, + @RequestParam(name = "q") String query, @RequestParam(name = "offset", required = false) Integer offset, @RequestParam(name = "fetch", required = false) Integer fetch, @RequestParam(name = "query_parameters", required = false) Map queryParameters, @@ -128,16 +117,11 @@ public ResponseEntity executeAdHocQuery( /** * {@inheritDoc} */ - @XacmlAuthorization(version = Version.V2) - @Action(action = "query_aql") - @ResourceId(resourceId = "OpenehrQueryController") - /*@ConstrainAql(constraint = "LimitByFacilityName")*/ - @Scope(scope = "ehrbase:query:search_ad_hoc") @PostMapping(path = "/aql") @PostAuthorize("checkAbacPostQuery(@requestAwareAuditResultMapHolder.getAuditResultMap())") @SuppressWarnings("unchecked") public ResponseEntity executeAdHocQuery( - @XacmlUrlRequestParameter("aql_query") @RequestBody Map queryRequest, + @RequestBody Map queryRequest, @RequestHeader(name = ACCEPT, required = false) String accept, @RequestHeader(name = CONTENT_TYPE) String contentType) { @@ -161,7 +145,6 @@ public ResponseEntity executeAdHocQuery( /** * {@inheritDoc} */ - @Scope(scope = "ehrbase:query:search") @GetMapping(path = {"/{qualified_query_name}", "/{qualified_query_name}/{version}"}) @PostAuthorize("checkAbacPostQuery(@requestAwareAuditResultMapHolder.getAuditResultMap())") public ResponseEntity executeStoredQuery( @@ -208,7 +191,6 @@ public ResponseEntity executeStoredQuery( /** * {@inheritDoc} */ - @Scope(scope = "ehrbase:query:search") @PostMapping(path = {"/{qualified_query_name}", "/{qualified_query_name}/{version}"}) @PostAuthorize("checkAbacPostQuery(@requestAwareAuditResultMapHolder.getAuditResultMap())") @SuppressWarnings("unchecked") diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrTemplateController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrTemplateController.java index b65b6b6b3..c9581a4c3 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrTemplateController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrTemplateController.java @@ -20,10 +20,6 @@ import static org.springframework.http.MediaType.APPLICATION_JSON; import static org.springframework.http.MediaType.APPLICATION_XML; -import ag.vitagroup.hip.cdr.authorization.annotation.Action; -import ag.vitagroup.hip.cdr.authorization.annotation.ResourceId; -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; -import ag.vitagroup.hip.cdr.authorization.annotation.XacmlAuthorization; import com.nedap.archie.rm.composition.Composition; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -54,6 +50,7 @@ import org.ehrbase.rest.util.InternalResponse; import org.openehr.schemas.v1.TemplateDocument; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -71,6 +68,7 @@ /** * Controller for /template resource as part of the Definitions sub-API of the openEHR REST API */ +@ConditionalOnMissingBean(value = {OpenehrTemplateController.class, TemplateApiSpecification.class}) @TenantAware @RestController @RequestMapping( @@ -95,7 +93,6 @@ public OpenehrTemplateController(TemplateService templateService, CompositionSer path = "/adl1.4", produces = {MediaType.APPLICATION_XML_VALUE}) @ResponseStatus(value = HttpStatus.CREATED) - @Scope(scope = "ehrbase:template:create") public ResponseEntity createTemplateClassic( @RequestHeader(value = "openEHR-VERSION", required = false) String openehrVersion, // TODO, see EHR-267 @RequestHeader(value = "openEHR-AUDIT_DETAILS", required = false) @@ -156,10 +153,6 @@ public ResponseEntity createTemplateClassic( // Note: based on latest-branch of 1.1.0 release of openEHR REST API, because this endpoint was changed // significantly @GetMapping("/adl1.4") - @XacmlAuthorization - @Action(action = "method:call:getTemplatesClassic") - @ResourceId(resourceId = "OpenehrTemplateController") - @Scope(scope = "ehrbase:template:read") public ResponseEntity getTemplatesClassic( @RequestHeader(value = "openEHR-VERSION", required = false) String openehrVersion, // TODO, see EHR-267 @RequestHeader(value = "openEHR-AUDIT_DETAILS", required = false) @@ -186,7 +179,6 @@ public ResponseEntity getTemplatesClassic( // Note: based on latest-branch of 1.1.0 release of openEHR REST API, because this endpoint was changed // significantly @GetMapping("/adl1.4/{template_id}") - @Scope(scope = "ehrbase:template:read") public ResponseEntity getTemplateClassic( @RequestHeader(value = "openEHR-VERSION", required = false) String openehrVersion, // TODO, see EHR-267 @RequestHeader(value = "openEHR-AUDIT_DETAILS", required = false) @@ -212,7 +204,6 @@ public ResponseEntity getTemplateClassic( } @GetMapping(path = "/adl1.4/{template_id}/example") - @Scope(scope = "ehrbase:template:example") public ResponseEntity getTemplateExample( @RequestHeader(value = ACCEPT, required = false) String accept, @PathVariable(value = "template_id") String templateId) { @@ -240,7 +231,6 @@ public ResponseEntity getTemplateExample( */ @PostMapping("/adl2") @ResponseStatus(value = HttpStatus.CREATED) - @Scope(scope = "ehrbase:template:create") public ResponseEntity createTemplateNew( @RequestHeader(value = "openEHR-VERSION", required = false) String openehrVersion, // TODO, see EHR-267 @RequestHeader(value = "openEHR-AUDIT_DETAILS", required = false) @@ -275,7 +265,6 @@ public ResponseEntity createTemplateNew( // also, this endpoint combines what is listed as two endpoints: // https://specifications.openehr.org/releases/ITS-REST/latest/definitions.html#definitions-adl-2-template-get @GetMapping("/adl2/{template_id}/{version_pattern}") - @Scope(scope = "ehrbase:template:read") public ResponseEntity getTemplateNew( @RequestHeader(value = "openEHR-VERSION", required = false) String openehrVersion, // TODO, see EHR-267 @RequestHeader(value = "openEHR-AUDIT_DETAILS", required = false) diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrVersionedCompositionController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrVersionedCompositionController.java index f949b8c2a..448f03468 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrVersionedCompositionController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrVersionedCompositionController.java @@ -21,7 +21,6 @@ import static org.ehrbase.rest.BaseController.VERSIONED_COMPOSITION; import static org.springframework.web.util.UriComponentsBuilder.fromPath; -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; import com.nedap.archie.rm.changecontrol.OriginalVersion; import com.nedap.archie.rm.composition.Composition; import com.nedap.archie.rm.ehr.VersionedComposition; @@ -46,6 +45,7 @@ import org.ehrbase.rest.BaseController; import org.ehrbase.rest.openehr.specification.VersionedCompositionApiSpecification; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; @@ -62,6 +62,8 @@ /** * Controller for /ehr/{ehrId}/versioned_composition resource of openEHR REST API */ +@ConditionalOnMissingBean( + value = {OpenehrVersionedCompositionController.class, VersionedCompositionApiSpecification.class}) @TenantAware @RestController @RequestMapping( @@ -82,7 +84,6 @@ public OpenehrVersionedCompositionController( this.contributionService = Objects.requireNonNull(contributionService); } - @Scope(scope = "ehrbase:composition:read") @GetMapping(path = "/{versioned_object_uid}") @Override public ResponseEntity> retrieveVersionedCompositionByVersionedObjectUid( @@ -110,7 +111,6 @@ public ResponseEntity> retrieveVersione return ResponseEntity.ok().headers(respHeaders).body(response); } - @Scope(scope = "ehrbase:composition:read") @GetMapping(path = "/{versioned_object_uid}/revision_history") @Override public ResponseEntity retrieveVersionedCompositionRevisionHistoryByEhr( @@ -138,7 +138,6 @@ public ResponseEntity retrieveVersionedCompositionR return ResponseEntity.ok().headers(respHeaders).body(response); } - @Scope(scope = "ehrbase:composition:read") @GetMapping(path = "/{versioned_object_uid}/version/{version_uid}") // checkAbacPre /-Post attributes (type, subject, payload, content type) @PostAuthorize("checkAbacPost(@openehrVersionedCompositionController.COMPOSITION, " @@ -179,7 +178,6 @@ public ResponseEntity> retrieveVersionO return getOriginalVersionResponseDataResponseEntity(accept, ehrId, versionedObjectId, version); } - @Scope(scope = "ehrbase:composition:read") @GetMapping(path = "/{versioned_object_uid}/version") // checkAbacPre /-Post attributes (type, subject, payload, content type) @PostAuthorize("checkAbacPost(@openehrVersionedCompositionController.COMPOSITION, " diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrVersionedEhrStatusController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrVersionedEhrStatusController.java index 18e30797d..841754bd3 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrVersionedEhrStatusController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrVersionedEhrStatusController.java @@ -17,7 +17,6 @@ */ package org.ehrbase.rest.openehr; -import ag.vitagroup.hip.cdr.authorization.annotation.Scope; import com.nedap.archie.rm.changecontrol.OriginalVersion; import com.nedap.archie.rm.ehr.EhrStatus; import com.nedap.archie.rm.ehr.VersionedEhrStatus; @@ -40,6 +39,7 @@ import org.ehrbase.openehr.sdk.response.dto.ehrscape.ContributionDto; import org.ehrbase.rest.BaseController; import org.ehrbase.rest.openehr.specification.VersionedEhrStatusApiSpecification; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; @@ -55,6 +55,7 @@ /** * Controller for /ehr/{ehrId}/versioned_ehr_status resource of openEHR REST API */ +@ConditionalOnMissingBean(value = {OpenehrVersionedEhrStatusController.class, VersionedEhrStatusApiSpecification.class}) @TenantAware @RestController @RequestMapping( @@ -71,7 +72,6 @@ public OpenehrVersionedEhrStatusController(EhrService ehrService, ContributionSe this.contributionService = Objects.requireNonNull(contributionService); } - @Scope(scope = "ehrbase:ehr:read_status") @GetMapping @Override public ResponseEntity> retrieveVersionedEhrStatusByEhr( @@ -97,7 +97,6 @@ public ResponseEntity> retrieveVersionedE return ResponseEntity.ok().headers(respHeaders).body(response); } - @Scope(scope = "ehrbase:ehr:read_status") @GetMapping(path = "/revision_history") @Override public ResponseEntity retrieveVersionedEhrStatusRevisionHistoryByEhr( @@ -123,7 +122,6 @@ public ResponseEntity retrieveVersionedEhrStatusRev return ResponseEntity.ok().headers(respHeaders).body(response); } - @Scope(scope = "ehrbase:ehr:read_status") @GetMapping(path = "/version") // checkAbacPre /-Post attributes (type, subject, payload, content type) @PreAuthorize("checkAbacPre(@openehrVersionedEhrStatusController.EHR_STATUS, " @@ -174,7 +172,6 @@ public ResponseEntity> retrieveVersionOfE return ResponseEntity.ok().headers(respHeaders).body(originalVersionResponseData); } - @Scope(scope = "ehrbase:ehr:read_status") @GetMapping(path = "/version/{version_uid}") // checkAbacPre /-Post attributes (type, subject, payload, content type) @PreAuthorize("checkAbacPre(@openehrVersionedEhrStatusController.EHR_STATUS, " From 7052a1e0dfa84eb1f952226e53b596d1a1dd4661 Mon Sep 17 00:00:00 2001 From: MBA Date: Mon, 31 Jul 2023 14:28:24 +0200 Subject: [PATCH 24/53] Change mvn dependency --- plugin/pom.xml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/plugin/pom.xml b/plugin/pom.xml index 041ca6006..09170fcb3 100644 --- a/plugin/pom.xml +++ b/plugin/pom.xml @@ -13,17 +13,24 @@ ../ + 1.1.0-SNAPSHOT + + cdr-xacml-authorization-lib + ag.vitagroup.hip.cdr.authorization + ${cdr-xacml-authorization-lib} + + com.nedap.healthcare.archie openehr-rm From 400766242d301720b13d0e38a2dff3ec9a8fee2e Mon Sep 17 00:00:00 2001 From: MBA Date: Tue, 1 Aug 2023 13:42:33 +0200 Subject: [PATCH 25/53] Changes XACML Impl. custom logic to handle the ehrbase external annotation which enforces xacml checks --- .../api/annotations/EhrbaseSecurity.java | 28 +++++++++++++++++++ plugin/pom.xml | 13 --------- .../security/PluginSecurityConfiguration.java | 9 +++--- 3 files changed, 33 insertions(+), 17 deletions(-) create mode 100644 api/src/main/java/org/ehrbase/api/annotations/EhrbaseSecurity.java diff --git a/api/src/main/java/org/ehrbase/api/annotations/EhrbaseSecurity.java b/api/src/main/java/org/ehrbase/api/annotations/EhrbaseSecurity.java new file mode 100644 index 000000000..3c929fda1 --- /dev/null +++ b/api/src/main/java/org/ehrbase/api/annotations/EhrbaseSecurity.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023 vitasystems GmbH and Hannover Medical School. + * + * This file is part of project EHRbase + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.ehrbase.api.annotations; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +@Retention(RUNTIME) +@Target(ElementType.METHOD) +public @interface EhrbaseSecurity {} diff --git a/plugin/pom.xml b/plugin/pom.xml index 09170fcb3..a126b4bcd 100644 --- a/plugin/pom.xml +++ b/plugin/pom.xml @@ -18,19 +18,6 @@ - - cdr-xacml-authorization-lib - ag.vitagroup.hip.cdr.authorization - ${cdr-xacml-authorization-lib} - - com.nedap.healthcare.archie openehr-rm diff --git a/plugin/src/main/java/org/ehrbase/plugin/security/PluginSecurityConfiguration.java b/plugin/src/main/java/org/ehrbase/plugin/security/PluginSecurityConfiguration.java index ecc5d00f6..a30f9fbb2 100644 --- a/plugin/src/main/java/org/ehrbase/plugin/security/PluginSecurityConfiguration.java +++ b/plugin/src/main/java/org/ehrbase/plugin/security/PluginSecurityConfiguration.java @@ -17,7 +17,7 @@ */ package org.ehrbase.plugin.security; -import ag.vitagroup.hip.cdr.authorization.annotation.XacmlAuthorization; +import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.List; import java.util.Objects; @@ -27,6 +27,7 @@ import org.aspectj.lang.Signature; import org.aspectj.lang.reflect.SourceLocation; import org.aspectj.runtime.internal.AroundClosure; +import org.ehrbase.api.annotations.EhrbaseSecurity; import org.ehrbase.api.annotations.TenantAware; import org.ehrbase.api.aspect.AnnotationAspect; import org.ehrbase.api.aspect.AuthorizationAspect; @@ -131,12 +132,12 @@ public Advisor authorizationAspect() { AuthorizationAspect theAspect = parentCtx.getBean(AuthorizationAspect.class); return new DefaultPointcutAdvisor( - new AnnotationMatchingPointcut(null, XacmlAuthorization.class, true), new AspectAdapter(theAspect) { + new AnnotationMatchingPointcut(null, EhrbaseSecurity.class, true), new AspectAdapter(theAspect) { public Object invoke(MethodInvocation invocation) throws Throwable { Method method = invocation.getMethod(); - XacmlAuthorization annotation = method.getAnnotation(XacmlAuthorization.class); - return getAspect().action(new ProceedingJoinPointAdapter(invocation), List.of(annotation)); + Annotation[] annotations = method.getDeclaredAnnotations(); + return getAspect().action(new ProceedingJoinPointAdapter(invocation), List.of(annotations)); } }); } From c626758468830cdd2c838102ded9f2edb087d58d Mon Sep 17 00:00:00 2001 From: MBA Date: Wed, 2 Aug 2023 13:04:32 +0200 Subject: [PATCH 26/53] cleanup --- .../application-trigger.yml | 9 ----- .../multi-tenant-plugin-1.5.1-SNAPSHOT.jar | Bin 18889 -> 0 bytes application/pom.xml | 13 ------- .../java/org/ehrbase/application/EhrBase.java | 1 - .../application-authorization.properties | 12 ------- .../src/main/resources/application-local.yml | 4 +-- .../src/main/resources/application-xacml.yml | 32 ------------------ .../src/main/resources/application.yml | 2 +- plugin/pom.xml | 1 - .../ehrbase/rest/DefaultExceptionHandler.java | 5 --- 10 files changed, 3 insertions(+), 76 deletions(-) delete mode 100644 application/plugin_config_dir/ehrbase_event_trigger_v1/application-trigger.yml delete mode 100644 application/plugin_dir/multi-tenant-plugin-1.5.1-SNAPSHOT.jar delete mode 100644 application/src/main/resources/application-authorization.properties delete mode 100644 application/src/main/resources/application-xacml.yml diff --git a/application/plugin_config_dir/ehrbase_event_trigger_v1/application-trigger.yml b/application/plugin_config_dir/ehrbase_event_trigger_v1/application-trigger.yml deleted file mode 100644 index 253195334..000000000 --- a/application/plugin_config_dir/ehrbase_event_trigger_v1/application-trigger.yml +++ /dev/null @@ -1,9 +0,0 @@ -spring: - rabbitmq: - host: 127.0.0.1 - port: 5672 - username: guest - password: guest - -eventtrigger: - workers: 1 diff --git a/application/plugin_dir/multi-tenant-plugin-1.5.1-SNAPSHOT.jar b/application/plugin_dir/multi-tenant-plugin-1.5.1-SNAPSHOT.jar deleted file mode 100644 index d22249bbe8cf388650cfc0e9132e0b3d6fc41cf1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18889 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 diff --git a/application/pom.xml b/application/pom.xml index 5985bdfe6..50b9c58bd 100644 --- a/application/pom.xml +++ b/application/pom.xml @@ -38,19 +38,6 @@ - - org.ehrbase - ehrbase-custom-xacml-authorization - 1.1.0-SNAPSHOT - - - org.springframework.boot spring-boot-starter-web diff --git a/application/src/main/java/org/ehrbase/application/EhrBase.java b/application/src/main/java/org/ehrbase/application/EhrBase.java index ca2c0cc58..9810a4ec4 100644 --- a/application/src/main/java/org/ehrbase/application/EhrBase.java +++ b/application/src/main/java/org/ehrbase/application/EhrBase.java @@ -37,7 +37,6 @@ R2dbcAutoConfiguration.class, SecurityAutoConfiguration.class }) -// @EnableXacmlAuthorization @Import({ServiceModuleConfiguration.class, RestEHRScapeModuleConfiguration.class, RestModuleConfiguration.class}) public class EhrBase { diff --git a/application/src/main/resources/application-authorization.properties b/application/src/main/resources/application-authorization.properties deleted file mode 100644 index 0272faf75..000000000 --- a/application/src/main/resources/application-authorization.properties +++ /dev/null @@ -1,12 +0,0 @@ -authorization.service.rpt.token-expiry-skew=PT3M -authorization.service.disable.for.ehrbase_multi_tenant_v1=false - -authorization.service.config[0].tenantId=1234-abc -authorization.service.config[0].host=http://localhost:8081 -authorization.service.config[0].realm=Sacred Heart -authorization.service.config[0].client-id=ehrbase - -#authorization.service.config[1].tenantId=1234-abc -#authorization.service.config[1].host=http://localhost:8081 -#authorization.service.config[1].realm=Sacred Heart -#authorization.service.config[1].client-id=ehrbase diff --git a/application/src/main/resources/application-local.yml b/application/src/main/resources/application-local.yml index 0ebe8a85d..73c43ded5 100644 --- a/application/src/main/resources/application-local.yml +++ b/application/src/main/resources/application-local.yml @@ -55,8 +55,8 @@ server: iterationScanDepth: 20 security: - authType: oauth -# authType: none + #authType: oauth + authType: none #use admin for cleaning up the db during tests admin-api: diff --git a/application/src/main/resources/application-xacml.yml b/application/src/main/resources/application-xacml.yml deleted file mode 100644 index 1dcd03314..000000000 --- a/application/src/main/resources/application-xacml.yml +++ /dev/null @@ -1,32 +0,0 @@ -#spring: -# rabbitmq: -# virtual-host: authorization - - - - -#hip.pdp.rabbitmq.virtual-host:/ -hip.pdp.rabbitmq.host: localhost -hip.pdp.rabbitmq.username: guest -hip.pdp.rabbitmq.password: guest - - - - - - - - - - - -policyChangeQueueName: policy.changes - -xacml.persistence: - hibernate.dialect: org.hibernate.dialect.PostgreSQLDialect - hibernate.hbm2ddl.auto: update - hibernate.default_schema: ehr - javax.persistence.jdbc.driver: org.postgresql.Driver - javax.persistence.jdbc.url: jdbc:postgresql://localhost:5432/ehrbase - javax.persistence.jdbc.user: ehrbase_restricted - javax.persistence.jdbc.password: ehrbase_restricted diff --git a/application/src/main/resources/application.yml b/application/src/main/resources/application.yml index 93902e1db..4a8eb86f7 100644 --- a/application/src/main/resources/application.yml +++ b/application/src/main/resources/application.yml @@ -45,7 +45,7 @@ spring: oauth2: resourceserver: jwt: - issuer-uri: http://localhost:8081/auth/realms/myTestRealm-c76fe4ff-28a4-4b24-9550-d34a324a836d + issuer-uri: # http://localhost:8081/auth/realms/ehrbase # Example issuer URI - or set via env var profiles: active: local datasource: diff --git a/plugin/pom.xml b/plugin/pom.xml index a126b4bcd..3e64f9144 100644 --- a/plugin/pom.xml +++ b/plugin/pom.xml @@ -13,7 +13,6 @@ ../ - 1.1.0-SNAPSHOT diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/DefaultExceptionHandler.java b/rest-openehr/src/main/java/org/ehrbase/rest/DefaultExceptionHandler.java index d17ecc8af..e96396b9e 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/DefaultExceptionHandler.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/DefaultExceptionHandler.java @@ -78,11 +78,6 @@ public ResponseEntity handleBadRequestExceptions(Exception ex) { return handleExceptionInternal(ex, ex.getMessage(), new HttpHeaders(), HttpStatus.BAD_REQUEST); } - // @ExceptionHandler({AccessDeniedException.class, AccessCtrlException.class}) - // public ResponseEntity handleObjectNotFoundException(Exception ex) { - // return handleExceptionInternal(ex, ex.getMessage(), new HttpHeaders(), HttpStatus.FORBIDDEN); - // } - // 404 @ExceptionHandler(ObjectNotFoundException.class) public ResponseEntity handleObjectNotFoundException(ObjectNotFoundException ex) { From 3f1098daea96c9415d597cb8df8f8851574a879e Mon Sep 17 00:00:00 2001 From: MBA Date: Thu, 3 Aug 2023 15:10:25 +0200 Subject: [PATCH 27/53] Rest endpoint instanciationis now surpressed by bean name --- .../rest/ehrscape/controller/CompositionController.java | 2 +- .../org/ehrbase/rest/ehrscape/controller/EhrController.java | 2 +- .../org/ehrbase/rest/ehrscape/controller/QueryController.java | 2 +- .../ehrbase/rest/ehrscape/controller/TemplateController.java | 2 +- .../src/main/java/org/ehrbase/rest/StatusController.java | 2 +- .../org/ehrbase/rest/admin/AdminCompositionController.java | 2 +- .../org/ehrbase/rest/admin/AdminContributionController.java | 2 +- .../src/main/java/org/ehrbase/rest/admin/AdminController.java | 2 +- .../java/org/ehrbase/rest/admin/AdminDirectoryController.java | 2 +- .../main/java/org/ehrbase/rest/admin/AdminEhrController.java | 2 +- .../java/org/ehrbase/rest/admin/AdminTemplateController.java | 2 +- .../org/ehrbase/rest/openehr/OpenehrCompositionController.java | 2 +- .../ehrbase/rest/openehr/OpenehrContributionController.java | 2 +- .../ehrbase/rest/openehr/OpenehrDefinitionQueryController.java | 2 +- .../org/ehrbase/rest/openehr/OpenehrDirectoryController.java | 2 +- .../java/org/ehrbase/rest/openehr/OpenehrEhrController.java | 2 +- .../org/ehrbase/rest/openehr/OpenehrEhrStatusController.java | 2 +- .../java/org/ehrbase/rest/openehr/OpenehrQueryController.java | 2 +- .../org/ehrbase/rest/openehr/OpenehrTemplateController.java | 2 +- .../rest/openehr/OpenehrVersionedCompositionController.java | 3 +-- .../rest/openehr/OpenehrVersionedEhrStatusController.java | 2 +- 21 files changed, 21 insertions(+), 22 deletions(-) diff --git a/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/CompositionController.java b/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/CompositionController.java index 81a97e3fe..c64cbdcf7 100644 --- a/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/CompositionController.java +++ b/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/CompositionController.java @@ -51,7 +51,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -@ConditionalOnMissingBean(value = {CompositionController.class}) +@ConditionalOnMissingBean(name = {"primarycompositioncontroller"}) @TenantAware @RestController @RequestMapping( diff --git a/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/EhrController.java b/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/EhrController.java index 1bc552e40..6fea006bc 100644 --- a/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/EhrController.java +++ b/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/EhrController.java @@ -63,7 +63,7 @@ * @author Stefan Spiska * @author Jake Smolka */ -@ConditionalOnMissingBean(value = {EhrController.class}) +@ConditionalOnMissingBean(name = "primaryehrcontroller") @TenantAware @RestController @RequestMapping(path = API_ECIS_CONTEXT_PATH_WITH_VERSION + "/ehr") diff --git a/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/QueryController.java b/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/QueryController.java index b58203cd3..8e6d1704e 100644 --- a/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/QueryController.java +++ b/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/QueryController.java @@ -36,7 +36,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -@ConditionalOnMissingBean(value = {QueryController.class}) +@ConditionalOnMissingBean(name = "primaryquerycontroller") @TenantAware @RestController @RequestMapping( diff --git a/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/TemplateController.java b/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/TemplateController.java index 422099e15..1ebb72ae1 100644 --- a/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/TemplateController.java +++ b/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/controller/TemplateController.java @@ -52,7 +52,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -@ConditionalOnMissingBean(value = {TemplateController.class}) +@ConditionalOnMissingBean(name = "primarytemplatecontroller") @TenantAware @RestController @RequestMapping( diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/StatusController.java b/rest-openehr/src/main/java/org/ehrbase/rest/StatusController.java index 5c56c6573..05d80cbf9 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/StatusController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/StatusController.java @@ -44,7 +44,7 @@ * API endpoint to get status of EHRbase and version information on used dependencies as archie or openEHR_sdk as well * as the current used JVM version or target PostgreSQL server version. */ -@ConditionalOnMissingBean(value = {StatusController.class}) +@ConditionalOnMissingBean(name = "primarystatuscontroller") @Tag(name = "Status", description = "Heartbeat, Version info, Status") @RestController @RequestMapping( diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminCompositionController.java b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminCompositionController.java index d840a1eda..ca8e5a243 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminCompositionController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminCompositionController.java @@ -46,7 +46,7 @@ /** * Admin API controller for Composition related data. Provides endpoint to remove compositions physically from database. */ -@ConditionalOnMissingBean(value = {AdminCompositionController.class}) +@ConditionalOnMissingBean(name = "primaryadmincompositioncontroller") @ConditionalOnProperty(prefix = "admin-api", name = "active") @TenantAware @Tag(name = "Admin - Composition") diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminContributionController.java b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminContributionController.java index 84ebd6a8f..6ac141752 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminContributionController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminContributionController.java @@ -50,7 +50,7 @@ * Admin API controller for Contribution related data. Provides endpoints to update and remove Contributions in * database physically. */ -@ConditionalOnMissingBean(value = {AdminContributionController.class}) +@ConditionalOnMissingBean(name = "primaryadmincontributioncontroller") @ConditionalOnProperty(prefix = "admin-api", name = "active") @TenantAware @Tag(name = "Admin - Contribution") diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminController.java b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminController.java index 6d7e1eb97..fe803c854 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminController.java @@ -33,7 +33,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -@ConditionalOnMissingBean(value = {AdminController.class}) +@ConditionalOnMissingBean(name = "primaryadmincontroller") @ConditionalOnProperty(prefix = "admin-api", name = "active") @TenantAware @Tag(name = "Admin - Heartbeat") diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminDirectoryController.java b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminDirectoryController.java index 84761dc13..b129fe890 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminDirectoryController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminDirectoryController.java @@ -44,7 +44,7 @@ /** * Admin API controller for directories. Provides endpoint to remove complete directory trees from database physically. */ -@ConditionalOnMissingBean(value = {AdminDirectoryController.class}) +@ConditionalOnMissingBean(name = "primaryadmindirectorycontroller") @ConditionalOnProperty(prefix = "admin-api", name = "active") @TenantAware @Tag(name = "Admin - Directory") diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminEhrController.java b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminEhrController.java index 4870c468d..b23772fd8 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminEhrController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminEhrController.java @@ -50,7 +50,7 @@ /** * Admin API controller for EHR related endpoints. Provides methods to update and delete EHRs physically in the DB. */ -@ConditionalOnMissingBean(value = {AdminEhrController.class}) +@ConditionalOnMissingBean(name = "primaryadminehrcontroller") @ConditionalOnProperty(prefix = "admin-api", name = "active") @TenantAware @Tag(name = "Admin - EHR") diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminTemplateController.java b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminTemplateController.java index bc34581c6..0128952db 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminTemplateController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/admin/AdminTemplateController.java @@ -46,7 +46,7 @@ /** * Admin API controller for Templates. Provides endpoints to update (replace) and delete templates. */ -@ConditionalOnMissingBean(value = {AdminTemplateController.class}) +@ConditionalOnMissingBean(name = "primaryadmintemplatecontroller") @ConditionalOnProperty(prefix = "admin-api", name = "active") @TenantAware @Tag(name = "Admin - Template") diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrCompositionController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrCompositionController.java index e1c3532e4..fabb28e51 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrCompositionController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrCompositionController.java @@ -75,7 +75,7 @@ * @author Jake Smolka * @since 1.0.0 */ -@ConditionalOnMissingBean(value = {OpenehrCompositionController.class, CompositionApiSpecification.class}) +@ConditionalOnMissingBean(name = "primaryopenehrcompositioncontroller") @TenantAware @RestController @RequestMapping( diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrContributionController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrContributionController.java index cd6ce4fb0..5f8912b6c 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrContributionController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrContributionController.java @@ -57,7 +57,7 @@ import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; -@ConditionalOnMissingBean(value = {OpenehrContributionController.class, ContributionApiSpecification.class}) +@ConditionalOnMissingBean(name = "primaryopenehrcontributioncontroller") @TenantAware @RestController @RequestMapping( diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDefinitionQueryController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDefinitionQueryController.java index 0ad0c2afd..0e8f8f3ce 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDefinitionQueryController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDefinitionQueryController.java @@ -61,7 +61,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -@ConditionalOnMissingBean(value = {OpenehrDefinitionQueryController.class, DefinitionQueryApiSpecification.class}) +@ConditionalOnMissingBean(name = "primaryopenehrdefinitionquerycontroller") @TenantAware @RestController @RequestMapping( diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDirectoryController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDirectoryController.java index e58fdc8ce..79a493cc2 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDirectoryController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDirectoryController.java @@ -62,7 +62,7 @@ * @author Renaud Subiger * @since 1.0 */ -@ConditionalOnMissingBean(value = {OpenehrDirectoryController.class, DirectoryApiSpecification.class}) +@ConditionalOnMissingBean(name = "primaryopenehrdirectorycontroller") @TenantAware @RestController @RequestMapping(path = BaseController.API_CONTEXT_PATH_WITH_VERSION + "/ehr") diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrController.java index bcaf40431..86ed44d8a 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrController.java @@ -59,7 +59,7 @@ /** * Controller for /ehr resource of openEHR REST API */ -@ConditionalOnMissingBean(value = {OpenehrEhrController.class, EhrApiSpecification.class}) +@ConditionalOnMissingBean(name = "primaryopenehrehrcontroller") @TenantAware @RestController @RequestMapping( diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrStatusController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrStatusController.java index 58b796124..9a08ce3a4 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrStatusController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrEhrStatusController.java @@ -62,7 +62,7 @@ * @author Renaud Subiger * @since 1.0 */ -@ConditionalOnMissingBean(value = {OpenehrEhrStatusController.class, EhrStatusApiSpecification.class}) +@ConditionalOnMissingBean(name = "primaryopenehrehrstatuscontroller") @TenantAware @RestController @RequestMapping(path = BaseController.API_CONTEXT_PATH_WITH_VERSION + "/ehr/{ehr_id}/ehr_status") diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java index 76640bf6b..004c72792 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrQueryController.java @@ -60,7 +60,7 @@ * @author Renaud Subiger * @since 1.0 */ -@ConditionalOnMissingBean(value = {OpenehrQueryController.class, QueryApiSpecification.class}) +@ConditionalOnMissingBean(name = "primaryopenehrquerycontroller") @TenantAware @RestController @RequestMapping(path = BaseController.API_CONTEXT_PATH_WITH_VERSION + "/query") diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrTemplateController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrTemplateController.java index c9581a4c3..a2ebcd87c 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrTemplateController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrTemplateController.java @@ -68,7 +68,7 @@ /** * Controller for /template resource as part of the Definitions sub-API of the openEHR REST API */ -@ConditionalOnMissingBean(value = {OpenehrTemplateController.class, TemplateApiSpecification.class}) +@ConditionalOnMissingBean(name = "primaryopenehrtemplatecontroller") @TenantAware @RestController @RequestMapping( diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrVersionedCompositionController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrVersionedCompositionController.java index 448f03468..290006e7c 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrVersionedCompositionController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrVersionedCompositionController.java @@ -62,8 +62,7 @@ /** * Controller for /ehr/{ehrId}/versioned_composition resource of openEHR REST API */ -@ConditionalOnMissingBean( - value = {OpenehrVersionedCompositionController.class, VersionedCompositionApiSpecification.class}) +@ConditionalOnMissingBean(name = "primaryopenehrversionedcompositioncontroller") @TenantAware @RestController @RequestMapping( diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrVersionedEhrStatusController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrVersionedEhrStatusController.java index 841754bd3..e3741f6b8 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrVersionedEhrStatusController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrVersionedEhrStatusController.java @@ -55,7 +55,7 @@ /** * Controller for /ehr/{ehrId}/versioned_ehr_status resource of openEHR REST API */ -@ConditionalOnMissingBean(value = {OpenehrVersionedEhrStatusController.class, VersionedEhrStatusApiSpecification.class}) +@ConditionalOnMissingBean(name = "primaryopenehrversionedehrstatuscontroller") @TenantAware @RestController @RequestMapping( From ef97326c63aed2f7a16e6b5884bd374b1a48345a Mon Sep 17 00:00:00 2001 From: MBA Date: Wed, 9 Aug 2023 16:22:34 +0200 Subject: [PATCH 28/53] Review change --- application/src/main/resources/application-local.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/src/main/resources/application-local.yml b/application/src/main/resources/application-local.yml index 73c43ded5..9c86cb646 100644 --- a/application/src/main/resources/application-local.yml +++ b/application/src/main/resources/application-local.yml @@ -56,7 +56,7 @@ server: security: #authType: oauth - authType: none + authType: NONE #use admin for cleaning up the db during tests admin-api: From 2909156de31682dc04f448a47d7417a4c90b5762 Mon Sep 17 00:00:00 2001 From: Alex Vidrean Date: Thu, 10 Aug 2023 12:02:44 +0300 Subject: [PATCH 29/53] Update sonar orb to 2.0.0 --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b6f0cb24d..b27d67287 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2516,7 +2516,7 @@ commands: orbs: maven: circleci/maven@1.0.1 openjdk-install: cloudesire/openjdk-install@1.2.3 - sonarcloud: sonarsource/sonarcloud@1.0.2 + sonarcloud: sonarsource/sonarcloud@2.0.0 executors: # https://hub.docker.com/u/cimg (circleci next-gen docker images) From 3988b568a5f35b363e202a7b9954ee5bdbdccc28 Mon Sep 17 00:00:00 2001 From: bot Date: Wed, 16 Aug 2023 10:29:56 +0000 Subject: [PATCH 30/53] updated version to 0.31.0-SNAPSHOT --- CHANGELOG.md | 6 ++++++ api/pom.xml | 2 +- application/pom.xml | 2 +- base/pom.xml | 2 +- bom/pom.xml | 4 ++-- jooq-pq/pom.xml | 2 +- plugin/pom.xml | 2 +- pom.xml | 4 ++-- rest-ehr-scape/pom.xml | 2 +- rest-openehr/pom.xml | 2 +- service/pom.xml | 2 +- test-coverage/pom.xml | 2 +- 12 files changed, 19 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2144c585f..ed318d8ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [unreleased] + ### Added + ### Changed + ### Fixed + ## [0.30.0] ### Added ### Changed @@ -685,3 +690,4 @@ the next release this file will provide a proper overview. [0.28.0]: https://github.com/ehrbase/ehrbase/compare/v0.27.4...v0.28.0 [0.29.0]: https://github.com/ehrbase/ehrbase/compare/v0.28.0...v0.29.0 [0.30.0]: https://github.com/ehrbase/ehrbase/compare/v0.29.0...v0.30.0 +[unreleased]: https://github.com/ehrbase/ehrbase/compare/v0.30.0...HEAD diff --git a/api/pom.xml b/api/pom.xml index 458fa405f..1c219d52b 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -26,7 +26,7 @@ org.ehrbase.openehr server - 0.30.0 + 0.31.0-SNAPSHOT api diff --git a/application/pom.xml b/application/pom.xml index 53d6e662d..e0c5c5e5e 100644 --- a/application/pom.xml +++ b/application/pom.xml @@ -26,7 +26,7 @@ org.ehrbase.openehr server - 0.30.0 + 0.31.0-SNAPSHOT application diff --git a/base/pom.xml b/base/pom.xml index 016c12639..fcbf9316e 100644 --- a/base/pom.xml +++ b/base/pom.xml @@ -28,7 +28,7 @@ org.ehrbase.openehr server - 0.30.0 + 0.31.0-SNAPSHOT base diff --git a/bom/pom.xml b/bom/pom.xml index 9b8ef6780..6ba65fe88 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -24,7 +24,7 @@ org.ehrbase.openehr bom - 0.30.0 + 0.31.0-SNAPSHOT pom EHRbase @@ -103,7 +103,7 @@ 3.3.0 2.13.0 3.13.0 - 2.2.0 + 2.3.0-SNAPSHOT 8.5.13 2.15.0 1.95.0 diff --git a/jooq-pq/pom.xml b/jooq-pq/pom.xml index 148e374f8..dd01b6ce6 100644 --- a/jooq-pq/pom.xml +++ b/jooq-pq/pom.xml @@ -28,7 +28,7 @@ org.ehrbase.openehr server - 0.30.0 + 0.31.0-SNAPSHOT jooq-pg diff --git a/plugin/pom.xml b/plugin/pom.xml index 14c7c1b59..190341bb3 100644 --- a/plugin/pom.xml +++ b/plugin/pom.xml @@ -5,7 +5,7 @@ server org.ehrbase.openehr - 0.30.0 + 0.31.0-SNAPSHOT 4.0.0 diff --git a/pom.xml b/pom.xml index 69cba80d1..fb2bc1a7e 100644 --- a/pom.xml +++ b/pom.xml @@ -28,12 +28,12 @@ org.ehrbase.openehr bom - 0.30.0 + 0.31.0-SNAPSHOT /bom/pom.xml server - 0.30.0 + 0.31.0-SNAPSHOT pom diff --git a/rest-ehr-scape/pom.xml b/rest-ehr-scape/pom.xml index 41f8864da..1fe584d51 100644 --- a/rest-ehr-scape/pom.xml +++ b/rest-ehr-scape/pom.xml @@ -28,7 +28,7 @@ org.ehrbase.openehr server - 0.30.0 + 0.31.0-SNAPSHOT rest-ehr-scape diff --git a/rest-openehr/pom.xml b/rest-openehr/pom.xml index 011657a6a..229dc73d4 100644 --- a/rest-openehr/pom.xml +++ b/rest-openehr/pom.xml @@ -28,7 +28,7 @@ org.ehrbase.openehr server - 0.30.0 + 0.31.0-SNAPSHOT rest-openehr diff --git a/service/pom.xml b/service/pom.xml index b2945556e..2d5ebb57e 100644 --- a/service/pom.xml +++ b/service/pom.xml @@ -26,7 +26,7 @@ org.ehrbase.openehr server - 0.30.0 + 0.31.0-SNAPSHOT service diff --git a/test-coverage/pom.xml b/test-coverage/pom.xml index 34d77dbd7..f74e29da5 100644 --- a/test-coverage/pom.xml +++ b/test-coverage/pom.xml @@ -28,7 +28,7 @@ org.ehrbase.openehr server - 0.30.0 + 0.31.0-SNAPSHOT test-coverage From 3f7abc2d49ce5abc485ec0d5b485b8c72e33e0c2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Aug 2023 11:17:52 +0200 Subject: [PATCH 31/53] Bump io.micrometer:micrometer-registry-prometheus from 1.11.2 to 1.11.3 (#1167) Bumps [io.micrometer:micrometer-registry-prometheus](https://github.com/micrometer-metrics/micrometer) from 1.11.2 to 1.11.3. - [Release notes](https://github.com/micrometer-metrics/micrometer/releases) - [Commits](https://github.com/micrometer-metrics/micrometer/compare/v1.11.2...v1.11.3) --- updated-dependencies: - dependency-name: io.micrometer:micrometer-registry-prometheus dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bom/pom.xml b/bom/pom.xml index 6ba65fe88..aeb037abe 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -118,7 +118,7 @@ 1.6.13 3.1.2 42.5.3 - 1.11.2 + 1.11.3 2.7.14 1.6.6 From dd895d7c4149ae685e47a7f4a44fd5947e0489ac Mon Sep 17 00:00:00 2001 From: Alex Vidrean Date: Tue, 22 Aug 2023 10:17:17 +0300 Subject: [PATCH 32/53] Remove commented security.authType --- application/src/main/resources/application-local.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/application/src/main/resources/application-local.yml b/application/src/main/resources/application-local.yml index 9c86cb646..3711ff92a 100644 --- a/application/src/main/resources/application-local.yml +++ b/application/src/main/resources/application-local.yml @@ -55,7 +55,6 @@ server: iterationScanDepth: 20 security: - #authType: oauth authType: NONE #use admin for cleaning up the db during tests From 4fe1ebb31b0c8a57af8796e6f4cb78836ce82a03 Mon Sep 17 00:00:00 2001 From: Alex Vidrean Date: Tue, 22 Aug 2023 10:21:40 +0300 Subject: [PATCH 33/53] Add changelog documentation --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ed318d8ed..7bd5b8c2a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [unreleased] ### Added ### Changed + - Removed authorization scopes from endpoints and added support for overwriting controllers ([#1157](https://github.com/ehrbase/ehrbase/pull/1157)) ### Fixed ## [0.30.0] From 5bfe3263094d3bdef3e710f51f91f36bff95095a Mon Sep 17 00:00:00 2001 From: Alex Vidrean Date: Wed, 23 Aug 2023 09:31:56 +0300 Subject: [PATCH 34/53] Fixed changelog file for version 0.30.0 --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ede1421a7..c4da609bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -691,4 +691,5 @@ the next release this file will provide a proper overview. [0.27.4]: https://github.com/ehrbase/ehrbase/compare/v0.27.3...v0.27.4 [0.28.0]: https://github.com/ehrbase/ehrbase/compare/v0.27.4...v0.28.0 [0.29.0]: https://github.com/ehrbase/ehrbase/compare/v0.28.0...v0.29.0 -[unreleased]: https://github.com/ehrbase/ehrbase/compare/v0.29.0...HEAD +[0.30.0]: https://github.com/ehrbase/ehrbase/compare/v0.29.0...v0.30.0 +[unreleased]: https://github.com/ehrbase/ehrbase/compare/v0.30.0...HEAD From eef548b9d0e47486095e6ea1a98d1644e5b60934 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Aug 2023 10:38:04 +0200 Subject: [PATCH 35/53] Bump spring-boot.version from 2.7.14 to 2.7.15 (#1171) Bumps `spring-boot.version` from 2.7.14 to 2.7.15. Updates `org.springframework.boot:spring-boot-dependencies` from 2.7.14 to 2.7.15 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v2.7.14...v2.7.15) Updates `org.springframework.boot:spring-boot-starter-logging` from 2.7.14 to 2.7.15 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v2.7.14...v2.7.15) Updates `org.springframework.boot:spring-boot-maven-plugin` from 2.7.14 to 2.7.15 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v2.7.14...v2.7.15) --- updated-dependencies: - dependency-name: org.springframework.boot:spring-boot-dependencies dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.springframework.boot:spring-boot-starter-logging dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.springframework.boot:spring-boot-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bom/pom.xml b/bom/pom.xml index aeb037abe..e23ddfc0e 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -119,7 +119,7 @@ 3.1.2 42.5.3 1.11.3 - 2.7.14 + 2.7.15 1.6.6 2.20.0 From 0e70e63883a3a2edd8d5f643e8401c59eb04f68b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Aug 2023 10:38:19 +0200 Subject: [PATCH 36/53] Bump org.apache.maven.plugins:maven-enforcer-plugin from 3.3.0 to 3.4.0 (#1170) Bumps [org.apache.maven.plugins:maven-enforcer-plugin](https://github.com/apache/maven-enforcer) from 3.3.0 to 3.4.0. - [Release notes](https://github.com/apache/maven-enforcer/releases) - [Commits](https://github.com/apache/maven-enforcer/compare/enforcer-3.3.0...enforcer-3.4.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-enforcer-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index fb2bc1a7e..426401cdf 100644 --- a/pom.xml +++ b/pom.xml @@ -172,7 +172,7 @@ org.apache.maven.plugins maven-enforcer-plugin - 3.3.0 + 3.4.0 From 374cbd59e3cac4c8849ad3c22e28fa927a27d73f Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 29 Aug 2023 10:11:50 +0300 Subject: [PATCH 37/53] Update GitHub actions to latest versions (#1172) * Update GitHub actions to latest versions * Add dependabot support for github-actions --- .github/dependabot.yml | 5 +++++ .github/workflows/build-multiarch-image-latest.yml | 10 +++++----- .github/workflows/build-multiarch-image-next.yml | 10 +++++----- .github/workflows/build-multiarch-image-tag.yml | 10 +++++----- .github/workflows/build.yml | 6 +++--- .github/workflows/codeql.yml | 2 +- .github/workflows/jdk-compat-robot.yml | 4 ++-- .github/workflows/jdk-compat.yml | 4 ++-- 8 files changed, 28 insertions(+), 23 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 0c61ec775..93a9bbf20 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -12,3 +12,8 @@ updates: ignore: - dependency-name: "*" update-types: ["version-update:semver-major"] + - package-ecosystem: "github-actions" + directory: "/" + schedule: + # Check for updates to GitHub Actions every week + interval: "weekly" diff --git a/.github/workflows/build-multiarch-image-latest.yml b/.github/workflows/build-multiarch-image-latest.yml index b39c0e823..0dd3a8a65 100644 --- a/.github/workflows/build-multiarch-image-latest.yml +++ b/.github/workflows/build-multiarch-image-latest.yml @@ -15,19 +15,19 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@v2 - name: Login to DockerHub - uses: docker/login-action@v1 + uses: docker/login-action@v2 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Build and push (AMD64) - uses: docker/build-push-action@v2 + uses: docker/build-push-action@v4 with: context: . platforms: linux/amd64 @@ -35,7 +35,7 @@ jobs: tags: ehrbase/ehrbase:latest-amd64 - name: Build and push (ARM64) - uses: docker/build-push-action@v2 + uses: docker/build-push-action@v4 with: context: . platforms: linux/arm64 diff --git a/.github/workflows/build-multiarch-image-next.yml b/.github/workflows/build-multiarch-image-next.yml index 1cef434db..ab5da03bf 100644 --- a/.github/workflows/build-multiarch-image-next.yml +++ b/.github/workflows/build-multiarch-image-next.yml @@ -31,19 +31,19 @@ jobs: # Set as Environment for all further steps echo "TAG=${v}" >> $GITHUB_ENV - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@v2 - name: Login to DockerHub - uses: docker/login-action@v1 + uses: docker/login-action@v2 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Build and push (AMD64) - uses: docker/build-push-action@v2 + uses: docker/build-push-action@v4 with: context: . platforms: linux/amd64 @@ -51,7 +51,7 @@ jobs: tags: ehrbase/ehrbase:${{env.TAG}}-amd64 - name: Build and push (ARM64) - uses: docker/build-push-action@v2 + uses: docker/build-push-action@v4 with: context: . platforms: linux/arm64 diff --git a/.github/workflows/build-multiarch-image-tag.yml b/.github/workflows/build-multiarch-image-tag.yml index d54fdff92..c2fe47094 100644 --- a/.github/workflows/build-multiarch-image-tag.yml +++ b/.github/workflows/build-multiarch-image-tag.yml @@ -15,7 +15,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Create TAG ENV from version of release Branch run: | @@ -27,16 +27,16 @@ jobs: echo "TAG=$TAG" >> $GITHUB_ENV - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@v2 - name: Login to DockerHub - uses: docker/login-action@v1 + uses: docker/login-action@v2 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Build and push (AMD64) - uses: docker/build-push-action@v2 + uses: docker/build-push-action@v4 with: context: . platforms: linux/amd64 @@ -44,7 +44,7 @@ jobs: tags: ehrbase/ehrbase:tag-amd64 - name: Build and push (ARM64) - uses: docker/build-push-action@v2 + uses: docker/build-push-action@v4 with: context: . platforms: linux/arm64 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0bda9b39d..194b69c07 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -33,12 +33,12 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 - name: Setup Java - uses: actions/setup-java@v2 + uses: actions/setup-java@v3 with: distribution: 'temurin' java-version: '17' @@ -48,7 +48,7 @@ jobs: run: mvn -B verify - name: Setup Maven Central - uses: actions/setup-java@v2 + uses: actions/setup-java@v3 with: distribution: 'temurin' java-version: '17' diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index f37a46eb2..c9e2b065d 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -56,7 +56,7 @@ jobs: uses: actions/checkout@v3 - name: Setup Java - uses: actions/setup-java@v2 + uses: actions/setup-java@v3 with: distribution: 'temurin' java-version: '17' diff --git a/.github/workflows/jdk-compat-robot.yml b/.github/workflows/jdk-compat-robot.yml index f4a2c2b26..0b563d361 100644 --- a/.github/workflows/jdk-compat-robot.yml +++ b/.github/workflows/jdk-compat-robot.yml @@ -36,12 +36,12 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 - name: Setup Java - uses: actions/setup-java@v2 + uses: actions/setup-java@v3 with: distribution: 'temurin' java-version: ${{ matrix.java }} diff --git a/.github/workflows/jdk-compat.yml b/.github/workflows/jdk-compat.yml index 4451da9c6..58bc561a1 100644 --- a/.github/workflows/jdk-compat.yml +++ b/.github/workflows/jdk-compat.yml @@ -28,12 +28,12 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 - name: Setup Java - uses: actions/setup-java@v2 + uses: actions/setup-java@v3 with: distribution: 'temurin' java-version: ${{ matrix.java }} From 05de1aea5a8605cbe5b294fc97720b6246a18ea9 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 4 Sep 2023 16:21:41 +0300 Subject: [PATCH 38/53] Update CHANGELOG.md Fix typo --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4da609bb..3795708b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ### Changed - Removed authorization scopes from endpoints and added support for overwriting controllers ([#1157](https://github.com/ehrbase/ehrbase/pull/1157)) ### Fixed - - Fix atna location ([#1160](https://github.com/ehrbase/ehrbase/pull/1160)) + - Fix audit logs location ([#1160](https://github.com/ehrbase/ehrbase/pull/1160)) ## [0.30.0] ### Added From 5842be7276862504f4f0c0263b08244f7a1a1304 Mon Sep 17 00:00:00 2001 From: stefanspiska Date: Mon, 4 Sep 2023 15:27:40 +0200 Subject: [PATCH 39/53] Feature/cdr 1037 spring boot3 (#1174) * migrate to sporing boot 3 * downgrade jbx implementation * disable auth * update auth * exclude commons-logging * match trailing slash * update basic auth * code cleanup * fix: trigger CircleCI * fix: trigger CircleCI * update changelog * code cleanup --------- Co-authored-by: vladislavploaia --- CHANGELOG.md | 1 + .../CustomMethodSecurityExpressionRoot.java | 2 +- .../application/config/ServerConfigImp.java | 4 +- .../BasicAuthSecurityConfiguration.java | 74 +++++++--------- .../security/OAuth2SecurityConfiguration.java | 85 +++++++++---------- .../config/security/SecurityFilter.java | 2 +- .../web/AuditHandlerInterceptorDelegator.java | 4 +- .../config/web/WebConfiguration.java | 6 ++ .../application/web/LoggingContextFilter.java | 8 +- .../src/main/resources/application.yml | 14 ++- bom/pom.xml | 31 ++++++- .../ehrscape/EhrScapeExceptionHandler.java | 9 +- .../ehrbase/rest/DefaultExceptionHandler.java | 9 +- .../ehrbase/rest/RestModuleConfiguration.java | 4 +- .../openehr/OpenehrDirectoryController.java | 21 ++--- .../org/ehrbase/rest/util/AuthHelper.java | 2 +- 16 files changed, 151 insertions(+), 125 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4da609bb..83e1b84a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [unreleased] ### Added ### Changed + - Migrated to spring boot 3 ([#1174](https://github.com/ehrbase/ehrbase/pull/1174)) - Removed authorization scopes from endpoints and added support for overwriting controllers ([#1157](https://github.com/ehrbase/ehrbase/pull/1157)) ### Fixed - Fix atna location ([#1160](https://github.com/ehrbase/ehrbase/pull/1160)) diff --git a/application/src/main/java/org/ehrbase/application/abac/CustomMethodSecurityExpressionRoot.java b/application/src/main/java/org/ehrbase/application/abac/CustomMethodSecurityExpressionRoot.java index 88bf2da66..b9d679bee 100644 --- a/application/src/main/java/org/ehrbase/application/abac/CustomMethodSecurityExpressionRoot.java +++ b/application/src/main/java/org/ehrbase/application/abac/CustomMethodSecurityExpressionRoot.java @@ -188,7 +188,7 @@ private boolean checkAbac(String type, String subject, Object payload, String co } // Check and extract JWT - var jwt = getJwtAuthenticationToken(this.authentication); + var jwt = getJwtAuthenticationToken(this.getAuthentication()); // Request body map. will result in simple JSON like {"patient_id":"...", ...} // but requires "Object" for template handling, which can have a Set for multiple IDs diff --git a/application/src/main/java/org/ehrbase/application/config/ServerConfigImp.java b/application/src/main/java/org/ehrbase/application/config/ServerConfigImp.java index 1ba494b8f..e09d2a8c0 100644 --- a/application/src/main/java/org/ehrbase/application/config/ServerConfigImp.java +++ b/application/src/main/java/org/ehrbase/application/config/ServerConfigImp.java @@ -17,8 +17,8 @@ */ package org.ehrbase.application.config; -import javax.validation.constraints.Max; -import javax.validation.constraints.Min; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; diff --git a/application/src/main/java/org/ehrbase/application/config/security/BasicAuthSecurityConfiguration.java b/application/src/main/java/org/ehrbase/application/config/security/BasicAuthSecurityConfiguration.java index 30caf0395..28c2fdc9d 100644 --- a/application/src/main/java/org/ehrbase/application/config/security/BasicAuthSecurityConfiguration.java +++ b/application/src/main/java/org/ehrbase/application/config/security/BasicAuthSecurityConfiguration.java @@ -18,18 +18,22 @@ package org.ehrbase.application.config.security; import static org.ehrbase.application.config.security.SecurityProperties.ADMIN; -import static org.ehrbase.application.config.security.SecurityProperties.USER; +import static org.springframework.security.config.Customizer.withDefaults; import javax.annotation.PostConstruct; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.provisioning.InMemoryUserDetailsManager; +import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; /** @@ -42,55 +46,43 @@ @Configuration @ConditionalOnProperty(prefix = "security", name = "authType", havingValue = "basic") @EnableWebSecurity -public class BasicAuthSecurityConfiguration extends WebSecurityConfigurerAdapter { +public class BasicAuthSecurityConfiguration { private final Logger logger = LoggerFactory.getLogger(getClass()); - private final SecurityProperties properties; - - public BasicAuthSecurityConfiguration(SecurityProperties securityProperties) { - this.properties = securityProperties; - } - @PostConstruct public void initialize() { logger.info("Using basic authentication"); } - @Override - public void configure(AuthenticationManagerBuilder auth) throws Exception { - // @formatter:off - auth.inMemoryAuthentication() - .withUser(properties.getAuthUser()) - .password("{noop}" + properties.getAuthPassword()) - .roles(USER) - .and() - .withUser(properties.getAuthAdminUser()) - .password("{noop}" + properties.getAuthAdminPassword()) - .roles(ADMIN); - // @formatter:on + @Bean + public InMemoryUserDetailsManager inMemoryUserDetailsManager( + SecurityProperties properties, ObjectProvider passwordEncoder) { + + return new InMemoryUserDetailsManager( + User.withUsername(properties.getAuthUser()) + .password("{noop}" + properties.getAuthPassword()) + .roles(SecurityProperties.USER) + .build(), + User.withUsername(properties.getAuthAdminUser()) + .password("{noop}" + properties.getAuthAdminPassword()) + .roles(SecurityProperties.ADMIN) + .build()); } - @Override - protected void configure(HttpSecurity http) throws Exception { + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.addFilterBefore(new SecurityFilter(), BasicAuthenticationFilter.class); - // @formatter:off - http.cors() - .and() - .csrf() - .ignoringAntMatchers("/rest/**") - .and() - .authorizeRequests() - .antMatchers("/rest/admin/**", "/management/**") - .hasRole(ADMIN) - .anyRequest() - .hasAnyRole(ADMIN, USER) - .and() - .sessionManagement() - .sessionCreationPolicy(SessionCreationPolicy.STATELESS) - .and() - .httpBasic(); - // @formatter:on + http.cors(withDefaults()) + .csrf(c -> c.ignoringRequestMatchers("/rest/**")) + .authorizeHttpRequests(auth -> auth.requestMatchers("/rest/admin/**", "/management/**") + .hasRole(ADMIN) + .anyRequest() + .hasAnyRole(ADMIN, SecurityProperties.USER)) + .sessionManagement(s -> s.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) + .httpBasic(withDefaults()); + + return http.build(); } } diff --git a/application/src/main/java/org/ehrbase/application/config/security/OAuth2SecurityConfiguration.java b/application/src/main/java/org/ehrbase/application/config/security/OAuth2SecurityConfiguration.java index 7dd490974..3ea65e1ab 100644 --- a/application/src/main/java/org/ehrbase/application/config/security/OAuth2SecurityConfiguration.java +++ b/application/src/main/java/org/ehrbase/application/config/security/OAuth2SecurityConfiguration.java @@ -17,12 +17,14 @@ */ package org.ehrbase.application.config.security; +import static org.ehrbase.application.config.security.SecurityProperties.ADMIN; +import static org.springframework.security.config.Customizer.withDefaults; + import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; import javax.annotation.PostConstruct; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,17 +32,19 @@ import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.security.oauth2.resource.OAuth2ResourceServerProperties; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.convert.converter.Converter; import org.springframework.security.authentication.AbstractAuthenticationToken; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.oauth2.jwt.Jwt; import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter; -import org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationFilter; +import org.springframework.security.oauth2.server.resource.web.authentication.BearerTokenAuthenticationFilter; +import org.springframework.security.web.SecurityFilterChain; /** * {@link Configuration} for OAuth2 authentication. @@ -52,7 +56,7 @@ @Configuration @EnableWebSecurity @ConditionalOnProperty(prefix = "security", name = "auth-type", havingValue = "oauth") -public class OAuth2SecurityConfiguration extends WebSecurityConfigurerAdapter { +public class OAuth2SecurityConfiguration { private static final String PUBLIC = "PUBLIC"; private static final String PRIVATE = "PRIVATE"; @@ -87,48 +91,43 @@ public void initialize() { logger.debug("Using admin role: {}", securityProperties.getOauth2AdminRole()); } - @Override - protected void configure(HttpSecurity http) throws Exception { + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { String userRole = securityProperties.getOauth2UserRole(); String adminRole = securityProperties.getOauth2AdminRole(); http.addFilterBefore(new SecurityFilter(), BearerTokenAuthenticationFilter.class); - // @formatter:off - var registry = http.cors() - .and() - .authorizeRequests() - .antMatchers("/rest/admin/**") - .hasRole(adminRole) - .antMatchers("/swagger-ui/**", "/v3/api-docs/**") - .permitAll(); - - var managementAuthorizedUrl = registry.and() - .authorizeRequests() - .antMatchers(this.managementWebEndpointProperties.getBasePath() + "/**"); - - switch (managementEndpointsAccessType) { - case ADMIN_ONLY -> - // management endpoints are locked behind an authorization - // and are only available for users with the admin role - managementAuthorizedUrl.hasRole(adminRole); - case PRIVATE -> - // management endpoints are locked behind an authorization, but are available to any role - managementAuthorizedUrl.hasAnyRole(adminRole, userRole, PROFILE_SCOPE); - case PUBLIC -> - // management endpoints can be accessed without an authorization - managementAuthorizedUrl.permitAll(); - default -> throw new IllegalStateException(String.format( - "Unexpected management endpoints access control type %s", managementEndpointsAccessType)); - } - - registry.anyRequest() - .hasAnyRole(adminRole, userRole, PROFILE_SCOPE) - .and() - .oauth2ResourceServer() - .jwt() - .jwtAuthenticationConverter(getJwtAuthenticationConverter()); - // @formatter:on + http.cors(withDefaults()) + .authorizeHttpRequests(auth -> { + AuthorizeHttpRequestsConfigurer.AuthorizationManagerRequestMatcherRegistry registry = + auth.requestMatchers("/rest/admin/**", "/management/**") + .hasRole(ADMIN); + + var managementAuthorizedUrl = + registry.requestMatchers(this.managementWebEndpointProperties.getBasePath() + "/**"); + + switch (managementEndpointsAccessType) { + case ADMIN_ONLY -> + // management endpoints are locked behind an authorization + // and are only available for users with the admin role + managementAuthorizedUrl.hasRole(adminRole); + case PRIVATE -> + // management endpoints are locked behind an authorization, but are available to any role + managementAuthorizedUrl.hasAnyRole(adminRole, userRole, PROFILE_SCOPE); + case PUBLIC -> + // management endpoints can be accessed without an authorization + managementAuthorizedUrl.permitAll(); + default -> throw new IllegalStateException(String.format( + "Unexpected management endpoints access control type %s", + managementEndpointsAccessType)); + } + + registry.anyRequest().hasAnyRole(adminRole, userRole, PROFILE_SCOPE); + }) + .oauth2ResourceServer(o -> o.jwt(j -> j.jwtAuthenticationConverter(getJwtAuthenticationConverter()))); + + return http.build(); } // Converter creates list of "ROLE_*" (upper case) authorities for each "realm access" role @@ -146,7 +145,7 @@ private Converter getJwtAuthenticationConverte .stream() .map(roleName -> "ROLE_" + roleName.toUpperCase()) .map(SimpleGrantedAuthority::new) - .collect(Collectors.toList())); + .toList()); } if (jwt.getClaims().containsKey("scope")) { @@ -154,7 +153,7 @@ private Converter getJwtAuthenticationConverte Arrays.stream(jwt.getClaims().get("scope").toString().split(" ")) .map(roleName -> "ROLE_" + roleName.toUpperCase()) .map(SimpleGrantedAuthority::new) - .collect(Collectors.toList())); + .toList()); } return authority; }); diff --git a/application/src/main/java/org/ehrbase/application/config/security/SecurityFilter.java b/application/src/main/java/org/ehrbase/application/config/security/SecurityFilter.java index 3427c0339..4618c0b65 100644 --- a/application/src/main/java/org/ehrbase/application/config/security/SecurityFilter.java +++ b/application/src/main/java/org/ehrbase/application/config/security/SecurityFilter.java @@ -17,8 +17,8 @@ */ package org.ehrbase.application.config.security; +import jakarta.servlet.*; import java.io.IOException; -import javax.servlet.*; import org.springframework.security.core.context.SecurityContextHolder; public class SecurityFilter implements Filter { diff --git a/application/src/main/java/org/ehrbase/application/config/web/AuditHandlerInterceptorDelegator.java b/application/src/main/java/org/ehrbase/application/config/web/AuditHandlerInterceptorDelegator.java index d7bd181fe..bae34fc20 100644 --- a/application/src/main/java/org/ehrbase/application/config/web/AuditHandlerInterceptorDelegator.java +++ b/application/src/main/java/org/ehrbase/application/config/web/AuditHandlerInterceptorDelegator.java @@ -17,8 +17,8 @@ */ package org.ehrbase.application.config.web; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.ehrbase.api.audit.interceptor.AuditInterceptor; import org.springframework.lang.Nullable; import org.springframework.web.servlet.HandlerInterceptor; diff --git a/application/src/main/java/org/ehrbase/application/config/web/WebConfiguration.java b/application/src/main/java/org/ehrbase/application/config/web/WebConfiguration.java index c7eb93f43..35d78bb48 100644 --- a/application/src/main/java/org/ehrbase/application/config/web/WebConfiguration.java +++ b/application/src/main/java/org/ehrbase/application/config/web/WebConfiguration.java @@ -24,6 +24,7 @@ import org.springframework.lang.NonNull; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.PathMatchConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** @@ -56,4 +57,9 @@ public void addCorsMappings(CorsRegistry registry) { public void addInterceptors(@NonNull InterceptorRegistry registry) { auditInterceptorHandler.registerAuditInterceptors(registry); } + + @Override + public void configurePathMatch(PathMatchConfigurer configurer) { + configurer.setUseTrailingSlashMatch(true); + } } diff --git a/application/src/main/java/org/ehrbase/application/web/LoggingContextFilter.java b/application/src/main/java/org/ehrbase/application/web/LoggingContextFilter.java index b01c53203..715c9fc31 100644 --- a/application/src/main/java/org/ehrbase/application/web/LoggingContextFilter.java +++ b/application/src/main/java/org/ehrbase/application/web/LoggingContextFilter.java @@ -17,12 +17,12 @@ */ package org.ehrbase.application.web; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.concurrent.ThreadLocalRandom; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import org.slf4j.MDC; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; diff --git a/application/src/main/resources/application.yml b/application/src/main/resources/application.yml index 4a8eb86f7..d482723ff 100644 --- a/application/src/main/resources/application.yml +++ b/application/src/main/resources/application.yml @@ -37,7 +37,8 @@ spring: type: CAFFEINE # change to type redis if usage of redis distributed cache is intended # the following redis properties are only used if the cache.type=redis - redis: + data: + redis: host: localhost port: 6379 @@ -190,15 +191,10 @@ management: # Enable / disable metrics endpoint enabled: false # Prometheus metric endpoint - Special metrics format to display in microservice observer solutions - prometheus: - # Enable / disable prometheus endpoint - enabled: false - # Metrics settings - metrics: - export: - prometheus: + prometheus: + metrics: + export: enabled: true - # External Terminology Validation Properties validation: external-terminology: diff --git a/bom/pom.xml b/bom/pom.xml index e23ddfc0e..9ede364a3 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -119,7 +119,7 @@ 3.1.2 42.5.3 1.11.3 - 2.7.15 + 3.1.1 1.6.6 2.20.0 @@ -180,6 +180,29 @@ pom import + + + org.ehrbase.openehr.sdk + serialisation + ${ehrbase.sdk.version} + + + commons-logging + commons-logging + + + + + org.ehrbase.openehr.sdk + validation + ${ehrbase.sdk.version} + + + commons-logging + commons-logging + + + commons-io commons-io @@ -354,6 +377,12 @@ java-jwt ${java-jwt.version} + + com.sun.xml.bind + jaxb-impl + 2.3.6 + + diff --git a/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/EhrScapeExceptionHandler.java b/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/EhrScapeExceptionHandler.java index 5e01dc39d..0498975a2 100644 --- a/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/EhrScapeExceptionHandler.java +++ b/rest-ehr-scape/src/main/java/org/ehrbase/rest/ehrscape/EhrScapeExceptionHandler.java @@ -35,6 +35,7 @@ import org.slf4j.LoggerFactory; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; +import org.springframework.http.HttpStatusCode; import org.springframework.http.ResponseEntity; import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.validation.BindException; @@ -126,7 +127,7 @@ public ResponseEntity handleUnsupportedMediaTypeException(UnsupportedMed @ExceptionHandler(ResponseStatusException.class) public ResponseEntity handleSpringResponseStatusException(ResponseStatusException ex) { // rethrow will not work properly, so we handle it - return handleExceptionInternal(ex, ex.getReason(), ex.getResponseHeaders(), ex.getStatus()); + return handleExceptionInternal(ex, ex.getReason(), ex.getResponseHeaders(), ex.getStatusCode()); } // 500 - general @@ -137,7 +138,7 @@ public ResponseEntity handleUncaughtException(Exception ex) { } private ResponseEntity handleExceptionInternal( - Exception ex, String message, HttpHeaders headers, HttpStatus status) { + Exception ex, String message, HttpHeaders headers, HttpStatusCode status) { if (status.is5xxServerError()) { logger.error("", ex); @@ -149,7 +150,9 @@ private ResponseEntity handleExceptionInternal( } Map body = new HashMap<>(); - body.put("error", status.getReasonPhrase()); + if (status instanceof HttpStatus httpStatus) { + body.put("error", httpStatus.getReasonPhrase()); + } body.put("message", message); return new ResponseEntity<>(body, headers, status); } diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/DefaultExceptionHandler.java b/rest-openehr/src/main/java/org/ehrbase/rest/DefaultExceptionHandler.java index e96396b9e..498d82913 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/DefaultExceptionHandler.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/DefaultExceptionHandler.java @@ -34,6 +34,7 @@ import org.slf4j.LoggerFactory; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; +import org.springframework.http.HttpStatusCode; import org.springframework.http.ResponseEntity; import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.validation.BindException; @@ -127,7 +128,7 @@ public ResponseEntity handleUnprocessableEntityException( @ExceptionHandler(ResponseStatusException.class) public ResponseEntity handleSpringResponseStatusException(ResponseStatusException ex) { // rethrow will not work properly, so we handle it - return handleExceptionInternal(ex, ex.getReason(), ex.getResponseHeaders(), ex.getStatus()); + return handleExceptionInternal(ex, ex.getReason(), ex.getResponseHeaders(), ex.getStatusCode()); } // 500 - general @@ -138,7 +139,7 @@ public ResponseEntity handleUncaughtException(Exception ex) { } private ResponseEntity handleExceptionInternal( - Exception ex, String message, HttpHeaders headers, HttpStatus status) { + Exception ex, String message, HttpHeaders headers, HttpStatusCode status) { if (status.is5xxServerError()) { logger.error("", ex); @@ -150,7 +151,9 @@ private ResponseEntity handleExceptionInternal( } Map body = new HashMap<>(); - body.put("error", status.getReasonPhrase()); + if (status instanceof HttpStatus httpStatus) { + body.put("error", httpStatus.getReasonPhrase()); + } body.put("message", message); return new ResponseEntity<>(body, headers, status); } diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/RestModuleConfiguration.java b/rest-openehr/src/main/java/org/ehrbase/rest/RestModuleConfiguration.java index 7cb1fd761..36e7bab44 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/RestModuleConfiguration.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/RestModuleConfiguration.java @@ -17,9 +17,9 @@ */ package org.ehrbase.rest; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.util.Optional; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import org.ehrbase.api.tenant.TenantAuthentication; import org.ehrbase.api.tenant.ThreadLocalSupplier; import org.springframework.beans.factory.annotation.Value; diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDirectoryController.java b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDirectoryController.java index 79a493cc2..6e2b59912 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDirectoryController.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/openehr/OpenehrDirectoryController.java @@ -18,6 +18,8 @@ package org.ehrbase.rest.openehr; import static org.apache.commons.lang3.StringUtils.unwrap; +import static org.springframework.http.HttpMethod.DELETE; +import static org.springframework.http.HttpMethod.POST; import static org.springframework.web.util.UriComponentsBuilder.fromPath; import com.nedap.archie.rm.directory.Folder; @@ -90,7 +92,7 @@ public ResponseEntity createDirectory( var createdFolder = directoryService.create(ehrId, folder); - return createDirectoryResponse(HttpMethod.POST, prefer, accept, createdFolder, ehrId); + return createDirectoryResponse(POST, prefer, accept, createdFolder, ehrId); } /** @@ -133,7 +135,7 @@ public ResponseEntity deleteDirectory( directoryService.delete(ehrId, folderId); createAuditLogsMsgBuilder(ehrId.toString(), folderId.toString()); - return createDirectoryResponse(HttpMethod.DELETE, null, accept, null, ehrId); + return createDirectoryResponse(DELETE, null, accept, null, ehrId); } /** @@ -251,17 +253,12 @@ private ResponseEntity createDirectoryResponse( } private HttpStatus getSuccessStatus(HttpMethod method) { - switch (method) { - case POST: { - return HttpStatus.CREATED; - } - case DELETE: { - return HttpStatus.NO_CONTENT; - } - default: { - return HttpStatus.OK; - } + if (method.equals(POST)) { + return HttpStatus.CREATED; + } else if (method.equals(DELETE)) { + return HttpStatus.NO_CONTENT; } + return HttpStatus.OK; } /** diff --git a/rest-openehr/src/main/java/org/ehrbase/rest/util/AuthHelper.java b/rest-openehr/src/main/java/org/ehrbase/rest/util/AuthHelper.java index c9160aafe..f5d3e7880 100644 --- a/rest-openehr/src/main/java/org/ehrbase/rest/util/AuthHelper.java +++ b/rest-openehr/src/main/java/org/ehrbase/rest/util/AuthHelper.java @@ -22,12 +22,12 @@ import com.auth0.jwt.interfaces.Claim; import com.auth0.jwt.interfaces.DecodedJWT; +import jakarta.servlet.http.HttpServletRequest; import java.nio.charset.StandardCharsets; import java.security.Principal; import java.util.Base64; import java.util.Map; import java.util.Optional; -import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang3.StringUtils; import org.springframework.security.authentication.AbstractAuthenticationToken; import org.springframework.security.oauth2.jwt.Jwt; From 07aa9d19933351de7b509bce794174cc2041c120 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Tue, 5 Sep 2023 15:06:32 +0300 Subject: [PATCH 40/53] add language as default (#1166) --- .../src/main/java/org/ehrbase/service/TemplateServiceImp.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/service/src/main/java/org/ehrbase/service/TemplateServiceImp.java b/service/src/main/java/org/ehrbase/service/TemplateServiceImp.java index e86725a40..1f433cda3 100644 --- a/service/src/main/java/org/ehrbase/service/TemplateServiceImp.java +++ b/service/src/main/java/org/ehrbase/service/TemplateServiceImp.java @@ -134,7 +134,7 @@ public Composition buildExample(String templateId) { public WebTemplate findTemplate(String templateId) { try { return knowledgeCacheService.getQueryOptMetaData(templateId); - } catch (NullPointerException e) { + } catch (NullPointerException | IllegalArgumentException e) { throw new ObjectNotFoundException("template", "Template with the specified id does not exist", e); } catch (Exception e) { throw new InternalServerException("Could not generate web template", e); From f2b00e7bce8e2d23d8669a98e360943083077408 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Sep 2023 11:14:11 +0200 Subject: [PATCH 41/53] Bump spring-boot.version from 3.1.1 to 3.1.3 (#1177) Bumps `spring-boot.version` from 3.1.1 to 3.1.3. Updates `org.springframework.boot:spring-boot-dependencies` from 3.1.1 to 3.1.3 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.1.1...v3.1.3) Updates `org.springframework.boot:spring-boot-starter-logging` from 3.1.1 to 3.1.3 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.1.1...v3.1.3) Updates `org.springframework.boot:spring-boot-maven-plugin` from 3.1.1 to 3.1.3 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.1.1...v3.1.3) --- updated-dependencies: - dependency-name: org.springframework.boot:spring-boot-dependencies dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.springframework.boot:spring-boot-starter-logging dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.springframework.boot:spring-boot-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bom/pom.xml b/bom/pom.xml index 9ede364a3..e3fbfc19a 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -119,7 +119,7 @@ 3.1.2 42.5.3 1.11.3 - 3.1.1 + 3.1.3 1.6.6 2.20.0 From d67c098025b6d8d70e8333bcfe147c31b6a85de9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Sep 2023 11:14:21 +0200 Subject: [PATCH 42/53] Bump org.apache.maven.plugins:maven-enforcer-plugin from 3.4.0 to 3.4.1 (#1178) Bumps [org.apache.maven.plugins:maven-enforcer-plugin](https://github.com/apache/maven-enforcer) from 3.4.0 to 3.4.1. - [Release notes](https://github.com/apache/maven-enforcer/releases) - [Commits](https://github.com/apache/maven-enforcer/compare/enforcer-3.4.0...enforcer-3.4.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-enforcer-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 426401cdf..b3e4925cd 100644 --- a/pom.xml +++ b/pom.xml @@ -172,7 +172,7 @@ org.apache.maven.plugins maven-enforcer-plugin - 3.4.0 + 3.4.1 From 993bd637a9eb80c5d471aedb10d256dcf1f4a38e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Sep 2023 11:14:32 +0200 Subject: [PATCH 43/53] Bump actions/checkout from 3 to 4 (#1176) Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build-multiarch-image-latest.yml | 2 +- .github/workflows/build-multiarch-image-next.yml | 2 +- .github/workflows/build-multiarch-image-tag.yml | 2 +- .github/workflows/build.yml | 2 +- .github/workflows/codeql.yml | 2 +- .github/workflows/jdk-compat-robot.yml | 4 ++-- .github/workflows/jdk-compat.yml | 2 +- .github/workflows/release.yml | 6 +++--- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/build-multiarch-image-latest.yml b/.github/workflows/build-multiarch-image-latest.yml index 0dd3a8a65..d3c0bf3e0 100644 --- a/.github/workflows/build-multiarch-image-latest.yml +++ b/.github/workflows/build-multiarch-image-latest.yml @@ -15,7 +15,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 diff --git a/.github/workflows/build-multiarch-image-next.yml b/.github/workflows/build-multiarch-image-next.yml index ab5da03bf..82aa3c597 100644 --- a/.github/workflows/build-multiarch-image-next.yml +++ b/.github/workflows/build-multiarch-image-next.yml @@ -31,7 +31,7 @@ jobs: # Set as Environment for all further steps echo "TAG=${v}" >> $GITHUB_ENV - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 diff --git a/.github/workflows/build-multiarch-image-tag.yml b/.github/workflows/build-multiarch-image-tag.yml index c2fe47094..bdfc48a64 100644 --- a/.github/workflows/build-multiarch-image-tag.yml +++ b/.github/workflows/build-multiarch-image-tag.yml @@ -15,7 +15,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Create TAG ENV from version of release Branch run: | diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 194b69c07..50afb708f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -33,7 +33,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index c9e2b065d..a136aaa05 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -53,7 +53,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup Java uses: actions/setup-java@v3 diff --git a/.github/workflows/jdk-compat-robot.yml b/.github/workflows/jdk-compat-robot.yml index 0b563d361..019e58934 100644 --- a/.github/workflows/jdk-compat-robot.yml +++ b/.github/workflows/jdk-compat-robot.yml @@ -36,7 +36,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 @@ -69,7 +69,7 @@ jobs: cat /var/tmp/log.txt - name: Checkout robot - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 repository: ehrbase/integration-tests diff --git a/.github/workflows/jdk-compat.yml b/.github/workflows/jdk-compat.yml index 58bc561a1..5c2f312d5 100644 --- a/.github/workflows/jdk-compat.yml +++ b/.github/workflows/jdk-compat.yml @@ -28,7 +28,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a97109fed..9de8fb8cb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,7 +14,7 @@ jobs: steps: # Install the sdk main in the local repo so maven version plugin can find them - name: Checkout SDK main - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 repository: ehrbase/openEHR_SDK @@ -33,7 +33,7 @@ jobs: run: mvn install -Dmaven.test.skip=true # Install the sdk dev in the local repo so maven version plugin can find them - name: Checkout SDK dev - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 repository: ehrbase/openEHR_SDK @@ -46,7 +46,7 @@ jobs: run: mvn install - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 # This will be used by git in all further steps From aff058a9ad01ba82ac66992e306f28da6e8b068f Mon Sep 17 00:00:00 2001 From: Alex Vidrean Date: Tue, 12 Sep 2023 13:20:19 +0300 Subject: [PATCH 44/53] Enabled swagger ui working with Spring Boot 3 --- .../org/ehrbase/application/config/SwaggerConfiguration.java | 2 +- .../config/security/OAuth2SecurityConfiguration.java | 1 - bom/pom.xml | 4 ++-- rest-ehr-scape/pom.xml | 2 +- rest-openehr/pom.xml | 2 +- 5 files changed, 5 insertions(+), 6 deletions(-) diff --git a/application/src/main/java/org/ehrbase/application/config/SwaggerConfiguration.java b/application/src/main/java/org/ehrbase/application/config/SwaggerConfiguration.java index 43f4f7d65..da0e7db60 100644 --- a/application/src/main/java/org/ehrbase/application/config/SwaggerConfiguration.java +++ b/application/src/main/java/org/ehrbase/application/config/SwaggerConfiguration.java @@ -21,7 +21,7 @@ import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.info.Info; import io.swagger.v3.oas.models.info.License; -import org.springdoc.core.GroupedOpenApi; +import org.springdoc.core.models.GroupedOpenApi; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/application/src/main/java/org/ehrbase/application/config/security/OAuth2SecurityConfiguration.java b/application/src/main/java/org/ehrbase/application/config/security/OAuth2SecurityConfiguration.java index 3ea65e1ab..42335a9a5 100644 --- a/application/src/main/java/org/ehrbase/application/config/security/OAuth2SecurityConfiguration.java +++ b/application/src/main/java/org/ehrbase/application/config/security/OAuth2SecurityConfiguration.java @@ -52,7 +52,6 @@ * @author Jake Smolka * @since 1.0.0 */ -@Deprecated @Configuration @EnableWebSecurity @ConditionalOnProperty(prefix = "security", name = "auth-type", havingValue = "oauth") diff --git a/bom/pom.xml b/bom/pom.xml index 9ede364a3..2aefa87e4 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -120,7 +120,7 @@ 42.5.3 1.11.3 3.1.1 - 1.6.6 + 2.2.0 2.20.0 1.4.13 @@ -325,7 +325,7 @@ org.springdoc - springdoc-openapi-ui + springdoc-openapi-starter-webmvc-ui ${springdoc-openapi.version} diff --git a/rest-ehr-scape/pom.xml b/rest-ehr-scape/pom.xml index 1fe584d51..0be0ca5d1 100644 --- a/rest-ehr-scape/pom.xml +++ b/rest-ehr-scape/pom.xml @@ -56,7 +56,7 @@ org.springdoc - springdoc-openapi-ui + springdoc-openapi-starter-webmvc-ui org.junit.vintage diff --git a/rest-openehr/pom.xml b/rest-openehr/pom.xml index ece1b1405..b4bc75da3 100644 --- a/rest-openehr/pom.xml +++ b/rest-openehr/pom.xml @@ -61,7 +61,7 @@ org.springdoc - springdoc-openapi-ui + springdoc-openapi-starter-webmvc-ui com.auth0 From 17805d042e981a26aa1132b5254180ed86eef32a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 09:16:33 +0200 Subject: [PATCH 45/53] Bump io.micrometer:micrometer-registry-prometheus from 1.11.3 to 1.11.4 (#1184) Bumps [io.micrometer:micrometer-registry-prometheus](https://github.com/micrometer-metrics/micrometer) from 1.11.3 to 1.11.4. - [Release notes](https://github.com/micrometer-metrics/micrometer/releases) - [Commits](https://github.com/micrometer-metrics/micrometer/compare/v1.11.3...v1.11.4) --- updated-dependencies: - dependency-name: io.micrometer:micrometer-registry-prometheus dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bom/pom.xml b/bom/pom.xml index bbc2c6126..ab17fc780 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -118,7 +118,7 @@ 1.6.13 3.1.2 42.5.3 - 1.11.3 + 1.11.4 3.1.3 2.2.0 From afb552352b796e1e5e9ac282b0619e1a296c5976 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 09:16:49 +0200 Subject: [PATCH 46/53] Bump docker/build-push-action from 4 to 5 (#1182) Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 4 to 5. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v4...v5) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build-multiarch-image-latest.yml | 4 ++-- .github/workflows/build-multiarch-image-next.yml | 4 ++-- .github/workflows/build-multiarch-image-tag.yml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-multiarch-image-latest.yml b/.github/workflows/build-multiarch-image-latest.yml index d3c0bf3e0..41468ada5 100644 --- a/.github/workflows/build-multiarch-image-latest.yml +++ b/.github/workflows/build-multiarch-image-latest.yml @@ -27,7 +27,7 @@ jobs: password: ${{ secrets.DOCKER_PASSWORD }} - name: Build and push (AMD64) - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: context: . platforms: linux/amd64 @@ -35,7 +35,7 @@ jobs: tags: ehrbase/ehrbase:latest-amd64 - name: Build and push (ARM64) - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: context: . platforms: linux/arm64 diff --git a/.github/workflows/build-multiarch-image-next.yml b/.github/workflows/build-multiarch-image-next.yml index 82aa3c597..d5e697d58 100644 --- a/.github/workflows/build-multiarch-image-next.yml +++ b/.github/workflows/build-multiarch-image-next.yml @@ -43,7 +43,7 @@ jobs: password: ${{ secrets.DOCKER_PASSWORD }} - name: Build and push (AMD64) - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: context: . platforms: linux/amd64 @@ -51,7 +51,7 @@ jobs: tags: ehrbase/ehrbase:${{env.TAG}}-amd64 - name: Build and push (ARM64) - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: context: . platforms: linux/arm64 diff --git a/.github/workflows/build-multiarch-image-tag.yml b/.github/workflows/build-multiarch-image-tag.yml index bdfc48a64..6f564f2c9 100644 --- a/.github/workflows/build-multiarch-image-tag.yml +++ b/.github/workflows/build-multiarch-image-tag.yml @@ -36,7 +36,7 @@ jobs: password: ${{ secrets.DOCKER_PASSWORD }} - name: Build and push (AMD64) - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: context: . platforms: linux/amd64 @@ -44,7 +44,7 @@ jobs: tags: ehrbase/ehrbase:tag-amd64 - name: Build and push (ARM64) - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: context: . platforms: linux/arm64 From 06d152bf5e010b6b9d72d3cdce4a169d4e760ca8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 09:16:58 +0200 Subject: [PATCH 47/53] Bump docker/setup-buildx-action from 2 to 3 (#1181) Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 2 to 3. - [Release notes](https://github.com/docker/setup-buildx-action/releases) - [Commits](https://github.com/docker/setup-buildx-action/compare/v2...v3) --- updated-dependencies: - dependency-name: docker/setup-buildx-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build-multiarch-image-latest.yml | 2 +- .github/workflows/build-multiarch-image-next.yml | 2 +- .github/workflows/build-multiarch-image-tag.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-multiarch-image-latest.yml b/.github/workflows/build-multiarch-image-latest.yml index 41468ada5..58b70015f 100644 --- a/.github/workflows/build-multiarch-image-latest.yml +++ b/.github/workflows/build-multiarch-image-latest.yml @@ -18,7 +18,7 @@ jobs: uses: actions/checkout@v4 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 + uses: docker/setup-buildx-action@v3 - name: Login to DockerHub uses: docker/login-action@v2 diff --git a/.github/workflows/build-multiarch-image-next.yml b/.github/workflows/build-multiarch-image-next.yml index d5e697d58..87ad1aff6 100644 --- a/.github/workflows/build-multiarch-image-next.yml +++ b/.github/workflows/build-multiarch-image-next.yml @@ -34,7 +34,7 @@ jobs: uses: actions/checkout@v4 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 + uses: docker/setup-buildx-action@v3 - name: Login to DockerHub uses: docker/login-action@v2 diff --git a/.github/workflows/build-multiarch-image-tag.yml b/.github/workflows/build-multiarch-image-tag.yml index 6f564f2c9..d5dfbbea5 100644 --- a/.github/workflows/build-multiarch-image-tag.yml +++ b/.github/workflows/build-multiarch-image-tag.yml @@ -27,7 +27,7 @@ jobs: echo "TAG=$TAG" >> $GITHUB_ENV - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 + uses: docker/setup-buildx-action@v3 - name: Login to DockerHub uses: docker/login-action@v2 From 35007ea770aed630c16e9d25263c5388154fbc8c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 16:30:17 +0200 Subject: [PATCH 48/53] Bump docker/login-action from 2 to 3 (#1183) Bumps [docker/login-action](https://github.com/docker/login-action) from 2 to 3. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/v2...v3) --- updated-dependencies: - dependency-name: docker/login-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build-multiarch-image-latest.yml | 2 +- .github/workflows/build-multiarch-image-next.yml | 2 +- .github/workflows/build-multiarch-image-tag.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-multiarch-image-latest.yml b/.github/workflows/build-multiarch-image-latest.yml index 58b70015f..81b0a7f6a 100644 --- a/.github/workflows/build-multiarch-image-latest.yml +++ b/.github/workflows/build-multiarch-image-latest.yml @@ -21,7 +21,7 @@ jobs: uses: docker/setup-buildx-action@v3 - name: Login to DockerHub - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} diff --git a/.github/workflows/build-multiarch-image-next.yml b/.github/workflows/build-multiarch-image-next.yml index 87ad1aff6..aa174566b 100644 --- a/.github/workflows/build-multiarch-image-next.yml +++ b/.github/workflows/build-multiarch-image-next.yml @@ -37,7 +37,7 @@ jobs: uses: docker/setup-buildx-action@v3 - name: Login to DockerHub - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} diff --git a/.github/workflows/build-multiarch-image-tag.yml b/.github/workflows/build-multiarch-image-tag.yml index d5dfbbea5..97af6f8b8 100644 --- a/.github/workflows/build-multiarch-image-tag.yml +++ b/.github/workflows/build-multiarch-image-tag.yml @@ -30,7 +30,7 @@ jobs: uses: docker/setup-buildx-action@v3 - name: Login to DockerHub - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} From 5fad66716a8fcd00d6aafc27970554b91f1b8c3e Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 19 Sep 2023 17:30:41 +0300 Subject: [PATCH 49/53] Add plugin path to sonar-project.properties (#1180) --- sonar-project.properties | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sonar-project.properties b/sonar-project.properties index e0a59da11..b7ba9e8cb 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -26,7 +26,8 @@ sonar.sources=api/src/main/java/, \ jooq-pq/src/main/java/, \ rest-ehr-scape/src/main/java/, \ rest-openehr/src/main/java/, \ - service/src/main/java/ + service/src/main/java/, \ + plugin/src/main/java sonar.java.binaries=**/target/** sonar.exclusions=**/test/** sonar.coverage.exclusions=**/test/** From 65aa0ab774dd408e147c0313c51f84f5c1d2c8ab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Sep 2023 10:59:48 +0200 Subject: [PATCH 50/53] Bump spring-boot.version from 3.1.3 to 3.1.4 (#1187) Bumps `spring-boot.version` from 3.1.3 to 3.1.4. Updates `org.springframework.boot:spring-boot-dependencies` from 3.1.3 to 3.1.4 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.1.3...v3.1.4) Updates `org.springframework.boot:spring-boot-starter-logging` from 3.1.3 to 3.1.4 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.1.3...v3.1.4) Updates `org.springframework.boot:spring-boot-maven-plugin` from 3.1.3 to 3.1.4 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.1.3...v3.1.4) --- updated-dependencies: - dependency-name: org.springframework.boot:spring-boot-dependencies dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.springframework.boot:spring-boot-starter-logging dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.springframework.boot:spring-boot-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bom/pom.xml b/bom/pom.xml index ab17fc780..b05823177 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -119,7 +119,7 @@ 3.1.2 42.5.3 1.11.4 - 3.1.3 + 3.1.4 2.2.0 2.20.0 From 83a3c4b75f98daca4850eea63cc20a4d6dd63f23 Mon Sep 17 00:00:00 2001 From: stefanspiska Date: Wed, 27 Sep 2023 10:14:19 +0200 Subject: [PATCH 51/53] code cleanup (#1188) --- .../main/java/org/ehrbase/service/PersistenceConfig.java | 6 ++++-- .../tenant/extraction/AuthenticatedExtractionStrategy.java | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/service/src/main/java/org/ehrbase/service/PersistenceConfig.java b/service/src/main/java/org/ehrbase/service/PersistenceConfig.java index 905845697..93144d492 100644 --- a/service/src/main/java/org/ehrbase/service/PersistenceConfig.java +++ b/service/src/main/java/org/ehrbase/service/PersistenceConfig.java @@ -78,10 +78,12 @@ public Connection acquire() { return connection; } catch (SQLException e) { try { + super.release(connection); - } finally { - throw new DataAccessException("Failed to set default tenant", e); + } catch (Exception r) { + } + throw new DataAccessException("Failed to set default tenant", e); } } }; diff --git a/service/src/main/java/org/ehrbase/tenant/extraction/AuthenticatedExtractionStrategy.java b/service/src/main/java/org/ehrbase/tenant/extraction/AuthenticatedExtractionStrategy.java index b481c6692..097915607 100644 --- a/service/src/main/java/org/ehrbase/tenant/extraction/AuthenticatedExtractionStrategy.java +++ b/service/src/main/java/org/ehrbase/tenant/extraction/AuthenticatedExtractionStrategy.java @@ -153,7 +153,7 @@ public boolean accept(Object... args) { } public Optional> extract(Object... args) { - return extract(null, args); + return extractWithPrior(Optional.empty(), args); } } // @format:on From 863f22b4ed0c4afc94fcb6f8027be891f34f34ad Mon Sep 17 00:00:00 2001 From: stefanspiska Date: Wed, 27 Sep 2023 11:58:41 +0200 Subject: [PATCH 52/53] Feature/pmk 251 (#1190) * change github action * fix AqlRoutines * inline parmeters * remove unnecessary DSL.field * fix order by * fix func build * fix review * Revert "change github action" This reverts commit 90714d93e9ef90bd8c6b9fff9e277cb03cb2a82e. * Changelog for #1190 --------- Co-authored-by: Alex Vidrean --- CHANGELOG.md | 1 + .../main/antlr4/org/ehrbase/aql/parser/Aql.g4 | 4 +- .../aql/compiler/QueryCompilerPass2.java | 85 ++++++++++++++++--- .../definition/CastFunctionDefinition.java | 44 ++++++++++ .../ehrbase/aql/definition/FuncParameter.java | 6 +- .../aql/definition/FuncParameterType.java | 3 +- .../org/ehrbase/aql/sql/QueryProcessor.java | 4 +- .../aql/sql/binding/ConstantField.java | 8 +- .../aql/sql/binding/FieldConstantHandler.java | 2 +- .../aql/sql/binding/FunctionExpression.java | 77 ++++++++++++++--- .../ehrbase/aql/sql/binding/JoinBinder.java | 33 +++---- .../ehrbase/aql/sql/binding/LateralJoins.java | 2 +- .../aql/sql/binding/OrderByBinder.java | 25 ++++-- .../ehrbase/aql/sql/binding/SuperQuery.java | 5 +- .../aql/sql/queryimpl/AqlRoutines.java | 38 ++++----- .../queryimpl/CompositionAttributeQuery.java | 4 +- .../FunctionBasedNodePredicateCall.java | 13 +-- .../aql/sql/queryimpl/JsonbEntryQuery.java | 2 +- .../ehrbase/aql/sql/queryimpl/NullField.java | 16 ++-- .../attribute/TemporalWithTimeZone.java | 10 +-- .../composition/CompositionName.java | 58 ------------- .../composition/CompositionUidValue.java | 20 ++--- .../composition/FullCompositionJson.java | 20 ++--- .../SimpleCompositionAttribute.java | 5 +- .../queryimpl/attribute/ehr/EhrIdValue.java | 15 ++-- .../queryimpl/attribute/ehr/FullEhrJson.java | 43 ++++------ .../ehr/ehrstatus/EhrStatusJson.java | 15 ++-- .../ehrstatus/SimpleEhrStatusAttribute.java | 3 +- .../eventcontext/EventContextJson.java | 3 +- .../SimpleEventContextAttribute.java | 3 +- .../partyref/SimplePartyRefAttribute.java | 3 +- .../attribute/setting/SettingAttribute.java | 7 +- .../attribute/system/SystemAttribute.java | 3 +- .../queryimpl/value_field/FormattedField.java | 70 --------------- .../sql/queryimpl/value_field/Functions.java | 5 ++ .../value_field/GenericJsonField.java | 28 +++--- .../value_field/SimpleAttribute.java | 60 ------------- .../ehrbase/dao/access/jooq/EntryAccess.java | 20 ++--- .../jooq/party/PersistedPartyRelated.java | 5 +- .../repository/EhrFolderRepository.java | 4 +- .../repository/PartyProxyRepository.java | 5 +- .../aql/sql/binding/OrderByBinderTest.java | 27 +++--- .../FunctionBasedNodePredicateCallTest.java | 40 ++++----- .../attribute/TemporalWithTimeZoneTest.java | 2 +- .../queryimpl/translator/testcase/UC40.java | 9 +- .../testcase/pg10/pgsql/UC15Test.java | 2 +- .../testcase/pg10/pgsql/UC20Test.java | 2 +- .../testcase/pg10/pgsql/UC21Test.java | 2 +- .../testcase/pg10/pgsql/UC23Test.java | 2 +- .../testcase/pg10/pgsql/UC24Test.java | 2 +- .../testcase/pg10/pgsql/UC27Test.java | 6 +- .../testcase/pg10/pgsql/UC28Test.java | 6 +- .../testcase/pg10/pgsql/UC29Test.java | 6 +- .../testcase/pg10/pgsql/UC30Test.java | 6 +- .../testcase/pg10/pgsql/UC31Test.java | 8 +- .../testcase/pg10/pgsql/UC32Test.java | 2 +- .../testcase/pg10/pgsql/UC33Test.java | 6 +- .../testcase/pg10/pgsql/UC34Test.java | 2 +- .../testcase/pg10/pgsql/UC35Test.java | 4 +- .../testcase/pg10/pgsql/UC36Test.java | 4 +- .../testcase/pg10/pgsql/UC40Test.java | 2 +- .../testcase/pg10/pgsql/UC41Test.java | 2 +- .../testcase/pg10/pgsql/UC42Test.java | 36 +------- .../testcase/pg10/pgsql/UC43Test.java | 26 +++--- .../testcase/pg10/pgsql/UC46Test.java | 2 +- .../testcase/pg10/pgsql/UC4Test.java | 4 +- .../testcase/pg10/pgsql/UC6Test.java | 2 +- .../testcase/pg10/pgsql/UC8Test.java | 2 +- .../value_field/FormattedFieldTest.java | 68 --------------- .../value_field/GenericJsonFieldTest.java | 14 ++- 70 files changed, 468 insertions(+), 605 deletions(-) create mode 100644 service/src/main/java/org/ehrbase/aql/definition/CastFunctionDefinition.java delete mode 100644 service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/composition/CompositionName.java delete mode 100644 service/src/main/java/org/ehrbase/aql/sql/queryimpl/value_field/FormattedField.java delete mode 100644 service/src/main/java/org/ehrbase/aql/sql/queryimpl/value_field/SimpleAttribute.java delete mode 100644 service/src/test/java/org/ehrbase/aql/sql/queryimpl/value_field/FormattedFieldTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fe953cf8..bfcd18d11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - Removed authorization scopes from endpoints and added support for overwriting controllers ([#1157](https://github.com/ehrbase/ehrbase/pull/1157)) ### Fixed - Fix audit logs location ([#1160](https://github.com/ehrbase/ehrbase/pull/1160)) + - Address AQL query security vulnerabilities ([#1190](https://github.com/ehrbase/ehrbase/pull/1190)) ## [0.30.0] ### Added diff --git a/service/src/main/antlr4/org/ehrbase/aql/parser/Aql.g4 b/service/src/main/antlr4/org/ehrbase/aql/parser/Aql.g4 index 461c0d0c4..c9162a589 100644 --- a/service/src/main/antlr4/org/ehrbase/aql/parser/Aql.g4 +++ b/service/src/main/antlr4/org/ehrbase/aql/parser/Aql.g4 @@ -30,10 +30,10 @@ topExpr // | TOP INTEGER FORWARD ; function - : FUNCTION_IDENTIFIER OPEN_PAR (IDENTIFIER|identifiedPath|operand|) (COMMA (IDENTIFIER|identifiedPath|operand))* CLOSE_PAR; + : FUNCTION_IDENTIFIER OPEN_PAR (function|identifiedPath|operand|) (COMMA (function|identifiedPath|operand))* CLOSE_PAR; castFunction : - CAST_FUNCTION_IDENTIFIER OPEN_PAR (IDENTIFIER|identifiedPath|operand) AS STRING CLOSE_PAR; + CAST_FUNCTION_IDENTIFIER OPEN_PAR (function|identifiedPath|operand) AS STRING CLOSE_PAR; extension : EXTENSION_IDENTIFIER OPEN_PAR STRING COMMA STRING CLOSE_PAR; diff --git a/service/src/main/java/org/ehrbase/aql/compiler/QueryCompilerPass2.java b/service/src/main/java/org/ehrbase/aql/compiler/QueryCompilerPass2.java index 416987a16..933208b9f 100644 --- a/service/src/main/java/org/ehrbase/aql/compiler/QueryCompilerPass2.java +++ b/service/src/main/java/org/ehrbase/aql/compiler/QueryCompilerPass2.java @@ -29,6 +29,7 @@ import org.antlr.v4.runtime.tree.ParseTree; import org.antlr.v4.runtime.tree.TerminalNode; import org.apache.commons.lang3.StringUtils; +import org.ehrbase.aql.definition.CastFunctionDefinition; import org.ehrbase.aql.definition.ConstantDefinition; import org.ehrbase.aql.definition.ExtensionDefinition; import org.ehrbase.aql.definition.FuncParameter; @@ -102,6 +103,7 @@ public class QueryCompilerPass2 extends AqlBaseListener { private final Deque variableStack = new ArrayDeque<>(); private final Map predicateDefinitionMap = new HashMap<>(); private final Random random = new Random(); + private int serial = 0; private Deque orderAttributes = null; private Integer limitAttribute = null; @@ -196,6 +198,12 @@ private void pushVariableDefinition(I_VariableDefinition variableDefinition) { private void handleFunctionDefinition( AqlParser.FunctionContext functionContext, AqlParser.SelectExprContext inSelectExprContext) { + FunctionDefinition definition = handleFunctionDefinitionInner(functionContext, inSelectExprContext); + pushVariableDefinition(definition); + } + + private FunctionDefinition handleFunctionDefinitionInner( + AqlParser.FunctionContext functionContext, AqlParser.SelectExprContext inSelectExprContext) { logger.debug("Found function"); String name = functionContext.FUNCTION_IDENTIFIER().getText(); @@ -205,8 +213,6 @@ private void handleFunctionDefinition( List parameters = new ArrayList<>(); - int serial = 0; - for (ParseTree pathTree : functionContext.children) { if (pathTree instanceof AqlParser.IdentifiedPathContext) { AqlParser.IdentifiedPathContext pathContext = (AqlParser.IdentifiedPathContext) pathTree; @@ -224,8 +230,14 @@ private void handleFunctionDefinition( variableDefinition.getAlias() == null ? variableDefinition.getPath() : variableDefinition.getAlias())); - } else if (pathTree instanceof AqlParser.OperandContext) { - parameters.add(new FuncParameter(FuncParameterType.OPERAND, pathTree.getText())); + } else if (pathTree instanceof AqlParser.OperandContext operandContext) { + + parameters.add(new FuncParameter(FuncParameterType.OPERAND, handleOperator(operandContext))); + } else if (pathTree instanceof AqlParser.FunctionContext functionContextInner) { + parameters.add(new FuncParameter( + FuncParameterType.FUNCTION, + handleFunctionDefinitionInner(functionContextInner, inSelectExprContext))); + } else if (pathTree instanceof TerminalNode) { parameters.add(new FuncParameter(FuncParameterType.IDENTIFIER, pathTree.getText())); } @@ -239,8 +251,7 @@ private void handleFunctionDefinition( } } String path = functionContext.getText(); - FunctionDefinition definition = new FunctionDefinition(name, alias, path, parameters); - pushVariableDefinition(definition); + return new FunctionDefinition(name, alias, path, parameters); } private void handleCastFunctionDefinition( @@ -249,7 +260,7 @@ private void handleCastFunctionDefinition( List parameters = new ArrayList<>(); - int serial = 0; + FuncParameter cast = null; for (ParseTree pathTree : castFunctionContext.children) { if (pathTree instanceof AqlParser.IdentifiedPathContext) { @@ -263,13 +274,26 @@ private void handleCastFunctionDefinition( variableDefinition.setAlias("_FCT_ARG_" + serial++); } pushVariableDefinition(variableDefinition); - parameters.add(new FuncParameter( + FuncParameter funcParameter = new FuncParameter( FuncParameterType.VARIABLE, variableDefinition.getAlias() == null ? variableDefinition.getPath() - : variableDefinition.getAlias())); - } else if (pathTree instanceof AqlParser.OperandContext) { - parameters.add(new FuncParameter(FuncParameterType.OPERAND, pathTree.getText())); + : variableDefinition.getAlias()); + parameters.add(funcParameter); + cast = funcParameter; + } else if (pathTree instanceof AqlParser.OperandContext operandContext) { + FuncParameter funcParameter = + new FuncParameter(FuncParameterType.OPERAND, handleOperator(operandContext)); + cast = funcParameter; + parameters.add(funcParameter); + } else if (pathTree instanceof AqlParser.FunctionContext functionContextInner) { + + FuncParameter funcParameter = new FuncParameter( + FuncParameterType.FUNCTION, + handleFunctionDefinitionInner(functionContextInner, inSelectExprContext)); + cast = funcParameter; + parameters.add(funcParameter); + } else if (pathTree instanceof TerminalNode) { String text = pathTree.getText(); if (text.contains("'")) { @@ -286,7 +310,12 @@ private void handleCastFunctionDefinition( alias = "CAST"; } String path = castFunctionContext.getText(); - FunctionDefinition definition = new FunctionDefinition("CAST", alias, path, parameters); + FunctionDefinition definition = new CastFunctionDefinition( + alias, + path, + parameters, + cast, + StringUtils.strip(castFunctionContext.STRING().getText(), "'")); pushVariableDefinition(definition); } @@ -313,9 +342,9 @@ public void handleTerminalNodeExpression( } else if (inStdExpressionContext.TRUE() != null) { value = true; } else if (inStdExpressionContext.FLOAT() != null) { - value = Float.valueOf(inStdExpressionContext.getText()); + value = Double.valueOf(inStdExpressionContext.getText()); } else if (inStdExpressionContext.INTEGER() != null) { - value = Integer.valueOf(inStdExpressionContext.getText()); + value = Long.valueOf(inStdExpressionContext.getText()); } else if (inStdExpressionContext.NULL() != null) { value = null; } else if (inStdExpressionContext.REAL() != null) { @@ -333,6 +362,34 @@ public void handleTerminalNodeExpression( pushVariableDefinition(definition); } + private Object handleOperator(AqlParser.OperandContext operandContext) { + Object value; + if (operandContext.BOOLEAN() != null) { + value = Boolean.valueOf(operandContext.getText()); + } else if (operandContext.FALSE() != null) { + value = false; + } else if (operandContext.TRUE() != null) { + value = true; + } else if (operandContext.FLOAT() != null) { + value = Float.valueOf(operandContext.getText()); + } else if (operandContext.INTEGER() != null) { + value = Integer.valueOf(operandContext.getText()); + } else if (operandContext.NULL() != null) { + value = null; + } else if (operandContext.REAL() != null) { + value = Double.valueOf(operandContext.getText()); + } else if (operandContext.UNKNOWN() != null) { + value = null; + } else if (operandContext.STRING() != null) { + value = StringUtils.strip(operandContext.getText(), "'"); + } else // DATE() + { + value = operandContext.getText(); + } + + return value; + } + /** * check if a variable definition is unique (e.g. new aliase) * diff --git a/service/src/main/java/org/ehrbase/aql/definition/CastFunctionDefinition.java b/service/src/main/java/org/ehrbase/aql/definition/CastFunctionDefinition.java new file mode 100644 index 000000000..5b30cdbbb --- /dev/null +++ b/service/src/main/java/org/ehrbase/aql/definition/CastFunctionDefinition.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2023 vitasystems GmbH and Hannover Medical School. + * + * This file is part of project EHRbase + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.ehrbase.aql.definition; + +import java.util.List; + +/** + * @author Stefan Spiska + */ +public class CastFunctionDefinition extends FunctionDefinition { + + private final FuncParameter castee; + private final String targetType; + + public CastFunctionDefinition( + String alias, String path, List parameters, FuncParameter castee, String targetType) { + super("CAST", alias, path, parameters); + this.castee = castee; + this.targetType = targetType; + } + + public FuncParameter getCastee() { + return castee; + } + + public String getTargetType() { + return targetType; + } +} diff --git a/service/src/main/java/org/ehrbase/aql/definition/FuncParameter.java b/service/src/main/java/org/ehrbase/aql/definition/FuncParameter.java index 3e2ade56a..0cf4d83be 100644 --- a/service/src/main/java/org/ehrbase/aql/definition/FuncParameter.java +++ b/service/src/main/java/org/ehrbase/aql/definition/FuncParameter.java @@ -23,9 +23,9 @@ public class FuncParameter { private FuncParameterType type; - private String value; + private Object value; - public FuncParameter(FuncParameterType type, String value) { + public FuncParameter(FuncParameterType type, Object value) { this.type = type; this.value = value; } @@ -34,7 +34,7 @@ public FuncParameterType getType() { return type; } - public String getValue() { + public Object getValue() { return value; } diff --git a/service/src/main/java/org/ehrbase/aql/definition/FuncParameterType.java b/service/src/main/java/org/ehrbase/aql/definition/FuncParameterType.java index 2427b208d..e9c0bd92c 100644 --- a/service/src/main/java/org/ehrbase/aql/definition/FuncParameterType.java +++ b/service/src/main/java/org/ehrbase/aql/definition/FuncParameterType.java @@ -23,5 +23,6 @@ public enum FuncParameterType { VARIABLE, OPERAND, - IDENTIFIER + IDENTIFIER, + FUNCTION } diff --git a/service/src/main/java/org/ehrbase/aql/sql/QueryProcessor.java b/service/src/main/java/org/ehrbase/aql/sql/QueryProcessor.java index 65662884f..6c20e3857 100644 --- a/service/src/main/java/org/ehrbase/aql/sql/QueryProcessor.java +++ b/service/src/main/java/org/ehrbase/aql/sql/QueryProcessor.java @@ -413,7 +413,9 @@ private List> buildExplain(Select select) { List details = new ArrayList<>(); details.add(sql); for (Param parameter : select.getParams().values()) { - details.add(parameter.getValue().toString()); + if (!parameter.isInline()) { + details.add(parameter.getValue().toString()); + } } explainList.add(details); return explainList; diff --git a/service/src/main/java/org/ehrbase/aql/sql/binding/ConstantField.java b/service/src/main/java/org/ehrbase/aql/sql/binding/ConstantField.java index 85db51f7f..825a965e9 100644 --- a/service/src/main/java/org/ehrbase/aql/sql/binding/ConstantField.java +++ b/service/src/main/java/org/ehrbase/aql/sql/binding/ConstantField.java @@ -36,9 +36,11 @@ Field toSql() { Field field; ConstantDefinition constantDefinition = (ConstantDefinition) variableDefinition; - if (constantDefinition.getValue() == null) // assume NULL - field = DSL.field("NULL"); - else field = DSL.field(DSL.val(constantDefinition.getValue())); + if (constantDefinition.getValue() == null) { // assume NULL + field = DSL.inline((Object) null); + } else { + field = DSL.inline(constantDefinition.getValue()); + } if (constantDefinition.getAlias() != null) field = field.as(constantDefinition.getAlias()); else { diff --git a/service/src/main/java/org/ehrbase/aql/sql/binding/FieldConstantHandler.java b/service/src/main/java/org/ehrbase/aql/sql/binding/FieldConstantHandler.java index d7db0f53b..a95c74ad4 100644 --- a/service/src/main/java/org/ehrbase/aql/sql/binding/FieldConstantHandler.java +++ b/service/src/main/java/org/ehrbase/aql/sql/binding/FieldConstantHandler.java @@ -51,7 +51,7 @@ public Field field() { List segments = LocatableHelper.dividePathIntoSegments(variableDefinition.getPath()); if (segments.get(segments.size() - 1).equals(I_DvTypeAdapter.ARCHETYPE_NODE_ID)) - return DSL.field(DSL.val(implicitArchetypeNodeId(segments.get(segments.size() - 2)))) + return DSL.inline(implicitArchetypeNodeId(segments.get(segments.size() - 2))) .as(alias()); return null; } diff --git a/service/src/main/java/org/ehrbase/aql/sql/binding/FunctionExpression.java b/service/src/main/java/org/ehrbase/aql/sql/binding/FunctionExpression.java index 3e00d9f46..2756e4643 100644 --- a/service/src/main/java/org/ehrbase/aql/sql/binding/FunctionExpression.java +++ b/service/src/main/java/org/ehrbase/aql/sql/binding/FunctionExpression.java @@ -19,8 +19,15 @@ import java.util.ArrayList; import java.util.List; +import org.ehrbase.aql.definition.CastFunctionDefinition; import org.ehrbase.aql.definition.FuncParameter; +import org.ehrbase.aql.definition.FuncParameterType; import org.ehrbase.aql.definition.I_VariableDefinition; +import org.jooq.DataType; +import org.jooq.Field; +import org.jooq.SelectQuery; +import org.jooq.impl.DSL; +import org.jooq.impl.SQLDataType; /** * handles function expression and parameters. @@ -28,33 +35,79 @@ public class FunctionExpression { private final I_VariableDefinition functionDefinition; + private final SelectQuery query; private final VariableDefinitions variables; - FunctionExpression(VariableDefinitions variables, I_VariableDefinition functionDefinition) { + FunctionExpression(VariableDefinitions variables, I_VariableDefinition functionDefinition, SelectQuery query) { this.variables = variables; this.functionDefinition = functionDefinition; + this.query = query; } - public String toString() { + public Field buildField() { - StringBuilder expression = new StringBuilder(); + if (functionDefinition instanceof CastFunctionDefinition castFunctionDefinition) { + return to(castFunctionDefinition.getCastee()).cast(getType(castFunctionDefinition.getTargetType())); + } - for (FuncParameter parameter : functionDefinition.getFuncParameters()) { - if (parameter.isVariable()) { - if (variables.isDistinct(parameter.getValue())) expression.append("DISTINCT "); - expression.append("\""); - expression.append(parameter.getValue()); - expression.append("\""); - } else expression.append(parameter.getValue()); + if (isAggregateDistinct()) { + return DSL.aggregateDistinct( + functionDefinition.getIdentifier(), + Object.class, + functionDefinition.getFuncParameters().stream() + .filter(funcParameter -> !funcParameter.isIdentifier()) + .map(this::to) + .toArray(i -> new Field[i])); + } else { + return DSL.function( + functionDefinition.getIdentifier(), + Object.class, + functionDefinition.getFuncParameters().stream() + .filter(funcParameter -> !funcParameter.isIdentifier()) + .map(this::to) + .toArray(i -> new Field[i])); } - return expression.toString(); + } + + private DataType getType(String as) { + + return switch (as.toUpperCase()) { + case "DATE" -> SQLDataType.DATE; + case "TIME" -> SQLDataType.TIME; + case "INTERVAL" -> SQLDataType.INTERVAL; + case "TIMESTAMP" -> SQLDataType.TIMESTAMP; + case "NUMERIC" -> SQLDataType.NUMERIC; + default -> SQLDataType.VARCHAR; + }; + } + + private boolean isAggregateDistinct() { + return functionDefinition.getFuncParameters().stream() + .filter(FuncParameter::isVariable) + .anyMatch(f -> variables.isDistinct(f.getValue().toString())); + } + + private Field to(FuncParameter funcParameter) { + + return switch (funcParameter.getType()) { + case VARIABLE -> OrderByBinder.find(query, funcParameter.getValue().toString()); + case OPERAND -> DSL.inline(funcParameter.getValue()); + case IDENTIFIER -> throw new UnsupportedOperationException( + funcParameter.getType().toString()); + case FUNCTION -> new FunctionExpression(variables, (I_VariableDefinition) funcParameter.getValue(), query) + .buildField(); + }; } List arguments() { List args = new ArrayList<>(); for (FuncParameter parameter : functionDefinition.getFuncParameters()) { - if (parameter.isVariable()) args.add(parameter.getValue()); + if (parameter.isVariable()) args.add(parameter.getValue().toString()); + if (parameter.getType().equals(FuncParameterType.FUNCTION)) { + args.addAll(new FunctionExpression(variables, (I_VariableDefinition) parameter.getValue(), query) + .arguments()); + } } return args; diff --git a/service/src/main/java/org/ehrbase/aql/sql/binding/JoinBinder.java b/service/src/main/java/org/ehrbase/aql/sql/binding/JoinBinder.java index daaa84250..d2b2bf239 100644 --- a/service/src/main/java/org/ehrbase/aql/sql/binding/JoinBinder.java +++ b/service/src/main/java/org/ehrbase/aql/sql/binding/JoinBinder.java @@ -28,7 +28,6 @@ import org.jooq.JoinType; import org.jooq.SelectQuery; import org.jooq.Table; -import org.jooq.impl.DSL; /** * Created by christian on 10/31/2016. @@ -152,7 +151,7 @@ private void joinComposition(SelectQuery selectQuery) { selectQuery.addJoin( compositionRecordTable, JoinType.RIGHT_OUTER_JOIN, - DSL.field(compositionRecordTable.field(COMPOSITION.ID)).eq(ENTRY.COMPOSITION_ID)); + compositionRecordTable.field(COMPOSITION.ID).eq(ENTRY.COMPOSITION_ID)); compositionJoined = true; } @@ -161,8 +160,7 @@ private void joinSystem(SelectQuery selectQuery) { selectQuery.addJoin( systemRecordTable, JoinType.JOIN, - DSL.field(systemRecordTable.field(SYSTEM.ID)) - .eq(DSL.field(ehrRecordTable.field(EHR_.SYSTEM_ID.getName(), UUID.class)))); + systemRecordTable.field(SYSTEM.ID).eq(ehrRecordTable.field(EHR_.SYSTEM_ID.getName(), UUID.class))); systemJoined = true; } @@ -172,15 +170,17 @@ private void joinEhrStatus(SelectQuery selectQuery, JoinSetup joinSetup) { joinComposition(selectQuery); selectQuery.addJoin( statusRecordTable, - DSL.field(statusRecordTable.field(STATUS.EHR_ID.getName(), UUID.class)) - .eq(DSL.field(compositionRecordTable.field(COMPOSITION.EHR_ID.getName(), UUID.class)))); + statusRecordTable + .field(STATUS.EHR_ID.getName(), UUID.class) + .eq(compositionRecordTable.field(COMPOSITION.EHR_ID.getName(), UUID.class))); statusJoined = true; } else { // assume it is joined on EHR if (joinSetup.isJoinEhr()) joinEhr(selectQuery); selectQuery.addJoin( statusRecordTable, - DSL.field(statusRecordTable.field(STATUS.EHR_ID.getName(), UUID.class)) - .eq(DSL.field(ehrRecordTable.field(EHR_.ID.getName(), UUID.class)))); + statusRecordTable + .field(STATUS.EHR_ID.getName(), UUID.class) + .eq(ehrRecordTable.field(EHR_.ID.getName(), UUID.class))); statusJoined = true; } } @@ -191,8 +191,9 @@ private void joinSubject(SelectQuery selectQuery, JoinSetup joinSetup) { Table subjectTable = subjectRef; selectQuery.addJoin( subjectTable, - DSL.field(subjectTable.field(PARTY_IDENTIFIED.ID.getName(), UUID.class)) - .eq(DSL.field(statusRecordTable.field(STATUS.PARTY.getName(), UUID.class)))); + subjectTable + .field(PARTY_IDENTIFIED.ID.getName(), UUID.class) + .eq(statusRecordTable.field(STATUS.PARTY.getName(), UUID.class))); subjectJoin = true; } @@ -209,7 +210,7 @@ private void joinContextFacility(SelectQuery selectQuery) { selectQuery.addJoin( facilityTable, JoinType.LEFT_OUTER_JOIN, - EVENT_CONTEXT.FACILITY.eq(DSL.field(facilityTable.field(PARTY_IDENTIFIED.ID.getName(), UUID.class)))); + EVENT_CONTEXT.FACILITY.eq(facilityTable.field(PARTY_IDENTIFIED.ID.getName(), UUID.class))); facilityJoined = true; } @@ -219,8 +220,9 @@ private void joinComposer(SelectQuery selectQuery) { Table composerTable = composerRef; selectQuery.addJoin( composerTable, - DSL.field(compositionRecordTable.field(COMPOSITION.COMPOSER.getName(), UUID.class)) - .eq(DSL.field(composerTable.field(PARTY_IDENTIFIED.ID.getName(), UUID.class)))); + compositionRecordTable + .field(COMPOSITION.COMPOSER.getName(), UUID.class) + .eq(composerTable.field(PARTY_IDENTIFIED.ID.getName(), UUID.class))); composerJoined = true; } @@ -230,8 +232,9 @@ private void joinEhr(SelectQuery selectQuery) { selectQuery.addJoin( ehrRecordTable, JoinType.RIGHT_OUTER_JOIN, - DSL.field(ehrRecordTable.field(EHR_.ID.getName(), UUID.class)) - .eq(DSL.field(compositionRecordTable.field(COMPOSITION.EHR_ID.getName(), UUID.class)))); + ehrRecordTable + .field(EHR_.ID.getName(), UUID.class) + .eq(compositionRecordTable.field(COMPOSITION.EHR_ID.getName(), UUID.class))); ehrJoined = true; } } diff --git a/service/src/main/java/org/ehrbase/aql/sql/binding/LateralJoins.java b/service/src/main/java/org/ehrbase/aql/sql/binding/LateralJoins.java index 29f178a31..f33a1c40d 100644 --- a/service/src/main/java/org/ehrbase/aql/sql/binding/LateralJoins.java +++ b/service/src/main/java/org/ehrbase/aql/sql/binding/LateralJoins.java @@ -87,7 +87,7 @@ public static void create( String variableAlias = "var_" + abs + "_" + inc(); SelectSelectStep wrappedSelectSelectStep = - DSL.select(DSL.field(selectSelectStep).as(variableAlias)); + DSL.select(selectSelectStep.asField().as(variableAlias)); Table table = DSL.table(wrappedSelectSelectStep).as(tableAlias); item.setLateralJoinTable( diff --git a/service/src/main/java/org/ehrbase/aql/sql/binding/OrderByBinder.java b/service/src/main/java/org/ehrbase/aql/sql/binding/OrderByBinder.java index f1aad14ab..13cb4e1ba 100644 --- a/service/src/main/java/org/ehrbase/aql/sql/binding/OrderByBinder.java +++ b/service/src/main/java/org/ehrbase/aql/sql/binding/OrderByBinder.java @@ -22,12 +22,13 @@ import java.util.Iterator; import java.util.List; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang.StringUtils; import org.ehrbase.aql.compiler.OrderAttribute; import org.ehrbase.aql.definition.I_VariableDefinition; +import org.jooq.Field; import org.jooq.Record; import org.jooq.SelectQuery; import org.jooq.SortField; -import org.jooq.impl.DSL; /** * Created by christian on 9/23/2016. @@ -46,13 +47,13 @@ public class OrderByBinder { this.variableDefinitions = variableDefinitions; } - List> getOrderByFields() { + List> getOrderByFields() { if (orderAttributes.isEmpty()) return Collections.emptyList(); - List> orderFields = new ArrayList<>(); + List> orderFields = new ArrayList<>(); for (OrderAttribute orderAttribute : orderAttributes) { - SortField field; + SortField field; String fieldIdentifier = null; // get the corresponding variable definition @@ -80,20 +81,26 @@ List> getOrderByFields() { orderAttribute.getVariableDefinition().setHidden(true); } - if (!fieldIdentifier.startsWith("\"")) - fieldIdentifier = "\"" + fieldIdentifier + "\""; // by postgresql convention - if (orderAttribute.getDirection() != null && orderAttribute.getDirection().equals(OrderAttribute.OrderDirection.DESC)) { - field = DSL.field(fieldIdentifier).desc(); + field = find(select, fieldIdentifier).desc(); } else // default to ASCENDING - field = DSL.field(fieldIdentifier).asc(); + field = find(select, fieldIdentifier).asc(); orderFields.add(field); } + return orderFields; } + public static Field find(SelectQuery selectQuery, String fieldIdentifier) { + return selectQuery.getSelect().stream() + .filter(a -> StringUtils.strip(a.getUnqualifiedName().toString(), "\"") + .equals(fieldIdentifier)) + .findFirst() + .orElseThrow(); + } + public SelectQuery bind() { if (CollectionUtils.isNotEmpty(orderAttributes)) { diff --git a/service/src/main/java/org/ehrbase/aql/sql/binding/SuperQuery.java b/service/src/main/java/org/ehrbase/aql/sql/binding/SuperQuery.java index bb08875f4..0c44f3459 100644 --- a/service/src/main/java/org/ehrbase/aql/sql/binding/SuperQuery.java +++ b/service/src/main/java/org/ehrbase/aql/sql/binding/SuperQuery.java @@ -116,8 +116,9 @@ private SelectQuery selectAggregate(SelectQuery selectQuery) { if (variableDefinition.isFunction()) { skipField.add(alias); - FunctionExpression functionExpression = new FunctionExpression(variableDefinitions, variableDefinition); - Field field = field(functionExpression.toString()); + FunctionExpression functionExpression = + new FunctionExpression(variableDefinitions, variableDefinition, this.query); + Field field = functionExpression.buildField(); skipField.addAll(functionExpression.arguments()); if (variableDefinition.getAlias() != null) { diff --git a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/AqlRoutines.java b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/AqlRoutines.java index 304447a87..dc43da0a7 100644 --- a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/AqlRoutines.java +++ b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/AqlRoutines.java @@ -18,10 +18,9 @@ package org.ehrbase.aql.sql.queryimpl; import static org.ehrbase.aql.sql.queryimpl.QueryImplConstants.AQL_NODE_ITERATIVE_FUNCTION; -import static org.ehrbase.aql.sql.queryimpl.QueryImplConstants.AQL_NODE_NAME_PREDICATE_MARKER; import java.util.Arrays; -import java.util.stream.Collectors; +import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.jooq.Configuration; import org.jooq.Field; @@ -35,45 +34,46 @@ private AqlRoutines() { } public static Field jsonArraySplitElements(Field jsonbVal) { - return DSL.field(AQL_NODE_ITERATIVE_FUNCTION + "(" + jsonbVal + ")").cast(JSONB.class); + + return DSL.function(AQL_NODE_ITERATIVE_FUNCTION, JSONB.class, jsonbVal); } public static Field jsonArraySplitElements(Configuration configuration, Field jsonbVal) { isSupported(configuration); - return DSL.field(AQL_NODE_ITERATIVE_FUNCTION + "(" + jsonbVal + ")").cast(JSONB.class); + + return jsonArraySplitElements(jsonbVal); } public static Field jsonpathItem(Field jsonbVal, String[] elements) { - return DSL.field("jsonb_extract_path(" + jsonbVal + "," + String.join(",", elements) + ")") - .cast(JSONB.class); + + return DSL.function("jsonb_extract_path", JSONB.class, ArrayUtils.addFirst(buildParameter(elements), jsonbVal)); } public static Field jsonpathItem(Configuration configuration, Field jsonbVal, String[] elements) { isSupported(configuration); - return DSL.field("jsonb_extract_path(" + jsonbVal + "," + String.join(",", elements) + ")") - .cast(JSONB.class); + return jsonpathItem(jsonbVal, elements); } - public static Field toJson(Configuration configuration, String expression) { - isSupported(configuration); - return DSL.field("to_json(" + expression + ")").cast(JSONB.class); - } + public static Field jsonpathItemAsText(Field jsonbVal, String[] elements) { - public static String jsonpathItemAsText(Field jsonbVal, String[] elements) { - return "jsonb_extract_path_text(" + jsonbVal + "," + String.join(",", elements) + ")"; + return DSL.function( + "jsonb_extract_path_text", String.class, ArrayUtils.addFirst(buildParameter(elements), jsonbVal)); } - public static String jsonpathItemAsText(Configuration configuration, Field jsonbVal, String[] elements) { + public static Field jsonpathItemAsText( + Configuration configuration, Field jsonbVal, String[] elements) { isSupported(configuration); - return "jsonb_extract_path_text(" + jsonbVal + "," + String.join(",", elements) + ")"; + return jsonpathItemAsText(jsonbVal, elements); + } + + private static Field[] buildParameter(String[] elements) { + return Arrays.stream(elements).map(DSL::inline).toArray(Field[]::new); } public static String[] jsonpathParameters(String rawParameters) { String parametersFormatted = StringUtils.remove(StringUtils.remove(rawParameters, "'{"), "}'"); return Arrays.stream(parametersFormatted.split(",")) .map(s -> (s.startsWith("'") ? s.replace("'", "") : s)) - .map(s -> (!s.equals(AQL_NODE_NAME_PREDICATE_MARKER) ? "'" + s + "'" : s)) - .collect(Collectors.toList()) - .toArray(new String[] {}); + .toArray(String[]::new); } } diff --git a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/CompositionAttributeQuery.java b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/CompositionAttributeQuery.java index 8b8bba546..e5ffd111e 100644 --- a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/CompositionAttributeQuery.java +++ b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/CompositionAttributeQuery.java @@ -133,7 +133,9 @@ else if (columnAlias.startsWith("context")) .getTable() .getName() + "." + variableDefinition.getSubstituteFieldVariable(); retField = DSL.field(sqlToLateralJoin).as(retField.getName()); - } else if (fieldResolutionContext.isUsingSetReturningFunction()) retField = DSL.field(DSL.select(retField)); + } else if (fieldResolutionContext.isUsingSetReturningFunction()) { + retField = DSL.select(retField).asField(); + } QualifiedAqlField aqlField = new QualifiedAqlField(retField); diff --git a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/FunctionBasedNodePredicateCall.java b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/FunctionBasedNodePredicateCall.java index b2078484a..f32c1707f 100644 --- a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/FunctionBasedNodePredicateCall.java +++ b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/FunctionBasedNodePredicateCall.java @@ -28,6 +28,7 @@ import java.util.List; import org.apache.commons.lang3.ArrayUtils; import org.ehrbase.aql.sql.queryimpl.attribute.FieldResolutionContext; +import org.ehrbase.aql.sql.queryimpl.value_field.Functions; import org.jooq.Configuration; import org.jooq.Field; import org.jooq.JSONB; @@ -77,7 +78,7 @@ private List resolveNodePredicateCall( Field nodeField; if (!itemPathArray.get(0).replace("\"", "").startsWith(QueryImplConstants.AQL_NODE_NAME_PREDICATE_FUNCTION)) { - nodeField = DSL.field(apply(function, tableFields).toString()).cast(JSONB.class); + nodeField = Functions.inline(apply(function, tableFields)).cast(JSONB.class); startList = 0; } else { nodeField = DSL.field(itemPathArray.get(0)); @@ -91,12 +92,12 @@ private List resolveNodePredicateCall( markerPos = itemPathArray.size(); expression.add(aqlNodeNamePredicate( - DSL.field(jsonpathItemAsText( + jsonpathItemAsText( configuration, nodeField, itemPathArray .subList(startList, markerPos) - .toArray(new String[] {}))) + .toArray(new String[] {})) .cast(JSONB.class), DSL.val(itemPathArray.get(markerPos + 1).replace("'", "")), DSL.val("")) @@ -113,8 +114,8 @@ private List resolveNodePredicateCall( if (!expression.contains(QueryImplConstants.AQL_NODE_NAME_PREDICATE_MARKER) && extractPathArguments.length > 0) { List resultList = new ArrayList<>(); - resultList.add(DSL.field(jsonpathItemAsText( - configuration, DSL.field(expression.get(0)).cast(JSONB.class), extractPathArguments)) + resultList.add(jsonpathItemAsText( + configuration, DSL.field(expression.get(0)).cast(JSONB.class), extractPathArguments) .toString()); expression = resultList; } @@ -127,7 +128,7 @@ private String[] rightPathExpression(List itemPathArray, int from, int t .subList( // test if the starting item is an index, then skip it as it is mutually exclusive with node // name predicate node selection - itemPathArray.get(from + 2).matches("'[0-9]*'|#") ? from + 3 : from + 2, to) + itemPathArray.get(from + 2).matches("[0-9]*|#") ? from + 3 : from + 2, to) .toArray(new String[] {}); } diff --git a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/JsonbEntryQuery.java b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/JsonbEntryQuery.java index e83438c66..b599870f5 100644 --- a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/JsonbEntryQuery.java +++ b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/JsonbEntryQuery.java @@ -234,7 +234,7 @@ public MultiFields makeField( } else if (clause.equals(Clause.WHERE)) { fieldPathItem = buildFieldWithCast(itemPath, castTypeAs, null); if (itemPathArray.contains(AQL_NODE_ITERATIVE_MARKER)) - fieldPathItem = DSL.field(DSL.select(fieldPathItem)); + fieldPathItem = DSL.select(fieldPathItem).asField(); } if (setReturningFunctionInWhere) diff --git a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/NullField.java b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/NullField.java index c8263cdee..8e70960c2 100644 --- a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/NullField.java +++ b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/NullField.java @@ -34,15 +34,21 @@ public NullField(I_VariableDefinition variableDefinition, String alias) { } public Field instance() { + // return a null field - String cast = ""; + Field nullField = DSL.inline((Object) null); + // force explicit type cast for DvQuantity if (variableDefinition != null && variableDefinition.getPath() != null - && variableDefinition.getPath().endsWith(MAGNITUDE)) cast = "::numeric"; + && variableDefinition.getPath().endsWith(MAGNITUDE)) { + nullField = nullField.cast(Double.class); + } - if (variableDefinition != null && alias != null) - return DSL.field(DSL.val((String) null) + cast).as(alias); - else return DSL.field(DSL.val((String) null) + cast); + if (variableDefinition != null && alias != null) { + return nullField.as(alias); + } else { + return nullField; + } } } diff --git a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/TemporalWithTimeZone.java b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/TemporalWithTimeZone.java index 18b740b85..fe8d922b9 100644 --- a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/TemporalWithTimeZone.java +++ b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/TemporalWithTimeZone.java @@ -20,7 +20,6 @@ import static org.ehrbase.aql.sql.queryimpl.AqlRoutines.jsonpathItemAsText; import static org.ehrbase.aql.sql.queryimpl.AqlRoutines.jsonpathParameters; import static org.ehrbase.jooq.pg.Routines.jsDvDateTime; -import static org.jooq.impl.DSL.field; import org.ehrbase.aql.sql.queryimpl.attribute.eventcontext.SimpleEventContextAttribute; import org.jooq.Field; @@ -38,10 +37,11 @@ public TemporalWithTimeZone(FieldResolutionContext fieldContext, JoinSetup joinS @Override public Field sqlField() { + // "ehr.js_dv_date_time("+tableField+"::timestamptz, // COALESCE("+timeZoneField+"::text,'UTC'))::json #>>'{value}'") - return as(field(jsonpathItemAsText( - jsDvDateTime(tableField, timeZoneField).cast(JSONB.class), jsonpathParameters("value")))); + return as(jsonpathItemAsText( + jsDvDateTime(tableField, timeZoneField).cast(JSONB.class), jsonpathParameters("value"))); } public TemporalWithTimeZone useTimeZone(TableField tableField) { @@ -53,8 +53,8 @@ public TemporalWithTimeZone useTimeZone(TableField tableField) { public IRMObjectAttribute forTableField(TableField tableField) { this.tableField = tableField; if (timeZoneField == null) { - String tzFieldName = tableField.getName().toUpperCase() + "_TZID"; // conventionally - timeZoneField = field(tableField.getTable().getName() + "." + tzFieldName); + String tzFieldName = tableField.getName() + "_tzid"; // conventionally + timeZoneField = tableField.getTable().field(tzFieldName); } return this; } diff --git a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/composition/CompositionName.java b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/composition/CompositionName.java deleted file mode 100644 index 285fee5a3..000000000 --- a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/composition/CompositionName.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2019 vitasystems GmbH and Hannover Medical School. - * - * This file is part of project EHRbase - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.ehrbase.aql.sql.queryimpl.attribute.composition; - -import static org.ehrbase.jooq.pg.Tables.ENTRY; - -import org.ehrbase.aql.sql.queryimpl.IQueryImpl; -import org.ehrbase.aql.sql.queryimpl.attribute.FieldResolutionContext; -import org.ehrbase.aql.sql.queryimpl.attribute.IRMObjectAttribute; -import org.ehrbase.aql.sql.queryimpl.attribute.JoinSetup; -import org.jooq.Field; -import org.jooq.TableField; -import org.jooq.impl.DSL; - -public class CompositionName extends CompositionAttribute { - - public CompositionName(FieldResolutionContext fieldContext, JoinSetup joinSetup) { - super(fieldContext, joinSetup); - } - - @Override - public Field sqlField() { - // extract the composition name from the jsonb root key - String trimName = "trim(LEADING '''' FROM (trim(TRAILING ''']' FROM\n" - + " (regexp_split_to_array((select root_json_key from jsonb_object_keys(" - + ENTRY.ENTRY_ + ") root_json_key where root_json_key like '/composition%')," - + " 'and name/value=')) [2])))"; - // postgresql equivalent expression - if (fieldContext.isWithAlias()) { - return aliased(DSL.field(trimName)); - } else { - if (fieldContext.getClause().equals(IQueryImpl.Clause.WHERE)) { - trimName = "(SELECT " + trimName + ")"; - } - return defaultAliased(DSL.field(trimName)); - } - } - - @Override - public IRMObjectAttribute forTableField(TableField tableField) { - return this; - } -} diff --git a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/composition/CompositionUidValue.java b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/composition/CompositionUidValue.java index 2ebe4a764..7ff2dcf94 100644 --- a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/composition/CompositionUidValue.java +++ b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/composition/CompositionUidValue.java @@ -29,7 +29,6 @@ import org.jooq.SelectQuery; import org.jooq.TableField; import org.jooq.impl.DSL; -import org.jooq.impl.SQLDataType; public class CompositionUidValue extends CompositionAttribute { @@ -53,7 +52,7 @@ public IRMObjectAttribute forTableField(TableField tableField) { return this; } - private Field uid() { + private Field uid() { // use inline SQL as it seems coalesce is not going through with POSTGRES dialect SelectQuery subSelect = fieldContext.getContext().selectQuery(); @@ -63,22 +62,13 @@ private Field uid() { JoinBinder.compositionRecordTable.field("id", UUID.class).eq(COMPOSITION_HISTORY.ID)); subSelect.addGroupBy(COMPOSITION_HISTORY.ID); - String coalesceVersion = "1 + COALESCE(\n(" + subSelect + "), 0)"; + Field version = DSL.inline(1).plus(DSL.function("COALESCE", Integer.class, subSelect.asField())); - return aliased(DSL.field( - JoinBinder.compositionRecordTable.field("id") - + "||" - + DSL.val("::") - + "||" - + DSL.val(fieldContext.getServerNodeId()) - + "||" - + DSL.val("::") - + "||" - + DSL.field(coalesceVersion), - SQLDataType.VARCHAR)); + return DSL.concat( + rawUid(), DSL.inline("::"), DSL.inline(fieldContext.getServerNodeId()), DSL.inline("::"), version); } private Field rawUid() { - return as(DSL.field(JoinBinder.compositionRecordTable.field("id", UUID.class))); + return as(JoinBinder.compositionRecordTable.field("id", UUID.class)); } } diff --git a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/composition/FullCompositionJson.java b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/composition/FullCompositionJson.java index 099c4a5c9..ed2e76932 100644 --- a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/composition/FullCompositionJson.java +++ b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/composition/FullCompositionJson.java @@ -55,22 +55,20 @@ public Field sqlField() { Field jsonFullComposition; if (jsonPath.isPresent()) { - jsonFullComposition = DSL.field(jsonpathItemAsText( + jsonFullComposition = jsonpathItemAsText( configuration, jsComposition2( - DSL.field(JoinBinder.compositionRecordTable.getName() + "." + tableField.getName()) - .cast(UUID.class), - DSL.val(fieldContext.getServerNodeId())) + JoinBinder.compositionRecordTable.field(tableField.getName(), UUID.class), + DSL.inline(fieldContext.getServerNodeId())) .cast(JSONB.class), - jsonpathParameters(jsonPath.get()))); + jsonpathParameters(jsonPath.get())); } else - jsonFullComposition = DSL.field(jsComposition2( - DSL.field(JoinBinder.compositionRecordTable.getName() + "." + tableField.getName()) - .cast(UUID.class), - DSL.val(fieldContext.getServerNodeId())) - .cast(String.class)); + jsonFullComposition = jsComposition2( + JoinBinder.compositionRecordTable.field(tableField.getName(), UUID.class), + DSL.inline(fieldContext.getServerNodeId())) + .cast(String.class); - if (fieldContext.isWithAlias()) return aliased(DSL.field(jsonFullComposition)); + if (fieldContext.isWithAlias()) return aliased(jsonFullComposition); else return defaultAliased(jsonFullComposition); } diff --git a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/composition/SimpleCompositionAttribute.java b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/composition/SimpleCompositionAttribute.java index 6a828b3d0..c7b70f731 100644 --- a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/composition/SimpleCompositionAttribute.java +++ b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/composition/SimpleCompositionAttribute.java @@ -25,7 +25,6 @@ import org.ehrbase.aql.sql.queryimpl.attribute.JoinSetup; import org.jooq.Field; import org.jooq.TableField; -import org.jooq.impl.DSL; @SuppressWarnings({"java:S3740", "java:S1452"}) public class SimpleCompositionAttribute extends CompositionAttribute { @@ -38,10 +37,10 @@ public SimpleCompositionAttribute(FieldResolutionContext fieldContext, JoinSetup @Override public Field sqlField() { - Field actualField = DSL.field(tableField); + Field actualField = tableField; if (tableField.getTable().equals(COMPOSITION)) { - actualField = DSL.field(JoinBinder.compositionRecordTable.getName() + "." + tableField.getName()); + actualField = JoinBinder.compositionRecordTable.field(tableField); } return as(actualField); diff --git a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/ehr/EhrIdValue.java b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/ehr/EhrIdValue.java index 2080cc52c..0bd9e9618 100644 --- a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/ehr/EhrIdValue.java +++ b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/ehr/EhrIdValue.java @@ -25,7 +25,6 @@ import org.ehrbase.aql.sql.queryimpl.attribute.JoinSetup; import org.jooq.Field; import org.jooq.TableField; -import org.jooq.impl.DSL; public class EhrIdValue extends EhrAttribute { @@ -40,19 +39,17 @@ public Field sqlField() { if (fieldContext.getPathResolver().hasPathExpression()) { joinSetup.setJoinEhr(true); if (fieldContext.isWithAlias()) { - return aliased(DSL.field("{0}", JoinBinder.ehrRecordTable.field(EHR_.ID.getName()))); - } else - return defaultAliased( - DSL.field(JoinBinder.ehrRecordTable.field(JoinBinder.ehrRecordTable.field(EHR_.ID.getName())))); + return aliased(JoinBinder.ehrRecordTable.field(EHR_.ID)); + } else return defaultAliased(JoinBinder.ehrRecordTable.field(JoinBinder.ehrRecordTable.field(EHR_.ID))); } else if (!joinSetup.isContainsEhrStatus()) { joinSetup.setJoinEhr(true); if (fieldContext.isWithAlias()) { - return aliased(DSL.field("{0}", JoinBinder.ehrRecordTable.field(EHR_.ID.getName()))); - } else return defaultAliased(DSL.field(JoinBinder.ehrRecordTable.field(EHR_.ID.getName()))); + return aliased(JoinBinder.ehrRecordTable.field(EHR_.ID)); + } else return defaultAliased(JoinBinder.ehrRecordTable.field(EHR_.ID)); } else { if (fieldContext.isWithAlias()) { - return aliased(DSL.field("{0}", JoinBinder.ehrRecordTable.field(EHR_.ID.getName()))); - } else return defaultAliased(DSL.field(JoinBinder.ehrRecordTable.field(EHR_.ID.getName()))); + return aliased(JoinBinder.ehrRecordTable.field(EHR_.ID)); + } else return defaultAliased(JoinBinder.ehrRecordTable.field(EHR_.ID)); } } diff --git a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/ehr/FullEhrJson.java b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/ehr/FullEhrJson.java index b67278918..43845ea80 100644 --- a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/ehr/FullEhrJson.java +++ b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/ehr/FullEhrJson.java @@ -75,50 +75,39 @@ public Field sqlField() { } if (prefix != null) { - jsonFullEhr = DSL.field(jsonpathItemAsText( + jsonFullEhr = jsonpathItemAsText( configuration, jsonArraySplitElements( configuration, jsonpathItem( configuration, jsEhr( - DSL.field(JoinBinder.ehrRecordTable - .getName() - .concat(".") - .concat(tableField.getName())) - .cast(UUID.class), - DSL.val(fieldContext.getServerNodeId())) + JoinBinder.ehrRecordTable.field( + tableField.getName(), UUID.class), + DSL.inline(fieldContext.getServerNodeId())) .cast(JSONB.class), prefix)), - suffix)); + suffix); if (fieldContext.getClause().equals(IQueryImpl.Clause.WHERE)) - jsonFullEhr = DSL.field(DSL.select(jsonFullEhr)); + jsonFullEhr = DSL.select(jsonFullEhr).asField(); } else { if (jsonPath.isPresent()) - jsonFullEhr = DSL.field(jsonpathItem( + jsonFullEhr = jsonpathItem( configuration, jsEhr( - DSL.field(JoinBinder.ehrRecordTable - .getName() - .concat(".") - .concat(tableField.getName())) - .cast(UUID.class), - DSL.val(fieldContext.getServerNodeId())) + JoinBinder.ehrRecordTable.field(tableField.getName(), UUID.class), + DSL.inline(fieldContext.getServerNodeId())) .cast(JSONB.class), - jsonpathParameters(jsonPath.get()))); + jsonpathParameters(jsonPath.get())); } } else - jsonFullEhr = DSL.field(jsEhr( - DSL.field(JoinBinder.ehrRecordTable - .getName() - .concat(".") - .concat(tableField.getName())) - .cast(UUID.class), - DSL.val(fieldContext.getServerNodeId())) - .cast(String.class)); - - if (fieldContext.isWithAlias()) return aliased(DSL.field(jsonFullEhr)); + jsonFullEhr = jsEhr( + JoinBinder.ehrRecordTable.field(tableField.getName(), UUID.class), + DSL.inline(fieldContext.getServerNodeId())) + .cast(String.class); + + if (fieldContext.isWithAlias()) return aliased(jsonFullEhr); else return defaultAliased(jsonFullEhr); } diff --git a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/ehr/ehrstatus/EhrStatusJson.java b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/ehr/ehrstatus/EhrStatusJson.java index f19e2f568..8db65250a 100644 --- a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/ehr/ehrstatus/EhrStatusJson.java +++ b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/ehr/ehrstatus/EhrStatusJson.java @@ -56,23 +56,24 @@ public Field sqlField() { .ehrStatus(JoinBinder.statusRecordTable.field(STATUS.EHR_ID)); else if (jsonPath.get().contains("uid")) { // this is required since jOOQ doesn't allow (easily) to convert a Field to a TableField - jsonEhrStatusField = DSL.field(jsonpathItemAsText( + jsonEhrStatusField = jsonpathItemAsText( fieldContext.getContext().configuration(), jsEhrStatus2( JoinBinder.statusRecordTable.field(STATUS.EHR_ID), - DSL.val(fieldContext.getServerNodeId())) + DSL.inline(fieldContext.getServerNodeId())) .cast(JSONB.class), - jsonpathParameters(jsonPath.get().replace("/", ",")))); + jsonpathParameters(jsonPath.get().replace("/", ","))); } else jsonEhrStatusField = new GenericJsonField(fieldContext, joinSetup) .forJsonPath(jsonPath.get()) .ehrStatus(JoinBinder.statusRecordTable.field(STATUS.EHR_ID)); } else - jsonEhrStatusField = DSL.field(jsEhrStatus2( - JoinBinder.statusRecordTable.field(STATUS.EHR_ID), DSL.val(fieldContext.getServerNodeId())) - .cast(String.class)); + jsonEhrStatusField = jsEhrStatus2( + JoinBinder.statusRecordTable.field(STATUS.EHR_ID), + DSL.inline(fieldContext.getServerNodeId())) + .cast(String.class); - return as(DSL.field(jsonEhrStatusField)); + return as(jsonEhrStatusField); } @Override diff --git a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/ehr/ehrstatus/SimpleEhrStatusAttribute.java b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/ehr/ehrstatus/SimpleEhrStatusAttribute.java index c9ba08510..5d05bc831 100644 --- a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/ehr/ehrstatus/SimpleEhrStatusAttribute.java +++ b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/ehr/ehrstatus/SimpleEhrStatusAttribute.java @@ -25,7 +25,6 @@ import org.ehrbase.aql.sql.queryimpl.attribute.JoinSetup; import org.jooq.Field; import org.jooq.TableField; -import org.jooq.impl.DSL; @SuppressWarnings({"java:S3740", "java:S1452"}) public class SimpleEhrStatusAttribute extends EhrStatusAttribute { @@ -38,7 +37,7 @@ public SimpleEhrStatusAttribute(FieldResolutionContext fieldContext, JoinSetup j @Override public Field sqlField() { - return as(DSL.field(tableField)); + return as(tableField); } @Override diff --git a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/eventcontext/EventContextJson.java b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/eventcontext/EventContextJson.java index b2be879b4..82fe1f27c 100644 --- a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/eventcontext/EventContextJson.java +++ b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/eventcontext/EventContextJson.java @@ -26,7 +26,6 @@ import org.ehrbase.aql.sql.queryimpl.value_field.GenericJsonField; import org.jooq.Field; import org.jooq.TableField; -import org.jooq.impl.DSL; public class EventContextJson extends EventContextAttribute { @@ -47,7 +46,7 @@ public Field sqlField() { .eventContext(EVENT_CONTEXT.ID); else jsonEventContext = new GenericJsonField(fieldContext, joinSetup).eventContext(EVENT_CONTEXT.ID); - if (fieldContext.isWithAlias()) return aliased(DSL.field(jsonEventContext)); + if (fieldContext.isWithAlias()) return aliased(jsonEventContext); else return defaultAliased(jsonEventContext); } diff --git a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/eventcontext/SimpleEventContextAttribute.java b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/eventcontext/SimpleEventContextAttribute.java index 8f7a880a2..066a98148 100644 --- a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/eventcontext/SimpleEventContextAttribute.java +++ b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/eventcontext/SimpleEventContextAttribute.java @@ -25,7 +25,6 @@ import org.ehrbase.aql.sql.queryimpl.attribute.JoinSetup; import org.jooq.Field; import org.jooq.TableField; -import org.jooq.impl.DSL; @SuppressWarnings({"java:S3740", "java:S1452"}) public class SimpleEventContextAttribute extends EventContextAttribute { @@ -38,7 +37,7 @@ public SimpleEventContextAttribute(FieldResolutionContext fieldContext, JoinSetu @Override public Field sqlField() { - return as(DSL.field(tableField)); + return as(tableField); } @Override diff --git a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/partyref/SimplePartyRefAttribute.java b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/partyref/SimplePartyRefAttribute.java index 8ad00ebd4..557b4c158 100644 --- a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/partyref/SimplePartyRefAttribute.java +++ b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/partyref/SimplePartyRefAttribute.java @@ -22,7 +22,6 @@ import org.ehrbase.aql.sql.queryimpl.attribute.JoinSetup; import org.jooq.Field; import org.jooq.TableField; -import org.jooq.impl.DSL; @SuppressWarnings({"java:S3740", "java:S1452"}) public class SimplePartyRefAttribute extends PartyRefAttribute { @@ -35,7 +34,7 @@ public SimplePartyRefAttribute(FieldResolutionContext fieldContext, JoinSetup jo @Override public Field sqlField() { - return as(DSL.field(tableField)); + return as(tableField); } @Override diff --git a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/setting/SettingAttribute.java b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/setting/SettingAttribute.java index b20c408bf..e76eb05bc 100644 --- a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/setting/SettingAttribute.java +++ b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/setting/SettingAttribute.java @@ -31,7 +31,6 @@ import org.jooq.Field; import org.jooq.JSONB; import org.jooq.TableField; -import org.jooq.impl.DSL; @SuppressWarnings({"java:S3740", "java:S1452"}) public class SettingAttribute extends EventContextAttribute { @@ -52,13 +51,13 @@ public Field sqlField() { .forJsonPath(jsonPath.get()) .eventContext(EVENT_CONTEXT.ID); - Field jsonContextField = DSL.field(jsonpathItem( + Field jsonContextField = jsonpathItem( fieldContext.getContext().configuration(), Routines.jsDvCodedText2(tableField).cast(JSONB.class), - jsonpathParameters(new GenericJsonPath(jsonPath.get()).jqueryPath()))) + jsonpathParameters(new GenericJsonPath(jsonPath.get()).jqueryPath())) .cast(String.class); - return as(DSL.field(jsonContextField)); + return as(jsonContextField); } return null; } diff --git a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/system/SystemAttribute.java b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/system/SystemAttribute.java index 35e24a559..c39def396 100644 --- a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/system/SystemAttribute.java +++ b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/attribute/system/SystemAttribute.java @@ -24,7 +24,6 @@ import org.ehrbase.aql.sql.queryimpl.attribute.RMObjectAttribute; import org.jooq.Field; import org.jooq.TableField; -import org.jooq.impl.DSL; @SuppressWarnings({"java:S3740", "java:S1452"}) public class SystemAttribute extends RMObjectAttribute { @@ -37,7 +36,7 @@ public SystemAttribute(FieldResolutionContext fieldContext, JoinSetup joinSetup) @Override public Field sqlField() { - return as(DSL.field(JoinBinder.systemRecordTable.getName() + "." + tableField.getName())); + return as(JoinBinder.systemRecordTable.field(tableField)); } @Override diff --git a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/value_field/FormattedField.java b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/value_field/FormattedField.java deleted file mode 100644 index c05df9e2d..000000000 --- a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/value_field/FormattedField.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2022 vitasystems GmbH and Hannover Medical School. - * - * This file is part of project EHRbase - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.ehrbase.aql.sql.queryimpl.value_field; - -import static org.ehrbase.aql.sql.queryimpl.AqlRoutines.toJson; - -import org.apache.commons.lang3.StringUtils; -import org.ehrbase.aql.sql.queryimpl.attribute.FieldResolutionContext; -import org.ehrbase.aql.sql.queryimpl.attribute.IRMObjectAttribute; -import org.ehrbase.aql.sql.queryimpl.attribute.JoinSetup; -import org.ehrbase.aql.sql.queryimpl.attribute.RMObjectAttribute; -import org.jooq.Field; -import org.jooq.TableField; -import org.jooq.impl.DSL; - -/** - * use to format a result using a function (f.e. to generate a correct ISO date/time - */ -@SuppressWarnings({"java:S3776", "java:S3740"}) -public class FormattedField extends RMObjectAttribute { - - public FormattedField(FieldResolutionContext fieldContext, JoinSetup joinSetup) { - super(fieldContext, joinSetup); - } - - public Field using( - String sqlType, String separator, String resultType, String plpgsqlFunction, Field... tableFields) { - // query the json representation of a node and cast the result as resultType - Field formattedField = DSL.field(plpgsqlFunction + "((" + StringUtils.join(tableFields, separator) + ")::" - + sqlType + ")::" + resultType); - - return as(DSL.field(formattedField)); - } - - public Field usingToJson(String sqlType, String separator, Field... tableFields) { - // query the json representation of a node and cast the result as resultType - Field formattedField = DSL.field(toJson( - fieldContext.getContext().configuration(), - DSL.field(StringUtils.join(tableFields, separator)) - .cast(DSL.val(sqlType)) - .toString())); - - return as(DSL.field(formattedField)); - } - - @Override - public Field sqlField() { - return null; - } - - @Override - public IRMObjectAttribute forTableField(TableField tableField) { - return this; - } -} diff --git a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/value_field/Functions.java b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/value_field/Functions.java index d709b9e9e..ee4c4e546 100644 --- a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/value_field/Functions.java +++ b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/value_field/Functions.java @@ -23,6 +23,7 @@ import org.jooq.Function3; import org.jooq.Function4; import org.jooq.TableField; +import org.jooq.impl.DSL; /** * @author Christian Chevalley @@ -67,4 +68,8 @@ private static Field applyFunction3(Function3 function, TableField... tableField private static Field applyFunction4(Function4 function, TableField... tableField) { return (Field) function.apply(tableField[0], tableField[1], tableField[2], tableField[3]); } + + public static Field inline(Field field) { + return DSL.field(field.toString(), field.getType()); + } } diff --git a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/value_field/GenericJsonField.java b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/value_field/GenericJsonField.java index 3adf12da2..f9c2dcf2c 100644 --- a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/value_field/GenericJsonField.java +++ b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/value_field/GenericJsonField.java @@ -61,7 +61,7 @@ public class GenericJsonField extends RMObjectAttribute { protected Optional jsonPath = Optional.empty(); - private static final String ITERATIVE_MARKER = "'" + AQL_NODE_ITERATIVE_MARKER + "'"; + private static final String ITERATIVE_MARKER = AQL_NODE_ITERATIVE_MARKER; public GenericJsonField(FieldResolutionContext fieldContext, JoinSetup joinSetup) { super(fieldContext, joinSetup); @@ -139,24 +139,27 @@ public Field jsonField(String rmType, Object function, TableField... tableFields if (tokenized.contains(QueryImplConstants.AQL_NODE_NAME_PREDICATE_MARKER)) { // replace the ITERATIVE_MARKERs by default index - Collections.replaceAll(tokenized, ITERATIVE_MARKER, "'0'"); + Collections.replaceAll(tokenized, ITERATIVE_MARKER, "0"); jsonField = new FunctionBasedNodePredicateCall(fieldContext, tokenized).resolve(function, tableFields); } else if (tokenized.contains(ITERATIVE_MARKER)) jsonField = fieldWithJsonArrayIteration(configuration, tokenized, function, tableFields); else - jsonField = DSL.field(jsonpathItemAsText( + jsonField = jsonpathItemAsText( configuration, - DSL.field(apply(function, tableFields).toString()).cast(JSONB.class), - tokenized.toArray(new String[] {}))); + Functions.inline(apply(function, tableFields).cast(JSONB.class)), + tokenized.toArray(new String[] {})); - } else jsonField = DSL.field(apply(function, tableFields).toString()).cast(String.class); + } else { + // output as sting + jsonField = Functions.inline(apply(function, tableFields)).cast(String.class); + } // check if the SQL expression contains a set returned in a WHERE clause (implying a lateral join) if (jsonField.toString().contains(QueryImplConstants.AQL_NODE_ITERATIVE_FUNCTION) && fieldContext.getClause().equals(IQueryImpl.Clause.WHERE)) - jsonField = DSL.field(DSL.select(jsonField)); + jsonField = DSL.select(jsonField).asField(); - return as(DSL.field(jsonField)); + return as(jsonField); } private Field fieldWithJsonArrayIteration( @@ -169,10 +172,7 @@ private Field fieldWithJsonArrayIteration( .toArray(new String[] {}); // initial - Field field = jsonpathItem( - configuration, - DSL.field(apply(function, tableFields).toString()).cast(JSONB.class), - prefix); + Field field = jsonpathItem(configuration, apply(function, tableFields).cast(JSONB.class), prefix); while (remaining.length > 0) { List tokens = Arrays.asList(remaining.clone()); @@ -185,8 +185,8 @@ private Field fieldWithJsonArrayIteration( remaining = new String[] {}; } - field = DSL.field(jsonpathItemAsText( - configuration, jsonArraySplitElements(configuration, field.cast(JSONB.class)), prefix)); + field = jsonpathItemAsText( + configuration, jsonArraySplitElements(configuration, field.cast(JSONB.class)), prefix); } return field; diff --git a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/value_field/SimpleAttribute.java b/service/src/main/java/org/ehrbase/aql/sql/queryimpl/value_field/SimpleAttribute.java deleted file mode 100644 index e60820b7b..000000000 --- a/service/src/main/java/org/ehrbase/aql/sql/queryimpl/value_field/SimpleAttribute.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2019 vitasystems GmbH and Hannover Medical School. - * - * This file is part of project EHRbase - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.ehrbase.aql.sql.queryimpl.value_field; - -import java.util.Optional; -import org.ehrbase.aql.sql.queryimpl.attribute.FieldResolutionContext; -import org.ehrbase.aql.sql.queryimpl.attribute.IRMObjectAttribute; -import org.ehrbase.aql.sql.queryimpl.attribute.JoinSetup; -import org.ehrbase.aql.sql.queryimpl.attribute.composition.CompositionAttribute; -import org.jooq.Field; -import org.jooq.TableField; -import org.jooq.impl.DSL; - -@SuppressWarnings({"java:S3740", "java:S1452"}) -public class SimpleAttribute extends CompositionAttribute { - - protected Field tableField; - Optional type = Optional.empty(); - - public SimpleAttribute(FieldResolutionContext fieldContext, JoinSetup joinSetup) { - super(fieldContext, joinSetup); - } - - @Override - public Field sqlField() { - Field actualField; - - if (type.isPresent()) actualField = DSL.field(tableField + "::" + type.get()); - else actualField = DSL.field(tableField); - - return as(actualField); - } - - @Override - public IRMObjectAttribute forTableField(TableField tableField) { - return forTableField(tableField); - } - - public SimpleAttribute forTableField(String pgtype, Field tableField) { - if (pgtype != null) type = Optional.of(pgtype); - - this.tableField = tableField; - return this; - } -} diff --git a/service/src/main/java/org/ehrbase/dao/access/jooq/EntryAccess.java b/service/src/main/java/org/ehrbase/dao/access/jooq/EntryAccess.java index 1db8594a2..6994f473b 100644 --- a/service/src/main/java/org/ehrbase/dao/access/jooq/EntryAccess.java +++ b/service/src/main/java/org/ehrbase/dao/access/jooq/EntryAccess.java @@ -477,16 +477,16 @@ public Boolean update(Timestamp transactionTime, boolean force) { UpdateQuery updateQuery = getContext().updateQuery(ENTRY); updateQuery.addValue(ENTRY.COMPOSITION_ID, getCompositionId()); - updateQuery.addValue(ENTRY.SEQUENCE, DSL.field(DSL.val(getSequence()))); - updateQuery.addValue(ENTRY.TEMPLATE_ID, DSL.field(DSL.val(getTemplateId()))); - - updateQuery.addValue(ENTRY.ITEM_TYPE, DSL.field(DSL.val(EntryType.valueOf(getItemType())))); - updateQuery.addValue(ENTRY.ARCHETYPE_ID, DSL.field(DSL.val(getArchetypeId()))); - updateQuery.addValue(ENTRY.CATEGORY, DSL.field(DSL.val(getCategory()))); - updateQuery.addValue(ENTRY.ENTRY_, DSL.field(DSL.val(getEntryJson()))); - updateQuery.addValue(ENTRY.SYS_TRANSACTION, DSL.field(DSL.val(transactionTime))); - updateQuery.addValue(ENTRY.NAME, DSL.field(DSL.val(getCompositionName()))); - updateQuery.addValue(ENTRY.RM_VERSION, DSL.field(DSL.val(getRmVersion()))); + updateQuery.addValue(ENTRY.SEQUENCE, DSL.val(getSequence())); + updateQuery.addValue(ENTRY.TEMPLATE_ID, DSL.val(getTemplateId())); + + updateQuery.addValue(ENTRY.ITEM_TYPE, DSL.val(EntryType.valueOf(getItemType()))); + updateQuery.addValue(ENTRY.ARCHETYPE_ID, DSL.val(getArchetypeId())); + updateQuery.addValue(ENTRY.CATEGORY, DSL.val(getCategory())); + updateQuery.addValue(ENTRY.ENTRY_, DSL.val(getEntryJson())); + updateQuery.addValue(ENTRY.SYS_TRANSACTION, DSL.val(transactionTime)); + updateQuery.addValue(ENTRY.NAME, DSL.val(getCompositionName())); + updateQuery.addValue(ENTRY.RM_VERSION, DSL.val(getRmVersion())); updateQuery.addConditions(ENTRY.ID.eq(getId())); logger.debug("Update done..."); diff --git a/service/src/main/java/org/ehrbase/dao/access/jooq/party/PersistedPartyRelated.java b/service/src/main/java/org/ehrbase/dao/access/jooq/party/PersistedPartyRelated.java index 0dc9dcef3..c2b02f2ac 100644 --- a/service/src/main/java/org/ehrbase/dao/access/jooq/party/PersistedPartyRelated.java +++ b/service/src/main/java/org/ehrbase/dao/access/jooq/party/PersistedPartyRelated.java @@ -146,7 +146,10 @@ public UUID findInDB(PartyProxy partyProxy) { .and(PARTY_IDENTIFIED.PARTY_REF_SCHEME.isNull()) .and(PARTY_IDENTIFIED.PARTY_REF_TYPE.isNull()) .and(PARTY_IDENTIFIED.NAME.eq(((PartyIdentified) partyProxy).getName())) - .and(DSL.field("(" + PARTY_IDENTIFIED.RELATIONSHIP + ").value") + .and(DSL.field( + "({0}).{1}", + PARTY_IDENTIFIED.RELATIONSHIP, + org.ehrbase.jooq.pg.udt.DvCodedText.VALUE.getUnqualifiedName()) .eq(relationshipAsRecord(partyProxy) .getValue())) .and(PARTY_IDENTIFIED.PARTY_TYPE.eq(PartyType.party_related))); diff --git a/service/src/main/java/org/ehrbase/repository/EhrFolderRepository.java b/service/src/main/java/org/ehrbase/repository/EhrFolderRepository.java index 18de6a4fb..f1909cedc 100644 --- a/service/src/main/java/org/ehrbase/repository/EhrFolderRepository.java +++ b/service/src/main/java/org/ehrbase/repository/EhrFolderRepository.java @@ -380,8 +380,8 @@ public Field[] convertToEhrFolderHistoryFields(Field[] fields) { private static SelectJoinStep headQuery(DSLContext context) { return context.select(EHR_FOLDER.fields()) .select( - DSL.field("null").as(EHR_FOLDER_HISTORY.SYS_PERIOD_UPPER.getName()), - DSL.field("false").as(EHR_FOLDER_HISTORY.SYS_DELETED.getName())) + DSL.inline((OffsetDateTime) null).as(EHR_FOLDER_HISTORY.SYS_PERIOD_UPPER.getName()), + DSL.inline(false).as(EHR_FOLDER_HISTORY.SYS_DELETED.getName())) .from(EHR_FOLDER); } diff --git a/service/src/main/java/org/ehrbase/repository/PartyProxyRepository.java b/service/src/main/java/org/ehrbase/repository/PartyProxyRepository.java index 004459484..77b75da7a 100644 --- a/service/src/main/java/org/ehrbase/repository/PartyProxyRepository.java +++ b/service/src/main/java/org/ehrbase/repository/PartyProxyRepository.java @@ -256,7 +256,10 @@ private Optional findInDBPartyRelated(PartyRelated partyProxy) { .and(PARTY_IDENTIFIED.PARTY_REF_SCHEME.isNull()) .and(PARTY_IDENTIFIED.PARTY_REF_TYPE.isNull()) .and(PARTY_IDENTIFIED.NAME.eq(partyProxy.getName())) - .and(DSL.field("(" + PARTY_IDENTIFIED.RELATIONSHIP + ").value") + .and(DSL.field( + "({0}).{1}", + PARTY_IDENTIFIED.RELATIONSHIP, + org.ehrbase.jooq.pg.udt.DvCodedText.VALUE.getUnqualifiedName()) .eq(relationshipAsRecord(partyProxy).getValue())) .and(PARTY_IDENTIFIED.PARTY_TYPE.eq(PartyType.party_related))); diff --git a/service/src/test/java/org/ehrbase/aql/sql/binding/OrderByBinderTest.java b/service/src/test/java/org/ehrbase/aql/sql/binding/OrderByBinderTest.java index 5fc9e4e60..65bb54364 100644 --- a/service/src/test/java/org/ehrbase/aql/sql/binding/OrderByBinderTest.java +++ b/service/src/test/java/org/ehrbase/aql/sql/binding/OrderByBinderTest.java @@ -24,6 +24,9 @@ import org.ehrbase.aql.compiler.OrderAttribute; import org.ehrbase.aql.definition.I_VariableDefinitionHelper; import org.ehrbase.dao.jooq.impl.DSLContextHelper; +import org.ehrbase.jooq.pg.tables.Ehr; +import org.jooq.Record; +import org.jooq.SelectQuery; import org.jooq.SortField; import org.junit.Test; @@ -33,17 +36,17 @@ public class OrderByBinderTest { public void getOrderByFields() { // ascending + SelectQuery query = DSLContextHelper.buildContext().selectQuery(); + query.addSelect(Ehr.EHR_.DATE_CREATED.as("date_created")); + query.addFrom(Ehr.EHR_); { // represents a/context/start_time/value as date_created and order by date_created ASC OrderAttribute orderAttribute = new OrderAttribute( I_VariableDefinitionHelper.build(null, "date_created", null, false, false, false)); orderAttribute.setDirection(OrderAttribute.OrderDirection.ASC); - OrderByBinder cut = new OrderByBinder( - null, - Collections.singletonList(orderAttribute), - DSLContextHelper.buildContext().selectQuery()); - List> actual = cut.getOrderByFields(); + OrderByBinder cut = new OrderByBinder(null, Collections.singletonList(orderAttribute), query); + List> actual = cut.getOrderByFields(); assertThat(actual).size().isEqualTo(1); SortField sortField = actual.get(0); @@ -57,11 +60,8 @@ public void getOrderByFields() { I_VariableDefinitionHelper.build(null, "date_created", null, false, false, false)); orderAttribute.setDirection(OrderAttribute.OrderDirection.DESC); - OrderByBinder cut = new OrderByBinder( - null, - Collections.singletonList(orderAttribute), - DSLContextHelper.buildContext().selectQuery()); - List> actual = cut.getOrderByFields(); + OrderByBinder cut = new OrderByBinder(null, Collections.singletonList(orderAttribute), query); + List> actual = cut.getOrderByFields(); assertThat(actual).size().isEqualTo(1); SortField sortField = actual.get(0); @@ -74,11 +74,8 @@ public void getOrderByFields() { OrderAttribute orderAttribute = new OrderAttribute( I_VariableDefinitionHelper.build(null, "date_created", null, false, false, false)); - OrderByBinder cut = new OrderByBinder( - null, - Collections.singletonList(orderAttribute), - DSLContextHelper.buildContext().selectQuery()); - List> actual = cut.getOrderByFields(); + OrderByBinder cut = new OrderByBinder(null, Collections.singletonList(orderAttribute), query); + List> actual = cut.getOrderByFields(); assertThat(actual).size().isEqualTo(1); SortField sortField = actual.get(0); diff --git a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/FunctionBasedNodePredicateCallTest.java b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/FunctionBasedNodePredicateCallTest.java index d862fce8b..e244f58c4 100644 --- a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/FunctionBasedNodePredicateCallTest.java +++ b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/FunctionBasedNodePredicateCallTest.java @@ -17,10 +17,10 @@ */ package org.ehrbase.aql.sql.queryimpl; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.ehrbase.aql.sql.queryimpl.QueryImplConstants.AQL_NODE_NAME_PREDICATE_MARKER; import static org.ehrbase.jooq.pg.Tables.EVENT_CONTEXT; import static org.jooq.impl.DSL.select; -import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import java.util.Arrays; @@ -105,16 +105,16 @@ public void testConstruct2() { @Test public void testConstruct3() { String[] pathArray = { - "'other_context'", - "'/items[openEHR-EHR-CLUSTER.case_identification.v0]'", + "other_context", + "/items[openEHR-EHR-CLUSTER.case_identification.v0]", AQL_NODE_NAME_PREDICATE_MARKER, - "'item-1'", - "'/items[at0001]'", + "item-1", + "/items[at0001]", AQL_NODE_NAME_PREDICATE_MARKER, - "'item-2'", - "'/name'", - "'0'", - "'value'", + "item-2", + "/name", + "0", + "value", }; FunctionBasedNodePredicateCall functionBasedNodePredicateCall = @@ -124,17 +124,17 @@ public void testConstruct3() { String dummySelect = select(test).toString(); - assertEquals( - dummySelect, - "select jsonb_extract_path_text(cast(\"ehr\".\"aql_node_name_predicate\"(\n" - + " cast(jsonb_extract_path_text(\"ehr\".\"aql_node_name_predicate\"(\n" - + " cast(jsonb_extract_path_text(cast(\"ehr\".\"js_context\"(\"ehr\".\"event_context\".\"id\") as jsonb),'other_context','/items[openEHR-EHR-CLUSTER.case_identification.v0]') as jsonb),\n" - + " 'item-1',\n" - + " ''\n" - + "),'/items[at0001]') as jsonb),\n" - + " 'item-2',\n" - + " ''\n" - + ") as jsonb),'/name','0','value')"); + assertThat(dummySelect) + .isEqualToIgnoringWhitespace( + "select jsonb_extract_path_text(cast(\"ehr\".\"aql_node_name_predicate\"(\n" + + " cast(jsonb_extract_path_text(\"ehr\".\"aql_node_name_predicate\"(\n" + + " cast(jsonb_extract_path_text(cast(\"ehr\".\"js_context\"(\"ehr\".\"event_context\".\"id\") as jsonb),'other_context','/items[openEHR-EHR-CLUSTER.case_identification.v0]') as jsonb),\n" + + " 'item-1',\n" + + " ''\n" + + "),'/items[at0001]') as jsonb),\n" + + " 'item-2',\n" + + " ''\n" + + ") as jsonb),'/name','0','value')"); } @Test diff --git a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/attribute/TemporalWithTimeZoneTest.java b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/attribute/TemporalWithTimeZoneTest.java index 164f985c7..320dd90f3 100644 --- a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/attribute/TemporalWithTimeZoneTest.java +++ b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/attribute/TemporalWithTimeZoneTest.java @@ -58,7 +58,7 @@ public void testJsonPathBuilding() { .as("test formatting dvdatetime value") .isEqualToIgnoringWhitespace("select jsonb_extract_path_text(cast(\"ehr\".\"js_dv_date_time\"(\n" + " \"ehr\".\"event_context\".\"start_time\", \n" - + " event_context.START_TIME_TZID\n" + + " \"ehr\".\"event_context\".\"start_time_tzid\"\n" + ") as jsonb),'value') \"/test\""); } } diff --git a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/UC40.java b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/UC40.java index adc59d480..c3b7d9c5a 100644 --- a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/UC40.java +++ b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/UC40.java @@ -22,10 +22,11 @@ public abstract class UC40 extends QueryProcessorTestBase { protected UC40() { - this.aql = "select" + " CAST (d/description[at0001]/items[at0004]/value/magnitude AS 'FLOAT') as max_magnitude" - + " from EHR e" - + " contains COMPOSITION" - + " contains ACTION d[openEHR-EHR-ACTION.immunisation_procedure.v1]"; + this.aql = + "select" + " CAST (d/description[at0001]/items[at0004]/value/magnitude AS 'NUMERIC') as max_magnitude" + + " from EHR e" + + " contains COMPOSITION" + + " contains ACTION d[openEHR-EHR-ACTION.immunisation_procedure.v1]"; this.expectedOutputWithJson = false; } } diff --git a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC15Test.java b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC15Test.java index 8341f78f1..102ce98e9 100644 --- a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC15Test.java +++ b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC15Test.java @@ -29,7 +29,7 @@ public UC15Test() { super(); this.expectedSqlExpression = "select distinct on (\"/ehr_status/other_details\") \"\".\"/ehr_status/other_details\"" - + " from (select jsonb_extract_path_text(cast(\"ehr\".\"js_ehr_status\"(\"status_join\".\"ehr_id\") as jsonb),'other_details') as \"/ehr_status/other_details\"" + + " from (select jsonb_extract_path_text(cast(\"ehr\".\"js_ehr_status\"(\"status_join\".\"ehr_id\") as jsonb), 'other_details') as \"/ehr_status/other_details\"" + " from \"ehr\".\"ehr\" as \"ehr_join\"" + " join \"ehr\".\"status\" as \"status_join\"" + " on \"status_join\".\"ehr_id\" = \"ehr_join\".\"id\"" diff --git a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC20Test.java b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC20Test.java index 51e9e673c..5c560c409 100644 --- a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC20Test.java +++ b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC20Test.java @@ -27,7 +27,7 @@ public class UC20Test extends UC20 { public UC20Test() { super(); this.expectedSqlExpression = - "select jsonb_extract_path_text(cast(\"ehr\".\"js_dv_coded_text_inner\"(\"ehr\".\"entry\".\"category\") as jsonb),'defining_code') as \"/category/defining_code\" from \"ehr\".\"entry\" right outer join \"ehr\".\"composition\" as \"composition_join\" on \"composition_join\".\"id\" = \"ehr\".\"entry\".\"composition_id\" right outer join \"ehr\".\"ehr\" as \"ehr_join\" on \"ehr_join\".\"id\" = \"composition_join\".\"ehr_id\" where (\"ehr\".\"entry\".\"template_id\" = ? and (\"ehr_join\".\"id\" = '4a7c01cf-bb1c-4d3d-8385-4ae0674befb1'))"; + "select jsonb_extract_path_text(cast(\"ehr\".\"js_dv_coded_text_inner\"(\"ehr\".\"entry\".\"category\") as jsonb), 'defining_code') as \"/category/defining_code\" from \"ehr\".\"entry\" right outer join \"ehr\".\"composition\" as \"composition_join\" on \"composition_join\".\"id\" = \"ehr\".\"entry\".\"composition_id\" right outer join \"ehr\".\"ehr\" as \"ehr_join\" on \"ehr_join\".\"id\" = \"composition_join\".\"ehr_id\" where (\"ehr\".\"entry\".\"template_id\" = ? and (\"ehr_join\".\"id\" = '4a7c01cf-bb1c-4d3d-8385-4ae0674befb1'))"; } @Test diff --git a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC21Test.java b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC21Test.java index 61653eb5c..60b541545 100644 --- a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC21Test.java +++ b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC21Test.java @@ -27,7 +27,7 @@ public class UC21Test extends UC21 { public UC21Test() { super(); this.expectedSqlExpression = - "select jsonb_extract_path_text(cast(\"ehr\".\"js_dv_coded_text_inner\"(\"ehr\".\"entry\".\"category\") as jsonb),'defining_code','terminology_id','value') as \"/category/defining_code/terminology_id/value\"" + "select jsonb_extract_path_text(cast(\"ehr\".\"js_dv_coded_text_inner\"(\"ehr\".\"entry\".\"category\") as jsonb),'defining_code', 'terminology_id', 'value') as \"/category/defining_code/terminology_id/value\"" + " from \"ehr\".\"entry\"" + " right outer join \"ehr\".\"composition\" as \"composition_join\" on \"composition_join\".\"id\" = \"ehr\".\"entry\".\"composition_id\"" + " right outer join \"ehr\".\"ehr\" as \"ehr_join\" on \"ehr_join\".\"id\" = \"composition_join\".\"ehr_id\"" diff --git a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC23Test.java b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC23Test.java index 5779fc62d..740d42f78 100644 --- a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC23Test.java +++ b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC23Test.java @@ -27,7 +27,7 @@ public class UC23Test extends UC23 { public UC23Test() { super(); this.expectedSqlExpression = - "select count(DISTINCT \"_FCT_ARG_0\") as \"count\" from (select cast(\"ehr\".\"js_dv_date_time\"(\n" + "select count(distinct \"_FCT_ARG_0\") as \"count\" from (select cast(\"ehr\".\"js_dv_date_time\"(\n" + " \"ehr_join\".\"date_created\", \n" + " \"ehr_join\".\"date_created_tzid\"\n" + ") as varchar) as \"_FCT_ARG_0\" from \"ehr\".\"ehr\" as \"ehr_join\") as \"\""; diff --git a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC24Test.java b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC24Test.java index eb72d28fe..1fe522040 100644 --- a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC24Test.java +++ b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC24Test.java @@ -27,7 +27,7 @@ public class UC24Test extends UC24 { public UC24Test() { super(); this.expectedSqlExpression = - "select cast(\"ehr\".\"js_composition\"(cast(cast(composition_join.id as uuid) as uuid), cast(? as text)) as varchar) as \"c\" from \"ehr\".\"entry\" right outer join \"ehr\".\"composition\" as \"composition_join\" on \"composition_join\".\"id\" = \"ehr\".\"entry\".\"composition_id\" where (\"ehr\".\"entry\".\"template_id\" = ? and ( null IS NULL ))"; + "select cast(\"ehr\".\"js_composition\"(cast(\"composition_join\".\"id\" as uuid), cast('local' as text)) as varchar) as \"c\" from \"ehr\".\"entry\" right outer join \"ehr\".\"composition\" as \"composition_join\" on \"composition_join\".\"id\" = \"ehr\".\"entry\".\"composition_id\" where (\"ehr\".\"entry\".\"template_id\" = ? and ( null IS NULL ))"; } @Test diff --git a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC27Test.java b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC27Test.java index 9fce1948c..edaa97611 100644 --- a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC27Test.java +++ b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC27Test.java @@ -28,10 +28,10 @@ public UC27Test() { super(); this.expectedSqlExpression = "select (ARRAY.COLUMN)::TEXT as \"/folders/name/value\" from \"ehr\".\"ehr\" as \"ehr_join\" join lateral (\n" - + " select jsonb_extract_path_text(cast(ehr.xjsonb_array_elements(cast(jsonb_extract_path(cast(\"ehr\".\"js_ehr\"(\n" - + " cast(ehr_join.id as uuid),\n" + + " select jsonb_extract_path_text(ehr.xjsonb_array_elements(jsonb_extract_path(cast(\"ehr\".\"js_ehr\"(\n" + + " \"ehr_join\".\"id\",\n" + " 'local'\n" - + ") as jsonb),'folders') as jsonb)) as jsonb),'name','0','value')\n" + + ") as jsonb),'folders')),'name','0','value')\n" + " AS COLUMN) as \"ARRAY\" on true where (\"ehr_join\".\"id\" = 'c2561bab-4d2b-4ffd-a893-4382e9048f8c' and 'case1'IN ( (ARRAY.COLUMN)::TEXT ) )"; } diff --git a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC28Test.java b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC28Test.java index 045d13950..53078acbc 100644 --- a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC28Test.java +++ b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC28Test.java @@ -28,10 +28,10 @@ public UC28Test() { super(); this.expectedSqlExpression = "select (ARRAY.COLUMN)::TEXT as \"/folders/name/value\" from \"ehr\".\"ehr\" as \"ehr_join\" join lateral (\n" - + " select jsonb_extract_path_text(cast(ehr.xjsonb_array_elements(cast(jsonb_extract_path(cast(\"ehr\".\"js_ehr\"(\n" - + " cast(ehr_join.id as uuid),\n" + + " select jsonb_extract_path_text(ehr.xjsonb_array_elements(jsonb_extract_path(cast(\"ehr\".\"js_ehr\"(\n" + + " \"ehr_join\".\"id\",\n" + " 'local'\n" - + ") as jsonb),'folders') as jsonb)) as jsonb),'name','0','value')\n" + + ") as jsonb),'folders')),'name','0','value')\n" + " AS COLUMN) as \"ARRAY\" on true where (\"ehr_join\".\"id\" = 'c2561bab-4d2b-4ffd-a893-4382e9048f8c' and 'case1' = SOME ( (SELECT (ARRAY.COLUMN)::TEXT ) ) )"; } diff --git a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC29Test.java b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC29Test.java index e9b059316..3279bf119 100644 --- a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC29Test.java +++ b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC29Test.java @@ -28,10 +28,10 @@ public UC29Test() { super(); this.expectedSqlExpression = "select (ARRAY.COLUMN)::TEXT as \"/folders/name/value\" from \"ehr\".\"ehr\" as \"ehr_join\" join lateral (\n" - + " select jsonb_extract_path_text(cast(ehr.xjsonb_array_elements(cast(jsonb_extract_path(cast(\"ehr\".\"js_ehr\"(\n" - + " cast(ehr_join.id as uuid),\n" + + " select jsonb_extract_path_text(ehr.xjsonb_array_elements(jsonb_extract_path(cast(\"ehr\".\"js_ehr\"(\n" + + " \"ehr_join\".\"id\" ,\n" + " 'local'\n" - + ") as jsonb),'folders') as jsonb)) as jsonb),'name','0','value')\n" + + ") as jsonb),'folders')),'name','0','value')\n" + " AS COLUMN) as \"ARRAY\" on true where (\"ehr_join\".\"id\" = 'c2561bab-4d2b-4ffd-a893-4382e9048f8c' and 'case1' = ANY ( (SELECT (ARRAY.COLUMN)::TEXT ) ) )"; } diff --git a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC30Test.java b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC30Test.java index 43f6cbe83..0ea51e629 100644 --- a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC30Test.java +++ b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC30Test.java @@ -28,10 +28,10 @@ public UC30Test() { super(); this.expectedSqlExpression = "select (ARRAY.COLUMN)::TEXT as \"/folders/name/value\" from \"ehr\".\"ehr\" as \"ehr_join\" join lateral (\n" - + " select jsonb_extract_path_text(cast(ehr.xjsonb_array_elements(cast(jsonb_extract_path(cast(\"ehr\".\"js_ehr\"(\n" - + " cast(ehr_join.id as uuid),\n" + + " select jsonb_extract_path_text(ehr.xjsonb_array_elements(jsonb_extract_path(cast(\"ehr\".\"js_ehr\"(\n" + + " \"ehr_join\".\"id\",\n" + " 'local'\n" - + ") as jsonb),'folders') as jsonb)) as jsonb),'name','0','value')\n" + + ") as jsonb),'folders')),'name','0','value')\n" + " AS COLUMN) as \"ARRAY\" on true where (\"ehr_join\".\"id\" = 'c2561bab-4d2b-4ffd-a893-4382e9048f8c' and 'case1' = ALL ( (SELECT (ARRAY.COLUMN)::TEXT ) ) )"; } diff --git a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC31Test.java b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC31Test.java index cb072e55c..d7368d944 100644 --- a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC31Test.java +++ b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC31Test.java @@ -28,10 +28,10 @@ public UC31Test() { super(); this.expectedSqlExpression = "select (ARRAY.COLUMN)::TEXT as \"/folders/name/value\" from \"ehr\".\"ehr\" as \"ehr_join\" join lateral (\n" - + " select jsonb_extract_path_text(cast(ehr.xjsonb_array_elements(cast(jsonb_extract_path(cast(\"ehr\".\"js_ehr\"(\n" - + " cast(ehr_join.id as uuid),\n" - + " 'local'\n" - + ") as jsonb),'folders') as jsonb)) as jsonb),'name','0','value')\n" + + " select jsonb_extract_path_text(ehr.xjsonb_array_elements(jsonb_extract_path( cast(\"ehr\".\"js_ehr\"(\n" + + " \"ehr_join\".\"id\",\n" + + " 'local'\n" + + ") as jsonb),'folders')),'name','0','value')\n" + " AS COLUMN) as \"ARRAY\" on true where ('case1' = ALL ( (SELECT (ARRAY.COLUMN)::TEXT ) ) and \"ehr_join\".\"id\" = 'c2561bab-4d2b-4ffd-a893-4382e9048f8c')"; } diff --git a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC32Test.java b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC32Test.java index 6117a513c..a3a96c2d4 100644 --- a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC32Test.java +++ b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC32Test.java @@ -30,7 +30,7 @@ public class UC32Test extends UC32 { public UC32Test() { super(); this.expectedSqlExpression = "select " + QueryImplConstants.AQL_NODE_ITERATIVE_FUNCTION - + "(ehr.js_ehr(ehr_join.id,'local')::jsonb #>'{folders}') #>>'{name,value}' as \"/folders/name/value\"" + + "(ehr.js_ehr(ehr_join.id,cast(? as text))::jsonb #>'{folders}') #>>'{name,value}' as \"/folders/name/value\"" + " from \"ehr\".\"ehr\" as \"ehr_join\"" + " where (" + " 'case1' IN (SELECT regexp_split_to_array('case1,case2', ','))" diff --git a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC33Test.java b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC33Test.java index 2666a217a..1e561f0db 100644 --- a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC33Test.java +++ b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC33Test.java @@ -28,10 +28,10 @@ public UC33Test() { super(); this.expectedSqlExpression = "select (ARRAY.COLUMN)::TEXT as \"/folders/name/value\" from \"ehr\".\"ehr\" as \"ehr_join\" join lateral (\n" - + " select jsonb_extract_path_text(cast(ehr.xjsonb_array_elements(cast(jsonb_extract_path(cast(\"ehr\".\"js_ehr\"(\n" - + " cast(ehr_join.id as uuid), \n" + + " select jsonb_extract_path_text(ehr.xjsonb_array_elements(jsonb_extract_path(cast(\"ehr\".\"js_ehr\"(\n" + + " \"ehr_join\".\"id\", \n" + " 'local'\n" - + ") as jsonb),'folders') as jsonb)) as jsonb),'name','0','value')\n" + + ") as jsonb),'folders')),'name','0','value')\n" + " AS COLUMN) as \"ARRAY\" on true where ('case1'IN ( 'case1','case2' ) and \"ehr_join\".\"id\" = 'c2561bab-4d2b-4ffd-a893-4382e9048f8c')"; } diff --git a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC34Test.java b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC34Test.java index 818d9f51e..35905abc1 100644 --- a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC34Test.java +++ b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC34Test.java @@ -27,7 +27,7 @@ public class UC34Test extends UC34 { public UC34Test() { super(); this.expectedSqlExpression = - "select min(DISTINCT \"_FCT_ARG_0\") as \"min\" from (select cast(\"ehr\".\"js_dv_date_time\"(\n" + "select min(distinct \"_FCT_ARG_0\") as \"min\" from (select cast(\"ehr\".\"js_dv_date_time\"(\n" + " \"ehr_join\".\"date_created\", \n" + " \"ehr_join\".\"date_created_tzid\"\n" + ") as varchar) as \"_FCT_ARG_0\" from \"ehr\".\"ehr\" as \"ehr_join\") as \"\""; diff --git a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC35Test.java b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC35Test.java index cb3332acc..91387f261 100644 --- a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC35Test.java +++ b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC35Test.java @@ -27,9 +27,9 @@ public class UC35Test extends UC35 { public UC35Test() { super(); this.expectedSqlExpression = - "select cast(jsonb_extract_path(cast(\"ehr\".\"js_ehr\"(\n" + " cast(ehr_join.id as uuid), \n" + "select jsonb_extract_path(cast(\"ehr\".\"js_ehr\"(\n" + " \"ehr_join\".\"id\" , \n" + " 'local'\n" - + ") as jsonb),'directory') as jsonb) as \"/directory\" from \"ehr\".\"ehr\" as \"ehr_join\""; + + ") as jsonb),'directory') as \"/directory\" from \"ehr\".\"ehr\" as \"ehr_join\""; } @Test diff --git a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC36Test.java b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC36Test.java index 0e4a88492..91dc1e1c8 100644 --- a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC36Test.java +++ b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC36Test.java @@ -26,8 +26,8 @@ public class UC36Test extends UC36 { public UC36Test() { super(); - this.expectedSqlExpression = "select cast(\"ehr\".\"js_ehr\"(\n" + " cast(ehr_join.id as uuid), \n" - + " ?\n" + this.expectedSqlExpression = "select cast(\"ehr\".\"js_ehr\"(\n" + " \"ehr_join\".\"id\", \n" + + " 'local'\n" + ") as varchar) as \"e\"\n" + "from \"ehr\".\"ehr\" as \"ehr_join\""; } diff --git a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC40Test.java b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC40Test.java index 1d3d7f292..211c55678 100644 --- a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC40Test.java +++ b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC40Test.java @@ -27,7 +27,7 @@ public class UC40Test extends UC40 { public UC40Test() { super(); this.expectedSqlExpression = - "select CAST (\"max_magnitude\" AS FLOAT ) as \"max_magnitude\" from (select (ARRAY.COLUMN#>>'{/description[at0001],/items[at0004],0,/value,magnitude}')::bigint as \"max_magnitude\" from \"ehr\".\"entry\" join lateral (\n" + "select cast(\"max_magnitude\" as numeric) as \"max_magnitude\" from (select (ARRAY.COLUMN#>>'{/description[at0001],/items[at0004],0,/value,magnitude}')::bigint as \"max_magnitude\" from \"ehr\".\"entry\" join lateral (\n" + " select (ehr.xjsonb_array_elements((\"ehr\".\"entry\".\"entry\"#>>'{/composition[openEHR-EHR-COMPOSITION.health_summary.v1],/content[openEHR-EHR-ACTION.immunisation_procedure.v1]}')::jsonb)) \n" + " AS COLUMN) as \"ARRAY\" on true where \"ehr\".\"entry\".\"template_id\" = ?) as \"\""; } diff --git a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC41Test.java b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC41Test.java index 4f39292a0..c540584e5 100644 --- a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC41Test.java +++ b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC41Test.java @@ -26,7 +26,7 @@ public class UC41Test extends UC41 { public UC41Test() { super(); - this.expectedSqlExpression = "select ? as \"constant\" from \"ehr\".\"entry\""; + this.expectedSqlExpression = "select true as \"constant\" from \"ehr\".\"entry\""; } @Test diff --git a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC42Test.java b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC42Test.java index a4ac072a9..bcedf0d19 100644 --- a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC42Test.java +++ b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC42Test.java @@ -27,41 +27,7 @@ public class UC42Test extends UC42 { public UC42Test() { super(); this.expectedSqlExpression = - "select ARRAY.COLUMN as \"Diagnose\", ARRAY.COLUMN as \"MabuseComposition\", ARRAY.COLUMN as \"NewerComposition\" from \"ehr\".\"entry\" right outer join \"ehr\".\"composition\" as \"composition_join\" on \"composition_join\".\"id\" = \"ehr\".\"entry\".\"composition_id\" join \"ehr\".\"event_context\" on \"ehr\".\"event_context\".\"composition_id\" = \"ehr\".\"entry\".\"composition_id\" join \"ehr\".\"party_identified\" as \"composer_ref\" on \"composition_join\".\"composer\" = \"composer_ref\".\"id\" left outer join lateral (select (select jsonb_extract_path_text(cast(\"ehr\".\"js_composition\"(\n" - + " cast(composition_join.id as uuid), \n" - + " 'local'\n" - + ") as jsonb),'uid','value') as \"Diagnose\" where cast(jsonb_extract_path_text(cast(\"ehr\".\"js_dv_coded_text_inner\"(\"ehr\".\"entry\".\"name\") as jsonb),'value') as varchar) = cast('Diagnose' as varchar)) as \"COLUMN\") as \"ARRAY\" on ? left outer join lateral (select (select jsonb_extract_path_text(cast(\"ehr\".\"js_composition\"(\n" - + " cast(composition_join.id as uuid), \n" - + " 'local'\n" - + ") as jsonb),'uid','value') as \"MabuseComposition\" where cast(jsonb_extract_path_text(cast(\"ehr\".\"js_party_ref\"(\n" - + " \"composer_ref\".\"party_ref_value\", \n" - + " \"composer_ref\".\"party_ref_scheme\", \n" - + " \"composer_ref\".\"party_ref_namespace\", \n" - + " \"composer_ref\".\"party_ref_type\"\n" - + ") as jsonb),'id','value') as varchar) = cast('Dr Mabuse' as varchar)) as \"COLUMN\") as \"ARRAY\" on ? left outer join lateral (select (select jsonb_extract_path_text(cast(\"ehr\".\"js_composition\"(\n" - + " cast(composition_join.id as uuid), \n" - + " 'local'\n" - + ") as jsonb),'uid','value') as \"NewerComposition\" where cast(jsonb_extract_path_text(cast(\"ehr\".\"js_dv_date_time\"(\n" - + " \"ehr\".\"event_context\".\"start_time\", \n" - + " event_context.START_TIME_TZID\n" - + ") as jsonb),'value') as varchar) > cast('2020-01-01' as varchar)) as \"COLUMN\") as \"ARRAY\" on ? where \"ehr\".\"entry\".\"template_id\" = ? union all select ARRAY.COLUMN as \"Diagnose\", ARRAY.COLUMN as \"MabuseComposition\", ARRAY.COLUMN as \"NewerComposition\" from \"ehr\".\"entry\" right outer join \"ehr\".\"composition\" as \"composition_join\" on \"composition_join\".\"id\" = \"ehr\".\"entry\".\"composition_id\" join \"ehr\".\"event_context\" on \"ehr\".\"event_context\".\"composition_id\" = \"ehr\".\"entry\".\"composition_id\" join \"ehr\".\"party_identified\" as \"composer_ref\" on \"composition_join\".\"composer\" = \"composer_ref\".\"id\" left outer join lateral (select (select jsonb_extract_path_text(cast(\"ehr\".\"js_composition\"(\n" - + " cast(composition_join.id as uuid), \n" - + " 'local'\n" - + ") as jsonb),'uid','value') as \"Diagnose\" where cast(jsonb_extract_path_text(cast(\"ehr\".\"js_dv_coded_text_inner\"(\"ehr\".\"entry\".\"name\") as jsonb),'value') as varchar) = cast('Diagnose' as varchar)) as \"COLUMN\") as \"ARRAY\" on ? left outer join lateral (select (select jsonb_extract_path_text(cast(\"ehr\".\"js_composition\"(\n" - + " cast(composition_join.id as uuid), \n" - + " 'local'\n" - + ") as jsonb),'uid','value') as \"MabuseComposition\" where cast(jsonb_extract_path_text(cast(\"ehr\".\"js_party_ref\"(\n" - + " \"composer_ref\".\"party_ref_value\", \n" - + " \"composer_ref\".\"party_ref_scheme\", \n" - + " \"composer_ref\".\"party_ref_namespace\", \n" - + " \"composer_ref\".\"party_ref_type\"\n" - + ") as jsonb),'id','value') as varchar) = cast('Dr Mabuse' as varchar)) as \"COLUMN\") as \"ARRAY\" on ? left outer join lateral (select (select jsonb_extract_path_text(cast(\"ehr\".\"js_composition\"(\n" - + " cast(composition_join.id as uuid), \n" - + " 'local'\n" - + ") as jsonb),'uid','value') as \"NewerComposition\" where cast(jsonb_extract_path_text(cast(\"ehr\".\"js_dv_date_time\"(\n" - + " \"ehr\".\"event_context\".\"start_time\", \n" - + " event_context.START_TIME_TZID\n" - + ") as jsonb),'value') as varchar) > cast('2020-01-01' as varchar)) as \"COLUMN\") as \"ARRAY\" on ? where \"ehr\".\"entry\".\"template_id\" = ?"; + "select ARRAY.COLUMN as \"Diagnose\", ARRAY.COLUMN as \"MabuseComposition\", ARRAY.COLUMN as \"NewerComposition\" from \"ehr\".\"entry\" right outer join \"ehr\".\"composition\" as \"composition_join\" on \"composition_join\".\"id\" = \"ehr\".\"entry\".\"composition_id\" join \"ehr\".\"event_context\" on \"ehr\".\"event_context\".\"composition_id\" = \"ehr\".\"entry\".\"composition_id\" join \"ehr\".\"party_identified\" as \"composer_ref\" on \"composition_join\".\"composer\" = \"composer_ref\".\"id\" left outer join lateral (select (select jsonb_extract_path_text(cast(\"ehr\".\"js_composition\"(cast(\"composition_join\".\"id\" as uuid), cast('local' as text)) as jsonb), 'uid', 'value') as \"Diagnose\" where cast(jsonb_extract_path_text(cast(\"ehr\".\"js_dv_coded_text_inner\"(\"ehr\".\"entry\".\"name\") as jsonb), 'value') as varchar) = cast('Diagnose' as varchar)) as \"COLUMN\") as \"ARRAY\" on ? left outer join lateral (select (select jsonb_extract_path_text(cast(\"ehr\".\"js_composition\"(cast(\"composition_join\".\"id\" as uuid), cast('local' as text)) as jsonb), 'uid', 'value') as \"MabuseComposition\" where cast(jsonb_extract_path_text(cast(\"ehr\".\"js_party_ref\"(\"composer_ref\".\"party_ref_value\", \"composer_ref\".\"party_ref_scheme\", \"composer_ref\".\"party_ref_namespace\", \"composer_ref\".\"party_ref_type\") as jsonb), 'id', 'value') as varchar) = cast('Dr Mabuse' as varchar)) as \"COLUMN\") as \"ARRAY\" on ? left outer join lateral (select (select jsonb_extract_path_text(cast(\"ehr\".\"js_composition\"(cast(\"composition_join\".\"id\" as uuid), cast('local' as text)) as jsonb), 'uid', 'value') as \"NewerComposition\" where cast(jsonb_extract_path_text(cast(\"ehr\".\"js_dv_date_time\"(\"ehr\".\"event_context\".\"start_time\", \"ehr\".\"event_context\".\"start_time_tzid\") as jsonb), 'value') as varchar) > cast('2020-01-01' as varchar)) as \"COLUMN\") as \"ARRAY\" on ? where \"ehr\".\"entry\".\"template_id\" = ? union all select ARRAY.COLUMN as \"Diagnose\", ARRAY.COLUMN as \"MabuseComposition\", ARRAY.COLUMN as \"NewerComposition\" from \"ehr\".\"entry\" right outer join \"ehr\".\"composition\" as \"composition_join\" on \"composition_join\".\"id\" = \"ehr\".\"entry\".\"composition_id\" join \"ehr\".\"event_context\" on \"ehr\".\"event_context\".\"composition_id\" = \"ehr\".\"entry\".\"composition_id\" join \"ehr\".\"party_identified\" as \"composer_ref\" on \"composition_join\".\"composer\" = \"composer_ref\".\"id\" left outer join lateral (select (select jsonb_extract_path_text(cast(\"ehr\".\"js_composition\"(cast(\"composition_join\".\"id\" as uuid), cast('local' as text)) as jsonb), 'uid', 'value') as \"Diagnose\" where cast(jsonb_extract_path_text(cast(\"ehr\".\"js_dv_coded_text_inner\"(\"ehr\".\"entry\".\"name\") as jsonb), 'value') as varchar) = cast('Diagnose' as varchar)) as \"COLUMN\") as \"ARRAY\" on ? left outer join lateral (select (select jsonb_extract_path_text(cast(\"ehr\".\"js_composition\"(cast(\"composition_join\".\"id\" as uuid), cast('local' as text)) as jsonb), 'uid', 'value') as \"MabuseComposition\" where cast(jsonb_extract_path_text(cast(\"ehr\".\"js_party_ref\"(\"composer_ref\".\"party_ref_value\", \"composer_ref\".\"party_ref_scheme\", \"composer_ref\".\"party_ref_namespace\", \"composer_ref\".\"party_ref_type\") as jsonb), 'id', 'value') as varchar) = cast('Dr Mabuse' as varchar)) as \"COLUMN\") as \"ARRAY\" on ? left outer join lateral (select (select jsonb_extract_path_text(cast(\"ehr\".\"js_composition\"(cast(\"composition_join\".\"id\" as uuid), cast('local' as text)) as jsonb), 'uid', 'value') as \"NewerComposition\" where cast(jsonb_extract_path_text(cast(\"ehr\".\"js_dv_date_time\"(\"ehr\".\"event_context\".\"start_time\", \"ehr\".\"event_context\".\"start_time_tzid\") as jsonb), 'value') as varchar) > cast('2020-01-01' as varchar)) as \"COLUMN\") as \"ARRAY\" on ? where \"ehr\".\"entry\".\"template_id\" = ?"; } @Test diff --git a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC43Test.java b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC43Test.java index 8b0001d79..0190f5b19 100644 --- a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC43Test.java +++ b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC43Test.java @@ -27,19 +27,19 @@ public class UC43Test extends UC43 { public UC43Test() { super(); this.expectedSqlExpression = - "select ARRAY.COLUMN as \"uid1\", ARRAY.COLUMN as \"uid2\" from \"ehr\".\"entry\" right outer join \"ehr\".\"composition\" as \"composition_join\" on \"composition_join\".\"id\" = \"ehr\".\"entry\".\"composition_id\" left outer join lateral (select (select jsonb_extract_path_text(cast(\"ehr\".\"js_composition\"(\n" - + " cast(composition_join.id as uuid), \n" - + " 'local'\n" - + ") as jsonb),'uid','value') as \"uid1\" where cast(jsonb_extract_path_text(cast(\"ehr\".\"js_dv_coded_text_inner\"(\"ehr\".\"entry\".\"name\") as jsonb),'value') as varchar) = cast('Laborbefund-1' as varchar)) as \"COLUMN\") as \"ARRAY\" on ? left outer join lateral (select (select jsonb_extract_path_text(cast(\"ehr\".\"js_composition\"(\n" - + " cast(composition_join.id as uuid), \n" - + " 'local'\n" - + ") as jsonb),'uid','value') as \"uid2\" where cast(jsonb_extract_path_text(cast(\"ehr\".\"js_dv_coded_text_inner\"(\"ehr\".\"entry\".\"name\") as jsonb),'value') as varchar) = cast('Laborbefund-2' as varchar)) as \"COLUMN\") as \"ARRAY\" on ? where \"ehr\".\"entry\".\"template_id\" = ? union all select ARRAY.COLUMN as \"uid1\", ARRAY.COLUMN as \"uid2\" from \"ehr\".\"entry\" right outer join \"ehr\".\"composition\" as \"composition_join\" on \"composition_join\".\"id\" = \"ehr\".\"entry\".\"composition_id\" left outer join lateral (select (select jsonb_extract_path_text(cast(\"ehr\".\"js_composition\"(\n" - + " cast(composition_join.id as uuid), \n" - + " 'local'\n" - + ") as jsonb),'uid','value') as \"uid1\" where cast(jsonb_extract_path_text(cast(\"ehr\".\"js_dv_coded_text_inner\"(\"ehr\".\"entry\".\"name\") as jsonb),'value') as varchar) = cast('Laborbefund-1' as varchar)) as \"COLUMN\") as \"ARRAY\" on ? left outer join lateral (select (select jsonb_extract_path_text(cast(\"ehr\".\"js_composition\"(\n" - + " cast(composition_join.id as uuid), \n" - + " 'local'\n" - + ") as jsonb),'uid','value') as \"uid2\" where cast(jsonb_extract_path_text(cast(\"ehr\".\"js_dv_coded_text_inner\"(\"ehr\".\"entry\".\"name\") as jsonb),'value') as varchar) = cast('Laborbefund-2' as varchar)) as \"COLUMN\") as \"ARRAY\" on ? where \"ehr\".\"entry\".\"template_id\" = ?"; + "select ARRAY.COLUMN as \"uid1\", ARRAY.COLUMN as \"uid2\" from \"ehr\".\"entry\" right outer join \"ehr\".\"composition\" as \"composition_join\" on \"composition_join\".\"id\" = \"ehr\".\"entry\".\"composition_id\" left outer join lateral (select (select jsonb_extract_path_text(cast(\"ehr\".\"js_composition\"(" + + " cast(\"composition_join\".\"id\" as uuid), " + + " cast('local' as text)" + + ") as jsonb),'uid', 'value') as \"uid1\" where cast(jsonb_extract_path_text(cast(\"ehr\".\"js_dv_coded_text_inner\"(\"ehr\".\"entry\".\"name\") as jsonb),'value') as varchar) = cast('Laborbefund-1' as varchar)) as \"COLUMN\") as \"ARRAY\" on ? left outer join lateral (select (select jsonb_extract_path_text(cast(\"ehr\".\"js_composition\"(" + + " cast(\"composition_join\".\"id\" as uuid), " + + " cast('local' as text)" + + ") as jsonb),'uid', 'value') as \"uid2\" where cast(jsonb_extract_path_text(cast(\"ehr\".\"js_dv_coded_text_inner\"(\"ehr\".\"entry\".\"name\") as jsonb),'value') as varchar) = cast('Laborbefund-2' as varchar)) as \"COLUMN\") as \"ARRAY\" on ? where \"ehr\".\"entry\".\"template_id\" = ? union all select ARRAY.COLUMN as \"uid1\", ARRAY.COLUMN as \"uid2\" from \"ehr\".\"entry\" right outer join \"ehr\".\"composition\" as \"composition_join\" on \"composition_join\".\"id\" = \"ehr\".\"entry\".\"composition_id\" left outer join lateral (select (select jsonb_extract_path_text(cast(\"ehr\".\"js_composition\"(" + + " cast(\"composition_join\".\"id\" as uuid), " + + " cast('local' as text)" + + ") as jsonb),'uid', 'value') as \"uid1\" where cast(jsonb_extract_path_text(cast(\"ehr\".\"js_dv_coded_text_inner\"(\"ehr\".\"entry\".\"name\") as jsonb),'value') as varchar) = cast('Laborbefund-1' as varchar)) as \"COLUMN\") as \"ARRAY\" on ? left outer join lateral (select (select jsonb_extract_path_text(cast(\"ehr\".\"js_composition\"(" + + " cast(\"composition_join\".\"id\" as uuid), " + + " cast('local' as text)" + + ") as jsonb),'uid', 'value') as \"uid2\" where cast(jsonb_extract_path_text(cast(\"ehr\".\"js_dv_coded_text_inner\"(\"ehr\".\"entry\".\"name\") as jsonb),'value') as varchar) = cast('Laborbefund-2' as varchar)) as \"COLUMN\") as \"ARRAY\" on ? where \"ehr\".\"entry\".\"template_id\" = ?"; } @Test diff --git a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC46Test.java b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC46Test.java index f0be926f2..fc88bf0c9 100644 --- a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC46Test.java +++ b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC46Test.java @@ -29,7 +29,7 @@ public UC46Test() { this.expectedSqlExpression = "select distinct on (\"description\", \"timing\") \"\".\"description\", \"\".\"timing\" from (select (ARRAY.COLUMN#>>'{/description[at0001],/items[at0002],0,/value,value}')::TEXT as \"description\", (ARRAY.COLUMN#>>'{/time,/value}')::TEXT as \"timing\" from \"ehr\".\"entry\" join lateral (\n" + " select (ehr.xjsonb_array_elements((\"ehr\".\"entry\".\"entry\"#>>'{/composition[openEHR-EHR-COMPOSITION.health_summary.v1],/content[openEHR-EHR-ACTION.immunisation_procedure.v1]}')::jsonb)) \n" - + " AS COLUMN) as \"ARRAY\" on true where \"ehr\".\"entry\".\"template_id\" = ?) as \"\" order by \"description\" asc"; + + " AS COLUMN) as \"ARRAY\" on true where \"ehr\".\"entry\".\"template_id\" = ?) as \"\" order by \"\".\"description\" asc"; } @Test diff --git a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC4Test.java b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC4Test.java index 1c73d75d5..1ca4404da 100644 --- a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC4Test.java +++ b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC4Test.java @@ -29,13 +29,13 @@ public UC4Test() { this.expectedSqlExpression = "select \"\".\"/composer/name\", \"\".\"/context/start_time/value\" from (select \"composer_ref\".\"name\" as \"/composer/name\", jsonb_extract_path_text(cast(\"ehr\".\"js_dv_date_time\"(\n" + " \"ehr\".\"event_context\".\"start_time\",\n" - + " event_context.START_TIME_TZID\n" + + " \"ehr\".\"event_context\".\"start_time_tzid\"\n" + ") as jsonb),'value') as \"/context/start_time/value\"" + " from \"ehr\".\"entry\"" + " right outer join \"ehr\".\"composition\" as \"composition_join\" on \"composition_join\".\"id\" = \"ehr\".\"entry\".\"composition_id\"" + " join \"ehr\".\"event_context\" on \"ehr\".\"event_context\".\"composition_id\" = \"ehr\".\"entry\".\"composition_id\"" + " join \"ehr\".\"party_identified\" as \"composer_ref\" on \"composition_join\".\"composer\" = \"composer_ref\".\"id\"" - + " where \"ehr\".\"entry\".\"template_id\" = ?) as \"\" order by \"/context/start_time/value\" desc"; + + " where \"ehr\".\"entry\".\"template_id\" = ?) as \"\" order by \"\".\"/context/start_time/value\" desc"; } @Test diff --git a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC6Test.java b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC6Test.java index 885522970..9883d25bc 100644 --- a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC6Test.java +++ b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC6Test.java @@ -29,7 +29,7 @@ public UC6Test() { this.expectedSqlExpression = "select \"\".\"description\" from (select (ARRAY.COLUMN#>>'{/description[at0001],/items[at0002],0,/value,value}')::TEXT as \"description\" from \"ehr\".\"entry\" join lateral (\n" + " select (ehr.xjsonb_array_elements((\"ehr\".\"entry\".\"entry\"#>>'{/composition[openEHR-EHR-COMPOSITION.health_summary.v1],/content[openEHR-EHR-ACTION.immunisation_procedure.v1]}')::jsonb)) \n" - + " AS COLUMN) as \"ARRAY\" on true where \"ehr\".\"entry\".\"template_id\" = ?) as \"\" order by \"description\" asc"; + + " AS COLUMN) as \"ARRAY\" on true where \"ehr\".\"entry\".\"template_id\" = ?) as \"\" order by \"\".\"description\" asc"; } @Test diff --git a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC8Test.java b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC8Test.java index fa3476442..50fbedf5f 100644 --- a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC8Test.java +++ b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/translator/testcase/pg10/pgsql/UC8Test.java @@ -27,7 +27,7 @@ public class UC8Test extends UC8 { public UC8Test() { super(); this.expectedSqlExpression = - "select cast(\"ehr\".\"js_composition\"(cast(cast(composition_join.id as uuid) as uuid), cast(? as text)) as varchar) as \"c\" from \"ehr\".\"entry\"" + "select cast(\"ehr\".\"js_composition\"(cast(\"composition_join\".\"id\" as uuid), cast('local' as text)) as varchar) as \"c\" from \"ehr\".\"entry\"" + " right outer join \"ehr\".\"composition\" as \"composition_join\" on \"composition_join\".\"id\" = \"ehr\".\"entry\".\"composition_id\"" + " where \"ehr\".\"entry\".\"template_id\" = ?"; } diff --git a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/value_field/FormattedFieldTest.java b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/value_field/FormattedFieldTest.java deleted file mode 100644 index 79e455fe6..000000000 --- a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/value_field/FormattedFieldTest.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2020 vitasystems GmbH and Hannover Medical School. - * - * This file is part of project EHRbase - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.ehrbase.aql.sql.queryimpl.value_field; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.ehrbase.jooq.pg.Tables.EHR_; -import static org.junit.Assert.*; - -import org.ehrbase.aql.TestAqlBase; -import org.ehrbase.aql.definition.VariableDefinition; -import org.ehrbase.aql.sql.binding.JoinBinder; -import org.ehrbase.aql.sql.queryimpl.IQueryImpl; -import org.ehrbase.aql.sql.queryimpl.attribute.FieldResolutionContext; -import org.ehrbase.aql.sql.queryimpl.attribute.JoinSetup; -import org.jooq.Field; -import org.jooq.impl.DSL; -import org.junit.Before; -import org.junit.Test; - -public class FormattedFieldTest extends TestAqlBase { - - FieldResolutionContext fieldResolutionContext; - JoinSetup joinSetup = new JoinSetup(); - - @Before - public void setUp() { - fieldResolutionContext = new FieldResolutionContext( - testDomainAccess.getContext(), - "test", - "test", - new VariableDefinition("test", null, "test", false), - IQueryImpl.Clause.SELECT, - null, - testDomainAccess.getIntrospectService(), - null); - } - - @Test - public void testSelectEhrDateCreatedValue() { - Field field = new FormattedField(fieldResolutionContext, joinSetup) - .usingToJson( - "timestamp with time zone", - "||", - JoinBinder.ehrRecordTable.field(EHR_.DATE_CREATED), - JoinBinder.ehrRecordTable.field(EHR_.DATE_CREATED_TZID)); - - assertNotNull(field); - assertThat(DSL.select(field).getQuery().toString()) - .as("test formatting dvdatetime value") - .isEqualToIgnoringWhitespace( - "select cast(to_json(cast(\"ehr_join\".\"date_created\"||\"ehr_join\".\"date_created_tzid\" as varchar)) as jsonb) \"/test\""); - } -} diff --git a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/value_field/GenericJsonFieldTest.java b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/value_field/GenericJsonFieldTest.java index d6ceec4ac..ddf7a54f6 100644 --- a/service/src/test/java/org/ehrbase/aql/sql/queryimpl/value_field/GenericJsonFieldTest.java +++ b/service/src/test/java/org/ehrbase/aql/sql/queryimpl/value_field/GenericJsonFieldTest.java @@ -91,15 +91,11 @@ public void testFieldWithIterativeMarker() { assertThat(DSL.select(field).getQuery().toString()) .as(jsonPath) - .isEqualToIgnoringWhitespace("select" + " jsonb_extract_path_text(" - + " cast(" - + QueryImplConstants.AQL_NODE_ITERATIVE_FUNCTION + "(" - + " cast(cast(jsonb_extract_path(" - + " cast(\"ehr\".\"js_dv_coded_text_inner\"(\"ehr\".\"entry\".\"category\") as jsonb),'mappings')" - + " as jsonb)" - + " as jsonb))" - + " as jsonb)," - + " 'match') \"/test\""); + .isEqualToIgnoringWhitespace( + "select" + " jsonb_extract_path_text(" + + QueryImplConstants.AQL_NODE_ITERATIVE_FUNCTION + "(" + + " cast( jsonb_extract_path(" + + " cast(\"ehr\".\"js_dv_coded_text_inner\"(\"ehr\".\"entry\".\"category\") as jsonb),'mappings') as jsonb)), 'match') \"/test\""); } @Test From d21d0a97ab1926b214b334aa9cd318f6ffb10bd1 Mon Sep 17 00:00:00 2001 From: bot Date: Wed, 27 Sep 2023 10:03:49 +0000 Subject: [PATCH 53/53] release 0.31.0: updated version to 0.31.0 --- CHANGELOG.md | 5 +++-- api/pom.xml | 2 +- application/pom.xml | 2 +- base/pom.xml | 2 +- bom/pom.xml | 4 ++-- jooq-pq/pom.xml | 2 +- plugin/pom.xml | 2 +- pom.xml | 4 ++-- rest-ehr-scape/pom.xml | 2 +- rest-openehr/pom.xml | 2 +- service/pom.xml | 2 +- test-coverage/pom.xml | 2 +- 12 files changed, 16 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bfcd18d11..f4552ceb6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,9 +5,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [unreleased] +## [0.31.0] ### Added ### Changed + - Upgrade openEHR_SDK to version 2.3.0 see https://github.com/ehrbase/openEHR_SDK/blob/develop/CHANGELOG.md - Migrated to spring boot 3 ([#1174](https://github.com/ehrbase/ehrbase/pull/1174)) - Removed authorization scopes from endpoints and added support for overwriting controllers ([#1157](https://github.com/ehrbase/ehrbase/pull/1157)) ### Fixed @@ -694,4 +695,4 @@ the next release this file will provide a proper overview. [0.28.0]: https://github.com/ehrbase/ehrbase/compare/v0.27.4...v0.28.0 [0.29.0]: https://github.com/ehrbase/ehrbase/compare/v0.28.0...v0.29.0 [0.30.0]: https://github.com/ehrbase/ehrbase/compare/v0.29.0...v0.30.0 -[unreleased]: https://github.com/ehrbase/ehrbase/compare/v0.30.0...HEAD +[0.31.0]: https://github.com/ehrbase/ehrbase/compare/v0.30.0...v0.31.0 diff --git a/api/pom.xml b/api/pom.xml index 1c219d52b..923e2d544 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -26,7 +26,7 @@ org.ehrbase.openehr server - 0.31.0-SNAPSHOT + 0.31.0 api diff --git a/application/pom.xml b/application/pom.xml index 13803fa39..07f10a93e 100644 --- a/application/pom.xml +++ b/application/pom.xml @@ -26,7 +26,7 @@ org.ehrbase.openehr server - 0.31.0-SNAPSHOT + 0.31.0 application diff --git a/base/pom.xml b/base/pom.xml index fcbf9316e..0c1b27865 100644 --- a/base/pom.xml +++ b/base/pom.xml @@ -28,7 +28,7 @@ org.ehrbase.openehr server - 0.31.0-SNAPSHOT + 0.31.0 base diff --git a/bom/pom.xml b/bom/pom.xml index b05823177..11d272194 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -24,7 +24,7 @@ org.ehrbase.openehr bom - 0.31.0-SNAPSHOT + 0.31.0 pom EHRbase @@ -103,7 +103,7 @@ 3.3.0 2.13.0 3.13.0 - 2.3.0-SNAPSHOT + 2.3.0 8.5.13 2.15.0 1.95.0 diff --git a/jooq-pq/pom.xml b/jooq-pq/pom.xml index dd01b6ce6..524c9fc8c 100644 --- a/jooq-pq/pom.xml +++ b/jooq-pq/pom.xml @@ -28,7 +28,7 @@ org.ehrbase.openehr server - 0.31.0-SNAPSHOT + 0.31.0 jooq-pg diff --git a/plugin/pom.xml b/plugin/pom.xml index b2cdfa381..30c682ccf 100644 --- a/plugin/pom.xml +++ b/plugin/pom.xml @@ -5,7 +5,7 @@ server org.ehrbase.openehr - 0.31.0-SNAPSHOT + 0.31.0 4.0.0 diff --git a/pom.xml b/pom.xml index b3e4925cd..fb84da02a 100644 --- a/pom.xml +++ b/pom.xml @@ -28,12 +28,12 @@ org.ehrbase.openehr bom - 0.31.0-SNAPSHOT + 0.31.0 /bom/pom.xml server - 0.31.0-SNAPSHOT + 0.31.0 pom diff --git a/rest-ehr-scape/pom.xml b/rest-ehr-scape/pom.xml index 0be0ca5d1..d84023f31 100644 --- a/rest-ehr-scape/pom.xml +++ b/rest-ehr-scape/pom.xml @@ -28,7 +28,7 @@ org.ehrbase.openehr server - 0.31.0-SNAPSHOT + 0.31.0 rest-ehr-scape diff --git a/rest-openehr/pom.xml b/rest-openehr/pom.xml index b4bc75da3..4999be507 100644 --- a/rest-openehr/pom.xml +++ b/rest-openehr/pom.xml @@ -28,7 +28,7 @@ org.ehrbase.openehr server - 0.31.0-SNAPSHOT + 0.31.0 rest-openehr diff --git a/service/pom.xml b/service/pom.xml index 2d5ebb57e..1d2c9c8b6 100644 --- a/service/pom.xml +++ b/service/pom.xml @@ -26,7 +26,7 @@ org.ehrbase.openehr server - 0.31.0-SNAPSHOT + 0.31.0 service diff --git a/test-coverage/pom.xml b/test-coverage/pom.xml index f74e29da5..4532a3bd2 100644 --- a/test-coverage/pom.xml +++ b/test-coverage/pom.xml @@ -28,7 +28,7 @@ org.ehrbase.openehr server - 0.31.0-SNAPSHOT + 0.31.0 test-coverage