1515import java .util .Set ;
1616import java .util .function .Function ;
1717import java .util .stream .Collectors ;
18+ import java .util .stream .Stream ;
1819
1920import jakarta .enterprise .inject .Instance ;
2021import jakarta .enterprise .inject .spi .CDI ;
@@ -39,7 +40,7 @@ public class QuarkusSecurityTestExtension implements QuarkusTestBeforeEachCallba
3940 @ Override
4041 public void afterEach (QuarkusTestMethodContext context ) {
4142 try {
42- if (getAnnotationContainer (context ).isPresent ()) {
43+ if (getTestSecurityContext (context ).isPresent ()) {
4344 final ArcContainer container = Arc .container ();
4445 container .select (TestAuthController .class ).get ().setEnabled (true );
4546 for (var testMechanism : container .select (AbstractTestHttpAuthenticationMechanism .class )) {
@@ -60,13 +61,12 @@ public void afterEach(QuarkusTestMethodContext context) {
6061 @ Override
6162 public void beforeEach (QuarkusTestMethodContext context ) {
6263 try {
63- Optional < AnnotationContainer < TestSecurity >> annotationContainerOptional = getAnnotationContainer (context );
64- if (annotationContainerOptional . isEmpty ()) {
64+ var testSecurityContext = getTestSecurityContext (context );
65+ if (! testSecurityContext . isPresent ()) {
6566 return ;
6667 }
67- var annotationContainer = annotationContainerOptional .get ();
68- Annotation [] allAnnotations = annotationContainer .getElement ().getAnnotations ();
69- TestSecurity testSecurity = annotationContainer .getAnnotation ();
68+ Annotation [] allAnnotations = testSecurityContext .allAnnotations ();
69+ TestSecurity testSecurity = testSecurityContext .annotationContainer .getAnnotation ();
7070 final ArcContainer container = Arc .container ();
7171 container .select (TestAuthController .class ).get ().setEnabled (testSecurity .authorizationEnabled ());
7272 if (testSecurity .user ().isEmpty ()) {
@@ -163,7 +163,7 @@ void addAction(String action) {
163163 possessedPermissions .stream ().anyMatch (possessedPermission -> possessedPermission .implies (requiredPermission )));
164164 }
165165
166- private Optional < AnnotationContainer < TestSecurity >> getAnnotationContainer (QuarkusTestMethodContext context )
166+ private TestSecurityContext getTestSecurityContext (QuarkusTestMethodContext context )
167167 throws Exception {
168168 //the usual ClassLoader hacks to get our copy of the TestSecurity annotation
169169 ClassLoader cl = Thread .currentThread ().getContextClassLoader ();
@@ -183,8 +183,9 @@ private Optional<AnnotationContainer<TestSecurity>> getAnnotationContainer(Quark
183183 TestSecurity .class );
184184 if (annotationContainerOptional .isEmpty ()) {
185185 annotationContainerOptional = AnnotationUtils .findAnnotation (original , TestSecurity .class );
186+ return new TestSecurityContext (annotationContainerOptional .orElse (null ), method );
186187 }
187- return annotationContainerOptional ;
188+ return new TestSecurityContext ( annotationContainerOptional . orElse ( null ), null ) ;
188189 }
189190
190191 private SecurityIdentity augment (SecurityIdentity identity , Annotation [] annotations ) {
@@ -194,4 +195,22 @@ private SecurityIdentity augment(SecurityIdentity identity, Annotation[] annotat
194195 }
195196 return identity ;
196197 }
198+
199+ private record TestSecurityContext (AnnotationContainer <TestSecurity > annotationContainer , Method method ) {
200+ private Annotation [] allAnnotations () {
201+ Annotation [] testSecurityElementAnnotations = annotationContainer .getElement ().getAnnotations ();
202+ boolean classLevelTestSecurity = method != null ;
203+ if (classLevelTestSecurity && method .getAnnotations ().length > 0 ) {
204+ // add method-level annotations as there could be for example @OidcSecurity
205+ return Stream .concat (
206+ Arrays .stream (method .getAnnotations ()),
207+ Arrays .stream (testSecurityElementAnnotations )).toArray (Annotation []::new );
208+ }
209+ return testSecurityElementAnnotations ;
210+ }
211+
212+ private boolean isPresent () {
213+ return annotationContainer != null ;
214+ }
215+ }
197216}
0 commit comments