Search in sources :

Example 1 with ExpressionResult

use of com.yahoo.elide.core.security.permissions.ExpressionResult 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 2 with ExpressionResult

use of com.yahoo.elide.core.security.permissions.ExpressionResult in project elide by yahoo.

the class AbstractPermissionExecutor method executeExpressions.

/**
 * Execute expressions.
 *
 * @param expression The expression to evaluate.
 * @param annotationClass The permission associated with the expression.
 * @param mode The evaluation mode of the expression.
 */
protected ExpressionResult executeExpressions(final Expression expression, final Class<? extends Annotation> annotationClass, Expression.EvaluationMode mode) {
    ExpressionResult result = expression.evaluate(mode);
    // Record the check
    if (log.isTraceEnabled()) {
        String checkKey = expression.toString();
        Long checkOccurrences = checkStats.getOrDefault(checkKey, 0L) + 1;
        checkStats.put(checkKey, checkOccurrences);
    }
    if (result == DEFERRED) {
        /*
             * Checking user checks only are an optimization step.  We don't need to defer these checks because
             * INLINE_ONLY checks will be evaluated later.  Also, the user checks don't have
             * the correct context to evaluate as COMMIT checks later.
             */
        if (mode == Expression.EvaluationMode.USER_CHECKS_ONLY) {
            return DEFERRED;
        }
        if (isInlineOnlyCheck(annotationClass)) {
            // Force evaluation of checks that can only be executed inline.
            result = expression.evaluate(Expression.EvaluationMode.ALL_CHECKS);
            if (result == FAIL) {
                ForbiddenAccessException e = new ForbiddenAccessException(annotationClass, expression, Expression.EvaluationMode.ALL_CHECKS);
                if (log.isTraceEnabled()) {
                    log.trace("{}", e.getLoggedMessage());
                }
                throw e;
            }
            return result;
        }
        commitCheckQueue.add(new AbstractPermissionExecutor.QueuedCheck(expression, annotationClass));
        return DEFERRED;
    }
    if (result == FAIL) {
        ForbiddenAccessException e = new ForbiddenAccessException(annotationClass, expression, mode);
        if (log.isTraceEnabled()) {
            log.trace("{}", e.getLoggedMessage());
        }
        throw e;
    }
    return result;
}
Also used : ExpressionResult(com.yahoo.elide.core.security.permissions.ExpressionResult) ForbiddenAccessException(com.yahoo.elide.core.exceptions.ForbiddenAccessException)

Example 3 with ExpressionResult

use of com.yahoo.elide.core.security.permissions.ExpressionResult in project elide by yahoo.

the class ActivePermissionExecutor method checkPermissions.

/**
 * First attempts to check user permissions (by looking in the cache and if not present by executing user
 * permissions).  If user permissions don't short circuit the check, run the provided expression executor.
 *
 * @param <A> type parameter
 * @param resourceClass Resource class
 * @param annotationClass Annotation class
 * @param fields Set of all field names that is being accessed
 * @param expressionSupplier Builds a permission expression.
 * @param expressionExecutor Evaluates the expression (post user check evaluation)
 */
protected <A extends Annotation> ExpressionResult checkPermissions(Type<?> resourceClass, Class<A> annotationClass, Set<String> fields, Supplier<Expression> expressionSupplier, Optional<Function<Expression, ExpressionResult>> expressionExecutor) {
    // If the user check has already been evaluated before, return the result directly and save the building cost
    ImmutableSet<String> immutableFields = fields == null ? null : ImmutableSet.copyOf(fields);
    ExpressionResult expressionResult = userPermissionCheckCache.get(Triple.of(annotationClass, resourceClass, immutableFields));
    if (expressionResult == PASS) {
        return expressionResult;
    }
    Expression expression = expressionSupplier.get();
    if (expressionResult == null) {
        expressionResult = executeExpressions(expression, annotationClass, Expression.EvaluationMode.USER_CHECKS_ONLY);
        userPermissionCheckCache.put(Triple.of(annotationClass, resourceClass, immutableFields), expressionResult);
        if (expressionResult == PASS) {
            return expressionResult;
        }
    }
    return expressionExecutor.map(executor -> executor.apply(expression)).orElse(expressionResult);
}
Also used : PASS(com.yahoo.elide.core.security.permissions.ExpressionResult.PASS) Getter(lombok.Getter) HashMap(java.util.HashMap) DEFERRED(com.yahoo.elide.core.security.permissions.ExpressionResult.DEFERRED) PermissionExecutor(com.yahoo.elide.core.security.PermissionExecutor) Function(java.util.function.Function) Supplier(java.util.function.Supplier) UpdatePermission(com.yahoo.elide.annotation.UpdatePermission) DeletePermission(com.yahoo.elide.annotation.DeletePermission) PermissionExpressionBuilder(com.yahoo.elide.core.security.permissions.PermissionExpressionBuilder) Map(java.util.Map) PersistentResource(com.yahoo.elide.core.PersistentResource) FilterExpression(com.yahoo.elide.core.filter.expression.FilterExpression) Triple(org.apache.commons.lang3.tuple.Triple) RequestScope(com.yahoo.elide.core.RequestScope) ChangeSpec(com.yahoo.elide.core.security.ChangeSpec) ImmutableSet(com.google.common.collect.ImmutableSet) Set(java.util.Set) LinkedBlockingQueue(java.util.concurrent.LinkedBlockingQueue) Expression(com.yahoo.elide.core.security.permissions.expressions.Expression) ForbiddenAccessException(com.yahoo.elide.core.exceptions.ForbiddenAccessException) ExpressionResult(com.yahoo.elide.core.security.permissions.ExpressionResult) Slf4j(lombok.extern.slf4j.Slf4j) ReadPermission(com.yahoo.elide.annotation.ReadPermission) ExpressionResultCache(com.yahoo.elide.core.security.permissions.ExpressionResultCache) CreatePermission(com.yahoo.elide.annotation.CreatePermission) Type(com.yahoo.elide.core.type.Type) Annotation(java.lang.annotation.Annotation) Optional(java.util.Optional) Queue(java.util.Queue) AllArgsConstructor(lombok.AllArgsConstructor) Collections(java.util.Collections) FAIL(com.yahoo.elide.core.security.permissions.ExpressionResult.FAIL) NonTransferable(com.yahoo.elide.annotation.NonTransferable) ExpressionResult(com.yahoo.elide.core.security.permissions.ExpressionResult) FilterExpression(com.yahoo.elide.core.filter.expression.FilterExpression) Expression(com.yahoo.elide.core.security.permissions.expressions.Expression)

Example 4 with ExpressionResult

use of com.yahoo.elide.core.security.permissions.ExpressionResult in project elide by yahoo.

the class ActivePermissionExecutor method executeCommitChecks.

/**
 * Execute commmit checks.
 */
@Override
public void executeCommitChecks() {
    commitCheckQueue.forEach((expr) -> {
        Expression expression = expr.getExpression();
        ExpressionResult result = expression.evaluate(Expression.EvaluationMode.ALL_CHECKS);
        if (result == FAIL) {
            ForbiddenAccessException e = new ForbiddenAccessException(expr.getAnnotationClass(), expression, Expression.EvaluationMode.ALL_CHECKS);
            if (log.isTraceEnabled()) {
                log.trace("{}", e.getLoggedMessage());
            }
            throw e;
        }
    });
    commitCheckQueue.clear();
}
Also used : FilterExpression(com.yahoo.elide.core.filter.expression.FilterExpression) Expression(com.yahoo.elide.core.security.permissions.expressions.Expression) ExpressionResult(com.yahoo.elide.core.security.permissions.ExpressionResult) ForbiddenAccessException(com.yahoo.elide.core.exceptions.ForbiddenAccessException)

Example 5 with ExpressionResult

use of com.yahoo.elide.core.security.permissions.ExpressionResult in project elide by yahoo.

the class PermissionExecutorTest method testUserCheckOnFieldSuccess.

@Test
public void testUserCheckOnFieldSuccess() {
    OpenBean openBean = new OpenBean();
    openBean.id = 1L;
    PersistentResource resource = newResource(OpenBean.class, false);
    RequestScope requestScope = resource.getRequestScope();
    ExpressionResult result = requestScope.getPermissionExecutor().checkUserPermissions(ClassType.of(OpenBean.class), ReadPermission.class, "open");
    assertEquals(ExpressionResult.PASS, result);
}
Also used : PersistentResource(com.yahoo.elide.core.PersistentResource) ExpressionResult(com.yahoo.elide.core.security.permissions.ExpressionResult) RequestScope(com.yahoo.elide.core.RequestScope) Test(org.junit.jupiter.api.Test)

Aggregations

ExpressionResult (com.yahoo.elide.core.security.permissions.ExpressionResult)12 ForbiddenAccessException (com.yahoo.elide.core.exceptions.ForbiddenAccessException)8 RequestScope (com.yahoo.elide.core.RequestScope)5 ReadPermission (com.yahoo.elide.annotation.ReadPermission)4 PersistentResource (com.yahoo.elide.core.PersistentResource)4 PermissionExecutor (com.yahoo.elide.core.security.PermissionExecutor)4 Expression (com.yahoo.elide.core.security.permissions.expressions.Expression)4 FilterExpression (com.yahoo.elide.core.filter.expression.FilterExpression)3 Set (java.util.Set)3 ImmutableSet (com.google.common.collect.ImmutableSet)2 DeletePermission (com.yahoo.elide.annotation.DeletePermission)2 PathElement (com.yahoo.elide.core.Path.PathElement)2 DEFERRED (com.yahoo.elide.core.security.permissions.ExpressionResult.DEFERRED)2 FAIL (com.yahoo.elide.core.security.permissions.ExpressionResult.FAIL)2 PASS (com.yahoo.elide.core.security.permissions.ExpressionResult.PASS)2 ExpressionResultCache (com.yahoo.elide.core.security.permissions.ExpressionResultCache)2 PermissionExpressionBuilder (com.yahoo.elide.core.security.permissions.PermissionExpressionBuilder)2 Type (com.yahoo.elide.core.type.Type)2 Annotation (java.lang.annotation.Annotation)2 Collections (java.util.Collections)2