Skip to content

Commit

Permalink
avoid npe in json deserialization
Browse files Browse the repository at this point in the history
  • Loading branch information
joshua-roberts committed Aug 30, 2024
1 parent 6ed8397 commit 568d260
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import gov.nist.csd.pm.pap.graph.relationship.AccessRightSet;
import gov.nist.csd.pm.pap.serialization.PolicyDeserializer;
import gov.nist.csd.pm.pap.PAP;
import gov.nist.csd.pm.pap.exception.PMException;
Expand All @@ -19,33 +20,52 @@ public void deserialize(PAP pap, UserContext author, String input) throws PMExce
Gson gson = new Gson();
JSONPolicy jsonPolicy = gson.fromJson(input, new TypeToken<JSONPolicy>() {}.getType());

pap.modify().operations().setResourceOperations(jsonPolicy.getResourceOperations());

Map<String, JSONNode> uaMap = new HashMap<>();
Map<String, JSONNode> oaMap = new HashMap<>();
Map<String, JSONNode> uMap = new HashMap<>();
Map<String, JSONNode> oMap = new HashMap<>();

for (JSONNode jsonNode : jsonPolicy.getGraph().uas) {
uaMap.put(jsonNode.getName(), jsonNode);
}
for (JSONNode jsonNode : jsonPolicy.getGraph().oas) {
oaMap.put(jsonNode.getName(), jsonNode);
}
for (JSONNode jsonNode : jsonPolicy.getGraph().users) {
uMap.put(jsonNode.getName(), jsonNode);
// account for the json schema allowing null properties
AccessRightSet resourceOperations = jsonPolicy.getResourceOperations();
if (resourceOperations == null) {
resourceOperations = new AccessRightSet();
}
for (JSONNode jsonNode : jsonPolicy.getGraph().objects) {
oMap.put(jsonNode.getName(), jsonNode);

JSONGraph graph = jsonPolicy.getGraph();
if (graph == null) {
graph = new JSONGraph();
}

List<String> prohibitions = jsonPolicy.getProhibitions();
if (prohibitions == null) {
prohibitions = new ArrayList<>();
}

List<String> obligations = jsonPolicy.getObligations();
if (obligations == null) {
obligations = new ArrayList<>();
}

List<String> operations = jsonPolicy.getOperations();
if (operations == null) {
operations = new ArrayList<>();
}

List<String> routines = jsonPolicy.getRoutines();
if (routines == null) {
routines = new ArrayList<>();
}

// set resource operations
pap.modify().operations().setResourceOperations(resourceOperations);

// create the graph
createGraph(pap, graph);

createGraph(pap, jsonPolicy.getGraph().pcs, uaMap, oaMap, uMap, oMap);
createRestOfPolicy(pap, author, prohibitions, obligations, operations, routines);
// create prohibitions, obligations, operations, and routines
createRestOfPolicy(
pap,
author,
prohibitions,
obligations,
operations,
routines
);
}

private void createRestOfPolicy(PAP pap,
Expand Down Expand Up @@ -74,14 +94,46 @@ private void createRestOfPolicy(PAP pap,
pap.executePML(author, sb.toString());
}

private void createGraph(PAP pap,
List<JSONNode> pcs,
Map<String, JSONNode> uaMap,
Map<String, JSONNode> oaMap,
Map<String, JSONNode> uMap,
Map<String, JSONNode> oMap)
private void createGraph(PAP pap, JSONGraph graph)
throws PMException {
createPCs(pap, pcs);
Map<String, JSONNode> uaMap = new HashMap<>();
Map<String, JSONNode> oaMap = new HashMap<>();
Map<String, JSONNode> uMap = new HashMap<>();
Map<String, JSONNode> oMap = new HashMap<>();

// account for type maps in json graph being null
if (graph.pcs == null) {
graph.pcs = new ArrayList<>();
}
if (graph.uas == null) {
graph.uas = new ArrayList<>();
}
if (graph.oas == null) {
graph.oas = new ArrayList<>();
}
if (graph.users == null) {
graph.users = new ArrayList<>();
}
if (graph.objects == null) {
graph.objects = new ArrayList<>();
}


// organize nodes into a map for fast look up during creation
for (JSONNode jsonNode : graph.uas) {
uaMap.put(jsonNode.getName(), jsonNode);
}
for (JSONNode jsonNode : graph.oas) {
oaMap.put(jsonNode.getName(), jsonNode);
}
for (JSONNode jsonNode : graph.users) {
uMap.put(jsonNode.getName(), jsonNode);
}
for (JSONNode jsonNode : graph.objects) {
oMap.put(jsonNode.getName(), jsonNode);
}

createPCs(pap, graph.pcs);

// create uas
createNodes(pap, UA, uaMap);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package gov.nist.csd.pm.pap.serialization.json;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
Expand All @@ -24,6 +25,14 @@ public JSONGraph(List<JSONNode> pcs,
this.objects = objects;
}

public JSONGraph() {
this.pcs = new ArrayList<>();
this.uas = new ArrayList<>();
this.oas = new ArrayList<>();
this.users = new ArrayList<>();
this.objects = new ArrayList<>();
}

public List<JSONNode> getPcs() {
return pcs;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package gov.nist.csd.pm.pap.serialization;

import gov.nist.csd.pm.impl.memory.pap.MemoryPAP;
import gov.nist.csd.pm.pap.exception.PMException;
import gov.nist.csd.pm.pap.graph.relationship.AccessRightSet;
import gov.nist.csd.pm.pap.query.UserContext;
import gov.nist.csd.pm.pap.serialization.json.JSONDeserializer;
import gov.nist.csd.pm.pap.serialization.json.JSONGraph;
import gov.nist.csd.pm.pap.serialization.json.JSONPolicy;
import gov.nist.csd.pm.pap.serialization.json.JSONSerializer;
import gov.nist.csd.pm.util.SamplePolicy;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.util.List;

import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;

public class JSONSerializationTest {

@Test
void testJSONSerializationDoesNotThrowNPE() throws PMException, IOException {
List<JSONPolicy> policies = List.of(
new JSONPolicy(new AccessRightSet(), new JSONGraph(), List.of(), List.of(), List.of(), List.of()),
new JSONPolicy(null, new JSONGraph(), List.of(), List.of(), List.of(), List.of()),
new JSONPolicy(new AccessRightSet(), null, List.of(), List.of(), List.of(), List.of()),
new JSONPolicy(new AccessRightSet(), new JSONGraph(), null, List.of(), List.of(), List.of()),
new JSONPolicy(new AccessRightSet(), new JSONGraph(), List.of(), null, List.of(), List.of()),
new JSONPolicy(new AccessRightSet(), new JSONGraph(), List.of(), List.of(), null, List.of()),
new JSONPolicy(new AccessRightSet(), new JSONGraph(), List.of(), List.of(), List.of(), null),
new JSONPolicy(new AccessRightSet(), new JSONGraph(List.of(), List.of(), List.of(), List.of(), List.of()), List.of(), List.of(), List.of(), List.of()),
new JSONPolicy(new AccessRightSet(), new JSONGraph(null, List.of(), List.of(), List.of(), List.of()), List.of(), List.of(), List.of(), List.of()),
new JSONPolicy(new AccessRightSet(), new JSONGraph(List.of(), null, List.of(), List.of(), List.of()), List.of(), List.of(), List.of(), List.of()),
new JSONPolicy(new AccessRightSet(), new JSONGraph(List.of(), List.of(), null, List.of(), List.of()), List.of(), List.of(), List.of(), List.of()),
new JSONPolicy(new AccessRightSet(), new JSONGraph(List.of(), List.of(), List.of(), null, List.of()), List.of(), List.of(), List.of(), List.of()),
new JSONPolicy(new AccessRightSet(), new JSONGraph(List.of(), List.of(), List.of(), List.of(), null), List.of(), List.of(), List.of(), List.of())
);

for (JSONPolicy policy : policies) {
assertDoesNotThrow(() -> new MemoryPAP().deserialize(new UserContext(), policy.toString(), new JSONDeserializer()));
}
}

}

0 comments on commit 568d260

Please sign in to comment.