From 87f289d9db1b55c5eb94581e8eeae4a129e9e96a Mon Sep 17 00:00:00 2001 From: Mudit Chaudhary Date: Tue, 11 Feb 2025 18:16:59 +0000 Subject: [PATCH 1/8] adds Entites class Signed-off-by: Mudit Chaudhary --- .../cedarpolicy/model/entity/Entities.java | 95 +++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 CedarJava/src/main/java/com/cedarpolicy/model/entity/Entities.java diff --git a/CedarJava/src/main/java/com/cedarpolicy/model/entity/Entities.java b/CedarJava/src/main/java/com/cedarpolicy/model/entity/Entities.java new file mode 100644 index 00000000..c74a0f9c --- /dev/null +++ b/CedarJava/src/main/java/com/cedarpolicy/model/entity/Entities.java @@ -0,0 +1,95 @@ +/* + * Copyright Cedar Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.cedarpolicy.model.entity; + +import static com.cedarpolicy.CedarJson.objectReader; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.*; + +/** + * A class representing a collection of Cedar policy entities. + */ +public class Entities { + private Set entities; + + /** + * Constructs a new empty Entities collection. + * Creates a new HashSet to store Entity objects. + */ + public Entities() { + this.entities = new HashSet<>(); + } + + /** + * Constructs a new Entities collection from a given Set of Entity objects. + * + * @param entities The Set of Entity objects to initialize this collection with + */ + public Entities(Set entities) { + this.entities = new HashSet<>(entities); + } + + /** + * Returns a copy of the set of entities in this collection. + * + * @return A new HashSet containing all Entity objects in this collection + */ + public Set getEntities() { + return new HashSet<>(entities); + } + + /** + * Parses a JSON string representation into an Entities collection. + * + * @param jsonString The JSON string containing entity data to parse + * + * @return A new Entities instance containing the parsed entities + * @throws JsonProcessingException If the JSON string cannot be parsed into + * valid entities + */ + public static Entities parse(String jsonString) throws JsonProcessingException { + return new Entities(objectReader().forType(new TypeReference>() { + }).readValue(jsonString)); + } + + /** + * Parses a JSON file at the specified path into an Entities collection. + * + * @param filePath The path to the JSON file containing entity data to parse + * + * @return A new Entities instance containing the parsed entities + * @throws IOException If there is an error reading the file + * @throws JsonProcessingException If the JSON content cannot be parsed into + * valid entities + */ + public static Entities parse(Path filePath) throws IOException, JsonProcessingException { + String jsonString = Files.readString(filePath); + return new Entities(objectReader().forType(new TypeReference>() { + }).readValue(jsonString)); + } + + @Override + public String toString() { + return String.join("\n", this.entities.stream().map(Entity::toString).toList()); + } +} From 97f5987601374edbb5ccc55da8c7626420c24163 Mon Sep 17 00:00:00 2001 From: Mudit Chaudhary Date: Wed, 12 Feb 2025 16:02:41 +0000 Subject: [PATCH 2/8] adds test for Entities Signed-off-by: Mudit Chaudhary --- CedarJava/build.gradle | 1 + .../java/com/cedarpolicy/EntitiesTests.java | 126 ++++++++++++++++++ 2 files changed, 127 insertions(+) create mode 100644 CedarJava/src/test/java/com/cedarpolicy/EntitiesTests.java diff --git a/CedarJava/build.gradle b/CedarJava/build.gradle index 8049169a..ef81c444 100644 --- a/CedarJava/build.gradle +++ b/CedarJava/build.gradle @@ -85,6 +85,7 @@ dependencies { compileOnly 'com.github.spotbugs:spotbugs-annotations:4.8.6' testImplementation 'net.jqwik:jqwik:1.9.2' testImplementation 'org.junit.jupiter:junit-jupiter-api:5.11.4' + testImplementation 'org.skyscreamer:jsonassert:2.0-rc1' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.11.4' } diff --git a/CedarJava/src/test/java/com/cedarpolicy/EntitiesTests.java b/CedarJava/src/test/java/com/cedarpolicy/EntitiesTests.java new file mode 100644 index 00000000..7e17879e --- /dev/null +++ b/CedarJava/src/test/java/com/cedarpolicy/EntitiesTests.java @@ -0,0 +1,126 @@ +/* + * Copyright Cedar Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.cedarpolicy; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.cedarpolicy.value.*; +import com.cedarpolicy.model.entity.Entity; +import com.cedarpolicy.model.entity.Entities; +import static com.cedarpolicy.CedarJson.objectWriter; + +import org.skyscreamer.jsonassert.*; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.JsonNode; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; + +public class EntitiesTests { + private static final String TEST_RESOURCES_DIR = "src/test/resources/"; + + @Test + public void givenValidEntitySetConstructorConstructs() { + + Entity alice = new Entity(EntityUID.parse("User::\"Alice\"").get()); + Set parentAlice = new HashSet<>(); + parentAlice.add(alice.getEUID()); + + PrimString stringAttr = new PrimString("stringAttrValue"); + HashMap attrs = new HashMap<>(); + attrs.put("stringAttr", stringAttr); + + Entity aliceChild = new Entity(EntityUID.parse("User::\"Alice_child\"").get(), attrs, parentAlice); + + Set entitySet = new HashSet<>(); + entitySet.add(aliceChild); + entitySet.add(alice); + + Entities entities = new Entities(entitySet); + + assertEquals(entitySet, entities.getEntities()); + } + + @Test + public void givenValidJSONStringParseReturns() throws JsonProcessingException { + String validEntitiesJson = """ + [ + {"uid":{"type":"Photo","id":"pic02"},"parents":[{"type":"PhotoParent","id":"picParent"}], + "attrs":{"dummyIP": {"__extn":{"fn":"ip","arg":"199.168.1.130"}}}}, + {"uid":{"type":"Photo","id":"pic01"},"parents":[{"type":"Photo","id":"pic02"}],"attrs":{}} + ] + """; + + String expectedRepresentation = "{\"entities\":[" + "{\"uid\":{\"type\":\"Photo\",\"id\":\"pic02\"}," + + "\"attrs\":{\"dummyIP\":{\"__extn\":{\"fn\":\"ip\",\"arg\":\"199.168.1.130\"}}}," + + "\"parents\":[{\"type\":\"PhotoParent\",\"id\":\"picParent\"}]," + "\"tags\":{}}," + + "{\"uid\":{\"type\":\"Photo\",\"id\":\"pic01\"}," + "\"attrs\":{}," + + "\"parents\":[{\"type\":\"Photo\",\"id\":\"pic02\"}]," + "\"tags\":{}}]}"; + + Entities entities = Entities.parse(validEntitiesJson); + String actualRepresentation = objectWriter().writeValueAsString(entities); + + JSONAssert.assertEquals(expectedRepresentation, actualRepresentation, JSONCompareMode.NON_EXTENSIBLE); + + validEntitiesJson = """ + [ + {"uid":{"type":"Photo","id":"pic01"},"parents":[],"attrs":{}}, + {"uid":{"type":"Photo","id":"pic02"},"parents":[],"attrs":{}} + ] + """; + + expectedRepresentation = "{\"entities\":[" + "{\"uid\":{\"type\":\"Photo\",\"id\":\"pic01\"}," + "\"attrs\":{}," + + "\"parents\":[]," + "\"tags\":{}}," + "{\"uid\":{\"type\":\"Photo\",\"id\":\"pic02\"}," + + "\"attrs\":{}," + "\"parents\":[]," + "\"tags\":{}}]}"; + + entities = Entities.parse(validEntitiesJson); + actualRepresentation = objectWriter().writeValueAsString(entities); + + JSONAssert.assertEquals(expectedRepresentation, actualRepresentation, JSONCompareMode.NON_EXTENSIBLE); + } + + @Test + public void givenInvalidJSONStringParseThrows() throws JsonProcessingException { + String invalidEntityJson = """ + [{"uid":{"type":"Photo","id":"pic01"}}, + {"uid":{"type":"Photo","id":"pic02"},"parents":[],"attrs":{}}] + """; + + assertThrows(JsonProcessingException.class, () -> { + Entities.parse(invalidEntityJson); + }); + + String invalidEntityJson2 = """ + [{"uid":{"type":"Photo","id":"pic02"}, "parents":[{"parent_id":"Alice"}]}, + {"uid":{"type":"Photo","id":"pic01"},"parents":[],"attrs":{}}] + """; + + assertThrows(JsonProcessingException.class, () -> { + Entities.parse(invalidEntityJson2); + }); + + } + +} From 4e6f80c3062e040ead266c50cbdb5fc85e4cee3e Mon Sep 17 00:00:00 2001 From: Mudit Chaudhary Date: Wed, 12 Feb 2025 16:53:32 +0000 Subject: [PATCH 3/8] adds load from file tests for Entities Signed-off-by: Mudit Chaudhary --- .../java/com/cedarpolicy/EntitiesTests.java | 23 +++++++++++++++---- .../src/test/resources/invalid_entities.json | 1 + .../src/test/resources/valid_entities.json | 5 ++++ 3 files changed, 25 insertions(+), 4 deletions(-) create mode 100644 CedarJava/src/test/resources/invalid_entities.json create mode 100644 CedarJava/src/test/resources/valid_entities.json diff --git a/CedarJava/src/test/java/com/cedarpolicy/EntitiesTests.java b/CedarJava/src/test/java/com/cedarpolicy/EntitiesTests.java index 7e17879e..1146ac77 100644 --- a/CedarJava/src/test/java/com/cedarpolicy/EntitiesTests.java +++ b/CedarJava/src/test/java/com/cedarpolicy/EntitiesTests.java @@ -19,7 +19,6 @@ import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertEquals; import com.cedarpolicy.value.*; import com.cedarpolicy.model.entity.Entity; @@ -29,8 +28,6 @@ import org.skyscreamer.jsonassert.*; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.JsonNode; import java.io.IOException; import java.nio.file.Path; @@ -81,7 +78,7 @@ public void givenValidJSONStringParseReturns() throws JsonProcessingException { Entities entities = Entities.parse(validEntitiesJson); String actualRepresentation = objectWriter().writeValueAsString(entities); - + JSONAssert.assertEquals(expectedRepresentation, actualRepresentation, JSONCompareMode.NON_EXTENSIBLE); validEntitiesJson = """ @@ -120,7 +117,25 @@ public void givenInvalidJSONStringParseThrows() throws JsonProcessingException { assertThrows(JsonProcessingException.class, () -> { Entities.parse(invalidEntityJson2); }); + } + + @Test + public void givenValidJSONFileParseReturns() throws JsonProcessingException, IOException { + Entities entities = Entities.parse(Path.of(TEST_RESOURCES_DIR + "valid_entities.json")); + String actualRepresentation = objectWriter().writeValueAsString(entities); + String expectedRepresentation = "{\"entities\":[" + "{\"uid\":{\"type\":\"Photo\",\"id\":\"pic02\"}," + + "\"attrs\":{\"dummyIP\":{\"__extn\":{\"fn\":\"ip\",\"arg\":\"199.168.1.130\"}}}," + + "\"parents\":[{\"type\":\"PhotoParent\",\"id\":\"picParent\"}]," + "\"tags\":{}}," + + "{\"uid\":{\"type\":\"Photo\",\"id\":\"pic01\"}," + "\"attrs\":{}," + + "\"parents\":[{\"type\":\"Photo\",\"id\":\"pic02\"}]," + "\"tags\":{}}]}"; + JSONAssert.assertEquals(expectedRepresentation, actualRepresentation, JSONCompareMode.NON_EXTENSIBLE); } + @Test + public void givenInvalidJSONFileParseThrows() throws JsonProcessingException, IOException { + assertThrows(JsonProcessingException.class, () -> { + Entities.parse(Path.of(TEST_RESOURCES_DIR + "invalid_entities.json")); + }); + } } diff --git a/CedarJava/src/test/resources/invalid_entities.json b/CedarJava/src/test/resources/invalid_entities.json new file mode 100644 index 00000000..d37cd9f8 --- /dev/null +++ b/CedarJava/src/test/resources/invalid_entities.json @@ -0,0 +1 @@ +{"uid":{"type":"Photo","id":"pic01"}} diff --git a/CedarJava/src/test/resources/valid_entities.json b/CedarJava/src/test/resources/valid_entities.json new file mode 100644 index 00000000..3746887d --- /dev/null +++ b/CedarJava/src/test/resources/valid_entities.json @@ -0,0 +1,5 @@ +[ + {"uid":{"type":"Photo","id":"pic02"},"parents":[{"type":"PhotoParent","id":"picParent"}], + "attrs":{"dummyIP": {"__extn":{"fn":"ip","arg":"199.168.1.130"}}}}, + {"uid":{"type":"Photo","id":"pic01"},"parents":[{"type":"Photo","id":"pic02"}],"attrs":{}} +] From c93c28571cbb000a63b3eab3049d16abe83e482b Mon Sep 17 00:00:00 2001 From: Mudit Chaudhary Date: Wed, 12 Feb 2025 16:55:50 +0000 Subject: [PATCH 4/8] reformats Entities class Signed-off-by: Mudit Chaudhary --- .../main/java/com/cedarpolicy/model/entity/Entities.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/CedarJava/src/main/java/com/cedarpolicy/model/entity/Entities.java b/CedarJava/src/main/java/com/cedarpolicy/model/entity/Entities.java index c74a0f9c..dd5f7928 100644 --- a/CedarJava/src/main/java/com/cedarpolicy/model/entity/Entities.java +++ b/CedarJava/src/main/java/com/cedarpolicy/model/entity/Entities.java @@ -33,8 +33,7 @@ public class Entities { private Set entities; /** - * Constructs a new empty Entities collection. - * Creates a new HashSet to store Entity objects. + * Constructs a new empty Entities collection. Creates a new HashSet to store Entity objects. */ public Entities() { this.entities = new HashSet<>(); @@ -64,8 +63,7 @@ public Set getEntities() { * @param jsonString The JSON string containing entity data to parse * * @return A new Entities instance containing the parsed entities - * @throws JsonProcessingException If the JSON string cannot be parsed into - * valid entities + * @throws JsonProcessingException If the JSON string cannot be parsed into valid entities */ public static Entities parse(String jsonString) throws JsonProcessingException { return new Entities(objectReader().forType(new TypeReference>() { @@ -79,8 +77,7 @@ public static Entities parse(String jsonString) throws JsonProcessingException { * * @return A new Entities instance containing the parsed entities * @throws IOException If there is an error reading the file - * @throws JsonProcessingException If the JSON content cannot be parsed into - * valid entities + * @throws JsonProcessingException If the JSON content cannot be parsed into valid entities */ public static Entities parse(Path filePath) throws IOException, JsonProcessingException { String jsonString = Files.readString(filePath); From d5ab9b1980c035d7591b5e59e8dc49f1ca4ba0bc Mon Sep 17 00:00:00 2001 From: Mudit Chaudhary Date: Wed, 12 Feb 2025 18:25:01 +0000 Subject: [PATCH 5/8] makes authorization calls compatible with Entities and maintains backward compatiblity Signed-off-by: Mudit Chaudhary --- .../com/cedarpolicy/AuthorizationEngine.java | 34 +++++++++++++++++++ .../cedarpolicy/BasicAuthorizationEngine.java | 20 +++++++++++ .../test/java/com/cedarpolicy/AuthTests.java | 33 ++++++++++++++++++ 3 files changed, 87 insertions(+) diff --git a/CedarJava/src/main/java/com/cedarpolicy/AuthorizationEngine.java b/CedarJava/src/main/java/com/cedarpolicy/AuthorizationEngine.java index 25f64dc0..addf5588 100644 --- a/CedarJava/src/main/java/com/cedarpolicy/AuthorizationEngine.java +++ b/CedarJava/src/main/java/com/cedarpolicy/AuthorizationEngine.java @@ -21,6 +21,7 @@ import com.cedarpolicy.model.exception.BadRequestException; import com.cedarpolicy.model.entity.Entity; import com.cedarpolicy.model.policy.PolicySet; +import com.cedarpolicy.model.entity.Entities; import java.util.Set; @@ -51,6 +52,21 @@ public interface AuthorizationEngine { */ AuthorizationResponse isAuthorized(AuthorizationRequest request, PolicySet policySet, Set entities) throws AuthException; + /** + * Asks whether the given AuthorizationRequest q is approved by the policySet and + * entities hierarchy given. Overloaded method to accept Entities object. + * + * @param request The request to evaluate + * @param policySet The policy set to evaluate against + * @param entities The entities to evaluate against + * @return The result of the request evaluation + * @throws BadRequestException if any errors were found in the syntax of the policies. + * @throws AuthException On failure to make the authorization request. Note that errors inside the + * authorization engine are included in the errors field on the + * AuthorizationResponse. + */ + AuthorizationResponse isAuthorized(AuthorizationRequest request, PolicySet policySet, Entities entities) throws AuthException; + /** * Asks whether the given AuthorizationRequest q is approved by the policySet and * entities given. If information required to answer is missing, residual policies are returned. @@ -67,6 +83,24 @@ public interface AuthorizationEngine { @Experimental(ExperimentalFeature.PARTIAL_EVALUATION) PartialAuthorizationResponse isAuthorizedPartial(PartialAuthorizationRequest request, PolicySet policySet, Set entities) throws AuthException; + + /** + * Asks whether the given AuthorizationRequest q is approved by the policySet and + * entities given. If information required to answer is missing, residual policies are returned. + * Overloaded method to accept Entities object. + * + * @param request The request to evaluate + * @param policySet The policy set to evaluate against + * @param entities The entities to evaluate against + * @return The result of the request evaluation + * @throws BadRequestException if any errors were found in the syntax of the policies. + * @throws AuthException On failure to make the authorization request. Note that errors inside the + * authorization engine are included in the errors field on the + * AuthorizationResponse. + */ + @Experimental(ExperimentalFeature.PARTIAL_EVALUATION) + PartialAuthorizationResponse isAuthorizedPartial(PartialAuthorizationRequest request, + PolicySet policySet, Entities entities) throws AuthException; /** * Asks whether the policies in the given {@link ValidationRequest} q are correct diff --git a/CedarJava/src/main/java/com/cedarpolicy/BasicAuthorizationEngine.java b/CedarJava/src/main/java/com/cedarpolicy/BasicAuthorizationEngine.java index 2cdde63c..67a87f2c 100644 --- a/CedarJava/src/main/java/com/cedarpolicy/BasicAuthorizationEngine.java +++ b/CedarJava/src/main/java/com/cedarpolicy/BasicAuthorizationEngine.java @@ -27,6 +27,7 @@ import com.cedarpolicy.model.exception.BadRequestException; import com.cedarpolicy.model.exception.InternalException; import com.cedarpolicy.model.exception.MissingExperimentalFeatureException; +import com.cedarpolicy.model.entity.Entities; import com.cedarpolicy.model.entity.Entity; import com.cedarpolicy.model.policy.PolicySet; import com.fasterxml.jackson.annotation.JsonCreator; @@ -57,6 +58,15 @@ public AuthorizationResponse isAuthorized(com.cedarpolicy.model.AuthorizationReq return call("AuthorizationOperation", AuthorizationResponse.class, request); } + /** + * Overloaded method to accept Entities object + */ + @Override + public AuthorizationResponse isAuthorized(com.cedarpolicy.model.AuthorizationRequest q, + PolicySet policySet, Entities entities) throws AuthException { + return isAuthorized(q, policySet, entities.getEntities()); + } + @Experimental(ExperimentalFeature.PARTIAL_EVALUATION) @Override public PartialAuthorizationResponse isAuthorizedPartial(com.cedarpolicy.model.PartialAuthorizationRequest q, @@ -73,6 +83,16 @@ public PartialAuthorizationResponse isAuthorizedPartial(com.cedarpolicy.model.Pa } } + /** + * Overoaded method to accept Entities object + */ + @Experimental(ExperimentalFeature.PARTIAL_EVALUATION) + @Override + public PartialAuthorizationResponse isAuthorizedPartial(com.cedarpolicy.model.PartialAuthorizationRequest q, + PolicySet policySet, Entities entities) throws AuthException { + return isAuthorizedPartial(q, policySet, entities.getEntities()); + } + @Override public ValidationResponse validate(ValidationRequest q) throws AuthException { return call("ValidateOperation", ValidationResponse.class, q); diff --git a/CedarJava/src/test/java/com/cedarpolicy/AuthTests.java b/CedarJava/src/test/java/com/cedarpolicy/AuthTests.java index 7b288b7c..8da4afe3 100644 --- a/CedarJava/src/test/java/com/cedarpolicy/AuthTests.java +++ b/CedarJava/src/test/java/com/cedarpolicy/AuthTests.java @@ -34,6 +34,7 @@ import com.cedarpolicy.value.Unknown; import com.cedarpolicy.value.Value; import com.cedarpolicy.value.PrimBool; +import com.cedarpolicy.model.entity.Entities; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.function.Executable; @@ -47,6 +48,14 @@ public class AuthTests { private void assertAllowed(AuthorizationRequest q, PolicySet policySet, Set entities) { assertDoesNotThrow(() -> { + // Using Entities object + Entities entitiesObj = new Entities(entities); + final var responseWithEntities = new BasicAuthorizationEngine().isAuthorized(q, policySet, entitiesObj); + assertEquals(responseWithEntities.type, SuccessOrFailure.Success); + final var successWithEntities = responseWithEntities.success.get(); + assertTrue(successWithEntities.isAllowed()); + + // Backward compatible using Set final var response = new BasicAuthorizationEngine().isAuthorized(q, policySet, entities); assertEquals(response.type, SuccessOrFailure.Success); final var success = response.success.get(); @@ -197,6 +206,30 @@ public void partialAuthConcreteWithContextObject() { }); } + @Test + public void partialAuthConcreteWithEntitiesObject() { + var auth = new BasicAuthorizationEngine(); + var alice = new EntityUID(EntityTypeName.parse("User").get(), "alice"); + var view = new EntityUID(EntityTypeName.parse("Action").get(), "view"); + Map contextMap = new HashMap<>(); + contextMap.put("authenticated", new PrimBool(true)); + Context context = new Context(contextMap); + var q = PartialAuthorizationRequest.builder().principal(alice).action(view).resource(alice).context(context).build(); + var policies = new HashSet(); + policies.add(new Policy("permit(principal == User::\"alice\",action,resource) when {context.authenticated == true};", "p0")); + var policySet = new PolicySet(policies); + assumePartialEvaluation(() -> { + try { + final PartialAuthorizationResponse response = auth.isAuthorizedPartial(q, policySet, new Entities()); + assertEquals(Decision.Allow, response.success.orElseThrow().getDecision()); + assertEquals(response.success.orElseThrow().getMustBeDetermining().iterator().next(), "p0"); + assertTrue(response.success.orElseThrow().getNontrivialResiduals().isEmpty()); + } catch (Exception e) { + fail("error: " + e.toString()); + } + }); + } + @Test public void residual() { var auth = new BasicAuthorizationEngine(); From f7c1ff10337ffdfba5e695a770f2cdb0f5ede810 Mon Sep 17 00:00:00 2001 From: Mudit Chaudhary Date: Wed, 12 Feb 2025 18:46:01 +0000 Subject: [PATCH 6/8] fixes nits Signed-off-by: Mudit Chaudhary --- CedarJava/src/test/java/com/cedarpolicy/EntitiesTests.java | 1 - 1 file changed, 1 deletion(-) diff --git a/CedarJava/src/test/java/com/cedarpolicy/EntitiesTests.java b/CedarJava/src/test/java/com/cedarpolicy/EntitiesTests.java index 1146ac77..f27ed5a1 100644 --- a/CedarJava/src/test/java/com/cedarpolicy/EntitiesTests.java +++ b/CedarJava/src/test/java/com/cedarpolicy/EntitiesTests.java @@ -40,7 +40,6 @@ public class EntitiesTests { @Test public void givenValidEntitySetConstructorConstructs() { - Entity alice = new Entity(EntityUID.parse("User::\"Alice\"").get()); Set parentAlice = new HashSet<>(); parentAlice.add(alice.getEUID()); From dd4bc63bdea05032d67d5379e531e06d476e5893 Mon Sep 17 00:00:00 2001 From: Mudit Chaudhary Date: Mon, 24 Feb 2025 21:06:06 +0000 Subject: [PATCH 7/8] fixes nits Signed-off-by: Mudit Chaudhary --- .../java/com/cedarpolicy/BasicAuthorizationEngine.java | 2 +- .../main/java/com/cedarpolicy/model/entity/Entities.java | 9 +++++---- .../main/java/com/cedarpolicy/model/entity/Entity.java | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/CedarJava/src/main/java/com/cedarpolicy/BasicAuthorizationEngine.java b/CedarJava/src/main/java/com/cedarpolicy/BasicAuthorizationEngine.java index 67a87f2c..2501cadd 100644 --- a/CedarJava/src/main/java/com/cedarpolicy/BasicAuthorizationEngine.java +++ b/CedarJava/src/main/java/com/cedarpolicy/BasicAuthorizationEngine.java @@ -84,7 +84,7 @@ public PartialAuthorizationResponse isAuthorizedPartial(com.cedarpolicy.model.Pa } /** - * Overoaded method to accept Entities object + * Overloaded method to accept Entities object */ @Experimental(ExperimentalFeature.PARTIAL_EVALUATION) @Override diff --git a/CedarJava/src/main/java/com/cedarpolicy/model/entity/Entities.java b/CedarJava/src/main/java/com/cedarpolicy/model/entity/Entities.java index dd5f7928..add62abb 100644 --- a/CedarJava/src/main/java/com/cedarpolicy/model/entity/Entities.java +++ b/CedarJava/src/main/java/com/cedarpolicy/model/entity/Entities.java @@ -24,7 +24,8 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import java.util.*; +import java.util.Set; +import java.util.HashSet; /** * A class representing a collection of Cedar policy entities. @@ -50,7 +51,7 @@ public Entities(Set entities) { /** * Returns a copy of the set of entities in this collection. - * + * * @return A new HashSet containing all Entity objects in this collection */ public Set getEntities() { @@ -61,7 +62,7 @@ public Set getEntities() { * Parses a JSON string representation into an Entities collection. * * @param jsonString The JSON string containing entity data to parse - * + * * @return A new Entities instance containing the parsed entities * @throws JsonProcessingException If the JSON string cannot be parsed into valid entities */ @@ -74,7 +75,7 @@ public static Entities parse(String jsonString) throws JsonProcessingException { * Parses a JSON file at the specified path into an Entities collection. * * @param filePath The path to the JSON file containing entity data to parse - * + * * @return A new Entities instance containing the parsed entities * @throws IOException If there is an error reading the file * @throws JsonProcessingException If the JSON content cannot be parsed into valid entities diff --git a/CedarJava/src/main/java/com/cedarpolicy/model/entity/Entity.java b/CedarJava/src/main/java/com/cedarpolicy/model/entity/Entity.java index ae05e0ae..b156b0d2 100644 --- a/CedarJava/src/main/java/com/cedarpolicy/model/entity/Entity.java +++ b/CedarJava/src/main/java/com/cedarpolicy/model/entity/Entity.java @@ -94,7 +94,7 @@ public Entity(EntityUID uid, Map attributes, Set paren * Get the value for the given attribute, or null if not present. * * @param attribute Attribute key - * + * * @return Attribute value for the given key or null if not present * @throws IllegalArgumentException if attribute is null */ From 18ab7e07789cc572f09c68158b1934d243a52a26 Mon Sep 17 00:00:00 2001 From: Mudit Chaudhary Date: Mon, 24 Feb 2025 22:10:04 +0000 Subject: [PATCH 8/8] organizes imports Signed-off-by: Mudit Chaudhary --- .../com/cedarpolicy/AuthorizationEngine.java | 18 ++++++++++++------ .../cedarpolicy/BasicAuthorizationEngine.java | 16 ++++++++++------ 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/CedarJava/src/main/java/com/cedarpolicy/AuthorizationEngine.java b/CedarJava/src/main/java/com/cedarpolicy/AuthorizationEngine.java index addf5588..abcde75e 100644 --- a/CedarJava/src/main/java/com/cedarpolicy/AuthorizationEngine.java +++ b/CedarJava/src/main/java/com/cedarpolicy/AuthorizationEngine.java @@ -16,14 +16,20 @@ package com.cedarpolicy; -import com.cedarpolicy.model.*; +import java.util.Set; + +import com.cedarpolicy.model.AuthorizationRequest; +import com.cedarpolicy.model.AuthorizationResponse; +import com.cedarpolicy.model.EntityValidationRequest; +import com.cedarpolicy.model.PartialAuthorizationRequest; +import com.cedarpolicy.model.PartialAuthorizationResponse; +import com.cedarpolicy.model.ValidationRequest; +import com.cedarpolicy.model.ValidationResponse; +import com.cedarpolicy.model.entity.Entities; +import com.cedarpolicy.model.entity.Entity; import com.cedarpolicy.model.exception.AuthException; import com.cedarpolicy.model.exception.BadRequestException; -import com.cedarpolicy.model.entity.Entity; import com.cedarpolicy.model.policy.PolicySet; -import com.cedarpolicy.model.entity.Entities; - -import java.util.Set; /** * Implementations of the AuthorizationEngine interface invoke Cedar to respond to an authorization @@ -83,7 +89,7 @@ public interface AuthorizationEngine { @Experimental(ExperimentalFeature.PARTIAL_EVALUATION) PartialAuthorizationResponse isAuthorizedPartial(PartialAuthorizationRequest request, PolicySet policySet, Set entities) throws AuthException; - + /** * Asks whether the given AuthorizationRequest q is approved by the policySet and * entities given. If information required to answer is missing, residual policies are returned. diff --git a/CedarJava/src/main/java/com/cedarpolicy/BasicAuthorizationEngine.java b/CedarJava/src/main/java/com/cedarpolicy/BasicAuthorizationEngine.java index 2501cadd..1b001bb6 100644 --- a/CedarJava/src/main/java/com/cedarpolicy/BasicAuthorizationEngine.java +++ b/CedarJava/src/main/java/com/cedarpolicy/BasicAuthorizationEngine.java @@ -20,15 +20,21 @@ import static com.cedarpolicy.CedarJson.objectWriter; import java.io.IOException; +import java.util.List; +import java.util.Set; import com.cedarpolicy.loader.LibraryLoader; -import com.cedarpolicy.model.*; +import com.cedarpolicy.model.AuthorizationResponse; +import com.cedarpolicy.model.EntityValidationRequest; +import com.cedarpolicy.model.PartialAuthorizationResponse; +import com.cedarpolicy.model.ValidationRequest; +import com.cedarpolicy.model.ValidationResponse; +import com.cedarpolicy.model.entity.Entities; +import com.cedarpolicy.model.entity.Entity; import com.cedarpolicy.model.exception.AuthException; import com.cedarpolicy.model.exception.BadRequestException; import com.cedarpolicy.model.exception.InternalException; import com.cedarpolicy.model.exception.MissingExperimentalFeatureException; -import com.cedarpolicy.model.entity.Entities; -import com.cedarpolicy.model.entity.Entity; import com.cedarpolicy.model.policy.PolicySet; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @@ -36,10 +42,8 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import java.util.List; -import java.util.Set; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; /** An authorization engine that is compiled in process. Communicated with via JNI. */ public final class BasicAuthorizationEngine implements AuthorizationEngine {