11package io .scalecube .services .methods ;
22
33import static io .scalecube .services .auth .Principal .NULL_PRINCIPAL ;
4+ import static io .scalecube .services .methods .StubService .NAMESPACE ;
45import static org .junit .jupiter .api .Assertions .assertEquals ;
56import static org .junit .jupiter .api .Assertions .assertTrue ;
67import static org .mockito .Mockito .mock ;
78import static org .mockito .Mockito .when ;
89
10+ import io .scalecube .services .CommunicationMode ;
911import io .scalecube .services .Reflect ;
1012import io .scalecube .services .RequestContext ;
1113import io .scalecube .services .api .ErrorData ;
1719import io .scalecube .services .transport .api .ServiceMessageDataDecoder ;
1820import java .lang .reflect .Method ;
1921import java .util .List ;
22+ import java .util .Set ;
2023import java .util .function .Consumer ;
2124import java .util .stream .Stream ;
2225import org .junit .jupiter .api .DisplayName ;
2730import org .mockito .ArgumentMatchers ;
2831import reactor .core .publisher .Flux ;
2932import reactor .core .publisher .Mono ;
33+ import reactor .core .scheduler .Schedulers ;
3034import reactor .test .StepVerifier ;
3135import reactor .util .context .Context ;
3236
@@ -286,6 +290,88 @@ static Stream<Principal> testAuthFailedWithRoleOrPermissionsMethodSource() {
286290 }
287291 }
288292
293+ @ Nested
294+ class ServiceRoleTests {
295+
296+ @ Test
297+ @ DisplayName ("Invocation of service method with @AllowedRole annotation" )
298+ void invokeWithAllowedRoleAnnotation () throws Exception {
299+ final var methodName = "invokeWithAllowedRoleAnnotation" ;
300+ final var method = StubService .class .getMethod (methodName );
301+ final var methodInfo =
302+ new MethodInfo (
303+ NAMESPACE ,
304+ methodName ,
305+ Void .TYPE ,
306+ false ,
307+ CommunicationMode .REQUEST_RESPONSE ,
308+ 0 ,
309+ Void .TYPE ,
310+ false ,
311+ true ,
312+ Schedulers .immediate (),
313+ null ,
314+ List .of (new ServiceRoleDefinition ("admin" , Set .of ("read" , "write" ))));
315+
316+ final var message = serviceMessage (methodName );
317+ final var principal = new PrincipalImpl ("admin" , List .of ("read" , "write" ));
318+
319+ final var authenticator = mock (Authenticator .class );
320+ when (authenticator .authenticate (ArgumentMatchers .any ())).thenReturn (Mono .just (principal ));
321+
322+ serviceMethodInvoker = serviceMethodInvoker (method , methodInfo , authenticator );
323+
324+ StepVerifier .create (
325+ serviceMethodInvoker
326+ .invokeOne (message )
327+ .contextWrite (requestContext (message , principal )))
328+ .verifyComplete ();
329+ }
330+
331+ @ ParameterizedTest
332+ @ MethodSource ("invokeWithAllowedRoleAnnotationFailedMethodSource" )
333+ @ DisplayName ("Failed to invoke of service method with @AllowedRole annotation" )
334+ void invokeWithAllowedRoleAnnotationFailed (Principal principal ) throws Exception {
335+ final var methodName = "invokeWithAllowedRoleAnnotation" ;
336+ final var method = StubService .class .getMethod (methodName );
337+ final var methodInfo =
338+ new MethodInfo (
339+ NAMESPACE ,
340+ methodName ,
341+ Void .TYPE ,
342+ false ,
343+ CommunicationMode .REQUEST_RESPONSE ,
344+ 0 ,
345+ Void .TYPE ,
346+ false ,
347+ true ,
348+ Schedulers .immediate (),
349+ null ,
350+ List .of (new ServiceRoleDefinition ("admin" , Set .of ("read" , "write" ))));
351+
352+ final var message = serviceMessage (methodName );
353+
354+ final var authenticator = mock (Authenticator .class );
355+ when (authenticator .authenticate (ArgumentMatchers .any ())).thenReturn (Mono .just (principal ));
356+
357+ serviceMethodInvoker = serviceMethodInvoker (method , methodInfo , authenticator );
358+
359+ StepVerifier .create (
360+ serviceMethodInvoker
361+ .invokeOne (message )
362+ .contextWrite (requestContext (message , principal )))
363+ .assertNext (assertError (403 , "Insufficient permissions" ))
364+ .verifyComplete ();
365+ }
366+
367+ static Stream <Principal > invokeWithAllowedRoleAnnotationFailedMethodSource () {
368+ return Stream .of (
369+ NULL_PRINCIPAL ,
370+ new PrincipalImpl ("invalid-role" , null ),
371+ new PrincipalImpl ("admin" , List .of ("invalid-permission" )));
372+ }
373+ }
374+
289375 private static Context requestContext (ServiceMessage message , Principal principal ) {
290376 return new RequestContext ().headers (message .headers ()).principal (principal );
291377 }
@@ -303,9 +389,7 @@ private ServiceMethodInvoker serviceMethodInvoker(
303389 }
304390
305391 private static ServiceMessage serviceMessage (String action ) {
306- return ServiceMessage .builder ()
307- .qualifier (Qualifier .asString (StubService .NAMESPACE , action ))
308- .build ();
392+ return ServiceMessage .builder ().qualifier (Qualifier .asString (NAMESPACE , action )).build ();
309393 }
310394
311395 private static Consumer <ServiceMessage > assertError (int errorCode , String errorMessage ) {
0 commit comments