PostFilter Support for Streams
Users can return a Stream from a @PostFilter-annotated method. Fixes: gh-3743
This commit is contained in:
parent
e1c7dd6480
commit
92e68a589a
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -20,6 +20,7 @@ import java.util.ArrayList;
|
|||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.*;
|
||||
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.apache.commons.logging.Log;
|
||||
|
@ -86,8 +87,8 @@ public class DefaultMethodSecurityExpressionHandler extends
|
|||
}
|
||||
|
||||
/**
|
||||
* Filters the {@code filterTarget} object (which must be either a collection or an
|
||||
* array), by evaluating the supplied expression.
|
||||
* Filters the {@code filterTarget} object (which must be either a collection, array,
|
||||
* or stream), by evaluating the supplied expression.
|
||||
* <p>
|
||||
* If a {@code Collection} is used, the original instance will be modified to contain
|
||||
* the elements for which the permission expression evaluates to {@code true}. For an
|
||||
|
@ -172,8 +173,27 @@ public class DefaultMethodSecurityExpressionHandler extends
|
|||
return filtered;
|
||||
}
|
||||
|
||||
if (filterTarget instanceof Stream) {
|
||||
final Stream<?> original = (Stream<?>) filterTarget;
|
||||
if (debug) {
|
||||
logger.debug("Filtering stream with " + original.count() + " elements");
|
||||
}
|
||||
|
||||
Stream<?> filtered = original.filter(filterObject -> {
|
||||
rootObject.setFilterObject(filterObject);
|
||||
return ExpressionUtils.evaluateAsBoolean(filterExpression, ctx);
|
||||
})
|
||||
.onClose(original::close);
|
||||
|
||||
if (debug) {
|
||||
logger.debug("Retaining elements: " + filtered.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
return filtered;
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(
|
||||
"Filter target must be a collection or array type, but was "
|
||||
"Filter target must be a collection, array, or stream type, but was "
|
||||
+ filterTarget);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -19,6 +19,7 @@ import static org.mockito.Mockito.verify;
|
|||
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
@ -30,6 +31,9 @@ import org.springframework.security.authentication.AuthenticationTrustResolver;
|
|||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.*;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class DefaultMethodSecurityExpressionHandlerTests {
|
||||
private DefaultMethodSecurityExpressionHandler handler;
|
||||
|
@ -68,4 +72,22 @@ public class DefaultMethodSecurityExpressionHandlerTests {
|
|||
|
||||
verify(trustResolver).isAnonymous(authentication);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testFilteringStream() {
|
||||
final Stream<String> stream = Stream.of("1", "2", "3");
|
||||
|
||||
Expression expression = handler.getExpressionParser().parseExpression("filterObject ne '2'");
|
||||
|
||||
EvaluationContext context = handler.createEvaluationContext(authentication,
|
||||
methodInvocation);
|
||||
|
||||
Object filtered = handler.filter(stream, expression, context);
|
||||
|
||||
Assert.assertTrue("response was wrong type", Stream.class.isAssignableFrom(filtered.getClass()));
|
||||
List<String> list = ((Stream<String>) filtered).collect(Collectors.toList());
|
||||
Assert.assertEquals(2, list.size());
|
||||
Assert.assertFalse("contains filtered element", list.contains("2"));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue