-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add getAdjacentDescendants method to AccessQuery interface (#169)
* add getAdjacentDescendants method to AccessQuery interface * add check to root * use pmadmin where pcs are used in access methods * support node or attributes in user and target contexts * update javadoc * fix privilege checker when toCheck is empty * updates * - modify memory access evaluators to only perform one traversal - remove access checks in the PDP AccessQueryAdjudicator - removed computePolicyClassAccessRights as the functionality is copied in explain
- Loading branch information
1 parent
7f35068
commit dbff2d1
Showing
154 changed files
with
1,536 additions
and
1,137 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
679 changes: 0 additions & 679 deletions
679
src/main/java/gov/nist/csd/pm/impl/memory/pap/MemoryAccessQuerier.java
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
224 changes: 224 additions & 0 deletions
224
src/main/java/gov/nist/csd/pm/impl/memory/pap/access/MemoryAccessQuerier.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,224 @@ | ||
package gov.nist.csd.pm.impl.memory.pap.access; | ||
|
||
import gov.nist.csd.pm.pap.exception.PMException; | ||
import gov.nist.csd.pm.pap.graph.dag.*; | ||
import gov.nist.csd.pm.pap.graph.relationship.AccessRightSet; | ||
import gov.nist.csd.pm.pap.AccessQuerier; | ||
import gov.nist.csd.pm.pap.query.model.context.UserContext; | ||
import gov.nist.csd.pm.pap.query.model.context.TargetContext; | ||
import gov.nist.csd.pm.pap.query.model.explain.*; | ||
import gov.nist.csd.pm.pap.query.model.subgraph.SubgraphPrivileges; | ||
import gov.nist.csd.pm.pap.store.GraphStoreBFS; | ||
import gov.nist.csd.pm.pap.store.PolicyStore; | ||
|
||
import java.util.*; | ||
|
||
import static gov.nist.csd.pm.pap.admin.AdminPolicyNode.PM_ADMIN_OBJECT; | ||
import static gov.nist.csd.pm.pap.AccessRightResolver.*; | ||
import static gov.nist.csd.pm.pap.graph.node.NodeType.U; | ||
import static gov.nist.csd.pm.pap.graph.node.Properties.NO_PROPERTIES; | ||
|
||
public class MemoryAccessQuerier extends AccessQuerier { | ||
|
||
public MemoryAccessQuerier(PolicyStore memoryPolicyStore) { | ||
super(memoryPolicyStore); | ||
} | ||
|
||
@Override | ||
public AccessRightSet computePrivileges(UserContext userCtx, TargetContext targetCtx) throws PMException { | ||
// traverse the user side of the graph to get the associations | ||
MemoryUserEvaluator userEvaluator = new MemoryUserEvaluator(store); | ||
UserDagResult userDagResult = userEvaluator.evaluate(userCtx); | ||
|
||
// traverse the target side of the graph to get permissions per policy class | ||
MemoryTargetEvaluator targetEvaluator = new MemoryTargetEvaluator(store); | ||
TargetDagResult targetDagResult = targetEvaluator.evaluate(userDagResult, targetCtx); | ||
|
||
// resolve the permissions | ||
return resolvePrivileges(userDagResult, targetDagResult, store.operations().getResourceOperations()); | ||
} | ||
|
||
@Override | ||
public List<AccessRightSet> computePrivileges(UserContext userCtx, List<TargetContext> targetCtxs) throws PMException { | ||
// traverse the user side of the graph to get the associations | ||
MemoryUserEvaluator userEvaluator = new MemoryUserEvaluator(store); | ||
UserDagResult userDagResult = userEvaluator.evaluate(userCtx); | ||
|
||
// traverse the target side of the graph to get permissions per policy class | ||
MemoryTargetEvaluator targetEvaluator = new MemoryTargetEvaluator(store); | ||
|
||
List<AccessRightSet> accessRightSets = new ArrayList<>(); | ||
for (TargetContext targetCtx : targetCtxs) { | ||
TargetDagResult targetDagResult = targetEvaluator.evaluate(userDagResult, targetCtx); | ||
AccessRightSet privs = resolvePrivileges(userDagResult, targetDagResult, store.operations().getResourceOperations()); | ||
|
||
accessRightSets.add(privs); | ||
} | ||
|
||
return accessRightSets; | ||
} | ||
|
||
@Override | ||
public AccessRightSet computeDeniedPrivileges(UserContext userCtx, TargetContext targetCtx) throws PMException { | ||
AccessRightSet accessRights = new AccessRightSet(); | ||
|
||
// traverse the user side of the graph to get the associations | ||
MemoryUserEvaluator userEvaluator = new MemoryUserEvaluator(store); | ||
UserDagResult userDagResult = userEvaluator.evaluate(userCtx); | ||
if (userDagResult.borderTargets().isEmpty()) { | ||
return accessRights; | ||
} | ||
|
||
// traverse the target side of the graph to get permissions per policy class | ||
MemoryTargetEvaluator targetEvaluator = new MemoryTargetEvaluator(store); | ||
TargetDagResult targetDagResult = targetEvaluator.evaluate(userDagResult, targetCtx); | ||
|
||
// resolve the permissions | ||
return resolveDeniedAccessRights(userDagResult, targetDagResult); | ||
} | ||
|
||
@Override | ||
public Map<String, AccessRightSet> computeCapabilityList(UserContext userCtx) throws PMException { | ||
Map<String, AccessRightSet> results = new HashMap<>(); | ||
|
||
//get border nodes. Can be OA or UA. Return empty set if no attrs are reachable | ||
MemoryUserEvaluator userEvaluator = new MemoryUserEvaluator(store); | ||
UserDagResult userDagResult = userEvaluator.evaluate(userCtx); | ||
if (userDagResult.borderTargets().isEmpty()) { | ||
return results; | ||
} | ||
|
||
for(String borderTarget : userDagResult.borderTargets().keySet()) { | ||
// compute permissions on the border attr | ||
getAndStorePrivileges(results, userDagResult, borderTarget); | ||
|
||
// compute decisions for the subgraph of the border attr | ||
Set<String> descendants = getDescendants(borderTarget); | ||
for (String descendant : descendants) { | ||
if (results.containsKey(descendant)) { | ||
continue; | ||
} | ||
|
||
getAndStorePrivileges(results, userDagResult, descendant); | ||
} | ||
} | ||
|
||
// add policy classes | ||
if (results.containsKey(PM_ADMIN_OBJECT.nodeName())) { | ||
AccessRightSet arset = results.get(PM_ADMIN_OBJECT.nodeName()); | ||
for (String pc : store.graph().getPolicyClasses()) { | ||
results.put(pc, arset); | ||
} | ||
} | ||
|
||
return results; | ||
} | ||
|
||
@Override | ||
public Map<String, AccessRightSet> computeACL(TargetContext targetCtx) throws PMException { | ||
Map<String, AccessRightSet> acl = new HashMap<>(); | ||
Collection<String> search = store.graph().search(U, NO_PROPERTIES); | ||
for (String user : search) { | ||
AccessRightSet list = this.computePrivileges(new UserContext(user), targetCtx); | ||
acl.put(user, list); | ||
} | ||
|
||
return acl; | ||
} | ||
|
||
@Override | ||
public Map<String, AccessRightSet> computeDestinationAttributes(UserContext userCtx) throws PMException { | ||
return new MemoryUserEvaluator(store) | ||
.evaluate(userCtx) | ||
.borderTargets(); | ||
} | ||
|
||
@Override | ||
public SubgraphPrivileges computeSubgraphPrivileges(UserContext userCtx, String root) throws PMException { | ||
List<SubgraphPrivileges> subgraphs = new ArrayList<>(); | ||
|
||
Collection<String> adjacentAscendants = store.graph().getAdjacentAscendants(root); | ||
for (String adjacent : adjacentAscendants) { | ||
subgraphs.add(computeSubgraphPrivileges(userCtx, adjacent)); | ||
} | ||
|
||
return new SubgraphPrivileges(root, computePrivileges(userCtx, new TargetContext(root)), subgraphs); | ||
} | ||
|
||
@Override | ||
public Map<String, AccessRightSet> computeAdjacentAscendantPrivileges(UserContext userCtx, String root) throws PMException { | ||
Map<String, AccessRightSet> ascendantPrivs = new HashMap<>(); | ||
|
||
Collection<String> adjacentAscendants = store.graph().getAdjacentAscendants(root); | ||
for (String adjacentAscendant : adjacentAscendants) { | ||
ascendantPrivs.put(adjacentAscendant, computePrivileges(userCtx, new TargetContext(adjacentAscendant))); | ||
} | ||
|
||
return ascendantPrivs; | ||
} | ||
|
||
@Override | ||
public Map<String, AccessRightSet> computeAdjacentDescendantPrivileges(UserContext userCtx, String root) throws PMException { | ||
Map<String, AccessRightSet> descendantPrivs = new HashMap<>(); | ||
|
||
Collection<String> adjacentDescendants = store.graph().getAdjacentDescendants(root); | ||
for (String adjacentDescendant : adjacentDescendants) { | ||
descendantPrivs.put(adjacentDescendant, computePrivileges(userCtx, new TargetContext(adjacentDescendant))); | ||
} | ||
|
||
return descendantPrivs; | ||
} | ||
|
||
@Override | ||
public Explain explain(UserContext userCtx, TargetContext targetCtx) throws PMException { | ||
return new MemoryExplainer(store) | ||
.explain(userCtx, targetCtx); | ||
} | ||
|
||
@Override | ||
public Map<String, AccessRightSet> computePersonalObjectSystem(UserContext userCtx) throws PMException { | ||
Map<String, AccessRightSet> pos = new HashMap<>(); | ||
|
||
for (String pc : store.graph().getPolicyClasses()) { | ||
new GraphStoreBFS(store.graph()) | ||
.withDirection(Direction.ASCENDANTS) | ||
.withVisitor(n -> { | ||
AccessRightSet privs = computePrivileges(userCtx, new TargetContext(n)); | ||
if (privs.isEmpty()) { | ||
return; | ||
} | ||
|
||
pos.put(n, privs); | ||
}) | ||
.withSinglePathShortCircuit(n -> { | ||
return pos.containsKey(n); | ||
}) | ||
.walk(pc); | ||
} | ||
return pos; | ||
} | ||
|
||
private void getAndStorePrivileges(Map<String, AccessRightSet> arsetMap, UserDagResult userDagResult, String target) throws PMException { | ||
TargetDagResult result = new MemoryTargetEvaluator(store) | ||
.evaluate(userDagResult, new TargetContext(target)); | ||
AccessRightSet privileges = resolvePrivileges(userDagResult, result, store.operations().getResourceOperations()); | ||
arsetMap.put(target, privileges); | ||
} | ||
|
||
private Set<String> getDescendants(String vNode) throws PMException { | ||
Set<String> descendants = new HashSet<>(); | ||
|
||
Collection<String> ascendants = store.graph().getAdjacentAscendants(vNode); | ||
if (ascendants.isEmpty()) { | ||
return descendants; | ||
} | ||
|
||
descendants.addAll(ascendants); | ||
for (String ascendant : ascendants) { | ||
descendants.add(ascendant); | ||
descendants.addAll(getDescendants(ascendant)); | ||
} | ||
|
||
return descendants; | ||
} | ||
} |
121 changes: 121 additions & 0 deletions
121
src/main/java/gov/nist/csd/pm/impl/memory/pap/access/MemoryExplainer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
package gov.nist.csd.pm.impl.memory.pap.access; | ||
|
||
import gov.nist.csd.pm.pap.exception.PMException; | ||
import gov.nist.csd.pm.pap.graph.dag.TargetDagResult; | ||
import gov.nist.csd.pm.pap.graph.dag.UserDagResult; | ||
import gov.nist.csd.pm.pap.graph.relationship.AccessRightSet; | ||
import gov.nist.csd.pm.pap.graph.relationship.Association; | ||
import gov.nist.csd.pm.pap.prohibition.Prohibition; | ||
import gov.nist.csd.pm.pap.query.model.context.TargetContext; | ||
import gov.nist.csd.pm.pap.query.model.context.UserContext; | ||
import gov.nist.csd.pm.pap.query.model.explain.*; | ||
import gov.nist.csd.pm.pap.store.PolicyStore; | ||
|
||
import java.util.*; | ||
|
||
import static gov.nist.csd.pm.pap.AccessRightResolver.*; | ||
|
||
public class MemoryExplainer { | ||
|
||
private PolicyStore policyStore; | ||
|
||
public MemoryExplainer(PolicyStore policyStore) { | ||
this.policyStore = policyStore; | ||
} | ||
|
||
public Explain explain(UserContext userCtx, TargetContext targetCtx) throws PMException { | ||
// resolve paths from u to target | ||
List<PolicyClassExplain> resolvedPaths = resolvePaths(userCtx, targetCtx); | ||
|
||
// evaluate user | ||
MemoryUserEvaluator userEvaluator = new MemoryUserEvaluator(policyStore); | ||
UserDagResult userDagResult = userEvaluator.evaluate(userCtx); | ||
|
||
// evaluate target | ||
MemoryTargetEvaluator targetEvaluator = new MemoryTargetEvaluator(policyStore); | ||
TargetDagResult targetDagResult = targetEvaluator.evaluate(userDagResult, targetCtx); | ||
|
||
// resolve privs and prohibitions | ||
AccessRightSet priv = resolvePrivileges(userDagResult, targetDagResult, policyStore.operations().getResourceOperations()); | ||
AccessRightSet deniedPriv = resolveDeniedAccessRights(userDagResult, targetDagResult); | ||
List<Prohibition> prohibitions = computeSatisfiedProhibitions(userDagResult, targetDagResult); | ||
|
||
return new Explain(priv, resolvedPaths, deniedPriv, prohibitions); | ||
} | ||
|
||
private List<PolicyClassExplain> resolvePaths(UserContext userCtx, TargetContext targetCtx) throws PMException { | ||
MemoryUserExplainer userExplainer = new MemoryUserExplainer(policyStore); | ||
MemoryTargetExplainer targetExplainer = new MemoryTargetExplainer(policyStore); | ||
Map<String, Map<Path, List<Association>>> targetPaths = targetExplainer.explainTarget(targetCtx); | ||
Map<String, Set<Path>> userPaths = userExplainer.explainIntersectionOfTargetPaths(userCtx, targetPaths); | ||
|
||
List<PolicyClassExplain> result = new ArrayList<>(); | ||
|
||
for (Map.Entry<String, Map<Path, List<Association>>> targetPathEntry : targetPaths.entrySet()) { | ||
String pc = targetPathEntry.getKey(); | ||
Map<Path, List<Association>> targetPathAssociations = targetPathEntry.getValue(); | ||
|
||
List<List<ExplainNode>> paths = getExplainNodePaths(targetPathAssociations, userPaths); | ||
AccessRightSet arset = getArsetFromPaths(paths); | ||
|
||
result.add(new PolicyClassExplain(pc, arset, paths)); | ||
} | ||
|
||
return result; | ||
} | ||
|
||
private List<List<ExplainNode>> getExplainNodePaths(Map<Path, List<Association>> targetPathAssociations, | ||
Map<String, Set<Path>> userPaths) { | ||
List<List<ExplainNode>> paths = new ArrayList<>(); | ||
|
||
for (Map.Entry<Path, List<Association>> targetPathEntry : targetPathAssociations.entrySet()) { | ||
Path path = targetPathEntry.getKey(); | ||
List<Association> pathAssocs = targetPathEntry.getValue(); | ||
|
||
List<ExplainNode> explainNodes = new ArrayList<>(); | ||
for (String node : path) { | ||
List<ExplainAssociation> explainAssocs = new ArrayList<>(); | ||
|
||
for (Association pathAssoc : pathAssocs) { | ||
String ua = pathAssoc.getSource(); | ||
String target = pathAssoc.getTarget(); | ||
if (!target.equals(node)) { | ||
continue; | ||
} | ||
|
||
Set<Path> userPathsToAssoc = userPaths.getOrDefault(ua, new HashSet<>()); | ||
|
||
explainAssocs.add(new ExplainAssociation( | ||
ua, | ||
pathAssoc.getAccessRightSet(), | ||
new ArrayList<>(userPathsToAssoc) | ||
)); | ||
} | ||
|
||
explainNodes.add(new ExplainNode(node, explainAssocs)); | ||
} | ||
|
||
paths.add(explainNodes); | ||
} | ||
|
||
return paths; | ||
} | ||
|
||
private AccessRightSet getArsetFromPaths(List<List<ExplainNode>> paths) { | ||
AccessRightSet accessRightSet = new AccessRightSet(); | ||
for (List<ExplainNode> path : paths) { | ||
for (ExplainNode explainNode : path) { | ||
List<ExplainAssociation> associations = explainNode.associations(); | ||
for (ExplainAssociation association : associations) { | ||
if (association.userPaths().isEmpty()) { | ||
continue; | ||
} | ||
|
||
accessRightSet.addAll(association.arset()); | ||
} | ||
} | ||
} | ||
|
||
return accessRightSet; | ||
} | ||
} |
Oops, something went wrong.