use of com.yahoo.elide.core.PersistentResource in project elide by yahoo.
the class VerifyFieldAccessFilterExpressionVisitorTest method testUserChecksDeferred.
@Test
public void testUserChecksDeferred() throws Exception {
RSQLFilterDialect dialect = RSQLFilterDialect.builder().dictionary(scope.getDictionary()).build();
FilterExpression expression = dialect.parseFilterExpression("authors.homeAddress==main", ClassType.of(Book.class), true);
Book book = new Book();
Author author = new Author();
book.setAuthors(Collections.singleton(author));
author.setBooks(Collections.singleton(book));
PersistentResource<Book> resource = new PersistentResource<>(book, "", scope);
PersistentResource<Author> resourceAuthor = new PersistentResource<>(author, "", scope);
PermissionExecutor permissionExecutor = scope.getPermissionExecutor();
DataStoreTransaction tx = scope.getTransaction();
when(permissionExecutor.checkUserPermissions(ClassType.of(Book.class), ReadPermission.class, AUTHORS)).thenReturn(ExpressionResult.PASS);
when(permissionExecutor.checkSpecificFieldPermissionsDeferred(resource, null, ReadPermission.class, AUTHORS)).thenReturn(ExpressionResult.PASS);
when(permissionExecutor.getReadPermissionFilter(ClassType.of(Author.class), null)).thenReturn(Optional.empty());
when(permissionExecutor.checkUserPermissions(ClassType.of(Author.class), ReadPermission.class, HOME)).thenReturn(ExpressionResult.DEFERRED);
when(permissionExecutor.checkSpecificFieldPermissions(resourceAuthor, null, ReadPermission.class, HOME)).thenThrow(ForbiddenAccessException.class);
when(tx.getToManyRelation(eq(tx), eq(book), any(), eq(scope))).thenReturn(new DataStoreIterableBuilder(book.getAuthors()).build());
VerifyFieldAccessFilterExpressionVisitor visitor = new VerifyFieldAccessFilterExpressionVisitor(resource);
// restricted HOME field
assertFalse(expression.accept(visitor));
verify(permissionExecutor, times(1)).evaluateFilterJoinUserChecks(any(), any());
verify(permissionExecutor, times(1)).checkUserPermissions(ClassType.of(Book.class), ReadPermission.class, AUTHORS);
verify(permissionExecutor, times(1)).getReadPermissionFilter(ClassType.of(Author.class), new HashSet<>());
verify(permissionExecutor, times(1)).checkUserPermissions(ClassType.of(Author.class), ReadPermission.class, HOME);
verify(permissionExecutor, times(1)).checkSpecificFieldPermissions(resourceAuthor, null, ReadPermission.class, HOME);
verify(permissionExecutor, times(2)).checkUserPermissions(any(), any(), isA(String.class));
verify(permissionExecutor, times(1)).handleFilterJoinReject(any(), any(), any());
verify(tx, times(1)).getToManyRelation(eq(tx), eq(book), any(), eq(scope));
}
use of com.yahoo.elide.core.PersistentResource in project elide by yahoo.
the class VerifyFieldAccessFilterExpressionVisitorTest method testShortCircuitRejectDeferThenFail.
@Test
public void testShortCircuitRejectDeferThenFail() throws Exception {
RSQLFilterDialect dialect = RSQLFilterDialect.builder().dictionary(scope.getDictionary()).build();
FilterExpression expression = dialect.parseFilterExpression("authors.homeAddress==main", ClassType.of(Book.class), true);
Book book = new Book();
Author author = new Author();
book.setAuthors(Collections.singleton(author));
author.setBooks(Collections.singleton(book));
PersistentResource<Book> resource = new PersistentResource<>(book, "", scope);
PermissionExecutor permissionExecutor = scope.getPermissionExecutor();
DataStoreTransaction tx = scope.getTransaction();
when(permissionExecutor.checkUserPermissions(ClassType.of(Book.class), ReadPermission.class, AUTHORS)).thenReturn(ExpressionResult.DEFERRED);
when(permissionExecutor.checkUserPermissions(ClassType.of(Author.class), ReadPermission.class, HOME)).thenThrow(ForbiddenAccessException.class);
VerifyFieldAccessFilterExpressionVisitor visitor = new VerifyFieldAccessFilterExpressionVisitor(resource);
// restricted HOME field
assertFalse(expression.accept(visitor));
verify(permissionExecutor, times(1)).evaluateFilterJoinUserChecks(any(), any());
verify(permissionExecutor, times(1)).checkUserPermissions(ClassType.of(Book.class), ReadPermission.class, AUTHORS);
verify(permissionExecutor, never()).getReadPermissionFilter(ClassType.of(Author.class), null);
verify(permissionExecutor, times(1)).checkUserPermissions(ClassType.of(Author.class), ReadPermission.class, HOME);
verify(permissionExecutor, never()).checkSpecificFieldPermissions(any(), any(), any(), any());
verify(permissionExecutor, never()).checkSpecificFieldPermissionsDeferred(any(), any(), any(), any());
verify(permissionExecutor, times(2)).checkUserPermissions(any(), any(), isA(String.class));
verify(permissionExecutor, times(1)).handleFilterJoinReject(any(), any(), any());
verify(tx, never()).getToManyRelation(any(), any(), any(), any());
}
use of com.yahoo.elide.core.PersistentResource in project elide by yahoo.
the class VerifyFieldAccessFilterExpressionVisitorTest method testShortCircuitPass.
@Test
public void testShortCircuitPass() throws Exception {
RSQLFilterDialect dialect = RSQLFilterDialect.builder().dictionary(scope.getDictionary()).build();
FilterExpression expression = dialect.parseFilterExpression("authors.name==foo", ClassType.of(Book.class), true);
Book book = new Book();
PersistentResource<Book> resource = new PersistentResource<>(book, "", scope);
PermissionExecutor permissionExecutor = scope.getPermissionExecutor();
DataStoreTransaction tx = scope.getTransaction();
when(permissionExecutor.checkUserPermissions(ClassType.of(Book.class), ReadPermission.class, AUTHORS)).thenReturn(ExpressionResult.PASS);
when(permissionExecutor.checkUserPermissions(ClassType.of(Author.class), ReadPermission.class, NAME)).thenReturn(ExpressionResult.PASS);
VerifyFieldAccessFilterExpressionVisitor visitor = new VerifyFieldAccessFilterExpressionVisitor(resource);
// restricted HOME field
assertTrue(expression.accept(visitor));
verify(permissionExecutor, times(1)).evaluateFilterJoinUserChecks(any(), any());
verify(permissionExecutor, times(1)).checkUserPermissions(ClassType.of(Book.class), ReadPermission.class, AUTHORS);
verify(permissionExecutor, times(1)).checkUserPermissions(ClassType.of(Author.class), ReadPermission.class, NAME);
verify(permissionExecutor, never()).checkSpecificFieldPermissions(resource, null, ReadPermission.class, GENRE);
verify(permissionExecutor, times(2)).checkUserPermissions(any(), any(), isA(String.class));
verify(permissionExecutor, never()).handleFilterJoinReject(any(), any(), any());
verify(tx, never()).getToManyRelation(any(), any(), any(), any());
}
use of com.yahoo.elide.core.PersistentResource in project elide by yahoo.
the class PersistentResourceFetcher method removeObjects.
/**
* Removes a relationship, or deletes a root level resource.
* @param context Environment encapsulating graphQL's request environment
* @return set of removed {@link PersistentResource} object(s)
*/
private ConnectionContainer removeObjects(Environment context) {
/* sanity check for id and data argument w REPLACE */
if (context.data.isPresent()) {
throw new BadRequestException("REPLACE must not include data argument");
}
if (!context.ids.isPresent()) {
throw new BadRequestException("REPLACE must include ids argument");
}
ConnectionContainer connection = (ConnectionContainer) fetchObjects(context);
Set<PersistentResource> toRemove = connection.getPersistentResources();
if (!context.isRoot()) {
/* has parent */
toRemove.forEach(item -> context.parentResource.removeRelation(context.field.getName(), item));
} else {
/* is root */
toRemove.forEach(PersistentResource::deleteResource);
}
return new ConnectionContainer(Collections.emptySet(), Optional.empty(), connection.getTypeName());
}
use of com.yahoo.elide.core.PersistentResource in project elide by yahoo.
the class PersistentResourceFetcher method fetchObject.
/**
* Fetches a root-level entity.
* @param requestScope Request scope
* @param projection constructed entityProjection for a class
* @param ids List of ids (can be NULL)
* @return {@link PersistentResource} object(s)
*/
public static ConnectionContainer fetchObject(RequestScope requestScope, EntityProjection projection, Optional<List<String>> ids) {
EntityDictionary dictionary = requestScope.getDictionary();
String typeName = dictionary.getJsonAliasFor(projection.getType());
/* fetching a collection */
Observable<PersistentResource> records = ids.map((idList) -> {
/* handle empty list of ids */
if (idList.isEmpty()) {
throw new BadRequestException("Empty list passed to ids");
}
return PersistentResource.loadRecords(projection, idList, requestScope);
}).orElseGet(() -> PersistentResource.loadRecords(projection, new ArrayList<>(), requestScope));
return new ConnectionContainer(records.toList(LinkedHashSet::new).blockingGet(), Optional.ofNullable(projection.getPagination()), typeName);
}
Aggregations