Skip to content

Commit

Permalink
feat: filter remedies in prohibitions (eclipse-edc#4092)
Browse files Browse the repository at this point in the history
  • Loading branch information
ndr-brt authored Apr 9, 2024
1 parent 1ee5974 commit 9df78b8
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@

import java.util.List;
import java.util.Objects;

import static java.util.stream.Collectors.toList;
import java.util.function.Function;

/**
* Filters a policy for a scope. This involves recursively removing rules and constraints not bound to the scope and
Expand All @@ -56,9 +55,9 @@ public ScopeFilter(RuleBindingRegistry registry) {
}

public Policy applyScope(Policy policy, String scope) {
var filteredObligations = policy.getObligations().stream().map(d -> applyScope(d, scope)).filter(Objects::nonNull).collect(toList());
var filteredPermissions = policy.getPermissions().stream().map(p -> applyScope(p, scope)).filter(Objects::nonNull).collect(toList());
var filteredProhibitions = policy.getProhibitions().stream().map(p -> applyScope(p, scope)).filter(Objects::nonNull).collect(toList());
var filteredObligations = filterBy(policy.getObligations(), d -> applyScope(d, scope));
var filteredPermissions = filterBy(policy.getPermissions(), d -> applyScope(d, scope));
var filteredProhibitions = filterBy(policy.getProhibitions(), d -> applyScope(d, scope));
return Policy.Builder.newInstance()
.type(policy.getType())
.assignee(policy.getAssignee())
Expand All @@ -77,8 +76,8 @@ Permission applyScope(Permission permission, String scope) {
if (actionNotInScope(permission, scope)) {
return null;
}
var filteredConstraints = applyScope(permission.getConstraints(), scope);
var filteredDuties = permission.getDuties().stream().map(d -> applyScope(d, scope)).filter(Objects::nonNull).toList();
var filteredConstraints = filterBy(permission.getConstraints(), c -> applyScope(c, scope));
var filteredDuties = filterBy(permission.getDuties(), d -> applyScope(d, scope));

return Permission.Builder.newInstance()
.action(permission.getAction())
Expand All @@ -92,11 +91,8 @@ Duty applyScope(Duty duty, String scope) {
if (actionNotInScope(duty, scope)) {
return null;
}
var filteredConsequences = duty.getConsequences().stream()
.map(consequence -> applyScope(consequence, scope))
.filter(Objects::nonNull)
.toList();
var filteredConstraints = applyScope(duty.getConstraints(), scope);
var filteredConsequences = filterBy(duty.getConsequences(), d -> applyScope(d, scope));
var filteredConstraints = filterBy(duty.getConstraints(), c -> applyScope(c, scope));

return Duty.Builder.newInstance()
.action(duty.getAction())
Expand All @@ -111,11 +107,13 @@ Prohibition applyScope(Prohibition prohibition, String scope) {
if (actionNotInScope(prohibition, scope)) {
return null;
}
var filteredConstraints = applyScope(prohibition.getConstraints(), scope);
var filteredConstraints = filterBy(prohibition.getConstraints(), c -> applyScope(c, scope));
var filteredRemedies = filterBy(prohibition.getRemedies(), d -> applyScope(d, scope));

return Prohibition.Builder.newInstance()
.action(prohibition.getAction())
.constraints(filteredConstraints)
.remedies(filteredRemedies)
.build();
}

Expand All @@ -134,10 +132,6 @@ private boolean actionNotInScope(Rule rule, String scope) {
return rule.getAction() != null && !registry.isInScope(rule.getAction().getType(), scope);
}

private List<Constraint> applyScope(List<Constraint> constraints, String scope) {
return constraints.stream().map(constraint -> applyScope(constraint, scope)).filter(Objects::nonNull).toList();
}

@Nullable
private Constraint applyScope(AtomicConstraint constraint, String scope) {
if (constraint.getLeftExpression() instanceof LiteralExpression literalExpression) {
Expand All @@ -146,4 +140,8 @@ private Constraint applyScope(AtomicConstraint constraint, String scope) {
return constraint;
}
}

private <T> List<T> filterBy(List<T> list, Function<T, T> filterFunction) {
return list.stream().map(filterFunction).filter(Objects::nonNull).toList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,23 @@
import org.eclipse.edc.policy.model.Policy;
import org.eclipse.edc.policy.model.PolicyType;
import org.eclipse.edc.policy.model.Prohibition;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

class ScopeFilterTest {

public static final String BOUND_SCOPE = "scope1";
private static final String BOUND_SCOPE = "scope1";
private static final Action REPORT_ACTION = Action.Builder.newInstance().type("report").build();
private static final Action SUB_ACTION = Action.Builder.newInstance().type("subaction").build();
private static final LiteralExpression BOUND_LITERAL = new LiteralExpression("bound");
private static final LiteralExpression UNBOUND_LITERAL = new LiteralExpression("unbound");
private static final LiteralExpression EMPTY_LITERAL = new LiteralExpression("");
public static final AtomicConstraint BOUND_CONSTRAINT = AtomicConstraint.Builder.newInstance().leftExpression(BOUND_LITERAL).rightExpression(EMPTY_LITERAL).build();
public static final AtomicConstraint UNBOUND_CONSTRAINT = AtomicConstraint.Builder.newInstance().leftExpression(UNBOUND_LITERAL).rightExpression(EMPTY_LITERAL).build();
private ScopeFilter scopeFilter;
private RuleBindingRegistry registry;
private static final AtomicConstraint BOUND_CONSTRAINT = AtomicConstraint.Builder.newInstance().leftExpression(BOUND_LITERAL).rightExpression(EMPTY_LITERAL).build();
private static final AtomicConstraint UNBOUND_CONSTRAINT = AtomicConstraint.Builder.newInstance().leftExpression(UNBOUND_LITERAL).rightExpression(EMPTY_LITERAL).build();

private final RuleBindingRegistry registry = new RuleBindingRegistryImpl();
private final ScopeFilter scopeFilter = new ScopeFilter(registry);

@Test
void verifyFiltersUnboundPermissionType() {
Expand Down Expand Up @@ -125,14 +125,19 @@ void verifyFiltersProhibitionType() {
.action(REPORT_ACTION)
.constraint(BOUND_CONSTRAINT)
.constraint(UNBOUND_CONSTRAINT)
.remedy(Duty.Builder.newInstance().constraint(BOUND_CONSTRAINT).build())
.remedy(Duty.Builder.newInstance().constraint(UNBOUND_CONSTRAINT).build())
.build();

var filteredPermission = scopeFilter.applyScope(prohibition, BOUND_SCOPE);

assertThat(filteredPermission).isNotNull();
assertThat(filteredPermission.getAction()).isNotNull();
assertThat(filteredPermission.getConstraints().size()).isEqualTo(1); // verify that the unbound constraint was removed
assertThat(filteredPermission.getConstraints()).hasSize(1); // verify that the unbound constraint was removed
assertThat(filteredPermission.getConstraints()).contains(BOUND_CONSTRAINT);
assertThat(filteredPermission.getRemedies()).hasSize(2)
.anyMatch(it -> it.getConstraints().contains(BOUND_CONSTRAINT))
.anyMatch(it -> it.getConstraints().isEmpty());
}

@Test
Expand Down Expand Up @@ -183,9 +188,4 @@ void verifyMultiplicityConstraint() {
assertThat(filteredConstraint.getConstraints().size()).isEqualTo(2);
}

@BeforeEach
void setUp() {
registry = new RuleBindingRegistryImpl();
scopeFilter = new ScopeFilter(registry);
}
}

0 comments on commit 9df78b8

Please sign in to comment.