Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.sap.cloud.security.ams.dcn.engine.CompatibilityEvaluationNodeFactory Maven / Gradle / Ivy
Go to download
Client Library for integrating Jakarta EE applications with SAP Authorization Management Service (AMS)
/************************************************************************
* © 2019-2024 SAP SE or an SAP affiliate company. All rights reserved. *
************************************************************************/
package com.sap.cloud.security.ams.dcn.engine;
import static com.sap.cloud.security.ams.dcl.client.el.Call.QualifiedNames.IN;
import static com.sap.cloud.security.ams.dcl.client.el.Call.QualifiedNames.OR;
import com.sap.cloud.security.ams.dcl.client.el.AttributeName;
import com.sap.cloud.security.ams.dcl.client.el.Call;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
/**
* {@link EvaluationNodeFactory} implementation for creating {@link EvaluationNode} instances that
* are compatible with OPA behaviour. This class deviates from the base implementations in {@link
* AbstractEvaluationNodeFactory} by providing compatibility transformations for the {@link
* EvaluationNode#toCondition()} implementation of many node types.
*/
public class CompatibilityEvaluationNodeFactory extends AbstractEvaluationNodeFactory {
@Override
public AllOfNode allOfNode(Collection nodes) {
return super.allOfNode(nodes)
.writtenBy(
(subNodes) -> {
Set commonConditions = new HashSet<>();
List> eqConditionsFromInOps = new ArrayList<>();
subNodes.forEach(
node -> {
if (node instanceof BinaryOperatorNode operatorNode && operatorNode.is(IN)) {
Optional rightValue = operatorNode.rhs().value();
if (rightValue.isPresent()) {
EvaluationNode lhs = operatorNode.lhs();
eqConditionsFromInOps.add(
((Collection>) rightValue.get())
.stream()
.map(value -> equalsNode(lhs, valueNode(value)).toCondition())
.toList());
return;
}
}
commonConditions.add(node.toCondition());
});
AtomicReference>> allTuples =
new AtomicReference<>(new ArrayList<>());
allTuples.get().add(commonConditions);
eqConditionsFromInOps.forEach(
eqConditionsOfSingleInOp ->
allTuples.set(
eqConditionsOfSingleInOp.stream()
.flatMap(
eqCondition ->
allTuples.get().stream()
.map(
tuple -> {
Set newTuple = new HashSet<>(tuple);
newTuple.add(eqCondition);
return newTuple;
}))
.toList()));
return switch (allTuples.get().size()) {
case 0 -> false;
case 1 ->
switch (allTuples.get().iterator().next().size()) {
case 0 -> true;
case 1 -> allTuples.get().iterator().next().iterator().next();
default ->
Call.createFrom(
Call.QualifiedNames.AND, allTuples.get().iterator().next());
};
default ->
Call.createFrom(
OR,
allTuples.get().stream()
.map(
tuple ->
switch (tuple.size()) {
case 0 ->
true; // impossible, multiple tuples are always created by
// adding elements
case 1 -> tuple.iterator().next();
default -> Call.createFrom(Call.QualifiedNames.AND, tuple);
})
.toList());
};
});
}
@Override
public AnyOfNode anyOfNode(Collection nodes) {
return super.anyOfNode(nodes)
.writtenBy(
(subNodes) -> {
Set subConditions = new HashSet<>();
for (EvaluationNode node : subNodes) {
Object condition = node.toCondition();
if (condition instanceof Call call && call.getQualifiedName().equals(OR)) {
subConditions.addAll(call.getArguments());
} else {
subConditions.add(condition);
}
}
return switch (subConditions.size()) {
case 0 -> false;
case 1 -> subConditions.iterator().next();
default -> Call.createFrom(OR, subConditions);
};
});
}
@Override
public BinaryOperatorNode inNode(EvaluationNode lhs, EvaluationNode rhs) {
return super.inNode(lhs, rhs)
.writtenBy(
(left, right) -> {
Object leftCondition = left.toCondition();
Optional rightValue = right.value();
if (rightValue.isPresent()) {
List eqCalls =
((Collection>) rightValue.get())
.stream()
.map(value -> Call.create(Call.QualifiedNames.EQ, leftCondition, value))
.toList();
return switch (eqCalls.size()) {
case 0 -> false;
case 1 -> eqCalls.get(0);
default -> Call.createFrom(OR, eqCalls);
};
}
return Call.create(IN, leftCondition, right.toCondition());
});
}
@Override
public BinaryOperatorNode notInNode(EvaluationNode lhs, EvaluationNode rhs) {
return super.notInNode(lhs, rhs)
.writtenBy(
(left, right) -> {
Object leftCondition = left.toCondition();
Optional rightValue = right.value();
if (rightValue.isPresent()) {
List neCalls =
((Collection>) rightValue.get())
.stream()
.map(value -> Call.create(Call.QualifiedNames.NE, leftCondition, value))
.toList();
return switch (neCalls.size()) {
case 0 -> true;
case 1 -> neCalls.get(0);
default -> Call.createFrom(Call.QualifiedNames.AND, neCalls);
};
}
return Call.create(Call.QualifiedNames.NOT_IN, leftCondition, right.toCondition());
});
}
@Override
public BinaryOperatorNode lessThanOrEqualsNode(EvaluationNode lhs, EvaluationNode rhs) {
return super.lessThanOrEqualsNode(lhs, rhs)
.writtenBy(
(left, right) -> {
if (left.equals(right)) {
return isNotNullNode(left).toCondition();
}
return Call.create(Call.QualifiedNames.LE, left.toCondition(), right.toCondition());
});
}
@Override
public BinaryOperatorNode equalsNode(EvaluationNode lhs, EvaluationNode rhs) {
return super.equalsNode(lhs, rhs)
.writtenBy(
(left, right) -> {
if (left.equals(right)) {
return isNotNullNode(left).toCondition();
}
Object leftCondition = left.toCondition();
Object rightCondition = right.toCondition();
if (rightCondition instanceof AttributeName rightName) {
if (left.value().isPresent()
|| (leftCondition instanceof AttributeName leftName
&& leftName.compareTo(rightName) > 0)) {
return Call.create(Call.QualifiedNames.EQ, rightCondition, leftCondition);
}
}
return Call.create(Call.QualifiedNames.EQ, leftCondition, rightCondition);
});
}
@Override
public BinaryOperatorNode notEqualsNode(EvaluationNode lhs, EvaluationNode rhs) {
return super.notEqualsNode(lhs, rhs)
.writtenBy(
(left, right) -> {
Object leftCondition = left.toCondition();
Object rightCondition = right.toCondition();
if (rightCondition instanceof AttributeName rightName) {
if (left.value().isPresent()
|| (leftCondition instanceof AttributeName leftName
&& leftName.compareTo(rightName) > 0)) {
return Call.create(Call.QualifiedNames.NE, rightCondition, leftCondition);
}
}
return Call.create(Call.QualifiedNames.NE, leftCondition, rightCondition);
});
}
@Override
public BinaryOperatorNode greaterThanOrEqualsNode(EvaluationNode lhs, EvaluationNode rhs) {
return super.greaterThanOrEqualsNode(lhs, rhs)
.writtenBy(
(left, right) -> {
if (left.equals(right)) {
return isNotNullNode(left).toCondition();
}
return Call.create(Call.QualifiedNames.GE, left.toCondition(), right.toCondition());
});
}
@Override
public TernaryOperatorNode betweenNode(
EvaluationNode lhs, EvaluationNode lowerBound, EvaluationNode upperBound) {
return super.betweenNode(lhs, lowerBound, upperBound)
.writtenBy(
(left, lower, upper) -> {
if (left.equals(lower) && lower.equals(upper)) {
return isNotNullNode(left).toCondition();
}
return Call.create(
Call.QualifiedNames.AND,
Call.create(Call.QualifiedNames.GE, left.toCondition(), lower.toCondition()),
Call.create(Call.QualifiedNames.LE, left.toCondition(), upper.toCondition()));
});
}
@Override
public TernaryOperatorNode notBetweenNode(
EvaluationNode lhs, EvaluationNode lowerBound, EvaluationNode upperBound) {
return super.notBetweenNode(lhs, lowerBound, upperBound)
.writtenBy(
(left, lower, upper) ->
Call.create(
Call.QualifiedNames.OR,
Call.create(Call.QualifiedNames.LT, left.toCondition(), lower.toCondition()),
Call.create(Call.QualifiedNames.GT, left.toCondition(), upper.toCondition())));
}
}