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] 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