use of com.yahoo.elide.core.security.permissions.expressions.Expression in project elide by yahoo.
the class PermissionExpressionNormalizationVisitor method visitAndExpression.
@Override
public Expression visitAndExpression(AndExpression andExpression) {
Expression left = andExpression.getLeft();
Expression right = andExpression.getRight();
return new AndExpression(left.accept(this), right.accept(this));
}
use of com.yahoo.elide.core.security.permissions.expressions.Expression in project elide by yahoo.
the class PermissionExpressionVisitor method visitAND.
@Override
public Expression visitAND(ExpressionParser.ANDContext ctx) {
Expression left = visit(ctx.left);
Expression right = visit(ctx.right);
return new AndExpression(left, right);
}
use of com.yahoo.elide.core.security.permissions.expressions.Expression in project elide by yahoo.
the class PermissionExpressionBuilder method buildUserCheckEntityAndAnyFieldExpression.
/**
* Build an expression that strictly evaluates UserCheck's and ignores other checks for an entity.
* expression = (entityRule AND (field1Rule OR field2Rule ... OR fieldNRule))
* <p>
* NOTE: This method returns _NO_ commit checks.
*
* @param resourceClass Resource class
* @param annotationClass Annotation class
* @param scope Request scope
* @param <A> type parameter
* @return User check expression to evaluate
*/
public <A extends Annotation> Expression buildUserCheckEntityAndAnyFieldExpression(final Type<?> resourceClass, final Class<A> annotationClass, Set<String> requestedFields, final RequestScope scope) {
final Function<Check, Expression> leafBuilderFn = (check) -> new CheckExpression(check, null, scope, null, cache);
ParseTree classPermissions = entityDictionary.getPermissionsForClass(resourceClass, annotationClass);
Expression entityExpression = normalizedExpressionFromParseTree(classPermissions, leafBuilderFn);
Expression anyFieldExpression = buildAnyFieldOnlyExpression(new PermissionCondition(annotationClass, resourceClass), leafBuilderFn, requestedFields);
if (entityExpression == null) {
return anyFieldExpression;
}
return new AndExpression(entityExpression, anyFieldExpression);
}
use of com.yahoo.elide.core.security.permissions.expressions.Expression in project elide by yahoo.
the class PermissionExpressionBuilder method buildAnyFieldOnlyExpression.
/**
* Builds disjunction of permission expression of all requested fields.
* If the field permission is null, then return default SUCCESSFUL_EXPRESSION.
* expression = (field1Rule OR field2Rule ... OR fieldNRule)
* @param condition The condition which triggered this permission expression check
* @param checkFn check function
* @param requestedFields The list of requested fields
* @return Expression
*/
private Expression buildAnyFieldOnlyExpression(final PermissionCondition condition, final Function<Check, Expression> checkFn, final Set<String> requestedFields) {
Type<?> resourceClass = condition.getEntityClass();
Class<? extends Annotation> annotationClass = condition.getPermission();
OrExpression allFieldsExpression = new OrExpression(FAILURE, null);
List<String> fields = entityDictionary.getAllExposedFields(resourceClass);
boolean fieldExpressionUsed = false;
for (String field : fields) {
if (requestedFields != null && !requestedFields.contains(field)) {
continue;
}
ParseTree fieldPermissions = entityDictionary.getPermissionsForField(resourceClass, field, annotationClass);
Expression fieldExpression = normalizedExpressionFromParseTree(fieldPermissions, checkFn);
if (fieldExpression == null) {
return SUCCESSFUL_EXPRESSION;
}
fieldExpressionUsed = true;
allFieldsExpression = new OrExpression(allFieldsExpression, fieldExpression);
}
if (!fieldExpressionUsed) {
return SUCCESSFUL_EXPRESSION;
}
return new AnyFieldExpression(condition, allFieldsExpression);
}
use of com.yahoo.elide.core.security.permissions.expressions.Expression in project elide by yahoo.
the class AbstractPermissionExecutor 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);
}
Aggregations