From 3354b92fbe062ba44974281f76b0ce3759c568e3 Mon Sep 17 00:00:00 2001 From: Hussein Ahmed Date: Mon, 23 Mar 2026 17:00:27 +0100 Subject: [PATCH] update IT for add ns field to policy entry --- .../authorization/PolicyEnforcementIT.java | 63 +++++++++++++++ .../rest/ThingsWithImportedPoliciesIT.java | 76 +++++++++++++++++++ 2 files changed, 139 insertions(+) diff --git a/system/src/test/java/org/eclipse/ditto/testing/system/things/authorization/PolicyEnforcementIT.java b/system/src/test/java/org/eclipse/ditto/testing/system/things/authorization/PolicyEnforcementIT.java index 5340de7..455e55f 100644 --- a/system/src/test/java/org/eclipse/ditto/testing/system/things/authorization/PolicyEnforcementIT.java +++ b/system/src/test/java/org/eclipse/ditto/testing/system/things/authorization/PolicyEnforcementIT.java @@ -24,6 +24,7 @@ import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.HashSet; import java.util.concurrent.TimeUnit; @@ -157,6 +158,38 @@ public void getThingWithoutGrantedRead() { .fire(); } + @Test + public void getThingWithNamespaceScopedPolicyEntry() { + final PolicyId policyId = + PolicyId.of(idGenerator().withPrefixedRandomName("getThingWithNamespaceScopedPolicyEntry")); + final Policy policy = createPolicyRootAndNamespaceScopedAccess(policyId, defaultClientSubjectId, + client2SubjectId, "com.acme", "READ"); + final ThingId allowedThingId = ThingId.of("com.acme", idGenerator().withRandomName()); + final ThingId deniedThingId = ThingId.of("other.ns", idGenerator().withRandomName()); + + putPolicy(policy) + .expectingHttpStatus(HttpStatus.CREATED) + .fire(); + + putThing(API_V_2, Thing.newBuilder().setId(allowedThingId).setPolicyId(policyId).build(), JsonSchemaVersion.V_2) + .expectingHttpStatus(CREATED) + .fire(); + + putThing(API_V_2, Thing.newBuilder().setId(deniedThingId).setPolicyId(policyId).build(), JsonSchemaVersion.V_2) + .expectingHttpStatus(CREATED) + .fire(); + + getThing(API_V_2, allowedThingId) + .withConfiguredAuth(serviceEnv.getTestingContext2()) + .expectingHttpStatus(HttpStatus.OK) + .fire(); + + getThing(API_V_2, deniedThingId) + .withConfiguredAuth(serviceEnv.getTestingContext2()) + .expectingHttpStatus(HttpStatus.NOT_FOUND) + .fire(); + } + @Test public void postThingAlterPolicyForReadAccess() { final ThingId thingId = ThingId.of(idGenerator().withRandomName()); @@ -931,6 +964,36 @@ private static Policy createPolicyRootAndAdditionalAccessWithRevoke(final Policy return PoliciesModelFactory.newPolicy(policyId, entry1, entry2); } + private static Policy createPolicyRootAndNamespaceScopedAccess(final PolicyId policyId, + final SubjectId rootUser, + final SubjectId additionalUser, + final String namespace, + final String additionalGrantedPermission) { + + final EffectedPermissions permissionsAll = + EffectedPermissions.newInstance(collect("READ", "WRITE"), Permissions.none()); + final EffectedPermissions permissionsAdditional = EffectedPermissions.newInstance( + Permissions.newInstance("READ", additionalGrantedPermission), Permissions.none()); + final PolicyEntry rootEntry = PoliciesModelFactory.newPolicyEntry( + Label.of("rootUser"), + Subjects.newInstance(PoliciesModelFactory.newSubject(rootUser, SubjectType.GENERATED)), + PoliciesModelFactory.newResources( + Resource.newInstance(ResourceKey.newInstance("policy:"), permissionsAll), + Resource.newInstance(ResourceKey.newInstance("thing:"), permissionsAll))); + + final PolicyEntry scopedEntry = PoliciesModelFactory.newPolicyEntry( + Label.of("namespaceScopedUser"), + Subjects.newInstance( + PoliciesModelFactory.newSubject(additionalUser, ARBITRARY_SUBJECT_TYPE)), + PoliciesModelFactory.newResources( + Resource.newInstance(ResourceKey.newInstance("thing:"), permissionsAdditional)), + Arrays.asList(namespace, namespace + ".*"), + org.eclipse.ditto.policies.model.ImportableType.IMPLICIT, + Collections.emptySet()); + + return PoliciesModelFactory.newPolicy(policyId, rootEntry, scopedEntry); + } + private static Policy createDefaultPolicy(final SubjectId user, final PolicyId policyId) { return createDefaultPolicy(user, policyId, Label.of("DEFAULT")); } diff --git a/system/src/test/java/org/eclipse/ditto/testing/system/things/rest/ThingsWithImportedPoliciesIT.java b/system/src/test/java/org/eclipse/ditto/testing/system/things/rest/ThingsWithImportedPoliciesIT.java index aa00b4e..ab6c233 100644 --- a/system/src/test/java/org/eclipse/ditto/testing/system/things/rest/ThingsWithImportedPoliciesIT.java +++ b/system/src/test/java/org/eclipse/ditto/testing/system/things/rest/ThingsWithImportedPoliciesIT.java @@ -15,26 +15,102 @@ import static org.eclipse.ditto.things.api.Permission.READ; import static org.eclipse.ditto.things.api.Permission.WRITE; +import java.util.Arrays; import java.util.List; import java.util.UUID; import org.eclipse.ditto.base.model.common.HttpStatus; import org.eclipse.ditto.json.JsonObject; import org.eclipse.ditto.policies.model.EffectedImports; +import org.eclipse.ditto.policies.model.EffectedPermissions; import org.eclipse.ditto.policies.model.ImportableType; import org.eclipse.ditto.policies.model.Label; +import org.eclipse.ditto.policies.model.Permissions; import org.eclipse.ditto.policies.model.PoliciesModelFactory; import org.eclipse.ditto.policies.model.PoliciesResourceType; import org.eclipse.ditto.policies.model.Policy; +import org.eclipse.ditto.policies.model.PolicyEntry; import org.eclipse.ditto.policies.model.PolicyId; +import org.eclipse.ditto.policies.model.Resource; +import org.eclipse.ditto.policies.model.ResourceKey; import org.eclipse.ditto.testing.common.IntegrationTest; import org.eclipse.ditto.testing.common.TestConstants; import org.eclipse.ditto.things.model.Thing; +import org.eclipse.ditto.things.model.ThingId; import org.eclipse.ditto.things.model.signals.commands.modify.CreateThing; import org.junit.Test; public final class ThingsWithImportedPoliciesIT extends IntegrationTest { + @Test + public void getThingWithNamespaceScopedAuthorizationInImportedPolicy() { + final PolicyId importedPolicyId = + PolicyId.of(serviceEnv.getDefaultNamespaceName(), UUID.randomUUID().toString()); + final PolicyId importingPolicyId = + PolicyId.of(serviceEnv.getDefaultNamespaceName(), UUID.randomUUID().toString()); + final ThingId allowedThingId = ThingId.of("com.acme", UUID.randomUUID().toString()); + final ThingId deniedThingId = ThingId.of("other.ns", UUID.randomUUID().toString()); + + final EffectedPermissions ownerPermissions = EffectedPermissions.newInstance( + PoliciesModelFactory.newPermissions(READ, WRITE), Permissions.none()); + final PolicyEntry ownerEntry = PoliciesModelFactory.newPolicyEntry( + Label.of("OWNER"), + PoliciesModelFactory.newSubjects(serviceEnv.getDefaultTestingContext().getOAuthClient().getDefaultSubject()), + PoliciesModelFactory.newResources( + Resource.newInstance(ResourceKey.newInstance("policy:"), ownerPermissions), + Resource.newInstance(ResourceKey.newInstance("thing:"), ownerPermissions))); + final PolicyEntry scopedReaderEntry = PoliciesModelFactory.newPolicyEntry( + Label.of("SCOPED_READER"), + PoliciesModelFactory.newSubjects(serviceEnv.getTestingContext2().getOAuthClient().getDefaultSubject()), + PoliciesModelFactory.newResources( + Resource.newInstance(ResourceKey.newInstance("thing:"), + EffectedPermissions.newInstance(PoliciesModelFactory.newPermissions(READ), + Permissions.none()))), + Arrays.asList("com.acme", "com.acme.*"), + ImportableType.EXPLICIT, + java.util.Collections.emptySet()); + final Policy importedPolicy = PoliciesModelFactory.newPolicy(importedPolicyId, ownerEntry, scopedReaderEntry); + + putPolicy(importedPolicy) + .expectingHttpStatus(HttpStatus.CREATED) + .fire(); + + final Policy importingPolicy = Policy.newBuilder(importingPolicyId) + .forLabel("OWNER") + .setSubject(serviceEnv.getDefaultTestingContext().getOAuthClient().getDefaultSubject()) + .setGrantedPermissions(PoliciesResourceType.policyResource("/"), READ, WRITE) + .setGrantedPermissions(PoliciesResourceType.thingResource("/"), READ, WRITE) + .setPolicyImport(PoliciesModelFactory.newPolicyImport(importedPolicyId, + EffectedImports.newInstance(List.of(Label.of("SCOPED_READER"))))) + .build(); + + putPolicy(importingPolicy) + .expectingHttpStatus(HttpStatus.CREATED) + .fire(); + + putThing(TestConstants.API_V_2, + Thing.newBuilder().setId(allowedThingId).setPolicyId(importingPolicyId).build(), + org.eclipse.ditto.base.model.json.JsonSchemaVersion.V_2) + .expectingHttpStatus(HttpStatus.CREATED) + .fire(); + + putThing(TestConstants.API_V_2, + Thing.newBuilder().setId(deniedThingId).setPolicyId(importingPolicyId).build(), + org.eclipse.ditto.base.model.json.JsonSchemaVersion.V_2) + .expectingHttpStatus(HttpStatus.CREATED) + .fire(); + + getThing(TestConstants.API_V_2, allowedThingId) + .withConfiguredAuth(serviceEnv.getTestingContext2()) + .expectingHttpStatus(HttpStatus.OK) + .fire(); + + getThing(TestConstants.API_V_2, deniedThingId) + .withConfiguredAuth(serviceEnv.getTestingContext2()) + .expectingHttpStatus(HttpStatus.NOT_FOUND) + .fire(); + } + /** * Retrieves a persisted Thing with missing authorization to do so. */