use of com.yahoo.elide.core.RequestScope 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;
}
use of com.yahoo.elide.core.RequestScope in project elide by yahoo.
the class PermissionExpressionBuilder method buildAnyFieldFilterExpression.
/**
* Build an expression representing any field on an entity.
*
* @param forType Resource class
* @param requestScope requestScope
* @return Expressions
*/
public FilterExpression buildAnyFieldFilterExpression(Type<?> forType, RequestScope requestScope, Set<String> requestedFields) {
Class<? extends Annotation> annotationClass = ReadPermission.class;
ParseTree classPermissions = entityDictionary.getPermissionsForClass(forType, annotationClass);
FilterExpression entityFilter = filterExpressionFromParseTree(classPermissions, forType, requestScope);
// case where the permissions does not have ANY filterExpressionCheck
if (entityFilter == FALSE_USER_CHECK_EXPRESSION || entityFilter == NO_EVALUATION_EXPRESSION || entityFilter == TRUE_USER_CHECK_EXPRESSION) {
entityFilter = null;
}
FilterExpression allFieldsFilterExpression = entityFilter;
List<String> fields = entityDictionary.getAllExposedFields(forType).stream().filter(field -> requestedFields == null || requestedFields.contains(field)).collect(Collectors.toList());
for (String field : fields) {
ParseTree fieldPermissions = entityDictionary.getPermissionsForField(forType, field, annotationClass);
FilterExpression fieldExpression = filterExpressionFromParseTree(fieldPermissions, forType, requestScope);
if (fieldExpression == null && entityFilter == null) {
// this field will be visible across all instances
return null;
}
if (fieldExpression == null || fieldExpression == FALSE_USER_CHECK_EXPRESSION) {
// In either case this field is not useful for filtering when loading records
continue;
}
if (fieldExpression == NO_EVALUATION_EXPRESSION || fieldExpression == TRUE_USER_CHECK_EXPRESSION) {
// When the expression is TRUE_USER_CHECK_EXPRESSION all records can be loaded
return null;
}
if (allFieldsFilterExpression != null) {
allFieldsFilterExpression = new OrFilterExpression(allFieldsFilterExpression, fieldExpression);
} else {
allFieldsFilterExpression = fieldExpression;
}
}
return allFieldsFilterExpression;
}
use of com.yahoo.elide.core.RequestScope in project elide by yahoo.
the class CanPaginateVisitorTest method testNotOperationExpression.
@Test
public void testNotOperationExpression() throws Exception {
@Entity
@Include(rootLevel = false)
class Book {
@Id
private long id;
@ReadPermission(expression = "NOT In Memory Check")
private String title;
}
EntityDictionary dictionary = TestDictionary.getTestDictionary(checkMappings);
dictionary.bindEntity(Book.class);
RequestScope scope = mock(RequestScope.class);
assertFalse(CanPaginateVisitor.canPaginate(ClassType.of(Book.class), dictionary, scope, new HashSet<>()));
}
use of com.yahoo.elide.core.RequestScope in project elide by yahoo.
the class CanPaginateVisitorTest method testSparseFields.
@Test
public void testSparseFields() throws Exception {
@Entity
@Include(rootLevel = false)
@ReadPermission(expression = "In Memory Check")
class Book {
@Id
private long id;
@ReadPermission(expression = "Filter Expression Check")
private String title;
@ReadPermission(expression = "Filter Expression Check")
private Date publicationDate;
private boolean outOfPrint;
}
EntityDictionary dictionary = TestDictionary.getTestDictionary(checkMappings);
dictionary.bindEntity(Book.class);
RequestScope scope = mock(RequestScope.class);
Set<String> sparseFields = new HashSet<>();
assertFalse(CanPaginateVisitor.canPaginate(ClassType.of(Book.class), dictionary, scope, sparseFields));
sparseFields.add("title");
sparseFields.add("publicationDate");
assertTrue(CanPaginateVisitor.canPaginate(ClassType.of(Book.class), dictionary, scope, sparseFields));
sparseFields.add("outOfPrint");
assertFalse(CanPaginateVisitor.canPaginate(ClassType.of(Book.class), dictionary, scope, sparseFields));
}
use of com.yahoo.elide.core.RequestScope in project elide by yahoo.
the class CanPaginateVisitorTest method testFieldFilterPermissions.
@Test
public void testFieldFilterPermissions() throws Exception {
@Entity
@Include(rootLevel = false)
class Book {
@Id
private long id;
@ReadPermission(expression = "Filter Expression Check")
private String title;
}
EntityDictionary dictionary = TestDictionary.getTestDictionary(checkMappings);
dictionary.bindEntity(Book.class);
RequestScope scope = mock(RequestScope.class);
assertTrue(CanPaginateVisitor.canPaginate(ClassType.of(Book.class), dictionary, scope, new HashSet<>()));
}
Aggregations