Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: filter remedies in prohibitions #4092

Merged
merged 1 commit into from
Apr 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
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);
}
}
Loading