Search in sources :

Example 1 with FilterPredicate

use of com.yahoo.elide.core.filter.predicates.FilterPredicate in project elide by yahoo.

the class FilterExpressionNormalizationVisitor method visitNotExpression.

@Override
public FilterExpression visitNotExpression(NotFilterExpression fe) {
    FilterExpression inner = fe.getNegated();
    if (inner instanceof AndFilterExpression) {
        AndFilterExpression and = (AndFilterExpression) inner;
        FilterExpression left = new NotFilterExpression(and.getLeft()).accept(this);
        FilterExpression right = new NotFilterExpression(and.getRight()).accept(this);
        return new OrFilterExpression(left, right);
    }
    if (inner instanceof OrFilterExpression) {
        OrFilterExpression or = (OrFilterExpression) inner;
        FilterExpression left = new NotFilterExpression(or.getLeft()).accept(this);
        FilterExpression right = new NotFilterExpression(or.getRight()).accept(this);
        return new AndFilterExpression(left, right);
    }
    if (inner instanceof NotFilterExpression) {
        NotFilterExpression not = (NotFilterExpression) inner;
        return (not.getNegated()).accept(this);
    }
    if (inner instanceof FilterPredicate) {
        FilterPredicate filter = (FilterPredicate) inner;
        return filter.negate();
    }
    return inner;
}
Also used : OrFilterExpression(com.yahoo.elide.core.filter.expression.OrFilterExpression) FilterPredicate(com.yahoo.elide.core.filter.predicates.FilterPredicate) NotFilterExpression(com.yahoo.elide.core.filter.expression.NotFilterExpression) OrFilterExpression(com.yahoo.elide.core.filter.expression.OrFilterExpression) AndFilterExpression(com.yahoo.elide.core.filter.expression.AndFilterExpression) FilterExpression(com.yahoo.elide.core.filter.expression.FilterExpression) NotFilterExpression(com.yahoo.elide.core.filter.expression.NotFilterExpression) AndFilterExpression(com.yahoo.elide.core.filter.expression.AndFilterExpression)

Example 2 with FilterPredicate

use of com.yahoo.elide.core.filter.predicates.FilterPredicate in project elide by yahoo.

the class VerifyFieldAccessFilterExpressionVisitor method visitPredicate.

/**
 * Enforce ReadPermission on provided query filter.
 *
 * @return true if allowed, false if rejected
 */
@Override
public Boolean visitPredicate(FilterPredicate filterPredicate) {
    RequestScope requestScope = resource.getRequestScope();
    Set<PersistentResource> val = Collections.singleton(resource);
    PermissionExecutor permissionExecutor = requestScope.getPermissionExecutor();
    ExpressionResult result = permissionExecutor.evaluateFilterJoinUserChecks(resource, filterPredicate);
    if (result == ExpressionResult.UNEVALUATED) {
        result = evaluateUserChecks(filterPredicate, permissionExecutor);
    }
    if (result == ExpressionResult.PASS) {
        return true;
    }
    if (result == ExpressionResult.FAIL) {
        return false;
    }
    for (PathElement element : filterPredicate.getPath().getPathElements()) {
        String fieldName = element.getFieldName();
        if ("this".equals(fieldName)) {
            continue;
        }
        try {
            val = val.stream().filter(Objects::nonNull).flatMap(x -> getValueChecked(x, fieldName, requestScope).toList(LinkedHashSet::new).blockingGet().stream()).filter(Objects::nonNull).collect(Collectors.toSet());
        } catch (ForbiddenAccessException e) {
            result = permissionExecutor.handleFilterJoinReject(filterPredicate, element, e);
            if (result == ExpressionResult.DEFERRED) {
                continue;
            }
            // pass or fail
            return result == ExpressionResult.PASS;
        }
    }
    return true;
}
Also used : FilterExpressionVisitor(com.yahoo.elide.core.filter.expression.FilterExpressionVisitor) FilterPredicate(com.yahoo.elide.core.filter.predicates.FilterPredicate) NotFilterExpression(com.yahoo.elide.core.filter.expression.NotFilterExpression) Set(java.util.Set) EntityProjection(com.yahoo.elide.core.request.EntityProjection) PermissionExecutor(com.yahoo.elide.core.security.PermissionExecutor) Collectors(java.util.stream.Collectors) EntityDictionary(com.yahoo.elide.core.dictionary.EntityDictionary) Objects(java.util.Objects) ForbiddenAccessException(com.yahoo.elide.core.exceptions.ForbiddenAccessException) ExpressionResult(com.yahoo.elide.core.security.permissions.ExpressionResult) ReadPermission(com.yahoo.elide.annotation.ReadPermission) OrFilterExpression(com.yahoo.elide.core.filter.expression.OrFilterExpression) PersistentResource(com.yahoo.elide.core.PersistentResource) AndFilterExpression(com.yahoo.elide.core.filter.expression.AndFilterExpression) Relationship(com.yahoo.elide.core.request.Relationship) Observable(io.reactivex.Observable) PathElement(com.yahoo.elide.core.Path.PathElement) RelationshipType(com.yahoo.elide.core.dictionary.RelationshipType) FilterExpression(com.yahoo.elide.core.filter.expression.FilterExpression) Collections(java.util.Collections) LinkedHashSet(java.util.LinkedHashSet) RequestScope(com.yahoo.elide.core.RequestScope) LinkedHashSet(java.util.LinkedHashSet) PersistentResource(com.yahoo.elide.core.PersistentResource) PathElement(com.yahoo.elide.core.Path.PathElement) ExpressionResult(com.yahoo.elide.core.security.permissions.ExpressionResult) PermissionExecutor(com.yahoo.elide.core.security.PermissionExecutor) Objects(java.util.Objects) RequestScope(com.yahoo.elide.core.RequestScope) ForbiddenAccessException(com.yahoo.elide.core.exceptions.ForbiddenAccessException)

Example 3 with FilterPredicate

use of com.yahoo.elide.core.filter.predicates.FilterPredicate in project elide by yahoo.

the class MatchesTemplateVisitor method matches.

private boolean matches(FilterExpression a, FilterExpression b) {
    if (!a.getClass().equals(b.getClass())) {
        return false;
    }
    if (a instanceof AndFilterExpression) {
        AndFilterExpression andA = (AndFilterExpression) a;
        AndFilterExpression andB = (AndFilterExpression) b;
        return matches(andA.getLeft(), andB.getLeft()) && matches(andA.getRight(), andB.getRight());
    }
    if (a instanceof OrFilterExpression) {
        OrFilterExpression orA = (OrFilterExpression) a;
        OrFilterExpression orB = (OrFilterExpression) b;
        return matches(orA.getLeft(), orB.getLeft()) && matches(orA.getRight(), orB.getRight());
    }
    if (a instanceof NotFilterExpression) {
        NotFilterExpression notA = (NotFilterExpression) a;
        NotFilterExpression notB = (NotFilterExpression) b;
        return matches(notA.getNegated(), notB.getNegated());
    }
    FilterPredicate predicateA = (FilterPredicate) a;
    FilterPredicate predicateB = (FilterPredicate) b;
    boolean valueMatches = predicateA.getValues().equals(predicateB.getValues());
    boolean operatorMatches = predicateA.getOperator().equals(predicateB.getOperator());
    boolean pathMatches = pathMatches(predicateA.getPath(), predicateB.getPath());
    boolean usingTemplate = false;
    if (predicateA.getValues().size() == 1) {
        String value = predicateA.getValues().get(0).toString();
        Matcher matcher = TEMPLATE_PATTERN.matcher(value);
        usingTemplate = matcher.matches();
        if (usingTemplate && pathMatches & operatorMatches) {
            String argumentName = matcher.group(1);
            arguments.put(argumentName, Argument.builder().name(argumentName).value(predicateB.getValues().size() == 1 ? predicateB.getValues().get(0) : predicateB.getValues()).build());
        }
    }
    return (operatorMatches && pathMatches && (valueMatches || usingTemplate));
}
Also used : OrFilterExpression(com.yahoo.elide.core.filter.expression.OrFilterExpression) Matcher(java.util.regex.Matcher) FilterPredicate(com.yahoo.elide.core.filter.predicates.FilterPredicate) NotFilterExpression(com.yahoo.elide.core.filter.expression.NotFilterExpression) AndFilterExpression(com.yahoo.elide.core.filter.expression.AndFilterExpression)

Example 4 with FilterPredicate

use of com.yahoo.elide.core.filter.predicates.FilterPredicate in project elide by yahoo.

the class Queryable method getFilterProjections.

default List<ColumnProjection> getFilterProjections(FilterExpression expression) {
    List<ColumnProjection> results = new ArrayList<>();
    if (expression == null) {
        return results;
    }
    Collection<FilterPredicate> predicates = expression.accept(new PredicateExtractionVisitor());
    predicates.stream().forEach((predicate -> {
        Map<String, Argument> arguments = new HashMap<>();
        predicate.getPath().lastElement().get().getArguments().forEach(argument -> arguments.put(argument.getName(), argument));
        ColumnProjection projection = getSource().getColumnProjection(predicate.getField(), arguments);
        results.add(projection);
    }));
    return results;
}
Also used : PredicateExtractionVisitor(com.yahoo.elide.core.filter.expression.PredicateExtractionVisitor) FilterPredicate(com.yahoo.elide.core.filter.predicates.FilterPredicate) Predicate(java.util.function.Predicate) Collection(java.util.Collection) Set(java.util.Set) HashMap(java.util.HashMap) Streams(com.google.common.collect.Streams) Collectors(java.util.stream.Collectors) ArrayList(java.util.ArrayList) Argument(com.yahoo.elide.core.request.Argument) ConnectionDetails(com.yahoo.elide.datastores.aggregation.queryengines.sql.ConnectionDetails) List(java.util.List) SQLDialect(com.yahoo.elide.datastores.aggregation.queryengines.sql.dialects.SQLDialect) SQLJoin(com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLJoin) Map(java.util.Map) FilterExpression(com.yahoo.elide.core.filter.expression.FilterExpression) Collections(java.util.Collections) LinkedHashSet(java.util.LinkedHashSet) ArrayList(java.util.ArrayList) PredicateExtractionVisitor(com.yahoo.elide.core.filter.expression.PredicateExtractionVisitor) FilterPredicate(com.yahoo.elide.core.filter.predicates.FilterPredicate) HashMap(java.util.HashMap) Map(java.util.Map)

Example 5 with FilterPredicate

use of com.yahoo.elide.core.filter.predicates.FilterPredicate in project elide by yahoo.

the class Queryable method extractFilterProjections.

/**
 * Converts a filter expression into a set of ColumnProjections.
 * @param query The parent query.
 * @param expression The filter expression to extract.
 * @return A set of zero or more column projections with their arguments.
 */
static Set<ColumnProjection> extractFilterProjections(Queryable query, FilterExpression expression) {
    if (expression == null) {
        return new LinkedHashSet<>();
    }
    Collection<FilterPredicate> predicates = expression.accept(new PredicateExtractionVisitor());
    Set<ColumnProjection> filterProjections = new LinkedHashSet<>();
    predicates.stream().forEach((predicate -> {
        Map<String, Argument> arguments = new HashMap<>();
        predicate.getPath().lastElement().get().getArguments().forEach(argument -> arguments.put(argument.getName(), argument));
        ColumnProjection projection = query.getSource().getColumnProjection(predicate.getField(), arguments);
        if (projection != null) {
            filterProjections.add(projection);
        }
    }));
    return filterProjections;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) PredicateExtractionVisitor(com.yahoo.elide.core.filter.expression.PredicateExtractionVisitor) FilterPredicate(com.yahoo.elide.core.filter.predicates.FilterPredicate) Predicate(java.util.function.Predicate) Collection(java.util.Collection) Set(java.util.Set) HashMap(java.util.HashMap) Streams(com.google.common.collect.Streams) Collectors(java.util.stream.Collectors) ArrayList(java.util.ArrayList) Argument(com.yahoo.elide.core.request.Argument) ConnectionDetails(com.yahoo.elide.datastores.aggregation.queryengines.sql.ConnectionDetails) List(java.util.List) SQLDialect(com.yahoo.elide.datastores.aggregation.queryengines.sql.dialects.SQLDialect) SQLJoin(com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLJoin) Map(java.util.Map) FilterExpression(com.yahoo.elide.core.filter.expression.FilterExpression) Collections(java.util.Collections) LinkedHashSet(java.util.LinkedHashSet) PredicateExtractionVisitor(com.yahoo.elide.core.filter.expression.PredicateExtractionVisitor) FilterPredicate(com.yahoo.elide.core.filter.predicates.FilterPredicate) HashMap(java.util.HashMap) Map(java.util.Map)

Aggregations

FilterPredicate (com.yahoo.elide.core.filter.predicates.FilterPredicate)101 Test (org.junit.jupiter.api.Test)78 Path (com.yahoo.elide.core.Path)63 FilterExpression (com.yahoo.elide.core.filter.expression.FilterExpression)47 AndFilterExpression (com.yahoo.elide.core.filter.expression.AndFilterExpression)46 OrFilterExpression (com.yahoo.elide.core.filter.expression.OrFilterExpression)41 SQLUnitTest (com.yahoo.elide.datastores.aggregation.framework.SQLUnitTest)33 Query (com.yahoo.elide.datastores.aggregation.query.Query)33 SQLTable (com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLTable)29 HashSet (java.util.HashSet)25 Day (com.yahoo.elide.datastores.aggregation.timegrains.Day)22 Book (example.Book)21 Date (java.util.Date)20 InPredicate (com.yahoo.elide.core.filter.predicates.InPredicate)18 EntityProjection (com.yahoo.elide.core.request.EntityProjection)16 Argument (com.yahoo.elide.core.request.Argument)15 Author (example.Author)15 Set (java.util.Set)15 GameRevenue (example.GameRevenue)14 MultivaluedHashMap (javax.ws.rs.core.MultivaluedHashMap)13