forked from quarkusio/quarkus
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
RESTEasy Reactive - prevent repeating of standard security checks
fixes: quarkusio#26536
- Loading branch information
1 parent
4e046f5
commit a5c9818
Showing
13 changed files
with
450 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
36 changes: 36 additions & 0 deletions
36
...ment/src/main/java/io/quarkus/arc/deployment/MethodInterceptorBindingFilterBuildItem.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package io.quarkus.arc.deployment; | ||
|
||
import java.util.Objects; | ||
import java.util.function.Predicate; | ||
|
||
import org.jboss.jandex.MethodInfo; | ||
|
||
import io.quarkus.arc.processor.InterceptorInfo; | ||
import io.quarkus.builder.item.MultiBuildItem; | ||
|
||
/** | ||
* Makes it possible to break binding between interceptors and concrete method. An interceptor won't | ||
* intercept the {@code interceptedMethod} anymore if {@code shouldRemoveBinding} is true, but the rest of interceptors | ||
* bindings are honoured. | ||
* | ||
* Only a single filter (build item) per method is supported, if there are multiple filters registered for the method, | ||
* the last one is used. | ||
*/ | ||
public final class MethodInterceptorBindingFilterBuildItem extends MultiBuildItem { | ||
|
||
/** | ||
* If evaluated as true, {@code interceptedMethod} won't be intercepted by the interceptor | ||
*/ | ||
final Predicate<InterceptorInfo> shouldRemoveBinding; | ||
|
||
/** | ||
* Intercepted method, only non-static methods are supported. | ||
*/ | ||
final MethodInfo interceptedMethod; | ||
|
||
public MethodInterceptorBindingFilterBuildItem(Predicate<InterceptorInfo> shouldRemoveBinding, | ||
MethodInfo interceptedMethod) { | ||
this.shouldRemoveBinding = Objects.requireNonNull(shouldRemoveBinding); | ||
this.interceptedMethod = Objects.requireNonNull(interceptedMethod); | ||
} | ||
} |
124 changes: 124 additions & 0 deletions
124
...ent/src/test/java/io/quarkus/arc/test/interceptor/MethodInterceptorBindingFilterTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
package io.quarkus.arc.test.interceptor; | ||
|
||
import static java.lang.annotation.ElementType.METHOD; | ||
import static java.lang.annotation.ElementType.TYPE; | ||
import static java.lang.annotation.RetentionPolicy.RUNTIME; | ||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
|
||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.Target; | ||
import java.util.List; | ||
import java.util.function.Predicate; | ||
|
||
import javax.annotation.Priority; | ||
import javax.inject.Inject; | ||
import javax.inject.Singleton; | ||
import javax.interceptor.AroundInvoke; | ||
import javax.interceptor.Interceptor; | ||
import javax.interceptor.InvocationContext; | ||
|
||
import org.jboss.jandex.DotName; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.api.extension.RegisterExtension; | ||
|
||
import io.quarkus.arc.deployment.BeanArchiveIndexBuildItem; | ||
import io.quarkus.arc.deployment.InterceptorBindingRegistrarBuildItem; | ||
import io.quarkus.arc.deployment.MethodInterceptorBindingFilterBuildItem; | ||
import io.quarkus.arc.processor.InterceptorBindingRegistrar; | ||
import io.quarkus.arc.processor.InterceptorInfo; | ||
import io.quarkus.builder.BuildContext; | ||
import io.quarkus.builder.BuildStep; | ||
import io.quarkus.test.QuarkusUnitTest; | ||
|
||
public class MethodInterceptorBindingFilterTest { | ||
|
||
@RegisterExtension | ||
static final QuarkusUnitTest config = new QuarkusUnitTest() | ||
.withApplicationRoot((jar) -> jar | ||
.addClasses(NotAnInterceptorBinding.class, PingPongBean.class, PingInterceptor.class, | ||
PungInterceptor.class)) | ||
.addBuildChainCustomizer(b -> { | ||
b.addBuildStep(new BuildStep() { | ||
@Override | ||
public void execute(BuildContext context) { | ||
context.produce(new InterceptorBindingRegistrarBuildItem(new InterceptorBindingRegistrar() { | ||
@Override | ||
public List<InterceptorBinding> getAdditionalBindings() { | ||
return List.of(InterceptorBinding.of(NotAnInterceptorBinding.class)); | ||
} | ||
})); | ||
} | ||
}).produces(InterceptorBindingRegistrarBuildItem.class).build(); | ||
}) | ||
.addBuildChainCustomizer(b -> { | ||
b.addBuildStep(new BuildStep() { | ||
@Override | ||
public void execute(BuildContext context) { | ||
var pingMethodInfo = context | ||
.consume(BeanArchiveIndexBuildItem.class) | ||
.getIndex() | ||
.getClassByName(DotName.createSimple(PingPongBean.class.getName())) | ||
.methods() | ||
.stream() | ||
.filter(mi -> mi.name().contains("ping")) | ||
.findFirst() | ||
.orElseThrow(); | ||
Predicate<InterceptorInfo> removePungInterceptorBinding = interceptorInfo -> interceptorInfo | ||
.getTarget() | ||
.map(t -> t.asClass().name().equals(DotName.createSimple(PungInterceptor.class.getName()))) | ||
.orElse(false); | ||
context.produce( | ||
new MethodInterceptorBindingFilterBuildItem(removePungInterceptorBinding, pingMethodInfo)); | ||
} | ||
}).consumes(BeanArchiveIndexBuildItem.class).produces(MethodInterceptorBindingFilterBuildItem.class).build(); | ||
}); | ||
|
||
@Inject | ||
PingPongBean bean; | ||
|
||
@Test | ||
public void testInterceptor() { | ||
assertEquals("PING PONG", bean.ping()); | ||
} | ||
|
||
@Singleton | ||
static class PingPongBean { | ||
|
||
@NotAnInterceptorBinding | ||
public String ping() { | ||
return "PONG"; | ||
} | ||
|
||
} | ||
|
||
@Priority(1) | ||
@Interceptor | ||
@NotAnInterceptorBinding | ||
static class PingInterceptor { | ||
|
||
@AroundInvoke | ||
Object aroundInvoke(InvocationContext ctx) throws Exception { | ||
return "PING " + ctx.proceed(); | ||
} | ||
|
||
} | ||
|
||
@Priority(2) | ||
@Interceptor | ||
@NotAnInterceptorBinding | ||
static class PungInterceptor { | ||
|
||
@AroundInvoke | ||
Object aroundInvoke(InvocationContext ctx) throws Exception { | ||
return "PUNG " + ctx.proceed(); | ||
} | ||
|
||
} | ||
|
||
@Target({ TYPE, METHOD }) | ||
@Retention(RUNTIME) | ||
@interface NotAnInterceptorBinding { | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.