diff --git a/basyx.aasregistry/basyx.aasregistry-feature-authorization/pom.xml b/basyx.aasregistry/basyx.aasregistry-feature-authorization/pom.xml
index d36eeabcd..be57092e4 100644
--- a/basyx.aasregistry/basyx.aasregistry-feature-authorization/pom.xml
+++ b/basyx.aasregistry/basyx.aasregistry-feature-authorization/pom.xml
@@ -61,5 +61,9 @@
org.eclipse.digitaltwin.basyx
basyx.authorization.rules.rbac.backend.inmemory
+
+ org.eclipse.digitaltwin.basyx
+ basyx.authorization.rules.rbac.backend.submodel
+
diff --git a/basyx.aasregistry/basyx.aasregistry-feature-authorization/src/main/java/org/eclipse/digitaltwin/basyx/aasregistry/feature/authorization/AuthorizedAasRegistryConfiguration.java b/basyx.aasregistry/basyx.aasregistry-feature-authorization/src/main/java/org/eclipse/digitaltwin/basyx/aasregistry/feature/authorization/AuthorizedAasRegistryConfiguration.java
index 8c34ce5f7..b59a03471 100644
--- a/basyx.aasregistry/basyx.aasregistry-feature-authorization/src/main/java/org/eclipse/digitaltwin/basyx/aasregistry/feature/authorization/AuthorizedAasRegistryConfiguration.java
+++ b/basyx.aasregistry/basyx.aasregistry-feature-authorization/src/main/java/org/eclipse/digitaltwin/basyx/aasregistry/feature/authorization/AuthorizedAasRegistryConfiguration.java
@@ -26,12 +26,14 @@
package org.eclipse.digitaltwin.basyx.aasregistry.feature.authorization;
import org.eclipse.digitaltwin.basyx.aasregistry.feature.authorization.rbac.AasRegistryTargetPermissionVerifier;
+import org.eclipse.digitaltwin.basyx.aasregistry.feature.authorization.rbac.backend.submodel.AasRegistryTargetInformationAdapter;
import org.eclipse.digitaltwin.basyx.authorization.CommonAuthorizationProperties;
import org.eclipse.digitaltwin.basyx.authorization.rbac.RbacPermissionResolver;
import org.eclipse.digitaltwin.basyx.authorization.rbac.RbacStorage;
import org.eclipse.digitaltwin.basyx.authorization.rbac.RoleProvider;
import org.eclipse.digitaltwin.basyx.authorization.rbac.SimpleRbacPermissionResolver;
import org.eclipse.digitaltwin.basyx.authorization.rbac.TargetPermissionVerifier;
+import org.eclipse.digitaltwin.basyx.authorization.rules.rbac.backend.submodel.TargetInformationAdapter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -54,5 +56,11 @@ public TargetPermissionVerifier getAasTargetPermis
public RbacPermissionResolver getAasPermissionResolver(RbacStorage rbacStorage, RoleProvider roleProvider, TargetPermissionVerifier targetPermissionVerifier) {
return new SimpleRbacPermissionResolver<>(rbacStorage, roleProvider, targetPermissionVerifier);
}
+
+ @Bean
+ public TargetInformationAdapter getAasRegistryTargetInformationAdapter() {
+
+ return new AasRegistryTargetInformationAdapter();
+ }
}
diff --git a/basyx.aasregistry/basyx.aasregistry-feature-authorization/src/main/java/org/eclipse/digitaltwin/basyx/aasregistry/feature/authorization/rbac/backend/submodel/AasRegistryTargetInformationAdapter.java b/basyx.aasregistry/basyx.aasregistry-feature-authorization/src/main/java/org/eclipse/digitaltwin/basyx/aasregistry/feature/authorization/rbac/backend/submodel/AasRegistryTargetInformationAdapter.java
new file mode 100644
index 000000000..ee37eaadf
--- /dev/null
+++ b/basyx.aasregistry/basyx.aasregistry-feature-authorization/src/main/java/org/eclipse/digitaltwin/basyx/aasregistry/feature/authorization/rbac/backend/submodel/AasRegistryTargetInformationAdapter.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (C) 2024 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.digitaltwin.basyx.aasregistry.feature.authorization.rbac.backend.submodel;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.eclipse.digitaltwin.aas4j.v3.model.Property;
+import org.eclipse.digitaltwin.aas4j.v3.model.SubmodelElement;
+import org.eclipse.digitaltwin.aas4j.v3.model.SubmodelElementCollection;
+import org.eclipse.digitaltwin.aas4j.v3.model.SubmodelElementList;
+import org.eclipse.digitaltwin.aas4j.v3.model.impl.DefaultProperty;
+import org.eclipse.digitaltwin.aas4j.v3.model.impl.DefaultSubmodelElementCollection;
+import org.eclipse.digitaltwin.aas4j.v3.model.impl.DefaultSubmodelElementList;
+import org.eclipse.digitaltwin.basyx.aasregistry.feature.authorization.AasRegistryTargetInformation;
+import org.eclipse.digitaltwin.basyx.authorization.rbac.TargetInformation;
+import org.eclipse.digitaltwin.basyx.authorization.rules.rbac.backend.submodel.TargetInformationAdapter;
+import org.eclipse.digitaltwin.basyx.core.exceptions.InvalidTargetInformationException;
+
+/**
+ * An implementation of the {@link TargetInformationAdapter} to adapt with Aas
+ * {@link TargetInformation}
+ *
+ * @author danish
+ */
+public class AasRegistryTargetInformationAdapter implements TargetInformationAdapter {
+
+ @Override
+ public SubmodelElementCollection adapt(TargetInformation targetInformation) {
+
+ SubmodelElementCollection targetInformationSMC = new DefaultSubmodelElementCollection.Builder().idShort("targetInformation").build();
+
+ SubmodelElementList aasId = new DefaultSubmodelElementList.Builder().idShort("aasIds").build();
+
+ List aasIds = ((AasRegistryTargetInformation) targetInformation).getAasIds().stream().map(this::transform).collect(Collectors.toList());
+ aasId.setValue(aasIds);
+
+ targetInformationSMC.setValue(Arrays.asList(aasId));
+
+ return targetInformationSMC;
+ }
+
+ @Override
+ public TargetInformation adapt(SubmodelElementCollection targetInformation) {
+
+ SubmodelElement aasIdSubmodelElement = targetInformation.getValue().stream().filter(sme -> sme.getIdShort().equals("aasIds")).findAny().orElseThrow(
+ () -> new InvalidTargetInformationException("The TargetInformation defined in the SubmodelElementCollection Rule with id: " + targetInformation.getIdShort() + " is not compatible with the " + getClass().getName()));
+
+ if (!(aasIdSubmodelElement instanceof SubmodelElementList))
+ throw new InvalidTargetInformationException("The TargetInformation defined in the SubmodelElementCollection Rule with id: " + targetInformation.getIdShort() + " is not compatible with the " + getClass().getName());
+
+ SubmodelElementList aasIdList = (SubmodelElementList) aasIdSubmodelElement;
+
+ List aasIds = aasIdList.getValue().stream().map(Property.class::cast).map(Property::getValue).collect(Collectors.toList());
+
+ return new AasRegistryTargetInformation(aasIds);
+ }
+
+ private Property transform(String aasId) {
+ return new DefaultProperty.Builder().value(aasId).build();
+ }
+
+}
diff --git a/basyx.aasregistry/basyx.aasregistry-feature-authorization/src/test/java/org/eclipse/digitaltwin/basyx/aasregistry/regression/feature/authorization/AasRegistryTargetInformationAdapterTest.java b/basyx.aasregistry/basyx.aasregistry-feature-authorization/src/test/java/org/eclipse/digitaltwin/basyx/aasregistry/regression/feature/authorization/AasRegistryTargetInformationAdapterTest.java
new file mode 100644
index 000000000..d3bac91be
--- /dev/null
+++ b/basyx.aasregistry/basyx.aasregistry-feature-authorization/src/test/java/org/eclipse/digitaltwin/basyx/aasregistry/regression/feature/authorization/AasRegistryTargetInformationAdapterTest.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (C) 2024 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.digitaltwin.basyx.aasregistry.regression.feature.authorization;
+
+import static org.junit.Assert.*;
+import org.eclipse.digitaltwin.aas4j.v3.model.Property;
+import org.eclipse.digitaltwin.aas4j.v3.model.SubmodelElement;
+import org.eclipse.digitaltwin.aas4j.v3.model.SubmodelElementCollection;
+import org.eclipse.digitaltwin.aas4j.v3.model.SubmodelElementList;
+import org.eclipse.digitaltwin.aas4j.v3.model.impl.DefaultProperty;
+import org.eclipse.digitaltwin.aas4j.v3.model.impl.DefaultSubmodelElementCollection;
+import org.eclipse.digitaltwin.aas4j.v3.model.impl.DefaultSubmodelElementList;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.eclipse.digitaltwin.basyx.aasregistry.feature.authorization.AasRegistryTargetInformation;
+import org.eclipse.digitaltwin.basyx.aasregistry.feature.authorization.rbac.backend.submodel.AasRegistryTargetInformationAdapter;
+import org.eclipse.digitaltwin.basyx.authorization.rbac.TargetInformation;
+import org.eclipse.digitaltwin.basyx.core.exceptions.InvalidTargetInformationException;
+
+/**
+ * Tests {@link AasRegistryTargetInformationAdapter}
+ *
+ * @author danish
+ */
+public class AasRegistryTargetInformationAdapterTest {
+
+ private AasRegistryTargetInformationAdapter aasRegistryTargetInformationAdapter;
+
+ @Before
+ public void setUp() {
+ aasRegistryTargetInformationAdapter = new AasRegistryTargetInformationAdapter();
+ }
+
+ @Test
+ public void testAdaptTargetInformationToSubmodelElementCollection() {
+
+ List aasIds = Arrays.asList("aasId1", "aasId2");
+ TargetInformation targetInformation = new AasRegistryTargetInformation(aasIds);
+
+ SubmodelElementCollection result = aasRegistryTargetInformationAdapter.adapt(targetInformation);
+
+ assertEquals("targetInformation", result.getIdShort());
+
+ List elements = result.getValue();
+ assertEquals(1, elements.size());
+
+ SubmodelElementList aasIdList = (SubmodelElementList) elements.get(0);
+ assertEquals("aasIds", aasIdList.getIdShort());
+
+ List actualAasIds = aasIdList.getValue().stream().map(Property.class::cast).map(Property::getValue).map(String::valueOf).collect(Collectors.toList());
+ assertEquals(aasIds, actualAasIds);
+ }
+
+ @Test
+ public void testAdaptSubmodelElementCollectionToTargetInformation() {
+
+ List expectedAasIds = Arrays.asList("aasId1", "aasId2");
+ List aasIdProperties = expectedAasIds.stream().map(aasId -> new DefaultProperty.Builder().value(aasId).build()).collect(Collectors.toList());
+
+ SubmodelElementList aasIdList = new DefaultSubmodelElementList.Builder().idShort("aasIds").value(aasIdProperties).build();
+
+ SubmodelElementCollection targetInformationSMC = new DefaultSubmodelElementCollection.Builder().idShort("targetInformation").value(Collections.singletonList(aasIdList)).build();
+
+ TargetInformation result = aasRegistryTargetInformationAdapter.adapt(targetInformationSMC);
+
+ assertTrue(result instanceof AasRegistryTargetInformation);
+ assertEquals(expectedAasIds, ((AasRegistryTargetInformation) result).getAasIds());
+ }
+
+ @Test
+ public void testAdaptTargetInformationWithEmptyAasIds() {
+
+ List aasIds = Collections.emptyList();
+ TargetInformation targetInformation = new AasRegistryTargetInformation(aasIds);
+
+ SubmodelElementCollection result = aasRegistryTargetInformationAdapter.adapt(targetInformation);
+
+ assertEquals("targetInformation", result.getIdShort());
+
+ List elements = result.getValue();
+ assertEquals(1, elements.size());
+
+ SubmodelElementList aasIdList = (SubmodelElementList) elements.get(0);
+ assertEquals("aasIds", aasIdList.getIdShort());
+
+ List actualAasIds = aasIdList.getValue().stream()
+ .map(Property.class::cast)
+ .map(Property::getValue)
+ .map(String::valueOf)
+ .collect(Collectors.toList());
+ assertTrue(actualAasIds.isEmpty());
+ }
+
+ @Test(expected = InvalidTargetInformationException.class)
+ public void testAdaptSubmodelElementCollectionWithInvalidStructure() {
+
+ SubmodelElementCollection targetInformationSMC = new DefaultSubmodelElementCollection.Builder().idShort("targetInformation")
+ .value(Collections.singletonList(new DefaultProperty.Builder().idShort("invalidElement").value("value").build()))
+ .build();
+
+ aasRegistryTargetInformationAdapter.adapt(targetInformationSMC);
+ }
+
+ @Test(expected = InvalidTargetInformationException.class)
+ public void testAdaptSubmodelElementCollectionWithoutAasIds() {
+
+ SubmodelElementCollection targetInformationSMC = new DefaultSubmodelElementCollection.Builder().idShort("targetInformation")
+ .value(Collections.emptyList())
+ .build();
+
+ aasRegistryTargetInformationAdapter.adapt(targetInformationSMC);
+ }
+
+}