Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 42 additions & 6 deletions CedarJava/src/main/java/com/cedarpolicy/model/schema/Schema.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@

package com.cedarpolicy.model.schema;

import java.util.Optional;

import com.cedarpolicy.loader.LibraryLoader;
import com.cedarpolicy.model.exception.InternalException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.Optional;

/** Represents a schema. */
public final class Schema {
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
Expand Down Expand Up @@ -122,21 +124,55 @@ public static Schema parse(JsonOrCedar type, String str) throws InternalExceptio

}

public String toCedarFormat() throws InternalException {
if (type == JsonOrCedar.Cedar && schemaText.isPresent()) {
return schemaText.get();
} else if (type == JsonOrCedar.Json && schemaJson.isPresent()) {
return jsonToCedarJni(schemaJson.get().toString());
} else {
throw new InternalException("Schema content is missing");
}
}

/**
* Converts a Cedar format schema to JSON format
*
* @return JsonNode representing the schema in JSON format
* @throws InternalException If schema is not in Cedar format
* @throws JsonMappingException If JSON mapping fails
* @throws JsonProcessingException If JSON processing fails
* @throws NullPointerException If schema text is null
*/
public JsonNode toJsonFormat()
throws InternalException, JsonMappingException, JsonProcessingException, NullPointerException {
if (type != JsonOrCedar.Cedar || schemaText.isEmpty()) {
throw new InternalException("Schema is not in cedar format");
}
return OBJECT_MAPPER.readTree(cedarToJsonJni(schemaText.get()));

}

/** Specifies the schema format used. */
public enum JsonOrCedar {
/**
* Cedar JSON schema format. See <a href="https://docs.cedarpolicy.com/schema/json-schema.html">
* https://docs.cedarpolicy.com/schema/json-schema.html</a>
* Cedar JSON schema format. See
* <a href="https://docs.cedarpolicy.com/schema/json-schema.html">
* https://docs.cedarpolicy.com/schema/json-schema.html</a>
*/
Json,
/**
* Cedar schema format. See <a href="https://docs.cedarpolicy.com/schema/human-readable-schema.html">
* https://docs.cedarpolicy.com/schema/human-readable-schema.html</a>
* Cedar schema format. See
* <a href="https://docs.cedarpolicy.com/schema/human-readable-schema.html">
* https://docs.cedarpolicy.com/schema/human-readable-schema.html</a>
*/
Cedar
}

private static native String parseJsonSchemaJni(String schemaJson) throws InternalException, NullPointerException;

private static native String parseCedarSchemaJni(String schemaText) throws InternalException, NullPointerException;

private static native String jsonToCedarJni(String json) throws InternalException, NullPointerException;

private static native String cedarToJsonJni(String cedar) throws InternalException, NullPointerException;
}
75 changes: 70 additions & 5 deletions CedarJava/src/test/java/com/cedarpolicy/SchemaTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,17 @@

package com.cedarpolicy;

import com.cedarpolicy.model.schema.Schema;
import com.cedarpolicy.model.schema.Schema.JsonOrCedar;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;

import com.cedarpolicy.model.exception.InternalException;
import com.cedarpolicy.model.schema.Schema;
import com.cedarpolicy.model.schema.Schema.JsonOrCedar;
import com.fasterxml.jackson.databind.JsonNode;

public class SchemaTests {
@Test
Expand Down Expand Up @@ -107,4 +111,65 @@ public void parseCedarSchema() {
Schema.parse(JsonOrCedar.Cedar, "namspace Foo::Bar;");
});
}

@Test
public void testToCedarFormat() throws InternalException {
String cedarSchema = "entity User;";
Schema cedarSchemaObj = new Schema(cedarSchema);
String result = cedarSchemaObj.toCedarFormat();
assertNotNull(result);
assertEquals(cedarSchema, result);

String jsonSchema = """
{
"": {
"entityTypes": {
"User": {}
},
"actions": {}
}
}
""";
Schema jsonSchemaObj = Schema.parse(JsonOrCedar.Json, jsonSchema);
String convertedCedar = jsonSchemaObj.toCedarFormat();
assertNotNull(convertedCedar);
assertTrue(convertedCedar.contains("entity User"));

Schema invalidSchema = new Schema(JsonOrCedar.Cedar, java.util.Optional.empty(), java.util.Optional.empty());
assertThrows(InternalException.class, () -> {
invalidSchema.toCedarFormat();
});
}

@Test
public void testToJsonFormat() throws Exception {
String cedarSchema = "entity User;";
Schema cedarSchemaObj = new Schema(cedarSchema);
JsonNode jsonResult = cedarSchemaObj.toJsonFormat();
assertNotNull(jsonResult);
assertTrue(jsonResult.has(""));
assertTrue(jsonResult.get("").has("entityTypes"));
assertTrue(jsonResult.get("").get("entityTypes").has("User"));

String jsonSchema = """
{
"": {
"entityTypes": {
"User": {}
},
"actions": {}
}
}
""";
Schema jsonSchemaObj = Schema.parse(JsonOrCedar.Json, jsonSchema);
assertThrows(InternalException.class, () -> {
jsonSchemaObj.toJsonFormat();
});

Schema invalidSchema = new Schema(JsonOrCedar.Cedar, java.util.Optional.empty(), java.util.Optional.empty());
assertThrows(InternalException.class, () -> {
invalidSchema.toJsonFormat();
});
}

}
Loading