Search in sources :

Example 1 with PersistentResource

use of com.yahoo.elide.core.PersistentResource 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 PersistentResource

use of com.yahoo.elide.core.PersistentResource in project elide by yahoo.

the class JsonApiTest method writeSingle.

@Test
public void writeSingle() throws JsonProcessingException {
    Parent parent = new Parent();
    Child child = new Child();
    parent.setId(123L);
    child.setId(2);
    parent.setChildren(Collections.singleton(child));
    parent.setFirstName("bob");
    child.setParents(Collections.singleton(parent));
    child.setFriends(new HashSet<>());
    RequestScope userScope = new TestRequestScope(BASE_URL, tx, user, dictionary);
    JsonApiDocument jsonApiDocument = new JsonApiDocument();
    jsonApiDocument.setData(new Data<>(new PersistentResource<>(parent, userScope.getUUIDFor(parent), userScope).toResource()));
    String expected = "{\"data\":{" + "\"type\":\"parent\"," + "\"id\":\"123\"," + "\"attributes\":{\"firstName\":\"bob\"}," + "\"relationships\":{" + "\"children\":{" + "\"links\":{\"self\":\"http://localhost:8080/json/parent/123/relationships/children\",\"related\":\"http://localhost:8080/json/parent/123/children\"}," + "\"data\":[{\"type\":\"child\",\"id\":\"2\"}]}," + "\"spouses\":{" + "\"links\":{\"self\":\"http://localhost:8080/json/parent/123/relationships/spouses\",\"related\":\"http://localhost:8080/json/parent/123/spouses\"}," + "\"data\":[]}}," + "\"links\":{\"self\":\"http://localhost:8080/json/parent/123\"}}}";
    Data<Resource> data = jsonApiDocument.getData();
    String doc = mapper.writeJsonApiDocument(jsonApiDocument);
    assertEquals(data, jsonApiDocument.getData());
    assertEquals(expected, doc);
    checkEquality(jsonApiDocument);
}
Also used : TestRequestScope(com.yahoo.elide.core.TestRequestScope) JsonApiDocument(com.yahoo.elide.jsonapi.models.JsonApiDocument) Parent(example.Parent) Resource(com.yahoo.elide.jsonapi.models.Resource) PersistentResource(com.yahoo.elide.core.PersistentResource) Child(example.Child) RequestScope(com.yahoo.elide.core.RequestScope) TestRequestScope(com.yahoo.elide.core.TestRequestScope) Test(org.junit.jupiter.api.Test)

Example 3 with PersistentResource

use of com.yahoo.elide.core.PersistentResource in project elide by yahoo.

the class JsonApiTest method writeListIncluded.

@Test
public void writeListIncluded() throws JsonProcessingException {
    Parent parent = new Parent();
    Child child = new Child();
    parent.setId(123L);
    child.setId(2);
    parent.setChildren(Collections.singleton(child));
    child.setParents(Collections.singleton(parent));
    parent.setFirstName("bob");
    child.setFriends(new HashSet<>());
    RequestScope userScope = new TestRequestScope(BASE_URL, tx, user, dictionary);
    PersistentResource<Parent> pRec = new PersistentResource<>(parent, userScope.getUUIDFor(parent), userScope);
    JsonApiDocument jsonApiDocument = new JsonApiDocument();
    jsonApiDocument.setData(new Data<>(Collections.singletonList(pRec.toResource())));
    jsonApiDocument.addIncluded(new PersistentResource<>(child, pRec, "children", userScope.getUUIDFor(child), userScope).toResource());
    // duplicate will be ignored
    jsonApiDocument.addIncluded(new PersistentResource<>(child, pRec, "children", userScope.getUUIDFor(child), userScope).toResource());
    String expected = "{\"data\":[{" + "\"type\":\"parent\"," + "\"id\":\"123\"," + "\"attributes\":{\"firstName\":\"bob\"}," + "\"relationships\":{" + "\"children\":{" + "\"links\":{\"self\":\"http://localhost:8080/json/parent/123/relationships/children\",\"related\":\"http://localhost:8080/json/parent/123/children\"}," + "\"data\":[{\"type\":\"child\",\"id\":\"2\"}]}," + "\"spouses\":{" + "\"links\":{\"self\":\"http://localhost:8080/json/parent/123/relationships/spouses\",\"related\":\"http://localhost:8080/json/parent/123/spouses\"}," + "\"data\":[]}}," + "\"links\":{\"self\":\"http://localhost:8080/json/parent/123\"}}]," + "\"included\":[{" + "\"type\":\"child\"," + "\"id\":\"2\"," + "\"attributes\":{\"name\":null}," + "\"relationships\":{" + "\"friends\":{" + "\"links\":{\"self\":\"http://localhost:8080/json/parent/123/children/2/relationships/friends\",\"related\":\"http://localhost:8080/json/parent/123/children/2/friends\"}," + "\"data\":[]}," + "\"parents\":{" + "\"links\":{\"self\":\"http://localhost:8080/json/parent/123/children/2/relationships/parents\",\"related\":\"http://localhost:8080/json/parent/123/children/2/parents\"}," + "\"data\":[{\"type\":\"parent\",\"id\":\"123\"}]}}," + "\"links\":{\"self\":\"http://localhost:8080/json/parent/123/children/2\"}}]" + "}";
    Data<Resource> data = jsonApiDocument.getData();
    String doc = mapper.writeJsonApiDocument(jsonApiDocument);
    assertEquals(data, jsonApiDocument.getData());
    assertEquals(expected, doc);
    checkEquality(jsonApiDocument);
}
Also used : TestRequestScope(com.yahoo.elide.core.TestRequestScope) PersistentResource(com.yahoo.elide.core.PersistentResource) JsonApiDocument(com.yahoo.elide.jsonapi.models.JsonApiDocument) Parent(example.Parent) Resource(com.yahoo.elide.jsonapi.models.Resource) PersistentResource(com.yahoo.elide.core.PersistentResource) Child(example.Child) RequestScope(com.yahoo.elide.core.RequestScope) TestRequestScope(com.yahoo.elide.core.TestRequestScope) Test(org.junit.jupiter.api.Test)

Example 4 with PersistentResource

use of com.yahoo.elide.core.PersistentResource in project elide by yahoo.

the class LifeCycleTest method testPreFlushLifecycleHookException.

@Test
public void testPreFlushLifecycleHookException() {
    DataStoreTransaction tx = mock(DataStoreTransaction.class);
    FieldTestModel testModel = mock(FieldTestModel.class);
    doThrow(IllegalStateException.class).when(testModel).attributeCallback(eq(UPDATE), eq(PREFLUSH), any(ChangeSpec.class));
    RequestScope scope = buildRequestScope(dictionary, tx);
    PersistentResource resource = new PersistentResource(testModel, "1", scope);
    resource.updateAttribute("field", "New value");
    scope.runQueuedPreSecurityTriggers();
    assertThrows(IllegalStateException.class, () -> scope.runQueuedPreFlushTriggers());
}
Also used : PersistentResource(com.yahoo.elide.core.PersistentResource) ChangeSpec(com.yahoo.elide.core.security.ChangeSpec) DataStoreTransaction(com.yahoo.elide.core.datastore.DataStoreTransaction) RequestScope(com.yahoo.elide.core.RequestScope) Test(org.junit.jupiter.api.Test)

Example 5 with PersistentResource

use of com.yahoo.elide.core.PersistentResource in project elide by yahoo.

the class LifeCycleTest method testAddToCollectionTrigger.

@Test
public void testAddToCollectionTrigger() {
    PropertyTestModel mockModel = mock(PropertyTestModel.class);
    DataStoreTransaction tx = mock(DataStoreTransaction.class);
    RequestScope scope = buildRequestScope(dictionary, tx);
    when(tx.createNewObject(ClassType.of(PropertyTestModel.class), scope)).thenReturn(mockModel);
    PropertyTestModel modelToAdd1 = mock(PropertyTestModel.class);
    PropertyTestModel modelToAdd2 = mock(PropertyTestModel.class);
    // First we test adding to a newly created object.
    PersistentResource resource = PersistentResource.createObject(ClassType.of(PropertyTestModel.class), scope, Optional.of("1"));
    PersistentResource resourceToAdd1 = new PersistentResource(modelToAdd1, scope.getUUIDFor(mockModel), scope);
    PersistentResource resourceToAdd2 = new PersistentResource(modelToAdd2, scope.getUUIDFor(mockModel), scope);
    resource.updateRelation("models", new HashSet<>(Arrays.asList(resourceToAdd1, resourceToAdd2)));
    scope.runQueuedPreSecurityTriggers();
    scope.runQueuedPreCommitTriggers();
    scope.runQueuedPostCommitTriggers();
    verify(mockModel, never()).relationCallback(eq(UPDATE), any(), any());
    verify(mockModel, times(1)).relationCallback(eq(CREATE), eq(POSTCOMMIT), notNull());
    // Build another resource, scope & reset the mock to do a pure update (no create):
    scope = buildRequestScope(dictionary, tx);
    resource = new PersistentResource(mockModel, scope.getUUIDFor(mockModel), scope);
    reset(mockModel);
    resource.updateRelation("models", new HashSet<>(Arrays.asList(resourceToAdd1, resourceToAdd2)));
    scope.runQueuedPreSecurityTriggers();
    scope.runQueuedPreCommitTriggers();
    scope.runQueuedPostCommitTriggers();
    verify(mockModel, never()).relationCallback(eq(CREATE), any(), any());
    verify(mockModel, times(1)).relationCallback(eq(UPDATE), eq(POSTCOMMIT), notNull());
}
Also used : PersistentResource(com.yahoo.elide.core.PersistentResource) DataStoreTransaction(com.yahoo.elide.core.datastore.DataStoreTransaction) RequestScope(com.yahoo.elide.core.RequestScope) Test(org.junit.jupiter.api.Test)

Aggregations

PersistentResource (com.yahoo.elide.core.PersistentResource)100 Test (org.junit.jupiter.api.Test)71 RequestScope (com.yahoo.elide.core.RequestScope)60 ReadPermission (com.yahoo.elide.annotation.ReadPermission)18 UpdatePermission (com.yahoo.elide.annotation.UpdatePermission)18 DataStoreTransaction (com.yahoo.elide.core.datastore.DataStoreTransaction)17 Include (com.yahoo.elide.annotation.Include)16 Entity (javax.persistence.Entity)16 Resource (com.yahoo.elide.jsonapi.models.Resource)13 AndFilterExpression (com.yahoo.elide.core.filter.expression.AndFilterExpression)10 NotFilterExpression (com.yahoo.elide.core.filter.expression.NotFilterExpression)10 OrFilterExpression (com.yahoo.elide.core.filter.expression.OrFilterExpression)10 PermissionExecutor (com.yahoo.elide.core.security.PermissionExecutor)10 JsonApiDocument (com.yahoo.elide.jsonapi.models.JsonApiDocument)10 Book (example.Book)10 LinkedHashSet (java.util.LinkedHashSet)9 EntityDictionary (com.yahoo.elide.core.dictionary.EntityDictionary)8 BadRequestException (com.yahoo.elide.core.exceptions.BadRequestException)8 FilterExpression (com.yahoo.elide.core.filter.expression.FilterExpression)8 RSQLFilterDialect (com.yahoo.elide.core.filter.dialect.RSQLFilterDialect)7