Skip to content

Commit 0b20767

Browse files
refactor plugin functions and other small fixes (#207)
* small refactor to patterns * remove epp specific exception * add plugin registry for adding ops and routines at runtime * wrap the PAP used by PDPTx so the PAP functions are not exposed outside the PDPTx class * ad tests for routines and operations with plugins * add overloaded constructor to PMLBootstrapper
1 parent 1b5e832 commit 0b20767

File tree

48 files changed

+750
-416
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+750
-416
lines changed

src/main/java/gov/nist/csd/pm/core/epp/EPP.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ public EPP(PDP pdp, PAP pap) {
2727
@Override
2828
public void processEvent(EventContext eventCtx) throws PMException {
2929
Collection<Obligation> obligations = pap.query().obligations().getObligations();
30-
for(Obligation obligation : obligations) {
30+
for (Obligation obligation : obligations) {
3131
long author = obligation.getAuthorId();
3232
List<Rule> rules = obligation.getRules();
33-
for(Rule rule : rules) {
34-
if(!rule.getEventPattern().matches(eventCtx, pap)) {
33+
for (Rule rule : rules) {
34+
if (!rule.getEventPattern().matches(eventCtx, pap)) {
3535
continue;
3636
}
3737

@@ -45,7 +45,7 @@ public void processEvent(EventContext eventCtx) throws PMException {
4545

4646
public void executeResponse(UserContext author, ObligationResponse obligationResponse, EventContext eventCtx) throws PMException {
4747
pdp.runTx(author, pdpTx -> {
48-
obligationResponse.execute(pdpTx, author, eventCtx);
48+
pdpTx.executeObligationResponse(eventCtx, obligationResponse);
4949
return null;
5050
});
5151
}

src/main/java/gov/nist/csd/pm/core/impl/memory/pap/MemoryPAP.java

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import gov.nist.csd.pm.core.common.exception.PMException;
44
import gov.nist.csd.pm.core.impl.memory.pap.store.MemoryPolicyStore;
5+
import gov.nist.csd.pm.core.pap.function.PluginRegistry;
56
import gov.nist.csd.pm.core.pap.function.op.PrivilegeChecker;
67
import gov.nist.csd.pm.core.pap.modification.GraphModifier;
78
import gov.nist.csd.pm.core.pap.modification.ObligationsModifier;
@@ -33,12 +34,13 @@ public MemoryPAP(MemoryPolicyStore store) throws PMException {
3334
public MemoryPAP(PolicyStore policyStore,
3435
PolicyModifier modifier,
3536
PolicyQuerier querier,
36-
PrivilegeChecker privilegeChecker) throws PMException {
37-
super(policyStore, modifier, querier, privilegeChecker);
37+
PrivilegeChecker privilegeChecker,
38+
PluginRegistry pluginRegistry) throws PMException {
39+
super(policyStore, modifier, querier, privilegeChecker, pluginRegistry);
3840
}
3941

40-
public MemoryPAP(PolicyQuerier querier, PolicyModifier modifier, PolicyStore policyStore) throws PMException {
41-
super(querier, modifier, policyStore);
42+
public MemoryPAP(PolicyQuerier querier, PolicyModifier modifier, PolicyStore policyStore, PluginRegistry pluginRegistry) throws PMException {
43+
super(querier, modifier, policyStore, pluginRegistry);
4244
}
4345

4446
public MemoryPAP(PAP pap) throws PMException {
@@ -56,25 +58,27 @@ private static MemoryPAP initDefault(MemoryPolicyStore memoryPolicyStore) throws
5658
}
5759

5860
private static MemoryPAP initMemoryPAP(MemoryPolicyStore memoryPolicyStore) throws PMException {
61+
PluginRegistry pluginRegistry = new PluginRegistry();
62+
5963
PolicyModifier policyModifier = new PolicyModifier(
6064
new GraphModifier(memoryPolicyStore, new RandomIdGenerator()),
6165
new ProhibitionsModifier(memoryPolicyStore),
6266
new ObligationsModifier(memoryPolicyStore),
63-
new OperationsModifier(memoryPolicyStore),
64-
new RoutinesModifier(memoryPolicyStore)
67+
new OperationsModifier(memoryPolicyStore, pluginRegistry),
68+
new RoutinesModifier(memoryPolicyStore, pluginRegistry)
6569
);
6670

6771
PolicyQuerier policyQuerier = new PolicyQuerier(
6872
new GraphQuerier(memoryPolicyStore),
6973
new ProhibitionsQuerier(memoryPolicyStore),
7074
new ObligationsQuerier(memoryPolicyStore),
71-
new OperationsQuerier(memoryPolicyStore),
72-
new RoutinesQuerier(memoryPolicyStore),
75+
new OperationsQuerier(memoryPolicyStore, pluginRegistry),
76+
new RoutinesQuerier(memoryPolicyStore, pluginRegistry),
7377
new AccessQuerier(memoryPolicyStore)
7478
);
7579

7680
PrivilegeChecker privilegeChecker = new PrivilegeChecker(policyQuerier.access());
7781

78-
return new MemoryPAP(memoryPolicyStore, policyModifier, policyQuerier, privilegeChecker);
82+
return new MemoryPAP(memoryPolicyStore, policyModifier, policyQuerier, privilegeChecker, pluginRegistry);
7983
}
8084
}

src/main/java/gov/nist/csd/pm/core/impl/neo4j/embedded/pap/Neo4jEmbeddedPAP.java

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import gov.nist.csd.pm.core.common.exception.PMException;
44
import gov.nist.csd.pm.core.impl.neo4j.embedded.pap.store.Neo4jEmbeddedPolicyStore;
55
import gov.nist.csd.pm.core.pap.PAP;
6+
import gov.nist.csd.pm.core.pap.function.PluginRegistry;
67
import gov.nist.csd.pm.core.pap.function.op.PrivilegeChecker;
78
import gov.nist.csd.pm.core.pap.id.RandomIdGenerator;
89
import gov.nist.csd.pm.core.pap.modification.GraphModifier;
@@ -29,13 +30,16 @@ public Neo4jEmbeddedPAP(Neo4jEmbeddedPolicyStore store) throws PMException {
2930
public Neo4jEmbeddedPAP(PolicyStore policyStore,
3031
PolicyModifier modifier,
3132
PolicyQuerier querier,
32-
PrivilegeChecker privilegeChecker) throws PMException {
33-
super(policyStore, modifier, querier, privilegeChecker);
33+
PrivilegeChecker privilegeChecker,
34+
PluginRegistry pluginRegistry) throws PMException {
35+
super(policyStore, modifier, querier, privilegeChecker, pluginRegistry);
3436
}
3537

36-
public Neo4jEmbeddedPAP(PolicyQuerier querier, PolicyModifier modifier, PolicyStore policyStore) throws
37-
PMException {
38-
super(querier, modifier, policyStore);
38+
public Neo4jEmbeddedPAP(PolicyQuerier querier,
39+
PolicyModifier modifier,
40+
PolicyStore policyStore,
41+
PluginRegistry pluginRegistry) throws PMException {
42+
super(querier, modifier, policyStore, pluginRegistry);
3943
}
4044

4145
public Neo4jEmbeddedPAP(PAP pap) throws PMException {
@@ -47,25 +51,27 @@ private static Neo4jEmbeddedPAP initDefault(Neo4jEmbeddedPolicyStore memoryPolic
4751
}
4852

4953
private static Neo4jEmbeddedPAP initNeo4MemoryPAP(Neo4jEmbeddedPolicyStore memoryPolicyStore) throws PMException {
54+
PluginRegistry pluginRegistry = new PluginRegistry();
55+
5056
PolicyModifier policyModifier = new PolicyModifier(
5157
new GraphModifier(memoryPolicyStore, new RandomIdGenerator()),
5258
new ProhibitionsModifier(memoryPolicyStore),
5359
new ObligationsModifier(memoryPolicyStore),
54-
new OperationsModifier(memoryPolicyStore),
55-
new RoutinesModifier(memoryPolicyStore)
60+
new OperationsModifier(memoryPolicyStore, pluginRegistry),
61+
new RoutinesModifier(memoryPolicyStore, pluginRegistry)
5662
);
5763

5864
PolicyQuerier policyQuerier = new PolicyQuerier(
5965
new GraphQuerier(memoryPolicyStore),
6066
new ProhibitionsQuerier(memoryPolicyStore),
6167
new ObligationsQuerier(memoryPolicyStore),
62-
new OperationsQuerier(memoryPolicyStore),
63-
new RoutinesQuerier(memoryPolicyStore),
68+
new OperationsQuerier(memoryPolicyStore, pluginRegistry),
69+
new RoutinesQuerier(memoryPolicyStore, pluginRegistry),
6470
new AccessQuerier(memoryPolicyStore)
6571
);
6672

6773
PrivilegeChecker privilegeChecker = new PrivilegeChecker(policyQuerier.access());
6874

69-
return new Neo4jEmbeddedPAP(memoryPolicyStore, policyModifier, policyQuerier, privilegeChecker);
75+
return new Neo4jEmbeddedPAP(memoryPolicyStore, policyModifier, policyQuerier, privilegeChecker, pluginRegistry);
7076
}
7177
}

src/main/java/gov/nist/csd/pm/core/pap/PAP.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import gov.nist.csd.pm.core.common.exception.PMException;
55
import gov.nist.csd.pm.core.pap.admin.AdminPolicy;
66
import gov.nist.csd.pm.core.pap.admin.AdminPolicyNode;
7+
import gov.nist.csd.pm.core.pap.function.PluginRegistry;
78
import gov.nist.csd.pm.core.pap.function.arg.Args;
89
import gov.nist.csd.pm.core.pap.function.AdminFunction;
910
import gov.nist.csd.pm.core.pap.function.AdminFunctionExecutor;
@@ -26,6 +27,7 @@
2627
import gov.nist.csd.pm.core.pdp.bootstrap.PolicyBootstrapper;
2728

2829
import java.util.*;
30+
import scala.concurrent.impl.FutureConvertersImpl.P;
2931

3032
import static gov.nist.csd.pm.core.common.graph.node.NodeType.ANY;
3133
import static gov.nist.csd.pm.core.common.graph.node.Properties.NO_PROPERTIES;
@@ -36,29 +38,32 @@ public abstract class PAP implements AdminFunctionExecutor, Transactional {
3638
private final PolicyModifier modifier;
3739
private final PolicyQuerier querier;
3840
private final PrivilegeChecker privilegeChecker;
41+
private final PluginRegistry pluginRegistry;
3942

40-
public PAP(PolicyStore policyStore, PolicyModifier modifier, PolicyQuerier querier, PrivilegeChecker privilegeChecker) throws PMException {
43+
public PAP(PolicyStore policyStore, PolicyModifier modifier, PolicyQuerier querier, PrivilegeChecker privilegeChecker, PluginRegistry pluginRegistry) throws PMException {
4144
this.policyStore = policyStore;
4245
this.modifier = modifier;
4346
this.querier = querier;
4447
this.privilegeChecker = privilegeChecker;
48+
this.pluginRegistry = pluginRegistry;
4549

4650
// verify admin policy
4751
AdminPolicy.verifyAdminPolicy(policyStore().graph());
4852
}
4953

50-
public PAP(PolicyQuerier querier, PolicyModifier modifier, PolicyStore policyStore) throws PMException {
54+
public PAP(PolicyQuerier querier, PolicyModifier modifier, PolicyStore policyStore, PluginRegistry pluginRegistry) throws PMException {
5155
this.querier = querier;
5256
this.modifier = modifier;
5357
this.policyStore = policyStore;
5458
this.privilegeChecker = new PrivilegeChecker(querier.access());
59+
this.pluginRegistry = pluginRegistry;
5560

5661
// verify admin policy
5762
AdminPolicy.verifyAdminPolicy(policyStore().graph());
5863
}
5964

6065
public PAP(PAP pap) throws PMException {
61-
this(pap.policyStore, pap.modifier, pap.querier, pap.privilegeChecker);
66+
this(pap.policyStore, pap.modifier, pap.querier, pap.privilegeChecker, pap.pluginRegistry);
6267
}
6368

6469
public PolicyQuery query() {
@@ -77,6 +82,10 @@ public PrivilegeChecker privilegeChecker() {
7782
return privilegeChecker;
7883
}
7984

85+
public PluginRegistry plugins() {
86+
return pluginRegistry;
87+
}
88+
8089
public PAP withIdGenerator(IdGenerator idGenerator) {
8190
this.modifier.graph().setIdGenerator(idGenerator);
8291
return this;
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package gov.nist.csd.pm.core.pap.function;
2+
3+
import gov.nist.csd.pm.core.pap.function.op.Operation;
4+
import gov.nist.csd.pm.core.pap.function.routine.Routine;
5+
import java.util.ArrayList;
6+
import java.util.List;
7+
8+
public class PluginRegistry {
9+
10+
private final List<Operation<?, ?>> operations;
11+
private final List<Routine<?, ?>> routines;
12+
13+
public PluginRegistry() {
14+
operations = new ArrayList<>();
15+
routines = new ArrayList<>();
16+
}
17+
18+
public PluginRegistry(List<Operation<?, ?>> operations, List<Routine<?, ?>> routines) {
19+
this.operations = operations;
20+
this.routines = routines;
21+
}
22+
23+
public List<Operation<?, ?>> getOperations() {
24+
return operations;
25+
}
26+
27+
public List<Routine<?, ?>> getRoutines() {
28+
return routines;
29+
}
30+
31+
public Operation<?, ?> getOperation(String name) {
32+
for (Operation<?, ?> op : operations) {
33+
if (op.getName().equals(name)) {
34+
return op;
35+
}
36+
}
37+
38+
return null;
39+
}
40+
41+
public Routine<?, ?> getRoutine(String name) {
42+
for (Routine<?, ?> routine : routines) {
43+
if (routine.getName().equals(name)) {
44+
return routine;
45+
}
46+
}
47+
48+
return null;
49+
}
50+
51+
public void registerOperation(Operation<?, ?> op) {
52+
boolean exists = operations.stream()
53+
.anyMatch(existing -> existing.getName().equals(op.getName()));
54+
55+
if (exists) {
56+
throw new IllegalArgumentException(
57+
"An operation with the name " + op.getName() + " is already registered"
58+
);
59+
}
60+
61+
operations.add(op);
62+
}
63+
64+
public void registerRoutine(Routine<?, ?> routine) {
65+
boolean exists = operations.stream()
66+
.anyMatch(existing -> existing.getName().equals(routine.getName()));
67+
68+
if (exists) {
69+
throw new IllegalArgumentException(
70+
"A routine with the name " + routine.getName() + " is already registered"
71+
);
72+
}
73+
74+
routines.add(routine);
75+
}
76+
77+
public void removeOperation(String opName) {
78+
operations.removeIf(op -> op.getName().equals(opName));
79+
}
80+
81+
public void removeRoutine(String routineName) {
82+
routines.removeIf(routine -> routine.getName().equals(routineName));
83+
}
84+
85+
public List<String> getOperationNames() {
86+
return operations.stream()
87+
.map(Operation::getName)
88+
.toList();
89+
}
90+
91+
public List<String> getRoutineNames() {
92+
return routines.stream()
93+
.map(Routine::getName)
94+
.toList();
95+
}
96+
}

src/main/java/gov/nist/csd/pm/core/pap/modification/OperationsModifier.java

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,26 @@
11
package gov.nist.csd.pm.core.pap.modification;
22

33
import gov.nist.csd.pm.core.common.exception.PMException;
4+
import gov.nist.csd.pm.core.common.exception.RoutineExistsException;
45
import gov.nist.csd.pm.core.common.graph.relationship.AccessRightSet;
56
import gov.nist.csd.pm.core.common.exception.AdminAccessRightExistsException;
67
import gov.nist.csd.pm.core.common.exception.OperationExistsException;
78
import gov.nist.csd.pm.core.pap.admin.AdminOperations;
9+
import gov.nist.csd.pm.core.pap.function.PluginRegistry;
810
import gov.nist.csd.pm.core.pap.function.op.Operation;
911
import gov.nist.csd.pm.core.pap.store.PolicyStore;
12+
import java.util.List;
1013

1114
import static gov.nist.csd.pm.core.pap.admin.AdminAccessRights.isAdminAccessRight;
1215
import static gov.nist.csd.pm.core.pap.admin.AdminAccessRights.isWildcardAccessRight;
1316

1417
public class OperationsModifier extends Modifier implements OperationsModification {
1518

16-
public OperationsModifier(PolicyStore store) {
19+
private PluginRegistry pluginRegistry;
20+
21+
public OperationsModifier(PolicyStore store, PluginRegistry pluginRegistry) {
1722
super(store);
23+
this.pluginRegistry = pluginRegistry;
1824
}
1925

2026
@Override
@@ -27,7 +33,8 @@ public void setResourceOperations(AccessRightSet resourceOperations) throws PMEx
2733
@Override
2834
public void createAdminOperation(Operation<?, ?> operation) throws PMException {
2935
if (AdminOperations.isAdminOperation(operation.getName())
30-
|| policyStore.operations().getAdminOperationNames().contains(operation.getName())) {
36+
|| policyStore.operations().getAdminOperationNames().contains(operation.getName())
37+
|| pluginRegistry.getOperationNames().contains(operation.getName())) {
3138
throw new OperationExistsException(operation.getName());
3239
}
3340

@@ -36,24 +43,29 @@ public void createAdminOperation(Operation<?, ?> operation) throws PMException {
3643

3744
@Override
3845
public void deleteAdminOperation(String operation) throws PMException {
46+
if (pluginRegistry.getOperationNames().contains(operation)) {
47+
pluginRegistry.removeOperation(operation);
48+
return;
49+
}
50+
3951
// return without error if the operation does not exist or is a built in admin op such as assign
4052
if (AdminOperations.ADMIN_OP_NAMES.contains(operation)
41-
|| !policyStore.operations().getAdminOperationNames().contains(operation)) {
53+
|| !policyStore.operations().getAdminOperationNames().contains(operation)) {
4254
return;
4355
}
4456

4557
policyStore.operations().deleteAdminOperation(operation);
4658
}
4759

4860
/**
49-
* Check that the provided resource operations are not existing admin access rights.
61+
* Check that the provided resource operations are not existing admin access rights, operations or routines.
5062
*
5163
* @param accessRightSet The access right set to check.
5264
* @throws PMException If any PM related exceptions occur in the implementing class.
5365
*/
5466
protected void checkSetResourceAccessRightsInput(AccessRightSet accessRightSet) throws PMException {
5567
for (String ar : accessRightSet) {
56-
if (isAdminAccessRight(ar) || isWildcardAccessRight(ar)) {
68+
if (isAdminAccessRight(ar) || isWildcardAccessRight(ar) ) {
5769
throw new AdminAccessRightExistsException(ar);
5870
}
5971
}

0 commit comments

Comments
 (0)