PersistentResource implements com.yahoo.elide.security.PersistentResource<T> { protected static Set<PersistentResource> filter(Class<? extends Annotation> permission, Optional<FilterExpression> filter, Set<PersistentResource> resources) { Set<PersistentResource> filteredSet = new LinkedHashSet<>(); for (PersistentResource resource : resources) { try { if (!resource.getRequestScope().getNewResources().contains(resource)) { resource.checkFieldAwarePermissions(permission); if (filter.isPresent() && !filter.get().accept(new VerifyFieldAccessFilterExpressionVisitor(resource))) { continue; } } filteredSet.add(resource); } catch (ForbiddenAccessException e) { } } if (resources instanceof SingleElementSet && resources.equals(filteredSet)) { return resources; } return filteredSet; } PersistentResource(@NonNull T obj, PersistentResource parent, String id, @NonNull RequestScope scope); @Override String toString(); static PersistentResource<T> createObject(
            PersistentResource<?> parent,
            Class<T> entityClass,
            RequestScope requestScope,
            Optional<String> uuid); @Override boolean matchesId(String checkId); @SuppressWarnings("resource") @NonNull static PersistentResource<T> loadRecord(
            Class<T> loadClass, String id, RequestScope requestScope); static Set<PersistentResource> loadRecords(
            Class<?> loadClass,
            List<String> ids,
            Optional<FilterExpression> filter,
            Optional<Sorting> sorting,
            Optional<Pagination> pagination,
            RequestScope requestScope); boolean updateAttribute(String fieldName, Object newVal); boolean updateRelation(String fieldName, Set<PersistentResource> resourceIdentifiers); boolean clearRelation(String relationName); void removeRelation(String fieldName, PersistentResource removeResource); boolean relationshipAlreadyExists(String fieldName, PersistentResource toAdd); void addRelation(String fieldName, PersistentResource newRelation); void deleteResource(); @Override String getId(); void setId(String id); boolean isIdGenerated(); @Override Optional<String> getUUID(); PersistentResource getRelation(String relation, String id); Set<PersistentResource> getRelation(String relation,
            List<String> ids,
            Optional<FilterExpression> filter,
            Optional<Sorting> sorting,
            Optional<Pagination> pagination); Set<PersistentResource> getRelationCheckedFiltered(String relationName,
            Optional<FilterExpression> filterExpression,
            Optional<Sorting> sorting,
            Optional<Pagination> pagination); RelationshipType getRelationshipType(String relation); Object getAttribute(String attr); @Override T getObject(); void setObject(T obj); @Override @JsonIgnore Class<T> getResourceClass(); @Override String getType(); @Override int hashCode(); @Override boolean equals(Object obj); ResourceLineage getLineage(); EntityDictionary getDictionary(); @Override RequestScope getRequestScope(); Resource toResource(); Resource toResourceWithSortingAndPagination(); Resource toResource(final Supplier<Map<String, Relationship>> relationshipSupplier,
                               final Supplier<Map<String, Object>> attributeSupplier); static Object getValue(Object target, String fieldName, RequestScope requestScope);  }
@Test public void testFilter() { Child child1 = newChild(1); Child child2 = newChild(-2); Child child3 = newChild(3); Child child4 = newChild(-4); { PersistentResource<Child> child1Resource = new PersistentResource<>(child1, null, "1", goodUserScope); PersistentResource<Child> child2Resource = new PersistentResource<>(child2, null, "-2", goodUserScope); PersistentResource<Child> child3Resource = new PersistentResource<>(child3, null, "3", goodUserScope); PersistentResource<Child> child4Resource = new PersistentResource<>(child4, null, "-4", goodUserScope); Set<PersistentResource> resources = Sets.newHashSet(child1Resource, child2Resource, child3Resource, child4Resource); Set<PersistentResource> results = PersistentResource.filter(ReadPermission.class, Optional.empty(), resources); assertEquals(2, results.size(), "Only a subset of the children are readable"); assertTrue(results.contains(child1Resource), "Readable children includes children with positive IDs"); assertTrue(results.contains(child3Resource), "Readable children includes children with positive IDs"); } { PersistentResource<Child> child1Resource = new PersistentResource<>(child1, null, "1", badUserScope); PersistentResource<Child> child2Resource = new PersistentResource<>(child2, null, "-2", badUserScope); PersistentResource<Child> child3Resource = new PersistentResource<>(child3, null, "3", badUserScope); PersistentResource<Child> child4Resource = new PersistentResource<>(child4, null, "-4", badUserScope); Set<PersistentResource> resources = Sets.newHashSet(child1Resource, child2Resource, child3Resource, child4Resource); Set<PersistentResource> results = PersistentResource.filter(ReadPermission.class, Optional.empty(), resources); assertEquals(0, results.size(), "No children are readable by an invalid user"); } }