Skip to content

Commit d8ba863

Browse files
Adding toJson JNI method for Policy object (#187)
1 parent 100f225 commit d8ba863

3 files changed

Lines changed: 59 additions & 1 deletion

File tree

CedarJava/src/main/java/com/cedarpolicy/model/slice/Policy.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ public String toString() {
6969
return "// Policy ID: " + policyID + "\n" + policySrc;
7070
}
7171

72+
public String toJson() throws InternalException, NullPointerException {
73+
return toJsonJni(policySrc);
74+
}
75+
7276
public static Policy parseStaticPolicy(String policyStr) throws InternalException, NullPointerException {
7377
var policyText = parsePolicyJni(policyStr);
7478
return new Policy(policyText, null);
@@ -97,4 +101,6 @@ public static boolean validateTemplateLinkedPolicy(Policy p, EntityUID principal
97101
private static native String parsePolicyJni(String policyStr) throws InternalException, NullPointerException;
98102
private static native String parsePolicyTemplateJni(String policyTemplateStr) throws InternalException, NullPointerException;
99103
private static native boolean validateTemplateLinkedPolicyJni(String templateText, EntityUID principal, EntityUID resource) throws InternalException, NullPointerException;
104+
105+
private native String toJsonJni(String policyStr) throws InternalException, NullPointerException;
100106
}

CedarJava/src/test/java/com/cedarpolicy/PolicyTests.java

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
import org.junit.jupiter.api.Test;
77

88
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
9-
import static org.junit.jupiter.api.Assertions.assertThrows;
9+
import static org.junit.jupiter.api.Assertions.assertEquals;
1010
import static org.junit.jupiter.api.Assertions.assertNotEquals;
11+
import static org.junit.jupiter.api.Assertions.assertThrows;
1112
import static org.junit.jupiter.api.Assertions.assertTrue;
13+
import static org.junit.jupiter.api.Assertions.fail;
1214

1315
public class PolicyTests {
1416
@Test
@@ -99,4 +101,34 @@ public void validateTemplateLinkedPolicyFailsWhenExpected() {
99101
Policy.validateTemplateLinkedPolicy(p3, principal, resource);
100102
});
101103
}
104+
105+
@Test
106+
public void staticPolicyToJsonTests() throws InternalException {
107+
assertThrows(NullPointerException.class, () -> {
108+
Policy p = new Policy(null, null);
109+
p.toJson();
110+
});
111+
assertThrows(InternalException.class, () -> {
112+
Policy p = new Policy("permit();", null);
113+
p.toJson();
114+
});
115+
116+
Policy p = Policy.parseStaticPolicy("permit(principal, action, resource);");
117+
String actualJson = p.toJson();
118+
String expectedJson = "{\"effect\":\"permit\",\"principal\":{\"op\":\"All\"},\"action\":{\"op\":\"All\"},"
119+
+ "\"resource\":{\"op\":\"All\"},\"conditions\":[]}";
120+
assertEquals(expectedJson, actualJson);
121+
}
122+
123+
@Test
124+
public void policyTemplateToJsonFailureTests() throws InternalException {
125+
try {
126+
String tbody = "permit(principal == ?principal, action, resource in ?resource);";
127+
Policy template = Policy.parsePolicyTemplate(tbody);
128+
template.toJson();
129+
fail("Expected InternalException");
130+
} catch (InternalException e) {
131+
assertTrue(e.getMessage().contains("expected a static policy, got a template containing the slot ?resource"));
132+
}
133+
}
102134
}

CedarJavaFFI/src/interface.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,26 @@ fn validate_template_linked_policy_internal<'a>(
316316
}
317317
}
318318

319+
#[jni_fn("com.cedarpolicy.model.slice.Policy")]
320+
pub fn toJsonJni<'a>(mut env: JNIEnv<'a>, _: JClass, policy_jstr: JString<'a>) -> jvalue {
321+
match to_json_internal(&mut env, policy_jstr) {
322+
Err(e) => jni_failed(&mut env, e.as_ref()),
323+
Ok(policy_json) => policy_json.as_jni(),
324+
}
325+
}
326+
327+
fn to_json_internal<'a>(env: &mut JNIEnv<'a>, policy_jstr: JString<'a>) -> Result<JValueOwned<'a>> {
328+
if policy_jstr.is_null() {
329+
raise_npe(env)
330+
} else {
331+
let policy_jstring = env.get_string(&policy_jstr)?;
332+
let policy_string = String::from(policy_jstring);
333+
let policy = Policy::from_str(&policy_string)?;
334+
let policy_json = serde_json::to_string(&policy.to_json().unwrap())?;
335+
Ok(JValueGen::Object(env.new_string(&policy_json)?.into()))
336+
}
337+
}
338+
319339
#[jni_fn("com.cedarpolicy.value.EntityIdentifier")]
320340
pub fn getEntityIdentifierRepr<'a>(mut env: JNIEnv<'a>, _: JClass, obj: JObject<'a>) -> jvalue {
321341
match get_entity_identifier_repr_internal(&mut env, obj) {

0 commit comments

Comments
 (0)