feat(lum): KeycloakRealmSetupService + rôles RBAC UnionFlow + Jacoco 100%
- Ajoute KeycloakRealmSetupService : auto-initialisation des rôles realm (admin, user_manager, user_viewer, role_manager...) et assignation du rôle user_manager au service account unionflow-server au démarrage (idempotent, retries, thread séparé pour ne pas bloquer le démarrage) → Corrige le 403 sur resetPassword / changement de mot de passe premier login - UserResource : étend les @RolesAllowed avec ADMIN/SUPER_ADMIN/USER pour permettre aux appels inter-services unionflow-server d'accéder aux endpoints sans être bloqués par le RBAC LUM ; corrige sendVerificationEmail (retourne Response) - application-dev.properties : service-accounts.user-manager-clients=unionflow-server - application-prod.properties : client-id, credentials.secret, token.audience, auto-setup - application-test.properties : H2 in-memory (plus besoin de Docker pour les tests) - pom.xml : H2 scope test, Jacoco 100% enforcement (exclusions MapStruct/repos/setup), annotation processors MapStruct+Lombok explicites - .gitignore + .env ajouté (.env exclu du commit) - script/docker/.env.example : variables KEYCLOAK_ADMIN_USERNAME/PASSWORD documentées
This commit is contained in:
@@ -6,6 +6,7 @@ import jakarta.ws.rs.core.UriInfo;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
@@ -84,5 +85,94 @@ class DevSecurityContextProducerTest {
|
||||
|
||||
verify(requestContext, times(1)).setSecurityContext(any(SecurityContext.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDevSecurityContext_GetUserPrincipal() throws Exception {
|
||||
setField("profile", "dev");
|
||||
setField("oidcEnabled", false);
|
||||
|
||||
when(requestContext.getUriInfo()).thenReturn(uriInfo);
|
||||
when(uriInfo.getPath()).thenReturn("/api/test");
|
||||
when(requestContext.getSecurityContext()).thenReturn(originalSecurityContext);
|
||||
|
||||
ArgumentCaptor<SecurityContext> captor = ArgumentCaptor.forClass(SecurityContext.class);
|
||||
producer.filter(requestContext);
|
||||
verify(requestContext).setSecurityContext(captor.capture());
|
||||
|
||||
SecurityContext devCtx = captor.getValue();
|
||||
assertNotNull(devCtx.getUserPrincipal());
|
||||
assertEquals("dev-user", devCtx.getUserPrincipal().getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDevSecurityContext_IsUserInRole() throws Exception {
|
||||
setField("profile", "dev");
|
||||
setField("oidcEnabled", false);
|
||||
|
||||
when(requestContext.getUriInfo()).thenReturn(uriInfo);
|
||||
when(uriInfo.getPath()).thenReturn("/api/test");
|
||||
when(requestContext.getSecurityContext()).thenReturn(originalSecurityContext);
|
||||
|
||||
ArgumentCaptor<SecurityContext> captor = ArgumentCaptor.forClass(SecurityContext.class);
|
||||
producer.filter(requestContext);
|
||||
verify(requestContext).setSecurityContext(captor.capture());
|
||||
|
||||
SecurityContext devCtx = captor.getValue();
|
||||
assertTrue(devCtx.isUserInRole("admin"));
|
||||
assertTrue(devCtx.isUserInRole("user_manager"));
|
||||
assertTrue(devCtx.isUserInRole("any_role"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDevSecurityContext_IsSecure_WithOriginal() throws Exception {
|
||||
setField("profile", "dev");
|
||||
setField("oidcEnabled", false);
|
||||
|
||||
when(requestContext.getUriInfo()).thenReturn(uriInfo);
|
||||
when(uriInfo.getPath()).thenReturn("/api/test");
|
||||
when(requestContext.getSecurityContext()).thenReturn(originalSecurityContext);
|
||||
when(originalSecurityContext.isSecure()).thenReturn(true);
|
||||
|
||||
ArgumentCaptor<SecurityContext> captor = ArgumentCaptor.forClass(SecurityContext.class);
|
||||
producer.filter(requestContext);
|
||||
verify(requestContext).setSecurityContext(captor.capture());
|
||||
|
||||
SecurityContext devCtx = captor.getValue();
|
||||
assertTrue(devCtx.isSecure()); // delegates to original which returns true
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDevSecurityContext_IsSecure_WithNullOriginal() throws Exception {
|
||||
setField("profile", "dev");
|
||||
setField("oidcEnabled", false);
|
||||
|
||||
when(requestContext.getUriInfo()).thenReturn(uriInfo);
|
||||
when(uriInfo.getPath()).thenReturn("/api/test");
|
||||
when(requestContext.getSecurityContext()).thenReturn(null); // null original
|
||||
|
||||
ArgumentCaptor<SecurityContext> captor = ArgumentCaptor.forClass(SecurityContext.class);
|
||||
producer.filter(requestContext);
|
||||
verify(requestContext).setSecurityContext(captor.capture());
|
||||
|
||||
SecurityContext devCtx = captor.getValue();
|
||||
assertFalse(devCtx.isSecure()); // original is null → returns false
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDevSecurityContext_GetAuthenticationScheme() throws Exception {
|
||||
setField("profile", "dev");
|
||||
setField("oidcEnabled", false);
|
||||
|
||||
when(requestContext.getUriInfo()).thenReturn(uriInfo);
|
||||
when(uriInfo.getPath()).thenReturn("/api/test");
|
||||
when(requestContext.getSecurityContext()).thenReturn(originalSecurityContext);
|
||||
|
||||
ArgumentCaptor<SecurityContext> captor = ArgumentCaptor.forClass(SecurityContext.class);
|
||||
producer.filter(requestContext);
|
||||
verify(requestContext).setSecurityContext(captor.capture());
|
||||
|
||||
SecurityContext devCtx = captor.getValue();
|
||||
assertEquals("DEV", devCtx.getAuthenticationScheme());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user