From 8a98da81c607d08088cddfc3e5d186d0b1a5a1fa Mon Sep 17 00:00:00 2001 From: Frank Schnicke Date: Mon, 3 Apr 2023 14:35:00 +0200 Subject: [PATCH 01/77] Updates version to 1.5.0-SNAPSHOT Signed-off-by: Frank Schnicke --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f0fbf56c..c4aa411b 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.eclipse.basyx basyx.sdk - 1.4.0 + 1.5.0-SNAPSHOT BaSyx SDK BaSyx Software Development Kit https://www.eclipse.org/basyx/ From c60b1b69d868f5da4273dfb28aaa87c347a7468d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Apr 2023 08:06:08 +0000 Subject: [PATCH 02/77] Bump sdk-client from 0.6.8 to 0.6.9 Bumps sdk-client from 0.6.8 to 0.6.9. --- updated-dependencies: - dependency-name: org.eclipse.milo:sdk-client dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c4aa411b..d52a7c46 100644 --- a/pom.xml +++ b/pom.xml @@ -206,7 +206,7 @@ org.eclipse.milo sdk-client - 0.6.8 + 0.6.9 From 52fed347a8a64f90099e19ec9e7b453eb9bede09 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Apr 2023 08:06:17 +0000 Subject: [PATCH 03/77] Bump sdk-server from 0.6.8 to 0.6.9 Bumps sdk-server from 0.6.8 to 0.6.9. --- updated-dependencies: - dependency-name: org.eclipse.milo:sdk-server dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c4aa411b..dcf70be7 100644 --- a/pom.xml +++ b/pom.xml @@ -213,7 +213,7 @@ org.eclipse.milo sdk-server - 0.6.8 + 0.6.9 From e1f9fbaf09d6609c58d37cfec11e419cfbde6db6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 12 Apr 2023 08:02:26 +0000 Subject: [PATCH 04/77] Bump mockito-core from 5.2.0 to 5.3.0 Bumps [mockito-core](https://github.com/mockito/mockito) from 5.2.0 to 5.3.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v5.2.0...v5.3.0) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8e3fc58e..c2c86aaf 100644 --- a/pom.xml +++ b/pom.xml @@ -184,7 +184,7 @@ org.mockito mockito-core - 5.2.0 + 5.3.0 test From 5750c653a8b6ab68e64f873beb86473797e909a2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Apr 2023 08:02:06 +0000 Subject: [PATCH 05/77] Bump spring-security-bom from 5.8.2 to 5.8.3 Bumps [spring-security-bom](https://github.com/spring-projects/spring-security) from 5.8.2 to 5.8.3. - [Release notes](https://github.com/spring-projects/spring-security/releases) - [Changelog](https://github.com/spring-projects/spring-security/blob/main/RELEASE.adoc) - [Commits](https://github.com/spring-projects/spring-security/compare/5.8.2...5.8.3) --- updated-dependencies: - dependency-name: org.springframework.security:spring-security-bom dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8e3fc58e..780c314c 100644 --- a/pom.xml +++ b/pom.xml @@ -46,7 +46,7 @@ UTF-8 UTF-8 - 5.8.2 + 5.8.3 From c453f94abf8db8317867ff7b972960e13d3544ce Mon Sep 17 00:00:00 2001 From: FlorianWege-IESE Date: Tue, 18 Apr 2023 13:42:04 +0200 Subject: [PATCH 06/77] Fix read rbac rules file - Can read rbac rules file from file system Signed-off-by: FlorianWege-IESE --- .../internal/RbacRuleSetDeserializer.java | 35 +++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/RbacRuleSetDeserializer.java b/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/RbacRuleSetDeserializer.java index db2b7366..4937570b 100644 --- a/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/RbacRuleSetDeserializer.java +++ b/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/RbacRuleSetDeserializer.java @@ -30,6 +30,8 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo.Id; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.jsontype.NamedType; + +import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; @@ -86,11 +88,7 @@ public RbacRuleSet fromFile(final String filePath) throws IOException { } logger.info("loading rbac rules..."); - try (final InputStream inputStream = RbacRuleSet.class.getResourceAsStream(filePath)) { - if (inputStream == null) { - throw new FileNotFoundException("could not find " + filePath); - } - + try (final InputStream inputStream = getInputStreamFromFile(filePath)) { final RbacRule[] rbacRules = deserialize(inputStream); logger.info("Read rbac rules: {}", Arrays.toString(rbacRules)); @@ -100,7 +98,32 @@ public RbacRuleSet fromFile(final String filePath) throws IOException { } } + private InputStream getInputStreamFromFile(final String filePath) throws IOException { + try { + final InputStream inputStream = new FileInputStream(filePath); + logger.info("read {} from file system", filePath); + return inputStream; + } catch (FileNotFoundException e) { + // did not find file on file system, fallback to read from classpath next + logger.info("did not find {} in file system, try classpath next", filePath); + } + + try { + final InputStream inputStream = RbacRuleSet.class.getResourceAsStream(filePath); + if (inputStream == null) { + throw new FileNotFoundException("could not find " + filePath); + } + logger.info("read {} from classpath", filePath); + return inputStream; + } catch (FileNotFoundException e) { + // did not find file on classpath, give up + logger.info("did not find {} on classpath, give up", filePath); + } + + throw new IOException("could not find " + filePath); + } + public RbacRule[] deserialize(final InputStream inputStream) throws IOException { return objectMapper.readValue(inputStream, RbacRule[].class); } -} +} \ No newline at end of file From ba7d7c1f77fafbbd94c30c1a765cbcca56894513 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Apr 2023 08:02:51 +0000 Subject: [PATCH 07/77] Bump tomcat-catalina from 9.0.73 to 9.0.74 Bumps tomcat-catalina from 9.0.73 to 9.0.74. --- updated-dependencies: - dependency-name: org.apache.tomcat:tomcat-catalina dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8e3fc58e..b6e2e5c5 100644 --- a/pom.xml +++ b/pom.xml @@ -248,7 +248,7 @@ org.apache.tomcat tomcat-catalina - 9.0.73 + 9.0.74 From 832aa19c95638e2c302901910b1c779dbfb7cec1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Apr 2023 08:02:24 +0000 Subject: [PATCH 08/77] Bump logback-classic from 1.4.6 to 1.4.7 Bumps [logback-classic](https://github.com/qos-ch/logback) from 1.4.6 to 1.4.7. - [Release notes](https://github.com/qos-ch/logback/releases) - [Commits](https://github.com/qos-ch/logback/compare/v_1.4.6...v_1.4.7) --- updated-dependencies: - dependency-name: ch.qos.logback:logback-classic dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8e3fc58e..028cda8e 100644 --- a/pom.xml +++ b/pom.xml @@ -169,7 +169,7 @@ ch.qos.logback logback-classic - 1.4.6 + 1.4.7 From 73197f1cb377de938cc21e3b51f76c349f2ce41c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Apr 2023 08:17:28 +0000 Subject: [PATCH 09/77] Bump mockito-core from 5.3.0 to 5.3.1 Bumps [mockito-core](https://github.com/mockito/mockito) from 5.3.0 to 5.3.1. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v5.3.0...v5.3.1) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d8c75b49..2175f883 100644 --- a/pom.xml +++ b/pom.xml @@ -184,7 +184,7 @@ org.mockito mockito-core - 5.3.0 + 5.3.1 test From 7c7b4276bdfff2cea7c11118b0e5a6723e20f94a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Apr 2023 08:17:30 +0000 Subject: [PATCH 10/77] Bump jackson-databind from 2.14.2 to 2.15.0 Bumps [jackson-databind](https://github.com/FasterXML/jackson) from 2.14.2 to 2.15.0. - [Release notes](https://github.com/FasterXML/jackson/releases) - [Commits](https://github.com/FasterXML/jackson/commits) --- updated-dependencies: - dependency-name: com.fasterxml.jackson.core:jackson-databind dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d8c75b49..6603f0d7 100644 --- a/pom.xml +++ b/pom.xml @@ -333,7 +333,7 @@ com.fasterxml.jackson.core jackson-databind - 2.14.2 + 2.15.0 From 03364a06aff394dd6dc1dc07ed0d7db6a059a621 Mon Sep 17 00:00:00 2001 From: CVEDetect <89496918+CVEDetect@users.noreply.github.com> Date: Tue, 25 Apr 2023 15:43:41 +0800 Subject: [PATCH 11/77] Fix CVE dependency issue (#277) --- pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pom.xml b/pom.xml index 9c82bc3e..9219091f 100644 --- a/pom.xml +++ b/pom.xml @@ -258,6 +258,12 @@ 4.1.2 + + org.apache.commons + commons-compress + 1.21 + + org.codehaus.janino From c9302d859f616a92fad47731e39a0c0f886c6415 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Apr 2023 08:04:05 +0000 Subject: [PATCH 12/77] Bump commons-compress from 1.21 to 1.23.0 Bumps commons-compress from 1.21 to 1.23.0. --- updated-dependencies: - dependency-name: org.apache.commons:commons-compress dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9219091f..057af4ba 100644 --- a/pom.xml +++ b/pom.xml @@ -261,7 +261,7 @@ org.apache.commons commons-compress - 1.21 + 1.23.0 From 3cf22a7fd2cf687303b6a24612cd7ea78bb6aa04 Mon Sep 17 00:00:00 2001 From: Mohammad Ghazanfar Ali Danish Date: Tue, 25 Apr 2023 10:24:39 +0200 Subject: [PATCH 13/77] Fixes empty Asset Signed-off-by: Mohammad Ghazanfar Ali Danish --- .../factory/xml/XMLToMetamodelConverter.java | 7 ++-- .../AssetAdministrationShellXMLConverter.java | 32 ++++++++++++++++++- ...TestAASXToMetamodelConverterFromBaSyx.java | 1 + 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/eclipse/basyx/aas/factory/xml/XMLToMetamodelConverter.java b/src/main/java/org/eclipse/basyx/aas/factory/xml/XMLToMetamodelConverter.java index a1819cc7..bedf8c40 100644 --- a/src/main/java/org/eclipse/basyx/aas/factory/xml/XMLToMetamodelConverter.java +++ b/src/main/java/org/eclipse/basyx/aas/factory/xml/XMLToMetamodelConverter.java @@ -73,13 +73,14 @@ public XMLToMetamodelConverter(String xmlContent) throws ParserConfigurationExce Map xmlConceptDescriptions = (Map) root.get(ConceptDescriptionXMLConverter.CONCEPT_DESCRIPTIONS); List conceptDescriptions = ConceptDescriptionXMLConverter.parseConceptDescriptions(xmlConceptDescriptions); + + Map xmlAssets = (Map) root.get(AssetXMLConverter.ASSETS); + List assets = AssetXMLConverter.parseAssets(xmlAssets); - List shells = AssetAdministrationShellXMLConverter.parseAssetAdministrationShells(xmlAASs, conceptDescriptions); + List shells = AssetAdministrationShellXMLConverter.parseAssetAdministrationShells(xmlAASs, conceptDescriptions, assets); Map xmlSubmodels = (Map) root.get(SubmodelXMLConverter.SUBMODELS); List submodels = SubmodelXMLConverter.parseSubmodels(xmlSubmodels); - Map xmlAssets = (Map) root.get(AssetXMLConverter.ASSETS); - List assets = AssetXMLConverter.parseAssets(xmlAssets); aasEnv = new AasEnv(shells, assets, conceptDescriptions, submodels); } diff --git a/src/main/java/org/eclipse/basyx/aas/factory/xml/converters/AssetAdministrationShellXMLConverter.java b/src/main/java/org/eclipse/basyx/aas/factory/xml/converters/AssetAdministrationShellXMLConverter.java index ea26eca4..c95149e5 100644 --- a/src/main/java/org/eclipse/basyx/aas/factory/xml/converters/AssetAdministrationShellXMLConverter.java +++ b/src/main/java/org/eclipse/basyx/aas/factory/xml/converters/AssetAdministrationShellXMLConverter.java @@ -30,13 +30,16 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import org.eclipse.basyx.aas.factory.xml.api.parts.ViewXMLConverter; import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell; import org.eclipse.basyx.aas.metamodel.api.parts.IConceptDictionary; import org.eclipse.basyx.aas.metamodel.api.parts.IView; +import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset; import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; +import org.eclipse.basyx.aas.metamodel.map.parts.Asset; import org.eclipse.basyx.aas.metamodel.map.parts.ConceptDictionary; import org.eclipse.basyx.submodel.factory.xml.XMLHelper; import org.eclipse.basyx.submodel.factory.xml.converters.qualifier.HasDataSpecificationXMLConverter; @@ -87,7 +90,7 @@ public class AssetAdministrationShellXMLConverter { * Map */ @SuppressWarnings("unchecked") - public static List parseAssetAdministrationShells(Map xmlAASObject, Collection conceptDescriptions) { + public static List parseAssetAdministrationShells(Map xmlAASObject, Collection conceptDescriptions, Collection assets) { if (xmlAASObject == null) { return Collections.emptyList(); } @@ -117,6 +120,11 @@ public static List parseAssetAdministrationShells(Map Collection submodelRefs = parseSubmodelRefs(xmlAAS); adminShell.setSubmodelReferences(submodelRefs); + + Asset asset = parseAsset(assets, assetRef); + + if (asset != null) + adminShell.setAsset(asset); aasList.add(adminShell); } @@ -353,5 +361,27 @@ private static Element buildConceptDictionary(Document document, IAssetAdministr } return conceptDicts; } + + private static Asset parseAsset(Collection assets, Reference assetRef) { + if (assetRef == null) + return null; + + Optional optionalAsset = assets.stream().filter(asset -> isReferenced(asset, assetRef)).findAny(); + + if (optionalAsset.isEmpty()) + return null; + + return (Asset) optionalAsset.get(); + } + + private static boolean isReferenced(IAsset asset, Reference assetReference) { + Optional optionalKey = assetReference.getKeys().stream().filter(key -> hasMatchingAsset(asset, key)).findAny(); + + return optionalKey.isPresent(); + } + + private static boolean hasMatchingAsset(IAsset asset, IKey key) { + return key.getValue().equals(asset.getIdentification().getId()); + } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestAASXToMetamodelConverterFromBaSyx.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestAASXToMetamodelConverterFromBaSyx.java index 8d0b90d7..9c3e37bf 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestAASXToMetamodelConverterFromBaSyx.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestAASXToMetamodelConverterFromBaSyx.java @@ -165,6 +165,7 @@ public void testLoadGeneratedAASX() throws InvalidFormatException, IOException, IAssetAdministrationShell parsedAAS = bundle.getAAS(); assertEquals(AAS_IDSHORT, parsedAAS.getIdShort()); assertEquals(AAS_IDENTIFICATION, parsedAAS.getIdentification().getId()); + assertEquals(ASSET_IDSHORT, parsedAAS.getAsset().getIdShort()); assertEquals(submodelSize, bundle.getSubmodels().size()); From f1b7f1c07df1d6e1866c6a285c20f4131ae5c1ab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 May 2023 08:07:05 +0000 Subject: [PATCH 14/77] Bump maven-failsafe-plugin from 3.0.0 to 3.1.0 Bumps [maven-failsafe-plugin](https://github.com/apache/maven-surefire) from 3.0.0 to 3.1.0. - [Release notes](https://github.com/apache/maven-surefire/releases) - [Commits](https://github.com/apache/maven-surefire/compare/surefire-3.0.0...surefire-3.1.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-failsafe-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 057af4ba..0aee920c 100644 --- a/pom.xml +++ b/pom.xml @@ -126,7 +126,7 @@ org.apache.maven.plugins maven-failsafe-plugin - 3.0.0 + 3.1.0 **/*HTTP* From e0937e9b042003dfc9f74d2d89563daa3cf28f81 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 May 2023 08:07:23 +0000 Subject: [PATCH 15/77] Bump maven-gpg-plugin from 3.0.1 to 3.1.0 Bumps [maven-gpg-plugin](https://github.com/apache/maven-gpg-plugin) from 3.0.1 to 3.1.0. - [Commits](https://github.com/apache/maven-gpg-plugin/compare/maven-gpg-plugin-3.0.1...maven-gpg-plugin-3.1.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-gpg-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 057af4ba..eb979067 100644 --- a/pom.xml +++ b/pom.xml @@ -402,7 +402,7 @@ org.apache.maven.plugins maven-gpg-plugin - 3.0.1 + 3.1.0 sign-artifacts From db3aa0d8f38db0ca1c518397e9ff4c5ef3c35c01 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 May 2023 08:07:31 +0000 Subject: [PATCH 16/77] Bump maven-surefire-plugin from 3.0.0 to 3.1.0 Bumps [maven-surefire-plugin](https://github.com/apache/maven-surefire) from 3.0.0 to 3.1.0. - [Release notes](https://github.com/apache/maven-surefire/releases) - [Commits](https://github.com/apache/maven-surefire/compare/surefire-3.0.0...surefire-3.1.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-surefire-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 057af4ba..9dd3c98d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,7 +110,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.0.0 + 3.1.0 **/*HTTP* From cb5df1f4ed38bbe741f904e37c92e51c47ed8947 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 May 2023 08:02:49 +0000 Subject: [PATCH 17/77] Bump tomcat-catalina from 9.0.74 to 9.0.75 Bumps tomcat-catalina from 9.0.74 to 9.0.75. --- updated-dependencies: - dependency-name: org.apache.tomcat:tomcat-catalina dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c35258a3..96a4f978 100644 --- a/pom.xml +++ b/pom.xml @@ -248,7 +248,7 @@ org.apache.tomcat tomcat-catalina - 9.0.74 + 9.0.75 From 5d1b161ad6fa5977701953f304108b375c77b0a5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 May 2023 08:12:47 +0000 Subject: [PATCH 18/77] Bump tika-core from 2.7.0 to 2.8.0 Bumps [tika-core](https://github.com/apache/tika) from 2.7.0 to 2.8.0. - [Changelog](https://github.com/apache/tika/blob/main/CHANGES.txt) - [Commits](https://github.com/apache/tika/compare/2.7.0...2.8.0) --- updated-dependencies: - dependency-name: org.apache.tika:tika-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 96a4f978..c5d6a517 100644 --- a/pom.xml +++ b/pom.xml @@ -366,7 +366,7 @@ org.apache.tika tika-core - 2.7.0 + 2.8.0 From 92484c580d9a69f6f85f951c63cdd52941f27580 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 May 2023 08:12:16 +0000 Subject: [PATCH 19/77] Bump commons-io from 2.11.0 to 2.12.0 Bumps commons-io from 2.11.0 to 2.12.0. --- updated-dependencies: - dependency-name: commons-io:commons-io dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c5d6a517..49526032 100644 --- a/pom.xml +++ b/pom.xml @@ -289,7 +289,7 @@ commons-io commons-io - 2.11.0 + 2.12.0 From 1367ac656aeb6084351caf03c338fdf6e1a530d9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 May 2023 08:12:23 +0000 Subject: [PATCH 20/77] Bump jackson-databind from 2.15.0 to 2.15.1 Bumps [jackson-databind](https://github.com/FasterXML/jackson) from 2.15.0 to 2.15.1. - [Commits](https://github.com/FasterXML/jackson/commits) --- updated-dependencies: - dependency-name: com.fasterxml.jackson.core:jackson-databind dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c5d6a517..e2702d05 100644 --- a/pom.xml +++ b/pom.xml @@ -339,7 +339,7 @@ com.fasterxml.jackson.core jackson-databind - 2.15.0 + 2.15.1 From 775f44a9650954ea80b88d747ddb8510591a68a0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 May 2023 08:10:09 +0000 Subject: [PATCH 21/77] Bump maven-source-plugin from 3.2.1 to 3.3.0 Bumps [maven-source-plugin](https://github.com/apache/maven-source-plugin) from 3.2.1 to 3.3.0. - [Commits](https://github.com/apache/maven-source-plugin/compare/maven-source-plugin-3.2.1...maven-source-plugin-3.3.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-source-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ec86cde8..5af397b2 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,7 @@ org.apache.maven.plugins maven-source-plugin - 3.2.1 + 3.3.0 attach-sources From e622d38d784a1f551cf3f94a1466e98c785a1682 Mon Sep 17 00:00:00 2001 From: Tilman Klaeger Date: Thu, 25 May 2023 07:00:46 +0200 Subject: [PATCH 22/77] Allow uppercase dataTypes and set them to lowercase (#290) --- .../property/valuetype/ValueTypeHelper.java | 15 ++++++++++++++ .../valuetype/TestValueTypeHelper.java | 20 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/ValueTypeHelper.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/ValueTypeHelper.java index 155ab7f2..f78946c1 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/ValueTypeHelper.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/ValueTypeHelper.java @@ -24,6 +24,9 @@ ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.math.BigInteger; import java.time.Duration; import java.time.Period; @@ -47,6 +50,7 @@ */ public class ValueTypeHelper { private static Map typeMap = new LinkedHashMap<>(); + private static Logger logger = LoggerFactory.getLogger(ValueTypeHelper.class); // insert all types into a Map to allow getting a PropertyValueType based on a // String @@ -67,8 +71,19 @@ public class ValueTypeHelper { * @return */ public static ValueType fromName(String name) { + + String name_with_lowercase_start = Character.toLowerCase(name.charAt(0)) + name.substring(1); + if (typeMap.containsKey(name)) { return typeMap.get(name); + } else if (typeMap.containsKey(name_with_lowercase_start)) { + logger.warn("Type " + name + " does not comply to the standard."); + logger.warn("Trying to use it as " + name_with_lowercase_start + "!"); + return typeMap.get(name_with_lowercase_start); + } else if (typeMap.containsKey(name.toLowerCase())) { + logger.warn("Type " + name + " does not comply to the standard."); + logger.warn("Trying to use it as " + name.toLowerCase() + "!"); + return typeMap.get(name.toLowerCase()); } else { throw new RuntimeException("Unknown type name " + name + "; can not handle this PropertyValueType"); } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/TestValueTypeHelper.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/TestValueTypeHelper.java index 790394ce..0c0f1567 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/TestValueTypeHelper.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/TestValueTypeHelper.java @@ -28,6 +28,8 @@ import static org.junit.Assert.assertEquals; +import java.util.Iterator; +import java.util.List; import javax.xml.datatype.DatatypeConfigurationException; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; @@ -44,6 +46,24 @@ */ public class TestValueTypeHelper { + @Test + public void NonStandardUpperCaseHandling() { + List testList = List.of("integer", "Integer", "Float", "dateTime", "base64Binary", "dateTimeStamp", + "INTEGER"); + List correctList = List.of("integer", "integer", "float", "dateTime", "base64Binary", "dateTimeStamp", + "integer"); + + Iterator testsIterator = testList.iterator(); + Iterator correctsIterator = correctList.iterator(); + + while (testsIterator.hasNext() && correctsIterator.hasNext()) { + ValueType type = ValueTypeHelper.fromName(testsIterator.next()); + ValueType expected = ValueTypeHelper.fromName(correctsIterator.next()); + assertEquals(expected, type); + + } + } + @Test public void dateFromString() throws DatatypeConfigurationException { String date = "2002-09-24"; From 56484f408426c3dd0703a0e5991279eee18d2ba0 Mon Sep 17 00:00:00 2001 From: Tilman Klaeger Date: Thu, 25 May 2023 07:12:57 +0200 Subject: [PATCH 23/77] Adding ValueType "decimal" (#289) Signed-off-by: Tilman Klaeger --- .../property/valuetype/ValueType.java | 7 ++++--- .../property/valuetype/ValueTypeHelper.java | 11 +++++++++- .../valuetype/TestValueTypeHelper.java | 20 +++++++++++++++++++ 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/ValueType.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/ValueType.java index 570cfbd2..7cd727ae 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/ValueType.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/ValueType.java @@ -38,9 +38,10 @@ public enum ValueType implements StandardizedLiteralEnum { Int8("byte"), Int16("short"), Int32("int"), Int64("long"), UInt8("unsignedByte"), UInt16("unsignedShort"), UInt32("unsignedInt"), UInt64("unsignedLong"), String("string"), LangString("langString"), AnyURI("anyURI"), Base64Binary( "base64Binary"), HexBinary("hexBinary"), NOTATION("notation"), ENTITY("entity"), ID("id"), IDREF("idref"), Integer("integer"), NonPositiveInteger("nonPositiveInteger"), NonNegativeInteger("nonNegativeInteger"), PositiveInteger( - "positiveInteger"), NegativeInteger("negativeInteger"), Double("double"), Float("float"), Boolean("boolean"), Duration("duration"), DayTimeDuration("dayTimeDuration"), YearMonthDuration("yearMonthDuration"), Date( - "date"), DateTime("dateTime"), DateTimeStamp( - "dateTimeStamp"), GDay("gDay"), GMonth("gMonth"), GMonthDay("gMonthDay"), GYear("gYear"), GYearMonth("gYearMonth"), QName("qName"), None("none"), AnyType("anyType"), AnySimpleType("anySimpleType"); + "positiveInteger"), NegativeInteger("negativeInteger"), Decimal("decimal"), Double("double"), Float("float"), Boolean("boolean"), Duration("duration"), DayTimeDuration("dayTimeDuration"), YearMonthDuration("yearMonthDuration"), Date( + "date"), DateTime("dateTime"), DateTimeStamp( + "dateTimeStamp"), GDay("gDay"), GMonth("gMonth"), GMonthDay("gMonthDay"), GYear("gYear"), GYearMonth("gYearMonth"), QName("qName"), None("none"), AnyType("anyType"), AnySimpleType("anySimpleType"), + ; private String standardizedLiteral; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/ValueTypeHelper.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/ValueTypeHelper.java index f78946c1..0f2fe635 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/ValueTypeHelper.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/ValueTypeHelper.java @@ -24,9 +24,9 @@ ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype; +import java.math.BigDecimal; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import java.math.BigInteger; import java.time.Duration; import java.time.Period; @@ -208,6 +208,15 @@ public static Object getJavaObject(Object value, ValueType objType) { target = new BigInteger((String) value); } break; + case Decimal: + if (((String) value).isEmpty()) { + // BigDecimal does not have anything like "NaN", so we set it to 0 to avoid setting it to null + // possibly resulting in NullPointerExceptions later on + target = BigDecimal.ZERO; + } else { + target = new BigDecimal((String) value); + } + break; case Double: if (((String) value).isEmpty()) { target = new Double("NaN"); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/TestValueTypeHelper.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/TestValueTypeHelper.java index 0c0f1567..1af87c4f 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/TestValueTypeHelper.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/TestValueTypeHelper.java @@ -38,6 +38,8 @@ import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueTypeHelper; import org.junit.Test; +import java.math.BigDecimal; + /** * Tests the ValueTypeHelper class * @@ -72,4 +74,22 @@ public void dateFromString() throws DatatypeConfigurationException { XMLGregorianCalendar expected = DatatypeFactory.newInstance().newXMLGregorianCalendar(date); assertEquals(expected, javaObject); } + + @Test + public void decimalDataType() { + String data = "10.10"; + Object javaObject = ValueTypeHelper.getJavaObject(data, ValueType.Decimal); + + BigDecimal expected = new BigDecimal(data); + assertEquals(expected, javaObject); + } + + @Test + public void decimalDataTypeNaN() { + String data = ""; + Object javaObject = ValueTypeHelper.getJavaObject(data, ValueType.Decimal); + + BigDecimal expected = new BigDecimal("0"); + assertEquals(expected, javaObject); + } } From 715e4dff534881b8b9a1f1711eb58096f8103c6e Mon Sep 17 00:00:00 2001 From: Frank Schnicke Date: Thu, 25 May 2023 11:59:16 +0200 Subject: [PATCH 24/77] AASXToMetamodelConverter is less chatty in info logging mode Signed-off-by: Frank Schnicke --- .../basyx/aas/factory/aasx/AASXToMetamodelConverter.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/eclipse/basyx/aas/factory/aasx/AASXToMetamodelConverter.java b/src/main/java/org/eclipse/basyx/aas/factory/aasx/AASXToMetamodelConverter.java index 55afad4f..59d96860 100644 --- a/src/main/java/org/eclipse/basyx/aas/factory/aasx/AASXToMetamodelConverter.java +++ b/src/main/java/org/eclipse/basyx/aas/factory/aasx/AASXToMetamodelConverter.java @@ -351,13 +351,13 @@ private void unzipFile(String filePath, OPCPackage aasxRoot, Path pathToDirector return; } - logger.info("Unzipping " + filePath); + logger.debug("Unzipping " + filePath); String relativePath = "files/" + VABPathTools.getParentPath(filePath); Path destDir; destDir = pathToDirectory.resolve(relativePath); - logger.info("Unzipping to " + destDir); + logger.debug("Unzipping to " + destDir); Files.createDirectories(destDir); PackagePart part = aasxRoot.getPart(PackagingURIHelper.createPartName("/" + filePath)); From a45b2ae3b55a5a579f2062029ec94be55eeb1f8f Mon Sep 17 00:00:00 2001 From: Frank Schnicke Date: Thu, 25 May 2023 12:07:11 +0200 Subject: [PATCH 25/77] Specifies dependency scope more precisely Signed-off-by: Frank Schnicke --- pom.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pom.xml b/pom.xml index 5af397b2..99ad9848 100644 --- a/pom.xml +++ b/pom.xml @@ -170,8 +170,16 @@ ch.qos.logback logback-classic 1.4.7 + runtime + + org.slf4j + slf4j-api + 2.0.7 + + + junit @@ -269,6 +277,7 @@ org.codehaus.janino janino 3.1.9 + runtime From 14c3b9f0e538b56751c7b67f0b03e8eeca62a2c3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 31 May 2023 08:02:16 +0000 Subject: [PATCH 26/77] Bump jackson-databind from 2.15.1 to 2.15.2 Bumps [jackson-databind](https://github.com/FasterXML/jackson) from 2.15.1 to 2.15.2. - [Commits](https://github.com/FasterXML/jackson/commits) --- updated-dependencies: - dependency-name: com.fasterxml.jackson.core:jackson-databind dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 99ad9848..3712da8a 100644 --- a/pom.xml +++ b/pom.xml @@ -348,7 +348,7 @@ com.fasterxml.jackson.core jackson-databind - 2.15.1 + 2.15.2 From 4c298420c54b2e89e621387c26a9ae76ca49a12f Mon Sep 17 00:00:00 2001 From: Rene Fischer <33397768+FischerRene@users.noreply.github.com> Date: Thu, 1 Jun 2023 11:20:06 +0200 Subject: [PATCH 27/77] Update MongoDB to use StorageAPI (#279) --- .../extensions/internal/storage/BaSyxStorageAPI.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/org/eclipse/basyx/extensions/internal/storage/BaSyxStorageAPI.java b/src/main/java/org/eclipse/basyx/extensions/internal/storage/BaSyxStorageAPI.java index 54a52e3e..589c3e64 100644 --- a/src/main/java/org/eclipse/basyx/extensions/internal/storage/BaSyxStorageAPI.java +++ b/src/main/java/org/eclipse/basyx/extensions/internal/storage/BaSyxStorageAPI.java @@ -24,6 +24,8 @@ ******************************************************************************/ package org.eclipse.basyx.extensions.internal.storage; +import java.io.File; +import java.io.InputStream; import java.util.HashMap; import java.util.Map; @@ -98,6 +100,12 @@ protected String getKey(T obj) { */ public abstract T rawRetrieve(String key); + public abstract File getFile(String key, String parentKey, Map objMap); + + public abstract String writeFile(String key, String parentKey, InputStream fileStream, ISubmodelElement submodelElement); + + public abstract void deleteFile(Submodel submodel, String idShort); + /** * Returns a Object that was originally retrieved from the abstract method * {@code rawRetrieve}. If the object to be returned is a submodel type, it will @@ -183,4 +191,5 @@ protected boolean isAASDescriptorType(Class type) { protected boolean isBaSyxType(Class type) { return (isShellType(type) || isSubmodelType(type) || isAASDescriptorType(type)); } + } From cf70ccd46d89f597a86dd18e25a11085b316a660 Mon Sep 17 00:00:00 2001 From: Mohammad Ghazanfar Ali Danish <62088117+mdanish98@users.noreply.github.com> Date: Thu, 1 Jun 2023 14:27:44 +0200 Subject: [PATCH 28/77] Fixes files not served issue (#299) Signed-off-by: Mohammad Ghazanfar Ali Danish --- .../http/server/BaSyxChildContext.java | 63 +++++++++++++++++++ .../protocol/http/server/BaSyxContext.java | 20 ++++++ .../protocol/http/server/BaSyxHTTPServer.java | 22 ++++++- 3 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/eclipse/basyx/vab/protocol/http/server/BaSyxChildContext.java diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BaSyxChildContext.java b/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BaSyxChildContext.java new file mode 100644 index 00000000..30c41637 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BaSyxChildContext.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright (C) 2023 the Eclipse BaSyx Authors + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ + +package org.eclipse.basyx.vab.protocol.http.server; + +import javax.servlet.http.HttpServlet; + +import org.apache.catalina.Context; + +/** + * Child context definition + * + * @author danish + * + */ +public class BaSyxChildContext { + + private Context childContext; + private HttpServlet servlet; + private String servletMappingPattern; + + public BaSyxChildContext(Context childContext, HttpServlet servlet, String servletMappingPattern) { + super(); + this.childContext = childContext; + this.servlet = servlet; + this.servletMappingPattern = servletMappingPattern; + } + + public Context getChildContext() { + return childContext; + } + + public HttpServlet getServlet() { + return servlet; + } + + public String getServletMappingPattern() { + return servletMappingPattern; + } + +} diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BaSyxContext.java b/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BaSyxContext.java index 672bfc87..f820aa8a 100644 --- a/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BaSyxContext.java +++ b/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BaSyxContext.java @@ -24,8 +24,12 @@ ******************************************************************************/ package org.eclipse.basyx.vab.protocol.http.server; +import org.apache.catalina.Context; import org.springframework.lang.Nullable; + +import java.util.ArrayList; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import java.util.Optional; import javax.servlet.http.HttpServlet; @@ -89,6 +93,8 @@ public class BaSyxContext extends LinkedHashMap { private JwtBearerTokenAuthenticationConfiguration jwtBearerTokenAuthenticationConfiguration; private String accessControlAllowOrigin; + + private List baSyxChildContext = new ArrayList<>(); /** * Constructor with default port @@ -180,6 +186,19 @@ public BaSyxContext addServletParameter(String key, Map paramete // Return 'this' reference to enable chaining of operations return this; } + + /** + * Add childContext + */ + public BaSyxContext addChildContext(BaSyxChildContext childContext) { + this.baSyxChildContext.add(childContext); + + return this; + } + + public List getChildContexts() { + return this.baSyxChildContext; + } /** * Get servlet parameter @@ -274,4 +293,5 @@ public String getAccessControlAllowOrigin() { public void setAccessControlAllowOrigin(String accessControlAllowOrigin) { this.accessControlAllowOrigin = accessControlAllowOrigin; } + } diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BaSyxHTTPServer.java b/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BaSyxHTTPServer.java index 7a5f57ae..c99bfad9 100644 --- a/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BaSyxHTTPServer.java +++ b/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BaSyxHTTPServer.java @@ -25,6 +25,7 @@ package org.eclipse.basyx.vab.protocol.http.server; import java.io.File; +import java.util.AbstractMap; import java.util.ArrayList; import java.util.Collection; import java.util.EnumSet; @@ -32,6 +33,7 @@ import java.util.List; import java.util.Map.Entry; import java.util.UUID; +import java.util.function.Consumer; import javax.servlet.Filter; import javax.servlet.http.HttpServlet; @@ -124,7 +126,9 @@ public BaSyxHTTPServer(BaSyxContext context) { tomcat.getHost().setAppBase("."); configureHealthEndpoint(); - + + addChildContextsIfConfigured(context); + // Create servlet context // - Base path for resource files File docBase = new File(context.docBasePath); // System.getProperty("java.io.tmpdir")); @@ -138,6 +142,22 @@ public BaSyxHTTPServer(BaSyxContext context) { while (servletIterator.hasNext()) { addNewServletAndMappingToTomcatEnvironment(context, rootCtx, servletIterator.next()); } + + } + + private void addChildContextsIfConfigured(BaSyxContext context) { + List childContexts = context.getChildContexts(); + + if (childContexts.isEmpty()) + return; + + childContexts.stream().forEach(childContext -> addNewServletAndMappingToTomcatEnvironment(context, childContext.getChildContext(), new AbstractMap.SimpleEntry<>(childContext.getServletMappingPattern(), childContext.getServlet()))); + + childContexts.stream().forEach(addChildContextToTomcat()); + } + + private Consumer addChildContextToTomcat() { + return childContext -> tomcat.getHost().addChild(childContext.getChildContext()); } private void configureHealthEndpoint() { From 17bce7fb7fa7ee98df6cb8fbac19755b2a9db66d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Jun 2023 08:03:17 +0000 Subject: [PATCH 29/77] Bump maven-failsafe-plugin from 3.1.0 to 3.1.2 Bumps [maven-failsafe-plugin](https://github.com/apache/maven-surefire) from 3.1.0 to 3.1.2. - [Release notes](https://github.com/apache/maven-surefire/releases) - [Commits](https://github.com/apache/maven-surefire/compare/surefire-3.1.0...surefire-3.1.2) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-failsafe-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3712da8a..aed22faa 100644 --- a/pom.xml +++ b/pom.xml @@ -126,7 +126,7 @@ org.apache.maven.plugins maven-failsafe-plugin - 3.1.0 + 3.1.2 **/*HTTP* From 04d283d8600a9e2406a8fcb7e43a0a82b5037428 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Jun 2023 08:03:31 +0000 Subject: [PATCH 30/77] Bump maven-surefire-plugin from 3.1.0 to 3.1.2 Bumps [maven-surefire-plugin](https://github.com/apache/maven-surefire) from 3.1.0 to 3.1.2. - [Release notes](https://github.com/apache/maven-surefire/releases) - [Commits](https://github.com/apache/maven-surefire/compare/surefire-3.1.0...surefire-3.1.2) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-surefire-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3712da8a..e549ae48 100644 --- a/pom.xml +++ b/pom.xml @@ -110,7 +110,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.1.0 + 3.1.2 **/*HTTP* From 15030fa2c67e19f8504e4c31de5df8cb26b9885c Mon Sep 17 00:00:00 2001 From: Frank Schnicke <77283144+FrankSchnicke@users.noreply.github.com> Date: Wed, 7 Jun 2023 14:28:00 +0200 Subject: [PATCH 31/77] Development entity (#300) Signed-off-by: Frank Schnicke --- .../api/submodelelement/entity/IEntity.java | 15 ++++ .../ConnectedSubmodelElementFactory.java | 4 + .../entity/ConnectedEntity.java | 84 ++++++++++++++++++ .../TestConnectedSubmodelElementFactory.java | 11 ++- .../entity/TestConnectedEntity.java | 88 +++++++++++++++++++ 5 files changed, 201 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/entity/ConnectedEntity.java create mode 100644 src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/entity/TestConnectedEntity.java diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/entity/IEntity.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/entity/IEntity.java index 27ceb96d..3506b5bb 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/entity/IEntity.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/entity/IEntity.java @@ -28,6 +28,7 @@ import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.entity.EntityValue; /** * An entity is a submodel element that is used to model entities. @@ -58,4 +59,18 @@ public interface IEntity extends ISubmodelElement { * @return */ IReference getAsset(); + + @Override + default EntityValue getValue() { + throw new RuntimeException("Fallback to default implementation is not intended, please override!"); + } + + /** + * Sets value of the Entity using the passed EntityValue + * + * @param value + */ + default void setValue(EntityValue value) { + throw new RuntimeException("Fallback to default implementation is not intended, please override!"); + } } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElementFactory.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElementFactory.java index 8cd95ff8..02378003 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElementFactory.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElementFactory.java @@ -40,6 +40,7 @@ import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement.ConnectedProperty; import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement.ConnectedRange; import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement.ConnectedReferenceElement; +import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.entity.ConnectedEntity; import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.event.ConnectedBasicEvent; import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.operation.ConnectedOperation; import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.relationship.ConnectedAnnotatedRelationshipElement; @@ -53,6 +54,7 @@ import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.ReferenceElement; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range.Range; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.entity.Entity; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.event.BasicEvent; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.AnnotatedRelationshipElement; @@ -159,6 +161,8 @@ public static ISubmodelElement getConnectedSubmodelElement(VABElementProxy rootP return new ConnectedBasicEvent(proxy); } else if (Capability.isCapability(mapContent)) { return new ConnectedCapability(proxy); + } else if (Entity.isEntity(mapContent)) { + return new ConnectedEntity(proxy); } else { return null; } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/entity/ConnectedEntity.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/entity/ConnectedEntity.java new file mode 100644 index 00000000..b40e7cd9 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/entity/ConnectedEntity.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (C) 2023 the Eclipse BaSyx Authors + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ + + +package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.entity; + +import java.util.Collection; +import java.util.Map; + +import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; +import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement; +import org.eclipse.basyx.submodel.metamodel.api.submodelelement.entity.EntityType; +import org.eclipse.basyx.submodel.metamodel.api.submodelelement.entity.IEntity; +import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.ConnectedSubmodelElement; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.entity.Entity; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.entity.EntityValue; +import org.eclipse.basyx.vab.modelprovider.VABElementProxy; + +/** + * Connected implementation of IEntity + * + * @author schnicke + * + */ +public class ConnectedEntity extends ConnectedSubmodelElement implements IEntity { + + /** + * Constructs an ConnectedEntity representing the data pointed to by the + * elementProxy + * + * @param elementProxy + */ + public ConnectedEntity(VABElementProxy elementProxy) { + super(elementProxy); + } + + @Override + public Collection getStatements() { + return getValue().getStatement(); + } + + @Override + public EntityType getEntityType() { + return Entity.createAsFacade(getElem()).getEntityType(); + } + + @Override + public IReference getAsset() { + return getValue().getAsset(); + } + + @Override + public void setValue(EntityValue value) { + super.setValue(value); + } + + @SuppressWarnings("unchecked") + @Override + public EntityValue getValue() { + return EntityValue.createAsFacade((Map) super.getValue()); + } +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/TestConnectedSubmodelElementFactory.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/TestConnectedSubmodelElementFactory.java index 42f4c131..561d5d44 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/TestConnectedSubmodelElementFactory.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/TestConnectedSubmodelElementFactory.java @@ -32,6 +32,7 @@ import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement; import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty; +import org.eclipse.basyx.submodel.metamodel.api.submodelelement.entity.EntityType; import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation; import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.ConnectedCapability; import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.ConnectedSubmodelElementCollection; @@ -42,6 +43,7 @@ import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement.ConnectedProperty; import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement.ConnectedRange; import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement.ConnectedReferenceElement; +import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.entity.ConnectedEntity; import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.event.ConnectedBasicEvent; import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.operation.ConnectedOperation; import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.relationship.ConnectedRelationshipElement; @@ -55,6 +57,7 @@ import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range.Range; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.entity.Entity; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.event.BasicEvent; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElement; @@ -75,6 +78,7 @@ */ public class TestConnectedSubmodelElementFactory { + private static final int SUBMODELEELEMENT_COUNT = 12; private static final String PROPERTY_ID = "PropertyId"; private static final String BLOB_ID = "BlobId"; private static final String FILE_ID = "FileId"; @@ -86,6 +90,7 @@ public class TestConnectedSubmodelElementFactory { private static final String OPERATION_ID = "OperationId"; private static final String RELELEMENT_ID = "RelElementId"; private static final String SMELEMCOLLECTION_ID = "SmElemCollectionId"; + private static final String ENTITY_ID = "EntityId"; VABElementProxy proxy; @@ -180,6 +185,9 @@ private Map buildSubmodelElements() { SubmodelElementCollection smElemCollection = new SubmodelElementCollection(); smElemCollection.setIdShort(SMELEMCOLLECTION_ID); ret.put(SMELEMCOLLECTION_ID, smElemCollection); + + Entity entity = new Entity(ENTITY_ID, EntityType.COMANAGEDENTITY); + ret.put(ENTITY_ID, entity); return ret; } @@ -213,7 +221,7 @@ public void testGetOperations() { public void testGetSubmodelElements() { Map submodelElements = ConnectedSubmodelElementFactory.getConnectedSubmodelElements(proxy, Submodel.SUBMODELELEMENT, Submodel.SUBMODELELEMENT); - assertEquals(11, submodelElements.size()); + assertEquals(SUBMODELEELEMENT_COUNT, submodelElements.size()); assertTrue(submodelElements.get(PROPERTY_ID) instanceof ConnectedProperty); assertTrue(submodelElements.get(BLOB_ID) instanceof ConnectedBlob); assertTrue(submodelElements.get(FILE_ID) instanceof ConnectedFile); @@ -225,6 +233,7 @@ public void testGetSubmodelElements() { assertTrue(submodelElements.get(CAPABILITY_ID) instanceof ConnectedCapability); assertTrue(submodelElements.get(RELELEMENT_ID) instanceof ConnectedRelationshipElement); assertTrue(submodelElements.get(SMELEMCOLLECTION_ID) instanceof ConnectedSubmodelElementCollection); + assertTrue(submodelElements.get(ENTITY_ID) instanceof ConnectedEntity); } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/entity/TestConnectedEntity.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/entity/TestConnectedEntity.java new file mode 100644 index 00000000..8fe070d4 --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/entity/TestConnectedEntity.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (C) 2023 the Eclipse BaSyx Authors + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ + + +package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected.submodelelement.entity; + +import static org.junit.Assert.assertEquals; + +import java.util.Collections; + +import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType; +import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements; +import org.eclipse.basyx.submodel.metamodel.api.submodelelement.entity.EntityType; +import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.entity.ConnectedEntity; +import org.eclipse.basyx.submodel.metamodel.map.reference.Key; +import org.eclipse.basyx.submodel.metamodel.map.reference.Reference; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.entity.Entity; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.entity.EntityValue; +import org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected.submodelelement.SubmodelElementTestHelper; +import org.eclipse.basyx.vab.modelprovider.VABElementProxy; +import org.junit.Before; +import org.junit.Test; + +/** + * Tests if a ConnectedEntity can be created and used correctly + * + * @author schnicke + * + */ +public class TestConnectedEntity { + private ConnectedEntity connectedEntity; + private Entity entity; + + @Before + public void build() { + entity = new Entity("entityIdShort", EntityType.COMANAGEDENTITY); + + VABElementProxy elementProxy = SubmodelElementTestHelper.createElementProxy(entity); + + connectedEntity = new ConnectedEntity(elementProxy); + } + + @Test + public void testGetValue() { + assertEquals(entity.getValue(), connectedEntity.getValue()); + } + + + @Test + public void testSetValue() { + EntityValue value = createExpectedEntityValue(); + + connectedEntity.setValue(value); + + assertEquals(value, connectedEntity.getValue()); + } + + private EntityValue createExpectedEntityValue() { + Property property = new Property("prop", 5); + Reference reference = new Reference(new Key(KeyElements.GLOBALREFERENCE, false, "test", IdentifierType.CUSTOM)); + + return new EntityValue(Collections.singleton(property), reference); + } + +} From 5a44955949d9168293906eb90c0ea36f7bae49f8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 8 Jun 2023 08:01:46 +0000 Subject: [PATCH 32/77] Bump commons-io from 2.12.0 to 2.13.0 Bumps commons-io from 2.12.0 to 2.13.0. --- updated-dependencies: - dependency-name: commons-io:commons-io dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ff9b6c7a..2a921c11 100644 --- a/pom.xml +++ b/pom.xml @@ -298,7 +298,7 @@ commons-io commons-io - 2.12.0 + 2.13.0 From ef25aa1cd345199dfb4dfd924228ad35c3b63413 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 9 Jun 2023 08:01:47 +0000 Subject: [PATCH 33/77] Bump tomcat-catalina from 9.0.75 to 9.0.76 Bumps tomcat-catalina from 9.0.75 to 9.0.76. --- updated-dependencies: - dependency-name: org.apache.tomcat:tomcat-catalina dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ff9b6c7a..200775a4 100644 --- a/pom.xml +++ b/pom.xml @@ -256,7 +256,7 @@ org.apache.tomcat tomcat-catalina - 9.0.75 + 9.0.76 From 012139030689b8388b38e1edf42478db20710e9c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Jun 2023 08:05:28 +0000 Subject: [PATCH 34/77] Bump logback-classic from 1.4.7 to 1.4.8 Bumps [logback-classic](https://github.com/qos-ch/logback) from 1.4.7 to 1.4.8. - [Commits](https://github.com/qos-ch/logback/compare/v_1.4.7...v_1.4.8) --- updated-dependencies: - dependency-name: ch.qos.logback:logback-classic dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ff9b6c7a..d6ad7611 100644 --- a/pom.xml +++ b/pom.xml @@ -169,7 +169,7 @@ ch.qos.logback logback-classic - 1.4.7 + 1.4.8 runtime From 52d777db5fa342b5c246188a50ea1074f8cbd8e2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Jun 2023 08:06:41 +0000 Subject: [PATCH 35/77] Bump mockito-core from 5.3.1 to 5.4.0 Bumps [mockito-core](https://github.com/mockito/mockito) from 5.3.1 to 5.4.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v5.3.1...v5.4.0) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ff9b6c7a..8cd4ecd7 100644 --- a/pom.xml +++ b/pom.xml @@ -192,7 +192,7 @@ org.mockito mockito-core - 5.3.1 + 5.4.0 test From d81f6250b739c230bcb7bbc0f283791529514ea7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Jun 2023 08:01:55 +0000 Subject: [PATCH 36/77] Bump spring-security-bom from 5.8.3 to 5.8.4 Bumps [spring-security-bom](https://github.com/spring-projects/spring-security) from 5.8.3 to 5.8.4. - [Release notes](https://github.com/spring-projects/spring-security/releases) - [Changelog](https://github.com/spring-projects/spring-security/blob/main/RELEASE.adoc) - [Commits](https://github.com/spring-projects/spring-security/compare/5.8.3...5.8.4) --- updated-dependencies: - dependency-name: org.springframework.security:spring-security-bom dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index bec2f5c9..cd4d2186 100644 --- a/pom.xml +++ b/pom.xml @@ -46,7 +46,7 @@ UTF-8 UTF-8 - 5.8.3 + 5.8.4 From 265bad12dac2d0e1e25da52128868966d16f930e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Jun 2023 08:01:14 +0000 Subject: [PATCH 37/77] Bump sdk-server from 0.6.9 to 0.6.10 Bumps sdk-server from 0.6.9 to 0.6.10. --- updated-dependencies: - dependency-name: org.eclipse.milo:sdk-server dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index bec2f5c9..591d7056 100644 --- a/pom.xml +++ b/pom.xml @@ -221,7 +221,7 @@ org.eclipse.milo sdk-server - 0.6.9 + 0.6.10 From b3ae39066fa6e8045401a1324719146ddcf2d473 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Jun 2023 08:01:16 +0000 Subject: [PATCH 38/77] Bump sdk-client from 0.6.9 to 0.6.10 Bumps sdk-client from 0.6.9 to 0.6.10. --- updated-dependencies: - dependency-name: org.eclipse.milo:sdk-client dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index bec2f5c9..029f3bf2 100644 --- a/pom.xml +++ b/pom.xml @@ -214,7 +214,7 @@ org.eclipse.milo sdk-client - 0.6.9 + 0.6.10 From af27bdee895123818d2a07393c2946e3aa9bd5b1 Mon Sep 17 00:00:00 2001 From: Mohammad Ghazanfar Ali Danish <62088117+mdanish98@users.noreply.github.com> Date: Wed, 21 Jun 2023 14:27:22 +0200 Subject: [PATCH 39/77] Updates poi-ooxml to latest version (v5.2.3) (#305) Signed-off-by: Mohammad Ghazanfar Ali Danish --- pom.xml | 10 +- .../aasx/AASXToMetamodelConverter.java | 96 ++++++++++++------- .../aasxupload/AASAggregatorAASXUpload.java | 3 +- ...TestAASXToMetamodelConverterFromBaSyx.java | 6 ++ .../TestAASXToMetamodelConverterFromFile.java | 6 ++ .../aasx/TestMetamodelToAASXConverter.java | 15 ++- 6 files changed, 89 insertions(+), 47 deletions(-) diff --git a/pom.xml b/pom.xml index bec2f5c9..ede25936 100644 --- a/pom.xml +++ b/pom.xml @@ -263,13 +263,13 @@ org.apache.poi poi-ooxml - 4.1.2 + 5.2.3 - + - org.apache.commons - commons-compress - 1.23.0 + org.apache.commons + commons-compress + 1.23.0 diff --git a/src/main/java/org/eclipse/basyx/aas/factory/aasx/AASXToMetamodelConverter.java b/src/main/java/org/eclipse/basyx/aas/factory/aasx/AASXToMetamodelConverter.java index 59d96860..9326f39c 100644 --- a/src/main/java/org/eclipse/basyx/aas/factory/aasx/AASXToMetamodelConverter.java +++ b/src/main/java/org/eclipse/basyx/aas/factory/aasx/AASXToMetamodelConverter.java @@ -70,10 +70,24 @@ * * The aas provides the references to the submodels and assets * + *

+ * The AASXToMetamodelConverter implements the AutoCloseable interface, indicating that it manages + * resources that need to be released after usage. To ensure proper resource cleanup, + * it is recommended to use one of the following approaches:
+ * + * 1. Try-with-resources
+ * 2. Finally block
+ * 3. Explicitly calling close {@link AASXToMetamodelConverter#close()} + *
+ * Please choose the appropriate method based on your specific use case to ensure + * proper resource management and cleanup. + * + *

+ * * @author zhangzai, conradi, danish * */ -public class AASXToMetamodelConverter { +public class AASXToMetamodelConverter implements AutoCloseable { private static final String XML_TYPE = "http://www.admin-shell.io/aasx/relationships/aas-spec"; private static final String AASX_ORIGIN = "/aasx/aasx-origin"; @@ -91,33 +105,27 @@ public class AASXToMetamodelConverter { public AASXToMetamodelConverter(String path) { this.aasxPath = path; + loadAASX(); } public AASXToMetamodelConverter(InputStream stream) { this.aasxInputStream = stream; + loadAASX(); } public AasEnv retrieveAasEnv() throws ParserConfigurationException, SAXException, IOException, InvalidFormatException { if (aasEnv != null) { return aasEnv; } - - loadAASX(); - + String xmlContent = getXMLResourceString(aasxRoot); XMLToMetamodelConverter converter = new XMLToMetamodelConverter(xmlContent); - closeOPCPackage(); + return converter.parseAasEnv(); } - public InputStream retrieveThumbnail() throws IOException, InvalidFormatException { - loadAASX(); - - InputStream thumbnailStream = getThumbnailStream(aasxRoot); - - closeOPCPackage(); - - return thumbnailStream; + public InputStream retrieveThumbnail() throws IOException { + return getThumbnailStream(aasxRoot); } @SuppressWarnings("unchecked") @@ -128,38 +136,44 @@ public Set retrieveAASBundles() throws IOException, Par return (Set) bundles; } - loadAASX(); - AasEnv localAasEnv = retrieveAasEnv(); bundles = new AASBundleFactory().create(localAasEnv.getAssetAdministrationShells(), localAasEnv.getSubmodels(), localAasEnv.getAssets()); - closeOPCPackage(); - return (Set) bundles; } public InputStream retrieveFileInputStream(String path) throws InvalidFormatException, IOException { - loadAASX(); PackagePart filePart = aasxRoot.getPart(PackagingURIHelper.createPartName(path)); - closeOPCPackage(); + return filePart.getInputStream(); } - private void loadAASX() throws IOException, InvalidFormatException { - if (aasxInputStream == null) { - aasxInputStream = FileLoaderHelper.getInputStream(aasxPath); + /** + * Closes the resources associated with the AASXToMetamodelConverter instance. + * After calling this method, the instance becomes unusable and subsequent method + * invocations may result in undefined behavior. + * + */ + @Override + public void close() { + try { + aasxRoot.close(); + } catch (IOException e) { + e.printStackTrace(); + logger.error("Error clearing the resource OPCPackage"); } - - if (aasxRoot == null) { - aasxRoot = OPCPackage.open(aasxInputStream); + + if (aasxInputStream != null) { + try { + aasxInputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + logger.error("Error clearing the resource InputStream"); + } } } - private void closeOPCPackage() throws IOException { - aasxRoot.close(); - } - /** * Return the Content of the XML file in the aasx-package as String * @@ -294,14 +308,12 @@ public void unzipRelatedFiles() throws IOException, ParserConfigurationException * @throws URISyntaxException */ public void unzipRelatedFiles(Path pathToDirectory) throws InvalidFormatException, IOException, ParserConfigurationException, SAXException, URISyntaxException { - loadAASX(); - List files = parseReferencedFilePathsFromAASX(); + for (String filePath: files) { unzipFile(filePath, aasxRoot, pathToDirectory); } - closeOPCPackage(); } /** @@ -371,4 +383,24 @@ private void unzipFile(String filePath, OPCPackage aasxRoot, Path pathToDirector InputStream stream = part.getInputStream(); FileUtils.copyInputStreamToFile(stream, new File(targetPath)); } + + private void loadAASX() { + if (aasxInputStream == null) { + try { + aasxInputStream = FileLoaderHelper.getInputStream(aasxPath); + } catch (IOException e) { + e.printStackTrace(); + throw new RuntimeException("IO Exception occurred while getting input stream from path " + aasxPath); + } + } + + if (aasxRoot == null) { + try { + aasxRoot = OPCPackage.open(aasxInputStream); + } catch (InvalidFormatException | IOException e) { + e.printStackTrace(); + throw new RuntimeException("Exception occurred while opening the OPC Package " + aasxPath); + } + } + } } diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/aasxupload/AASAggregatorAASXUpload.java b/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/aasxupload/AASAggregatorAASXUpload.java index 85bb71f6..b371b883 100644 --- a/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/aasxupload/AASAggregatorAASXUpload.java +++ b/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/aasxupload/AASAggregatorAASXUpload.java @@ -70,8 +70,7 @@ public AASAggregatorAASXUpload(IAASAggregator aggregator) { @Override public void uploadAASX(InputStream aasxStream) { - try { - AASXToMetamodelConverter converter = new AASXToMetamodelConverter(aasxStream); + try (AASXToMetamodelConverter converter = new AASXToMetamodelConverter(aasxStream)) { Set bundles = converter.retrieveAASBundles(); AASBundleHelper.integrate(this, bundles); uploadFilesInAASX(converter); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestAASXToMetamodelConverterFromBaSyx.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestAASXToMetamodelConverterFromBaSyx.java index 9c3e37bf..0310e285 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestAASXToMetamodelConverterFromBaSyx.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestAASXToMetamodelConverterFromBaSyx.java @@ -71,6 +71,7 @@ import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation; +import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.Test; @@ -142,6 +143,11 @@ public void setup() throws IOException, TransformerException, ParserConfiguratio packageManager = new AASXToMetamodelConverter(CREATED_AASX_FILE_PATH); } + @After + public void close() { + packageManager.close(); + } + @Test public void thumbnailInPackage() throws InvalidFormatException, IOException, ParserConfigurationException, SAXException { assertTrue(IOUtils.contentEquals(new ByteArrayInputStream(THUMBNAIL), packageManager.retrieveThumbnail())); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestAASXToMetamodelConverterFromFile.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestAASXToMetamodelConverterFromFile.java index 9fc470ca..f22d8e05 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestAASXToMetamodelConverterFromFile.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestAASXToMetamodelConverterFromFile.java @@ -50,6 +50,7 @@ import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType; +import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.xml.sax.SAXException; @@ -141,6 +142,11 @@ public static void setup() throws InvalidFormatException, IOException, ParserCon specificSubmodel = specificSubmodelOptional.get(); specificSubmodelElements = specificSubmodel.getSubmodelElements(); } + + @AfterClass + public static void tearDown() { + packageConverter.close(); + } /** * Test the converted AAS with expected information. diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestMetamodelToAASXConverter.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestMetamodelToAASXConverter.java index 72db0a7b..c1f602f8 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestMetamodelToAASXConverter.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestMetamodelToAASXConverter.java @@ -313,22 +313,21 @@ private void assertIsXML(ZipInputStream in) throws IOException { } private Set deserializeAASX(ByteArrayOutputStream byteStream) throws IOException, InvalidFormatException, ParserConfigurationException, SAXException { - AASXToMetamodelConverter aasxDeserializer = getDeserializedAASX(byteStream); - - return aasxDeserializer.retrieveAASBundles(); + try (AASXToMetamodelConverter aasxDeserializer = getDeserializedAASX(byteStream)) { + return aasxDeserializer.retrieveAASBundles(); + } } private InputStream getThumbnailStreamFromAASX(ByteArrayOutputStream byteStream) throws IOException, InvalidFormatException, ParserConfigurationException, SAXException { - AASXToMetamodelConverter aasxDeserializer = getDeserializedAASX(byteStream); - - return aasxDeserializer.retrieveThumbnail(); + try (AASXToMetamodelConverter aasxDeserializer = getDeserializedAASX(byteStream)) { + return aasxDeserializer.retrieveThumbnail(); + } } private AASXToMetamodelConverter getDeserializedAASX(ByteArrayOutputStream byteStream) { InputStream in = new ByteArrayInputStream(byteStream.toByteArray()); - AASXToMetamodelConverter aasxDeserializer = new AASXToMetamodelConverter(in); - return aasxDeserializer; + return new AASXToMetamodelConverter(in); } private void assertFilepathsAreCorrect(Set aasBundles) { From e1a6ea8e90311a3ee3ed1df68f219bddea582fee Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Jun 2023 08:05:29 +0000 Subject: [PATCH 40/77] Bump jersey-client from 2.39.1 to 2.40 Bumps jersey-client from 2.39.1 to 2.40. --- updated-dependencies: - dependency-name: org.glassfish.jersey.core:jersey-client dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ede25936..9c9dcab1 100644 --- a/pom.xml +++ b/pom.xml @@ -242,7 +242,7 @@ org.glassfish.jersey.core jersey-client - 2.39.1 + 2.40 From 6b128128770a412f3a7ec2b1b5e246dcce8508ab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Jun 2023 08:05:38 +0000 Subject: [PATCH 41/77] Bump jersey-hk2 from 2.39.1 to 2.40 Bumps jersey-hk2 from 2.39.1 to 2.40. --- updated-dependencies: - dependency-name: org.glassfish.jersey.inject:jersey-hk2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ede25936..7a98ff44 100644 --- a/pom.xml +++ b/pom.xml @@ -249,7 +249,7 @@ org.glassfish.jersey.inject jersey-hk2 - 2.39.1 + 2.40 From 99855bd3f0cd94f69ff507eea3b21970411bb9d2 Mon Sep 17 00:00:00 2001 From: FlorianWege-IESE <105274868+FlorianWege-IESE@users.noreply.github.com> Date: Tue, 27 Jun 2023 13:28:35 +0200 Subject: [PATCH 42/77] Authorization submodel semantic id + new submodel API methods (#262) Signed-off-by: FlorianWege-IESE Co-authored-by: Daespen --- .../SimpleRbacAASAggregatorAuthorizer.java | 10 +- .../internal/SimpleRbacAASAPIAuthorizer.java | 6 +- .../internal/AuthorizedTaggedDirectory.java | 17 +- ...tedAuthorityTaggedDirectoryAuthorizer.java | 5 +- .../internal/ITaggedDirectoryAuthorizer.java | 11 +- .../SimpleRbacTaggedDirectoryAuthorizer.java | 13 +- .../internal/AuthorizedAASRegistry.java | 52 ++++- ...GrantedAuthorityAASRegistryAuthorizer.java | 9 +- .../internal/IAASRegistryAuthorizer.java | 19 +- .../SimpleRbacAASRegistryAuthorizer.java | 29 ++- .../BaSyxObjectTargetInformation.java | 72 ++++++- .../internal/KeycloakRoleAuthenticator.java | 48 ++++- .../authorization/internal/RbacRule.java | 18 +- .../authorization/internal/RbacRuleDTO.java | 8 +- .../internal/RbacRuleSetDeserializer.java | 75 ++++++- .../internal/SimpleRbacInhibitException.java | 2 +- .../AuthorizedSubmodelAggregator.java | 62 +++++- ...AuthoritySubmodelAggregatorAuthorizer.java | 19 +- .../ISubmodelAggregatorAuthorizer.java | 41 ++-- ...impleRbacSubmodelAggregatorAuthorizer.java | 85 +++----- .../internal/AuthorizedSubmodelAPI.java | 85 ++++++-- ...GrantedAuthoritySubmodelAPIAuthorizer.java | 23 +-- .../internal/ISubmodelAPIAuthorizer.java | 52 +++-- .../SimpleRbacSubmodelAPIAuthorizer.java | 69 +++---- ...TestSimpleRbacAuthorizedAASAggregator.java | 8 +- .../TestSimpleRbacAuthorizedAASAPI.java | 6 +- ...stSimpleRbacAuthorizedTaggedDirectory.java | 6 +- ...GrantedAuthorityAuthorizedAASRegistry.java | 3 + .../TestSimpleRbacAuthorizedAASRegistry.java | 12 +- .../TestPredefinedSetRbacRuleChecker.java | 184 ++++++++++++++---- .../internal/TestRbacRuleSetDeserializer.java | 22 ++- ...AuthorityAuthorizedSubmodelAggregator.java | 22 +++ ...impleRbacAuthorizedSubmodelAggregator.java | 8 +- ...GrantedAuthorityAuthorizedSubmodelAPI.java | 45 +++++ .../TestSimpleRbacAuthorizedSubmodelAPI.java | 54 ++++- .../authorization/internal/rbac_rules.json | 12 ++ .../internal/rbac_rules_multiple_actions.json | 21 ++ 37 files changed, 915 insertions(+), 318 deletions(-) create mode 100644 src/test/resources/authorization/internal/rbac_rules_multiple_actions.json diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/authorization/internal/SimpleRbacAASAggregatorAuthorizer.java b/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/authorization/internal/SimpleRbacAASAggregatorAuthorizer.java index fc29531f..90294356 100644 --- a/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/authorization/internal/SimpleRbacAASAggregatorAuthorizer.java +++ b/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/authorization/internal/SimpleRbacAASAggregatorAuthorizer.java @@ -59,14 +59,14 @@ public Collection authorizeGetAASList(final SubjectIn @Override public IAssetAdministrationShell authorizeGetAAS(final SubjectInformationType subjectInformation, final IIdentifier aasId, final Supplier aasSupplier) throws InhibitException { - SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, AASAggregatorScopes.READ_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), null, null)); + SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, AASAggregatorScopes.READ_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), null, null, null)); return aasSupplier.get(); } @Override public IModelProvider authorizeGetAASProvider(final SubjectInformationType subjectInformation, final IIdentifier aasId, final Supplier modelProviderSupplier) throws InhibitException { - SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, AASAggregatorScopes.READ_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), null, null)); + SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, AASAggregatorScopes.READ_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), null, null, null)); return modelProviderSupplier.get(); } @@ -75,18 +75,18 @@ public IModelProvider authorizeGetAASProvider(final SubjectInformationType subje public void authorizeCreateAAS(final SubjectInformationType subjectInformation, final AssetAdministrationShell aas) throws InhibitException { final IIdentifier aasId = aas.getIdentification(); - SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, AASAggregatorScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), null, null)); + SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, AASAggregatorScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), null, null, null)); } @Override public void authorizeUpdateAAS(final SubjectInformationType subjectInformation, final AssetAdministrationShell aas) throws InhibitException { final IIdentifier aasId = aas.getIdentification(); - SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, AASAggregatorScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), null, null)); + SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, AASAggregatorScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), null, null, null)); } @Override public void authorizeDeleteAAS(final SubjectInformationType subjectInformation, final IIdentifier aasId) throws InhibitException { - SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, AASAggregatorScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), null, null)); + SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, AASAggregatorScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), null, null, null)); } } diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/api/authorization/internal/SimpleRbacAASAPIAuthorizer.java b/src/main/java/org/eclipse/basyx/extensions/aas/api/authorization/internal/SimpleRbacAASAPIAuthorizer.java index 70a15f3d..8549d707 100644 --- a/src/main/java/org/eclipse/basyx/extensions/aas/api/authorization/internal/SimpleRbacAASAPIAuthorizer.java +++ b/src/main/java/org/eclipse/basyx/extensions/aas/api/authorization/internal/SimpleRbacAASAPIAuthorizer.java @@ -55,7 +55,7 @@ public SimpleRbacAASAPIAuthorizer(final IRbacRuleChecker rbacRuleChecker, final public IAssetAdministrationShell authorizeGetAAS(final SubjectInformationType subjectInformation, final Supplier aasSupplier) throws InhibitException { final IIdentifier aasId = getAasId(aasSupplier); - SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, AASAPIScopes.READ_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), null, null)); + SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, AASAPIScopes.READ_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), null, null, null)); return aasSupplier.get(); } @@ -64,14 +64,14 @@ public IAssetAdministrationShell authorizeGetAAS(final SubjectInformationType su public void authorizeAddSubmodel(final SubjectInformationType subjectInformation, final Supplier aasSupplier, final IReference smId) throws InhibitException { final IIdentifier aasId = getAasId(aasSupplier); - SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, AASAPIScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getReferenceId(smId), null)); + SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, AASAPIScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getReferenceId(smId), null, null)); } @Override public void authorizeRemoveSubmodel(final SubjectInformationType subjectInformation, final Supplier aasSupplier, final String smIdShortPath) throws InhibitException { final IIdentifier aasId = getAasId(aasSupplier); - SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, AASAPIScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), smIdShortPath, null)); + SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, AASAPIScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), smIdShortPath, null, null)); } private IIdentifier getAasId(final Supplier aasSupplier) { diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/authorized/internal/AuthorizedTaggedDirectory.java b/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/authorized/internal/AuthorizedTaggedDirectory.java index 7a8b718e..f487668c 100644 --- a/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/authorized/internal/AuthorizedTaggedDirectory.java +++ b/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/authorized/internal/AuthorizedTaggedDirectory.java @@ -24,12 +24,6 @@ ******************************************************************************/ package org.eclipse.basyx.extensions.aas.directory.tagged.authorized.internal; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Objects; -import java.util.Set; -import java.util.stream.Collectors; import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn; import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor; import org.eclipse.basyx.extensions.aas.directory.tagged.api.IAASTaggedDirectory; @@ -41,9 +35,13 @@ import org.eclipse.basyx.extensions.shared.authorization.internal.InhibitException; import org.eclipse.basyx.extensions.shared.authorization.internal.NotAuthorizedException; import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; +import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.*; +import java.util.stream.Collectors; + /** * Implementation of {@link IAASTaggedDirectory} for restricting access to * sensitive data @@ -93,7 +91,8 @@ public void register(final TaggedAASDescriptor descriptor) { } protected void authorizeRegister(final TaggedAASDescriptor descriptor) throws InhibitException { - taggedDirectoryAuthorizer.authorizeRegister(subjectInformationProvider.get(), descriptor); + final IIdentifier aasId = getAasIdUnsecured(descriptor); + taggedDirectoryAuthorizer.authorizeRegister(subjectInformationProvider.get(), aasId, descriptor); } @Override @@ -186,7 +185,9 @@ public void registerSubmodel(final IIdentifier aasId, final TaggedSubmodelDescri } protected void authorizeRegisterSubmodel(final IIdentifier aasId, final TaggedSubmodelDescriptor smDescriptor) throws InhibitException { - taggedDirectoryAuthorizer.authorizeRegisterSubmodel(subjectInformationProvider.get(), aasId, smDescriptor); + final IIdentifier smId = getSmIdUnsecured(smDescriptor); + final IReference smSemanticId = getSmSemanticIdUnsecured(smDescriptor); + taggedDirectoryAuthorizer.authorizeRegisterSubmodel(subjectInformationProvider.get(), aasId, smId, smSemanticId, smDescriptor); } @Override diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/authorized/internal/GrantedAuthorityTaggedDirectoryAuthorizer.java b/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/authorized/internal/GrantedAuthorityTaggedDirectoryAuthorizer.java index e9d13b5d..4f1fb7b8 100644 --- a/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/authorized/internal/GrantedAuthorityTaggedDirectoryAuthorizer.java +++ b/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/authorized/internal/GrantedAuthorityTaggedDirectoryAuthorizer.java @@ -34,6 +34,7 @@ import org.eclipse.basyx.extensions.shared.authorization.internal.IGrantedAuthorityAuthenticator; import org.eclipse.basyx.extensions.shared.authorization.internal.InhibitException; import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; +import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; /** * Scope based implementation for {@link ITaggedDirectoryAuthorizer}. @@ -46,7 +47,7 @@ public GrantedAuthorityTaggedDirectoryAuthorizer(final IGrantedAuthorityAuthenti } @Override - public void authorizeRegister(final SubjectInformationType subjectInformation, final TaggedAASDescriptor taggedAASDescriptorSupplier) throws InhibitException { + public void authorizeRegister(final SubjectInformationType subjectInformation, final IIdentifier aasId, final TaggedAASDescriptor taggedAASDescriptorSupplier) throws InhibitException { GrantedAuthorityHelper.checkAuthority(grantedAuthorityAuthenticator, subjectInformation, AuthorizedAASRegistry.WRITE_AUTHORITY); } @@ -65,7 +66,7 @@ public Set authorizeLookupTags(final SubjectInformationType } @Override - public void authorizeRegisterSubmodel(final SubjectInformationType subjectInformation, final IIdentifier aasId, final TaggedSubmodelDescriptor taggedSubmodelDescriptor) throws InhibitException { + public void authorizeRegisterSubmodel(final SubjectInformationType subjectInformation, final IIdentifier aasId, final IIdentifier smId, final IReference smSemanticId, final TaggedSubmodelDescriptor taggedSubmodelDescriptor) throws InhibitException { GrantedAuthorityHelper.checkAuthority(grantedAuthorityAuthenticator, subjectInformation, AuthorizedAASRegistry.WRITE_AUTHORITY); } diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/authorized/internal/ITaggedDirectoryAuthorizer.java b/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/authorized/internal/ITaggedDirectoryAuthorizer.java index 94ede207..64f690e2 100644 --- a/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/authorized/internal/ITaggedDirectoryAuthorizer.java +++ b/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/authorized/internal/ITaggedDirectoryAuthorizer.java @@ -33,6 +33,7 @@ import org.eclipse.basyx.extensions.aas.registration.authorization.internal.IAASRegistryAuthorizer; import org.eclipse.basyx.extensions.shared.authorization.internal.InhibitException; import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; +import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; /** * Interface for the authorization points used in @@ -46,12 +47,14 @@ public interface ITaggedDirectoryAuthorizer extends IAAS * * @param subjectInformation * information of the requester. + * @param aasId + * id of the AAS. * @param taggedAASDescriptor * the AAS descriptor. * @throws InhibitException * if authorization failed */ - public void authorizeRegister(final SubjectInformationType subjectInformation, final TaggedAASDescriptor taggedAASDescriptor) throws InhibitException; + public void authorizeRegister(final SubjectInformationType subjectInformation, final IIdentifier aasId, final TaggedAASDescriptor taggedAASDescriptor) throws InhibitException; /** * Checks authorization for {@link IAASTaggedDirectory#lookupTag(String)}. @@ -91,12 +94,16 @@ public interface ITaggedDirectoryAuthorizer extends IAAS * information of the requester. * @param aasId * id of the AAS. + * @param smId + * id of the submodel. + * @param smSemanticId + * smenatic id of the submodel. * @param taggedSubmodelDescriptor * supplier for the submodel descriptor. * @throws InhibitException * if authorization failed */ - public void authorizeRegisterSubmodel(final SubjectInformationType subjectInformation, final IIdentifier aasId, final TaggedSubmodelDescriptor taggedSubmodelDescriptor) throws InhibitException; + public void authorizeRegisterSubmodel(final SubjectInformationType subjectInformation, final IIdentifier aasId, final IIdentifier smId, final IReference smSemanticId, final TaggedSubmodelDescriptor taggedSubmodelDescriptor) throws InhibitException; /** * Checks authorization for diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/authorized/internal/SimpleRbacTaggedDirectoryAuthorizer.java b/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/authorized/internal/SimpleRbacTaggedDirectoryAuthorizer.java index 10d6b310..610eb499 100644 --- a/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/authorized/internal/SimpleRbacTaggedDirectoryAuthorizer.java +++ b/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/authorized/internal/SimpleRbacTaggedDirectoryAuthorizer.java @@ -38,6 +38,7 @@ import org.eclipse.basyx.extensions.shared.authorization.internal.SimpleRbacHelper; import org.eclipse.basyx.extensions.shared.authorization.internal.TagTargetInformation; import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; +import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; /** * Simple role based implementation for {@link ITaggedDirectoryAuthorizer}. @@ -50,10 +51,8 @@ public SimpleRbacTaggedDirectoryAuthorizer(final IRbacRuleChecker rbacRuleChecke } @Override - public void authorizeRegister(final SubjectInformationType subjectInformation, final TaggedAASDescriptor taggedAASDescriptor) throws InhibitException { - final IIdentifier aasId = taggedAASDescriptor.getIdentifier(); - - SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, AASRegistryScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), null, null)); + public void authorizeRegister(final SubjectInformationType subjectInformation, final IIdentifier aasId, final TaggedAASDescriptor taggedAASDescriptor) throws InhibitException { + SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, AASRegistryScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), null, null, null)); } @Override @@ -69,10 +68,8 @@ public Set authorizeLookupTags(final SubjectInformationType } @Override - public void authorizeRegisterSubmodel(final SubjectInformationType subjectInformation, final IIdentifier aasId, final TaggedSubmodelDescriptor taggedSubmodelDescriptor) throws InhibitException { - final IIdentifier smId = taggedSubmodelDescriptor.getIdentifier(); - - SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, AASRegistryScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), null)); + public void authorizeRegisterSubmodel(final SubjectInformationType subjectInformation, final IIdentifier aasId, final IIdentifier smId, final IReference smSemanticId, final TaggedSubmodelDescriptor taggedSubmodelDescriptor) throws InhibitException { + SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, AASRegistryScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), IdHelper.getReferenceId(smSemanticId), null)); } @Override diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/registration/authorization/internal/AuthorizedAASRegistry.java b/src/main/java/org/eclipse/basyx/extensions/aas/registration/authorization/internal/AuthorizedAASRegistry.java index d92c6430..defa31c4 100644 --- a/src/main/java/org/eclipse/basyx/extensions/aas/registration/authorization/internal/AuthorizedAASRegistry.java +++ b/src/main/java/org/eclipse/basyx/extensions/aas/registration/authorization/internal/AuthorizedAASRegistry.java @@ -40,7 +40,9 @@ import org.eclipse.basyx.extensions.shared.authorization.internal.ISubjectInformationProvider; import org.eclipse.basyx.extensions.shared.authorization.internal.InhibitException; import org.eclipse.basyx.extensions.shared.authorization.internal.NotAuthorizedException; +import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; +import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; import org.eclipse.basyx.vab.exception.provider.ProviderException; import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException; import org.slf4j.Logger; @@ -90,7 +92,8 @@ public void register(final AASDescriptor deviceAASDescriptor) throws ProviderExc } protected void authorizeRegister(final AASDescriptor aasDescriptor) throws InhibitException { - aasRegistryAuthorizer.authorizeRegisterAas(subjectInformationProvider.get(), aasDescriptor); + final IIdentifier aasId = getAasIdUnsecured(aasDescriptor); + aasRegistryAuthorizer.authorizeRegisterAas(subjectInformationProvider.get(), aasId, aasDescriptor); } @Override @@ -109,7 +112,9 @@ public void register(final IIdentifier aasId, final SubmodelDescriptor smDescrip } protected void authorizeRegister(final IIdentifier aasId, final SubmodelDescriptor smDescriptor) throws InhibitException { - aasRegistryAuthorizer.authorizeRegisterSubmodel(subjectInformationProvider.get(), aasId, smDescriptor); + final IIdentifier smId = getSmIdUnsecured(smDescriptor); + final IReference smSemanticId = getSmSemanticIdUnsecured(smDescriptor); + aasRegistryAuthorizer.authorizeRegisterSubmodel(subjectInformationProvider.get(), aasId, smId, smSemanticId, smDescriptor); } @Override @@ -147,7 +152,9 @@ public void delete(final IIdentifier aasId, final IIdentifier smId) throws Provi } protected void authorizeDelete(final IIdentifier aasId, final IIdentifier smId) throws InhibitException { - aasRegistryAuthorizer.authorizeUnregisterSubmodel(subjectInformationProvider.get(), aasId, smId); + final SubmodelDescriptor smDescriptor = getSmDescriptorUnsecured(aasId, smId); + final IReference smSemanticId = getSmSemanticIdUnsecured(smDescriptor); + aasRegistryAuthorizer.authorizeUnregisterSubmodel(subjectInformationProvider.get(), aasId, smId, smSemanticId); } @Override @@ -278,6 +285,43 @@ public SubmodelDescriptor lookupSubmodel(final IIdentifier aasId, final IIdentif } protected SubmodelDescriptor authorizeLookupSubmodel(final IIdentifier aasId, final IIdentifier smId) throws InhibitException { - return aasRegistryAuthorizer.authorizeLookupSubmodel(subjectInformationProvider.get(), aasId, smId, () -> decoratedRegistry.lookupSubmodel(aasId, smId)); + final SubmodelDescriptor smDescriptor = getSmDescriptorUnsecured(aasId, smId); + final IReference smSemanticId = getSmSemanticIdUnsecured(smDescriptor); + return aasRegistryAuthorizer.authorizeLookupSubmodel(subjectInformationProvider.get(), aasId, smId, smSemanticId, () -> decoratedRegistry.lookupSubmodel(aasId, smId)); + } + + protected IIdentifier getAasIdUnsecured(final AASDescriptor aasDescriptor) throws ResourceNotFoundException { + if (aasDescriptor == null) { + return null; + } + + try (final ElevatedCodeAuthentication.ElevatedCodeAuthenticationAreaHandler ignored = ElevatedCodeAuthentication.enterElevatedCodeAuthenticationArea()) { + return aasDescriptor.getIdentifier(); + } + } + + protected SubmodelDescriptor getSmDescriptorUnsecured(final IIdentifier aasId, final IIdentifier smId) throws ResourceNotFoundException { + try (final ElevatedCodeAuthentication.ElevatedCodeAuthenticationAreaHandler ignored = ElevatedCodeAuthentication.enterElevatedCodeAuthenticationArea()) { + return decoratedRegistry.lookupSubmodel(aasId, smId); + } + } + + protected IIdentifier getSmIdUnsecured(final SubmodelDescriptor smDescriptor) throws ResourceNotFoundException { + if (smDescriptor == null) { + return null; + } + + try (final ElevatedCodeAuthentication.ElevatedCodeAuthenticationAreaHandler ignored = ElevatedCodeAuthentication.enterElevatedCodeAuthenticationArea()) { + return smDescriptor.getIdentifier(); + } + } + protected IReference getSmSemanticIdUnsecured(final SubmodelDescriptor smDescriptor) throws ResourceNotFoundException { + if (smDescriptor == null) { + return null; + } + + try (final ElevatedCodeAuthentication.ElevatedCodeAuthenticationAreaHandler ignored = ElevatedCodeAuthentication.enterElevatedCodeAuthenticationArea()) { + return smDescriptor.getSemanticId(); + } } } diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/registration/authorization/internal/GrantedAuthorityAASRegistryAuthorizer.java b/src/main/java/org/eclipse/basyx/extensions/aas/registration/authorization/internal/GrantedAuthorityAASRegistryAuthorizer.java index 2a5890fd..35f5b439 100644 --- a/src/main/java/org/eclipse/basyx/extensions/aas/registration/authorization/internal/GrantedAuthorityAASRegistryAuthorizer.java +++ b/src/main/java/org/eclipse/basyx/extensions/aas/registration/authorization/internal/GrantedAuthorityAASRegistryAuthorizer.java @@ -32,6 +32,7 @@ import org.eclipse.basyx.extensions.shared.authorization.internal.IGrantedAuthorityAuthenticator; import org.eclipse.basyx.extensions.shared.authorization.internal.InhibitException; import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; +import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; /** * Scope based implementation for {@link IAASRegistryAuthorizer}. @@ -46,12 +47,12 @@ public GrantedAuthorityAASRegistryAuthorizer(final IGrantedAuthorityAuthenticato } @Override - public void authorizeRegisterAas(final SubjectInformationType subjectInformation, final AASDescriptor aasDescriptor) throws InhibitException { + public void authorizeRegisterAas(final SubjectInformationType subjectInformation, final IIdentifier aasId, final AASDescriptor aasDescriptor) throws InhibitException { GrantedAuthorityHelper.checkAuthority(grantedAuthorityAuthenticator, subjectInformation, AuthorizedAASRegistry.WRITE_AUTHORITY); } @Override - public void authorizeRegisterSubmodel(final SubjectInformationType subjectInformation, final IIdentifier aasId, final SubmodelDescriptor smDescriptor) throws InhibitException { + public void authorizeRegisterSubmodel(final SubjectInformationType subjectInformation, final IIdentifier aasId, final IIdentifier smId, final IReference smSemanticId, final SubmodelDescriptor smDescriptor) throws InhibitException { GrantedAuthorityHelper.checkAuthority(grantedAuthorityAuthenticator, subjectInformation, AuthorizedAASRegistry.WRITE_AUTHORITY); } @@ -61,7 +62,7 @@ public void authorizeUnregisterAas(final SubjectInformationType subjectInformati } @Override - public void authorizeUnregisterSubmodel(final SubjectInformationType subjectInformation, final IIdentifier aasId, final IIdentifier smId) throws InhibitException { + public void authorizeUnregisterSubmodel(final SubjectInformationType subjectInformation, final IIdentifier aasId, final IIdentifier smId, final IReference smSemanticId) throws InhibitException { GrantedAuthorityHelper.checkAuthority(grantedAuthorityAuthenticator, subjectInformation, AuthorizedAASRegistry.WRITE_AUTHORITY); } @@ -87,7 +88,7 @@ public List authorizeLookupSubmodels(final SubjectInformatio } @Override - public SubmodelDescriptor authorizeLookupSubmodel(final SubjectInformationType subjectInformation, final IIdentifier aasId, final IIdentifier smId, final Supplier smSupplier) throws InhibitException { + public SubmodelDescriptor authorizeLookupSubmodel(final SubjectInformationType subjectInformation, final IIdentifier aasId, final IIdentifier smId, final IReference smSemanticId, final Supplier smSupplier) throws InhibitException { GrantedAuthorityHelper.checkAuthority(grantedAuthorityAuthenticator, subjectInformation, AuthorizedAASRegistry.READ_AUTHORITY); return smSupplier.get(); diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/registration/authorization/internal/IAASRegistryAuthorizer.java b/src/main/java/org/eclipse/basyx/extensions/aas/registration/authorization/internal/IAASRegistryAuthorizer.java index 251dbc1c..dbff4ff8 100644 --- a/src/main/java/org/eclipse/basyx/extensions/aas/registration/authorization/internal/IAASRegistryAuthorizer.java +++ b/src/main/java/org/eclipse/basyx/extensions/aas/registration/authorization/internal/IAASRegistryAuthorizer.java @@ -31,6 +31,7 @@ import org.eclipse.basyx.aas.registration.api.IAASRegistry; import org.eclipse.basyx.extensions.shared.authorization.internal.InhibitException; import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; +import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; /** * Interface for the authorization points used in {@link AuthorizedAASRegistry}. @@ -43,12 +44,14 @@ public interface IAASRegistryAuthorizer { * * @param subjectInformation * information of the requester. + * @param aasId + * id of the AAS. * @param aasDescriptor * descriptor of the AAS. * @throws InhibitException * if authorization failed */ - public void authorizeRegisterAas(final SubjectInformationType subjectInformation, final AASDescriptor aasDescriptor) throws InhibitException; + public void authorizeRegisterAas(final SubjectInformationType subjectInformation, final IIdentifier aasId, final AASDescriptor aasDescriptor) throws InhibitException; /** * Checks authorization for @@ -58,12 +61,16 @@ public interface IAASRegistryAuthorizer { * information of the requester. * @param aasId * id of the AAS. + * @param smId + * id of the submodel. + * @param smSemanticId + * semantic id of the submodel. * @param smDescriptor * the submodel descriptor. * @throws InhibitException * if authorization failed */ - public void authorizeRegisterSubmodel(final SubjectInformationType subjectInformation, final IIdentifier aasId, final SubmodelDescriptor smDescriptor) throws InhibitException; + public void authorizeRegisterSubmodel(final SubjectInformationType subjectInformation, final IIdentifier aasId, final IIdentifier smId, final IReference smSemanticId, final SubmodelDescriptor smDescriptor) throws InhibitException; /** * Checks authorization for {@link IAASRegistry#delete(IIdentifier)}. @@ -87,10 +94,12 @@ public interface IAASRegistryAuthorizer { * id of the AAS. * @param smId * id of the submodel. + * @param smSemanticId + * semantic id of the submodel. * @throws InhibitException * if authorization failed */ - public void authorizeUnregisterSubmodel(final SubjectInformationType subjectInformation, final IIdentifier aasId, final IIdentifier smId) throws InhibitException; + public void authorizeUnregisterSubmodel(final SubjectInformationType subjectInformation, final IIdentifier aasId, final IIdentifier smId, final IReference smSemanticId) throws InhibitException; /** * Checks authorization for {@link IAASRegistry#lookupAAS(IIdentifier)}. @@ -145,11 +154,13 @@ public interface IAASRegistryAuthorizer { * id of the AAS. * @param smId * id of the submodel. + * @param smSemanticId + * semantic id of the submodel. * @param smSupplier * supplier for the submodel. * @return the authorized submodel descriptor. * @throws InhibitException * if authorization failed */ - public SubmodelDescriptor authorizeLookupSubmodel(final SubjectInformationType subjectInformation, final IIdentifier aasId, final IIdentifier smId, final Supplier smSupplier) throws InhibitException; + public SubmodelDescriptor authorizeLookupSubmodel(final SubjectInformationType subjectInformation, final IIdentifier aasId, final IIdentifier smId, final IReference smSemanticId, final Supplier smSupplier) throws InhibitException; } \ No newline at end of file diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/registration/authorization/internal/SimpleRbacAASRegistryAuthorizer.java b/src/main/java/org/eclipse/basyx/extensions/aas/registration/authorization/internal/SimpleRbacAASRegistryAuthorizer.java index 7ffb6736..db3440a3 100644 --- a/src/main/java/org/eclipse/basyx/extensions/aas/registration/authorization/internal/SimpleRbacAASRegistryAuthorizer.java +++ b/src/main/java/org/eclipse/basyx/extensions/aas/registration/authorization/internal/SimpleRbacAASRegistryAuthorizer.java @@ -36,6 +36,7 @@ import org.eclipse.basyx.extensions.shared.authorization.internal.InhibitException; import org.eclipse.basyx.extensions.shared.authorization.internal.SimpleRbacHelper; import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; +import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; /** * Simple role based implementation for {@link IAASRegistryAuthorizer}. @@ -52,53 +53,49 @@ public SimpleRbacAASRegistryAuthorizer(final IRbacRuleChecker rbacRuleChecker, f } @Override - public void authorizeRegisterAas(final SubjectInformationType subjectInformation, final AASDescriptor aasDescriptor) throws InhibitException { - final IIdentifier aasId = aasDescriptor.getIdentifier(); - - SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, AASRegistryScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), null, null)); + public void authorizeRegisterAas(final SubjectInformationType subjectInformation, final IIdentifier aasId, final AASDescriptor aasDescriptor) throws InhibitException { + SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, AASRegistryScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), null, null, null)); } @Override - public void authorizeRegisterSubmodel(final SubjectInformationType subjectInformation, final IIdentifier aasId, final SubmodelDescriptor smDescriptor) throws InhibitException { - final IIdentifier smId = smDescriptor.getIdentifier(); - - SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, AASRegistryScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), null)); + public void authorizeRegisterSubmodel(final SubjectInformationType subjectInformation, final IIdentifier aasId, final IIdentifier smId, final IReference smSemanticId, final SubmodelDescriptor smDescriptor) throws InhibitException { + SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, AASRegistryScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), IdHelper.getReferenceId(smSemanticId), null)); } @Override public void authorizeUnregisterAas(final SubjectInformationType subjectInformation, final IIdentifier aasId) throws InhibitException { - SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, AASRegistryScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), null, null)); + SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, AASRegistryScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), null, null, null)); } @Override - public void authorizeUnregisterSubmodel(final SubjectInformationType subjectInformation, final IIdentifier aasId, final IIdentifier smId) throws InhibitException { - SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, AASRegistryScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), null)); + public void authorizeUnregisterSubmodel(final SubjectInformationType subjectInformation, final IIdentifier aasId, final IIdentifier smId, final IReference smSemanticId) throws InhibitException { + SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, AASRegistryScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), IdHelper.getReferenceId(smSemanticId), null)); } @Override public AASDescriptor authorizeLookupAAS(final SubjectInformationType subjectInformation, final IIdentifier aasId, final Supplier aasSupplier) throws InhibitException { - SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, AASRegistryScopes.READ_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), null, null)); + SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, AASRegistryScopes.READ_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), null, null, null)); return aasSupplier.get(); } @Override public List authorizeLookupAll(final SubjectInformationType subjectInformation, final Supplier> aasDescriptorsSupplier) throws InhibitException { - SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, AASRegistryScopes.READ_SCOPE, new BaSyxObjectTargetInformation(null, null, null)); + SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, AASRegistryScopes.READ_SCOPE, new BaSyxObjectTargetInformation(null, null, null, null)); return aasDescriptorsSupplier.get(); } @Override public List authorizeLookupSubmodels(final SubjectInformationType subjectInformation, final IIdentifier aasId, final Supplier> submodelDescriptorsSupplier) throws InhibitException { - SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, AASRegistryScopes.READ_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), null, null)); + SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, AASRegistryScopes.READ_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), null, null, null)); return submodelDescriptorsSupplier.get(); } @Override - public SubmodelDescriptor authorizeLookupSubmodel(final SubjectInformationType subjectInformation, final IIdentifier aasId, final IIdentifier smId, final Supplier smSupplier) throws InhibitException { - SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, AASRegistryScopes.READ_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), null)); + public SubmodelDescriptor authorizeLookupSubmodel(final SubjectInformationType subjectInformation, final IIdentifier aasId, final IIdentifier smId, final IReference smSemanticId, final Supplier smSupplier) throws InhibitException { + SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, AASRegistryScopes.READ_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), IdHelper.getReferenceId(smSemanticId), null)); return smSupplier.get(); } diff --git a/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/BaSyxObjectTargetInformation.java b/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/BaSyxObjectTargetInformation.java index 417120b3..2be1691f 100644 --- a/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/BaSyxObjectTargetInformation.java +++ b/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/BaSyxObjectTargetInformation.java @@ -35,7 +35,7 @@ /** * Specialization of {@link TargetInformation} that uses the - * aasId/smId/smElIdShortPath tuple. + * aasId/smId/smSemanticId/smElIdShortPath tuple. * * @author wege */ @@ -43,6 +43,7 @@ public class BaSyxObjectTargetInformation implements TargetInformation { private String aasId; private String smId; + private String smSemanticId; private String smElIdShortPath; public String getAasId() { @@ -53,22 +54,64 @@ public String getSmId() { return smId; } + public String getSmSemanticId() { + return smSemanticId; + } + public String getSmElIdShortPath() { return smElIdShortPath; } @JsonCreator - public BaSyxObjectTargetInformation(final @JsonProperty("aasId") String aasId, final @JsonProperty("smId") String smId, final @JsonProperty("smElIdShortPath") String smElIdShortPath) { + public BaSyxObjectTargetInformation( + final @JsonProperty("aasId") String aasId, + final @JsonProperty("smId") String smId, + final @JsonProperty("smSemanticId") String smSemanticId, + final @JsonProperty("smElIdShortPath") String smElIdShortPath + ) { this.aasId = aasId; this.smId = smId; + this.smSemanticId = smSemanticId; this.smElIdShortPath = smElIdShortPath; } + public static class Builder { + private String aasId; + private String smId; + private String smSemanticId; + private String smElIdShortPath; + + public Builder setAasId(final String aasId) { + this.aasId = aasId; + return this; + } + + public Builder setSmId(final String smId) { + this.smId = smId; + return this; + } + + public Builder setSmSemanticId(final String smSemanticId) { + this.smSemanticId = smSemanticId; + return this; + } + + public Builder setSmElIdShortPath(final String smElIdShortPath) { + this.smElIdShortPath = smElIdShortPath; + return this; + } + + public BaSyxObjectTargetInformation build() { + return new BaSyxObjectTargetInformation(aasId, smId, smSemanticId, smElIdShortPath); + } + } + @Override public Map toMap() { final Map map = new HashMap<>(); map.put("aasId", aasId); map.put("smId", smId); + map.put("smSemanticId", smSemanticId); map.put("smElIdShortPath", smElIdShortPath); return map; } @@ -85,17 +128,36 @@ public boolean equals(final Object o) { final BaSyxObjectTargetInformation other = (BaSyxObjectTargetInformation) o; - return new EqualsBuilder().append(getAasId(), other.getAasId()).append(getSmId(), other.getSmId()).append(getSmElIdShortPath(), other.getSmElIdShortPath()).isEquals(); + return new EqualsBuilder() + .append(getAasId(), other.getAasId()) + .append(getSmId(), other.getSmId()) + .append(getSmSemanticId(), other.getSmSemanticId()) + .append(getSmElIdShortPath(), other.getSmElIdShortPath()) + .isEquals(); } @Override public int hashCode() { - return new HashCodeBuilder(17, 37).append(getAasId()).append(getSmId()).append(getSmElIdShortPath()).toHashCode(); + return new HashCodeBuilder(17, 37) + .append(getAasId()) + .append(getSmId()) + .append(getSmSemanticId()) + .append(getSmElIdShortPath()) + .toHashCode(); } @Override public String toString() { - return new StringBuilder("BaSyxObjectTargetInformation{").append("aasId='").append(aasId).append('\'').append(", smId='").append(smId).append('\'').append(", smElIdShortPath='").append(smElIdShortPath).append('\'').append('}') + return new StringBuilder("BaSyxObjectTargetInformation{") + .append("aasId='").append(aasId) + .append('\'') + .append(", smId='").append(smId) + .append('\'') + .append(", smSemanticId='").append(smSemanticId) + .append('\'') + .append(", smElIdShortPath='").append(smElIdShortPath) + .append('\'') + .append('}') .toString(); } } diff --git a/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/KeycloakRoleAuthenticator.java b/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/KeycloakRoleAuthenticator.java index a3e1944f..492e5827 100644 --- a/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/KeycloakRoleAuthenticator.java +++ b/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/KeycloakRoleAuthenticator.java @@ -59,19 +59,53 @@ private List jwtStr2roles(JwtAuthenticationToken token) { logger.info("jwt: {}", token.getTokenAttributes()); try { - final Object realmAccessObject = token.getTokenAttributes().get("realm_access"); + final List realmRoles = getRealmAccessRoles(token); + final List resourceRoles = getResoureAccessRoles(token); - final Map realmAccess = (Map) realmAccessObject; + final List roles = new ArrayList<>(); + roles.addAll(realmRoles); + roles.addAll(resourceRoles); - final Object rolesObject = realmAccess.get("roles"); - - if (rolesObject != null) { - final List roles = (List) rolesObject; - return roles.stream().map(Object::toString).collect(Collectors.toList()); + if (!roles.isEmpty()) { + return roles; } } catch (final Exception e) { logger.error(e.getMessage(), e); } return new ArrayList<>(Collections.singletonList("anonymous")); } + + private List getRealmAccessRoles(JwtAuthenticationToken token) { + final Object realmAccessObject = token.getTokenAttributes().get("realm_access"); + + if (realmAccessObject == null) { + return Collections.emptyList(); + } + + return getCategoryRoles(realmAccessObject); + } + + private List getResoureAccessRoles(JwtAuthenticationToken token) { + final Object resourceAccessObject = token.getTokenAttributes().get("resource_access"); + + if (resourceAccessObject == null) { + return Collections.emptyList(); + } + + final Map resourceAccess = (Map) resourceAccessObject; + + return resourceAccess.values().stream().map(this::getCategoryRoles).flatMap(List::stream).collect(Collectors.toList()); + } + + private List getCategoryRoles(Object categoryObject) { + final Map category = (Map) categoryObject; + + final Object rolesObject = category.get("roles"); + + if (rolesObject == null) { + return Collections.emptyList(); + } + + return (List) rolesObject; + } } diff --git a/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/RbacRule.java b/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/RbacRule.java index 79c7def2..b6eaf37e 100644 --- a/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/RbacRule.java +++ b/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/RbacRule.java @@ -78,16 +78,28 @@ public boolean equals(final Object o) { final RbacRule rbacRule = (RbacRule) o; - return new EqualsBuilder().append(getRole(), rbacRule.getRole()).append(getAction(), rbacRule.getAction()).append(getTargetInformation(), rbacRule.getTargetInformation()).isEquals(); + return new EqualsBuilder() + .append(getRole(), rbacRule.getRole()) + .append(getAction(), rbacRule.getAction()) + .append(getTargetInformation(), rbacRule.getTargetInformation()) + .isEquals(); } @Override public int hashCode() { - return new HashCodeBuilder(17, 37).append(getRole()).append(getAction()).append(getTargetInformation()).toHashCode(); + return new HashCodeBuilder(17, 37) + .append(getRole()) + .append(getAction()) + .append(getTargetInformation()) + .toHashCode(); } @Override public String toString() { - return new StringBuilder("RbacRule{").append("role='").append(role).append('\'').append(", action='").append(action).append('\'').append(", targetInformation='").append(targetInformation).append('\'').append('}').toString(); + return new StringBuilder("RbacRule{").append("role='") + .append(role).append('\'').append(", action='") + .append(action).append('\'').append(", targetInformation='") + .append(targetInformation).append('\'').append('}') + .toString(); } } diff --git a/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/RbacRuleDTO.java b/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/RbacRuleDTO.java index c1d92cd5..1bc0b741 100644 --- a/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/RbacRuleDTO.java +++ b/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/RbacRuleDTO.java @@ -49,9 +49,15 @@ public Map getTargetInformation() { return targetInformation; } - private RbacRuleDTO() { + public RbacRuleDTO() { role = ""; action = ""; targetInformation = new HashMap<>(); } + + public RbacRuleDTO(final String role, final String action, final Map targetInformation) { + this.role = role; + this.action = action; + this.targetInformation = targetInformation; + } } diff --git a/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/RbacRuleSetDeserializer.java b/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/RbacRuleSetDeserializer.java index 4937570b..705d108a 100644 --- a/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/RbacRuleSetDeserializer.java +++ b/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/RbacRuleSetDeserializer.java @@ -24,22 +24,27 @@ ******************************************************************************/ package org.eclipse.basyx.extensions.shared.authorization.internal; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonTypeInfo; -import com.fasterxml.jackson.annotation.JsonTypeInfo.Id; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.jsontype.NamedType; - import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; +import java.util.Map; import java.util.function.Consumer; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeInfo.Id; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.jsontype.NamedType; + /** * Deserializer for {@link RbacRuleSet}. *

@@ -77,6 +82,7 @@ public RbacRuleSetDeserializer() { public RbacRuleSetDeserializer(final Consumer objectMapperConsumer) { objectMapper = new ObjectMapper(); + objectMapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY); objectMapper.addMixIn(RbacRule.class, RbacRuleMixin.class); objectMapper.addMixIn(TargetInformation.class, TargetInformationMixin.class).registerSubtypes(new NamedType(BaSyxObjectTargetInformation.class, "basyx"), new NamedType(TagTargetInformation.class, "tag")); objectMapperConsumer.accept(objectMapper); @@ -107,7 +113,6 @@ private InputStream getInputStreamFromFile(final String filePath) throws IOExcep // did not find file on file system, fallback to read from classpath next logger.info("did not find {} in file system, try classpath next", filePath); } - try { final InputStream inputStream = RbacRuleSet.class.getResourceAsStream(filePath); if (inputStream == null) { @@ -119,11 +124,61 @@ private InputStream getInputStreamFromFile(final String filePath) throws IOExcep // did not find file on classpath, give up logger.info("did not find {} on classpath, give up", filePath); } - throw new IOException("could not find " + filePath); } + private static class RbacRuleMultiple { + String role; + String[] actions; + Map[] targetInformation; + + public RbacRuleMultiple() { + } + + public RbacRuleMultiple(final @JsonProperty("role") String role, final @JsonProperty("action") String[] actions, final @JsonProperty("targetInformation") Map[] targetInformation) { + this.role = role; + this.actions = actions; + this.targetInformation = targetInformation; + } + + public String getRole() { + return role; + } + + public String[] getActions() { + return actions; + } + + public Map[] getTargetInformation() { + return targetInformation; + } + } + + private static class Pair { + private final T first; + private final U second; + + public Pair(final T first, final U second) { + this.first = first; + this.second = second; + } + } + + private List> cartesianProduct2(final T[] firsts, final U[] seconds) { + final List> result = new ArrayList<>(); + + for (final T first : firsts) { + for (final U second : seconds) { + result.add(new Pair<>(first, second)); + } + } + + return result; + } + public RbacRule[] deserialize(final InputStream inputStream) throws IOException { - return objectMapper.readValue(inputStream, RbacRule[].class); + final RbacRuleMultiple[] rbacRulesRaw = objectMapper.readValue(inputStream, RbacRuleMultiple[].class); + return Arrays.stream(rbacRulesRaw).flatMap(raw -> cartesianProduct2(raw.actions, raw.targetInformation).stream().map(pair -> objectMapper.convertValue(new RbacRuleDTO(raw.role, pair.first, pair.second), RbacRule.class))) + .toArray(RbacRule[]::new); } } \ No newline at end of file diff --git a/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/SimpleRbacInhibitException.java b/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/SimpleRbacInhibitException.java index 1d2de5aa..0ee844ea 100644 --- a/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/SimpleRbacInhibitException.java +++ b/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/SimpleRbacInhibitException.java @@ -64,7 +64,7 @@ public InhibitException reduceSmIdToSmIdShortPath(final String smIdShortPath) { private TargetInformation reduceSmIdToSmIdShortPath_convertTargetInformation(final String smIdShortPath) { if (targetInformation instanceof BaSyxObjectTargetInformation) { - return new BaSyxObjectTargetInformation(((BaSyxObjectTargetInformation) targetInformation).getAasId(), ((BaSyxObjectTargetInformation) targetInformation).getSmId(), String.format("(id of %s)", smIdShortPath)); + return new BaSyxObjectTargetInformation(((BaSyxObjectTargetInformation) targetInformation).getAasId(), ((BaSyxObjectTargetInformation) targetInformation).getSmId(), ((BaSyxObjectTargetInformation) targetInformation).getSmSemanticId(), String.format("(id of %s)", smIdShortPath)); } return targetInformation; diff --git a/src/main/java/org/eclipse/basyx/extensions/submodel/aggregator/authorization/internal/AuthorizedSubmodelAggregator.java b/src/main/java/org/eclipse/basyx/extensions/submodel/aggregator/authorization/internal/AuthorizedSubmodelAggregator.java index 3b1abe15..396d4226 100644 --- a/src/main/java/org/eclipse/basyx/extensions/submodel/aggregator/authorization/internal/AuthorizedSubmodelAggregator.java +++ b/src/main/java/org/eclipse/basyx/extensions/submodel/aggregator/authorization/internal/AuthorizedSubmodelAggregator.java @@ -39,8 +39,13 @@ import org.eclipse.basyx.submodel.aggregator.api.ISubmodelAggregator; import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType; import org.eclipse.basyx.submodel.metamodel.api.qualifier.IIdentifiable; +import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; +import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements; import org.eclipse.basyx.submodel.metamodel.map.Submodel; +import org.eclipse.basyx.submodel.metamodel.map.reference.Key; +import org.eclipse.basyx.submodel.metamodel.map.reference.Reference; import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI; import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException; import org.slf4j.Logger; @@ -120,7 +125,9 @@ public ISubmodel getSubmodel(final IIdentifier identifier) throws ResourceNotFou } protected ISubmodel authorizeGetSubmodel(final IIdentifier smId) throws ResourceNotFoundException, InhibitException { - return submodelAggregatorAuthorizer.authorizeGetSubmodel(subjectInformationProvider.get(), aas, smId, () -> decoratedSubmodelAggregator.getSubmodel(smId)); + final ISubmodel sm = getSmUnsecured(smId); + final IReference smSemanticId = getSmSemanticIdUnsecured(sm); + return submodelAggregatorAuthorizer.authorizeGetSubmodel(subjectInformationProvider.get(), aas, smId, smSemanticId, () -> decoratedSubmodelAggregator.getSubmodel(smId)); } @Override @@ -137,7 +144,10 @@ public ISubmodel getSubmodelbyIdShort(final String smIdShortPath) throws Resourc } protected ISubmodel authorizeGetSubmodelbyIdShort(final String smIdShortPath) throws ResourceNotFoundException, InhibitException { - return submodelAggregatorAuthorizer.authorizeGetSubmodelbyIdShort(subjectInformationProvider.get(), aas, smIdShortPath, () -> decoratedSubmodelAggregator.getSubmodelbyIdShort(smIdShortPath)); + final ISubmodel sm = getSmUnsecured(smIdShortPath); + final IIdentifier smId = getSmIdUnsecured(sm); + final IReference smSemanticId = getSmSemanticIdUnsecured(sm); + return submodelAggregatorAuthorizer.authorizeGetSubmodelbyIdShort(subjectInformationProvider.get(), aas, smId, smSemanticId, () -> decoratedSubmodelAggregator.getSubmodelbyIdShort(smIdShortPath)); } @Override @@ -154,7 +164,9 @@ public ISubmodelAPI getSubmodelAPIById(final IIdentifier identifier) throws Reso } protected ISubmodelAPI authorizeGetSubmodelAPIById(final IIdentifier smId) throws ResourceNotFoundException, InhibitException { - return submodelAggregatorAuthorizer.authorizeGetSubmodelAPIById(subjectInformationProvider.get(), aas, smId, () -> decoratedSubmodelAggregator.getSubmodelAPIById(smId)); + final ISubmodel sm = getSmUnsecured(smId); + final IReference smSemanticId = getSmSemanticIdUnsecured(sm); + return submodelAggregatorAuthorizer.authorizeGetSubmodelAPIById(subjectInformationProvider.get(), aas, smId, smSemanticId, () -> decoratedSubmodelAggregator.getSubmodelAPIById(smId)); } @Override @@ -171,9 +183,12 @@ public ISubmodelAPI getSubmodelAPIByIdShort(final String smIdShortPath) throws R } protected ISubmodelAPI authorizeGetSubmodelAPIByIdShort(final String smIdShortPath) throws ResourceNotFoundException, InhibitException { + final ISubmodel sm = getSmUnsecured(smIdShortPath); + final IIdentifier smId = getSmIdUnsecured(sm); + final IReference smSemanticId = getSmSemanticIdUnsecured(sm); try { try { - return submodelAggregatorAuthorizer.authorizeGetSubmodelAPIByIdShort(subjectInformationProvider.get(), aas, smIdShortPath, () -> decoratedSubmodelAggregator.getSubmodelAPIByIdShort(smIdShortPath)); + return submodelAggregatorAuthorizer.authorizeGetSubmodelAPIByIdShort(subjectInformationProvider.get(), aas, smId, smSemanticId, () -> decoratedSubmodelAggregator.getSubmodelAPIByIdShort(smIdShortPath)); } catch (final InhibitException inhibitException) { throw inhibitException.reduceSmIdToSmIdShortPath(smIdShortPath); } @@ -182,7 +197,9 @@ protected ISubmodelAPI authorizeGetSubmodelAPIByIdShort(final String smIdShortPa // submodel, // if no, the authorization will throw an InhibitException, otherwise we throw // the ResourceNotFoundException - submodelAggregatorAuthorizer.authorizeGetSubmodelAPIById(subjectInformationProvider.get(), aas, new ModelUrn("*"), () -> null); + final IIdentifier anySmId = new ModelUrn("*"); + final IReference anySemanticSmId = new Reference(new Key(KeyElements.SUBMODEL, true, "*", IdentifierType.CUSTOM)); + submodelAggregatorAuthorizer.authorizeGetSubmodelAPIById(subjectInformationProvider.get(), aas, anySmId, anySemanticSmId, () -> null); throw resourceNotFoundException; } @@ -204,7 +221,9 @@ public void createSubmodel(final Submodel submodel) { } protected void authorizeCreateSubmodel(final IIdentifier smId) throws InhibitException { - submodelAggregatorAuthorizer.authorizeCreateSubmodel(subjectInformationProvider.get(), aas, smId); + final ISubmodel sm = getSmUnsecured(smId); + final IReference smSemanticId = getSmSemanticIdUnsecured(sm); + submodelAggregatorAuthorizer.authorizeCreateSubmodel(subjectInformationProvider.get(), aas, smId, smSemanticId); } @Override @@ -224,7 +243,9 @@ public void createSubmodel(final ISubmodelAPI submodelAPI) { protected void authorizeCreateSubmodel(final ISubmodelAPI submodelAPI) throws InhibitException { final IIdentifier smId = Optional.ofNullable(submodelAPI).map(ISubmodelAPI::getSubmodel).map(IIdentifiable::getIdentification).orElse(null); - submodelAggregatorAuthorizer.authorizeCreateSubmodel(subjectInformationProvider.get(), aas, smId); + final ISubmodel sm = getSmUnsecured(smId); + final IReference smSemanticId = getSmSemanticIdUnsecured(sm); + submodelAggregatorAuthorizer.authorizeCreateSubmodel(subjectInformationProvider.get(), aas, smId, smSemanticId); } @Override @@ -244,7 +265,9 @@ public void updateSubmodel(final Submodel submodel) throws ResourceNotFoundExcep } protected void authorizeUpdateSubmodel(final IIdentifier smId) throws InhibitException { - submodelAggregatorAuthorizer.authorizeUpdateSubmodel(subjectInformationProvider.get(), aas, smId); + final ISubmodel sm = getSmUnsecured(smId); + final IReference smSemanticId = getSmSemanticIdUnsecured(sm); + submodelAggregatorAuthorizer.authorizeUpdateSubmodel(subjectInformationProvider.get(), aas, smId, smSemanticId); } @Override @@ -263,7 +286,9 @@ public void deleteSubmodelByIdentifier(final IIdentifier identifier) { } protected void authorizeDeleteSubmodelByIdentifier(final IIdentifier smId) throws InhibitException { - submodelAggregatorAuthorizer.authorizeDeleteSubmodelByIdentifier(subjectInformationProvider.get(), aas, smId); + final ISubmodel sm = getSmUnsecured(smId); + final IReference smSemanticId = getSmSemanticIdUnsecured(sm); + submodelAggregatorAuthorizer.authorizeDeleteSubmodelByIdentifier(subjectInformationProvider.get(), aas, smId, smSemanticId); } @Override @@ -284,7 +309,14 @@ public void deleteSubmodelByIdShort(final String smIdShortPath) { protected void authorizeDeleteSubmodelByIdShort(final String smIdShortPath) throws InhibitException { final ISubmodel sm = getSmUnsecured(smIdShortPath); final IIdentifier smId = getSmIdUnsecured(sm); - submodelAggregatorAuthorizer.authorizeDeleteSubmodelByIdentifier(subjectInformationProvider.get(), aas, smId); + final IReference smSemanticId = getSmSemanticIdUnsecured(sm); + submodelAggregatorAuthorizer.authorizeDeleteSubmodelByIdentifier(subjectInformationProvider.get(), aas, smId, smSemanticId); + } + + private ISubmodel getSmUnsecured(final IIdentifier smId) throws ResourceNotFoundException { + try (final ElevatedCodeAuthenticationAreaHandler ignored = ElevatedCodeAuthentication.enterElevatedCodeAuthenticationArea()) { + return decoratedSubmodelAggregator.getSubmodel(smId); + } } private ISubmodel getSmUnsecured(final String smIdShortPath) throws ResourceNotFoundException { @@ -302,4 +334,14 @@ private IIdentifier getSmIdUnsecured(final ISubmodel sm) throws ResourceNotFound return sm.getIdentification(); } } + + private IReference getSmSemanticIdUnsecured(final ISubmodel sm) throws ResourceNotFoundException { + if (sm == null) { + return null; + } + + try (final ElevatedCodeAuthenticationAreaHandler ignored = ElevatedCodeAuthentication.enterElevatedCodeAuthenticationArea()) { + return sm.getSemanticId(); + } + } } diff --git a/src/main/java/org/eclipse/basyx/extensions/submodel/aggregator/authorization/internal/GrantedAuthoritySubmodelAggregatorAuthorizer.java b/src/main/java/org/eclipse/basyx/extensions/submodel/aggregator/authorization/internal/GrantedAuthoritySubmodelAggregatorAuthorizer.java index b4ead7f8..fb96ba29 100644 --- a/src/main/java/org/eclipse/basyx/extensions/submodel/aggregator/authorization/internal/GrantedAuthoritySubmodelAggregatorAuthorizer.java +++ b/src/main/java/org/eclipse/basyx/extensions/submodel/aggregator/authorization/internal/GrantedAuthoritySubmodelAggregatorAuthorizer.java @@ -32,6 +32,7 @@ import org.eclipse.basyx.extensions.shared.authorization.internal.InhibitException; import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; +import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI; /** @@ -54,45 +55,49 @@ public Collection authorizeGetSubmodelList(final SubjectInformationTy } @Override - public ISubmodel authorizeGetSubmodel(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final Supplier smSupplier) throws InhibitException { + public ISubmodel authorizeGetSubmodel(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, final Supplier smSupplier) + throws InhibitException { GrantedAuthorityHelper.checkAuthority(grantedAuthorityAuthenticator, subjectInformation, AuthorizedSubmodelAggregator.READ_AUTHORITY); return smSupplier.get(); } @Override - public ISubmodel authorizeGetSubmodelbyIdShort(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final String smIdShortPath, final Supplier smSupplier) throws InhibitException { + public ISubmodel authorizeGetSubmodelbyIdShort(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, final Supplier smSupplier) + throws InhibitException { GrantedAuthorityHelper.checkAuthority(grantedAuthorityAuthenticator, subjectInformation, AuthorizedSubmodelAggregator.READ_AUTHORITY); return smSupplier.get(); } @Override - public ISubmodelAPI authorizeGetSubmodelAPIById(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final Supplier smAPISupplier) throws InhibitException { + public ISubmodelAPI authorizeGetSubmodelAPIById(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, final Supplier smAPISupplier) + throws InhibitException { GrantedAuthorityHelper.checkAuthority(grantedAuthorityAuthenticator, subjectInformation, AuthorizedSubmodelAggregator.READ_AUTHORITY); return smAPISupplier.get(); } @Override - public ISubmodelAPI authorizeGetSubmodelAPIByIdShort(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final String smIdShortPath, final Supplier smAPISupplier) throws InhibitException { + public ISubmodelAPI authorizeGetSubmodelAPIByIdShort(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, + final Supplier smAPISupplier) throws InhibitException { GrantedAuthorityHelper.checkAuthority(grantedAuthorityAuthenticator, subjectInformation, AuthorizedSubmodelAggregator.READ_AUTHORITY); return smAPISupplier.get(); } @Override - public void authorizeCreateSubmodel(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId) throws InhibitException { + public void authorizeCreateSubmodel(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId) throws InhibitException { GrantedAuthorityHelper.checkAuthority(grantedAuthorityAuthenticator, subjectInformation, AuthorizedSubmodelAggregator.WRITE_AUTHORITY); } @Override - public void authorizeUpdateSubmodel(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId) throws InhibitException { + public void authorizeUpdateSubmodel(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId) throws InhibitException { GrantedAuthorityHelper.checkAuthority(grantedAuthorityAuthenticator, subjectInformation, AuthorizedSubmodelAggregator.WRITE_AUTHORITY); } @Override - public void authorizeDeleteSubmodelByIdentifier(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId) throws InhibitException { + public void authorizeDeleteSubmodelByIdentifier(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId) throws InhibitException { GrantedAuthorityHelper.checkAuthority(grantedAuthorityAuthenticator, subjectInformation, AuthorizedSubmodelAggregator.WRITE_AUTHORITY); } } diff --git a/src/main/java/org/eclipse/basyx/extensions/submodel/aggregator/authorization/internal/ISubmodelAggregatorAuthorizer.java b/src/main/java/org/eclipse/basyx/extensions/submodel/aggregator/authorization/internal/ISubmodelAggregatorAuthorizer.java index 9ee50a74..27cca04c 100644 --- a/src/main/java/org/eclipse/basyx/extensions/submodel/aggregator/authorization/internal/ISubmodelAggregatorAuthorizer.java +++ b/src/main/java/org/eclipse/basyx/extensions/submodel/aggregator/authorization/internal/ISubmodelAggregatorAuthorizer.java @@ -31,6 +31,7 @@ import org.eclipse.basyx.submodel.aggregator.api.ISubmodelAggregator; import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; +import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; import org.eclipse.basyx.submodel.metamodel.map.Submodel; import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI; @@ -68,13 +69,16 @@ public interface ISubmodelAggregatorAuthorizer { * {@link AuthorizedSubmodelAggregator}, may be null. * @param smId * id of the submodel. + * @param smSemanticId + * semantic id of the submodel. * @param smSupplier * supplier for the submodel. * @return the authorized submodel. * @throws InhibitException * if authorization failed */ - public ISubmodel authorizeGetSubmodel(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final Supplier smSupplier) throws InhibitException; + public ISubmodel authorizeGetSubmodel(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, final Supplier smSupplier) + throws InhibitException; /** * Checks authorization for @@ -85,15 +89,18 @@ public interface ISubmodelAggregatorAuthorizer { * @param aas * the aas the submodel belongs to as passed in the constructor of * {@link AuthorizedSubmodelAggregator}, may be null. - * @param smIdShortPath - * short path id of the submodel. + * @param smId + * id of the submodel. + * @param smSemanticId + * semantic id of the submodel. * @param smSupplier * supplier for the submodel. * @return the authorized submodel. * @throws InhibitException * if authorization failed */ - public ISubmodel authorizeGetSubmodelbyIdShort(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final String smIdShortPath, final Supplier smSupplier) throws InhibitException; + public ISubmodel authorizeGetSubmodelbyIdShort(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, final Supplier smSupplier) + throws InhibitException; /** * Checks authorization for @@ -106,13 +113,16 @@ public interface ISubmodelAggregatorAuthorizer { * {@link AuthorizedSubmodelAggregator}, may be null. * @param smId * id of the submodel. + * @param smSemanticId + * semantic id of the submodel. * @param smAPISupplier * supplier for the submodel API. * @return the authorized submodel API * @throws InhibitException * if authorization failed */ - public ISubmodelAPI authorizeGetSubmodelAPIById(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final Supplier smAPISupplier) throws InhibitException; + public ISubmodelAPI authorizeGetSubmodelAPIById(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, final Supplier smAPISupplier) + throws InhibitException; /** * Checks authorization for @@ -123,15 +133,18 @@ public interface ISubmodelAggregatorAuthorizer { * @param aas * the aas the submodel belongs to as passed in the constructor of * {@link AuthorizedSubmodelAggregator}, may be null. - * @param smIdShortPath - * short path id of the submodel. + * @param smId + * id of the submodel. + * @param smSemanticId + * semantic id of the submodel. * @param smAPISupplier * supplier for the submodel API. * @return the authorized submodel API. * @throws InhibitException * if authorization failed */ - public ISubmodelAPI authorizeGetSubmodelAPIByIdShort(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final String smIdShortPath, final Supplier smAPISupplier) throws InhibitException; + public ISubmodelAPI authorizeGetSubmodelAPIByIdShort(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, + final Supplier smAPISupplier) throws InhibitException; /** * Checks authorization for @@ -144,10 +157,12 @@ public interface ISubmodelAggregatorAuthorizer { * {@link AuthorizedSubmodelAggregator}, may be null. * @param smId * id of the submodel. + * @param smSemanticId + * semantic id of the submodel. * @throws InhibitException * if authorization failed */ - public void authorizeCreateSubmodel(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId) throws InhibitException; + public void authorizeCreateSubmodel(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId) throws InhibitException; /** * Checks authorization for @@ -160,10 +175,12 @@ public interface ISubmodelAggregatorAuthorizer { * {@link AuthorizedSubmodelAggregator}, may be null. * @param smId * id of the submodel. + * @param smSemanticId + * semantic id of the submodel. * @throws InhibitException * if authorization failed */ - public void authorizeUpdateSubmodel(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId) throws InhibitException; + public void authorizeUpdateSubmodel(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId) throws InhibitException; /** * Checks authorization for @@ -177,8 +194,10 @@ public interface ISubmodelAggregatorAuthorizer { * {@link AuthorizedSubmodelAggregator}, may be null. * @param smId * id of the submodel. + * @param smSemanticId + * semantic id of the submodel. * @throws InhibitException * if authorization failed */ - public void authorizeDeleteSubmodelByIdentifier(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId) throws InhibitException; + public void authorizeDeleteSubmodelByIdentifier(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId) throws InhibitException; } diff --git a/src/main/java/org/eclipse/basyx/extensions/submodel/aggregator/authorization/internal/SimpleRbacSubmodelAggregatorAuthorizer.java b/src/main/java/org/eclipse/basyx/extensions/submodel/aggregator/authorization/internal/SimpleRbacSubmodelAggregatorAuthorizer.java index 852c7b8b..485fa099 100644 --- a/src/main/java/org/eclipse/basyx/extensions/submodel/aggregator/authorization/internal/SimpleRbacSubmodelAggregatorAuthorizer.java +++ b/src/main/java/org/eclipse/basyx/extensions/submodel/aggregator/authorization/internal/SimpleRbacSubmodelAggregatorAuthorizer.java @@ -24,22 +24,17 @@ ******************************************************************************/ package org.eclipse.basyx.extensions.submodel.aggregator.authorization.internal; -import java.util.Collection; -import java.util.function.Supplier; import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell; -import org.eclipse.basyx.extensions.shared.authorization.internal.BaSyxObjectTargetInformation; -import org.eclipse.basyx.extensions.shared.authorization.internal.ElevatedCodeAuthentication; -import org.eclipse.basyx.extensions.shared.authorization.internal.ElevatedCodeAuthentication.ElevatedCodeAuthenticationAreaHandler; -import org.eclipse.basyx.extensions.shared.authorization.internal.IRbacRuleChecker; -import org.eclipse.basyx.extensions.shared.authorization.internal.IRoleAuthenticator; -import org.eclipse.basyx.extensions.shared.authorization.internal.IdHelper; -import org.eclipse.basyx.extensions.shared.authorization.internal.InhibitException; -import org.eclipse.basyx.extensions.shared.authorization.internal.SimpleRbacHelper; +import org.eclipse.basyx.extensions.shared.authorization.internal.*; import org.eclipse.basyx.extensions.submodel.aggregator.authorization.SubmodelAggregatorScopes; import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; +import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI; +import java.util.Collection; +import java.util.function.Supplier; + /** * Simple role based implementation for {@link ISubmodelAggregatorAuthorizer}. * @@ -60,95 +55,73 @@ public Collection authorizeGetSubmodelList(final SubjectInformationTy } @Override - public ISubmodel authorizeGetSubmodel(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final Supplier smSupplier) throws InhibitException { + public ISubmodel authorizeGetSubmodel(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, final Supplier smSupplier) + throws InhibitException { final IIdentifier aasId = getAASId(aas); - SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, SubmodelAggregatorScopes.READ_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), null)); + SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, SubmodelAggregatorScopes.READ_SCOPE, + new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), IdHelper.getReferenceId(smSemanticId), null)); return smSupplier.get(); } @Override - public ISubmodel authorizeGetSubmodelbyIdShort(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final String smIdShortPath, final Supplier smSupplier) throws InhibitException { + public ISubmodel authorizeGetSubmodelbyIdShort(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, final Supplier smSupplier) + throws InhibitException { final IIdentifier aasId = getAASId(aas); - final IIdentifier smId = getSmIdUnsecured(smSupplier); - SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, SubmodelAggregatorScopes.READ_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), null)); + SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, SubmodelAggregatorScopes.READ_SCOPE, + new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), IdHelper.getReferenceId(smSemanticId), null)); return smSupplier.get(); } @Override - public ISubmodelAPI authorizeGetSubmodelAPIById(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final Supplier smAPISupplier) throws InhibitException { + public ISubmodelAPI authorizeGetSubmodelAPIById(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, final Supplier smAPISupplier) + throws InhibitException { final IIdentifier aasId = getAASId(aas); - SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, SubmodelAggregatorScopes.READ_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), null)); + SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, SubmodelAggregatorScopes.READ_SCOPE, + new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), IdHelper.getReferenceId(smSemanticId), null)); return smAPISupplier.get(); } @Override - public ISubmodelAPI authorizeGetSubmodelAPIByIdShort(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final String smIdShortPath, final Supplier smAPISupplier) throws InhibitException { + public ISubmodelAPI authorizeGetSubmodelAPIByIdShort(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, + final Supplier smAPISupplier) throws InhibitException { final IIdentifier aasId = getAASId(aas); - final IIdentifier smId = getSmIdUnsecuredByAPI(smAPISupplier); - SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, SubmodelAggregatorScopes.READ_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), null)); + SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, SubmodelAggregatorScopes.READ_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), null, null)); return smAPISupplier.get(); } @Override - public void authorizeCreateSubmodel(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId) throws InhibitException { + public void authorizeCreateSubmodel(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId) throws InhibitException { final IIdentifier aasId = getAASId(aas); - SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, SubmodelAggregatorScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), null)); + SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, SubmodelAggregatorScopes.WRITE_SCOPE, + new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), IdHelper.getReferenceId(smSemanticId), null)); } @Override - public void authorizeUpdateSubmodel(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId) throws InhibitException { + public void authorizeUpdateSubmodel(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId) throws InhibitException { final IIdentifier aasId = getAASId(aas); - SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, SubmodelAggregatorScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), null)); + SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, SubmodelAggregatorScopes.WRITE_SCOPE, + new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), IdHelper.getReferenceId(smSemanticId), null)); } @Override - public void authorizeDeleteSubmodelByIdentifier(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId) throws InhibitException { + public void authorizeDeleteSubmodelByIdentifier(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId) throws InhibitException { final IIdentifier aasId = getAASId(aas); - SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, SubmodelAggregatorScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), null)); + SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, SubmodelAggregatorScopes.WRITE_SCOPE, + new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), IdHelper.getReferenceId(smSemanticId), null)); } private IIdentifier getAASId(final IAssetAdministrationShell aas) { return aas != null ? aas.getIdentification() : null; } - - private IIdentifier getSmIdUnsecured(final Supplier smSupplier) { - try (final ElevatedCodeAuthenticationAreaHandler ignored = ElevatedCodeAuthentication.enterElevatedCodeAuthenticationArea()) { - final ISubmodel sm = smSupplier.get(); - - if (sm == null) { - return null; - } - - return sm.getIdentification(); - } - } - - private IIdentifier getSmIdUnsecuredByAPI(final Supplier smAPISupplier) { - try (final ElevatedCodeAuthenticationAreaHandler ignored = ElevatedCodeAuthentication.enterElevatedCodeAuthenticationArea()) { - final ISubmodelAPI smAPI = smAPISupplier.get(); - - if (smAPI == null) { - return null; - } - - final ISubmodel sm = smAPI.getSubmodel(); - - if (sm == null) { - return null; - } - - return sm.getIdentification(); - } - } } diff --git a/src/main/java/org/eclipse/basyx/extensions/submodel/authorization/internal/AuthorizedSubmodelAPI.java b/src/main/java/org/eclipse/basyx/extensions/submodel/authorization/internal/AuthorizedSubmodelAPI.java index d5d40db4..d041b336 100644 --- a/src/main/java/org/eclipse/basyx/extensions/submodel/authorization/internal/AuthorizedSubmodelAPI.java +++ b/src/main/java/org/eclipse/basyx/extensions/submodel/authorization/internal/AuthorizedSubmodelAPI.java @@ -38,6 +38,7 @@ import org.eclipse.basyx.extensions.submodel.authorization.SubmodelAPIScopes; import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; +import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement; import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation; import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI; @@ -90,7 +91,8 @@ public ISubmodel getSubmodel() { protected ISubmodel authorizeGetSubmodel() throws InhibitException { final IIdentifier smId = getSmIdUnsecured(); - return submodelAPIAuthorizer.authorizeGetSubmodel(subjectInformationProvider.get(), aas, smId, decoratedSubmodelAPI::getSubmodel); + final IReference smSemanticId = getSmSemanticIdUnsecured(); + return submodelAPIAuthorizer.authorizeGetSubmodel(subjectInformationProvider.get(), aas, smId, smSemanticId, decoratedSubmodelAPI::getSubmodel); } @Override @@ -125,7 +127,8 @@ public void addSubmodelElement(final String idShortPath, final ISubmodelElement protected void authorizeAddSubmodelElement(final String smElIdShortPath) throws InhibitException { final IIdentifier smId = getSmIdUnsecured(); - submodelAPIAuthorizer.authorizeAddSubmodelElement(subjectInformationProvider.get(), aas, smId, smElIdShortPath); + final IReference smSemanticId = getSmSemanticIdUnsecured(); + submodelAPIAuthorizer.authorizeAddSubmodelElement(subjectInformationProvider.get(), aas, smId, smSemanticId, smElIdShortPath); } @Override @@ -143,7 +146,8 @@ public ISubmodelElement getSubmodelElement(final String idShortPath) { protected ISubmodelElement authorizeGetSubmodelElement(final String smElIdShortPath) throws InhibitException { final IIdentifier smId = getSmIdUnsecured(); - return submodelAPIAuthorizer.authorizeGetSubmodelElement(subjectInformationProvider.get(), aas, smId, smElIdShortPath, () -> decoratedSubmodelAPI.getSubmodelElement(smElIdShortPath)); + final IReference smSemanticId = getSmSemanticIdUnsecured(); + return submodelAPIAuthorizer.authorizeGetSubmodelElement(subjectInformationProvider.get(), aas, smId, smSemanticId, smElIdShortPath, () -> decoratedSubmodelAPI.getSubmodelElement(smElIdShortPath)); } @Override @@ -163,7 +167,8 @@ public void deleteSubmodelElement(final String idShortPath) { protected void authorizeDeleteSubmodelElement(final String smElIdShortPath) throws InhibitException { final IIdentifier smId = getSmIdUnsecured(); - submodelAPIAuthorizer.authorizeDeleteSubmodelElement(subjectInformationProvider.get(), aas, smId, smElIdShortPath); + final IReference smSemanticId = getSmSemanticIdUnsecured(); + submodelAPIAuthorizer.authorizeDeleteSubmodelElement(subjectInformationProvider.get(), aas, smId, smSemanticId, smElIdShortPath); } @Override @@ -192,7 +197,9 @@ protected Collection authorizeGetOperations() throws InhibitExceptio } private Collection getOperationListOnly() throws InhibitException { - return submodelAPIAuthorizer.authorizeGetOperations(subjectInformationProvider.get(), aas, decoratedSubmodelAPI::getSubmodel, decoratedSubmodelAPI::getOperations); + final IIdentifier smId = getSmIdUnsecured(); + final IReference smSemanticId = getSmSemanticIdUnsecured(); + return submodelAPIAuthorizer.authorizeGetOperations(subjectInformationProvider.get(), aas, smId, smSemanticId, decoratedSubmodelAPI::getSubmodel, decoratedSubmodelAPI::getOperations); } @Override @@ -221,7 +228,9 @@ protected Collection authorizeGetSubmodelElements() throws Inh } private Collection getSubmodelElementListOnly() throws InhibitException { - return submodelAPIAuthorizer.authorizeGetSubmodelElements(subjectInformationProvider.get(), aas, decoratedSubmodelAPI::getSubmodel, decoratedSubmodelAPI::getSubmodelElements); + final IIdentifier smId = getSmIdUnsecured(); + final IReference smSemanticId = getSmSemanticIdUnsecured(); + return submodelAPIAuthorizer.authorizeGetSubmodelElements(subjectInformationProvider.get(), aas, smId, smSemanticId, decoratedSubmodelAPI::getSubmodel, decoratedSubmodelAPI::getSubmodelElements); } @Override @@ -241,7 +250,8 @@ public void updateSubmodelElement(final String idShortPath, final Object newValu protected void authorizeUpdateSubmodelElement(final String smElIdShortPath) throws InhibitException { final IIdentifier smId = getSmIdUnsecured(); - submodelAPIAuthorizer.authorizeUpdateSubmodelElement(subjectInformationProvider.get(), aas, smId, smElIdShortPath); + final IReference smSemanticId = getSmSemanticIdUnsecured(); + submodelAPIAuthorizer.authorizeUpdateSubmodelElement(subjectInformationProvider.get(), aas, smId, smSemanticId, smElIdShortPath); } @Override @@ -259,7 +269,8 @@ public Object getSubmodelElementValue(final String idShortPath) { protected Object authorizeGetSubmodelElementValue(final String smElIdShortPath) throws InhibitException { final IIdentifier smId = getSmIdUnsecured(); - return submodelAPIAuthorizer.authorizeGetSubmodelElementValue(subjectInformationProvider.get(), aas, smId, smElIdShortPath, () -> decoratedSubmodelAPI.getSubmodelElementValue(smElIdShortPath)); + final IReference smSemanticId = getSmSemanticIdUnsecured(); + return submodelAPIAuthorizer.authorizeGetSubmodelElementValue(subjectInformationProvider.get(), aas, smId, smSemanticId, smElIdShortPath, () -> decoratedSubmodelAPI.getSubmodelElementValue(smElIdShortPath)); } @Override @@ -298,7 +309,8 @@ protected String fixInvokeIdShortPath(final String inputIdShortPath) { protected void authorizeInvokeOperation(final String smElIdShortPath) throws InhibitException { final IIdentifier smId = getSmIdUnsecured(); - submodelAPIAuthorizer.authorizeInvokeOperation(subjectInformationProvider.get(), aas, smId, smElIdShortPath); + final IReference smSemanticId = getSmSemanticIdUnsecured(); + submodelAPIAuthorizer.authorizeInvokeOperation(subjectInformationProvider.get(), aas, smId, smSemanticId, smElIdShortPath); } @Override @@ -316,7 +328,44 @@ public Object getOperationResult(final String smElIdShortPath, final String requ protected Object authorizeGetOperationResult(final String smElIdShortPath, final String requestId) throws InhibitException { final IIdentifier smId = getSmIdUnsecured(); - return submodelAPIAuthorizer.authorizeGetOperationResult(subjectInformationProvider.get(), aas, smId, smElIdShortPath, requestId, () -> decoratedSubmodelAPI.getOperationResult(smElIdShortPath, requestId)); + final IReference smSemanticId = getSmSemanticIdUnsecured(); + + // TODO: parameter object for the target of the operation? + // TODO: or general Target object? + // TODO: or general context object? + + return submodelAPIAuthorizer.authorizeGetOperationResult(subjectInformationProvider.get(), aas, smId, smSemanticId, smElIdShortPath, requestId, () -> decoratedSubmodelAPI.getOperationResult(smElIdShortPath, requestId)); + } + + @Override + public File getSubmodelElementFile(String idShortPath) { + if (ElevatedCodeAuthentication.isCodeAuthentication()) { + return decoratedSubmodelAPI.getSubmodelElementFile(idShortPath); + } + + try { + // TODO: maybe write own authorize method later and use its return + authorizeGetSubmodelElement(idShortPath); + return decoratedSubmodelAPI.getSubmodelElementFile(idShortPath); + } catch (final InhibitException e) { + throw new NotAuthorizedException(e); + } + } + + @Override + public void uploadSubmodelElementFile(String idShortPath, InputStream fileStream) { + if (ElevatedCodeAuthentication.isCodeAuthentication()) { + decoratedSubmodelAPI.uploadSubmodelElementFile(idShortPath, fileStream); + return; + } + + try { + // TODO: maybe write own authorize method later + authorizeUpdateSubmodelElement(idShortPath); + decoratedSubmodelAPI.uploadSubmodelElementFile(idShortPath, fileStream); + } catch (final InhibitException e) { + throw new NotAuthorizedException(e); + } } private IIdentifier getSmIdUnsecured() throws ResourceNotFoundException { @@ -329,13 +378,15 @@ private IIdentifier getSmIdUnsecured() throws ResourceNotFoundException { return sm.getIdentification(); } - @Override - public File getSubmodelElementFile(String idShortPath) { - return decoratedSubmodelAPI.getSubmodelElementFile(idShortPath); - } + private IReference getSmSemanticIdUnsecured() { + try (final ElevatedCodeAuthentication.ElevatedCodeAuthenticationAreaHandler ignored = ElevatedCodeAuthentication.enterElevatedCodeAuthenticationArea()) { + final ISubmodel sm = decoratedSubmodelAPI.getSubmodel(); - @Override - public void uploadSubmodelElementFile(String idShortPath, InputStream fileStream) { - decoratedSubmodelAPI.uploadSubmodelElementFile(idShortPath, fileStream); + if (sm == null) { + return null; + } + + return sm.getSemanticId(); + } } } diff --git a/src/main/java/org/eclipse/basyx/extensions/submodel/authorization/internal/GrantedAuthoritySubmodelAPIAuthorizer.java b/src/main/java/org/eclipse/basyx/extensions/submodel/authorization/internal/GrantedAuthoritySubmodelAPIAuthorizer.java index a22fb8c1..0ed5871f 100644 --- a/src/main/java/org/eclipse/basyx/extensions/submodel/authorization/internal/GrantedAuthoritySubmodelAPIAuthorizer.java +++ b/src/main/java/org/eclipse/basyx/extensions/submodel/authorization/internal/GrantedAuthoritySubmodelAPIAuthorizer.java @@ -32,6 +32,7 @@ import org.eclipse.basyx.extensions.shared.authorization.internal.InhibitException; import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; +import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement; import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation; @@ -48,7 +49,7 @@ public GrantedAuthoritySubmodelAPIAuthorizer(final IGrantedAuthorityAuthenticato } @Override - public Collection authorizeGetSubmodelElements(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final Supplier smSupplier, + public Collection authorizeGetSubmodelElements(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, final Supplier smSupplier, final Supplier> smElListSupplier) throws InhibitException { GrantedAuthorityHelper.checkAuthority(grantedAuthorityAuthenticator, subjectInformation, AuthorizedSubmodelAPI.READ_AUTHORITY); @@ -56,37 +57,37 @@ public Collection authorizeGetSubmodelElements(final SubjectIn } @Override - public ISubmodelElement authorizeGetSubmodelElement(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final String smElIdShortPath, - final Supplier smElSupplier) throws InhibitException { + public ISubmodelElement authorizeGetSubmodelElement(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, final String smElIdShortPath, + final Supplier smElSupplier) throws InhibitException { GrantedAuthorityHelper.checkAuthority(grantedAuthorityAuthenticator, subjectInformation, AuthorizedSubmodelAPI.READ_AUTHORITY); return smElSupplier.get(); } @Override - public ISubmodel authorizeGetSubmodel(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final Supplier smSupplier) throws InhibitException { + public ISubmodel authorizeGetSubmodel(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, final Supplier smSupplier) throws InhibitException { GrantedAuthorityHelper.checkAuthority(grantedAuthorityAuthenticator, subjectInformation, AuthorizedSubmodelAPI.READ_AUTHORITY); return smSupplier.get(); } @Override - public void authorizeAddSubmodelElement(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final String smElIdShortPath) throws InhibitException { + public void authorizeAddSubmodelElement(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, final String smElIdShortPath) throws InhibitException { GrantedAuthorityHelper.checkAuthority(grantedAuthorityAuthenticator, subjectInformation, AuthorizedSubmodelAPI.WRITE_AUTHORITY); } @Override - public void authorizeDeleteSubmodelElement(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final String smElIdShortPath) throws InhibitException { + public void authorizeDeleteSubmodelElement(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, final String smElIdShortPath) throws InhibitException { GrantedAuthorityHelper.checkAuthority(grantedAuthorityAuthenticator, subjectInformation, AuthorizedSubmodelAPI.WRITE_AUTHORITY); } @Override - public void authorizeUpdateSubmodelElement(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final String smElIdShortPath) throws InhibitException { + public void authorizeUpdateSubmodelElement(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, final String smElIdShortPath) throws InhibitException { GrantedAuthorityHelper.checkAuthority(grantedAuthorityAuthenticator, subjectInformation, AuthorizedSubmodelAPI.WRITE_AUTHORITY); } @Override - public Object authorizeGetSubmodelElementValue(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final String smElIdShortPath, final Supplier valueSupplier) + public Object authorizeGetSubmodelElementValue(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, final String smElIdShortPath, final Supplier valueSupplier) throws InhibitException { GrantedAuthorityHelper.checkAuthority(grantedAuthorityAuthenticator, subjectInformation, AuthorizedSubmodelAPI.READ_AUTHORITY); @@ -94,7 +95,7 @@ public Object authorizeGetSubmodelElementValue(final SubjectInformationType subj } @Override - public Collection authorizeGetOperations(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final Supplier smSupplier, + public Collection authorizeGetOperations(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, final Supplier smSupplier, final Supplier> operationListSupplier) throws InhibitException { GrantedAuthorityHelper.checkAuthority(grantedAuthorityAuthenticator, subjectInformation, AuthorizedSubmodelAPI.READ_AUTHORITY); @@ -102,12 +103,12 @@ public Collection authorizeGetOperations(final SubjectInformationTyp } @Override - public void authorizeInvokeOperation(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final String smElIdShortPath) throws InhibitException { + public void authorizeInvokeOperation(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, final String smElIdShortPath) throws InhibitException { GrantedAuthorityHelper.checkAuthority(grantedAuthorityAuthenticator, subjectInformation, AuthorizedSubmodelAPI.EXECUTE_AUTHORITY); } @Override - public Object authorizeGetOperationResult(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final String smElIdShortPath, final String requestId, + public Object authorizeGetOperationResult(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, final String smElIdShortPath, final String requestId, final Supplier operationResultSupplier) throws InhibitException { GrantedAuthorityHelper.checkAuthority(grantedAuthorityAuthenticator, subjectInformation, AuthorizedSubmodelAPI.READ_AUTHORITY); diff --git a/src/main/java/org/eclipse/basyx/extensions/submodel/authorization/internal/ISubmodelAPIAuthorizer.java b/src/main/java/org/eclipse/basyx/extensions/submodel/authorization/internal/ISubmodelAPIAuthorizer.java index ab9937a6..f6a1bf4b 100644 --- a/src/main/java/org/eclipse/basyx/extensions/submodel/authorization/internal/ISubmodelAPIAuthorizer.java +++ b/src/main/java/org/eclipse/basyx/extensions/submodel/authorization/internal/ISubmodelAPIAuthorizer.java @@ -30,6 +30,7 @@ import org.eclipse.basyx.extensions.shared.authorization.internal.InhibitException; import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; +import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement; import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation; import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI; @@ -48,6 +49,10 @@ public interface ISubmodelAPIAuthorizer { * @param aas * the aas the submodel belongs to as passed in the constructor of * {@link AuthorizedSubmodelAPI}, may be null. + * @param smId + * id of the submodel. + * @param smSemanticId + * semantic id of the submodel. * @param smSupplier * supplier for the submodel. * @param smElListSupplier @@ -56,8 +61,8 @@ public interface ISubmodelAPIAuthorizer { * @throws InhibitException * if authorization failed */ - public Collection authorizeGetSubmodelElements(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final Supplier smSupplier, - final Supplier> smElListSupplier) throws InhibitException; + public Collection authorizeGetSubmodelElements(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, + final Supplier smSupplier, final Supplier> smElListSupplier) throws InhibitException; /** * Checks authorization for {@link ISubmodelAPI#getSubmodelElement(String)}. @@ -69,6 +74,8 @@ public Collection authorizeGetSubmodelElements(final SubjectIn * {@link AuthorizedSubmodelAPI}, may be null. * @param smId * id of the submodel. + * @param smSemanticId + * semantic id of the submodel. * @param smElIdShortPath * short path id of the submodel element. * @param smElSupplier @@ -77,7 +84,7 @@ public Collection authorizeGetSubmodelElements(final SubjectIn * @throws InhibitException * if authorization failed */ - public ISubmodelElement authorizeGetSubmodelElement(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final String smElIdShortPath, + public ISubmodelElement authorizeGetSubmodelElement(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, final String smElIdShortPath, final Supplier smElSupplier) throws InhibitException; /** @@ -90,13 +97,16 @@ public ISubmodelElement authorizeGetSubmodelElement(final SubjectInformationType * {@link AuthorizedSubmodelAPI}, may be null. * @param smId * id of the submodel. + * @param smSemanticId + * semantic id of the submodel. * @param smSupplier * supplier for the submodel. * @return the authorized submodel. * @throws InhibitException * if authorization failed */ - public ISubmodel authorizeGetSubmodel(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final Supplier smSupplier) throws InhibitException; + public ISubmodel authorizeGetSubmodel(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, final Supplier smSupplier) + throws InhibitException; /** * Checks authorization for @@ -109,12 +119,14 @@ public ISubmodelElement authorizeGetSubmodelElement(final SubjectInformationType * {@link AuthorizedSubmodelAPI}, may be null. * @param smId * id of the submodel. + * @param smSemanticId + * semantic id of the submodel. * @param smElIdShortPath * short path id of the submodel element. * @throws InhibitException * if authorization failed */ - public void authorizeAddSubmodelElement(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final String smElIdShortPath) throws InhibitException; + public void authorizeAddSubmodelElement(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, final String smElIdShortPath) throws InhibitException; /** * Checks authorization for {@link ISubmodelAPI#deleteSubmodelElement(String)}. @@ -126,12 +138,15 @@ public ISubmodelElement authorizeGetSubmodelElement(final SubjectInformationType * {@link AuthorizedSubmodelAPI}, may be null. * @param smId * id of the submodel. + * @param smSemanticId + * semantic id of the submodel. * @param smElIdShortPath * short path id of the submodel element. * @throws InhibitException * if authorization failed */ - public void authorizeDeleteSubmodelElement(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final String smElIdShortPath) throws InhibitException; + public void authorizeDeleteSubmodelElement(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, final String smElIdShortPath) + throws InhibitException; /** * Checks authorization for @@ -144,12 +159,15 @@ public ISubmodelElement authorizeGetSubmodelElement(final SubjectInformationType * {@link AuthorizedSubmodelAPI}, may be null. * @param smId * id of the submodel. + * @param smSemanticId + * semantic id of the submodel. * @param smElIdShortPath * short path id of the submodel element. * @throws InhibitException * if authorization failed */ - public void authorizeUpdateSubmodelElement(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final String smElIdShortPath) throws InhibitException; + public void authorizeUpdateSubmodelElement(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, final String smElIdShortPath) + throws InhibitException; /** * Checks authorization for @@ -162,6 +180,8 @@ public ISubmodelElement authorizeGetSubmodelElement(final SubjectInformationType * {@link AuthorizedSubmodelAPI}, may be null. * @param smId * id of the submodel. + * @param smSemanticId + * semantic id of the submodel. * @param smElIdShortPath * short path id of the submodel element. * @param valueSupplier @@ -170,8 +190,8 @@ public ISubmodelElement authorizeGetSubmodelElement(final SubjectInformationType * @throws InhibitException * if authorization failed */ - public Object authorizeGetSubmodelElementValue(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final String smElIdShortPath, final Supplier valueSupplier) - throws InhibitException; + public Object authorizeGetSubmodelElementValue(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, final String smElIdShortPath, + final Supplier valueSupplier) throws InhibitException; /** * Checks authorization for {@link ISubmodelAPI#getOperations()}. @@ -181,6 +201,10 @@ public Object authorizeGetSubmodelElementValue(final SubjectInformationType subj * @param aas * the aas the submodel belongs to as passed in the constructor of * {@link AuthorizedSubmodelAPI}, may be null. + * @param smId + * id of the submodel. + * @param smSemanticId + * semantic id of the submodel. * @param smSupplier * supplier for the submodel. * @param operationListSupplier @@ -189,7 +213,7 @@ public Object authorizeGetSubmodelElementValue(final SubjectInformationType subj * @throws InhibitException * if authorization failed */ - public Collection authorizeGetOperations(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final Supplier smSupplier, + public Collection authorizeGetOperations(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, final Supplier smSupplier, final Supplier> operationListSupplier) throws InhibitException; /** @@ -204,12 +228,14 @@ public Collection authorizeGetOperations(final SubjectInformationTyp * {@link AuthorizedSubmodelAPI}, may be null. * @param smId * id of the submodel. + * @param smSemanticId + * semantic id of the submodel. * @param smElIdShortPath * short path id of the submodel element. * @throws InhibitException * if authorization failed */ - public void authorizeInvokeOperation(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final String smElIdShortPath) throws InhibitException; + public void authorizeInvokeOperation(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, final String smElIdShortPath) throws InhibitException; /** * Checks authorization for @@ -222,6 +248,8 @@ public Collection authorizeGetOperations(final SubjectInformationTyp * {@link AuthorizedSubmodelAPI}, may be null. * @param smId * id of the submodel. + * @param smSemanticId + * semantic id of the submodel. * @param smElIdShortPath * short path id of the submodel element. * @param requestId @@ -232,6 +260,6 @@ public Collection authorizeGetOperations(final SubjectInformationTyp * @throws InhibitException * if authorization failed */ - public Object authorizeGetOperationResult(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final String smElIdShortPath, final String requestId, + public Object authorizeGetOperationResult(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, final String smElIdShortPath, final String requestId, final Supplier operationResultSupplier) throws InhibitException; } diff --git a/src/main/java/org/eclipse/basyx/extensions/submodel/authorization/internal/SimpleRbacSubmodelAPIAuthorizer.java b/src/main/java/org/eclipse/basyx/extensions/submodel/authorization/internal/SimpleRbacSubmodelAPIAuthorizer.java index c0eef496..a587957f 100644 --- a/src/main/java/org/eclipse/basyx/extensions/submodel/authorization/internal/SimpleRbacSubmodelAPIAuthorizer.java +++ b/src/main/java/org/eclipse/basyx/extensions/submodel/authorization/internal/SimpleRbacSubmodelAPIAuthorizer.java @@ -24,23 +24,18 @@ ******************************************************************************/ package org.eclipse.basyx.extensions.submodel.authorization.internal; -import java.util.Collection; -import java.util.function.Supplier; import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell; -import org.eclipse.basyx.extensions.shared.authorization.internal.BaSyxObjectTargetInformation; -import org.eclipse.basyx.extensions.shared.authorization.internal.ElevatedCodeAuthentication; -import org.eclipse.basyx.extensions.shared.authorization.internal.ElevatedCodeAuthentication.ElevatedCodeAuthenticationAreaHandler; -import org.eclipse.basyx.extensions.shared.authorization.internal.IRbacRuleChecker; -import org.eclipse.basyx.extensions.shared.authorization.internal.IdHelper; -import org.eclipse.basyx.extensions.shared.authorization.internal.InhibitException; -import org.eclipse.basyx.extensions.shared.authorization.internal.IRoleAuthenticator; -import org.eclipse.basyx.extensions.shared.authorization.internal.SimpleRbacHelper; +import org.eclipse.basyx.extensions.shared.authorization.internal.*; import org.eclipse.basyx.extensions.submodel.authorization.SubmodelAPIScopes; import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; +import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement; import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation; +import java.util.Collection; +import java.util.function.Supplier; + /** * Simple role based implementation for {@link ISubmodelAPIAuthorizer}. * @@ -56,90 +51,88 @@ public SimpleRbacSubmodelAPIAuthorizer(final IRbacRuleChecker rbacRuleChecker, f } @Override - public Collection authorizeGetSubmodelElements(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final Supplier smSupplier, + public Collection authorizeGetSubmodelElements(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, final Supplier smSupplier, final Supplier> smElListSupplier) throws InhibitException { final IIdentifier aasId = getAasId(aas); - final IIdentifier smId = getSmIdUnsecured(smSupplier); - SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, SubmodelAPIScopes.READ_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), null)); + SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, SubmodelAPIScopes.READ_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), IdHelper.getReferenceId(smSemanticId), null)); return smElListSupplier.get(); } @Override - public ISubmodelElement authorizeGetSubmodelElement(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final String smElIdShortPath, + public ISubmodelElement authorizeGetSubmodelElement(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, final String smElIdShortPath, final Supplier smElSupplier) throws InhibitException { final IIdentifier aasId = getAasId(aas); - SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, SubmodelAPIScopes.READ_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), smElIdShortPath)); + SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, SubmodelAPIScopes.READ_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), IdHelper.getReferenceId(smSemanticId), smElIdShortPath)); return smElSupplier.get(); } @Override - public ISubmodel authorizeGetSubmodel(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final Supplier smSupplier) throws InhibitException { + public ISubmodel authorizeGetSubmodel(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, final Supplier smSupplier) throws InhibitException { final IIdentifier aasId = getAasId(aas); - SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, SubmodelAPIScopes.READ_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), null)); + SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, SubmodelAPIScopes.READ_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), IdHelper.getReferenceId(smSemanticId), null)); return smSupplier.get(); } @Override - public void authorizeAddSubmodelElement(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final String smElIdShortPath) throws InhibitException { + public void authorizeAddSubmodelElement(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, final String smElIdShortPath) throws InhibitException { final IIdentifier aasId = getAasId(aas); - SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, SubmodelAPIScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), smElIdShortPath)); + SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, SubmodelAPIScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), IdHelper.getReferenceId(smSemanticId), smElIdShortPath)); } @Override - public void authorizeDeleteSubmodelElement(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final String smElIdShortPath) throws InhibitException { + public void authorizeDeleteSubmodelElement(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, final String smElIdShortPath) throws InhibitException { final IIdentifier aasId = getAasId(aas); - SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, SubmodelAPIScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), smElIdShortPath)); + SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, SubmodelAPIScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), IdHelper.getReferenceId(smSemanticId), smElIdShortPath)); } @Override - public void authorizeUpdateSubmodelElement(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final String smElIdShortPath) throws InhibitException { + public void authorizeUpdateSubmodelElement(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, final String smElIdShortPath) throws InhibitException { final IIdentifier aasId = getAasId(aas); - SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, SubmodelAPIScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), smElIdShortPath)); + SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, SubmodelAPIScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), IdHelper.getReferenceId(smSemanticId), smElIdShortPath)); } @Override - public Object authorizeGetSubmodelElementValue(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final String smElIdShortPath, final Supplier valueSupplier) + public Object authorizeGetSubmodelElementValue(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, final String smElIdShortPath, final Supplier valueSupplier) throws InhibitException { final IIdentifier aasId = getAasId(aas); - SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, SubmodelAPIScopes.READ_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), smElIdShortPath)); + SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, SubmodelAPIScopes.READ_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), IdHelper.getReferenceId(smSemanticId), smElIdShortPath)); return valueSupplier.get(); } @Override - public Collection authorizeGetOperations(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final Supplier smSupplier, + public Collection authorizeGetOperations(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, final Supplier smSupplier, final Supplier> operationListSupplier) throws InhibitException { final IIdentifier aasId = getAasId(aas); - final IIdentifier smId = getSmIdUnsecured(smSupplier); - SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, SubmodelAPIScopes.READ_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), null)); + SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, SubmodelAPIScopes.READ_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), IdHelper.getReferenceId(smSemanticId), null)); return operationListSupplier.get(); } @Override - public void authorizeInvokeOperation(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final String smElIdShortPath) throws InhibitException { + public void authorizeInvokeOperation(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, final String smElIdShortPath) throws InhibitException { final IIdentifier aasId = getAasId(aas); - SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, SubmodelAPIScopes.EXECUTE_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), smElIdShortPath)); + SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, SubmodelAPIScopes.EXECUTE_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), IdHelper.getReferenceId(smSemanticId), smElIdShortPath)); } @Override - public Object authorizeGetOperationResult(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final String smElIdShortPath, final String requestId, + public Object authorizeGetOperationResult(final SubjectInformationType subjectInformation, final IAssetAdministrationShell aas, final IIdentifier smId, final IReference smSemanticId, final String smElIdShortPath, final String requestId, final Supplier operationResultSupplier) throws InhibitException { final IIdentifier aasId = getAasId(aas); - SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, SubmodelAPIScopes.READ_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), smElIdShortPath)); + SimpleRbacHelper.checkRule(rbacRuleChecker, roleAuthenticator, subjectInformation, SubmodelAPIScopes.READ_SCOPE, new BaSyxObjectTargetInformation(IdHelper.getIdentifierId(aasId), IdHelper.getIdentifierId(smId), IdHelper.getReferenceId(smSemanticId), smElIdShortPath)); return operationResultSupplier.get(); } @@ -147,16 +140,4 @@ public Object authorizeGetOperationResult(final SubjectInformationType subjectIn private IIdentifier getAasId(final IAssetAdministrationShell aas) { return aas != null ? aas.getIdentification() : null; } - - private IIdentifier getSmIdUnsecured(final Supplier smSupplier) { - try (final ElevatedCodeAuthenticationAreaHandler ignored = ElevatedCodeAuthentication.enterElevatedCodeAuthenticationArea()) { - final ISubmodel sm = smSupplier.get(); - - if (sm == null) { - return null; - } - - return sm.getIdentification(); - } - } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/aggregator/authorization/internal/TestSimpleRbacAuthorizedAASAggregator.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/aggregator/authorization/internal/TestSimpleRbacAuthorizedAASAggregator.java index ec4971aa..37153eac 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/aggregator/authorization/internal/TestSimpleRbacAuthorizedAASAggregator.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/aggregator/authorization/internal/TestSimpleRbacAuthorizedAASAggregator.java @@ -89,10 +89,10 @@ public class TestSimpleRbacAuthorizedAASAggregator { @Before public void setUp() { - rbacRuleSet.addRule(new RbacRule(adminRole, AASAggregatorScopes.READ_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*"))); - rbacRuleSet.addRule(new RbacRule(adminRole, AASAggregatorScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*"))); - rbacRuleSet.addRule(new RbacRule(readerRole, AASAggregatorScopes.READ_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*"))); - rbacRuleSet.addRule(new RbacRule(partialReaderRole, AASAggregatorScopes.READ_SCOPE, new BaSyxObjectTargetInformation(SHELL_IDENTIFIER.getId(), "*", "*"))); + rbacRuleSet.addRule(new RbacRule(adminRole, AASAggregatorScopes.READ_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*", "*"))); + rbacRuleSet.addRule(new RbacRule(adminRole, AASAggregatorScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*", "*"))); + rbacRuleSet.addRule(new RbacRule(readerRole, AASAggregatorScopes.READ_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*", "*"))); + rbacRuleSet.addRule(new RbacRule(partialReaderRole, AASAggregatorScopes.READ_SCOPE, new BaSyxObjectTargetInformation(SHELL_IDENTIFIER.getId(), "*", "*", "*"))); testSubject = new AuthorizedAASAggregator<>(apiMock, new SimpleRbacAASAggregatorAuthorizer<>(new PredefinedSetRbacRuleChecker(rbacRuleSet), new KeycloakRoleAuthenticator()), new JWTAuthenticationContextProvider()); shell = new AssetAdministrationShell(SHELL_ID, SHELL_IDENTIFIER, SHELL_ASSET); secondShell = new AssetAdministrationShell(SECOND_SHELL_ID, SECOND_SHELL_IDENTIFIER, SECOND_SHELL_ASSET); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/api/authorization/internal/TestSimpleRbacAuthorizedAASAPI.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/api/authorization/internal/TestSimpleRbacAuthorizedAASAPI.java index 678d1a1f..c266dfe9 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/api/authorization/internal/TestSimpleRbacAuthorizedAASAPI.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/api/authorization/internal/TestSimpleRbacAuthorizedAASAPI.java @@ -83,9 +83,9 @@ public class TestSimpleRbacAuthorizedAASAPI { @Before public void setUp() { - rbacRuleSet.addRule(new RbacRule(adminRole, AASAPIScopes.READ_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*"))); - rbacRuleSet.addRule(new RbacRule(adminRole, AASAPIScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*"))); - rbacRuleSet.addRule(new RbacRule(readerRole, AASAPIScopes.READ_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*"))); + rbacRuleSet.addRule(new RbacRule(adminRole, AASAPIScopes.READ_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*", "*"))); + rbacRuleSet.addRule(new RbacRule(adminRole, AASAPIScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*", "*"))); + rbacRuleSet.addRule(new RbacRule(readerRole, AASAPIScopes.READ_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*", "*"))); testSubject = new AuthorizedAASAPI<>(apiMock, new SimpleRbacAASAPIAuthorizer<>(new PredefinedSetRbacRuleChecker(rbacRuleSet), new KeycloakRoleAuthenticator()), new JWTAuthenticationContextProvider()); shell = new AssetAdministrationShell(SHELL_ID, SHELL_IDENTIFIER, SHELL_ASSET); submodel = new Submodel(SUBMODEL_ID, SUBMODEL_IDENTIFIER); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/authorized/internal/TestSimpleRbacAuthorizedTaggedDirectory.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/authorized/internal/TestSimpleRbacAuthorizedTaggedDirectory.java index 44bcf3b2..91f6c579 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/authorized/internal/TestSimpleRbacAuthorizedTaggedDirectory.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/authorized/internal/TestSimpleRbacAuthorizedTaggedDirectory.java @@ -92,9 +92,9 @@ public class TestSimpleRbacAuthorizedTaggedDirectory { @Before public void setUp() { - rbacRuleSet.addRule(new RbacRule(adminRole, AASRegistryScopes.READ_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*"))); - rbacRuleSet.addRule(new RbacRule(adminRole, AASRegistryScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*"))); - rbacRuleSet.addRule(new RbacRule(readerRole, AASRegistryScopes.READ_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*"))); + rbacRuleSet.addRule(new RbacRule(adminRole, AASRegistryScopes.READ_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*", "*"))); + rbacRuleSet.addRule(new RbacRule(adminRole, AASRegistryScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*", "*"))); + rbacRuleSet.addRule(new RbacRule(readerRole, AASRegistryScopes.READ_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*", "*"))); rbacRuleSet.addRule(new RbacRule(readerRole, AASRegistryScopes.READ_SCOPE, new TagTargetInformation("*"))); testSubject = new AuthorizedTaggedDirectory<>(apiMock, new SimpleRbacTaggedDirectoryAuthorizer<>(new PredefinedSetRbacRuleChecker(rbacRuleSet), new KeycloakRoleAuthenticator()), new JWTAuthenticationContextProvider()); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/registration/authorization/internal/TestGrantedAuthorityAuthorizedAASRegistry.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/registration/authorization/internal/TestGrantedAuthorityAuthorizedAASRegistry.java index 00e77a9f..e48c0f3f 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/registration/authorization/internal/TestGrantedAuthorityAuthorizedAASRegistry.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/registration/authorization/internal/TestGrantedAuthorityAuthorizedAASRegistry.java @@ -159,6 +159,7 @@ public void givenPrincipalIsMissingWriteAuthority_whenDeleteAAS_thenThrowNotAuth @Test public void givenPrincipalHasWriteAuthority_whenDeleteSubmodel_thenInvocationIsForwarded() { SecurityContextHolder.setContext(getSecurityContextWithWriteAuthority()); + Mockito.when(apiMock.lookupSubmodel(SHELL_IDENTIFIER, SUBMODEL_IDENTIFIER)).thenReturn(smDescriptor); testSubject.delete(SHELL_IDENTIFIER, SUBMODEL_IDENTIFIER); Mockito.verify(apiMock).delete(SHELL_IDENTIFIER, SUBMODEL_IDENTIFIER); @@ -167,6 +168,7 @@ public void givenPrincipalHasWriteAuthority_whenDeleteSubmodel_thenInvocationIsF @Test(expected = NotAuthorizedException.class) public void givenPrincipalIsMissingWriteAuthority_whenDeleteSubmodel_thenThrowNotAuthorized() { SecurityContextHolder.setContext(getSecurityContextWithoutAuthorities()); + Mockito.when(apiMock.lookupSubmodel(SHELL_IDENTIFIER, SUBMODEL_IDENTIFIER)).thenReturn(smDescriptor); testSubject.delete(SHELL_IDENTIFIER, SUBMODEL_IDENTIFIER); } @@ -237,6 +239,7 @@ public void givenPrincipalHasReadAuthority_whenLookupSubmodel_thenInvocationIsFo @Test(expected = NotAuthorizedException.class) public void givenPrincipalIsMissingReadAuthority_whenLookupSubmodel_thenThrowNotAuthorized() { SecurityContextHolder.setContext(getSecurityContextWithoutAuthorities()); + Mockito.when(apiMock.lookupSubmodel(SHELL_IDENTIFIER, SUBMODEL_IDENTIFIER)).thenReturn(smDescriptor); testSubject.lookupSubmodel(SHELL_IDENTIFIER, SUBMODEL_IDENTIFIER); } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/registration/authorization/internal/TestSimpleRbacAuthorizedAASRegistry.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/registration/authorization/internal/TestSimpleRbacAuthorizedAASRegistry.java index c946535a..eaad0beb 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/registration/authorization/internal/TestSimpleRbacAuthorizedAASRegistry.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/registration/authorization/internal/TestSimpleRbacAuthorizedAASRegistry.java @@ -86,10 +86,10 @@ public class TestSimpleRbacAuthorizedAASRegistry { @Before public void setUp() { - rbacRuleSet.addRule(new RbacRule(adminRole, AASRegistryScopes.READ_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*"))); - rbacRuleSet.addRule(new RbacRule(adminRole, AASRegistryScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*"))); - rbacRuleSet.addRule(new RbacRule(readerRole, AASRegistryScopes.READ_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*"))); - rbacRuleSet.addRule(new RbacRule(partialReaderRole, AASRegistryScopes.READ_SCOPE, new BaSyxObjectTargetInformation(SHELL_IDENTIFIER.getId(), SUBMODEL_IDENTIFIER.getId(), "*"))); + rbacRuleSet.addRule(new RbacRule(adminRole, AASRegistryScopes.READ_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*", "*"))); + rbacRuleSet.addRule(new RbacRule(adminRole, AASRegistryScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*", "*"))); + rbacRuleSet.addRule(new RbacRule(readerRole, AASRegistryScopes.READ_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*", "*"))); + rbacRuleSet.addRule(new RbacRule(partialReaderRole, AASRegistryScopes.READ_SCOPE, new BaSyxObjectTargetInformation(SHELL_IDENTIFIER.getId(), SUBMODEL_IDENTIFIER.getId(), "*", "*"))); testSubject = new AuthorizedAASRegistry<>(apiMock, new SimpleRbacAASRegistryAuthorizer<>(new PredefinedSetRbacRuleChecker(rbacRuleSet), new KeycloakRoleAuthenticator()), new JWTAuthenticationContextProvider()); aasDescriptor = new AASDescriptor(SHELL_ID, SHELL_IDENTIFIER, ""); smDescriptor = new SubmodelDescriptor(SUBMODEL_ID, SUBMODEL_IDENTIFIER, ""); @@ -158,6 +158,7 @@ public void givenPrincipalIsMissingWriteAuthority_whenDeleteAAS_thenThrowNotAuth @Test public void givenPrincipalHasWriteAuthority_whenDeleteSubmodel_thenInvocationIsForwarded() { securityContextProvider.setSecurityContextWithRoles(adminRole); + Mockito.when(apiMock.lookupSubmodel(SHELL_IDENTIFIER, SUBMODEL_IDENTIFIER)).thenReturn(smDescriptor); testSubject.delete(SHELL_IDENTIFIER, SUBMODEL_IDENTIFIER); Mockito.verify(apiMock).delete(SHELL_IDENTIFIER, SUBMODEL_IDENTIFIER); @@ -166,6 +167,7 @@ public void givenPrincipalHasWriteAuthority_whenDeleteSubmodel_thenInvocationIsF @Test(expected = NotAuthorizedException.class) public void givenPrincipalIsMissingWriteAuthority_whenDeleteSubmodel_thenThrowNotAuthorized() { securityContextProvider.setSecurityContextWithoutRoles(); + Mockito.when(apiMock.lookupSubmodel(SHELL_IDENTIFIER, SUBMODEL_IDENTIFIER)).thenReturn(smDescriptor); testSubject.delete(SHELL_IDENTIFIER, SUBMODEL_IDENTIFIER); } @@ -240,6 +242,7 @@ public void givenPrincipalHasPartialReadAuthority_whenLookupSubmodels_thenInvoca final List expectedSubmodelDescriptorList = Collections.singletonList(smDescriptor); Mockito.when(apiMock.lookupSubmodels(SHELL_IDENTIFIER)).thenReturn(Arrays.asList(smDescriptor, secondSmDescriptor)); Mockito.when(apiMock.lookupSubmodel(SHELL_IDENTIFIER, SUBMODEL_IDENTIFIER)).thenReturn(smDescriptor); + Mockito.when(apiMock.lookupSubmodel(SHELL_IDENTIFIER, SECOND_SUBMODEL_IDENTIFIER)).thenReturn(secondSmDescriptor); final List returnedSubmodelDescriptorList = testSubject.lookupSubmodels(SHELL_IDENTIFIER); Assert.assertEquals(expectedSubmodelDescriptorList, returnedSubmodelDescriptorList); @@ -258,6 +261,7 @@ public void givenPrincipalHasReadAuthority_whenLookupSubmodel_thenInvocationIsFo @Test(expected = NotAuthorizedException.class) public void givenPrincipalIsMissingReadAuthority_whenLookupSubmodel_thenThrowNotAuthorized() { securityContextProvider.setSecurityContextWithoutRoles(); + Mockito.when(apiMock.lookupSubmodel(SHELL_IDENTIFIER, SUBMODEL_IDENTIFIER)).thenReturn(smDescriptor); testSubject.lookupSubmodel(SHELL_IDENTIFIER, SUBMODEL_IDENTIFIER); } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/shared/internal/TestPredefinedSetRbacRuleChecker.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/shared/internal/TestPredefinedSetRbacRuleChecker.java index 792571cf..77fdd64f 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/shared/internal/TestPredefinedSetRbacRuleChecker.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/shared/internal/TestPredefinedSetRbacRuleChecker.java @@ -57,7 +57,7 @@ public class TestPredefinedSetRbacRuleChecker { public void givenNothing_whenCheckForRuleNull$Null$NullNullNull_thenReturnFalse() { final PredefinedSetRbacRuleChecker testSubject = new PredefinedSetRbacRuleChecker(new RbacRuleSet()); - final boolean result = testSubject.checkRbacRuleIsSatisfied(null, null, new BaSyxObjectTargetInformation(null, null, null)); + final boolean result = testSubject.checkRbacRuleIsSatisfied(null, null, new BaSyxObjectTargetInformation(null, null, null, null)); Assert.assertFalse(result); } @@ -66,7 +66,7 @@ public class TestPredefinedSetRbacRuleChecker { public void givenNothing_whenCheckForRuleEmpty$Null$NullNullNull_thenReturnFalse() { final PredefinedSetRbacRuleChecker testSubject = new PredefinedSetRbacRuleChecker(rbacRuleSet); - final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.emptyList(), null, new BaSyxObjectTargetInformation(null, null, null)); + final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.emptyList(), null, new BaSyxObjectTargetInformation(null, null, null, null)); Assert.assertFalse(result); } @@ -75,11 +75,11 @@ public class TestPredefinedSetRbacRuleChecker { public void givenRuleAdmin$Empty$NullNullNull_whenCheckForRuleEmpty$Null$NullNullNull_thenReturnFalse() { final RbacRuleSet rbacRuleSet = new RbacRuleSet(); - rbacRuleSet.addRule(new RbacRule(adminRole, "", new BaSyxObjectTargetInformation(null, null, null))); + rbacRuleSet.addRule(new RbacRule(adminRole, "", new BaSyxObjectTargetInformation(null, null, null, null))); final PredefinedSetRbacRuleChecker testSubject = new PredefinedSetRbacRuleChecker(rbacRuleSet); - final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.emptyList(), null, new BaSyxObjectTargetInformation(null, null, null)); + final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.emptyList(), null, new BaSyxObjectTargetInformation(null, null, null, null)); Assert.assertFalse(result); } @@ -88,11 +88,11 @@ public class TestPredefinedSetRbacRuleChecker { public void givenRuleAdmin$Empty$NullNullNull_whenCheckForRuleAdmin$Null$NullNullNull_thenReturnFalse() { final RbacRuleSet rbacRuleSet = new RbacRuleSet(); - rbacRuleSet.addRule(new RbacRule(adminRole, "", new BaSyxObjectTargetInformation(null, null, null))); + rbacRuleSet.addRule(new RbacRule(adminRole, "", new BaSyxObjectTargetInformation(null, null, null, null))); final PredefinedSetRbacRuleChecker testSubject = new PredefinedSetRbacRuleChecker(rbacRuleSet); - final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), null, new BaSyxObjectTargetInformation(null, null, null)); + final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), null, new BaSyxObjectTargetInformation(null, null, null, null)); Assert.assertFalse(result); } @@ -101,11 +101,11 @@ public class TestPredefinedSetRbacRuleChecker { public void givenRuleAdmin$Empty$NullNullNull_whenCheckForRuleAdmin$Read$SomSomeSome_thenReturnFalse() { final RbacRuleSet rbacRuleSet = new RbacRuleSet(); - rbacRuleSet.addRule(new RbacRule(adminRole, "", new BaSyxObjectTargetInformation(null, null, null))); + rbacRuleSet.addRule(new RbacRule(adminRole, "", new BaSyxObjectTargetInformation(null, null, null, null))); final PredefinedSetRbacRuleChecker testSubject = new PredefinedSetRbacRuleChecker(rbacRuleSet); - final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), readAction, new BaSyxObjectTargetInformation(someId, someId, someId)); + final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), readAction, new BaSyxObjectTargetInformation(someId, someId, someId, someId)); Assert.assertFalse(result); } @@ -114,11 +114,11 @@ public class TestPredefinedSetRbacRuleChecker { public void givenRuleAdmin$Read$SomeSomeSome_whenCheckForRuleAdmin$Read$SomeSomeSome_thenReturnTrue() { final RbacRuleSet rbacRuleSet = new RbacRuleSet(); - rbacRuleSet.addRule(new RbacRule(adminRole, readAction, new BaSyxObjectTargetInformation(someId, someId, someId))); + rbacRuleSet.addRule(new RbacRule(adminRole, readAction, new BaSyxObjectTargetInformation(someId, someId, someId, someId))); final PredefinedSetRbacRuleChecker testSubject = new PredefinedSetRbacRuleChecker(rbacRuleSet); - final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), readAction, new BaSyxObjectTargetInformation(someId, someId, someId)); + final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), readAction, new BaSyxObjectTargetInformation(someId, someId, someId, someId)); Assert.assertTrue(result); } @@ -127,11 +127,11 @@ public class TestPredefinedSetRbacRuleChecker { public void givenRuleAdmin$Read$SomeSomeSome_whenCheckForRuleNormal$Read$SomeSomeSome_thenReturnFalse() { final RbacRuleSet rbacRuleSet = new RbacRuleSet(); - rbacRuleSet.addRule(new RbacRule(adminRole, readAction, new BaSyxObjectTargetInformation(someId, someId, someId))); + rbacRuleSet.addRule(new RbacRule(adminRole, readAction, new BaSyxObjectTargetInformation(someId, someId, someId, someId))); final PredefinedSetRbacRuleChecker testSubject = new PredefinedSetRbacRuleChecker(rbacRuleSet); - final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(normalRole), readAction, new BaSyxObjectTargetInformation(someId, someId, someId)); + final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(normalRole), readAction, new BaSyxObjectTargetInformation(someId, someId, someId, someId)); Assert.assertFalse(result); } @@ -140,11 +140,11 @@ public class TestPredefinedSetRbacRuleChecker { public void givenRuleAdmin$Read$SomeSomeSome_whenCheckForRuleAdmin$Write$SomeSomeSome_thenReturnFalse() { final RbacRuleSet rbacRuleSet = new RbacRuleSet(); - rbacRuleSet.addRule(new RbacRule(adminRole, readAction, new BaSyxObjectTargetInformation(someId, someId, someId))); + rbacRuleSet.addRule(new RbacRule(adminRole, readAction, new BaSyxObjectTargetInformation(someId, someId, someId, someId))); final PredefinedSetRbacRuleChecker testSubject = new PredefinedSetRbacRuleChecker(rbacRuleSet); - final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), writeAction, new BaSyxObjectTargetInformation(someId, someId, someId)); + final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), writeAction, new BaSyxObjectTargetInformation(someId, someId, someId, someId)); Assert.assertFalse(result); } @@ -153,11 +153,11 @@ public class TestPredefinedSetRbacRuleChecker { public void givenRuleAdmin$Write$SomeSomeSome_whenCheckForRuleAdmin$Write$OtherSomeSome_thenReturnFalse() { final RbacRuleSet rbacRuleSet = new RbacRuleSet(); - rbacRuleSet.addRule(new RbacRule(adminRole, writeAction, new BaSyxObjectTargetInformation(someId, someId, someId))); + rbacRuleSet.addRule(new RbacRule(adminRole, writeAction, new BaSyxObjectTargetInformation(someId, someId, someId, someId))); final PredefinedSetRbacRuleChecker testSubject = new PredefinedSetRbacRuleChecker(rbacRuleSet); - final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), writeAction, new BaSyxObjectTargetInformation(otherId, someId, someId)); + final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), writeAction, new BaSyxObjectTargetInformation(otherId, someId, someId, someId)); Assert.assertFalse(result); } @@ -166,11 +166,11 @@ public class TestPredefinedSetRbacRuleChecker { public void givenRuleAdmin$Write$AnySomeSome_whenCheckForRuleAdmin$Write$OtherSomeSome_thenReturnTrue() { final RbacRuleSet rbacRuleSet = new RbacRuleSet(); - rbacRuleSet.addRule(new RbacRule(adminRole, writeAction, new BaSyxObjectTargetInformation(any, someId, someId))); + rbacRuleSet.addRule(new RbacRule(adminRole, writeAction, new BaSyxObjectTargetInformation(any, someId, someId, someId))); final PredefinedSetRbacRuleChecker testSubject = new PredefinedSetRbacRuleChecker(rbacRuleSet); - final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), writeAction, new BaSyxObjectTargetInformation(otherId, someId, someId)); + final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), writeAction, new BaSyxObjectTargetInformation(otherId, someId, someId, someId)); Assert.assertTrue(result); } @@ -179,11 +179,11 @@ public class TestPredefinedSetRbacRuleChecker { public void givenRuleAdmin$Write$AnySomeSome_whenCheckForRuleAdmin$Write$OtherOtherSome_thenReturnFalse() { final RbacRuleSet rbacRuleSet = new RbacRuleSet(); - rbacRuleSet.addRule(new RbacRule(adminRole, writeAction, new BaSyxObjectTargetInformation(any, someId, someId))); + rbacRuleSet.addRule(new RbacRule(adminRole, writeAction, new BaSyxObjectTargetInformation(any, someId, someId, someId))); final PredefinedSetRbacRuleChecker testSubject = new PredefinedSetRbacRuleChecker(rbacRuleSet); - final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), writeAction, new BaSyxObjectTargetInformation(otherId, otherId, someId)); + final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), writeAction, new BaSyxObjectTargetInformation(otherId, otherId, otherId, someId)); Assert.assertFalse(result); } @@ -192,11 +192,11 @@ public class TestPredefinedSetRbacRuleChecker { public void givenRuleAdmin$Write$AnyAnySome_whenCheckForRuleAdmin$Write$OtherOtherSome_thenReturnTrue() { final RbacRuleSet rbacRuleSet = new RbacRuleSet(); - rbacRuleSet.addRule(new RbacRule(adminRole, writeAction, new BaSyxObjectTargetInformation(any, any, someId))); + rbacRuleSet.addRule(new RbacRule(adminRole, writeAction, new BaSyxObjectTargetInformation(any, any, any, someId))); final PredefinedSetRbacRuleChecker testSubject = new PredefinedSetRbacRuleChecker(rbacRuleSet); - final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), writeAction, new BaSyxObjectTargetInformation(otherId, otherId, someId)); + final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), writeAction, new BaSyxObjectTargetInformation(otherId, otherId, otherId, someId)); Assert.assertTrue(result); } @@ -205,11 +205,11 @@ public class TestPredefinedSetRbacRuleChecker { public void givenRuleAdmin$Write$AnyAnySome_whenCheckForRuleAdmin$Write$OtherOtherOther_thenReturnFalse() { final RbacRuleSet rbacRuleSet = new RbacRuleSet(); - rbacRuleSet.addRule(new RbacRule(adminRole, writeAction, new BaSyxObjectTargetInformation(any, any, someId))); + rbacRuleSet.addRule(new RbacRule(adminRole, writeAction, new BaSyxObjectTargetInformation(any, any, any, someId))); final PredefinedSetRbacRuleChecker testSubject = new PredefinedSetRbacRuleChecker(rbacRuleSet); - final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), writeAction, new BaSyxObjectTargetInformation(otherId, otherId, otherId)); + final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), writeAction, new BaSyxObjectTargetInformation(otherId, otherId, otherId, otherId)); Assert.assertFalse(result); } @@ -218,11 +218,11 @@ public class TestPredefinedSetRbacRuleChecker { public void givenRuleAdmin$Write$AnyAnyAny_whenCheckForRuleAdmin$Write$OtherOtherOther_thenReturnTrue() { final RbacRuleSet rbacRuleSet = new RbacRuleSet(); - rbacRuleSet.addRule(new RbacRule(adminRole, writeAction, new BaSyxObjectTargetInformation(any, any, any))); + rbacRuleSet.addRule(new RbacRule(adminRole, writeAction, new BaSyxObjectTargetInformation(any, any, any, any))); final PredefinedSetRbacRuleChecker testSubject = new PredefinedSetRbacRuleChecker(rbacRuleSet); - final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), writeAction, new BaSyxObjectTargetInformation(otherId, otherId, otherId)); + final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), writeAction, new BaSyxObjectTargetInformation(otherId, otherId, otherId, otherId)); Assert.assertTrue(result); } @@ -231,11 +231,11 @@ public class TestPredefinedSetRbacRuleChecker { public void givenRuleAdmin$Write$AnyAnyFooAny_whenCheckForRuleAdmin$Write$OtherOtherOther_thenReturnFalse() { final RbacRuleSet rbacRuleSet = new RbacRuleSet(); - rbacRuleSet.addRule(new RbacRule(adminRole, writeAction, new BaSyxObjectTargetInformation(any, any, "foo/" + any))); + rbacRuleSet.addRule(new RbacRule(adminRole, writeAction, new BaSyxObjectTargetInformation(any, any, any, "foo/" + any))); final PredefinedSetRbacRuleChecker testSubject = new PredefinedSetRbacRuleChecker(rbacRuleSet); - final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), writeAction, new BaSyxObjectTargetInformation(otherId, otherId, otherId)); + final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), writeAction, new BaSyxObjectTargetInformation(otherId, otherId, otherId, otherId)); Assert.assertFalse(result); } @@ -244,11 +244,11 @@ public class TestPredefinedSetRbacRuleChecker { public void givenRuleAdmin$Write$AnyAnyFooAny_whenCheckForRuleAdmin$Write$OtherOtherFooOther_thenReturnTrue() { final RbacRuleSet rbacRuleSet = new RbacRuleSet(); - rbacRuleSet.addRule(new RbacRule(adminRole, writeAction, new BaSyxObjectTargetInformation(any, any, "foo/" + any))); + rbacRuleSet.addRule(new RbacRule(adminRole, writeAction, new BaSyxObjectTargetInformation(any, any, any, "foo/" + any))); final PredefinedSetRbacRuleChecker testSubject = new PredefinedSetRbacRuleChecker(rbacRuleSet); - final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), writeAction, new BaSyxObjectTargetInformation(otherId, otherId, "foo/other")); + final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), writeAction, new BaSyxObjectTargetInformation(otherId, otherId, otherId, "foo/other")); Assert.assertTrue(result); } @@ -257,11 +257,11 @@ public class TestPredefinedSetRbacRuleChecker { public void givenRuleAdmin$Write$AnyAnyFooAnyBar_whenCheckForRuleAdmin$Write$OtherOtherFooOtherFoobar_thenReturnFalse() { final RbacRuleSet rbacRuleSet = new RbacRuleSet(); - rbacRuleSet.addRule(new RbacRule(adminRole, writeAction, new BaSyxObjectTargetInformation(any, any, "foo/" + any + "/bar"))); + rbacRuleSet.addRule(new RbacRule(adminRole, writeAction, new BaSyxObjectTargetInformation(any, any, any, "foo/" + any + "/bar"))); final PredefinedSetRbacRuleChecker testSubject = new PredefinedSetRbacRuleChecker(rbacRuleSet); - final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), writeAction, new BaSyxObjectTargetInformation(otherId, otherId, "foo/other/foobar")); + final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), writeAction, new BaSyxObjectTargetInformation(otherId, otherId, otherId, "foo/other/foobar")); Assert.assertFalse(result); } @@ -270,11 +270,11 @@ public class TestPredefinedSetRbacRuleChecker { public void givenRuleAdmin$Write$AnyAnyFooAnyFoobar_whenCheckForRuleAdmin$Write$OtherOtherFooOtherFoobar_thenReturnTrue() { final RbacRuleSet rbacRuleSet = new RbacRuleSet(); - rbacRuleSet.addRule(new RbacRule(adminRole, writeAction, new BaSyxObjectTargetInformation(any, any, "foo/" + any + "/foobar"))); + rbacRuleSet.addRule(new RbacRule(adminRole, writeAction, new BaSyxObjectTargetInformation(any, any, any, "foo/" + any + "/foobar"))); final PredefinedSetRbacRuleChecker testSubject = new PredefinedSetRbacRuleChecker(rbacRuleSet); - final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), writeAction, new BaSyxObjectTargetInformation(otherId, otherId, "foo/other/foobar")); + final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), writeAction, new BaSyxObjectTargetInformation(otherId, otherId, otherId, "foo/other/foobar")); Assert.assertTrue(result); } @@ -283,13 +283,13 @@ public class TestPredefinedSetRbacRuleChecker { public void givenRuleAdmin$Write$AnyAnyFooAnyFoobar_and_RuleNormal$Read$AnyAnyAny_whenCheckForRuleAdmin$Write$OtherOtherFooOtherFoobar_thenReturnTrue() { final RbacRuleSet rbacRuleSet = new RbacRuleSet(); - rbacRuleSet.addRule(new RbacRule(adminRole, writeAction, new BaSyxObjectTargetInformation(any, any, "foo/" + any + "/foobar"))); + rbacRuleSet.addRule(new RbacRule(adminRole, writeAction, new BaSyxObjectTargetInformation(any, any, any, "foo/" + any + "/foobar"))); - rbacRuleSet.addRule(new RbacRule(normalRole, readAction, new BaSyxObjectTargetInformation(any, any, any))); + rbacRuleSet.addRule(new RbacRule(normalRole, readAction, new BaSyxObjectTargetInformation(any, any, any, any))); final PredefinedSetRbacRuleChecker testSubject = new PredefinedSetRbacRuleChecker(rbacRuleSet); - final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), writeAction, new BaSyxObjectTargetInformation(otherId, otherId, "foo/other/foobar")); + final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), writeAction, new BaSyxObjectTargetInformation(otherId, otherId, otherId, "foo/other/foobar")); Assert.assertTrue(result); } @@ -298,13 +298,117 @@ public class TestPredefinedSetRbacRuleChecker { public void givenRuleAdmin$Write$AnyAnySomeId_and_RuleNormal$Read$AnyAnyAny_whenCheckForRuleAdmin$Write$OtherOtherFooOtherFoobar$_thenReturnFalse() { final RbacRuleSet rbacRuleSet = new RbacRuleSet(); - rbacRuleSet.addRule(new RbacRule(adminRole, writeAction, new BaSyxObjectTargetInformation(any, any, someId))); + rbacRuleSet.addRule(new RbacRule(adminRole, writeAction, new BaSyxObjectTargetInformation(any, any, any, someId))); - rbacRuleSet.addRule(new RbacRule(normalRole, readAction, new BaSyxObjectTargetInformation(any, any, any))); + rbacRuleSet.addRule(new RbacRule(normalRole, readAction, new BaSyxObjectTargetInformation(any, any, any, any))); final PredefinedSetRbacRuleChecker testSubject = new PredefinedSetRbacRuleChecker(rbacRuleSet); - final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), writeAction, new BaSyxObjectTargetInformation(otherId, otherId, "foo/other/foobar")); + final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), writeAction, new BaSyxObjectTargetInformation(otherId, otherId, otherId, "foo/other/foobar")); + + Assert.assertFalse(result); + } + + @Test + public void givenRuleAdmin$Write$NullSomeIdOtherIdNull_whenCheckForRuleAdmin$Write$NullSomeOtherNull_thenReturnTrue() { + final RbacRuleSet rbacRuleSet = new RbacRuleSet(); + + rbacRuleSet.addRule(new RbacRule(adminRole, writeAction, new BaSyxObjectTargetInformation(null, someId, otherId, null))); + + final PredefinedSetRbacRuleChecker testSubject = new PredefinedSetRbacRuleChecker(rbacRuleSet); + + final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), writeAction, new BaSyxObjectTargetInformation(null, someId, otherId, null)); + + Assert.assertTrue(result); + } + + @Test + public void givenRuleAdmin$Write$NullSomeIdOtherIdNull_whenCheckForRuleAdmin$Write$NullOtherOtherNull_thenReturnFalse() { + final RbacRuleSet rbacRuleSet = new RbacRuleSet(); + + rbacRuleSet.addRule(new RbacRule(adminRole, writeAction, new BaSyxObjectTargetInformation(null, someId, otherId, null))); + + final PredefinedSetRbacRuleChecker testSubject = new PredefinedSetRbacRuleChecker(rbacRuleSet); + + final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), writeAction, new BaSyxObjectTargetInformation(null, otherId, otherId, null)); + + Assert.assertFalse(result); + } + + @Test + public void givenRuleAdmin$Write$NullSomeIdOtherIdSomeId_whenCheckForRuleAdmin$Write$NullSomeOtherSome_thenReturnTrue() { + final RbacRuleSet rbacRuleSet = new RbacRuleSet(); + + rbacRuleSet.addRule(new RbacRule(adminRole, writeAction, new BaSyxObjectTargetInformation(null, someId, otherId, someId))); + + final PredefinedSetRbacRuleChecker testSubject = new PredefinedSetRbacRuleChecker(rbacRuleSet); + + final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), writeAction, new BaSyxObjectTargetInformation(null, someId, otherId, someId)); + + Assert.assertTrue(result); + } + + @Test + public void givenRuleAdmin$Write$NullSomeIdOtherIdSomeId_whenCheckForRuleAdmin$Write$NullSomeSomeSome_thenReturnFalse() { + final RbacRuleSet rbacRuleSet = new RbacRuleSet(); + + rbacRuleSet.addRule(new RbacRule(adminRole, writeAction, new BaSyxObjectTargetInformation(null, someId, otherId, someId))); + + final PredefinedSetRbacRuleChecker testSubject = new PredefinedSetRbacRuleChecker(rbacRuleSet); + + final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), writeAction, new BaSyxObjectTargetInformation(null, someId, someId, someId)); + + Assert.assertFalse(result); + } + + @Test + public void givenRuleAdmin$Read$NullSomeIdOtherIdNull_whenCheckForRuleAdmin$Read$NullSomeOtherNull_thenReturnTrue() { + final RbacRuleSet rbacRuleSet = new RbacRuleSet(); + + rbacRuleSet.addRule(new RbacRule(adminRole, readAction, new BaSyxObjectTargetInformation(null, someId, otherId, null))); + + final PredefinedSetRbacRuleChecker testSubject = new PredefinedSetRbacRuleChecker(rbacRuleSet); + + final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), readAction, new BaSyxObjectTargetInformation(null, someId, otherId, null)); + + Assert.assertTrue(result); + } + + @Test + public void givenRuleAdmin$Read$NullSomeIdOtherIdNull_whenCheckForRuleAdmin$Read$NullOtherOtherNull_thenReturnFalse() { + final RbacRuleSet rbacRuleSet = new RbacRuleSet(); + + rbacRuleSet.addRule(new RbacRule(adminRole, readAction, new BaSyxObjectTargetInformation(null, someId, otherId, null))); + + final PredefinedSetRbacRuleChecker testSubject = new PredefinedSetRbacRuleChecker(rbacRuleSet); + + final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), readAction, new BaSyxObjectTargetInformation(null, otherId, otherId, null)); + + Assert.assertFalse(result); + } + + @Test + public void givenRuleAdmin$Read$NullSomeIdOtherIdSomeId_whenCheckForRuleAdmin$Read$NullSomeOtherSome_thenReturnTrue() { + final RbacRuleSet rbacRuleSet = new RbacRuleSet(); + + rbacRuleSet.addRule(new RbacRule(adminRole, readAction, new BaSyxObjectTargetInformation(null, someId, otherId, someId))); + + final PredefinedSetRbacRuleChecker testSubject = new PredefinedSetRbacRuleChecker(rbacRuleSet); + + final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), readAction, new BaSyxObjectTargetInformation(null, someId, otherId, someId)); + + Assert.assertTrue(result); + } + + @Test + public void givenRuleAdmin$Read$NullSomeIdOtherIdSomeId_whenCheckForRuleAdmin$Read$NullSomeSomeSome_thenReturnFalse() { + final RbacRuleSet rbacRuleSet = new RbacRuleSet(); + + rbacRuleSet.addRule(new RbacRule(adminRole, readAction, new BaSyxObjectTargetInformation(null, someId, otherId, someId))); + + final PredefinedSetRbacRuleChecker testSubject = new PredefinedSetRbacRuleChecker(rbacRuleSet); + + final boolean result = testSubject.checkRbacRuleIsSatisfied(Collections.singletonList(adminRole), readAction, new BaSyxObjectTargetInformation(null, someId, someId, someId)); Assert.assertFalse(result); } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/shared/internal/TestRbacRuleSetDeserializer.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/shared/internal/TestRbacRuleSetDeserializer.java index 7ae4555b..cac7afe1 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/shared/internal/TestRbacRuleSetDeserializer.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/shared/internal/TestRbacRuleSetDeserializer.java @@ -41,11 +41,25 @@ public class TestRbacRuleSetDeserializer { @Test public void test() throws IOException { - final RbacRuleSetDeserializer rbacRuleSetDeserializer = new RbacRuleSetDeserializer((objectMapper) -> { - }); + final RbacRuleSetDeserializer rbacRuleSetDeserializer = new RbacRuleSetDeserializer(); final RbacRuleSet rbacRuleSet = rbacRuleSetDeserializer.fromFile("/authorization/internal/rbac_rules.json"); - Assert.assertEquals(16, rbacRuleSet.getRules().size()); - Assert.assertTrue(rbacRuleSet.getRules().contains(new RbacRule("reader", "urn:org.eclipse.basyx:scope:aas-registry:read", new BaSyxObjectTargetInformation("*", "*", "*")))); + Assert.assertEquals(17, rbacRuleSet.getRules().size()); + Assert.assertTrue(rbacRuleSet.getRules().contains(new RbacRule("reader", "urn:org.eclipse.basyx:scope:aas-registry:read", new BaSyxObjectTargetInformation("*", "*", null, "*")))); Assert.assertTrue(rbacRuleSet.getRules().contains(new RbacRule("reader", "urn:org.eclipse.basyx:scope:aas-registry:read", new TagTargetInformation("tag")))); + Assert.assertTrue(rbacRuleSet.getRules().contains(new RbacRule("reader", "urn:org.eclipse.basyx:scope:aas-registry:read", new BaSyxObjectTargetInformation("*", "*", "example-semantic-id", "*")))); + } + + final String[] multipleActions = new String[] { "urn:org.eclipse.basyx:scope:aas-aggregator:read", "urn:org.eclipse.basyx:scope:aas-aggregator:write", "urn:org.eclipse.basyx:scope:aas-api:read", + "urn:org.eclipse.basyx:scope:aas-api:write", "urn:org.eclipse.basyx:scope:sm-aggregator:read", "urn:org.eclipse.basyx:scope:sm-api:read", "urn:org.eclipse.basyx:scope:aas-registry:read" }; + + @Test + public void multipleActions() throws IOException { + final RbacRuleSetDeserializer rbacRuleSetDeserializer = new RbacRuleSetDeserializer(); + final RbacRuleSet rbacRuleSet = rbacRuleSetDeserializer.fromFile("/authorization/internal/rbac_rules_multiple_actions.json"); + Assert.assertEquals(multipleActions.length, rbacRuleSet.getRules().size()); + for (final String action : multipleActions) { + final RbacRule matchRule = new RbacRule("admin", action, new BaSyxObjectTargetInformation("*", "*", "*", "*")); + Assert.assertTrue("rule not contained: " + matchRule, rbacRuleSet.getRules().contains(matchRule)); + } } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/aggregator/authorization/internal/TestGrantedAuthorityAuthorizedSubmodelAggregator.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/aggregator/authorization/internal/TestGrantedAuthorityAuthorizedSubmodelAggregator.java index 909fd32c..c70dac63 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/aggregator/authorization/internal/TestGrantedAuthorityAuthorizedSubmodelAggregator.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/aggregator/authorization/internal/TestGrantedAuthorityAuthorizedSubmodelAggregator.java @@ -118,6 +118,7 @@ public void givenPrincipalHasReadAuthority_whenGetSubmodelList_thenInvocationIsF @Test(expected = ProviderException.class) public void givenPrincipalIsMissingReadAuthority_whenGetSubmodel_thenThrowProviderException() { securityContextProvider.setSecurityContextWithoutAuthorities(); + Mockito.when(apiMock.getSubmodel(SUBMODEL_IDENTIFIER)).thenReturn(submodel); testSubject.getSubmodel(SUBMODEL_IDENTIFIER); } @@ -125,6 +126,7 @@ public void givenPrincipalIsMissingReadAuthority_whenGetSubmodel_thenThrowProvid @Test(expected = ProviderException.class) public void givenSecurityContextIsEmpty_whenGetSubmodel_thenThrowProviderException() { securityContextProvider.setEmptySecurityContext(); + Mockito.when(apiMock.getSubmodel(SUBMODEL_IDENTIFIER)).thenReturn(submodel); testSubject.getSubmodel(SUBMODEL_IDENTIFIER); } @@ -141,6 +143,7 @@ public void givenPrincipalHasReadAuthority_whenGetSubmodel_thenInvocationIsForwa @Test(expected = ProviderException.class) public void givenPrincipalIsMissingReadAuthority_whenGetSubmodelbyIdShort_thenThrowProviderException() { securityContextProvider.setSecurityContextWithoutAuthorities(); + Mockito.when(apiMock.getSubmodelbyIdShort(SUBMODEL_IDSHORT)).thenReturn(submodel); testSubject.getSubmodelbyIdShort(SUBMODEL_IDSHORT); } @@ -148,6 +151,7 @@ public void givenPrincipalIsMissingReadAuthority_whenGetSubmodelbyIdShort_thenTh @Test(expected = ProviderException.class) public void givenSecurityContextIsEmpty_whenGetSubmodelbyIdShort_thenThrowProviderException() { securityContextProvider.setEmptySecurityContext(); + Mockito.when(apiMock.getSubmodelbyIdShort(SUBMODEL_IDSHORT)).thenReturn(submodel); testSubject.getSubmodelbyIdShort(SUBMODEL_IDSHORT); } @@ -164,6 +168,7 @@ public void givenPrincipalHasReadAuthority_whenGetSubmodelbyIdShort_thenInvocati @Test(expected = ProviderException.class) public void givenPrincipalIsMissingReadAuthority_whenGetSubmodelAPIById_thenThrowProviderException() { securityContextProvider.setSecurityContextWithoutAuthorities(); + Mockito.when(apiMock.getSubmodel(SUBMODEL_IDENTIFIER)).thenReturn(submodel); testSubject.getSubmodelAPIById(SUBMODEL_IDENTIFIER); } @@ -171,6 +176,7 @@ public void givenPrincipalIsMissingReadAuthority_whenGetSubmodelAPIById_thenThro @Test(expected = ProviderException.class) public void givenSecurityContextIsEmpty_whenGetSubmodelAPIById_thenThrowProviderException() { securityContextProvider.setEmptySecurityContext(); + Mockito.when(apiMock.getSubmodel(SUBMODEL_IDENTIFIER)).thenReturn(submodel); testSubject.getSubmodelAPIById(SUBMODEL_IDENTIFIER); } @@ -179,6 +185,7 @@ public void givenSecurityContextIsEmpty_whenGetSubmodelAPIById_thenThrowProvider public void givenPrincipalHasReadAuthority_whenGetSubmodelAPIById_thenInvocationIsForwarded() { securityContextProvider.setSecurityContextWithReadAuthority(); Mockito.when(apiMock.getSubmodelAPIById(SUBMODEL_IDENTIFIER)).thenReturn(submodelAPI); + Mockito.when(apiMock.getSubmodel(SUBMODEL_IDENTIFIER)).thenReturn(submodel); final ISubmodelAPI returnedSubmodelAPI = testSubject.getSubmodelAPIById(SUBMODEL_IDENTIFIER); assertEquals(submodelAPI, returnedSubmodelAPI); @@ -188,6 +195,7 @@ public void givenPrincipalHasReadAuthority_whenGetSubmodelAPIById_thenInvocation public void givenPrincipalHasReadAuthority_whenGetSubmodelAPIByIdShort_thenInvocationIsForwarded() { securityContextProvider.setSecurityContextWithReadAuthority(); Mockito.when(apiMock.getSubmodelAPIByIdShort(SUBMODEL_IDSHORT)).thenReturn(submodelAPI); + Mockito.when(apiMock.getSubmodelbyIdShort(SUBMODEL_IDSHORT)).thenReturn(submodel); final ISubmodelAPI returnedSubmodelAPI = testSubject.getSubmodelAPIByIdShort(SUBMODEL_IDSHORT); assertEquals(submodelAPI, returnedSubmodelAPI); @@ -196,6 +204,7 @@ public void givenPrincipalHasReadAuthority_whenGetSubmodelAPIByIdShort_thenInvoc @Test(expected = ProviderException.class) public void givenPrincipalIsMissingReadAuthority_whenGetSubmodelAPIByIdShort_thenThrowProviderException() { securityContextProvider.setSecurityContextWithoutAuthorities(); + Mockito.when(apiMock.getSubmodelbyIdShort(SUBMODEL_IDSHORT)).thenReturn(null); testSubject.getSubmodelAPIByIdShort(SUBMODEL_IDSHORT); } @@ -203,6 +212,7 @@ public void givenPrincipalIsMissingReadAuthority_whenGetSubmodelAPIByIdShort_the @Test(expected = ProviderException.class) public void givenSecurityContextIsEmpty_whenGetSubmodelAPIByIdShort_thenThrowProviderException() { securityContextProvider.setEmptySecurityContext(); + Mockito.when(apiMock.getSubmodelbyIdShort(SUBMODEL_IDSHORT)).thenReturn(null); testSubject.getSubmodelAPIByIdShort(SUBMODEL_IDSHORT); } @@ -210,6 +220,7 @@ public void givenSecurityContextIsEmpty_whenGetSubmodelAPIByIdShort_thenThrowPro @Test public void givenPrincipalHasWriteAuthority_whenCreateSubmodel_thenInvocationIsForwarded() { securityContextProvider.setSecurityContextWithWriteAuthority(); + Mockito.when(apiMock.getSubmodel(SUBMODEL_IDENTIFIER)).thenReturn(submodel); testSubject.createSubmodel(submodel); Mockito.verify(apiMock).createSubmodel(submodel); @@ -218,6 +229,7 @@ public void givenPrincipalHasWriteAuthority_whenCreateSubmodel_thenInvocationIsF @Test(expected = ProviderException.class) public void givenPrincipalIsMissingReadAuthority_whenCreateSubmodel_thenThrowProviderException() { securityContextProvider.setSecurityContextWithoutAuthorities(); + Mockito.when(apiMock.getSubmodel(SUBMODEL_IDENTIFIER)).thenReturn(submodel); testSubject.createSubmodel(submodel); } @@ -225,6 +237,7 @@ public void givenPrincipalIsMissingReadAuthority_whenCreateSubmodel_thenThrowPro @Test(expected = ProviderException.class) public void givenSecurityContextIsEmpty_whenCreateSubmodel_thenThrowProviderException() { securityContextProvider.setEmptySecurityContext(); + Mockito.when(apiMock.getSubmodel(SUBMODEL_IDENTIFIER)).thenReturn(submodel); testSubject.createSubmodel(submodel); } @@ -232,6 +245,7 @@ public void givenSecurityContextIsEmpty_whenCreateSubmodel_thenThrowProviderExce @Test public void givenPrincipalHasWriteAuthority_whenCreateSubmodelAPI_thenInvocationIsForwarded() { securityContextProvider.setSecurityContextWithWriteAuthority(); + Mockito.when(apiMock.getSubmodel(SUBMODEL_IDENTIFIER)).thenReturn(submodel); testSubject.createSubmodel(submodelAPI); Mockito.verify(apiMock).createSubmodel(submodelAPI); @@ -240,6 +254,7 @@ public void givenPrincipalHasWriteAuthority_whenCreateSubmodelAPI_thenInvocation @Test(expected = ProviderException.class) public void givenPrincipalIsMissingReadAuthority_whenCreateSubmodelAPI_thenThrowProviderException() { securityContextProvider.setSecurityContextWithoutAuthorities(); + Mockito.when(apiMock.getSubmodel(SUBMODEL_IDENTIFIER)).thenReturn(submodel); testSubject.createSubmodel(submodelAPI); } @@ -247,6 +262,7 @@ public void givenPrincipalIsMissingReadAuthority_whenCreateSubmodelAPI_thenThrow @Test(expected = ProviderException.class) public void givenSecurityContextIsEmpty_whenCreateSubmodelAPI_thenThrowProviderException() { securityContextProvider.setEmptySecurityContext(); + Mockito.when(apiMock.getSubmodel(SUBMODEL_IDENTIFIER)).thenReturn(submodel); testSubject.createSubmodel(submodelAPI); } @@ -254,6 +270,7 @@ public void givenSecurityContextIsEmpty_whenCreateSubmodelAPI_thenThrowProviderE @Test public void givenPrincipalHasWriteAuthority_whenUpdateSubmodel_thenInvocationIsForwarded() { securityContextProvider.setSecurityContextWithWriteAuthority(); + Mockito.when(apiMock.getSubmodel(SUBMODEL_IDENTIFIER)).thenReturn(submodel); testSubject.updateSubmodel(submodel); Mockito.verify(apiMock).updateSubmodel(submodel); @@ -262,6 +279,7 @@ public void givenPrincipalHasWriteAuthority_whenUpdateSubmodel_thenInvocationIsF @Test(expected = ProviderException.class) public void givenPrincipalIsMissingReadAuthority_whenUpdateSubmodel_thenThrowProviderException() { securityContextProvider.setSecurityContextWithoutAuthorities(); + Mockito.when(apiMock.getSubmodel(SUBMODEL_IDENTIFIER)).thenReturn(submodel); testSubject.updateSubmodel(submodel); } @@ -269,6 +287,7 @@ public void givenPrincipalIsMissingReadAuthority_whenUpdateSubmodel_thenThrowPro @Test(expected = ProviderException.class) public void givenSecurityContextIsEmpty_whenUpdateSubmodel_thenThrowProviderException() { securityContextProvider.setEmptySecurityContext(); + Mockito.when(apiMock.getSubmodel(SUBMODEL_IDENTIFIER)).thenReturn(submodel); testSubject.updateSubmodel(submodel); } @@ -276,6 +295,7 @@ public void givenSecurityContextIsEmpty_whenUpdateSubmodel_thenThrowProviderExce @Test public void givenPrincipalHasWriteAuthority_whenDeleteSubmodelByIdentifier_thenInvocationIsForwarded() { securityContextProvider.setSecurityContextWithWriteAuthority(); + Mockito.when(apiMock.getSubmodel(SUBMODEL_IDENTIFIER)).thenReturn(submodel); testSubject.deleteSubmodelByIdentifier(SUBMODEL_IDENTIFIER); Mockito.verify(apiMock).deleteSubmodelByIdentifier(SUBMODEL_IDENTIFIER); @@ -284,6 +304,7 @@ public void givenPrincipalHasWriteAuthority_whenDeleteSubmodelByIdentifier_thenI @Test(expected = ProviderException.class) public void givenPrincipalIsMissingReadAuthority_whenDeleteSubmodelByIdentifier_thenThrowProviderException() { securityContextProvider.setSecurityContextWithoutAuthorities(); + Mockito.when(apiMock.getSubmodel(SUBMODEL_IDENTIFIER)).thenReturn(submodel); testSubject.deleteSubmodelByIdentifier(SUBMODEL_IDENTIFIER); } @@ -291,6 +312,7 @@ public void givenPrincipalIsMissingReadAuthority_whenDeleteSubmodelByIdentifier_ @Test(expected = ProviderException.class) public void givenSecurityContextIsEmpty_whenDeleteSubmodelByIdentifier_thenThrowProviderException() { securityContextProvider.setEmptySecurityContext(); + Mockito.when(apiMock.getSubmodel(SUBMODEL_IDENTIFIER)).thenReturn(submodel); testSubject.deleteSubmodelByIdentifier(SUBMODEL_IDENTIFIER); } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/aggregator/authorization/internal/TestSimpleRbacAuthorizedSubmodelAggregator.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/aggregator/authorization/internal/TestSimpleRbacAuthorizedSubmodelAggregator.java index ae7a8606..56c289ac 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/aggregator/authorization/internal/TestSimpleRbacAuthorizedSubmodelAggregator.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/aggregator/authorization/internal/TestSimpleRbacAuthorizedSubmodelAggregator.java @@ -99,10 +99,10 @@ public static void setUpClass() { @Before public void setUp() { - rbacRuleSet.addRule(new RbacRule(adminRole, SubmodelAggregatorScopes.READ_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*"))); - rbacRuleSet.addRule(new RbacRule(adminRole, SubmodelAggregatorScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*"))); - rbacRuleSet.addRule(new RbacRule(readerRole, SubmodelAggregatorScopes.READ_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*"))); - rbacRuleSet.addRule(new RbacRule(partialReaderRole, SubmodelAggregatorScopes.READ_SCOPE, new BaSyxObjectTargetInformation("*", SUBMODEL_IDENTIFIER.getId(), "*"))); + rbacRuleSet.addRule(new RbacRule(adminRole, SubmodelAggregatorScopes.READ_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*", "*"))); + rbacRuleSet.addRule(new RbacRule(adminRole, SubmodelAggregatorScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*", "*"))); + rbacRuleSet.addRule(new RbacRule(readerRole, SubmodelAggregatorScopes.READ_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*", "*"))); + rbacRuleSet.addRule(new RbacRule(partialReaderRole, SubmodelAggregatorScopes.READ_SCOPE, new BaSyxObjectTargetInformation("*", SUBMODEL_IDENTIFIER.getId(), "*", "*"))); testSubject = new AuthorizedSubmodelAggregator<>(apiMock, new SimpleRbacSubmodelAggregatorAuthorizer<>(new PredefinedSetRbacRuleChecker(rbacRuleSet), new KeycloakRoleAuthenticator()), new JWTAuthenticationContextProvider()); } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/authorization/internal/TestGrantedAuthorityAuthorizedSubmodelAPI.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/authorization/internal/TestGrantedAuthorityAuthorizedSubmodelAPI.java index f433cd04..34184046 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/authorization/internal/TestGrantedAuthorityAuthorizedSubmodelAPI.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/authorization/internal/TestGrantedAuthorityAuthorizedSubmodelAPI.java @@ -26,6 +26,9 @@ import static org.junit.Assert.assertEquals; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; import org.eclipse.basyx.extensions.shared.authorization.internal.AuthenticationContextProvider; @@ -369,4 +372,46 @@ public void givenPrincipalHasReadAuthority_whenGetOperationResult_thenInvocation final Object returnedValue = authorizedSubmodelAPI.getOperationResult(PROPERTY_IDSHORT, ASYNC_REQUEST_ID); assertEquals(PROPERTY_VALUE, returnedValue); } + + @Test(expected = NotAuthorizedException.class) + public void givenPrincipalIsMissingReadAuthority_whenGetSubmodelElementFile_thenThrowNotAuthorized() { + securityContextProvider.setSecurityContextWithoutAuthorities(); + authorizedSubmodelAPI.getSubmodelElementFile(PROPERTY_IDSHORT); + } + + @Test(expected = NotAuthorizedException.class) + public void givenSecurityContextIsEmpty_whenGetSubmodelElementFile_thenThrowNotAuthorized() { + securityContextProvider.setEmptySecurityContext(); + authorizedSubmodelAPI.getSubmodelElementFile(PROPERTY_IDSHORT); + } + + @Test + public void givenPrincipalHasReadAuthority_whenGetSubmodelElementFile_thenInvocationIsForwarded() { + final File expectedFile = new File("returnFile"); + securityContextProvider.setSecurityContextWithReadAuthority(); + Mockito.when(apiMock.getSubmodelElement(PROPERTY_IDSHORT)).thenReturn(PROPERTY); + Mockito.when(apiMock.getSubmodelElementFile(PROPERTY_IDSHORT)).thenReturn(expectedFile); + final Object returnedValue = authorizedSubmodelAPI.getSubmodelElementFile(PROPERTY_IDSHORT); + assertEquals(expectedFile, returnedValue); + } + + @Test(expected = NotAuthorizedException.class) + public void givenPrincipalIsMissingWriteAuthority_whenUploadSubmodelElementFile_thenThrowNotAuthorized() { + securityContextProvider.setSecurityContextWithoutAuthorities(); + authorizedSubmodelAPI.uploadSubmodelElementFile(PROPERTY_IDSHORT, new ByteArrayInputStream("hello file".getBytes())); + } + + @Test(expected = NotAuthorizedException.class) + public void givenSecurityContextIsEmpty_whenUploadSubmodelElementFile_thenThrowNotAuthorized() { + securityContextProvider.setEmptySecurityContext(); + authorizedSubmodelAPI.uploadSubmodelElementFile(PROPERTY_IDSHORT, new ByteArrayInputStream("hello file".getBytes())); + } + + @Test + public void givenPrincipalHasWriteAuthority_whenUploadSubmodelElementFile_thenInvocationIsForwarded() { + final InputStream inputStream = new ByteArrayInputStream("hello file".getBytes()); + securityContextProvider.setSecurityContextWithWriteAuthority(); + authorizedSubmodelAPI.uploadSubmodelElementFile(PROPERTY_IDSHORT, inputStream); + Mockito.verify(apiMock).uploadSubmodelElementFile(PROPERTY_IDSHORT, inputStream); + } } \ No newline at end of file diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/authorization/internal/TestSimpleRbacAuthorizedSubmodelAPI.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/authorization/internal/TestSimpleRbacAuthorizedSubmodelAPI.java index c4fe6206..4a95ad4d 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/authorization/internal/TestSimpleRbacAuthorizedSubmodelAPI.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/authorization/internal/TestSimpleRbacAuthorizedSubmodelAPI.java @@ -26,6 +26,9 @@ import static org.junit.Assert.assertEquals; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; import org.eclipse.basyx.extensions.shared.authorization.internal.BaSyxObjectTargetInformation; @@ -92,11 +95,11 @@ public static void setUpClass() { @Before public void setUp() { - rbacRuleSet.addRule(new RbacRule(adminRole, SubmodelAPIScopes.READ_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*"))); - rbacRuleSet.addRule(new RbacRule(adminRole, SubmodelAPIScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*"))); - rbacRuleSet.addRule(new RbacRule(adminRole, SubmodelAPIScopes.EXECUTE_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*"))); - rbacRuleSet.addRule(new RbacRule(readerRole, SubmodelAPIScopes.READ_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*"))); - rbacRuleSet.addRule(new RbacRule(executorRole, SubmodelAPIScopes.EXECUTE_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*"))); + rbacRuleSet.addRule(new RbacRule(adminRole, SubmodelAPIScopes.READ_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*", "*"))); + rbacRuleSet.addRule(new RbacRule(adminRole, SubmodelAPIScopes.WRITE_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*", "*"))); + rbacRuleSet.addRule(new RbacRule(adminRole, SubmodelAPIScopes.EXECUTE_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*", "*"))); + rbacRuleSet.addRule(new RbacRule(readerRole, SubmodelAPIScopes.READ_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*", "*"))); + rbacRuleSet.addRule(new RbacRule(executorRole, SubmodelAPIScopes.EXECUTE_SCOPE, new BaSyxObjectTargetInformation("*", "*", "*", "*"))); authorizedSubmodelAPI = new AuthorizedSubmodelAPI<>(apiMock, new SimpleRbacSubmodelAPIAuthorizer<>(new PredefinedSetRbacRuleChecker(rbacRuleSet), new KeycloakRoleAuthenticator()), new JWTAuthenticationContextProvider()); } @@ -346,4 +349,45 @@ public void givenPrincipalHasReadAuthority_whenGetOperationResult_thenInvocation final Object returnedValue = authorizedSubmodelAPI.getOperationResult(PROPERTY_IDSHORT, ASYNC_REQUEST_ID); assertEquals(PROPERTY_VALUE, returnedValue); } + + @Test(expected = NotAuthorizedException.class) + public void givenPrincipalIsMissingReadAuthority_whenGetSubmodelElementFile_thenThrowNotAuthorized() { + securityContextProvider.setSecurityContextWithoutRoles(); + authorizedSubmodelAPI.getSubmodelElementFile(PROPERTY_IDSHORT); + } + + @Test(expected = NotAuthorizedException.class) + public void givenSecurityContextIsEmpty_whenGetSubmodelElementFile_thenThrowNotAuthorized() { + securityContextProvider.setEmptySecurityContext(); + authorizedSubmodelAPI.getSubmodelElementFile(PROPERTY_IDSHORT); + } + + @Test + public void givenPrincipalHasReadAuthority_whenGetSubmodelElementFile_thenInvocationIsForwarded() { + final File expectedFile = new File("returnFile"); + securityContextProvider.setSecurityContextWithRoles(readerRole); + Mockito.when(apiMock.getSubmodelElementFile(PROPERTY_IDSHORT)).thenReturn(expectedFile); + final Object returnedValue = authorizedSubmodelAPI.getSubmodelElementFile(PROPERTY_IDSHORT); + assertEquals(expectedFile, returnedValue); + } + + @Test(expected = NotAuthorizedException.class) + public void givenPrincipalIsMissingWriteAuthority_whenUploadSubmodelElementFile_thenThrowNotAuthorized() { + securityContextProvider.setSecurityContextWithoutRoles(); + authorizedSubmodelAPI.uploadSubmodelElementFile(PROPERTY_IDSHORT, new ByteArrayInputStream("hello file".getBytes())); + } + + @Test(expected = NotAuthorizedException.class) + public void givenSecurityContextIsEmpty_whenUploadSubmodelElementFile_thenThrowNotAuthorized() { + securityContextProvider.setEmptySecurityContext(); + authorizedSubmodelAPI.uploadSubmodelElementFile(PROPERTY_IDSHORT, new ByteArrayInputStream("hello file".getBytes())); + } + + @Test + public void givenPrincipalHasWriteAuthority_whenUploadSubmodelElementFile_thenInvocationIsForwarded() { + final InputStream inputStream = new ByteArrayInputStream("hello file".getBytes()); + securityContextProvider.setSecurityContextWithRoles(adminRole); + authorizedSubmodelAPI.uploadSubmodelElementFile(PROPERTY_IDSHORT, inputStream); + Mockito.verify(apiMock).uploadSubmodelElementFile(PROPERTY_IDSHORT, inputStream); + } } diff --git a/src/test/resources/authorization/internal/rbac_rules.json b/src/test/resources/authorization/internal/rbac_rules.json index af2bc0a9..13e14bfd 100644 --- a/src/test/resources/authorization/internal/rbac_rules.json +++ b/src/test/resources/authorization/internal/rbac_rules.json @@ -161,5 +161,17 @@ "@type": "tag", "tag": "tag" } + }, + + { + "role": "reader", + "action": "urn:org.eclipse.basyx:scope:aas-registry:read", + "targetInformation": { + "@type": "basyx", + "aasId": "*", + "smId": "*", + "smSemanticId": "example-semantic-id", + "smElIdShortPath": "*" + } } ] \ No newline at end of file diff --git a/src/test/resources/authorization/internal/rbac_rules_multiple_actions.json b/src/test/resources/authorization/internal/rbac_rules_multiple_actions.json new file mode 100644 index 00000000..b3e6734c --- /dev/null +++ b/src/test/resources/authorization/internal/rbac_rules_multiple_actions.json @@ -0,0 +1,21 @@ +[ + { + "role": "admin", + "action": [ + "urn:org.eclipse.basyx:scope:aas-aggregator:read", + "urn:org.eclipse.basyx:scope:aas-aggregator:write", + "urn:org.eclipse.basyx:scope:aas-api:read", + "urn:org.eclipse.basyx:scope:aas-api:write", + "urn:org.eclipse.basyx:scope:sm-aggregator:read", + "urn:org.eclipse.basyx:scope:sm-api:read", + "urn:org.eclipse.basyx:scope:aas-registry:read" + ], + "targetInformation": { + "@type": "basyx", + "aasId": "*", + "smId": "*", + "smSemanticId": "*", + "smElIdShortPath": "*" + } + } +] \ No newline at end of file From 3d5dd63fd91d20fc2b508efecde062532f07fc49 Mon Sep 17 00:00:00 2001 From: Daniel Espen Date: Thu, 29 Jun 2023 11:47:46 +0200 Subject: [PATCH 43/77] Fixes FileUpload file streams not closing in case of exceptions Signed-off-by: Daniel Espen --- .../basyx/submodel/restapi/vab/VABSubmodelAPI.java | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/eclipse/basyx/submodel/restapi/vab/VABSubmodelAPI.java b/src/main/java/org/eclipse/basyx/submodel/restapi/vab/VABSubmodelAPI.java index 9b6e6c9f..3ce9a036 100644 --- a/src/main/java/org/eclipse/basyx/submodel/restapi/vab/VABSubmodelAPI.java +++ b/src/main/java/org/eclipse/basyx/submodel/restapi/vab/VABSubmodelAPI.java @@ -164,13 +164,10 @@ private void createFile(String idShortPath, Object newValue, ISubmodelElement su java.io.File targetFile = new java.io.File(filePath); - FileOutputStream outStream = new FileOutputStream(targetFile); - InputStream inStream = (InputStream) newValue; - - IOUtils.copy(inStream, outStream); - - inStream.close(); - outStream.close(); + try (FileOutputStream outStream = new FileOutputStream(targetFile); + InputStream inStream = (InputStream) newValue) { + IOUtils.copy(inStream, outStream); + } } private String getFilePath(String idShortPath, File file) { From 248a39a7b8e687076e3a8213fb5c63af100c23e1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Jul 2023 07:24:23 +0000 Subject: [PATCH 44/77] Bump janino from 3.1.9 to 3.1.10 Bumps [janino](https://github.com/janino-compiler/janino) from 3.1.9 to 3.1.10. - [Release notes](https://github.com/janino-compiler/janino/releases) - [Commits](https://github.com/janino-compiler/janino/compare/v3.1.9...v3.1.10) --- updated-dependencies: - dependency-name: org.codehaus.janino:janino dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2bbfb7fd..550fade0 100644 --- a/pom.xml +++ b/pom.xml @@ -276,7 +276,7 @@ org.codehaus.janino janino - 3.1.9 + 3.1.10 runtime From 3f1594022edbdd5c0e0993364a2231cc06e3a696 Mon Sep 17 00:00:00 2001 From: Frank Schnicke Date: Wed, 5 Jul 2023 15:29:05 +0200 Subject: [PATCH 45/77] Fixes order of AAS/Submodel deletion * First, remove from registry, then from AAS Server Signed-off-by: Frank Schnicke --- ...nectedAssetAdministrationShellManager.java | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/eclipse/basyx/aas/manager/ConnectedAssetAdministrationShellManager.java b/src/main/java/org/eclipse/basyx/aas/manager/ConnectedAssetAdministrationShellManager.java index cdecc479..dcb97820 100644 --- a/src/main/java/org/eclipse/basyx/aas/manager/ConnectedAssetAdministrationShellManager.java +++ b/src/main/java/org/eclipse/basyx/aas/manager/ConnectedAssetAdministrationShellManager.java @@ -127,25 +127,28 @@ public Collection retrieveAASAll() { @Override public void deleteAAS(IIdentifier id) { - // Lookup AAS descriptor AASDescriptor aasDescriptor = aasDirectory.lookupAAS(id); - // Get AAS address from AAS descriptor String addr = aasDescriptor.getFirstEndpoint(); - // Address ends in "/aas", has to be stripped for removal - addr = VABPathTools.stripSlashes(addr); - addr = addr.substring(0, addr.length() - "/aas".length()); - - // Delete from server - proxyFactory.createProxy(addr).deleteValue(""); + String harmonizedAddress = getHarmonizedAddress(addr); - // Delete from Registry aasDirectory.delete(id); + deleteAasFromAddress(harmonizedAddress); + // TODO: How to handle submodels -> Lifecycle needs to be clarified } + private void deleteAasFromAddress(String address) { + proxyFactory.createProxy(address).deleteValue(""); + } + + private String getHarmonizedAddress(String address) { + String strippedAddr = VABPathTools.stripSlashes(address); + return strippedAddr.substring(0, strippedAddr.length() - "/aas".length()); + } + @Override public void createSubmodel(IIdentifier aasId, Submodel submodel) { @@ -167,9 +170,10 @@ public void createSubmodel(IIdentifier aasId, Submodel submodel) { @Override public void deleteSubmodel(IIdentifier aasId, IIdentifier submodelId) { IAssetAdministrationShell shell = retrieveAAS(aasId); - shell.removeSubmodel(submodelId); aasDirectory.delete(aasId, submodelId); + + shell.removeSubmodel(submodelId); } @Override From eee2ec2b57dbbf339dd46723faa0f7387da06470 Mon Sep 17 00:00:00 2001 From: jannisjung <92165516+jannisjung@users.noreply.github.com> Date: Tue, 11 Jul 2023 09:21:21 +0200 Subject: [PATCH 46/77] Adjusts abstract BaSyxStorageAPI for MongoDB Backend (#319) Signed-off-by: Jannis Jung Co-authored-by: Daniel Espen --- .gitignore | 2 + .../internal/storage/BaSyxStorageAPI.java | 73 +++++++--- .../FeatureNotImplementedException.java | 8 ++ .../storage/BaSyxStorageAPISuite.java | 92 +++++++++--- .../storage/TestBaSyxStorageAPI.java | 134 ++++++++++++++++++ .../restapi/SubmodelProviderTest.java | 22 ++- 6 files changed, 294 insertions(+), 37 deletions(-) create mode 100644 src/test/java/org/eclipse/basyx/testsuite/regression/extensions/storage/TestBaSyxStorageAPI.java diff --git a/.gitignore b/.gitignore index 42281a30..6dc115d4 100644 --- a/.gitignore +++ b/.gitignore @@ -73,3 +73,5 @@ local.properties .idea *.iml +.moquette_uuid +file_sme.json diff --git a/src/main/java/org/eclipse/basyx/extensions/internal/storage/BaSyxStorageAPI.java b/src/main/java/org/eclipse/basyx/extensions/internal/storage/BaSyxStorageAPI.java index 589c3e64..7b2330f6 100644 --- a/src/main/java/org/eclipse/basyx/extensions/internal/storage/BaSyxStorageAPI.java +++ b/src/main/java/org/eclipse/basyx/extensions/internal/storage/BaSyxStorageAPI.java @@ -26,11 +26,15 @@ import java.io.File; import java.io.InputStream; +import java.util.Collection; import java.util.HashMap; import java.util.Map; +import java.util.stream.Collectors; +import org.apache.commons.collections4.CollectionUtils; import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell; import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor; +import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelDescriptor; import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; import org.eclipse.basyx.submodel.metamodel.api.qualifier.IIdentifiable; import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement; @@ -56,6 +60,13 @@ public abstract class BaSyxStorageAPI implements IBaSyxStorageAPI { protected final String COLLECTION_NAME; protected final Class TYPE; + /** + * The default constructor is primarily used for mocking purposes of the class. + */ + BaSyxStorageAPI() { + this(null, null); + } + /** * * @param collectionName @@ -70,9 +81,10 @@ public BaSyxStorageAPI(String collectionName, Class type) { } /** - * DISCLAIMER: Currently only supports to extract keys from IIdentifiables. - * Helper method that extracts a key for persistence storage requests from an - * object. + * DISCLAIMER: Currently only supports to extract keys from IIdentifiables and + * ModelDescriptors. + * Helper method that extracts a key for persistence storage + * requests from an object. * * @param obj * An object that contains a key that can be used to find the @@ -80,10 +92,16 @@ public BaSyxStorageAPI(String collectionName, Class type) { * @return The key */ protected String getKey(T obj) { - if (!(obj instanceof IIdentifiable)) { - throw new IllegalArgumentException("Can only extract a key from a object of type " + IIdentifiable.class.getName()); + if (!(obj instanceof IIdentifiable || obj instanceof ModelDescriptor)) { + throw new IllegalArgumentException("Can only extract a key from a object of types " + IIdentifiable.class.getName() + " or " + ModelDescriptor.class.getName()); + } + + if (obj instanceof ModelDescriptor) { + return ((ModelDescriptor) obj).getIdentifier().getId(); + } else { + return ((IIdentifiable) obj).getIdentification().getId(); + } - return ((IIdentifiable) obj).getIdentification().getId(); } /** @@ -100,12 +118,22 @@ protected String getKey(T obj) { */ public abstract T rawRetrieve(String key); + public abstract Collection rawRetrieveAll(); + public abstract File getFile(String key, String parentKey, Map objMap); public abstract String writeFile(String key, String parentKey, InputStream fileStream, ISubmodelElement submodelElement); public abstract void deleteFile(Submodel submodel, String idShort); + /** + * This Method shall return an implementation specific connection object which + * can be used to implement more advanced operations on the storage. + * + * @return An object that can be used for direct storage access + */ + public abstract Object getStorageConnection(); + /** * Returns a Object that was originally retrieved from the abstract method * {@code rawRetrieve}. If the object to be returned is a submodel type, it will @@ -121,6 +149,20 @@ public T retrieve(String key) { return retrieved; } + @SuppressWarnings("unchecked") + @Override + public Collection retrieveAll() { + Collection retrieves = rawRetrieveAll(); + if (!CollectionUtils.isEmpty(retrieves) && isSubmodelType(getElementClass(retrieves))) { + return (Collection) retrieves.stream().map(submodel -> handleRetrievedSubmodel((Submodel) submodel)).collect(Collectors.toList()); + } + return retrieves; + } + + private Class getElementClass(Collection collection) { + return collection.iterator().next().getClass(); + } + /** * Helper to bring the SubmodelElements a retrieved SubmodelObject to the * correct Type of ISubmodelElements. Background: SubmodelsElements are @@ -137,7 +179,7 @@ public T retrieve(String key) { @SuppressWarnings("unchecked") protected Submodel handleRetrievedSubmodel(Submodel retrieved) { Map> elementMaps = (Map>) retrieved.get(Submodel.SUBMODELELEMENT); - Map elements = forceToISubmodelElements(elementMaps); + Map elements = enforceISubmodelElements(elementMaps); retrieved.put(Submodel.SUBMODELELEMENT, elements); return retrieved; } @@ -154,7 +196,7 @@ protected Submodel handleRetrievedSubmodel(Submodel retrieved) { * can be get with {@code submodel.get(Submodel.SUBMODELELEMENT)})) * @return A map in the expected form of {@code Map} */ - private Map forceToISubmodelElements(Map> submodelElementObjectMap) { + private Map enforceISubmodelElements(Map> submodelElementObjectMap) { Map elements = new HashMap<>(); submodelElementObjectMap.forEach((idShort, elementMap) -> { @@ -164,32 +206,23 @@ private Map forceToISubmodelElements(Map type) { return ISubmodel.class.isAssignableFrom(type); } - /* - * Not yet tested - */ protected boolean isShellType(Class type) { return IAssetAdministrationShell.class.isAssignableFrom(type); } - /* - * Not yet tested - */ protected boolean isAASDescriptorType(Class type) { return AASDescriptor.class.isAssignableFrom(type); } - /* - * Not yet tested - */ protected boolean isBaSyxType(Class type) { return (isShellType(type) || isSubmodelType(type) || isAASDescriptorType(type)); } + public String getCollectionName() { + return COLLECTION_NAME; + } } diff --git a/src/main/java/org/eclipse/basyx/vab/exception/FeatureNotImplementedException.java b/src/main/java/org/eclipse/basyx/vab/exception/FeatureNotImplementedException.java index e6ff4a30..a322cd5b 100644 --- a/src/main/java/org/eclipse/basyx/vab/exception/FeatureNotImplementedException.java +++ b/src/main/java/org/eclipse/basyx/vab/exception/FeatureNotImplementedException.java @@ -37,4 +37,12 @@ public class FeatureNotImplementedException extends RuntimeException { */ private static final long serialVersionUID = 1L; + public FeatureNotImplementedException() { + super(); + } + + public FeatureNotImplementedException(final String message) { + super(message); + } + } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/storage/BaSyxStorageAPISuite.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/storage/BaSyxStorageAPISuite.java index 424f17bf..c1922fae 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/storage/BaSyxStorageAPISuite.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/storage/BaSyxStorageAPISuite.java @@ -28,6 +28,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import java.util.Arrays; import java.util.Collection; import org.eclipse.basyx.extensions.internal.storage.BaSyxStorageAPI; @@ -49,12 +50,22 @@ */ public abstract class BaSyxStorageAPISuite { - private static final Identifier SUBMODEL_IDENTIFIER = new Identifier(IdentifierType.CUSTOM, "testSubmodelIidentifier"); - protected static Submodel testType = new Submodel("testSubmodel", SUBMODEL_IDENTIFIER); - private BaSyxStorageAPI storageAPI; + private final Identifier SUBMODEL_IDENTIFIER = new Identifier(IdentifierType.CUSTOM, "testSubmodelIidentifier"); + protected Submodel testSubmodel = new Submodel("testSubmodel", SUBMODEL_IDENTIFIER); + protected BaSyxStorageAPI storageAPI; protected abstract BaSyxStorageAPI getStorageAPI(); + /** + * This Storage API is used to approve data persistency. Therefore this method + * shall not return the very same object returned by {@link #getStorageAPI()} + * but still connect to the same storage. + * + * @return A BaSyxStorageAPI that is not same as returned by + * {@link #getStorageAPI()} + */ + protected abstract BaSyxStorageAPI getSecondStorageAPI(); + @Before public void setUp() { storageAPI = getStorageAPI(); @@ -62,31 +73,80 @@ public void setUp() { @After public void cleanUp() { - storageAPI.delete(testType.getIdentification().getId()); + storageAPI.delete(testSubmodel.getIdentification().getId()); } @Test - public void retrieve() { - storageAPI.createOrUpdate(testType); - Submodel actual = storageAPI.retrieve(testType.getIdentification().getId()); - assertEquals(testType, actual); + public void createOrUpdateAndretrieve() { + storageAPI.createOrUpdate(testSubmodel); + Submodel actual = storageAPI.retrieve(testSubmodel.getIdentification().getId()); + assertEquals(testSubmodel, actual); + } + + @Test + public void retrieveAll() { + Submodel[] testSubmodels = createTestSubmodels(); + uploadMultiple(testSubmodels); + + Collection retrieves = storageAPI.retrieveAll(); + for (Submodel submodel : testSubmodels) { + assertTrue(retrieves.contains(submodel)); + } + } + + private Submodel[] createTestSubmodels() { + Submodel[] testTypes = new Submodel[3]; + Arrays.setAll(testTypes, i -> new Submodel(testSubmodel.getIdShort() + i, new Identifier(IdentifierType.CUSTOM, "test" + i))); + return testTypes; + } + + private void uploadMultiple(Submodel[] testTypes) { + for (Submodel submodel : testTypes) { + storageAPI.createOrUpdate(submodel); + } } @Test public void update() { - storageAPI.createOrUpdate(testType); - testType.setIdShort("updated"); - Submodel actual = storageAPI.createOrUpdate(testType); + storageAPI.createOrUpdate(testSubmodel); + testSubmodel.setIdShort("updated"); + Submodel actual = storageAPI.update(testSubmodel, testSubmodel.getIdentification().getId()); - assertEquals(testType, actual); + assertEquals(testSubmodel, actual); + } + + @Test + public void updateShallServeAsCreate() { + Submodel actual = storageAPI.update(testSubmodel, testSubmodel.getIdentification().getId()); + + assertEquals(testSubmodel, actual); } @Test public void delete() { - System.out.println(testType); - storageAPI.createOrUpdate(testType); - assertTrue(storageAPI.delete(testType.getIdentification().getId())); + storageAPI.createOrUpdate(testSubmodel); + assertTrue(storageAPI.delete(testSubmodel.getIdentification().getId())); Collection allElements = storageAPI.retrieveAll(); - assertFalse(allElements.contains(testType)); + assertFalse(allElements.contains(testSubmodel)); + } + + @Test + public void proofPersistency() { + storageAPI.createOrUpdate(testSubmodel); + Submodel persistentSubmodel = getSecondStorageAPI().retrieve(testSubmodel.getIdentification().getId()); + assertEquals(testSubmodel, persistentSubmodel); } + + /** + * This test must be implemented individually for every storage backend + */ + @Test + public abstract void createCollectionIfNotExists(); + + /** + * This test must be implemented individually for every storage backend + */ + @Test + public abstract void deleteCollection(); + } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/storage/TestBaSyxStorageAPI.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/storage/TestBaSyxStorageAPI.java new file mode 100644 index 00000000..a9c8071d --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/storage/TestBaSyxStorageAPI.java @@ -0,0 +1,134 @@ +/******************************************************************************* + * Copyright (C) 2023 the Eclipse BaSyx Authors + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.testsuite.regression.extensions.storage; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.basyx.extensions.internal.storage.BaSyxStorageAPI; +import org.eclipse.basyx.submodel.metamodel.map.Submodel; +import org.mockito.Mockito; +import org.mockito.invocation.InvocationOnMock; + +/** + * + * @author jungjan + * + */ +public class TestBaSyxStorageAPI extends BaSyxStorageAPISuite { + private Map mockedStorage = new HashMap<>(); + + @SuppressWarnings("unchecked") + private BaSyxStorageAPI mockedStorageAPI = Mockito.spy(BaSyxStorageAPI.class); + + public TestBaSyxStorageAPI() { + super(); + initMockedStorageAPI(); + } + + private void initMockedStorageAPI() { + Mockito.when(mockedStorageAPI.createOrUpdate(Mockito.any(Submodel.class))).then(this::mockedCreateOrUpdate); + Mockito.when(mockedStorageAPI.update(Mockito.any(Submodel.class), Mockito.anyString())).then(this::mockedUpdate); + Mockito.when(mockedStorageAPI.rawRetrieve(Mockito.anyString())).then(this::mockedRawRetrieve); + Mockito.when(mockedStorageAPI.rawRetrieveAll()).then(this::mockedRawRetrieveAll); + Mockito.when(mockedStorageAPI.delete(Mockito.anyString())).then(this::mockedDelete); + } + + @Override + protected BaSyxStorageAPI getStorageAPI() { + return mockedStorageAPI; + } + + /** + * Please DON'T implement this method as below for Production tests. This method + * shall help proof the data persistency. Therefore in production this method + * must return a BaSyxStorageAPI that is not the same as the one returned by + * {@link #getStorageAPI()} + */ + @Override + protected BaSyxStorageAPI getSecondStorageAPI() { + return getStorageAPI(); + } + + private Submodel mockedCreateOrUpdate(InvocationOnMock invocation) { + Submodel submodel = invocation.getArgument(0); + return createOrUpdate(submodel); + } + + private Submodel createOrUpdate(Submodel submodel) { + String identificationId = submodel.getIdentification().getId(); + mockedStorage.put(identificationId, submodel); + return submodel; + } + + private Submodel mockedUpdate(InvocationOnMock invocation) { + String key = invocation.getArgument(1); + Submodel submodel = invocation.getArgument(0); + if (!mockedStorageHasKey(key)) { + createOrUpdate(submodel); + } + mockedStorage.put(key, submodel); + return submodel; + } + + private Submodel mockedRawRetrieve(InvocationOnMock invocation) { + String key = invocation.getArgument(0); + if (!mockedStorageHasKey(key)) { + return null; + } + return mockedStorage.get(key); + } + + private Collection mockedRawRetrieveAll(InvocationOnMock invocation) { + return this.mockedStorage.values(); + } + + private boolean mockedDelete(InvocationOnMock invocation) { + String key = invocation.getArgument(0); + if (!mockedStorageHasKey(key)) { + return false; + } + mockedStorage.remove(key); + return true; + } + + private boolean mockedStorageHasKey(String identificationId) { + return mockedStorage.containsKey(identificationId); + } + + @Override + public void createCollectionIfNotExists() { + mockedStorageAPI.createCollectionIfNotExists("testCollection"); + Mockito.verify(mockedStorageAPI, Mockito.times(1)).createCollectionIfNotExists("testCollection"); + } + + @Override + public void deleteCollection() { + mockedStorageAPI.deleteCollection(); + Mockito.verify(mockedStorageAPI, Mockito.times(1)).deleteCollection(); + } + +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SubmodelProviderTest.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SubmodelProviderTest.java index a24e5cc5..bf0fa004 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SubmodelProviderTest.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SubmodelProviderTest.java @@ -32,8 +32,8 @@ import java.util.ArrayList; import java.util.Collection; -import java.util.LinkedHashMap; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.Map; import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement; @@ -686,6 +686,26 @@ public void testInvokeAsyncException() throws Exception { } } + @SuppressWarnings("unchecked") + @Test + public void testIndirectSubmodelElementCollectionValueType() { + VABElementProxy submodelProvider = getConnectionManager().connectToVABElement(submodelAddr); + String containerRootPath = VABPathTools.concatenatePaths(SubmodelProvider.SUBMODEL, MultiSubmodelElementProvider.ELEMENTS, "containerRoot"); + Map directCollection = (Map) submodelProvider.getValue(containerRootPath); + Object indirectCollectionValue = directCollection.get(Property.VALUE); + + assertTrue(indirectCollectionValue instanceof Collection); + } + + @Test + public void testDirectSubmodelElementCollectionValueType() { + VABElementProxy submodelProvider = getConnectionManager().connectToVABElement(submodelAddr); + String containerRootValuePath = VABPathTools.concatenatePaths(SubmodelProvider.SUBMODEL, MultiSubmodelElementProvider.ELEMENTS, "containerRoot", Property.VALUE); + Object directCollectionValue = submodelProvider.getValue(containerRootValuePath); + + assertTrue(directCollectionValue instanceof Collection); + } + protected Map wrapParameter(String name, Object value) { Map param = new LinkedHashMap<>(); param.put(Identifiable.IDSHORT, name); From 5ec91d87945e044bb2c661fdfb5d45103d234adc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Jul 2023 07:50:03 +0000 Subject: [PATCH 47/77] Bump tomcat-catalina from 9.0.76 to 9.0.78 Bumps tomcat-catalina from 9.0.76 to 9.0.78. --- updated-dependencies: - dependency-name: org.apache.tomcat:tomcat-catalina dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 550fade0..b3d85073 100644 --- a/pom.xml +++ b/pom.xml @@ -256,7 +256,7 @@ org.apache.tomcat tomcat-catalina - 9.0.76 + 9.0.78 From ffe171070501e73d2e8729622143a53f01655dfe Mon Sep 17 00:00:00 2001 From: Daespen Date: Wed, 12 Jul 2023 15:32:23 +0200 Subject: [PATCH 48/77] Fixes file collisions for multiple aasx source files (#320) Signed-off-by: Daniel Espen --- .../aasx/AASXToMetamodelConverter.java | 9 +++ .../aasx/SubmodelFileEndpointLoader.java | 6 +- .../basyx/vab/modelprovider/VABPathTools.java | 13 ++++- ...TestAASXToMetamodelConverterFromBaSyx.java | 57 ++++++++++++------- .../vab/modelprovider/VABPathToolsTest.java | 4 ++ 5 files changed, 66 insertions(+), 23 deletions(-) diff --git a/src/main/java/org/eclipse/basyx/aas/factory/aasx/AASXToMetamodelConverter.java b/src/main/java/org/eclipse/basyx/aas/factory/aasx/AASXToMetamodelConverter.java index 9326f39c..cd3759f9 100644 --- a/src/main/java/org/eclipse/basyx/aas/factory/aasx/AASXToMetamodelConverter.java +++ b/src/main/java/org/eclipse/basyx/aas/factory/aasx/AASXToMetamodelConverter.java @@ -297,6 +297,15 @@ public void unzipRelatedFiles() throws IOException, ParserConfigurationException unzipRelatedFiles(getTemporaryDirPath()); } + /** + * Unzips all files referenced by the aasx file according to its relationships + * and a relative child path + */ + public void unzipRelatedFilesToChildPath(String childPath) throws IOException, ParserConfigurationException, SAXException, URISyntaxException, InvalidFormatException { + Path tempPath = getTemporaryDirPath().resolve(childPath); + unzipRelatedFiles(tempPath); + } + /** * Unzips all files referenced by the aasx file to a specified directory * diff --git a/src/main/java/org/eclipse/basyx/aas/factory/aasx/SubmodelFileEndpointLoader.java b/src/main/java/org/eclipse/basyx/aas/factory/aasx/SubmodelFileEndpointLoader.java index ae21277c..fa8ab873 100644 --- a/src/main/java/org/eclipse/basyx/aas/factory/aasx/SubmodelFileEndpointLoader.java +++ b/src/main/java/org/eclipse/basyx/aas/factory/aasx/SubmodelFileEndpointLoader.java @@ -34,6 +34,7 @@ import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File; +import org.eclipse.basyx.vab.modelprovider.VABPathTools; /** * A utility class for configuring file endpoints in submodels @@ -55,7 +56,8 @@ public class SubmodelFileEndpointLoader { * path at which the files are hosted on the host (e.g. "/files") */ public static void setRelativeFileEndpoints(ISubmodel submodel, String host, int port, String path) { - String fileRoot = "http://" + host + ":" + port + path; + String basePath = "http://" + host + ":" + port; + String fileRoot = VABPathTools.append(basePath, path); setRelativeFileEndpoints(submodel, fileRoot); } @@ -108,7 +110,7 @@ private static void setFileEndpoint(File file, String fileRoot) { } catch (MalformedURLException e1) { // assume that the file value is already a relative path } - String newEndpoint = fileRoot + relativePath; + String newEndpoint = VABPathTools.append(fileRoot, relativePath); file.setValue(newEndpoint); } } diff --git a/src/main/java/org/eclipse/basyx/vab/modelprovider/VABPathTools.java b/src/main/java/org/eclipse/basyx/vab/modelprovider/VABPathTools.java index 16cd1409..183e98b2 100644 --- a/src/main/java/org/eclipse/basyx/vab/modelprovider/VABPathTools.java +++ b/src/main/java/org/eclipse/basyx/vab/modelprovider/VABPathTools.java @@ -218,8 +218,17 @@ public static String append(String path, String element) { if (path == null || element == null) { return null; } - - if (path.lastIndexOf(SEPERATOR) == path.length() - 1) { + if (element.length() == 0) { + return path; + } + boolean lastPathCharIsSeperator = path.lastIndexOf(SEPERATOR) == path.length() - 1; + boolean firstElementCharIsSeparator = SEPERATOR.charAt(0) == element.charAt(0); + boolean atLeastOneSeparatorInTheMiddle = lastPathCharIsSeperator || firstElementCharIsSeparator; + boolean twoSeperatorsInTheMiddle = lastPathCharIsSeperator && firstElementCharIsSeparator; + + if (twoSeperatorsInTheMiddle) { + return path + element.substring(1); + } else if (atLeastOneSeparatorInTheMiddle) { return path + element; } else { return path + SEPERATOR + element; diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestAASXToMetamodelConverterFromBaSyx.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestAASXToMetamodelConverterFromBaSyx.java index 0310e285..6f41d8b3 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestAASXToMetamodelConverterFromBaSyx.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestAASXToMetamodelConverterFromBaSyx.java @@ -42,8 +42,10 @@ import java.util.Set; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; + import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerException; + import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; @@ -112,9 +114,9 @@ public class TestAASXToMetamodelConverterFromBaSyx { private static final String PDF_PATH = "/aasx/Document/docu.pdf"; private static final String PDF_MIMETYPE = "application/pdf"; private static final String PDF_IDSHORT = "pdf"; - private static final String TARGET_PATH = "/basyx-temp/files"; // gets set by BaSyx - private static final String[] EXPECTED_UNZIPPED_FILES = { TARGET_PATH + PDF_PATH, TARGET_PATH + IMAGE_PATH }; - private static final String[] EXPECTED_UNZIPPED_FILES_IN_TEMP_DIR = { PDF_PATH, IMAGE_PATH }; + private static final String BASYX_PATH = "/basyx-temp"; // gets set by BaSyx + private static final String FILES_PATH = "/files"; + private static final String[] EXPECTED_UNZIPPED_FILES = { PDF_PATH, IMAGE_PATH }; private static final String REL_PATH = "_rels/.rels"; private static final String ORIGIN_REL_PATH = "aasx/_rels/aasx-origin.rels"; @@ -127,7 +129,7 @@ public class TestAASXToMetamodelConverterFromBaSyx { private static final String TARGET_PATH_REGEX_START = "Target=.*"; private static final String TARGET_PATH_REGEX_FULL = "Target=\"/.*"; private static final String DOCPROPS_PATH_REGEX = "Target=\"docProps.*"; - + private static final byte[] THUMBNAIL = { 22, 23, 24, 25, 26 }; private int bundleSize; @@ -142,12 +144,12 @@ public void setup() throws IOException, TransformerException, ParserConfiguratio packageManager = new AASXToMetamodelConverter(CREATED_AASX_FILE_PATH); } - + @After public void close() { packageManager.close(); } - + @Test public void thumbnailInPackage() throws InvalidFormatException, IOException, ParserConfigurationException, SAXException { assertTrue(IOUtils.contentEquals(new ByteArrayInputStream(THUMBNAIL), packageManager.retrieveThumbnail())); @@ -224,7 +226,7 @@ public void testQualifierValue() throws Exception { ISubmodelElement operationWithQualifer = submodelElements.get(OPERATION_WITH_QUALIFIER_IDSHORT); IConstraint[] constraints = operationWithQualifer.getQualifiers().toArray(new IConstraint[] {}); - Qualifier qualifier = (Qualifier)constraints[0]; + Qualifier qualifier = (Qualifier) constraints[0]; assertEquals(QUALIFIER_VALUE, qualifier.getValue()); } @@ -241,12 +243,29 @@ public void testQualifierValue() throws Exception { public void testFilesOfGeneratedAASX() throws InvalidFormatException, IOException, ParserConfigurationException, SAXException, URISyntaxException { // Unzip files from the .aasx packageManager.unzipRelatedFiles(); - + String tempDirectory = FileUtils.getTempDirectory().getAbsolutePath(); // Check if all expected files are present - for (String path : EXPECTED_UNZIPPED_FILES) { - assertTrue(new java.io.File(tempDirectory + path).exists()); + for (String path : EXPECTED_UNZIPPED_FILES) { + String fullFilePath = tempDirectory + BASYX_PATH + FILES_PATH + path; + assertTrue(new java.io.File(fullFilePath).exists()); + } + } + + /** + * Tests the connected files of the parsed AASX file for subdirs + */ + @Test + public void testFilesOfGeneratedAASXChildPaths() throws InvalidFormatException, IOException, ParserConfigurationException, SAXException, URISyntaxException { + String childPath = "testChildPath"; + packageManager.unzipRelatedFilesToChildPath(childPath); + + String tempDirectory = FileUtils.getTempDirectory().getAbsolutePath(); + + for (String path : EXPECTED_UNZIPPED_FILES) { + String fullFilePath = tempDirectory + BASYX_PATH + "/" + childPath + FILES_PATH + path; + assertTrue(new java.io.File(fullFilePath).exists()); } } @@ -261,13 +280,13 @@ public void testFilesOfGeneratedAASX() throws InvalidFormatException, IOExceptio */ @Test public void testFilesUnzippedToSpecifiedDirectory() throws InvalidFormatException, IOException, ParserConfigurationException, SAXException, URISyntaxException { - Path pathToTempDir = Files.createTempDirectory("aasx"); - packageManager.unzipRelatedFiles(pathToTempDir); + Path pathToTempDir = Files.createTempDirectory("aasx"); + packageManager.unzipRelatedFiles(pathToTempDir); - for (String p : EXPECTED_UNZIPPED_FILES_IN_TEMP_DIR) { - Path path = Path.of(pathToTempDir.toString() + "/files" + p); - assertTrue(new java.io.File(path.toString()).exists()); - } + for (String p : EXPECTED_UNZIPPED_FILES) { + Path path = Path.of(pathToTempDir.toString() + "/files" + p); + assertTrue(new java.io.File(path.toString()).exists()); + } } /** @@ -483,9 +502,9 @@ private void createAASXFile(String filePath) throws IOException, TransformerExce fileList.add(createInMemoryFile(IMAGE_PATH)); fileList.add(createInMemoryFile(PDF_PATH)); submodelElementsSize = 8; - - Thumbnail thumbnail = new Thumbnail(ThumbnailExtension.PNG, new ByteArrayInputStream(THUMBNAIL)); - + + Thumbnail thumbnail = new Thumbnail(ThumbnailExtension.PNG, new ByteArrayInputStream(THUMBNAIL)); + try (FileOutputStream out = new FileOutputStream(filePath)) { MetamodelToAASXConverter.buildAASX(aasList, assetList, conceptDescriptionList, submodelList, fileList, thumbnail, out); } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/VABPathToolsTest.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/VABPathToolsTest.java index 79653173..119434bc 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/VABPathToolsTest.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/VABPathToolsTest.java @@ -185,8 +185,12 @@ public void testBuildPath() { public void testAppend() { assertEquals("/parent/child", VABPathTools.append("/parent", "child")); assertEquals("/parent/child", VABPathTools.append("/parent/", "child")); + assertEquals("/parent/child", VABPathTools.append("/parent", "/child")); + assertEquals("/parent/child", VABPathTools.append("/parent/", "/child")); assertEquals("/parent/x/child", VABPathTools.append("/parent/x", "child")); assertEquals("/parent/x/child", VABPathTools.append("/parent/x/", "child")); + assertEquals("/parent", VABPathTools.append("/parent", "")); + assertEquals("child", VABPathTools.append("", "child")); assertNull(VABPathTools.append(null, "")); assertNull(VABPathTools.append("", null)); } From 2fd6dd9d28abdaccf385ed6ac9ecd03beaa435ea Mon Sep 17 00:00:00 2001 From: Sebastian Eicke <134835859+seicke-harting@users.noreply.github.com> Date: Fri, 14 Jul 2023 12:00:44 +0200 Subject: [PATCH 49/77] Add (further) setIdentification Method to ConceptDescription --- .../submodel/metamodel/map/parts/ConceptDescription.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/parts/ConceptDescription.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/parts/ConceptDescription.java index 7e986ca1..efb061d7 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/parts/ConceptDescription.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/parts/ConceptDescription.java @@ -143,6 +143,10 @@ public void setAdministration(AdministrativeInformation information) { Identifiable.createAsFacade(this, getKeyElement()).setAdministration(information); } + public void setIdentification(IIdentifier id) { + setIdentification(id.getIdType(), id.getId()); + } + public void setIdentification(IdentifierType idType, String id) { Identifiable.createAsFacadeNonStrict(this, getKeyElement()).setIdentification(idType, id); } From f4bacc8322f717394b5129e61f5e31f4d8bd6040 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Jul 2023 08:04:17 +0000 Subject: [PATCH 50/77] Bump spring-security-bom from 5.8.4 to 5.8.5 Bumps [spring-security-bom](https://github.com/spring-projects/spring-security) from 5.8.4 to 5.8.5. - [Release notes](https://github.com/spring-projects/spring-security/releases) - [Changelog](https://github.com/spring-projects/spring-security/blob/main/RELEASE.adoc) - [Commits](https://github.com/spring-projects/spring-security/compare/5.8.4...5.8.5) --- updated-dependencies: - dependency-name: org.springframework.security:spring-security-bom dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b3d85073..50abfb7e 100644 --- a/pom.xml +++ b/pom.xml @@ -46,7 +46,7 @@ UTF-8 UTF-8 - 5.8.4 + 5.8.5 From 7373c31de03d6189bd0bc76c6c0c988b8e6a1ebe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 28 Jul 2023 07:23:20 +0000 Subject: [PATCH 51/77] Bump org.apache.commons:commons-lang3 from 3.12.0 to 3.13.0 Bumps org.apache.commons:commons-lang3 from 3.12.0 to 3.13.0. --- updated-dependencies: - dependency-name: org.apache.commons:commons-lang3 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b3d85073..669fb626 100644 --- a/pom.xml +++ b/pom.xml @@ -326,7 +326,7 @@ org.apache.commons commons-lang3 - 3.12.0 + 3.13.0 From 9b7f14312c41687a4d6f7a18b140be6d0e3f0988 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zai=20M=C3=BCller-Zhang?= <97607180+zhangzai123@users.noreply.github.com> Date: Fri, 28 Jul 2023 11:28:46 +0200 Subject: [PATCH 52/77] "make mongodb stateless", ignore the corner case unit test (#331) * Completely deleting unit-test submodelReferencesPresentAfterUpdate() and its private methods. Signed-off-by: Zai Zhang --- .../aas/aggregator/AASAggregatorSuite.java | 40 ------------------- 1 file changed, 40 deletions(-) diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/AASAggregatorSuite.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/AASAggregatorSuite.java index 68b9b5fb..f434073b 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/AASAggregatorSuite.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/AASAggregatorSuite.java @@ -31,21 +31,15 @@ import java.util.Collection; import org.eclipse.basyx.aas.aggregator.api.IAASAggregator; -import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider; -import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager; import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell; import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind; import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn; import org.eclipse.basyx.aas.metamodel.map.parts.Asset; -import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry; import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType; -import org.eclipse.basyx.submodel.metamodel.map.Submodel; import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier; import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings; import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException; -import org.eclipse.basyx.vab.modelprovider.api.IModelProvider; -import org.eclipse.basyx.vab.protocol.api.IConnectorFactory; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -150,40 +144,6 @@ public void testUpdate() throws Exception { assertEquals(aas1AltCategory, aas.getCategory()); } - @Test - public void submodelReferencesPresentAfterUpdate() { - IAASAggregator aggregator = getAggregator(); - - ModelUrn aasUrn = new ModelUrn(aas1Id); - - ConnectedAssetAdministrationShellManager manager = createConnectedAASManager(aggregator); - manager.createAAS(aas1, ""); - - Submodel submodel = createSubmodel("testSm", "testSmIdentifier"); - manager.createSubmodel(aasUrn, submodel); - - aggregator.updateAAS(aas1); - - assertEquals(submodel.getIdShort(), manager.retrieveSubmodel(aasUrn, submodel.getIdentification()).getIdShort()); - } - - private Submodel createSubmodel(String idShort, String customId) { - String submodelId = idShort; - Identifier submodelIdentifier = new Identifier(IdentifierType.CUSTOM, customId); - Submodel submodel = new Submodel(submodelId, submodelIdentifier); - return submodel; - } - - private ConnectedAssetAdministrationShellManager createConnectedAASManager(IAASAggregator aggregator) { - return new ConnectedAssetAdministrationShellManager(new InMemoryRegistry(), new IConnectorFactory() { - - @Override - public IModelProvider getConnector(String addr) { - return new AASAggregatorProvider(aggregator); - } - }); - } - @Test public void testDelete() throws Exception { IAASAggregator aggregator = getAggregator(); From 16e236282e1fabb668f21ae1f14c56a0adc6b6cf Mon Sep 17 00:00:00 2001 From: Markus Damm <125889012+M-Damm@users.noreply.github.com> Date: Mon, 31 Jul 2023 07:55:10 +0200 Subject: [PATCH 53/77] fixed file upload bug and corresponding test (#329) * fixed file upload bug and corresponding test * additional fix with aasx upload --- .../aas/aggregator/aasxupload/AASAggregatorAASXUpload.java | 2 +- .../org/eclipse/basyx/submodel/restapi/SubmodelProvider.java | 2 +- .../regression/submodel/restapi/TestHttpFileUpload.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/aasxupload/AASAggregatorAASXUpload.java b/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/aasxupload/AASAggregatorAASXUpload.java index b371b883..95ea0927 100644 --- a/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/aasxupload/AASAggregatorAASXUpload.java +++ b/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/aasxupload/AASAggregatorAASXUpload.java @@ -99,7 +99,7 @@ private void uploadNestedFiles(IIdentifier aasIdentification, AASXToMetamodelCon private void uploadFileInSubmodelElement(IIdentifier aasIdentification, AASXToMetamodelConverter converter, File submodelElement, String submodelElementPath) { try { - getAASProvider(aasIdentification).createValue(submodelElementPath + "/File/upload", converter.retrieveFileInputStream((String) submodelElement.getValue())); + getAASProvider(aasIdentification).createValue(submodelElementPath + "/upload", converter.retrieveFileInputStream((String) submodelElement.getValue())); } catch (InvalidFormatException | IOException e) { e.printStackTrace(); } diff --git a/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelProvider.java b/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelProvider.java index 4990fb13..8aa8dc3d 100644 --- a/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelProvider.java +++ b/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelProvider.java @@ -349,7 +349,7 @@ private boolean endsWithFileUpload(String[] splitted) { private String getFileIdShortFromSplittedPath4FileUpload(String[] splitted) { String idShort = ""; - for (int i = 1; i < splitted.length - 2; i++) { + for (int i = 1; i < splitted.length - 1; i++) { idShort = concatFileIdShortPath(splitted, idShort, i); } return idShort; diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/TestHttpFileUpload.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/TestHttpFileUpload.java index 6b2fd2d0..3c740fbe 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/TestHttpFileUpload.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/TestHttpFileUpload.java @@ -129,7 +129,7 @@ private CloseableHttpResponse uploadDummyFileToSubmodelElement(String submodelEl HttpPost uploadFile = new HttpPost( API_URL + "/basyx.examples.test/aas/submodels/test_sm/submodel/submodelElements/" - + submodelElementIdShort + "/File/upload"); + + submodelElementIdShort + "/upload"); MultipartEntityBuilder builder = MultipartEntityBuilder.create(); builder.addPart("file", new FileBody(file)); From a48f9f7c928950ed5d798f0abdf9284a5050e735 Mon Sep 17 00:00:00 2001 From: Daespen Date: Mon, 31 Jul 2023 10:02:22 +0200 Subject: [PATCH 54/77] Fixes File idShort collisions (#324) Signed-off-by: Daniel Espen --- .../submodel/restapi/SubmodelProvider.java | 11 +- .../restapi/SubmodelProviderTest.java | 111 ++++++++++++++++++ 2 files changed, 121 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelProvider.java b/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelProvider.java index 8aa8dc3d..750a1f5f 100644 --- a/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelProvider.java +++ b/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelProvider.java @@ -39,6 +39,7 @@ import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter; import org.eclipse.basyx.submodel.metamodel.facade.submodelelement.SubmodelElementFacadeFactory; import org.eclipse.basyx.submodel.metamodel.map.Submodel; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueTypeHelper; @@ -379,9 +380,17 @@ private String getIdShortFromSplittedPath(String[] splitted) { @SuppressWarnings("unchecked") private Object handleFile(String[] splitted) { String idShortPath = getFileIdShortFromSplittedPath4FileDownload(splitted); + + if (idShortPath.isEmpty()) { + return submodelAPI.getSubmodelElement(FILE); + } + Map submodelElement = (Map) submodelAPI.getSubmodelElement(idShortPath); - if (!File.isFile(submodelElement)) { + if (SubmodelElementCollection.isSubmodelElementCollection(submodelElement)) { + SubmodelElementCollection smeCollection = SubmodelElementCollection.createAsFacade(submodelElement); + return smeCollection.getSubmodelElement(FILE); + } else if (!File.isFile(submodelElement)) { throw new MalformedRequestException("/File is only allowed for File Submodel Elements"); } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SubmodelProviderTest.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SubmodelProviderTest.java index bf0fa004..9afc9b5f 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SubmodelProviderTest.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SubmodelProviderTest.java @@ -42,6 +42,7 @@ import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable; import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueTypeHelper; @@ -67,6 +68,8 @@ public class SubmodelProviderTest { private VABConnectionManager connManager; protected static final String submodelAddr = "urn:fhg:es.iese:aas:1:1:submodel"; protected static final String SMPROVIDER_PATH_PREFIX = "/" + SubmodelProvider.SUBMODEL + "/"; + protected static final String SIMPLE_FILE_VALUE = "simpleFile.xml"; + protected static final String SIMPLE_PROPERTY_VALUE = "simpleProperty"; protected VABConnectionManager getConnectionManager() { if (connManager == null) { @@ -391,6 +394,114 @@ public void testUpdateElementInSmElementCollection() { assertEquals(321, value.intValue()); } + @SuppressWarnings("unchecked") + @Test + public void collectionIdShortFileCollision() { + VABElementProxy submodelProxy = getConnectionManager().connectToVABElement(submodelAddr); + + String colIdShort = "Files"; + String fileIdShort = "File"; + + SubmodelElementCollection fileCollection = new SubmodelElementCollection(colIdShort); + File fileSubmodelElement = new File("application/xml"); + String fileValue = "simpleFile.xml"; + fileSubmodelElement.setValue(fileValue); + fileSubmodelElement.setIdShort(fileIdShort); + fileCollection.addSubmodelElement(fileSubmodelElement); + + String smeCollectionPath = VABPathTools.concatenatePaths(SMPROVIDER_PATH_PREFIX, MultiSubmodelElementProvider.ELEMENTS, colIdShort); + submodelProxy.setValue(smeCollectionPath, fileCollection); + + String fileValuePath = VABPathTools.concatenatePaths(smeCollectionPath, fileIdShort); + Map resultingFileMap = (Map) submodelProxy.getValue(fileValuePath); + File resultingFile = File.createAsFacade(resultingFileMap); + assertEquals(fileValue, resultingFile.getValue()); + } + + /** + * Test getting a File with "File" as IdShort + */ + @Test + public void getFileSubmodelElement() { + VABElementProxy submodelProxy = getConnectionManager().connectToVABElement(submodelAddr); + String fileIdShort = "MySimpleFile"; + createSimpleFile(submodelProxy, fileIdShort); + assertSimpleFileValue(submodelProxy, fileIdShort); + } + + @Test + public void getIdShortCollision() { + VABElementProxy submodelProxy = getConnectionManager().connectToVABElement(submodelAddr); + String fileIdShort = "File"; + + Property fileProperty = new Property(fileIdShort, SIMPLE_PROPERTY_VALUE); + String propertyAccessPath = VABPathTools.concatenatePaths(SMPROVIDER_PATH_PREFIX, MultiSubmodelElementProvider.ELEMENTS, fileIdShort); + submodelProxy.setValue(propertyAccessPath, fileProperty); + + assertSimplePropertyValue(submodelProxy, fileIdShort); + } + + @Test + public void getFileIdShortCollision() { + VABElementProxy submodelProxy = getConnectionManager().connectToVABElement(submodelAddr); + String fileIdShort = "File"; + createSimpleFile(submodelProxy, fileIdShort); + assertSimpleFileValue(submodelProxy, fileIdShort); + } + + private void createSimpleFile(VABElementProxy submodelProxy, String fileIdShort) { + File fileSubmodelElement = new File("application/xml"); + fileSubmodelElement.setValue(SIMPLE_FILE_VALUE); + fileSubmodelElement.setIdShort(fileIdShort); + + String fileAccessPath = VABPathTools.concatenatePaths(SMPROVIDER_PATH_PREFIX, MultiSubmodelElementProvider.ELEMENTS, fileIdShort); + submodelProxy.setValue(fileAccessPath, fileSubmodelElement); + } + + @SuppressWarnings("unchecked") + private void assertSimpleFileValue(VABElementProxy submodelProxy, String fileIdShort) { + String fileAccessPath = VABPathTools.concatenatePaths(SMPROVIDER_PATH_PREFIX, MultiSubmodelElementProvider.ELEMENTS, fileIdShort); + Map resultingFileMap = (Map) submodelProxy.getValue(fileAccessPath); + File resultingFile = File.createAsFacade(resultingFileMap); + assertEquals(SIMPLE_FILE_VALUE, resultingFile.getValue()); + } + + @SuppressWarnings("unchecked") + private void assertSimplePropertyValue(VABElementProxy submodelProxy, String propertyIdShort) { + String accessPath = VABPathTools.concatenatePaths(SMPROVIDER_PATH_PREFIX, MultiSubmodelElementProvider.ELEMENTS, propertyIdShort); + Map resultingPropertyMap = (Map) submodelProxy.getValue(accessPath); + Property resultingProperty = Property.createAsFacade(resultingPropertyMap); + assertEquals(SIMPLE_PROPERTY_VALUE, resultingProperty.getValue()); + } + + @SuppressWarnings("unchecked") + @Test + public void nestedCollectionIdShortFileCollision() { + VABElementProxy submodelProxy = getConnectionManager().connectToVABElement(submodelAddr); + + String fileIdShort = "File"; + File fileSubmodelElement = new File("application/xml"); + String fileValue = "simpleFile.xml"; + fileSubmodelElement.setValue(fileValue); + fileSubmodelElement.setIdShort(fileIdShort); + + String innerColIdShort = "Files"; + SubmodelElementCollection innerCollection = new SubmodelElementCollection(innerColIdShort); + innerCollection.addSubmodelElement(fileSubmodelElement); + + String outerColIdShort = "Files"; + SubmodelElementCollection outerCollection = new SubmodelElementCollection(outerColIdShort); + outerCollection.addSubmodelElement(innerCollection); + + String outerCollectionPath = VABPathTools.concatenatePaths(SMPROVIDER_PATH_PREFIX, MultiSubmodelElementProvider.ELEMENTS, outerColIdShort); + submodelProxy.setValue(outerCollectionPath, outerCollection); + + String fileValuePath = VABPathTools.concatenatePaths(outerCollectionPath, innerColIdShort, fileIdShort); + Map resultingFileMap = (Map) submodelProxy.getValue(fileValuePath); + File resultingFile = File.createAsFacade(resultingFileMap); + assertEquals(fileValue, resultingFile.getValue()); + } + /** * Test reading a single operation */ From 6e988559f7b452d78e4e888096b88a2319c8912a Mon Sep 17 00:00:00 2001 From: Rene-Pascal Fischer Date: Mon, 31 Jul 2023 11:04:53 +0200 Subject: [PATCH 55/77] Reworks comments and names of file tests --- .../restapi/SubmodelProviderTest.java | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SubmodelProviderTest.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SubmodelProviderTest.java index 9afc9b5f..2d5e5533 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SubmodelProviderTest.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SubmodelProviderTest.java @@ -394,9 +394,13 @@ public void testUpdateElementInSmElementCollection() { assertEquals(321, value.intValue()); } + /** + * Test getting a file in a collection having the "File" keyword as the start of + * its IdShort. + */ @SuppressWarnings("unchecked") @Test - public void collectionIdShortFileCollision() { + public void getFileFromCollectionWithFileKeywordCollision() { VABElementProxy submodelProxy = getConnectionManager().connectToVABElement(submodelAddr); String colIdShort = "Files"; @@ -419,18 +423,22 @@ public void collectionIdShortFileCollision() { } /** - * Test getting a File with "File" as IdShort + * Test getting a file with a non colliding IdShort. */ @Test - public void getFileSubmodelElement() { + public void getSimpleFileSubmodelElement() { VABElementProxy submodelProxy = getConnectionManager().connectToVABElement(submodelAddr); String fileIdShort = "MySimpleFile"; createSimpleFile(submodelProxy, fileIdShort); assertSimpleFileValue(submodelProxy, fileIdShort); } + /** + * Test getting a property that happens to have the "File" keyword as its + * IdShort. + */ @Test - public void getIdShortCollision() { + public void getPropertyWithFileKeywordCollision() { VABElementProxy submodelProxy = getConnectionManager().connectToVABElement(submodelAddr); String fileIdShort = "File"; @@ -441,8 +449,11 @@ public void getIdShortCollision() { assertSimplePropertyValue(submodelProxy, fileIdShort); } + /** + * Test getting a File with the "File" keyword as its IdShort. + */ @Test - public void getFileIdShortCollision() { + public void getFileWithFileKeywordCollision() { VABElementProxy submodelProxy = getConnectionManager().connectToVABElement(submodelAddr); String fileIdShort = "File"; createSimpleFile(submodelProxy, fileIdShort); From 917d504c3c66416b17ffbf10155c489e9604e5f5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Aug 2023 07:52:40 +0000 Subject: [PATCH 56/77] Bump ch.qos.logback:logback-classic from 1.4.8 to 1.4.9 Bumps [ch.qos.logback:logback-classic](https://github.com/qos-ch/logback) from 1.4.8 to 1.4.9. - [Commits](https://github.com/qos-ch/logback/compare/v_1.4.8...v_1.4.9) --- updated-dependencies: - dependency-name: ch.qos.logback:logback-classic dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index feb87d10..7a3260b9 100644 --- a/pom.xml +++ b/pom.xml @@ -169,7 +169,7 @@ ch.qos.logback logback-classic - 1.4.8 + 1.4.9 runtime From 92eb4d81bae3dacd4bc1cf805a0a2a5fe198e66f Mon Sep 17 00:00:00 2001 From: Jannik Fried Date: Thu, 10 Aug 2023 08:30:14 +0200 Subject: [PATCH 57/77] Harmonizes interface to use most specific class as return value --- .../org/eclipse/basyx/submodel/restapi/vab/VABSubmodelAPI.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/org/eclipse/basyx/submodel/restapi/vab/VABSubmodelAPI.java b/src/main/java/org/eclipse/basyx/submodel/restapi/vab/VABSubmodelAPI.java index 3ce9a036..51bc8978 100644 --- a/src/main/java/org/eclipse/basyx/submodel/restapi/vab/VABSubmodelAPI.java +++ b/src/main/java/org/eclipse/basyx/submodel/restapi/vab/VABSubmodelAPI.java @@ -36,7 +36,6 @@ import org.apache.tika.mime.MimeType; import org.apache.tika.mime.MimeTypeException; import org.apache.tika.mime.MimeTypes; -import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement; import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation; import org.eclipse.basyx.submodel.metamodel.map.Submodel; @@ -90,7 +89,7 @@ private MultiSubmodelElementProvider getElementProvider() { @SuppressWarnings("unchecked") @Override - public ISubmodel getSubmodel() { + public Submodel getSubmodel() { // For access on the container property root, return the whole model Map map = (Map) modelProvider.getValue(SubmodelAPIHelper.getSubmodelPath()); From e91f6ab32384269b47a674b864f33034290d2272 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 10 Aug 2023 08:03:35 +0000 Subject: [PATCH 58/77] Bump ch.qos.logback:logback-classic from 1.4.9 to 1.4.11 Bumps [ch.qos.logback:logback-classic](https://github.com/qos-ch/logback) from 1.4.9 to 1.4.11. - [Commits](https://github.com/qos-ch/logback/compare/v_1.4.9...v_1.4.11) --- updated-dependencies: - dependency-name: ch.qos.logback:logback-classic dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7a3260b9..e7ba30ec 100644 --- a/pom.xml +++ b/pom.xml @@ -169,7 +169,7 @@ ch.qos.logback logback-classic - 1.4.9 + 1.4.11 runtime From 6d78c768c1014d60b244a7c278b471ecb8c33010 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Aug 2023 08:03:36 +0000 Subject: [PATCH 59/77] Bump org.apache.tomcat:tomcat-catalina from 9.0.78 to 9.0.79 Bumps org.apache.tomcat:tomcat-catalina from 9.0.78 to 9.0.79. --- updated-dependencies: - dependency-name: org.apache.tomcat:tomcat-catalina dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e7ba30ec..82624c4a 100644 --- a/pom.xml +++ b/pom.xml @@ -256,7 +256,7 @@ org.apache.tomcat tomcat-catalina - 9.0.78 + 9.0.79 From fe79a31d77a359eef493a32d86446a30c416efa0 Mon Sep 17 00:00:00 2001 From: Sebastian Eicke <134835859+seicke-harting@users.noreply.github.com> Date: Wed, 16 Aug 2023 13:04:26 +0200 Subject: [PATCH 60/77] Generalised EmbeddedDataSpecification (#337) * Update EmbeddedDataSpecification.java Generalised EmbeddedDataSpecification to comply not only with the IEC 61360 template * Update EmbeddedDataSpecification.java Delete unnecessary import --- .../map/dataspecification/EmbeddedDataSpecification.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/EmbeddedDataSpecification.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/EmbeddedDataSpecification.java index 79520d67..291dd88d 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/EmbeddedDataSpecification.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/EmbeddedDataSpecification.java @@ -27,7 +27,6 @@ import java.util.Map; import org.eclipse.basyx.submodel.metamodel.api.dataspecification.IDataSpecificationContent; -import org.eclipse.basyx.submodel.metamodel.api.dataspecification.IDataSpecificationIEC61360Content; import org.eclipse.basyx.submodel.metamodel.api.dataspecification.IEmbeddedDataSpecification; import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; import org.eclipse.basyx.submodel.metamodel.map.reference.Reference; @@ -68,12 +67,10 @@ public void setDataSpecificationTemplate(IReference ref) { @SuppressWarnings("unchecked") @Override public IDataSpecificationContent getContent() { - // Assume the concent complies to the IEC61360 template - // => only this template is supported currently - return DataSpecificationIEC61360Content.createAsFacade((Map) get(CONTENT)); + return DataSpecificationContent.createAsFacade((Map) get(CONTENT)); } - public void setContent(IDataSpecificationIEC61360Content content) { + public void setContent(IDataSpecificationContent content) { put(CONTENT, content); } } From f92e9f04d8fafbb922683676ab1db4b8c51389a9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Aug 2023 07:34:37 +0000 Subject: [PATCH 61/77] Bump org.springframework.security:spring-security-bom Bumps [org.springframework.security:spring-security-bom](https://github.com/spring-projects/spring-security) from 5.8.5 to 5.8.6. - [Release notes](https://github.com/spring-projects/spring-security/releases) - [Changelog](https://github.com/spring-projects/spring-security/blob/main/RELEASE.adoc) - [Commits](https://github.com/spring-projects/spring-security/compare/5.8.5...5.8.6) --- updated-dependencies: - dependency-name: org.springframework.security:spring-security-bom dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 82624c4a..604d7d08 100644 --- a/pom.xml +++ b/pom.xml @@ -46,7 +46,7 @@ UTF-8 UTF-8 - 5.8.5 + 5.8.6 From 8bb070f8f137098d174184041dce7c7ee80c3f16 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 23 Aug 2023 07:52:23 +0000 Subject: [PATCH 62/77] Bump org.mockito:mockito-core from 5.4.0 to 5.5.0 Bumps [org.mockito:mockito-core](https://github.com/mockito/mockito) from 5.4.0 to 5.5.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v5.4.0...v5.5.0) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 604d7d08..6acc544d 100644 --- a/pom.xml +++ b/pom.xml @@ -192,7 +192,7 @@ org.mockito mockito-core - 5.4.0 + 5.5.0 test From 5dfbdb776e680da77c07ba2693b8332ddc460b9a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Aug 2023 07:20:28 +0000 Subject: [PATCH 63/77] Bump org.apache.tomcat:tomcat-catalina from 9.0.79 to 9.0.80 Bumps org.apache.tomcat:tomcat-catalina from 9.0.79 to 9.0.80. --- updated-dependencies: - dependency-name: org.apache.tomcat:tomcat-catalina dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6acc544d..a1d3bfc3 100644 --- a/pom.xml +++ b/pom.xml @@ -256,7 +256,7 @@ org.apache.tomcat tomcat-catalina - 9.0.79 + 9.0.80 From 8be71dde8b2fdc332d774d59d8f0aa5264284159 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 29 Aug 2023 07:47:02 +0000 Subject: [PATCH 64/77] Bump org.apache.tika:tika-core from 2.8.0 to 2.9.0 Bumps [org.apache.tika:tika-core](https://github.com/apache/tika) from 2.8.0 to 2.9.0. - [Changelog](https://github.com/apache/tika/blob/main/CHANGES.txt) - [Commits](https://github.com/apache/tika/compare/2.8.0...2.9.0) --- updated-dependencies: - dependency-name: org.apache.tika:tika-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6acc544d..f7aba07d 100644 --- a/pom.xml +++ b/pom.xml @@ -375,7 +375,7 @@ org.apache.tika tika-core - 2.8.0 + 2.9.0 From 3ea5ea74e92b7511703e0fd5866c88200d1b1725 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Sep 2023 07:59:06 +0000 Subject: [PATCH 65/77] Bump org.slf4j:slf4j-api from 2.0.7 to 2.0.9 Bumps org.slf4j:slf4j-api from 2.0.7 to 2.0.9. --- updated-dependencies: - dependency-name: org.slf4j:slf4j-api dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6acc544d..200eff4b 100644 --- a/pom.xml +++ b/pom.xml @@ -176,7 +176,7 @@ org.slf4j slf4j-api - 2.0.7 + 2.0.9 From e4585509e6d537cd7ebcec92d6cd9aff6f935490 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Sep 2023 07:44:25 +0000 Subject: [PATCH 66/77] Bump actions/checkout from 3 to 4 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] --- .github/workflows/maven-publish-snapshot.yml | 2 +- .github/workflows/maven-run-tests.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/maven-publish-snapshot.yml b/.github/workflows/maven-publish-snapshot.yml index 2b4aa922..695f51d2 100644 --- a/.github/workflows/maven-publish-snapshot.yml +++ b/.github/workflows/maven-publish-snapshot.yml @@ -18,7 +18,7 @@ jobs: packages: write steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up JDK 11 uses: actions/setup-java@v3 with: diff --git a/.github/workflows/maven-run-tests.yml b/.github/workflows/maven-run-tests.yml index 99fb60c8..3ca8e4e9 100644 --- a/.github/workflows/maven-run-tests.yml +++ b/.github/workflows/maven-run-tests.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up JDK 11 uses: actions/setup-java@v3 with: From ff8dd1dd3f872a82253b15c3e034572c6c6d6840 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zai=20M=C3=BCller-Zhang?= <97607180+zhangzai123@users.noreply.github.com> Date: Wed, 6 Sep 2023 13:03:46 +0200 Subject: [PATCH 67/77] Make MongDb stateless, add create(Identifier aasIdentifier) into IAASAPIFactory to prevent that MongoDb creates new AAS every time whenn fetching the provider (#343) Signed-off-by: Zai Zhang Co-authored-by: Rene-Pascal Fischer --- .../org/eclipse/basyx/aas/restapi/AASAPIFactory.java | 6 ++++++ .../basyx/aas/restapi/api/IAASAPIFactory.java | 7 +++++++ .../basyx/aas/restapi/vab/VABAASAPIFactory.java | 8 ++++++++ .../AuthorizedDecoratingAASAPIFactory.java | 6 ++++++ .../internal/AuthorizedDecoratingAASAPIFactory.java | 6 ++++++ .../aas/api/mqtt/MqttDecoratingAASAPIFactory.java | 12 +++++++++++- 6 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/eclipse/basyx/aas/restapi/AASAPIFactory.java b/src/main/java/org/eclipse/basyx/aas/restapi/AASAPIFactory.java index 0e19b076..226dede7 100644 --- a/src/main/java/org/eclipse/basyx/aas/restapi/AASAPIFactory.java +++ b/src/main/java/org/eclipse/basyx/aas/restapi/AASAPIFactory.java @@ -28,6 +28,7 @@ import org.eclipse.basyx.aas.restapi.api.IAASAPI; import org.eclipse.basyx.aas.restapi.api.IAASAPIFactory; import org.eclipse.basyx.aas.restapi.vab.VABAASAPIFactory; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; /** * AAS API provider that provides the default AAS API @@ -50,4 +51,9 @@ public IAASAPI getAASApi(AssetAdministrationShell aas) { return aasAPIFactory.create(aas); } + @Override + public IAASAPI create(IIdentifier aasId) { + return aasAPIFactory.create(aasId); + } + } diff --git a/src/main/java/org/eclipse/basyx/aas/restapi/api/IAASAPIFactory.java b/src/main/java/org/eclipse/basyx/aas/restapi/api/IAASAPIFactory.java index 1acff459..48030acd 100644 --- a/src/main/java/org/eclipse/basyx/aas/restapi/api/IAASAPIFactory.java +++ b/src/main/java/org/eclipse/basyx/aas/restapi/api/IAASAPIFactory.java @@ -25,6 +25,8 @@ package org.eclipse.basyx.aas.restapi.api; import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; +import org.eclipse.basyx.vab.exception.FeatureNotImplementedException; /** * Interface for providing an AAS API @@ -44,7 +46,12 @@ public interface IAASAPIFactory { @Deprecated public IAASAPI getAASApi(AssetAdministrationShell aas); + public default IAASAPI create(AssetAdministrationShell aas) { return getAASApi(aas); } + + public default IAASAPI create(IIdentifier aasId) { + throw new FeatureNotImplementedException(); + } } diff --git a/src/main/java/org/eclipse/basyx/aas/restapi/vab/VABAASAPIFactory.java b/src/main/java/org/eclipse/basyx/aas/restapi/vab/VABAASAPIFactory.java index 5f45b2c5..bae7df78 100644 --- a/src/main/java/org/eclipse/basyx/aas/restapi/vab/VABAASAPIFactory.java +++ b/src/main/java/org/eclipse/basyx/aas/restapi/vab/VABAASAPIFactory.java @@ -27,6 +27,8 @@ import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; import org.eclipse.basyx.aas.restapi.api.IAASAPI; import org.eclipse.basyx.aas.restapi.api.IAASAPIFactory; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; +import org.eclipse.basyx.vab.exception.FeatureNotImplementedException; import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider; /** @@ -39,4 +41,10 @@ public class VABAASAPIFactory implements IAASAPIFactory { public IAASAPI getAASApi(AssetAdministrationShell aas) { return new VABAASAPI(new VABLambdaProvider(aas)); } + + @Override + public IAASAPI create(IIdentifier aasId) { + // This should not be used for VABAASAPI + throw new FeatureNotImplementedException(); + } } diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/api/authorization/AuthorizedDecoratingAASAPIFactory.java b/src/main/java/org/eclipse/basyx/extensions/aas/api/authorization/AuthorizedDecoratingAASAPIFactory.java index a86f4e78..3f570057 100644 --- a/src/main/java/org/eclipse/basyx/extensions/aas/api/authorization/AuthorizedDecoratingAASAPIFactory.java +++ b/src/main/java/org/eclipse/basyx/extensions/aas/api/authorization/AuthorizedDecoratingAASAPIFactory.java @@ -12,6 +12,7 @@ import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; import org.eclipse.basyx.aas.restapi.api.IAASAPI; import org.eclipse.basyx.aas.restapi.api.IAASAPIFactory; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; /** * Api provider for constructing a new AAS API that is authorized @@ -29,4 +30,9 @@ public AuthorizedDecoratingAASAPIFactory(IAASAPIFactory factoryToBeDecorated) { public IAASAPI getAASApi(AssetAdministrationShell aas) { return new AuthorizedAASAPI(apiFactory.create(aas)); } + + @Override + public IAASAPI create(IIdentifier aasId) { + return new AuthorizedAASAPI(apiFactory.create(aasId)); + } } \ No newline at end of file diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/api/authorization/internal/AuthorizedDecoratingAASAPIFactory.java b/src/main/java/org/eclipse/basyx/extensions/aas/api/authorization/internal/AuthorizedDecoratingAASAPIFactory.java index 431798c5..ad00d0de 100644 --- a/src/main/java/org/eclipse/basyx/extensions/aas/api/authorization/internal/AuthorizedDecoratingAASAPIFactory.java +++ b/src/main/java/org/eclipse/basyx/extensions/aas/api/authorization/internal/AuthorizedDecoratingAASAPIFactory.java @@ -28,6 +28,7 @@ import org.eclipse.basyx.aas.restapi.api.IAASAPI; import org.eclipse.basyx.aas.restapi.api.IAASAPIFactory; import org.eclipse.basyx.extensions.shared.authorization.internal.ISubjectInformationProvider; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; /** * Api provider for constructing a new AAS API that is authorized @@ -50,4 +51,9 @@ public AuthorizedDecoratingAASAPIFactory(final IAASAPIFactory factoryToBeDecorat public IAASAPI getAASApi(final AssetAdministrationShell aas) { return new AuthorizedAASAPI<>(apiFactory.create(aas), aasAPIAuthorizer, subjectInformationProvider); } + + @Override + public IAASAPI create(IIdentifier aasId) { + return new AuthorizedAASAPI<>(apiFactory.create(aasId), aasAPIAuthorizer, subjectInformationProvider); + } } \ No newline at end of file diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/api/mqtt/MqttDecoratingAASAPIFactory.java b/src/main/java/org/eclipse/basyx/extensions/aas/api/mqtt/MqttDecoratingAASAPIFactory.java index 1923269c..a556a725 100644 --- a/src/main/java/org/eclipse/basyx/extensions/aas/api/mqtt/MqttDecoratingAASAPIFactory.java +++ b/src/main/java/org/eclipse/basyx/extensions/aas/api/mqtt/MqttDecoratingAASAPIFactory.java @@ -13,6 +13,7 @@ import org.eclipse.basyx.aas.restapi.api.IAASAPI; import org.eclipse.basyx.aas.restapi.api.IAASAPIFactory; import org.eclipse.basyx.aas.restapi.observing.ObservableAASAPI; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; import org.eclipse.basyx.vab.exception.provider.ProviderException; import org.eclipse.paho.client.mqttv3.MqttClient; import org.eclipse.paho.client.mqttv3.MqttException; @@ -33,8 +34,12 @@ public MqttDecoratingAASAPIFactory(IAASAPIFactory factoryToBeDecorated, MqttClie @Override public IAASAPI getAASApi(AssetAdministrationShell aas) { + return createMqttDecoratingAASAPI(apiFactory.create(aas)); + } + + private IAASAPI createMqttDecoratingAASAPI(IAASAPI aasAPI) { try { - ObservableAASAPI observedAPI = new ObservableAASAPI(apiFactory.create(aas)); + ObservableAASAPI observedAPI = new ObservableAASAPI(aasAPI); MqttAASAPIObserver mqttAASAPIObserver = new MqttAASAPIObserver(client, MqttAASAPIHelper.getAASIdShort(observedAPI)); observedAPI.addObserver(mqttAASAPIObserver); return observedAPI; @@ -42,4 +47,9 @@ public IAASAPI getAASApi(AssetAdministrationShell aas) { throw new ProviderException(e); } } + + @Override + public IAASAPI create(IIdentifier aasId) { + return createMqttDecoratingAASAPI(apiFactory.create(aasId)); + } } \ No newline at end of file From 14feb21013cf5de866a28d513ac3515f75243787 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Sep 2023 07:43:46 +0000 Subject: [PATCH 68/77] Bump org.eclipse.milo:sdk-client from 0.6.10 to 0.6.11 Bumps org.eclipse.milo:sdk-client from 0.6.10 to 0.6.11. --- updated-dependencies: - dependency-name: org.eclipse.milo:sdk-client dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 72f6d382..30a7b712 100644 --- a/pom.xml +++ b/pom.xml @@ -214,7 +214,7 @@ org.eclipse.milo sdk-client - 0.6.10 + 0.6.11 From b50b19c8cb83b9fbaa18860316c142b17eaa0637 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Sep 2023 07:43:56 +0000 Subject: [PATCH 69/77] Bump org.eclipse.milo:sdk-server from 0.6.10 to 0.6.11 Bumps org.eclipse.milo:sdk-server from 0.6.10 to 0.6.11. --- updated-dependencies: - dependency-name: org.eclipse.milo:sdk-server dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 72f6d382..5227b312 100644 --- a/pom.xml +++ b/pom.xml @@ -221,7 +221,7 @@ org.eclipse.milo sdk-server - 0.6.10 + 0.6.11 From bb6dffd61b3645c287aa899d48d7bfd04a97517d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Sep 2023 07:18:04 +0000 Subject: [PATCH 70/77] Bump org.apache.commons:commons-compress from 1.23.0 to 1.24.0 Bumps org.apache.commons:commons-compress from 1.23.0 to 1.24.0. --- updated-dependencies: - dependency-name: org.apache.commons:commons-compress dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 72f6d382..896fe930 100644 --- a/pom.xml +++ b/pom.xml @@ -269,7 +269,7 @@ org.apache.commons commons-compress - 1.23.0 + 1.24.0 From 8080b56021ec189b6caeb3f97e50ed68c04ffb83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zai=20M=C3=BCller-Zhang?= <97607180+zhangzai123@users.noreply.github.com> Date: Tue, 12 Sep 2023 06:13:57 +0200 Subject: [PATCH 71/77] Merge two @Before Methods in AASAggregatorSuite into one to clean up (#350) Signed-off-by: Zai Zhang --- .../aas/aggregator/AASAggregatorSuite.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/AASAggregatorSuite.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/AASAggregatorSuite.java index f434073b..fe30fe55 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/AASAggregatorSuite.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/AASAggregatorSuite.java @@ -66,8 +66,7 @@ public abstract class AASAggregatorSuite { private static final String aas2Category = "TestCategory2"; // initializing dummy test data - @Before - public void initAASDummies() { + private void initAASDummies() { aas1 = new AssetAdministrationShell(aas1Id, new Identifier(IdentifierType.CUSTOM, aas1Id), new Asset("asset1IdShort", new Identifier(IdentifierType.CUSTOM, "asset1"), AssetKind.INSTANCE)); aas1.setDescription(description1); aas1.setCategory(aas1Category); @@ -79,12 +78,17 @@ public void initAASDummies() { protected abstract IAASAggregator getAggregator(); - @Before - public void clearAASAggregator() { + private void clearAASAggregator() { IAASAggregator aggregator = getAggregator(); aggregator.getAASList().stream().map(a -> a.getIdentification()).forEach(id -> aggregator.deleteAAS(id)); } + @Before + public void setup() { + initAASDummies(); + clearAASAggregator(); + } + @Test public void testCreateAndGetAAS() { IAASAggregator aggregator = getAggregator(); From cd87ca1a653f2dccfdf3604e5e0d867bf6261650 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Sep 2023 07:36:51 +0000 Subject: [PATCH 72/77] Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.5.0 to 3.6.0 Bumps [org.apache.maven.plugins:maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.5.0 to 3.6.0. - [Release notes](https://github.com/apache/maven-javadoc-plugin/releases) - [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.5.0...maven-javadoc-plugin-3.6.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-javadoc-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 33f7aa17..1d9054aa 100644 --- a/pom.xml +++ b/pom.xml @@ -147,7 +147,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.5.0 + 3.6.0 8 From c33c267797c5effc2cf8e944763c1b3139aba049 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 07:47:23 +0000 Subject: [PATCH 73/77] Bump org.springframework.security:spring-security-bom Bumps [org.springframework.security:spring-security-bom](https://github.com/spring-projects/spring-security) from 5.8.6 to 5.8.7. - [Release notes](https://github.com/spring-projects/spring-security/releases) - [Changelog](https://github.com/spring-projects/spring-security/blob/main/RELEASE.adoc) - [Commits](https://github.com/spring-projects/spring-security/compare/5.8.6...5.8.7) --- updated-dependencies: - dependency-name: org.springframework.security:spring-security-bom dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 33f7aa17..be3a18c2 100644 --- a/pom.xml +++ b/pom.xml @@ -46,7 +46,7 @@ UTF-8 UTF-8 - 5.8.6 + 5.8.7 From 9bf6ce2eef95aeb6cb1c2789d753f02f86afb423 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Oct 2023 07:06:44 +0000 Subject: [PATCH 74/77] Bump commons-io:commons-io from 2.13.0 to 2.14.0 Bumps commons-io:commons-io from 2.13.0 to 2.14.0. --- updated-dependencies: - dependency-name: commons-io:commons-io dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 33f7aa17..84b3db85 100644 --- a/pom.xml +++ b/pom.xml @@ -298,7 +298,7 @@ commons-io commons-io - 2.13.0 + 2.14.0 From 6127bb50e17d49c843e0aaf417e8ac5ed1e3169e Mon Sep 17 00:00:00 2001 From: Frank Schnicke Date: Wed, 4 Oct 2023 07:13:10 +0200 Subject: [PATCH 75/77] Removes warnings Signed-off-by: Frank Schnicke --- .../authorization/internal/AuthorizedAASRegistry.java | 2 +- .../authorization/internal/KeycloakRoleAuthenticator.java | 2 ++ .../authorization/internal/RbacRuleSetDeserializer.java | 1 + .../basyx/vab/protocol/http/server/BaSyxContext.java | 6 +++--- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/registration/authorization/internal/AuthorizedAASRegistry.java b/src/main/java/org/eclipse/basyx/extensions/aas/registration/authorization/internal/AuthorizedAASRegistry.java index defa31c4..18b8c2be 100644 --- a/src/main/java/org/eclipse/basyx/extensions/aas/registration/authorization/internal/AuthorizedAASRegistry.java +++ b/src/main/java/org/eclipse/basyx/extensions/aas/registration/authorization/internal/AuthorizedAASRegistry.java @@ -30,6 +30,7 @@ import java.util.List; import java.util.Objects; import java.util.stream.Collectors; + import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor; import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor; @@ -40,7 +41,6 @@ import org.eclipse.basyx.extensions.shared.authorization.internal.ISubjectInformationProvider; import org.eclipse.basyx.extensions.shared.authorization.internal.InhibitException; import org.eclipse.basyx.extensions.shared.authorization.internal.NotAuthorizedException; -import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; import org.eclipse.basyx.vab.exception.provider.ProviderException; diff --git a/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/KeycloakRoleAuthenticator.java b/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/KeycloakRoleAuthenticator.java index 492e5827..bf8c6034 100644 --- a/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/KeycloakRoleAuthenticator.java +++ b/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/KeycloakRoleAuthenticator.java @@ -30,6 +30,7 @@ import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.core.context.SecurityContextHolder; @@ -97,6 +98,7 @@ private List getResoureAccessRoles(JwtAuthenticationToken token) { return resourceAccess.values().stream().map(this::getCategoryRoles).flatMap(List::stream).collect(Collectors.toList()); } + @SuppressWarnings("unchecked") private List getCategoryRoles(Object categoryObject) { final Map category = (Map) categoryObject; diff --git a/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/RbacRuleSetDeserializer.java b/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/RbacRuleSetDeserializer.java index 705d108a..771b5467 100644 --- a/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/RbacRuleSetDeserializer.java +++ b/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/RbacRuleSetDeserializer.java @@ -127,6 +127,7 @@ private InputStream getInputStreamFromFile(final String filePath) throws IOExcep throw new IOException("could not find " + filePath); } + @SuppressWarnings("unused") private static class RbacRuleMultiple { String role; String[] actions; diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BaSyxContext.java b/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BaSyxContext.java index f820aa8a..21e6b4bd 100644 --- a/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BaSyxContext.java +++ b/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BaSyxContext.java @@ -24,16 +24,16 @@ ******************************************************************************/ package org.eclipse.basyx.vab.protocol.http.server; -import org.apache.catalina.Context; -import org.springframework.lang.Nullable; - import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Optional; + import javax.servlet.http.HttpServlet; +import org.springframework.lang.Nullable; + /** * BaSyx context that contains an Industrie 4.0 Servlet infrastructure * From 585419c414b5d466c225b0c358399eef6717caf4 Mon Sep 17 00:00:00 2001 From: FlorianWege-IESE Date: Wed, 4 Oct 2023 08:04:17 +0200 Subject: [PATCH 76/77] Fix PredefindeSetRbacRuleChecker target info type check Signed-off-by: FlorianWege-IESE --- .../PredefinedSetRbacRuleChecker.java | 20 +++++++++++++------ .../internal/TagTargetInformation.java | 2 +- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/PredefinedSetRbacRuleChecker.java b/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/PredefinedSetRbacRuleChecker.java index 693a7d3b..f04d1645 100644 --- a/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/PredefinedSetRbacRuleChecker.java +++ b/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/PredefinedSetRbacRuleChecker.java @@ -75,15 +75,23 @@ private boolean checkActionMatchesRbacRule(final RbacRule rbacRule, final String return rbacRule.getAction().equals("*") || rbacRule.getAction().equals(action); } - private boolean checkRbacRuleMatchesTargetInformation(final RbacRule rbacRule, final TargetInformation targetInformation) { - final Map targetInformationMap = targetInformation.toMap(); + private boolean checkRbacRuleMatchesTargetInformation(final RbacRule rbacRule, final TargetInformation matchTargetInformation) { + final TargetInformation rbacRuleTargetInformation = rbacRule.getTargetInformation(); + if (!rbacRuleTargetInformation.getClass().isAssignableFrom(matchTargetInformation.getClass())) { + // return false if the type of the target is not the same or a subtype of the target information specified in the rbac rule + // otherwise two target information objects of unrelated types may be found equal if their properties match since + // the type property is not considered + return false; + } + + final Map matchTargetInformationMap = matchTargetInformation.toMap(); final Map rbacRuleTargetInformationMap = rbacRule.getTargetInformation().toMap(); - for (final Map.Entry targetInfo : targetInformationMap.entrySet()) { - final String key = targetInfo.getKey(); - final String targetInfoValue = targetInfo.getValue(); + for (final Map.Entry matchTargetInformationMapEntry : matchTargetInformationMap.entrySet()) { + final String key = matchTargetInformationMapEntry.getKey(); + final String matchTargetInformationSingleValue = matchTargetInformationMapEntry.getValue(); final String rbacRuleValue = rbacRuleTargetInformationMap.get(key); - if (!checkRegexStringMatch(rbacRuleValue, targetInfoValue)) { + if (!checkRegexStringMatch(rbacRuleValue, matchTargetInformationSingleValue)) { return false; } } diff --git a/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/TagTargetInformation.java b/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/TagTargetInformation.java index de2f8919..285c23a2 100644 --- a/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/TagTargetInformation.java +++ b/src/main/java/org/eclipse/basyx/extensions/shared/authorization/internal/TagTargetInformation.java @@ -81,6 +81,6 @@ public int hashCode() { @Override public String toString() { - return new StringBuilder("BaSyxObjectTargetInformation{").append("tag='").append(tag).append('\'').append('}').toString(); + return new StringBuilder("TagTargetInformation{").append("tag='").append(tag).append('\'').append('}').toString(); } } From ccb5a3625a627d51bf729d53408aa01474c60605 Mon Sep 17 00:00:00 2001 From: Frank Schnicke Date: Wed, 4 Oct 2023 09:02:46 +0200 Subject: [PATCH 77/77] Updates Version to 1.5.0 Signed-off-by: Frank Schnicke --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c4c58583..6edd9cdb 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.eclipse.basyx basyx.sdk - 1.5.0-SNAPSHOT + 1.5.0 BaSyx SDK BaSyx Software Development Kit https://www.eclipse.org/basyx/