diff --git a/.gitignore b/.gitignore index ef93977..eb78596 100644 --- a/.gitignore +++ b/.gitignore @@ -1,114 +1,114 @@ -# ==================================== -# GITIGNORE POUR SERVER API (Maven Library) -# ==================================== - -# ===== MAVEN ===== -target/ -pom.xml.tag -pom.xml.releaseBackup -pom.xml.versionsBackup -pom.xml.next -release.properties -dependency-reduced-pom.xml -buildNumber.properties -.mvn/timing.properties -.mvn/wrapper/maven-wrapper.jar -.flattened-pom.xml - -# ===== JAVA COMPILED FILES ===== -*.class -*.jar -*.war -*.ear -*.nar -*.zip -*.tar.gz -*.rar - -# ===== IDE - ECLIPSE ===== -.project -.classpath -.settings/ -.factorypath -.metadata/ -bin/ -.apt_generated -.springBeans -.sts4-cache - -# ===== IDE - INTELLIJ IDEA ===== -.idea/ -*.iml -*.ipr -*.iws -out/ - -# ===== IDE - NETBEANS ===== -nbproject/ -nbbuild/ -nbdist/ -.nb-gradle/ -nb-configuration.xml -nbactions.xml - -# ===== IDE - VS CODE ===== -.vscode/ -*.code-workspace - -# ===== OS SPECIFIC ===== -.DS_Store -Thumbs.db -ehthumbs.db -Desktop.ini -$RECYCLE.BIN/ -*~ - -# ===== LOGS ===== -*.log -*.log.* -logs/ -log/ - -# ===== TEMPORARY FILES ===== -*.tmp -*.temp -*.bak -*.backup -*.old -*.swp -*.swo -*.orig -*.rej - -# ===== ENVIRONMENT & CONFIGURATION ===== -.env -.env.local -.env.* -*.local -application-local.properties - -# ===== SECURITY - KEYS & CERTIFICATES ===== -*.key -*.pem -*.crt -*.p12 -*.jks -*.keystore -.certs/ -.certificates/ - -# ===== TEST COVERAGE ===== -.jacoco/ -jacoco.exec -coverage/ -.nyc_output/ - -# ===== GENERATED SOURCES ===== -src/gen/ -generated-sources/ -generated-test-sources/ - -# ===== BUILD ARTIFACTS ===== -dist/ -build/ -out/ +# ==================================== +# GITIGNORE POUR SERVER API (Maven Library) +# ==================================== + +# ===== MAVEN ===== +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +.mvn/wrapper/maven-wrapper.jar +.flattened-pom.xml + +# ===== JAVA COMPILED FILES ===== +*.class +*.jar +*.war +*.ear +*.nar +*.zip +*.tar.gz +*.rar + +# ===== IDE - ECLIPSE ===== +.project +.classpath +.settings/ +.factorypath +.metadata/ +bin/ +.apt_generated +.springBeans +.sts4-cache + +# ===== IDE - INTELLIJ IDEA ===== +.idea/ +*.iml +*.ipr +*.iws +out/ + +# ===== IDE - NETBEANS ===== +nbproject/ +nbbuild/ +nbdist/ +.nb-gradle/ +nb-configuration.xml +nbactions.xml + +# ===== IDE - VS CODE ===== +.vscode/ +*.code-workspace + +# ===== OS SPECIFIC ===== +.DS_Store +Thumbs.db +ehthumbs.db +Desktop.ini +$RECYCLE.BIN/ +*~ + +# ===== LOGS ===== +*.log +*.log.* +logs/ +log/ + +# ===== TEMPORARY FILES ===== +*.tmp +*.temp +*.bak +*.backup +*.old +*.swp +*.swo +*.orig +*.rej + +# ===== ENVIRONMENT & CONFIGURATION ===== +.env +.env.local +.env.* +*.local +application-local.properties + +# ===== SECURITY - KEYS & CERTIFICATES ===== +*.key +*.pem +*.crt +*.p12 +*.jks +*.keystore +.certs/ +.certificates/ + +# ===== TEST COVERAGE ===== +.jacoco/ +jacoco.exec +coverage/ +.nyc_output/ + +# ===== GENERATED SOURCES ===== +src/gen/ +generated-sources/ +generated-test-sources/ + +# ===== BUILD ARTIFACTS ===== +dist/ +build/ +out/ diff --git a/README.md b/README.md index dcf9930..6a7f7b5 100644 --- a/README.md +++ b/README.md @@ -1,124 +1,124 @@ -# lions-user-manager-server-api - -> Contrats partagés entre le serveur et le client — DTOs, interfaces de services, enums, validations - -## Rôle - -Ce module constitue la couche de contrats (API layer) du projet Lions User Manager. Il est compilé en JAR et publié sur le **Gitea Package Registry** pour être consommé par `server-impl` et `client` comme dépendance Maven. - ---- - -## Contenu - -### DTOs - -| DTO | Description | -|-----|-------------| -| `UserDTO` | Représentation complète d'un utilisateur Keycloak | -| `UserCreationDTO` | Données de création d'un utilisateur | -| `UserUpdateDTO` | Données de mise à jour | -| `RoleDTO` | Rôle Keycloak | -| `RealmDTO` | Realm Keycloak | -| `RealmAssignmentDTO` | Assignation d'un utilisateur à un realm | -| `AuditLogDTO` | Entrée de journal d'audit | -| `SyncHistoryDTO` | Historique de synchronisation | -| `SyncConsistencyDTO` | Rapport de cohérence sync | -| `ImportResultDTO` | Résultat d'import CSV | - -### Interfaces de services - -| Interface | Responsabilité | -|-----------|----------------| -| `UserService` | CRUD utilisateurs, export/import CSV | -| `RoleService` | Gestion des rôles par realm | -| `AuditService` | Consultation et export des logs d'audit | -| `SyncService` | Synchronisation Keycloak ↔ base de données | -| `RealmAuthorizationService` | Gestion des realms autorisés | - -### Interfaces de ressources (JAX-RS) - -| Interface | Path | -|-----------|------| -| `UserResourceApi` | `/api/users` | -| `RoleResourceApi` | `/api/roles` | -| `AuditResourceApi` | `/api/audit` | -| `SyncResourceApi` | `/api/sync` | -| `RealmResourceApi` | `/api/realms` | -| `RealmAssignmentResourceApi` | `/api/realm-assignments` | - -### Enums - -- `StatutUser` — ACTIF, INACTIF, SUSPENDU -- `TypeRole` — ADMIN, USER, VIEWER -- `TypeActionAudit` — CREATE, UPDATE, DELETE, LOGIN, LOGOUT, SYNC - -### Validations - -- `ValidationConstants` — Constantes partagées (longueurs, patterns regex) - ---- - -## Dépôt Git - -`https://git.lions.dev/lionsdev/lions-user-manager-server-api` - ---- - -## Maven Registry - -Le jar est disponible sur le **Gitea Package Registry** : - -``` -groupId : dev.lions.user.manager -artifactId : lions-user-manager-server-api -version : 1.0.0 -registry : https://git.lions.dev/api/packages/lionsdev/maven -``` - -### Consommer ce module (server-impl / client) - -```xml - - dev.lions.user.manager - lions-user-manager-server-api - 1.0.0 - -``` - -```xml - - - gitea-lionsdev - https://git.lions.dev/api/packages/lionsdev/maven - - -``` - ---- - -## Publier une nouvelle version - -1. Incrémenter la version dans `../pom.xml` (parent) -2. Exécuter depuis la racine du monorepo : - -```bash -# Windows -script\publish-api.bat - -# Linux / macOS -./script/publish-api.sh -``` - ---- - -## Build local - -```bash -mvn clean install -DskipTests -``` - ---- - -## Licence - -Propriétaire — Lions Dev © 2025 +# lions-user-manager-server-api + +> Contrats partagés entre le serveur et le client — DTOs, interfaces de services, enums, validations + +## Rôle + +Ce module constitue la couche de contrats (API layer) du projet Lions User Manager. Il est compilé en JAR et publié sur le **Gitea Package Registry** pour être consommé par `server-impl` et `client` comme dépendance Maven. + +--- + +## Contenu + +### DTOs + +| DTO | Description | +|-----|-------------| +| `UserDTO` | Représentation complète d'un utilisateur Keycloak | +| `UserCreationDTO` | Données de création d'un utilisateur | +| `UserUpdateDTO` | Données de mise à jour | +| `RoleDTO` | Rôle Keycloak | +| `RealmDTO` | Realm Keycloak | +| `RealmAssignmentDTO` | Assignation d'un utilisateur à un realm | +| `AuditLogDTO` | Entrée de journal d'audit | +| `SyncHistoryDTO` | Historique de synchronisation | +| `SyncConsistencyDTO` | Rapport de cohérence sync | +| `ImportResultDTO` | Résultat d'import CSV | + +### Interfaces de services + +| Interface | Responsabilité | +|-----------|----------------| +| `UserService` | CRUD utilisateurs, export/import CSV | +| `RoleService` | Gestion des rôles par realm | +| `AuditService` | Consultation et export des logs d'audit | +| `SyncService` | Synchronisation Keycloak ↔ base de données | +| `RealmAuthorizationService` | Gestion des realms autorisés | + +### Interfaces de ressources (JAX-RS) + +| Interface | Path | +|-----------|------| +| `UserResourceApi` | `/api/users` | +| `RoleResourceApi` | `/api/roles` | +| `AuditResourceApi` | `/api/audit` | +| `SyncResourceApi` | `/api/sync` | +| `RealmResourceApi` | `/api/realms` | +| `RealmAssignmentResourceApi` | `/api/realm-assignments` | + +### Enums + +- `StatutUser` — ACTIF, INACTIF, SUSPENDU +- `TypeRole` — ADMIN, USER, VIEWER +- `TypeActionAudit` — CREATE, UPDATE, DELETE, LOGIN, LOGOUT, SYNC + +### Validations + +- `ValidationConstants` — Constantes partagées (longueurs, patterns regex) + +--- + +## Dépôt Git + +`https://git.lions.dev/lionsdev/lions-user-manager-server-api` + +--- + +## Maven Registry + +Le jar est disponible sur le **Gitea Package Registry** : + +``` +groupId : dev.lions.user.manager +artifactId : lions-user-manager-server-api +version : 1.0.0 +registry : https://git.lions.dev/api/packages/lionsdev/maven +``` + +### Consommer ce module (server-impl / client) + +```xml + + dev.lions.user.manager + lions-user-manager-server-api + 1.0.0 + +``` + +```xml + + + gitea-lionsdev + https://git.lions.dev/api/packages/lionsdev/maven + + +``` + +--- + +## Publier une nouvelle version + +1. Incrémenter la version dans `../pom.xml` (parent) +2. Exécuter depuis la racine du monorepo : + +```bash +# Windows +script\publish-api.bat + +# Linux / macOS +./script/publish-api.sh +``` + +--- + +## Build local + +```bash +mvn clean install -DskipTests +``` + +--- + +## Licence + +Propriétaire — Lions Dev © 2025 diff --git a/lombok.config b/lombok.config index 2b45606..b4edc26 100644 --- a/lombok.config +++ b/lombok.config @@ -1,6 +1,6 @@ -# This file configures Lombok for the project -# See https://projectlombok.org/features/configuration - -# Add @Generated annotation to all generated code -# This allows JaCoCo to automatically exclude Lombok-generated code from coverage -lombok.addLombokGeneratedAnnotation = true +# This file configures Lombok for the project +# See https://projectlombok.org/features/configuration + +# Add @Generated annotation to all generated code +# This allows JaCoCo to automatically exclude Lombok-generated code from coverage +lombok.addLombokGeneratedAnnotation = true diff --git a/parent-pom.xml b/parent-pom.xml index 4e9abcc..56c5d5d 100644 --- a/parent-pom.xml +++ b/parent-pom.xml @@ -1,265 +1,266 @@ - - - 4.0.0 - - dev.lions.user.manager - lions-user-manager-parent - 1.0.0 - pom - - Lions User Manager - Parent - Module de gestion centralisée des utilisateurs via Keycloak Admin API - - - - gitea-lionsdev - https://git.lions.dev/api/packages/lionsdev/maven - - - gitea-lionsdev - https://git.lions.dev/api/packages/lionsdev/maven - - - - - - gitea-lionsdev - https://git.lions.dev/api/packages/lionsdev/maven - true - true - - - - - 21 - 21 - 21 - UTF-8 - UTF-8 - - - 3.20.0 - 3.15.1 - 14.0.5 - 1.0.0 - 26.0.7 - 1.18.36 - 1.6.3 - - - 5.11.4 - 5.14.2 - 1.20.6 - 5.5.0 - - - 3.13.0 - 3.5.2 - 3.5.2 - 0.8.12 - - - - lions-user-manager-server-api - lions-user-manager-server-impl-quarkus - lions-user-manager-client-quarkus-primefaces-freya - - - - - - - io.quarkus.platform - quarkus-bom - ${quarkus.version} - pom - import - - - - - dev.lions.user.manager - lions-user-manager-server-api - ${project.version} - - - - - dev.lions - primefaces-freya-extension - ${primefaces-freya-extension.version} - - - - - org.projectlombok - lombok - ${lombok.version} - provided - - - - - org.mapstruct - mapstruct - ${mapstruct.version} - - - - - org.junit.jupiter - junit-jupiter - ${junit.version} - test - - - - org.testcontainers - testcontainers-bom - ${testcontainers.version} - pom - import - - - - io.rest-assured - rest-assured - ${rest-assured.version} - test - - - - org.mockito - mockito-core - ${mockito.version} - test - - - - org.mockito - mockito-junit-jupiter - ${mockito.version} - - - - - - - - - dev - - true - - - dev - - - - prod - - prod - - - - native - - prod - native - - - - io.quarkus - quarkus-junit5 - test - - - - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - ${maven-compiler-plugin.version} - - - - org.projectlombok - lombok - ${lombok.version} - - - org.mapstruct - mapstruct-processor - ${mapstruct.version} - - - - - - - io.quarkus.platform - quarkus-maven-plugin - ${quarkus.version} - - - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - - - org.apache.maven.plugins - maven-failsafe-plugin - ${maven-failsafe-plugin.version} - - - - org.jacoco - jacoco-maven-plugin - ${jacoco-maven-plugin.version} - - - - prepare-agent - - - - report - test - - report - - - - jacoco-check - - check - - - - - PACKAGE - - - LINE - COVEREDRATIO - 0.80 - - - - - - - - - - - - + + + 4.0.0 + + dev.lions.user.manager + lions-user-manager-parent + 1.1.0 + pom + + Lions User Manager - Parent + Module de gestion centralisée des utilisateurs via Keycloak Admin API + + + + gitea-lionsdev + https://git.lions.dev/api/packages/lionsdev/maven + + + gitea-lionsdev + https://git.lions.dev/api/packages/lionsdev/maven + + + + + + gitea-lionsdev + https://git.lions.dev/api/packages/lionsdev/maven + true + true + + + + + 21 + 21 + 21 + UTF-8 + UTF-8 + + + 3.27.3 + 3.15.1 + 14.0.5 + 1.0.0 + 26.0.7 + 1.18.38 + 1.6.3 + + + 5.11.4 + 5.14.2 + 1.21.4 + 3.4.2 + 5.5.0 + + + 3.13.0 + 3.5.2 + 3.5.2 + 0.8.12 + + + + lions-user-manager-server-api + lions-user-manager-server-impl-quarkus + lions-user-manager-client-quarkus-primefaces-freya + + + + + + + io.quarkus.platform + quarkus-bom + ${quarkus.version} + pom + import + + + + + dev.lions.user.manager + lions-user-manager-server-api + ${project.version} + + + + + dev.lions + primefaces-freya-extension + ${primefaces-freya-extension.version} + + + + + org.projectlombok + lombok + ${lombok.version} + provided + + + + + org.mapstruct + mapstruct + ${mapstruct.version} + + + + + org.junit.jupiter + junit-jupiter + ${junit.version} + test + + + + org.testcontainers + testcontainers-bom + ${testcontainers.version} + pom + import + + + + io.rest-assured + rest-assured + ${rest-assured.version} + test + + + + org.mockito + mockito-core + ${mockito.version} + test + + + + org.mockito + mockito-junit-jupiter + ${mockito.version} + + + + + + + + + dev + + true + + + dev + + + + prod + + prod + + + + native + + prod + native + + + + io.quarkus + quarkus-junit5 + test + + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + + + org.projectlombok + lombok + ${lombok.version} + + + org.mapstruct + mapstruct-processor + ${mapstruct.version} + + + + + + + io.quarkus.platform + quarkus-maven-plugin + ${quarkus.version} + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + + + org.apache.maven.plugins + maven-failsafe-plugin + ${maven-failsafe-plugin.version} + + + + org.jacoco + jacoco-maven-plugin + ${jacoco-maven-plugin.version} + + + + prepare-agent + + + + report + test + + report + + + + jacoco-check + + check + + + + + PACKAGE + + + LINE + COVEREDRATIO + 0.80 + + + + + + + + + + + + diff --git a/pom.xml b/pom.xml index 5d2ce73..806c9ca 100644 --- a/pom.xml +++ b/pom.xml @@ -1,91 +1,134 @@ - - - 4.0.0 - - - dev.lions.user.manager - lions-user-manager-parent - 1.0.0 - - - lions-user-manager-server-api - jar - - Lions User Manager - Server API - Contrats API: DTOs, interfaces de services, enums et validations - - - - - org.projectlombok - lombok - - - - - jakarta.validation - jakarta.validation-api - - - - jakarta.ws.rs - jakarta.ws.rs-api - - - - - com.fasterxml.jackson.core - jackson-annotations - - - - - org.eclipse.microprofile.openapi - microprofile-openapi-api - - - - - io.quarkus - quarkus-core - provided - true - - - - - org.junit.jupiter - junit-jupiter - test - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - 21 - - - - - - io.smallrye - jandex-maven-plugin - 3.2.4 - - - make-index - - jandex - - - - - - - + + + 4.0.0 + + dev.lions.user.manager + 1.1.0 + + + 21 + ${java.version} + ${java.version} + UTF-8 + 3.27.3 + 1.18.38 + + + lions-user-manager-server-api + jar + + Lions User Manager - Server API + Contrats API: DTOs, interfaces de services, enums et validations + + + + gitea-lionsdev + https://git.lions.dev/api/packages/lionsdev/maven + + + + + + gitea-lionsdev + https://git.lions.dev/api/packages/lionsdev/maven + true + true + + + + + + + + io.quarkus.platform + quarkus-bom + ${quarkus.platform.version} + pom + import + + + + org.projectlombok + lombok + ${lombok.version} + provided + + + + + + + + org.projectlombok + lombok + + + + + jakarta.validation + jakarta.validation-api + + + + jakarta.ws.rs + jakarta.ws.rs-api + + + + + com.fasterxml.jackson.core + jackson-annotations + + + + + org.eclipse.microprofile.openapi + microprofile-openapi-api + + + + + io.quarkus + quarkus-core + provided + true + + + + + org.junit.jupiter + junit-jupiter + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.13.0 + + 21 + + + + + + io.smallrye + jandex-maven-plugin + 3.2.4 + + + make-index + + jandex + + + + + + + diff --git a/script/publish-api.bat b/script/publish-api.bat index 3ae7c10..f185071 100644 --- a/script/publish-api.bat +++ b/script/publish-api.bat @@ -1,30 +1,30 @@ -@echo off -REM Publie le parent pom + server-api sur le Gitea Package Registry -REM Usage : script\publish-api.bat -REM Depuis : n'importe où dans le repo server-api -REM Prérequis: credentials dans %USERPROFILE%\.m2\settings.xml (server id: gitea-lionsdev) - -set REGISTRY_URL=https://git.lions.dev/api/packages/lionsdev/maven -set REGISTRY_ID=gitea-lionsdev - -cd /d "%~dp0.." - -echo. -echo [1/2] Publication du parent pom... -call mvn deploy:deploy-file ^ - -DgroupId=dev.lions.user.manager ^ - -DartifactId=lions-user-manager-parent ^ - -Dversion=1.0.0 ^ - -Dpackaging=pom ^ - -Dfile=parent-pom.xml ^ - -DrepositoryId=%REGISTRY_ID% ^ - -Durl=%REGISTRY_URL% -if %errorlevel% neq 0 echo [WARN] Parent pom deja publie pour cette version (409), on continue. - -echo. -echo [2/2] Publication du server-api... -call mvn deploy -DskipTests -if %errorlevel% neq 0 echo [WARN] Server-api deja publie pour cette version (409) - incrementer la version pour republier. - -echo. -echo Done -- https://git.lions.dev/lionsdev/-/packages +@echo off +REM Publie le parent pom + server-api sur le Gitea Package Registry +REM Usage : script\publish-api.bat +REM Depuis : n'importe où dans le repo server-api +REM Prérequis: credentials dans %USERPROFILE%\.m2\settings.xml (server id: gitea-lionsdev) + +set REGISTRY_URL=https://git.lions.dev/api/packages/lionsdev/maven +set REGISTRY_ID=gitea-lionsdev + +cd /d "%~dp0.." + +echo. +echo [1/2] Publication du parent pom... +call mvn deploy:deploy-file ^ + -DgroupId=dev.lions.user.manager ^ + -DartifactId=lions-user-manager-parent ^ + -Dversion=1.0.0 ^ + -Dpackaging=pom ^ + -Dfile=parent-pom.xml ^ + -DrepositoryId=%REGISTRY_ID% ^ + -Durl=%REGISTRY_URL% +if %errorlevel% neq 0 echo [WARN] Parent pom deja publie pour cette version (409), on continue. + +echo. +echo [2/2] Publication du server-api... +call mvn deploy -DskipTests +if %errorlevel% neq 0 echo [WARN] Server-api deja publie pour cette version (409) - incrementer la version pour republier. + +echo. +echo Done -- https://git.lions.dev/lionsdev/-/packages diff --git a/script/publish-api.sh b/script/publish-api.sh index de5106a..a52cffc 100644 --- a/script/publish-api.sh +++ b/script/publish-api.sh @@ -1,32 +1,32 @@ -#!/bin/bash -# Publie le parent pom + server-api sur le Gitea Package Registry -# Usage : ./script/publish-api.sh -# Depuis : n'importe où dans le repo server-api -# Prérequis: credentials dans ~/.m2/settings.xml (server id: gitea-lionsdev) - -set -e - -REGISTRY_URL="https://git.lions.dev/api/packages/lionsdev/maven" -REGISTRY_ID="gitea-lionsdev" - -cd "$(dirname "$0")/.." - -echo "" -echo "[1/2] Publication du parent pom..." -mvn deploy:deploy-file \ - -DgroupId=dev.lions.user.manager \ - -DartifactId=lions-user-manager-parent \ - -Dversion=1.0.0 \ - -Dpackaging=pom \ - -Dfile=parent-pom.xml \ - -DrepositoryId="${REGISTRY_ID}" \ - -Durl="${REGISTRY_URL}" \ -|| echo "[WARN] Parent pom deja publie pour cette version (409), on continue." - -echo "" -echo "[2/2] Publication du server-api..." -mvn deploy -DskipTests \ -|| echo "[WARN] Server-api deja publie pour cette version (409) - incrementer la version pour republier." - -echo "" -echo "Done -- https://git.lions.dev/lionsdev/-/packages" +#!/bin/bash +# Publie le parent pom + server-api sur le Gitea Package Registry +# Usage : ./script/publish-api.sh +# Depuis : n'importe où dans le repo server-api +# Prérequis: credentials dans ~/.m2/settings.xml (server id: gitea-lionsdev) + +set -e + +REGISTRY_URL="https://git.lions.dev/api/packages/lionsdev/maven" +REGISTRY_ID="gitea-lionsdev" + +cd "$(dirname "$0")/.." + +echo "" +echo "[1/2] Publication du parent pom..." +mvn deploy:deploy-file \ + -DgroupId=dev.lions.user.manager \ + -DartifactId=lions-user-manager-parent \ + -Dversion=1.1.0 \ + -Dpackaging=pom \ + -Dfile=parent-pom.xml \ + -DrepositoryId="${REGISTRY_ID}" \ + -Durl="${REGISTRY_URL}" \ +|| echo "[WARN] Parent pom deja publie pour cette version (409), on continue." + +echo "" +echo "[2/2] Publication du server-api..." +mvn deploy -DskipTests \ +|| echo "[WARN] Server-api deja publie pour cette version (409) - incrementer la version pour republier." + +echo "" +echo "Done -- https://git.lions.dev/lionsdev/-/packages" diff --git a/src/main/java/dev/lions/user/manager/api/AuditResourceApi.java b/src/main/java/dev/lions/user/manager/api/AuditResourceApi.java index a9d04e2..eb85d21 100644 --- a/src/main/java/dev/lions/user/manager/api/AuditResourceApi.java +++ b/src/main/java/dev/lions/user/manager/api/AuditResourceApi.java @@ -1,111 +1,111 @@ -package dev.lions.user.manager.api; - -import dev.lions.user.manager.dto.audit.AuditLogDTO; -import dev.lions.user.manager.dto.common.CountDTO; -import dev.lions.user.manager.enums.audit.TypeActionAudit; -import jakarta.ws.rs.*; -import jakarta.ws.rs.core.MediaType; -import jakarta.ws.rs.core.Response; -import org.eclipse.microprofile.openapi.annotations.Operation; -import org.eclipse.microprofile.openapi.annotations.media.Content; -import org.eclipse.microprofile.openapi.annotations.media.Schema; -import org.eclipse.microprofile.openapi.annotations.parameters.Parameter; -import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; -import org.eclipse.microprofile.openapi.annotations.responses.APIResponses; -import org.eclipse.microprofile.openapi.annotations.tags.Tag; - -import java.util.List; -import java.util.Map; - -/** - * Interface JAX-RS pour l'API d'audit. - */ -@Path("/api/audit") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -@Tag(name = "Audit", description = "Consultation des logs d'audit et statistiques") -public interface AuditResourceApi { - - @POST - @Path("/search") - @Operation(summary = "Rechercher des logs d'audit", description = "Recherche avancée de logs selon critères") - @APIResponses({ - @APIResponse(responseCode = "200", description = "Résultats de recherche", content = @Content(schema = @Schema(implementation = AuditLogDTO.class, type = org.eclipse.microprofile.openapi.annotations.enums.SchemaType.ARRAY))), - @APIResponse(responseCode = "500", description = "Erreur serveur") - }) - List searchLogs( - @QueryParam("acteur") String acteurUsername, - @QueryParam("dateDebut") String dateDebut, - @QueryParam("dateFin") String dateFin, - @QueryParam("typeAction") TypeActionAudit typeAction, - @QueryParam("ressourceType") String ressourceType, - @QueryParam("succes") Boolean succes, - @QueryParam("page") @DefaultValue("0") int page, - @QueryParam("pageSize") @DefaultValue("50") int pageSize); - - @GET - @Path("/actor/{acteurUsername}") - @Operation(summary = "Récupérer les logs d'un acteur", description = "Liste les derniers logs d'un utilisateur") - List getLogsByActor( - @Parameter(description = "Username de l'acteur") @PathParam("acteurUsername") String acteurUsername, - @Parameter(description = "Nombre de logs à retourner") @QueryParam("limit") @DefaultValue("100") int limit); - - @GET - @Path("/resource/{ressourceType}/{ressourceId}") - @Operation(summary = "Récupérer les logs d'une ressource", description = "Liste les derniers logs d'une ressource spécifique") - List getLogsByResource( - @PathParam("ressourceType") String ressourceType, - @PathParam("ressourceId") String ressourceId, - @QueryParam("limit") @DefaultValue("100") int limit); - - @GET - @Path("/action/{typeAction}") - @Operation(summary = "Récupérer les logs par type d'action", description = "Liste les logs d'un type d'action spécifique") - List getLogsByAction( - @PathParam("typeAction") TypeActionAudit typeAction, - @QueryParam("dateDebut") String dateDebut, - @QueryParam("dateFin") String dateFin, - @QueryParam("limit") @DefaultValue("100") int limit); - - @GET - @Path("/stats/actions") - @Operation(summary = "Statistiques par type d'action", description = "Retourne le nombre de logs par type d'action") - Map getActionStatistics( - @QueryParam("dateDebut") String dateDebut, - @QueryParam("dateFin") String dateFin); - - @GET - @Path("/stats/users") - @Operation(summary = "Statistiques par utilisateur", description = "Retourne le nombre d'actions par utilisateur") - Map getUserActivityStatistics( - @QueryParam("dateDebut") String dateDebut, - @QueryParam("dateFin") String dateFin); - - @GET - @Path("/stats/failures") - @Operation(summary = "Comptage des échecs", description = "Retourne le nombre d'échecs sur une période") - CountDTO getFailureCount( - @QueryParam("dateDebut") String dateDebut, - @QueryParam("dateFin") String dateFin); - - @GET - @Path("/stats/success") - @Operation(summary = "Comptage des succès", description = "Retourne le nombre de succès sur une période") - CountDTO getSuccessCount( - @QueryParam("dateDebut") String dateDebut, - @QueryParam("dateFin") String dateFin); - - @GET - @Path("/export/csv") - @Produces(MediaType.TEXT_PLAIN) - @Operation(summary = "Exporter les logs en CSV", description = "Génère un fichier CSV des logs d'audit") - Response exportLogsToCSV( - @QueryParam("dateDebut") String dateDebut, - @QueryParam("dateFin") String dateFin); - - @DELETE - @Path("/purge") - @Operation(summary = "Purger les anciens logs", description = "Supprime les logs de plus de X jours") - void purgeOldLogs( - @QueryParam("joursAnciennete") @DefaultValue("90") int joursAnciennete); -} +package dev.lions.user.manager.api; + +import dev.lions.user.manager.dto.audit.AuditLogDTO; +import dev.lions.user.manager.dto.common.CountDTO; +import dev.lions.user.manager.enums.audit.TypeActionAudit; +import jakarta.ws.rs.*; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import org.eclipse.microprofile.openapi.annotations.Operation; +import org.eclipse.microprofile.openapi.annotations.media.Content; +import org.eclipse.microprofile.openapi.annotations.media.Schema; +import org.eclipse.microprofile.openapi.annotations.parameters.Parameter; +import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; +import org.eclipse.microprofile.openapi.annotations.responses.APIResponses; +import org.eclipse.microprofile.openapi.annotations.tags.Tag; + +import java.util.List; +import java.util.Map; + +/** + * Interface JAX-RS pour l'API d'audit. + */ +@Path("/api/audit") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@Tag(name = "Audit", description = "Consultation des logs d'audit et statistiques") +public interface AuditResourceApi { + + @POST + @Path("/search") + @Operation(summary = "Rechercher des logs d'audit", description = "Recherche avancée de logs selon critères") + @APIResponses({ + @APIResponse(responseCode = "200", description = "Résultats de recherche", content = @Content(schema = @Schema(implementation = AuditLogDTO.class, type = org.eclipse.microprofile.openapi.annotations.enums.SchemaType.ARRAY))), + @APIResponse(responseCode = "500", description = "Erreur serveur") + }) + List searchLogs( + @QueryParam("acteur") String acteurUsername, + @QueryParam("dateDebut") String dateDebut, + @QueryParam("dateFin") String dateFin, + @QueryParam("typeAction") TypeActionAudit typeAction, + @QueryParam("ressourceType") String ressourceType, + @QueryParam("succes") Boolean succes, + @QueryParam("page") @DefaultValue("0") int page, + @QueryParam("pageSize") @DefaultValue("50") int pageSize); + + @GET + @Path("/actor/{acteurUsername}") + @Operation(summary = "Récupérer les logs d'un acteur", description = "Liste les derniers logs d'un utilisateur") + List getLogsByActor( + @Parameter(description = "Username de l'acteur") @PathParam("acteurUsername") String acteurUsername, + @Parameter(description = "Nombre de logs à retourner") @QueryParam("limit") @DefaultValue("100") int limit); + + @GET + @Path("/resource/{ressourceType}/{ressourceId}") + @Operation(summary = "Récupérer les logs d'une ressource", description = "Liste les derniers logs d'une ressource spécifique") + List getLogsByResource( + @PathParam("ressourceType") String ressourceType, + @PathParam("ressourceId") String ressourceId, + @QueryParam("limit") @DefaultValue("100") int limit); + + @GET + @Path("/action/{typeAction}") + @Operation(summary = "Récupérer les logs par type d'action", description = "Liste les logs d'un type d'action spécifique") + List getLogsByAction( + @PathParam("typeAction") TypeActionAudit typeAction, + @QueryParam("dateDebut") String dateDebut, + @QueryParam("dateFin") String dateFin, + @QueryParam("limit") @DefaultValue("100") int limit); + + @GET + @Path("/stats/actions") + @Operation(summary = "Statistiques par type d'action", description = "Retourne le nombre de logs par type d'action") + Map getActionStatistics( + @QueryParam("dateDebut") String dateDebut, + @QueryParam("dateFin") String dateFin); + + @GET + @Path("/stats/users") + @Operation(summary = "Statistiques par utilisateur", description = "Retourne le nombre d'actions par utilisateur") + Map getUserActivityStatistics( + @QueryParam("dateDebut") String dateDebut, + @QueryParam("dateFin") String dateFin); + + @GET + @Path("/stats/failures") + @Operation(summary = "Comptage des échecs", description = "Retourne le nombre d'échecs sur une période") + CountDTO getFailureCount( + @QueryParam("dateDebut") String dateDebut, + @QueryParam("dateFin") String dateFin); + + @GET + @Path("/stats/success") + @Operation(summary = "Comptage des succès", description = "Retourne le nombre de succès sur une période") + CountDTO getSuccessCount( + @QueryParam("dateDebut") String dateDebut, + @QueryParam("dateFin") String dateFin); + + @GET + @Path("/export/csv") + @Produces(MediaType.TEXT_PLAIN) + @Operation(summary = "Exporter les logs en CSV", description = "Génère un fichier CSV des logs d'audit") + Response exportLogsToCSV( + @QueryParam("dateDebut") String dateDebut, + @QueryParam("dateFin") String dateFin); + + @DELETE + @Path("/purge") + @Operation(summary = "Purger les anciens logs", description = "Supprime les logs de plus de X jours") + void purgeOldLogs( + @QueryParam("joursAnciennete") @DefaultValue("90") int joursAnciennete); +} diff --git a/src/main/java/dev/lions/user/manager/api/RealmAssignmentResourceApi.java b/src/main/java/dev/lions/user/manager/api/RealmAssignmentResourceApi.java index 5cde415..6e1b82d 100644 --- a/src/main/java/dev/lions/user/manager/api/RealmAssignmentResourceApi.java +++ b/src/main/java/dev/lions/user/manager/api/RealmAssignmentResourceApi.java @@ -1,103 +1,103 @@ -package dev.lions.user.manager.api; - -import dev.lions.user.manager.dto.realm.AuthorizedRealmsDTO; -import dev.lions.user.manager.dto.realm.RealmAccessCheckDTO; -import dev.lions.user.manager.dto.realm.RealmAssignmentDTO; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import jakarta.ws.rs.*; -import jakarta.ws.rs.core.MediaType; -import jakarta.ws.rs.core.Response; -import org.eclipse.microprofile.openapi.annotations.Operation; -import org.eclipse.microprofile.openapi.annotations.media.Content; -import org.eclipse.microprofile.openapi.annotations.media.Schema; -import org.eclipse.microprofile.openapi.annotations.parameters.Parameter; -import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; -import org.eclipse.microprofile.openapi.annotations.responses.APIResponses; -import org.eclipse.microprofile.openapi.annotations.tags.Tag; - -import java.util.List; - -/** - * Interface JAX-RS pour l'API de gestion des affectations de realms. - */ -@Path("/api/realm-assignments") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -@Tag(name = "Realm Assignments", description = "Gestion des affectations de realms (contrôle d'accès multi-tenant)") -public interface RealmAssignmentResourceApi { - - @GET - @Operation(summary = "Lister toutes les affectations", description = "Liste toutes les affectations de realms") - List getAllAssignments(); - - @GET - @Path("/user/{userId}") - @Operation(summary = "Affectations par utilisateur", description = "Liste les realms assignés à un utilisateur") - List getAssignmentsByUser( - @Parameter(description = "ID de l'utilisateur") @PathParam("userId") String userId); - - @GET - @Path("/realm/{realmName}") - @Operation(summary = "Affectations par realm", description = "Liste les utilisateurs ayant accès à un realm") - List getAssignmentsByRealm( - @Parameter(description = "Nom du realm") @PathParam("realmName") String realmName); - - @GET - @Path("/{assignmentId}") - @Operation(summary = "Récupérer une affectation", description = "Récupère une affectation par son ID") - RealmAssignmentDTO getAssignmentById( - @Parameter(description = "ID de l'affectation") @PathParam("assignmentId") String assignmentId); - - @GET - @Path("/check") - @Operation(summary = "Vérifier l'accès", description = "Vérifie si un utilisateur peut gérer un realm") - RealmAccessCheckDTO canManageRealm( - @Parameter(description = "ID de l'utilisateur") @QueryParam("userId") String userId, - @Parameter(description = "Nom du realm") @QueryParam("realmName") String realmName); - - @GET - @Path("/authorized-realms/{userId}") - @Operation(summary = "Realms autorisés", description = "Liste les realms qu'un utilisateur peut gérer") - AuthorizedRealmsDTO getAuthorizedRealms( - @Parameter(description = "ID de l'utilisateur") @PathParam("userId") String userId); - - @POST - @Operation(summary = "Assigner un realm", description = "Assigne un realm à un utilisateur") - @APIResponses({ - @APIResponse(responseCode = "201", description = "Affectation créée", content = @Content(schema = @Schema(implementation = RealmAssignmentDTO.class))) - }) - Response assignRealmToUser(@Valid @NotNull RealmAssignmentDTO assignment); - - @DELETE - @Path("/user/{userId}/realm/{realmName}") - @Operation(summary = "Révoquer un realm", description = "Retire l'accès d'un utilisateur à un realm") - void revokeRealmFromUser( - @Parameter(description = "ID de l'utilisateur") @PathParam("userId") String userId, - @Parameter(description = "Nom du realm") @PathParam("realmName") String realmName); - - @DELETE - @Path("/user/{userId}") - @Operation(summary = "Révoquer tous les realms", description = "Retire tous les accès d'un utilisateur") - void revokeAllRealmsFromUser( - @Parameter(description = "ID de l'utilisateur") @PathParam("userId") String userId); - - @PUT - @Path("/{assignmentId}/deactivate") - @Operation(summary = "Désactiver une affectation", description = "Désactive une affectation sans la supprimer") - void deactivateAssignment( - @Parameter(description = "ID de l'affectation") @PathParam("assignmentId") String assignmentId); - - @PUT - @Path("/{assignmentId}/activate") - @Operation(summary = "Activer une affectation", description = "Réactive une affectation") - void activateAssignment( - @Parameter(description = "ID de l'affectation") @PathParam("assignmentId") String assignmentId); - - @PUT - @Path("/super-admin/{userId}") - @Operation(summary = "Définir super admin", description = "Définit ou retire le statut de super admin") - void setSuperAdmin( - @Parameter(description = "ID de l'utilisateur") @PathParam("userId") String userId, - @Parameter(description = "Super admin (true/false)") @QueryParam("superAdmin") @NotNull Boolean superAdmin); -} +package dev.lions.user.manager.api; + +import dev.lions.user.manager.dto.realm.AuthorizedRealmsDTO; +import dev.lions.user.manager.dto.realm.RealmAccessCheckDTO; +import dev.lions.user.manager.dto.realm.RealmAssignmentDTO; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import jakarta.ws.rs.*; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import org.eclipse.microprofile.openapi.annotations.Operation; +import org.eclipse.microprofile.openapi.annotations.media.Content; +import org.eclipse.microprofile.openapi.annotations.media.Schema; +import org.eclipse.microprofile.openapi.annotations.parameters.Parameter; +import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; +import org.eclipse.microprofile.openapi.annotations.responses.APIResponses; +import org.eclipse.microprofile.openapi.annotations.tags.Tag; + +import java.util.List; + +/** + * Interface JAX-RS pour l'API de gestion des affectations de realms. + */ +@Path("/api/realm-assignments") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@Tag(name = "Realm Assignments", description = "Gestion des affectations de realms (contrôle d'accès multi-tenant)") +public interface RealmAssignmentResourceApi { + + @GET + @Operation(summary = "Lister toutes les affectations", description = "Liste toutes les affectations de realms") + List getAllAssignments(); + + @GET + @Path("/user/{userId}") + @Operation(summary = "Affectations par utilisateur", description = "Liste les realms assignés à un utilisateur") + List getAssignmentsByUser( + @Parameter(description = "ID de l'utilisateur") @PathParam("userId") String userId); + + @GET + @Path("/realm/{realmName}") + @Operation(summary = "Affectations par realm", description = "Liste les utilisateurs ayant accès à un realm") + List getAssignmentsByRealm( + @Parameter(description = "Nom du realm") @PathParam("realmName") String realmName); + + @GET + @Path("/{assignmentId}") + @Operation(summary = "Récupérer une affectation", description = "Récupère une affectation par son ID") + RealmAssignmentDTO getAssignmentById( + @Parameter(description = "ID de l'affectation") @PathParam("assignmentId") String assignmentId); + + @GET + @Path("/check") + @Operation(summary = "Vérifier l'accès", description = "Vérifie si un utilisateur peut gérer un realm") + RealmAccessCheckDTO canManageRealm( + @Parameter(description = "ID de l'utilisateur") @QueryParam("userId") String userId, + @Parameter(description = "Nom du realm") @QueryParam("realmName") String realmName); + + @GET + @Path("/authorized-realms/{userId}") + @Operation(summary = "Realms autorisés", description = "Liste les realms qu'un utilisateur peut gérer") + AuthorizedRealmsDTO getAuthorizedRealms( + @Parameter(description = "ID de l'utilisateur") @PathParam("userId") String userId); + + @POST + @Operation(summary = "Assigner un realm", description = "Assigne un realm à un utilisateur") + @APIResponses({ + @APIResponse(responseCode = "201", description = "Affectation créée", content = @Content(schema = @Schema(implementation = RealmAssignmentDTO.class))) + }) + Response assignRealmToUser(@Valid @NotNull RealmAssignmentDTO assignment); + + @DELETE + @Path("/user/{userId}/realm/{realmName}") + @Operation(summary = "Révoquer un realm", description = "Retire l'accès d'un utilisateur à un realm") + void revokeRealmFromUser( + @Parameter(description = "ID de l'utilisateur") @PathParam("userId") String userId, + @Parameter(description = "Nom du realm") @PathParam("realmName") String realmName); + + @DELETE + @Path("/user/{userId}") + @Operation(summary = "Révoquer tous les realms", description = "Retire tous les accès d'un utilisateur") + void revokeAllRealmsFromUser( + @Parameter(description = "ID de l'utilisateur") @PathParam("userId") String userId); + + @PUT + @Path("/{assignmentId}/deactivate") + @Operation(summary = "Désactiver une affectation", description = "Désactive une affectation sans la supprimer") + void deactivateAssignment( + @Parameter(description = "ID de l'affectation") @PathParam("assignmentId") String assignmentId); + + @PUT + @Path("/{assignmentId}/activate") + @Operation(summary = "Activer une affectation", description = "Réactive une affectation") + void activateAssignment( + @Parameter(description = "ID de l'affectation") @PathParam("assignmentId") String assignmentId); + + @PUT + @Path("/super-admin/{userId}") + @Operation(summary = "Définir super admin", description = "Définit ou retire le statut de super admin") + void setSuperAdmin( + @Parameter(description = "ID de l'utilisateur") @PathParam("userId") String userId, + @Parameter(description = "Super admin (true/false)") @QueryParam("superAdmin") @NotNull Boolean superAdmin); +} diff --git a/src/main/java/dev/lions/user/manager/api/RealmResourceApi.java b/src/main/java/dev/lions/user/manager/api/RealmResourceApi.java index 0b86bd3..f9c474d 100644 --- a/src/main/java/dev/lions/user/manager/api/RealmResourceApi.java +++ b/src/main/java/dev/lions/user/manager/api/RealmResourceApi.java @@ -1,44 +1,44 @@ -package dev.lions.user.manager.api; - -import jakarta.ws.rs.GET; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.PathParam; -import jakarta.ws.rs.Produces; -import jakarta.ws.rs.core.MediaType; -import org.eclipse.microprofile.openapi.annotations.parameters.Parameter; -import org.eclipse.microprofile.openapi.annotations.Operation; -import org.eclipse.microprofile.openapi.annotations.media.Content; -import org.eclipse.microprofile.openapi.annotations.media.Schema; -import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; -import org.eclipse.microprofile.openapi.annotations.responses.APIResponses; -import org.eclipse.microprofile.openapi.annotations.tags.Tag; - -import java.util.List; - -/** - * Interface JAX-RS pour la gestion des realms Keycloak. - */ -@Path("/api/realms") -@Produces(MediaType.APPLICATION_JSON) -@Tag(name = "Realms", description = "Gestion des realms Keycloak") -public interface RealmResourceApi { - - @GET - @Path("/list") - @Operation(summary = "Lister tous les realms", description = "Récupère la liste de tous les realms disponibles dans Keycloak") - @APIResponses({ - @APIResponse(responseCode = "200", description = "Liste des realms", content = @Content(schema = @Schema(type = org.eclipse.microprofile.openapi.annotations.enums.SchemaType.ARRAY, implementation = String.class))), - @APIResponse(responseCode = "500", description = "Erreur serveur") - }) - List getAllRealms(); - - @GET - @Path("/{realm}/clients") - @Operation(summary = "Lister les clients d'un realm", description = "Récupère la liste des clientId de tous les clients d'un realm") - @APIResponses({ - @APIResponse(responseCode = "200", description = "Liste des clients"), - @APIResponse(responseCode = "500", description = "Erreur serveur") - }) - List getRealmClients( - @Parameter(description = "Nom du realm") @PathParam("realm") String realmName); -} +package dev.lions.user.manager.api; + +import jakarta.ws.rs.GET; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; +import org.eclipse.microprofile.openapi.annotations.parameters.Parameter; +import org.eclipse.microprofile.openapi.annotations.Operation; +import org.eclipse.microprofile.openapi.annotations.media.Content; +import org.eclipse.microprofile.openapi.annotations.media.Schema; +import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; +import org.eclipse.microprofile.openapi.annotations.responses.APIResponses; +import org.eclipse.microprofile.openapi.annotations.tags.Tag; + +import java.util.List; + +/** + * Interface JAX-RS pour la gestion des realms Keycloak. + */ +@Path("/api/realms") +@Produces(MediaType.APPLICATION_JSON) +@Tag(name = "Realms", description = "Gestion des realms Keycloak") +public interface RealmResourceApi { + + @GET + @Path("/list") + @Operation(summary = "Lister tous les realms", description = "Récupère la liste de tous les realms disponibles dans Keycloak") + @APIResponses({ + @APIResponse(responseCode = "200", description = "Liste des realms", content = @Content(schema = @Schema(type = org.eclipse.microprofile.openapi.annotations.enums.SchemaType.ARRAY, implementation = String.class))), + @APIResponse(responseCode = "500", description = "Erreur serveur") + }) + List getAllRealms(); + + @GET + @Path("/{realm}/clients") + @Operation(summary = "Lister les clients d'un realm", description = "Récupère la liste des clientId de tous les clients d'un realm") + @APIResponses({ + @APIResponse(responseCode = "200", description = "Liste des clients"), + @APIResponse(responseCode = "500", description = "Erreur serveur") + }) + List getRealmClients( + @Parameter(description = "Nom du realm") @PathParam("realm") String realmName); +} diff --git a/src/main/java/dev/lions/user/manager/api/RoleResourceApi.java b/src/main/java/dev/lions/user/manager/api/RoleResourceApi.java index 3e4b60b..423328a 100644 --- a/src/main/java/dev/lions/user/manager/api/RoleResourceApi.java +++ b/src/main/java/dev/lions/user/manager/api/RoleResourceApi.java @@ -1,163 +1,163 @@ -package dev.lions.user.manager.api; - -import dev.lions.user.manager.dto.role.RoleAssignmentRequestDTO; -import dev.lions.user.manager.dto.role.RoleDTO; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import jakarta.ws.rs.*; -import jakarta.ws.rs.core.MediaType; -import jakarta.ws.rs.core.Response; -import org.eclipse.microprofile.openapi.annotations.Operation; -import org.eclipse.microprofile.openapi.annotations.media.Content; -import org.eclipse.microprofile.openapi.annotations.media.Schema; -import org.eclipse.microprofile.openapi.annotations.parameters.Parameter; -import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; -import org.eclipse.microprofile.openapi.annotations.responses.APIResponses; -import org.eclipse.microprofile.openapi.annotations.tags.Tag; - -import java.util.List; - -/** - * Interface JAX-RS pour la gestion des rôles Keycloak. - */ -@Path("/api/roles") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -@Tag(name = "Roles", description = "Gestion des rôles Keycloak (realm et client)") -public interface RoleResourceApi { - - // ==================== Endpoints Realm Roles ==================== - - @POST - @Path("/realm") - @Operation(summary = "Créer un rôle realm", description = "Crée un nouveau rôle au niveau du realm") - @APIResponses({ - @APIResponse(responseCode = "201", description = "Rôle créé", content = @Content(schema = @Schema(implementation = RoleDTO.class))) - }) - Response createRealmRole( - @Valid @NotNull RoleDTO roleDTO, - @Parameter(description = "Nom du realm") @QueryParam("realm") String realmName); - - @GET - @Path("/realm/{roleName}") - @Operation(summary = "Récupérer un rôle realm par nom", description = "Récupère les détails d'un rôle realm") - RoleDTO getRealmRole( - @Parameter(description = "Nom du rôle") @PathParam("roleName") String roleName, - @Parameter(description = "Nom du realm") @QueryParam("realm") String realmName); - - @GET - @Path("/realm") - @Operation(summary = "Lister tous les rôles realm", description = "Liste tous les rôles du realm") - List getAllRealmRoles( - @Parameter(description = "Nom du realm") @QueryParam("realm") String realmName); - - @PUT - @Path("/realm/{roleName}") - @Operation(summary = "Mettre à jour un rôle realm", description = "Met à jour les informations d'un rôle realm") - RoleDTO updateRealmRole( - @PathParam("roleName") String roleName, - @Valid @NotNull RoleDTO roleDTO, - @QueryParam("realm") String realmName); - - @DELETE - @Path("/realm/{roleName}") - @Operation(summary = "Supprimer un rôle realm", description = "Supprime un rôle realm") - void deleteRealmRole( - @PathParam("roleName") String roleName, - @QueryParam("realm") String realmName); - - // ==================== Endpoints Client Roles ==================== - - @POST - @Path("/client/{clientId}") - @Operation(summary = "Créer un rôle client", description = "Crée un nouveau rôle pour un client spécifique") - @APIResponses({ - @APIResponse(responseCode = "201", description = "Rôle créé", content = @Content(schema = @Schema(implementation = RoleDTO.class))) - }) - Response createClientRole( - @PathParam("clientId") String clientId, - @Valid @NotNull RoleDTO roleDTO, - @QueryParam("realm") String realmName); - - @GET - @Path("/client/{clientId}/{roleName}") - @Operation(summary = "Récupérer un rôle client par nom", description = "Récupère les détails d'un rôle client") - RoleDTO getClientRole( - @PathParam("clientId") String clientId, - @PathParam("roleName") String roleName, - @QueryParam("realm") String realmName); - - @GET - @Path("/client/{clientId}") - @Operation(summary = "Lister tous les rôles d'un client", description = "Liste tous les rôles d'un client spécifique") - List getAllClientRoles( - @PathParam("clientId") String clientId, - @QueryParam("realm") String realmName); - - @DELETE - @Path("/client/{clientId}/{roleName}") - @Operation(summary = "Supprimer un rôle client", description = "Supprime un rôle d'un client") - void deleteClientRole( - @PathParam("clientId") String clientId, - @PathParam("roleName") String roleName, - @QueryParam("realm") String realmName); - - // ==================== Endpoints Attribution de rôles ==================== - - @POST - @Path("/assign/realm/{userId}") - @Operation(summary = "Attribuer des rôles realm à un utilisateur", description = "Assigne un ou plusieurs rôles realm à un utilisateur") - void assignRealmRoles( - @PathParam("userId") String userId, - @QueryParam("realm") String realmName, - @NotNull RoleAssignmentRequestDTO request); - - @POST - @Path("/revoke/realm/{userId}") - @Operation(summary = "Révoquer des rôles realm d'un utilisateur", description = "Révoque un ou plusieurs rôles realm d'un utilisateur") - void revokeRealmRoles( - @PathParam("userId") String userId, - @QueryParam("realm") String realmName, - @NotNull RoleAssignmentRequestDTO request); - - @POST - @Path("/assign/client/{clientId}/{userId}") - @Operation(summary = "Attribuer des rôles client à un utilisateur", description = "Assigne un ou plusieurs rôles client à un utilisateur") - void assignClientRoles( - @PathParam("clientId") String clientId, - @PathParam("userId") String userId, - @QueryParam("realm") String realmName, - @NotNull RoleAssignmentRequestDTO request); - - @GET - @Path("/user/realm/{userId}") - @Operation(summary = "Récupérer les rôles realm d'un utilisateur", description = "Liste tous les rôles realm d'un utilisateur") - List getUserRealmRoles( - @PathParam("userId") String userId, - @QueryParam("realm") String realmName); - - @GET - @Path("/user/client/{clientId}/{userId}") - @Operation(summary = "Récupérer les rôles client d'un utilisateur", description = "Liste tous les rôles client d'un utilisateur") - List getUserClientRoles( - @PathParam("clientId") String clientId, - @PathParam("userId") String userId, - @QueryParam("realm") String realmName); - - // ==================== Endpoints Rôles composites ==================== - - @POST - @Path("/composite/{roleName}/add") - @Operation(summary = "Ajouter des rôles composites", description = "Ajoute des rôles composites à un rôle") - void addComposites( - @PathParam("roleName") String roleName, - @QueryParam("realm") String realmName, - @NotNull RoleAssignmentRequestDTO request); - - @GET - @Path("/composite/{roleName}") - @Operation(summary = "Récupérer les rôles composites", description = "Liste tous les rôles composites d'un rôle") - List getComposites( - @PathParam("roleName") String roleName, - @QueryParam("realm") String realmName); -} +package dev.lions.user.manager.api; + +import dev.lions.user.manager.dto.role.RoleAssignmentRequestDTO; +import dev.lions.user.manager.dto.role.RoleDTO; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import jakarta.ws.rs.*; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import org.eclipse.microprofile.openapi.annotations.Operation; +import org.eclipse.microprofile.openapi.annotations.media.Content; +import org.eclipse.microprofile.openapi.annotations.media.Schema; +import org.eclipse.microprofile.openapi.annotations.parameters.Parameter; +import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; +import org.eclipse.microprofile.openapi.annotations.responses.APIResponses; +import org.eclipse.microprofile.openapi.annotations.tags.Tag; + +import java.util.List; + +/** + * Interface JAX-RS pour la gestion des rôles Keycloak. + */ +@Path("/api/roles") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@Tag(name = "Roles", description = "Gestion des rôles Keycloak (realm et client)") +public interface RoleResourceApi { + + // ==================== Endpoints Realm Roles ==================== + + @POST + @Path("/realm") + @Operation(summary = "Créer un rôle realm", description = "Crée un nouveau rôle au niveau du realm") + @APIResponses({ + @APIResponse(responseCode = "201", description = "Rôle créé", content = @Content(schema = @Schema(implementation = RoleDTO.class))) + }) + Response createRealmRole( + @Valid @NotNull RoleDTO roleDTO, + @Parameter(description = "Nom du realm") @QueryParam("realm") String realmName); + + @GET + @Path("/realm/{roleName}") + @Operation(summary = "Récupérer un rôle realm par nom", description = "Récupère les détails d'un rôle realm") + RoleDTO getRealmRole( + @Parameter(description = "Nom du rôle") @PathParam("roleName") String roleName, + @Parameter(description = "Nom du realm") @QueryParam("realm") String realmName); + + @GET + @Path("/realm") + @Operation(summary = "Lister tous les rôles realm", description = "Liste tous les rôles du realm") + List getAllRealmRoles( + @Parameter(description = "Nom du realm") @QueryParam("realm") String realmName); + + @PUT + @Path("/realm/{roleName}") + @Operation(summary = "Mettre à jour un rôle realm", description = "Met à jour les informations d'un rôle realm") + RoleDTO updateRealmRole( + @PathParam("roleName") String roleName, + @Valid @NotNull RoleDTO roleDTO, + @QueryParam("realm") String realmName); + + @DELETE + @Path("/realm/{roleName}") + @Operation(summary = "Supprimer un rôle realm", description = "Supprime un rôle realm") + void deleteRealmRole( + @PathParam("roleName") String roleName, + @QueryParam("realm") String realmName); + + // ==================== Endpoints Client Roles ==================== + + @POST + @Path("/client/{clientId}") + @Operation(summary = "Créer un rôle client", description = "Crée un nouveau rôle pour un client spécifique") + @APIResponses({ + @APIResponse(responseCode = "201", description = "Rôle créé", content = @Content(schema = @Schema(implementation = RoleDTO.class))) + }) + Response createClientRole( + @PathParam("clientId") String clientId, + @Valid @NotNull RoleDTO roleDTO, + @QueryParam("realm") String realmName); + + @GET + @Path("/client/{clientId}/{roleName}") + @Operation(summary = "Récupérer un rôle client par nom", description = "Récupère les détails d'un rôle client") + RoleDTO getClientRole( + @PathParam("clientId") String clientId, + @PathParam("roleName") String roleName, + @QueryParam("realm") String realmName); + + @GET + @Path("/client/{clientId}") + @Operation(summary = "Lister tous les rôles d'un client", description = "Liste tous les rôles d'un client spécifique") + List getAllClientRoles( + @PathParam("clientId") String clientId, + @QueryParam("realm") String realmName); + + @DELETE + @Path("/client/{clientId}/{roleName}") + @Operation(summary = "Supprimer un rôle client", description = "Supprime un rôle d'un client") + void deleteClientRole( + @PathParam("clientId") String clientId, + @PathParam("roleName") String roleName, + @QueryParam("realm") String realmName); + + // ==================== Endpoints Attribution de rôles ==================== + + @POST + @Path("/assign/realm/{userId}") + @Operation(summary = "Attribuer des rôles realm à un utilisateur", description = "Assigne un ou plusieurs rôles realm à un utilisateur") + void assignRealmRoles( + @PathParam("userId") String userId, + @QueryParam("realm") String realmName, + @NotNull RoleAssignmentRequestDTO request); + + @POST + @Path("/revoke/realm/{userId}") + @Operation(summary = "Révoquer des rôles realm d'un utilisateur", description = "Révoque un ou plusieurs rôles realm d'un utilisateur") + void revokeRealmRoles( + @PathParam("userId") String userId, + @QueryParam("realm") String realmName, + @NotNull RoleAssignmentRequestDTO request); + + @POST + @Path("/assign/client/{clientId}/{userId}") + @Operation(summary = "Attribuer des rôles client à un utilisateur", description = "Assigne un ou plusieurs rôles client à un utilisateur") + void assignClientRoles( + @PathParam("clientId") String clientId, + @PathParam("userId") String userId, + @QueryParam("realm") String realmName, + @NotNull RoleAssignmentRequestDTO request); + + @GET + @Path("/user/realm/{userId}") + @Operation(summary = "Récupérer les rôles realm d'un utilisateur", description = "Liste tous les rôles realm d'un utilisateur") + List getUserRealmRoles( + @PathParam("userId") String userId, + @QueryParam("realm") String realmName); + + @GET + @Path("/user/client/{clientId}/{userId}") + @Operation(summary = "Récupérer les rôles client d'un utilisateur", description = "Liste tous les rôles client d'un utilisateur") + List getUserClientRoles( + @PathParam("clientId") String clientId, + @PathParam("userId") String userId, + @QueryParam("realm") String realmName); + + // ==================== Endpoints Rôles composites ==================== + + @POST + @Path("/composite/{roleName}/add") + @Operation(summary = "Ajouter des rôles composites", description = "Ajoute des rôles composites à un rôle") + void addComposites( + @PathParam("roleName") String roleName, + @QueryParam("realm") String realmName, + @NotNull RoleAssignmentRequestDTO request); + + @GET + @Path("/composite/{roleName}") + @Operation(summary = "Récupérer les rôles composites", description = "Liste tous les rôles composites d'un rôle") + List getComposites( + @PathParam("roleName") String roleName, + @QueryParam("realm") String realmName); +} diff --git a/src/main/java/dev/lions/user/manager/api/SyncResourceApi.java b/src/main/java/dev/lions/user/manager/api/SyncResourceApi.java index 45d4670..8bf0717 100644 --- a/src/main/java/dev/lions/user/manager/api/SyncResourceApi.java +++ b/src/main/java/dev/lions/user/manager/api/SyncResourceApi.java @@ -1,54 +1,54 @@ -package dev.lions.user.manager.api; - -import dev.lions.user.manager.dto.sync.HealthStatusDTO; -import dev.lions.user.manager.dto.sync.SyncConsistencyDTO; -import dev.lions.user.manager.dto.sync.SyncHistoryDTO; -import dev.lions.user.manager.dto.sync.SyncResultDTO; -import jakarta.ws.rs.*; -import jakarta.ws.rs.core.MediaType; -import org.eclipse.microprofile.openapi.annotations.Operation; -import org.eclipse.microprofile.openapi.annotations.tags.Tag; - -/** - * Interface JAX-RS définissant le contrat de l'API de synchronisation. - * Cette interface doit être implémentée par le serveur et utilisée par le - * client (via MicroProfile Rest Client). - */ -@Path("/api/sync") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -@Tag(name = "Sync", description = "Synchronisation avec Keycloak et health checks") -public interface SyncResourceApi { - - @GET - @Path("/health/keycloak") - @Operation(summary = "Vérifier la santé de Keycloak", description = "Retourne le statut de santé de Keycloak") - HealthStatusDTO checkKeycloakHealth(); - - @POST - @Path("/users") - @Operation(summary = "Synchroniser les utilisateurs", description = "Synchronise tous les utilisateurs depuis Keycloak") - SyncResultDTO syncUsers(@QueryParam("realm") String realmName); - - @POST - @Path("/roles") - @Operation(summary = "Synchroniser les rôles", description = "Synchronise les rôles (realm et/ou client)") - SyncResultDTO syncRoles( - @QueryParam("realm") String realmName, - @QueryParam("clientName") String clientName); - - @GET - @Path("/consistency") - @Operation(summary = "Vérifier la cohérence des données", description = "Compare le cache local et Keycloak pour un realm") - SyncConsistencyDTO checkDataConsistency(@QueryParam("realm") String realmName); - - @GET - @Path("/status") - @Operation(summary = "Statut de la dernière synchro", description = "Retourne le statut de la dernière synchronisation du realm") - SyncHistoryDTO getLastSyncStatus(@QueryParam("realm") String realmName); - - @POST - @Path("/force") - @Operation(summary = "Forcer une synchro", description = "Lance une synchronisation complète du realm (users + roles)") - SyncHistoryDTO forceSyncRealm(@QueryParam("realm") String realmName); -} +package dev.lions.user.manager.api; + +import dev.lions.user.manager.dto.sync.HealthStatusDTO; +import dev.lions.user.manager.dto.sync.SyncConsistencyDTO; +import dev.lions.user.manager.dto.sync.SyncHistoryDTO; +import dev.lions.user.manager.dto.sync.SyncResultDTO; +import jakarta.ws.rs.*; +import jakarta.ws.rs.core.MediaType; +import org.eclipse.microprofile.openapi.annotations.Operation; +import org.eclipse.microprofile.openapi.annotations.tags.Tag; + +/** + * Interface JAX-RS définissant le contrat de l'API de synchronisation. + * Cette interface doit être implémentée par le serveur et utilisée par le + * client (via MicroProfile Rest Client). + */ +@Path("/api/sync") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@Tag(name = "Sync", description = "Synchronisation avec Keycloak et health checks") +public interface SyncResourceApi { + + @GET + @Path("/health/keycloak") + @Operation(summary = "Vérifier la santé de Keycloak", description = "Retourne le statut de santé de Keycloak") + HealthStatusDTO checkKeycloakHealth(); + + @POST + @Path("/users") + @Operation(summary = "Synchroniser les utilisateurs", description = "Synchronise tous les utilisateurs depuis Keycloak") + SyncResultDTO syncUsers(@QueryParam("realm") String realmName); + + @POST + @Path("/roles") + @Operation(summary = "Synchroniser les rôles", description = "Synchronise les rôles (realm et/ou client)") + SyncResultDTO syncRoles( + @QueryParam("realm") String realmName, + @QueryParam("clientName") String clientName); + + @GET + @Path("/consistency") + @Operation(summary = "Vérifier la cohérence des données", description = "Compare le cache local et Keycloak pour un realm") + SyncConsistencyDTO checkDataConsistency(@QueryParam("realm") String realmName); + + @GET + @Path("/status") + @Operation(summary = "Statut de la dernière synchro", description = "Retourne le statut de la dernière synchronisation du realm") + SyncHistoryDTO getLastSyncStatus(@QueryParam("realm") String realmName); + + @POST + @Path("/force") + @Operation(summary = "Forcer une synchro", description = "Lance une synchronisation complète du realm (users + roles)") + SyncHistoryDTO forceSyncRealm(@QueryParam("realm") String realmName); +} diff --git a/src/main/java/dev/lions/user/manager/api/UserMetricsResourceApi.java b/src/main/java/dev/lions/user/manager/api/UserMetricsResourceApi.java index 90e5d80..0bf4fda 100644 --- a/src/main/java/dev/lions/user/manager/api/UserMetricsResourceApi.java +++ b/src/main/java/dev/lions/user/manager/api/UserMetricsResourceApi.java @@ -1,32 +1,32 @@ -package dev.lions.user.manager.api; - -import dev.lions.user.manager.dto.common.UserSessionStatsDTO; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.Produces; -import jakarta.ws.rs.QueryParam; -import jakarta.ws.rs.core.MediaType; -import org.eclipse.microprofile.openapi.annotations.Operation; -import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; -import org.eclipse.microprofile.openapi.annotations.responses.APIResponses; -import org.eclipse.microprofile.openapi.annotations.tags.Tag; - -/** - * API de métriques liées aux utilisateurs (sessions, utilisateurs en ligne, etc.). - */ -@Path("/api/metrics/users") -@Produces(MediaType.APPLICATION_JSON) -@Tag(name = "User Metrics", description = "Statistiques sur les utilisateurs et leurs sessions") -public interface UserMetricsResourceApi { - - @GET - @Path("/sessions") - @Operation(summary = "Statistiques de sessions utilisateurs", - description = "Retourne des statistiques agrégées sur les utilisateurs et leurs sessions pour un realm") - @APIResponses({ - @APIResponse(responseCode = "200", description = "Statistiques retournées avec succès"), - @APIResponse(responseCode = "500", description = "Erreur serveur") - }) - UserSessionStatsDTO getUserSessionStats(@QueryParam("realm") String realmName); -} - +package dev.lions.user.manager.api; + +import dev.lions.user.manager.dto.common.UserSessionStatsDTO; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.QueryParam; +import jakarta.ws.rs.core.MediaType; +import org.eclipse.microprofile.openapi.annotations.Operation; +import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; +import org.eclipse.microprofile.openapi.annotations.responses.APIResponses; +import org.eclipse.microprofile.openapi.annotations.tags.Tag; + +/** + * API de métriques liées aux utilisateurs (sessions, utilisateurs en ligne, etc.). + */ +@Path("/api/metrics/users") +@Produces(MediaType.APPLICATION_JSON) +@Tag(name = "User Metrics", description = "Statistiques sur les utilisateurs et leurs sessions") +public interface UserMetricsResourceApi { + + @GET + @Path("/sessions") + @Operation(summary = "Statistiques de sessions utilisateurs", + description = "Retourne des statistiques agrégées sur les utilisateurs et leurs sessions pour un realm") + @APIResponses({ + @APIResponse(responseCode = "200", description = "Statistiques retournées avec succès"), + @APIResponse(responseCode = "500", description = "Erreur serveur") + }) + UserSessionStatsDTO getUserSessionStats(@QueryParam("realm") String realmName); +} + diff --git a/src/main/java/dev/lions/user/manager/api/UserResourceApi.java b/src/main/java/dev/lions/user/manager/api/UserResourceApi.java index f1124aa..a5526f4 100644 --- a/src/main/java/dev/lions/user/manager/api/UserResourceApi.java +++ b/src/main/java/dev/lions/user/manager/api/UserResourceApi.java @@ -1,138 +1,138 @@ -package dev.lions.user.manager.api; - -import dev.lions.user.manager.dto.importexport.ImportResultDTO; -import dev.lions.user.manager.dto.user.*; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import jakarta.ws.rs.*; -import jakarta.ws.rs.core.MediaType; -import jakarta.ws.rs.core.Response; -import org.eclipse.microprofile.openapi.annotations.Operation; -import org.eclipse.microprofile.openapi.annotations.media.Content; -import org.eclipse.microprofile.openapi.annotations.media.Schema; -import org.eclipse.microprofile.openapi.annotations.parameters.Parameter; -import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; -import org.eclipse.microprofile.openapi.annotations.responses.APIResponses; -import org.eclipse.microprofile.openapi.annotations.tags.Tag; - -import java.util.List; - -/** - * Interface JAX-RS pour la gestion des utilisateurs. - */ -@Path("/api/users") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -@Tag(name = "Users", description = "Gestion des utilisateurs Keycloak") -public interface UserResourceApi { - - @POST - @Path("/search") - @Operation(summary = "Rechercher des utilisateurs", description = "Recherche d'utilisateurs selon des critères") - UserSearchResultDTO searchUsers(@Valid @NotNull UserSearchCriteriaDTO criteria); - - @GET - @Path("/{userId}") - @Operation(summary = "Récupérer un utilisateur par ID", description = "Récupère les détails d'un utilisateur") - UserDTO getUserById( - @Parameter(description = "ID de l'utilisateur") @PathParam("userId") String userId, - @Parameter(description = "Nom du realm") @QueryParam("realm") String realmName); - - @GET - @Operation(summary = "Lister tous les utilisateurs", description = "Liste paginée de tous les utilisateurs") - UserSearchResultDTO getAllUsers( - @QueryParam("realm") String realmName, - @QueryParam("page") @DefaultValue("0") int page, - @QueryParam("pageSize") @DefaultValue("20") int pageSize); - - @POST - @Operation(summary = "Créer un utilisateur", description = "Crée un nouvel utilisateur dans Keycloak") - @APIResponses({ - @APIResponse(responseCode = "201", description = "Utilisateur créé", content = @Content(schema = @Schema(implementation = UserDTO.class))) - }) - Response createUser( - @Valid @NotNull UserDTO user, - @QueryParam("realm") String realmName); - - @PUT - @Path("/{userId}") - @Operation(summary = "Mettre à jour un utilisateur", description = "Met à jour les informations d'un utilisateur") - UserDTO updateUser( - @PathParam("userId") String userId, - @Valid @NotNull UserDTO user, - @QueryParam("realm") String realmName); - - @DELETE - @Path("/{userId}") - @Operation(summary = "Supprimer un utilisateur", description = "Supprime un utilisateur (soft ou hard delete)") - void deleteUser( - @PathParam("userId") String userId, - @QueryParam("realm") String realmName, - @QueryParam("hardDelete") @DefaultValue("false") boolean hardDelete); - - @POST - @Path("/{userId}/activate") - @Operation(summary = "Activer un utilisateur", description = "Active un utilisateur désactivé") - void activateUser( - @PathParam("userId") String userId, - @QueryParam("realm") String realmName); - - @POST - @Path("/{userId}/deactivate") - @Operation(summary = "Désactiver un utilisateur", description = "Désactive un utilisateur") - void deactivateUser( - @PathParam("userId") String userId, - @QueryParam("realm") String realmName, - @QueryParam("raison") String raison); - - @POST - @Path("/{userId}/reset-password") - @Operation(summary = "Réinitialiser le mot de passe", description = "Définit un nouveau mot de passe pour l'utilisateur") - void resetPassword( - @PathParam("userId") String userId, - @QueryParam("realm") String realmName, - @NotNull PasswordResetRequestDTO request); - - @POST - @Path("/{userId}/send-verification-email") - @Operation(summary = "Envoyer email de vérification", description = "Envoie un email de vérification à l'utilisateur") - @APIResponses({ - @APIResponse(responseCode = "202", description = "Demande acceptée (email envoyé ou tentative effectuée)"), - @APIResponse(responseCode = "404", description = "Utilisateur non trouvé") - }) - Response sendVerificationEmail( - @PathParam("userId") String userId, - @QueryParam("realm") String realmName); - - @POST - @Path("/{userId}/logout-sessions") - @Operation(summary = "Déconnecter toutes les sessions", description = "Révoque toutes les sessions actives de l'utilisateur") - SessionsRevokedDTO logoutAllSessions( - @PathParam("userId") String userId, - @QueryParam("realm") String realmName); - - @GET - @Path("/{userId}/sessions") - @Operation(summary = "Récupérer les sessions actives", description = "Liste les sessions actives de l'utilisateur") - @APIResponses({ - @APIResponse(responseCode = "200", description = "Liste des sessions", content = @Content(schema = @Schema(type = org.eclipse.microprofile.openapi.annotations.enums.SchemaType.ARRAY, implementation = String.class))) - }) - List getActiveSessions( - @PathParam("userId") String userId, - @QueryParam("realm") String realmName); - - @GET - @Path("/export/csv") - @Produces("text/csv") - @Operation(summary = "Exporter les utilisateurs en CSV", description = "Exporte la liste des utilisateurs du realm au format CSV") - Response exportUsersToCSV(@QueryParam("realm") String realmName); - - @POST - @Path("/import/csv") - @Consumes(MediaType.TEXT_PLAIN) - @Produces(MediaType.APPLICATION_JSON) - @Operation(summary = "Importer des utilisateurs depuis un CSV", description = "Importe des utilisateurs à partir d'un fichier CSV") - ImportResultDTO importUsersFromCSV( - @QueryParam("realm") String realmName, - String csvContent); -} +package dev.lions.user.manager.api; + +import dev.lions.user.manager.dto.importexport.ImportResultDTO; +import dev.lions.user.manager.dto.user.*; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import jakarta.ws.rs.*; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import org.eclipse.microprofile.openapi.annotations.Operation; +import org.eclipse.microprofile.openapi.annotations.media.Content; +import org.eclipse.microprofile.openapi.annotations.media.Schema; +import org.eclipse.microprofile.openapi.annotations.parameters.Parameter; +import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; +import org.eclipse.microprofile.openapi.annotations.responses.APIResponses; +import org.eclipse.microprofile.openapi.annotations.tags.Tag; + +import java.util.List; + +/** + * Interface JAX-RS pour la gestion des utilisateurs. + */ +@Path("/api/users") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@Tag(name = "Users", description = "Gestion des utilisateurs Keycloak") +public interface UserResourceApi { + + @POST + @Path("/search") + @Operation(summary = "Rechercher des utilisateurs", description = "Recherche d'utilisateurs selon des critères") + UserSearchResultDTO searchUsers(@Valid @NotNull UserSearchCriteriaDTO criteria); + + @GET + @Path("/{userId}") + @Operation(summary = "Récupérer un utilisateur par ID", description = "Récupère les détails d'un utilisateur") + UserDTO getUserById( + @Parameter(description = "ID de l'utilisateur") @PathParam("userId") String userId, + @Parameter(description = "Nom du realm") @QueryParam("realm") String realmName); + + @GET + @Operation(summary = "Lister tous les utilisateurs", description = "Liste paginée de tous les utilisateurs") + UserSearchResultDTO getAllUsers( + @QueryParam("realm") String realmName, + @QueryParam("page") @DefaultValue("0") int page, + @QueryParam("pageSize") @DefaultValue("20") int pageSize); + + @POST + @Operation(summary = "Créer un utilisateur", description = "Crée un nouvel utilisateur dans Keycloak") + @APIResponses({ + @APIResponse(responseCode = "201", description = "Utilisateur créé", content = @Content(schema = @Schema(implementation = UserDTO.class))) + }) + Response createUser( + @Valid @NotNull UserDTO user, + @QueryParam("realm") String realmName); + + @PUT + @Path("/{userId}") + @Operation(summary = "Mettre à jour un utilisateur", description = "Met à jour les informations d'un utilisateur") + UserDTO updateUser( + @PathParam("userId") String userId, + @Valid @NotNull UserDTO user, + @QueryParam("realm") String realmName); + + @DELETE + @Path("/{userId}") + @Operation(summary = "Supprimer un utilisateur", description = "Supprime un utilisateur (soft ou hard delete)") + void deleteUser( + @PathParam("userId") String userId, + @QueryParam("realm") String realmName, + @QueryParam("hardDelete") @DefaultValue("false") boolean hardDelete); + + @POST + @Path("/{userId}/activate") + @Operation(summary = "Activer un utilisateur", description = "Active un utilisateur désactivé") + void activateUser( + @PathParam("userId") String userId, + @QueryParam("realm") String realmName); + + @POST + @Path("/{userId}/deactivate") + @Operation(summary = "Désactiver un utilisateur", description = "Désactive un utilisateur") + void deactivateUser( + @PathParam("userId") String userId, + @QueryParam("realm") String realmName, + @QueryParam("raison") String raison); + + @POST + @Path("/{userId}/reset-password") + @Operation(summary = "Réinitialiser le mot de passe", description = "Définit un nouveau mot de passe pour l'utilisateur") + void resetPassword( + @PathParam("userId") String userId, + @QueryParam("realm") String realmName, + @NotNull PasswordResetRequestDTO request); + + @POST + @Path("/{userId}/send-verification-email") + @Operation(summary = "Envoyer email de vérification", description = "Envoie un email de vérification à l'utilisateur") + @APIResponses({ + @APIResponse(responseCode = "202", description = "Demande acceptée (email envoyé ou tentative effectuée)"), + @APIResponse(responseCode = "404", description = "Utilisateur non trouvé") + }) + Response sendVerificationEmail( + @PathParam("userId") String userId, + @QueryParam("realm") String realmName); + + @POST + @Path("/{userId}/logout-sessions") + @Operation(summary = "Déconnecter toutes les sessions", description = "Révoque toutes les sessions actives de l'utilisateur") + SessionsRevokedDTO logoutAllSessions( + @PathParam("userId") String userId, + @QueryParam("realm") String realmName); + + @GET + @Path("/{userId}/sessions") + @Operation(summary = "Récupérer les sessions actives", description = "Liste les sessions actives de l'utilisateur") + @APIResponses({ + @APIResponse(responseCode = "200", description = "Liste des sessions", content = @Content(schema = @Schema(type = org.eclipse.microprofile.openapi.annotations.enums.SchemaType.ARRAY, implementation = String.class))) + }) + List getActiveSessions( + @PathParam("userId") String userId, + @QueryParam("realm") String realmName); + + @GET + @Path("/export/csv") + @Produces("text/csv") + @Operation(summary = "Exporter les utilisateurs en CSV", description = "Exporte la liste des utilisateurs du realm au format CSV") + Response exportUsersToCSV(@QueryParam("realm") String realmName); + + @POST + @Path("/import/csv") + @Consumes(MediaType.TEXT_PLAIN) + @Produces(MediaType.APPLICATION_JSON) + @Operation(summary = "Importer des utilisateurs depuis un CSV", description = "Importe des utilisateurs à partir d'un fichier CSV") + ImportResultDTO importUsersFromCSV( + @QueryParam("realm") String realmName, + String csvContent); +} diff --git a/src/main/java/dev/lions/user/manager/dto/audit/AuditLogDTO.java b/src/main/java/dev/lions/user/manager/dto/audit/AuditLogDTO.java index 5c42f39..51b7f15 100644 --- a/src/main/java/dev/lions/user/manager/dto/audit/AuditLogDTO.java +++ b/src/main/java/dev/lions/user/manager/dto/audit/AuditLogDTO.java @@ -1,178 +1,178 @@ -package dev.lions.user.manager.dto.audit; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonInclude; -import dev.lions.user.manager.dto.base.BaseDTO; -import dev.lions.user.manager.enums.audit.TypeActionAudit; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; -import lombok.experimental.SuperBuilder; -import org.eclipse.microprofile.openapi.annotations.media.Schema; - -import java.time.LocalDateTime; -import java.util.Map; - -/** - * DTO représentant une entrée d'audit - * Enregistre toutes les actions effectuées via l'API de gestion - */ -@Data -@SuperBuilder -@NoArgsConstructor -@AllArgsConstructor -@EqualsAndHashCode(callSuper = true) -@JsonInclude(JsonInclude.Include.NON_NULL) -@Schema(description = "Entrée d'audit des actions utilisateur") -public class AuditLogDTO extends BaseDTO { - - private static final long serialVersionUID = 1L; - - // Qui a fait l'action - @Schema(description = "ID de l'utilisateur qui a effectué l'action", example = "f47ac10b-58cc-4372-a567-0e02b2c3d479") - private String acteurUserId; - - @Schema(description = "Username de l'utilisateur qui a effectué l'action", example = "admin@lions.dev") - private String acteurUsername; - - @Schema(description = "Nom complet de l'acteur", example = "Admin Principal") - private String acteurNomComplet; - - @Schema(description = "Rôles de l'acteur au moment de l'action") - private String acteurRoles; - - // Quand - @Schema(description = "Date et heure de l'action", example = "2025-01-15T10:30:00") - @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") - private LocalDateTime dateAction; - - // Quoi - @Schema(description = "Type d'action effectuée", example = "USER_CREATE") - private TypeActionAudit typeAction; - - @Schema(description = "Type de ressource affectée", example = "USER") - private String ressourceType; - - @Schema(description = "ID de la ressource affectée", example = "a1b2c3d4-e5f6-7890-1234-567890abcdef") - private String ressourceId; - - @Schema(description = "Nom/Identifiant de la ressource", example = "jdupont") - private String ressourceName; - - // Où - @Schema(description = "Nom du Realm", example = "btpxpress") - private String realmName; - - @Schema(description = "Adresse IP de l'acteur", example = "192.168.1.100") - private String ipAddress; - - @Schema(description = "User-Agent du client", example = "Mozilla/5.0...") - private String userAgent; - - @Schema(description = "Localisation géographique", example = "Abidjan, Côte d'Ivoire") - private String geolocation; - - // Comment - @Schema(description = "Endpoint API appelé", example = "/api/users/create") - private String apiEndpoint; - - @Schema(description = "Méthode HTTP", example = "POST") - private String httpMethod; - - // Détails - @Schema(description = "Description de l'action", example = "Création d'un nouvel utilisateur") - private String description; - - @Schema(description = "Détails de l'action au format JSON") - private String detailsJson; - - @Schema(description = "Ancienne valeur (avant modification)") - private String oldValue; - - @Schema(description = "Nouvelle valeur (après modification)") - private String newValue; - - @Schema(description = "Différences entre ancienne et nouvelle valeur") - private String diff; - - // Résultat - @Schema(description = "Succès de l'opération", example = "true") - private Boolean success; - - @Schema(description = "Code d'erreur (si échec)", example = "USER_ALREADY_EXISTS") - private String errorCode; - - @Schema(description = "Message d'erreur (si échec)") - private String errorMessage; - - @Schema(description = "Trace d'erreur complète (si échec)") - private String stackTrace; - - // Métadonnées - @Schema(description = "Durée d'exécution en millisecondes", example = "145") - private Long executionTimeMs; - - @Schema(description = "ID de session/transaction", example = "sess_abc123") - private String sessionId; - - @Schema(description = "ID de corrélation (pour tracer requêtes liées)", example = "corr_xyz789") - private String correlationId; - - @Schema(description = "Raison de l'action", example = "Demande du manager") - private String raison; - - @Schema(description = "Commentaires administratifs", example = "Promotion suite à évaluation annuelle") - private String commentaires; - - @Schema(description = "Métadonnées supplémentaires") - private Map metadata; - - // Flags - @Schema(description = "Indique si l'action est critique", example = "false") - private Boolean critique; - - @Schema(description = "Indique si l'action nécessite une alerte", example = "false") - private Boolean requiresAlert; - - @Schema(description = "Indique si l'action a été notifiée", example = "true") - private Boolean notified; - - /** - * Détermine si l'action a réussi - * @return true si success = true - */ - public boolean isSuccessful() { - return Boolean.TRUE.equals(success); - } - - /** - * Détermine si l'action a échoué - * @return true si success = false - */ - public boolean isFailed() { - return Boolean.FALSE.equals(success); - } - - /** - * Détermine si l'action est critique - * @return true si critique = true ou si typeAction est critique - */ - public boolean isCritique() { - return Boolean.TRUE.equals(critique) || (typeAction != null && typeAction.isCritical()); - } - - /** - * Retourne un résumé court de l'action - * @return résumé - */ - public String getSummary() { - return String.format("%s: %s effectué par %s sur %s %s", - dateAction, - typeAction != null ? typeAction.getLibelle() : "Action inconnue", - acteurUsername != null ? acteurUsername : "Inconnu", - ressourceType != null ? ressourceType : "Ressource", - ressourceName != null ? ressourceName : ressourceId - ); - } -} +package dev.lions.user.manager.dto.audit; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonInclude; +import dev.lions.user.manager.dto.base.BaseDTO; +import dev.lions.user.manager.enums.audit.TypeActionAudit; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; +import org.eclipse.microprofile.openapi.annotations.media.Schema; + +import java.time.LocalDateTime; +import java.util.Map; + +/** + * DTO représentant une entrée d'audit + * Enregistre toutes les actions effectuées via l'API de gestion + */ +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +@Schema(description = "Entrée d'audit des actions utilisateur") +public class AuditLogDTO extends BaseDTO { + + private static final long serialVersionUID = 1L; + + // Qui a fait l'action + @Schema(description = "ID de l'utilisateur qui a effectué l'action", example = "f47ac10b-58cc-4372-a567-0e02b2c3d479") + private String acteurUserId; + + @Schema(description = "Username de l'utilisateur qui a effectué l'action", example = "admin@lions.dev") + private String acteurUsername; + + @Schema(description = "Nom complet de l'acteur", example = "Admin Principal") + private String acteurNomComplet; + + @Schema(description = "Rôles de l'acteur au moment de l'action") + private String acteurRoles; + + // Quand + @Schema(description = "Date et heure de l'action", example = "2025-01-15T10:30:00") + @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") + private LocalDateTime dateAction; + + // Quoi + @Schema(description = "Type d'action effectuée", example = "USER_CREATE") + private TypeActionAudit typeAction; + + @Schema(description = "Type de ressource affectée", example = "USER") + private String ressourceType; + + @Schema(description = "ID de la ressource affectée", example = "a1b2c3d4-e5f6-7890-1234-567890abcdef") + private String ressourceId; + + @Schema(description = "Nom/Identifiant de la ressource", example = "jdupont") + private String ressourceName; + + // Où + @Schema(description = "Nom du Realm", example = "btpxpress") + private String realmName; + + @Schema(description = "Adresse IP de l'acteur", example = "192.168.1.100") + private String ipAddress; + + @Schema(description = "User-Agent du client", example = "Mozilla/5.0...") + private String userAgent; + + @Schema(description = "Localisation géographique", example = "Abidjan, Côte d'Ivoire") + private String geolocation; + + // Comment + @Schema(description = "Endpoint API appelé", example = "/api/users/create") + private String apiEndpoint; + + @Schema(description = "Méthode HTTP", example = "POST") + private String httpMethod; + + // Détails + @Schema(description = "Description de l'action", example = "Création d'un nouvel utilisateur") + private String description; + + @Schema(description = "Détails de l'action au format JSON") + private String detailsJson; + + @Schema(description = "Ancienne valeur (avant modification)") + private String oldValue; + + @Schema(description = "Nouvelle valeur (après modification)") + private String newValue; + + @Schema(description = "Différences entre ancienne et nouvelle valeur") + private String diff; + + // Résultat + @Schema(description = "Succès de l'opération", example = "true") + private Boolean success; + + @Schema(description = "Code d'erreur (si échec)", example = "USER_ALREADY_EXISTS") + private String errorCode; + + @Schema(description = "Message d'erreur (si échec)") + private String errorMessage; + + @Schema(description = "Trace d'erreur complète (si échec)") + private String stackTrace; + + // Métadonnées + @Schema(description = "Durée d'exécution en millisecondes", example = "145") + private Long executionTimeMs; + + @Schema(description = "ID de session/transaction", example = "sess_abc123") + private String sessionId; + + @Schema(description = "ID de corrélation (pour tracer requêtes liées)", example = "corr_xyz789") + private String correlationId; + + @Schema(description = "Raison de l'action", example = "Demande du manager") + private String raison; + + @Schema(description = "Commentaires administratifs", example = "Promotion suite à évaluation annuelle") + private String commentaires; + + @Schema(description = "Métadonnées supplémentaires") + private Map metadata; + + // Flags + @Schema(description = "Indique si l'action est critique", example = "false") + private Boolean critique; + + @Schema(description = "Indique si l'action nécessite une alerte", example = "false") + private Boolean requiresAlert; + + @Schema(description = "Indique si l'action a été notifiée", example = "true") + private Boolean notified; + + /** + * Détermine si l'action a réussi + * @return true si success = true + */ + public boolean isSuccessful() { + return Boolean.TRUE.equals(success); + } + + /** + * Détermine si l'action a échoué + * @return true si success = false + */ + public boolean isFailed() { + return Boolean.FALSE.equals(success); + } + + /** + * Détermine si l'action est critique + * @return true si critique = true ou si typeAction est critique + */ + public boolean isCritique() { + return Boolean.TRUE.equals(critique) || (typeAction != null && typeAction.isCritical()); + } + + /** + * Retourne un résumé court de l'action + * @return résumé + */ + public String getSummary() { + return String.format("%s: %s effectué par %s sur %s %s", + dateAction, + typeAction != null ? typeAction.getLibelle() : "Action inconnue", + acteurUsername != null ? acteurUsername : "Inconnu", + ressourceType != null ? ressourceType : "Ressource", + ressourceName != null ? ressourceName : ressourceId + ); + } +} diff --git a/src/main/java/dev/lions/user/manager/dto/base/BaseDTO.java b/src/main/java/dev/lions/user/manager/dto/base/BaseDTO.java index cbfae0b..39825ff 100644 --- a/src/main/java/dev/lions/user/manager/dto/base/BaseDTO.java +++ b/src/main/java/dev/lions/user/manager/dto/base/BaseDTO.java @@ -1,47 +1,47 @@ -package dev.lions.user.manager.dto.base; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonInclude; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.experimental.SuperBuilder; -import org.eclipse.microprofile.openapi.annotations.media.Schema; - -import java.io.Serializable; -import java.time.LocalDateTime; - -/** - * DTO de base pour tous les objets métier - * Contient les attributs communs (id, dates, audit) - */ -@Data -@SuperBuilder -@NoArgsConstructor -@AllArgsConstructor -@JsonInclude(JsonInclude.Include.NON_NULL) -@Schema(description = "DTO de base contenant les attributs communs à tous les objets") -public abstract class BaseDTO implements Serializable { - - private static final long serialVersionUID = 1L; - - @Schema(description = "Identifiant unique (UUID Keycloak)", example = "f47ac10b-58cc-4372-a567-0e02b2c3d479") - private String id; - - @Schema(description = "Date de création", example = "2025-01-15T10:30:00") - @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") - private LocalDateTime dateCreation; - - @Schema(description = "Date de dernière modification", example = "2025-01-15T14:20:00") - @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") - private LocalDateTime dateModification; - - @Schema(description = "Utilisateur ayant créé l'entité", example = "admin@lions.dev") - private String creeParUsername; - - @Schema(description = "Utilisateur ayant modifié l'entité", example = "superadmin@lions.dev") - private String modifieParUsername; - - @Schema(description = "Numéro de version pour gestion optimiste", example = "1") - private Long version; -} +package dev.lions.user.manager.dto.base; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; +import org.eclipse.microprofile.openapi.annotations.media.Schema; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * DTO de base pour tous les objets métier + * Contient les attributs communs (id, dates, audit) + */ +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@Schema(description = "DTO de base contenant les attributs communs à tous les objets") +public abstract class BaseDTO implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "Identifiant unique (UUID Keycloak)", example = "f47ac10b-58cc-4372-a567-0e02b2c3d479") + private String id; + + @Schema(description = "Date de création", example = "2025-01-15T10:30:00") + @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") + private LocalDateTime dateCreation; + + @Schema(description = "Date de dernière modification", example = "2025-01-15T14:20:00") + @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") + private LocalDateTime dateModification; + + @Schema(description = "Utilisateur ayant créé l'entité", example = "admin@lions.dev") + private String creeParUsername; + + @Schema(description = "Utilisateur ayant modifié l'entité", example = "superadmin@lions.dev") + private String modifieParUsername; + + @Schema(description = "Numéro de version pour gestion optimiste", example = "1") + private Long version; +} diff --git a/src/main/java/dev/lions/user/manager/dto/common/ApiErrorDTO.java b/src/main/java/dev/lions/user/manager/dto/common/ApiErrorDTO.java index 79ae915..ddbddcf 100644 --- a/src/main/java/dev/lions/user/manager/dto/common/ApiErrorDTO.java +++ b/src/main/java/dev/lions/user/manager/dto/common/ApiErrorDTO.java @@ -1,21 +1,21 @@ -package dev.lions.user.manager.dto.common; - -import io.quarkus.runtime.annotations.RegisterForReflection; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.eclipse.microprofile.openapi.annotations.media.Schema; - -import java.io.Serializable; - -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -@RegisterForReflection -@Schema(description = "Réponse d'erreur standard") -public class ApiErrorDTO implements Serializable { - @Schema(description = "Message d'erreur") - private String message; -} +package dev.lions.user.manager.dto.common; + +import io.quarkus.runtime.annotations.RegisterForReflection; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.eclipse.microprofile.openapi.annotations.media.Schema; + +import java.io.Serializable; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@RegisterForReflection +@Schema(description = "Réponse d'erreur standard") +public class ApiErrorDTO implements Serializable { + @Schema(description = "Message d'erreur") + private String message; +} diff --git a/src/main/java/dev/lions/user/manager/dto/common/CountDTO.java b/src/main/java/dev/lions/user/manager/dto/common/CountDTO.java index de80897..55f47e2 100644 --- a/src/main/java/dev/lions/user/manager/dto/common/CountDTO.java +++ b/src/main/java/dev/lions/user/manager/dto/common/CountDTO.java @@ -1,21 +1,21 @@ -package dev.lions.user.manager.dto.common; - -import io.quarkus.runtime.annotations.RegisterForReflection; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.eclipse.microprofile.openapi.annotations.media.Schema; - -import java.io.Serializable; - -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -@RegisterForReflection -@Schema(description = "Réponse de comptage générique") -public class CountDTO implements Serializable { - @Schema(description = "Nombre d'éléments") - private long count; -} +package dev.lions.user.manager.dto.common; + +import io.quarkus.runtime.annotations.RegisterForReflection; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.eclipse.microprofile.openapi.annotations.media.Schema; + +import java.io.Serializable; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@RegisterForReflection +@Schema(description = "Réponse de comptage générique") +public class CountDTO implements Serializable { + @Schema(description = "Nombre d'éléments") + private long count; +} diff --git a/src/main/java/dev/lions/user/manager/dto/common/UserSessionStatsDTO.java b/src/main/java/dev/lions/user/manager/dto/common/UserSessionStatsDTO.java index 01840e2..fe810ce 100644 --- a/src/main/java/dev/lions/user/manager/dto/common/UserSessionStatsDTO.java +++ b/src/main/java/dev/lions/user/manager/dto/common/UserSessionStatsDTO.java @@ -1,32 +1,32 @@ -package dev.lions.user.manager.dto.common; - -import io.quarkus.runtime.annotations.RegisterForReflection; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.eclipse.microprofile.openapi.annotations.media.Schema; - -import java.io.Serializable; - -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -@RegisterForReflection -@Schema(description = "Statistiques de sessions et d'utilisateurs en ligne pour un realm") -public class UserSessionStatsDTO implements Serializable { - - @Schema(description = "Nom du realm concerné") - private String realmName; - - @Schema(description = "Nombre total d'utilisateurs dans le realm") - private long totalUsers; - - @Schema(description = "Nombre total de sessions actives (approximation)") - private long activeSessions; - - @Schema(description = "Nombre d'utilisateurs considérés comme en ligne (approximation)") - private long onlineUsers; -} - +package dev.lions.user.manager.dto.common; + +import io.quarkus.runtime.annotations.RegisterForReflection; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.eclipse.microprofile.openapi.annotations.media.Schema; + +import java.io.Serializable; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@RegisterForReflection +@Schema(description = "Statistiques de sessions et d'utilisateurs en ligne pour un realm") +public class UserSessionStatsDTO implements Serializable { + + @Schema(description = "Nom du realm concerné") + private String realmName; + + @Schema(description = "Nombre total d'utilisateurs dans le realm") + private long totalUsers; + + @Schema(description = "Nombre total de sessions actives (approximation)") + private long activeSessions; + + @Schema(description = "Nombre d'utilisateurs considérés comme en ligne (approximation)") + private long onlineUsers; +} + diff --git a/src/main/java/dev/lions/user/manager/dto/importexport/ImportResultDTO.java b/src/main/java/dev/lions/user/manager/dto/importexport/ImportResultDTO.java index 27b2c72..026b966 100644 --- a/src/main/java/dev/lions/user/manager/dto/importexport/ImportResultDTO.java +++ b/src/main/java/dev/lions/user/manager/dto/importexport/ImportResultDTO.java @@ -1,123 +1,123 @@ -package dev.lions.user.manager.dto.importexport; - -import com.fasterxml.jackson.annotation.JsonInclude; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.eclipse.microprofile.openapi.annotations.media.Schema; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -/** - * DTO représentant le résultat d'un import CSV d'utilisateurs - * Contient les statistiques et le détail des erreurs rencontrées - * - * @author Lions Development Team - * @version 1.0.0 - * @since 2026-01-02 - */ -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -@JsonInclude(JsonInclude.Include.NON_NULL) -@Schema(description = "Résultat d'un import CSV d'utilisateurs") -public class ImportResultDTO implements Serializable { - - private static final long serialVersionUID = 1L; - - @Schema(description = "Nombre total de lignes traitées", example = "100") - private int totalLines; - - @Schema(description = "Nombre d'utilisateurs créés avec succès", example = "95") - private int successCount; - - @Schema(description = "Nombre d'erreurs rencontrées", example = "5") - private int errorCount; - - @Schema(description = "Message de statut global", example = "Import terminé: 95 utilisateurs créés, 5 erreurs") - private String message; - - @Schema(description = "Liste des erreurs détaillées") - @Builder.Default - private List errors = new ArrayList<>(); - - /** - * Ajoute une erreur au rapport - */ - public void addError(ImportErrorDTO error) { - if (errors == null) { - errors = new ArrayList<>(); - } - errors.add(error); - errorCount = errors.size(); - } - - /** - * Génère le message de statut - */ - public void generateMessage() { - if (errorCount == 0) { - message = String.format("✅ Import réussi: %d utilisateur(s) créé(s)", successCount); - } else { - message = String.format("⚠️ Import terminé avec erreurs: %d utilisateur(s) créé(s), %d erreur(s)", - successCount, errorCount); - } - } - - /** - * DTO représentant une erreur d'import sur une ligne - */ - @Data - @Builder - @NoArgsConstructor - @AllArgsConstructor - @JsonInclude(JsonInclude.Include.NON_NULL) - @Schema(description = "Détail d'une erreur d'import") - public static class ImportErrorDTO implements Serializable { - - private static final long serialVersionUID = 1L; - - @Schema(description = "Numéro de ligne (1-indexed)", example = "42") - private int lineNumber; - - @Schema(description = "Contenu de la ligne en erreur", example = "john.doe,invalid-email,John,Doe,true") - private String lineContent; - - @Schema(description = "Type d'erreur", example = "VALIDATION_ERROR") - private ErrorType errorType; - - @Schema(description = "Champ concerné par l'erreur", example = "email") - private String field; - - @Schema(description = "Message d'erreur descriptif", example = "Format d'email invalide") - private String message; - - @Schema(description = "Détails techniques de l'erreur") - private String details; - } - - /** - * Types d'erreurs possibles lors de l'import - */ - @Schema(description = "Type d'erreur d'import") - public enum ErrorType { - @Schema(description = "Ligne mal formée ou nombre de colonnes incorrect") - INVALID_FORMAT, - - @Schema(description = "Erreur de validation des données") - VALIDATION_ERROR, - - @Schema(description = "Utilisateur déjà existant") - DUPLICATE_USER, - - @Schema(description = "Erreur lors de la création de l'utilisateur") - CREATION_ERROR, - - @Schema(description = "Erreur interne du système") - SYSTEM_ERROR - } -} +package dev.lions.user.manager.dto.importexport; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.eclipse.microprofile.openapi.annotations.media.Schema; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * DTO représentant le résultat d'un import CSV d'utilisateurs + * Contient les statistiques et le détail des erreurs rencontrées + * + * @author Lions Development Team + * @version 1.0.0 + * @since 2026-01-02 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@Schema(description = "Résultat d'un import CSV d'utilisateurs") +public class ImportResultDTO implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "Nombre total de lignes traitées", example = "100") + private int totalLines; + + @Schema(description = "Nombre d'utilisateurs créés avec succès", example = "95") + private int successCount; + + @Schema(description = "Nombre d'erreurs rencontrées", example = "5") + private int errorCount; + + @Schema(description = "Message de statut global", example = "Import terminé: 95 utilisateurs créés, 5 erreurs") + private String message; + + @Schema(description = "Liste des erreurs détaillées") + @Builder.Default + private List errors = new ArrayList<>(); + + /** + * Ajoute une erreur au rapport + */ + public void addError(ImportErrorDTO error) { + if (errors == null) { + errors = new ArrayList<>(); + } + errors.add(error); + errorCount = errors.size(); + } + + /** + * Génère le message de statut + */ + public void generateMessage() { + if (errorCount == 0) { + message = String.format("✅ Import réussi: %d utilisateur(s) créé(s)", successCount); + } else { + message = String.format("⚠️ Import terminé avec erreurs: %d utilisateur(s) créé(s), %d erreur(s)", + successCount, errorCount); + } + } + + /** + * DTO représentant une erreur d'import sur une ligne + */ + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + @JsonInclude(JsonInclude.Include.NON_NULL) + @Schema(description = "Détail d'une erreur d'import") + public static class ImportErrorDTO implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "Numéro de ligne (1-indexed)", example = "42") + private int lineNumber; + + @Schema(description = "Contenu de la ligne en erreur", example = "john.doe,invalid-email,John,Doe,true") + private String lineContent; + + @Schema(description = "Type d'erreur", example = "VALIDATION_ERROR") + private ErrorType errorType; + + @Schema(description = "Champ concerné par l'erreur", example = "email") + private String field; + + @Schema(description = "Message d'erreur descriptif", example = "Format d'email invalide") + private String message; + + @Schema(description = "Détails techniques de l'erreur") + private String details; + } + + /** + * Types d'erreurs possibles lors de l'import + */ + @Schema(description = "Type d'erreur d'import") + public enum ErrorType { + @Schema(description = "Ligne mal formée ou nombre de colonnes incorrect") + INVALID_FORMAT, + + @Schema(description = "Erreur de validation des données") + VALIDATION_ERROR, + + @Schema(description = "Utilisateur déjà existant") + DUPLICATE_USER, + + @Schema(description = "Erreur lors de la création de l'utilisateur") + CREATION_ERROR, + + @Schema(description = "Erreur interne du système") + SYSTEM_ERROR + } +} diff --git a/src/main/java/dev/lions/user/manager/dto/realm/AuthorizedRealmsDTO.java b/src/main/java/dev/lions/user/manager/dto/realm/AuthorizedRealmsDTO.java index 3b3f92c..76471f7 100644 --- a/src/main/java/dev/lions/user/manager/dto/realm/AuthorizedRealmsDTO.java +++ b/src/main/java/dev/lions/user/manager/dto/realm/AuthorizedRealmsDTO.java @@ -1,25 +1,25 @@ -package dev.lions.user.manager.dto.realm; - -import io.quarkus.runtime.annotations.RegisterForReflection; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.eclipse.microprofile.openapi.annotations.media.Schema; - -import java.io.Serializable; -import java.util.List; - -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -@RegisterForReflection -@Schema(description = "Liste des realms autorisés pour un utilisateur") -public class AuthorizedRealmsDTO implements Serializable { - @Schema(description = "Liste des realms (peut être vide si super admin)") - private List realms; - - @Schema(description = "L'utilisateur est super admin") - private boolean isSuperAdmin; -} +package dev.lions.user.manager.dto.realm; + +import io.quarkus.runtime.annotations.RegisterForReflection; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.eclipse.microprofile.openapi.annotations.media.Schema; + +import java.io.Serializable; +import java.util.List; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@RegisterForReflection +@Schema(description = "Liste des realms autorisés pour un utilisateur") +public class AuthorizedRealmsDTO implements Serializable { + @Schema(description = "Liste des realms (peut être vide si super admin)") + private List realms; + + @Schema(description = "L'utilisateur est super admin") + private boolean isSuperAdmin; +} diff --git a/src/main/java/dev/lions/user/manager/dto/realm/RealmAccessCheckDTO.java b/src/main/java/dev/lions/user/manager/dto/realm/RealmAccessCheckDTO.java index e9ac4ab..363cd3b 100644 --- a/src/main/java/dev/lions/user/manager/dto/realm/RealmAccessCheckDTO.java +++ b/src/main/java/dev/lions/user/manager/dto/realm/RealmAccessCheckDTO.java @@ -1,27 +1,27 @@ -package dev.lions.user.manager.dto.realm; - -import io.quarkus.runtime.annotations.RegisterForReflection; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.eclipse.microprofile.openapi.annotations.media.Schema; - -import java.io.Serializable; - -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -@RegisterForReflection -@Schema(description = "Réponse de vérification d'accès au realm") -public class RealmAccessCheckDTO implements Serializable { - @Schema(description = "L'utilisateur peut gérer le realm") - private boolean canManage; - - @Schema(description = "ID de l'utilisateur") - private String userId; - - @Schema(description = "Nom du realm") - private String realmName; -} +package dev.lions.user.manager.dto.realm; + +import io.quarkus.runtime.annotations.RegisterForReflection; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.eclipse.microprofile.openapi.annotations.media.Schema; + +import java.io.Serializable; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@RegisterForReflection +@Schema(description = "Réponse de vérification d'accès au realm") +public class RealmAccessCheckDTO implements Serializable { + @Schema(description = "L'utilisateur peut gérer le realm") + private boolean canManage; + + @Schema(description = "ID de l'utilisateur") + private String userId; + + @Schema(description = "Nom du realm") + private String realmName; +} diff --git a/src/main/java/dev/lions/user/manager/dto/realm/RealmAssignmentDTO.java b/src/main/java/dev/lions/user/manager/dto/realm/RealmAssignmentDTO.java index 1ec3c49..3e72979 100644 --- a/src/main/java/dev/lions/user/manager/dto/realm/RealmAssignmentDTO.java +++ b/src/main/java/dev/lions/user/manager/dto/realm/RealmAssignmentDTO.java @@ -1,119 +1,119 @@ -package dev.lions.user.manager.dto.realm; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonInclude; -import dev.lions.user.manager.dto.base.BaseDTO; -import jakarta.validation.constraints.NotBlank; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; -import lombok.experimental.SuperBuilder; -import org.eclipse.microprofile.openapi.annotations.media.Schema; -import io.quarkus.runtime.annotations.RegisterForReflection; - -import java.time.LocalDateTime; - -/** - * DTO pour assigner ou révoquer l'accès d'un utilisateur à un realm - * Permet de gérer les permissions multi-tenant - */ -@Data -@SuperBuilder -@NoArgsConstructor -@AllArgsConstructor -@EqualsAndHashCode(callSuper = true) -@JsonInclude(JsonInclude.Include.NON_NULL) -@Schema(description = "Attribution ou révocation d'accès à un realm") -@RegisterForReflection -public class RealmAssignmentDTO extends BaseDTO { - - private static final long serialVersionUID = 1L; - - @NotBlank(message = "L'ID utilisateur est obligatoire") - @Schema(description = "ID de l'utilisateur Keycloak", example = "f47ac10b-58cc-4372-a567-0e02b2c3d479", required = true) - private String userId; - - @Schema(description = "Username de l'utilisateur", example = "jdupont") - private String username; - - @Schema(description = "Email de l'utilisateur", example = "jdupont@example.com") - private String email; - - @NotBlank(message = "Le nom du realm est obligatoire") - @Schema(description = "Nom du realm assigné", example = "btpxpress", required = true) - private String realmName; - - @Schema(description = "Indique si l'utilisateur est super admin (peut gérer tous les realms)", example = "false") - private Boolean isSuperAdmin; - - @Schema(description = "Date d'assignation", example = "2025-01-15T10:30:00") - @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") - private LocalDateTime assignedAt; - - @Schema(description = "Username de l'administrateur qui a fait l'assignation", example = "admin@lions.dev") - private String assignedBy; - - @Schema(description = "Raison de l'assignation", example = "Nouveau gestionnaire du realm client") - private String raison; - - @Schema(description = "Commentaires administratifs", example = "Accès temporaire pour support") - private String commentaires; - - @Schema(description = "Indique si c'est une assignation temporaire", example = "false") - private Boolean temporaire; - - @Schema(description = "Date d'expiration de l'assignation temporaire", example = "2025-12-31T23:59:59") - @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") - private LocalDateTime dateExpiration; - - @Schema(description = "Indique si l'assignation est active", example = "true") - private Boolean active; - - /** - * Vérifie si l'assignation est temporaire - * @return true si temporaire - */ - public boolean isTemporaire() { - return Boolean.TRUE.equals(temporaire); - } - - /** - * Vérifie si l'assignation est active - * @return true si active - */ - public boolean isActive() { - return Boolean.TRUE.equals(active); - } - - /** - * Vérifie si l'assignation a expiré - * @return true si expirée - */ - public boolean isExpired() { - if (!isTemporaire() || dateExpiration == null) { - return false; - } - return LocalDateTime.now().isAfter(dateExpiration); - } - - /** - * Vérifie si l'utilisateur est super admin - * @return true si super admin - */ - public boolean isSuperAdmin() { - return Boolean.TRUE.equals(isSuperAdmin); - } - - /** - * Retourne un résumé de l'assignation - * @return résumé - */ - public String getSummary() { - return String.format("Realm '%s' assigné à %s%s", - realmName, - username != null ? username : userId, - isTemporaire() ? " (temporaire)" : "" - ); - } -} +package dev.lions.user.manager.dto.realm; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonInclude; +import dev.lions.user.manager.dto.base.BaseDTO; +import jakarta.validation.constraints.NotBlank; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; +import org.eclipse.microprofile.openapi.annotations.media.Schema; +import io.quarkus.runtime.annotations.RegisterForReflection; + +import java.time.LocalDateTime; + +/** + * DTO pour assigner ou révoquer l'accès d'un utilisateur à un realm + * Permet de gérer les permissions multi-tenant + */ +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +@Schema(description = "Attribution ou révocation d'accès à un realm") +@RegisterForReflection +public class RealmAssignmentDTO extends BaseDTO { + + private static final long serialVersionUID = 1L; + + @NotBlank(message = "L'ID utilisateur est obligatoire") + @Schema(description = "ID de l'utilisateur Keycloak", example = "f47ac10b-58cc-4372-a567-0e02b2c3d479", required = true) + private String userId; + + @Schema(description = "Username de l'utilisateur", example = "jdupont") + private String username; + + @Schema(description = "Email de l'utilisateur", example = "jdupont@example.com") + private String email; + + @NotBlank(message = "Le nom du realm est obligatoire") + @Schema(description = "Nom du realm assigné", example = "btpxpress", required = true) + private String realmName; + + @Schema(description = "Indique si l'utilisateur est super admin (peut gérer tous les realms)", example = "false") + private Boolean isSuperAdmin; + + @Schema(description = "Date d'assignation", example = "2025-01-15T10:30:00") + @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") + private LocalDateTime assignedAt; + + @Schema(description = "Username de l'administrateur qui a fait l'assignation", example = "admin@lions.dev") + private String assignedBy; + + @Schema(description = "Raison de l'assignation", example = "Nouveau gestionnaire du realm client") + private String raison; + + @Schema(description = "Commentaires administratifs", example = "Accès temporaire pour support") + private String commentaires; + + @Schema(description = "Indique si c'est une assignation temporaire", example = "false") + private Boolean temporaire; + + @Schema(description = "Date d'expiration de l'assignation temporaire", example = "2025-12-31T23:59:59") + @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") + private LocalDateTime dateExpiration; + + @Schema(description = "Indique si l'assignation est active", example = "true") + private Boolean active; + + /** + * Vérifie si l'assignation est temporaire + * @return true si temporaire + */ + public boolean isTemporaire() { + return Boolean.TRUE.equals(temporaire); + } + + /** + * Vérifie si l'assignation est active + * @return true si active + */ + public boolean isActive() { + return Boolean.TRUE.equals(active); + } + + /** + * Vérifie si l'assignation a expiré + * @return true si expirée + */ + public boolean isExpired() { + if (!isTemporaire() || dateExpiration == null) { + return false; + } + return LocalDateTime.now().isAfter(dateExpiration); + } + + /** + * Vérifie si l'utilisateur est super admin + * @return true si super admin + */ + public boolean isSuperAdmin() { + return Boolean.TRUE.equals(isSuperAdmin); + } + + /** + * Retourne un résumé de l'assignation + * @return résumé + */ + public String getSummary() { + return String.format("Realm '%s' assigné à %s%s", + realmName, + username != null ? username : userId, + isTemporaire() ? " (temporaire)" : "" + ); + } +} diff --git a/src/main/java/dev/lions/user/manager/dto/role/RoleAssignmentDTO.java b/src/main/java/dev/lions/user/manager/dto/role/RoleAssignmentDTO.java index f2da065..8737758 100644 --- a/src/main/java/dev/lions/user/manager/dto/role/RoleAssignmentDTO.java +++ b/src/main/java/dev/lions/user/manager/dto/role/RoleAssignmentDTO.java @@ -1,101 +1,101 @@ -package dev.lions.user.manager.dto.role; - -import com.fasterxml.jackson.annotation.JsonInclude; -import dev.lions.user.manager.enums.role.TypeRole; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotEmpty; -import jakarta.validation.constraints.NotNull; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.eclipse.microprofile.openapi.annotations.media.Schema; - -import java.io.Serializable; -import java.util.List; - -/** - * DTO pour assigner ou révoquer des rôles à un utilisateur - * Utilisé dans les opérations d'attribution de rôles - */ -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -@JsonInclude(JsonInclude.Include.NON_NULL) -@Schema(description = "Attribution ou révocation de rôles") -public class RoleAssignmentDTO implements Serializable { - - private static final long serialVersionUID = 1L; - - @NotBlank(message = "L'ID utilisateur est obligatoire") - @Schema(description = "ID de l'utilisateur cible", example = "f47ac10b-58cc-4372-a567-0e02b2c3d479", required = true) - private String userId; - - @Schema(description = "Username de l'utilisateur cible (optionnel)", example = "jdupont") - private String username; - - @NotEmpty(message = "Au moins un rôle doit être spécifié") - @Schema(description = "Liste des noms de rôles à attribuer ou révoquer", required = true) - private List roleNames; - - @Schema(description = "Liste des IDs de rôles à attribuer ou révoquer") - private List roleIds; - - @NotNull(message = "Le type de rôle est obligatoire") - @Schema(description = "Type de rôle", example = "REALM_ROLE", required = true) - private TypeRole typeRole; - - @Schema(description = "Nom du Realm", example = "btpxpress") - private String realmName; - - @Schema(description = "Nom du Client (requis si typeRole = CLIENT_ROLE)", example = "btpxpress-app") - private String clientName; - - @Schema(description = "ID du Client (optionnel)") - private String clientId; - - @Schema(description = "Raison de l'attribution/révocation", example = "Promotion au poste de gestionnaire") - private String raison; - - @Schema(description = "Commentaires administratifs", example = "Demandé par le manager") - private String commentaires; - - @Schema(description = "Indique si c'est une attribution temporaire", example = "false") - private Boolean temporaire; - - @Schema(description = "Date d'expiration de l'attribution temporaire", example = "2025-12-31T23:59:59") - private String dateExpiration; - - @Schema(description = "Indique si les rôles composites doivent être inclus", example = "true") - @Builder.Default - private Boolean includeComposites = true; - - @Schema(description = "Indique si l'opération doit notifier l'utilisateur", example = "true") - @Builder.Default - private Boolean notifyUser = false; - - /** - * Valide que les données nécessaires sont présentes pour un rôle client - * @return true si valide - */ - public boolean isValidForClientRole() { - return typeRole == TypeRole.CLIENT_ROLE && clientName != null && !clientName.isBlank(); - } - - /** - * Valide que les données nécessaires sont présentes pour un rôle realm - * @return true si valide - */ - public boolean isValidForRealmRole() { - return typeRole == TypeRole.REALM_ROLE; - } - - /** - * Retourne le nombre de rôles à assigner/révoquer - * @return nombre de rôles - */ - public int getRoleCount() { - return roleNames != null ? roleNames.size() : 0; - } -} +package dev.lions.user.manager.dto.role; + +import com.fasterxml.jackson.annotation.JsonInclude; +import dev.lions.user.manager.enums.role.TypeRole; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.eclipse.microprofile.openapi.annotations.media.Schema; + +import java.io.Serializable; +import java.util.List; + +/** + * DTO pour assigner ou révoquer des rôles à un utilisateur + * Utilisé dans les opérations d'attribution de rôles + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@Schema(description = "Attribution ou révocation de rôles") +public class RoleAssignmentDTO implements Serializable { + + private static final long serialVersionUID = 1L; + + @NotBlank(message = "L'ID utilisateur est obligatoire") + @Schema(description = "ID de l'utilisateur cible", example = "f47ac10b-58cc-4372-a567-0e02b2c3d479", required = true) + private String userId; + + @Schema(description = "Username de l'utilisateur cible (optionnel)", example = "jdupont") + private String username; + + @NotEmpty(message = "Au moins un rôle doit être spécifié") + @Schema(description = "Liste des noms de rôles à attribuer ou révoquer", required = true) + private List roleNames; + + @Schema(description = "Liste des IDs de rôles à attribuer ou révoquer") + private List roleIds; + + @NotNull(message = "Le type de rôle est obligatoire") + @Schema(description = "Type de rôle", example = "REALM_ROLE", required = true) + private TypeRole typeRole; + + @Schema(description = "Nom du Realm", example = "btpxpress") + private String realmName; + + @Schema(description = "Nom du Client (requis si typeRole = CLIENT_ROLE)", example = "btpxpress-app") + private String clientName; + + @Schema(description = "ID du Client (optionnel)") + private String clientId; + + @Schema(description = "Raison de l'attribution/révocation", example = "Promotion au poste de gestionnaire") + private String raison; + + @Schema(description = "Commentaires administratifs", example = "Demandé par le manager") + private String commentaires; + + @Schema(description = "Indique si c'est une attribution temporaire", example = "false") + private Boolean temporaire; + + @Schema(description = "Date d'expiration de l'attribution temporaire", example = "2025-12-31T23:59:59") + private String dateExpiration; + + @Schema(description = "Indique si les rôles composites doivent être inclus", example = "true") + @Builder.Default + private Boolean includeComposites = true; + + @Schema(description = "Indique si l'opération doit notifier l'utilisateur", example = "true") + @Builder.Default + private Boolean notifyUser = false; + + /** + * Valide que les données nécessaires sont présentes pour un rôle client + * @return true si valide + */ + public boolean isValidForClientRole() { + return typeRole == TypeRole.CLIENT_ROLE && clientName != null && !clientName.isBlank(); + } + + /** + * Valide que les données nécessaires sont présentes pour un rôle realm + * @return true si valide + */ + public boolean isValidForRealmRole() { + return typeRole == TypeRole.REALM_ROLE; + } + + /** + * Retourne le nombre de rôles à assigner/révoquer + * @return nombre de rôles + */ + public int getRoleCount() { + return roleNames != null ? roleNames.size() : 0; + } +} diff --git a/src/main/java/dev/lions/user/manager/dto/role/RoleAssignmentRequestDTO.java b/src/main/java/dev/lions/user/manager/dto/role/RoleAssignmentRequestDTO.java index e90fa46..84ebb7a 100644 --- a/src/main/java/dev/lions/user/manager/dto/role/RoleAssignmentRequestDTO.java +++ b/src/main/java/dev/lions/user/manager/dto/role/RoleAssignmentRequestDTO.java @@ -1,22 +1,22 @@ -package dev.lions.user.manager.dto.role; - -import io.quarkus.runtime.annotations.RegisterForReflection; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.eclipse.microprofile.openapi.annotations.media.Schema; - -import java.io.Serializable; -import java.util.List; - -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -@RegisterForReflection -@Schema(description = "Requête d'attribution ou de révocation de rôles") -public class RoleAssignmentRequestDTO implements Serializable { - @Schema(description = "Liste des noms de rôles", required = true) - private List roleNames; -} +package dev.lions.user.manager.dto.role; + +import io.quarkus.runtime.annotations.RegisterForReflection; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.eclipse.microprofile.openapi.annotations.media.Schema; + +import java.io.Serializable; +import java.util.List; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@RegisterForReflection +@Schema(description = "Requête d'attribution ou de révocation de rôles") +public class RoleAssignmentRequestDTO implements Serializable { + @Schema(description = "Liste des noms de rôles", required = true) + private List roleNames; +} diff --git a/src/main/java/dev/lions/user/manager/dto/role/RoleDTO.java b/src/main/java/dev/lions/user/manager/dto/role/RoleDTO.java index 31bf580..e2b5087 100644 --- a/src/main/java/dev/lions/user/manager/dto/role/RoleDTO.java +++ b/src/main/java/dev/lions/user/manager/dto/role/RoleDTO.java @@ -1,146 +1,146 @@ -package dev.lions.user.manager.dto.role; - -import com.fasterxml.jackson.annotation.JsonInclude; -import dev.lions.user.manager.dto.base.BaseDTO; -import dev.lions.user.manager.enums.role.TypeRole; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.Pattern; -import jakarta.validation.constraints.Size; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; -import lombok.experimental.SuperBuilder; -import org.eclipse.microprofile.openapi.annotations.media.Schema; -import io.quarkus.runtime.annotations.RegisterForReflection; - -import java.util.List; -import java.util.Map; - -/** - * DTO représentant un rôle Keycloak - * Mappé depuis RoleRepresentation de Keycloak Admin API - */ -@Data -@SuperBuilder -@NoArgsConstructor -@AllArgsConstructor -@EqualsAndHashCode(callSuper = true) -@JsonInclude(JsonInclude.Include.NON_NULL) -@Schema(description = "Rôle Keycloak (Realm ou Client)") -@RegisterForReflection -public class RoleDTO extends BaseDTO { - - private static final long serialVersionUID = 1L; - - @NotBlank(message = "Le nom du rôle est obligatoire") - @Size(min = 2, max = 100, message = "Le nom du rôle doit contenir entre 2 et 100 caractères") - @Pattern(regexp = "^[a-zA-Z0-9_-]+$", message = "Le nom du rôle ne peut contenir que des lettres, chiffres, underscores et tirets") - @Schema(description = "Nom du rôle", example = "admin_btpxpress", required = true) - private String name; - - @Schema(description = "Description du rôle", example = "Administrateur avec tous les privilèges") - private String description; - - @Schema(description = "Type de rôle", example = "REALM_ROLE") - private TypeRole typeRole; - - @Schema(description = "Indique si c'est un rôle composite", example = "false") - private Boolean composite; - - @Schema(description = "ID du conteneur (Realm ou Client)", example = "btpxpress") - private String containerId; - - @Schema(description = "Nom du Realm", example = "btpxpress") - private String realmName; - - @Schema(description = "Nom du Client (si rôle client)", example = "btpxpress-app") - private String clientName; - - @Schema(description = "ID du Client (si rôle client)") - private String clientId; - - @Schema(description = "Rôles composites inclus dans ce rôle") - private List compositeRoles; - - @Schema(description = "Rôles Realm composites") - private List compositeRealmRoles; - - @Schema(description = "Rôles Client composites par client") - private Map> compositeClientRoles; - - @Schema(description = "Attributs personnalisés du rôle") - private Map> attributes; - - @Schema(description = "Nombre d'utilisateurs ayant ce rôle", example = "15") - private Integer userCount; - - @Schema(description = "Indique si le rôle est un rôle système", example = "false") - private Boolean systemRole; - - @Schema(description = "Indique si le rôle peut être supprimé", example = "true") - private Boolean deletable; - - /** - * Détermine si c'est un rôle Realm - * @return true si typeRole est REALM_ROLE - */ - public boolean isRealmRole() { - return typeRole == TypeRole.REALM_ROLE; - } - - /** - * Détermine si c'est un rôle Client - * @return true si typeRole est CLIENT_ROLE - */ - public boolean isClientRole() { - return typeRole == TypeRole.CLIENT_ROLE; - } - - /** - * Détermine si le rôle est composite - * @return true si composite = true et a des rôles composites - */ - public boolean isComposite() { - return Boolean.TRUE.equals(composite) - && ((compositeRoles != null && !compositeRoles.isEmpty()) - || (compositeRealmRoles != null && !compositeRealmRoles.isEmpty()) - || (compositeClientRoles != null && !compositeClientRoles.isEmpty())); - } - - /** - * Retourne le nom complet du rôle (avec préfixe client si applicable) - * @return nom complet - */ - public String getFullName() { - if (isClientRole() && clientName != null) { - return clientName + ":" + name; - } - return name; - } - - /** - * DTO pour rôle composite - */ - @Data - @NoArgsConstructor - @AllArgsConstructor - @SuperBuilder - @Schema(description = "Rôle composite") - public static class RoleCompositeDTO { - @Schema(description = "ID du rôle", example = "f47ac10b-58cc-4372-a567-0e02b2c3d479") - private String id; - - @Schema(description = "Nom du rôle", example = "gestionnaire") - private String name; - - @Schema(description = "Description du rôle") - private String description; - - @Schema(description = "Type de rôle", example = "REALM_ROLE") - private TypeRole typeRole; - - @Schema(description = "Nom du client (si client role)") - private String clientName; - } -} +package dev.lions.user.manager.dto.role; + +import com.fasterxml.jackson.annotation.JsonInclude; +import dev.lions.user.manager.dto.base.BaseDTO; +import dev.lions.user.manager.enums.role.TypeRole; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; +import org.eclipse.microprofile.openapi.annotations.media.Schema; +import io.quarkus.runtime.annotations.RegisterForReflection; + +import java.util.List; +import java.util.Map; + +/** + * DTO représentant un rôle Keycloak + * Mappé depuis RoleRepresentation de Keycloak Admin API + */ +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +@Schema(description = "Rôle Keycloak (Realm ou Client)") +@RegisterForReflection +public class RoleDTO extends BaseDTO { + + private static final long serialVersionUID = 1L; + + @NotBlank(message = "Le nom du rôle est obligatoire") + @Size(min = 2, max = 100, message = "Le nom du rôle doit contenir entre 2 et 100 caractères") + @Pattern(regexp = "^[a-zA-Z0-9_-]+$", message = "Le nom du rôle ne peut contenir que des lettres, chiffres, underscores et tirets") + @Schema(description = "Nom du rôle", example = "admin_btpxpress", required = true) + private String name; + + @Schema(description = "Description du rôle", example = "Administrateur avec tous les privilèges") + private String description; + + @Schema(description = "Type de rôle", example = "REALM_ROLE") + private TypeRole typeRole; + + @Schema(description = "Indique si c'est un rôle composite", example = "false") + private Boolean composite; + + @Schema(description = "ID du conteneur (Realm ou Client)", example = "btpxpress") + private String containerId; + + @Schema(description = "Nom du Realm", example = "btpxpress") + private String realmName; + + @Schema(description = "Nom du Client (si rôle client)", example = "btpxpress-app") + private String clientName; + + @Schema(description = "ID du Client (si rôle client)") + private String clientId; + + @Schema(description = "Rôles composites inclus dans ce rôle") + private List compositeRoles; + + @Schema(description = "Rôles Realm composites") + private List compositeRealmRoles; + + @Schema(description = "Rôles Client composites par client") + private Map> compositeClientRoles; + + @Schema(description = "Attributs personnalisés du rôle") + private Map> attributes; + + @Schema(description = "Nombre d'utilisateurs ayant ce rôle", example = "15") + private Integer userCount; + + @Schema(description = "Indique si le rôle est un rôle système", example = "false") + private Boolean systemRole; + + @Schema(description = "Indique si le rôle peut être supprimé", example = "true") + private Boolean deletable; + + /** + * Détermine si c'est un rôle Realm + * @return true si typeRole est REALM_ROLE + */ + public boolean isRealmRole() { + return typeRole == TypeRole.REALM_ROLE; + } + + /** + * Détermine si c'est un rôle Client + * @return true si typeRole est CLIENT_ROLE + */ + public boolean isClientRole() { + return typeRole == TypeRole.CLIENT_ROLE; + } + + /** + * Détermine si le rôle est composite + * @return true si composite = true et a des rôles composites + */ + public boolean isComposite() { + return Boolean.TRUE.equals(composite) + && ((compositeRoles != null && !compositeRoles.isEmpty()) + || (compositeRealmRoles != null && !compositeRealmRoles.isEmpty()) + || (compositeClientRoles != null && !compositeClientRoles.isEmpty())); + } + + /** + * Retourne le nom complet du rôle (avec préfixe client si applicable) + * @return nom complet + */ + public String getFullName() { + if (isClientRole() && clientName != null) { + return clientName + ":" + name; + } + return name; + } + + /** + * DTO pour rôle composite + */ + @Data + @NoArgsConstructor + @AllArgsConstructor + @SuperBuilder + @Schema(description = "Rôle composite") + public static class RoleCompositeDTO { + @Schema(description = "ID du rôle", example = "f47ac10b-58cc-4372-a567-0e02b2c3d479") + private String id; + + @Schema(description = "Nom du rôle", example = "gestionnaire") + private String name; + + @Schema(description = "Description du rôle") + private String description; + + @Schema(description = "Type de rôle", example = "REALM_ROLE") + private TypeRole typeRole; + + @Schema(description = "Nom du client (si client role)") + private String clientName; + } +} diff --git a/src/main/java/dev/lions/user/manager/dto/sync/HealthStatusDTO.java b/src/main/java/dev/lions/user/manager/dto/sync/HealthStatusDTO.java index cb996c6..7914e6a 100644 --- a/src/main/java/dev/lions/user/manager/dto/sync/HealthStatusDTO.java +++ b/src/main/java/dev/lions/user/manager/dto/sync/HealthStatusDTO.java @@ -1,46 +1,46 @@ -package dev.lions.user.manager.dto.sync; - -import com.fasterxml.jackson.annotation.JsonInclude; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.eclipse.microprofile.openapi.annotations.media.Schema; - -import java.io.Serializable; - -/** - * DTO représentant le statut de santé de Keycloak - */ -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -@JsonInclude(JsonInclude.Include.NON_NULL) -@Schema(description = "Statut de santé de Keycloak") -public class HealthStatusDTO implements Serializable { - - private static final long serialVersionUID = 1L; - - @Schema(description = "Timestamp du check de santé (millisecondes)", example = "1699545600000") - private long timestamp; - - @Schema(description = "Indique si Keycloak est accessible", example = "true") - private boolean keycloakAccessible; - - @Schema(description = "Version de Keycloak", example = "23.0.3") - private String keycloakVersion; - - @Schema(description = "Indique si les realms sont accessibles", example = "true") - private boolean realmsAccessible; - - @Schema(description = "Nombre de realms disponibles", example = "5") - private int realmsCount; - - @Schema(description = "Indique si Keycloak est globalement en bonne santé", example = "true") - private boolean overallHealthy; - - @Schema(description = "Message d'erreur si le check a échoué") - private String errorMessage; -} - +package dev.lions.user.manager.dto.sync; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.eclipse.microprofile.openapi.annotations.media.Schema; + +import java.io.Serializable; + +/** + * DTO représentant le statut de santé de Keycloak + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@Schema(description = "Statut de santé de Keycloak") +public class HealthStatusDTO implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "Timestamp du check de santé (millisecondes)", example = "1699545600000") + private long timestamp; + + @Schema(description = "Indique si Keycloak est accessible", example = "true") + private boolean keycloakAccessible; + + @Schema(description = "Version de Keycloak", example = "23.0.3") + private String keycloakVersion; + + @Schema(description = "Indique si les realms sont accessibles", example = "true") + private boolean realmsAccessible; + + @Schema(description = "Nombre de realms disponibles", example = "5") + private int realmsCount; + + @Schema(description = "Indique si Keycloak est globalement en bonne santé", example = "true") + private boolean overallHealthy; + + @Schema(description = "Message d'erreur si le check a échoué") + private String errorMessage; +} + diff --git a/src/main/java/dev/lions/user/manager/dto/sync/SyncConsistencyDTO.java b/src/main/java/dev/lions/user/manager/dto/sync/SyncConsistencyDTO.java index ac6a1d1..6010480 100644 --- a/src/main/java/dev/lions/user/manager/dto/sync/SyncConsistencyDTO.java +++ b/src/main/java/dev/lions/user/manager/dto/sync/SyncConsistencyDTO.java @@ -1,29 +1,29 @@ -package dev.lions.user.manager.dto.sync; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.util.Set; - -/** - * DTO rapport de cohérence entre données Keycloak et cache local. - */ -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class SyncConsistencyDTO { - private String realmName; - private String status; // OK, MISMATCH, ERROR - private Integer usersKeycloakCount; - private Integer usersLocalCount; - private Set missingUsersInLocal; - private Set missingUsersInKeycloak; - private Integer rolesKeycloakCount; - private Integer rolesLocalCount; - private Set missingRolesInLocal; - private Set missingRolesInKeycloak; - private String error; -} +package dev.lions.user.manager.dto.sync; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Set; + +/** + * DTO rapport de cohérence entre données Keycloak et cache local. + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SyncConsistencyDTO { + private String realmName; + private String status; // OK, MISMATCH, ERROR + private Integer usersKeycloakCount; + private Integer usersLocalCount; + private Set missingUsersInLocal; + private Set missingUsersInKeycloak; + private Integer rolesKeycloakCount; + private Integer rolesLocalCount; + private Set missingRolesInLocal; + private Set missingRolesInKeycloak; + private String error; +} diff --git a/src/main/java/dev/lions/user/manager/dto/sync/SyncHistoryDTO.java b/src/main/java/dev/lions/user/manager/dto/sync/SyncHistoryDTO.java index ca19650..fb503d3 100644 --- a/src/main/java/dev/lions/user/manager/dto/sync/SyncHistoryDTO.java +++ b/src/main/java/dev/lions/user/manager/dto/sync/SyncHistoryDTO.java @@ -1,23 +1,23 @@ -package dev.lions.user.manager.dto.sync; - -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.AllArgsConstructor; - -import java.time.LocalDateTime; - -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class SyncHistoryDTO { - private String id; - private String realmName; - private LocalDateTime syncDate; - private String syncType; // FULL, PARTIAL, USER, ROLE - private String status; // SUCCESS, FAILURE - private Integer itemsProcessed; - private Long durationMs; - private String errorMessage; -} +package dev.lions.user.manager.dto.sync; + +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.AllArgsConstructor; + +import java.time.LocalDateTime; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SyncHistoryDTO { + private String id; + private String realmName; + private LocalDateTime syncDate; + private String syncType; // FULL, PARTIAL, USER, ROLE + private String status; // SUCCESS, FAILURE + private Integer itemsProcessed; + private Long durationMs; + private String errorMessage; +} diff --git a/src/main/java/dev/lions/user/manager/dto/sync/SyncResultDTO.java b/src/main/java/dev/lions/user/manager/dto/sync/SyncResultDTO.java index d05c687..829d00b 100644 --- a/src/main/java/dev/lions/user/manager/dto/sync/SyncResultDTO.java +++ b/src/main/java/dev/lions/user/manager/dto/sync/SyncResultDTO.java @@ -1,57 +1,57 @@ -package dev.lions.user.manager.dto.sync; - -import com.fasterxml.jackson.annotation.JsonInclude; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.eclipse.microprofile.openapi.annotations.media.Schema; - -import java.io.Serializable; - -/** - * DTO représentant le résultat d'une synchronisation - */ -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -@JsonInclude(JsonInclude.Include.NON_NULL) -@Schema(description = "Résultat d'une synchronisation avec Keycloak") -public class SyncResultDTO implements Serializable { - - private static final long serialVersionUID = 1L; - - @Schema(description = "Nom du realm synchronisé", example = "lions") - private String realmName; - - @Schema(description = "Nombre d'utilisateurs synchronisés", example = "150") - private int usersCount; - - @Schema(description = "Nombre de rôles realm synchronisés", example = "25") - private int realmRolesCount; - - @Schema(description = "Nombre de rôles client synchronisés", example = "50") - private int clientRolesCount; - - @Schema(description = "Indique si la synchronisation a réussi", example = "true") - private boolean success; - - @Schema(description = "Message d'erreur si la synchronisation a échoué") - private String errorMessage; - - @Schema(description = "Timestamp de début de la synchronisation (millisecondes)", example = "1699545600000") - private long startTime; - - @Schema(description = "Timestamp de fin de la synchronisation (millisecondes)", example = "1699545615000") - private long endTime; - - /** - * Retourne la durée de la synchronisation en millisecondes - * @return durée en ms - */ - public long getDurationMs() { - return endTime - startTime; - } -} - +package dev.lions.user.manager.dto.sync; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.eclipse.microprofile.openapi.annotations.media.Schema; + +import java.io.Serializable; + +/** + * DTO représentant le résultat d'une synchronisation + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@Schema(description = "Résultat d'une synchronisation avec Keycloak") +public class SyncResultDTO implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "Nom du realm synchronisé", example = "lions") + private String realmName; + + @Schema(description = "Nombre d'utilisateurs synchronisés", example = "150") + private int usersCount; + + @Schema(description = "Nombre de rôles realm synchronisés", example = "25") + private int realmRolesCount; + + @Schema(description = "Nombre de rôles client synchronisés", example = "50") + private int clientRolesCount; + + @Schema(description = "Indique si la synchronisation a réussi", example = "true") + private boolean success; + + @Schema(description = "Message d'erreur si la synchronisation a échoué") + private String errorMessage; + + @Schema(description = "Timestamp de début de la synchronisation (millisecondes)", example = "1699545600000") + private long startTime; + + @Schema(description = "Timestamp de fin de la synchronisation (millisecondes)", example = "1699545615000") + private long endTime; + + /** + * Retourne la durée de la synchronisation en millisecondes + * @return durée en ms + */ + public long getDurationMs() { + return endTime - startTime; + } +} + diff --git a/src/main/java/dev/lions/user/manager/dto/user/PasswordResetRequestDTO.java b/src/main/java/dev/lions/user/manager/dto/user/PasswordResetRequestDTO.java index 870ad48..7bc384d 100644 --- a/src/main/java/dev/lions/user/manager/dto/user/PasswordResetRequestDTO.java +++ b/src/main/java/dev/lions/user/manager/dto/user/PasswordResetRequestDTO.java @@ -1,25 +1,25 @@ -package dev.lions.user.manager.dto.user; - -import io.quarkus.runtime.annotations.RegisterForReflection; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.eclipse.microprofile.openapi.annotations.media.Schema; - -import java.io.Serializable; - -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -@RegisterForReflection -@Schema(description = "Requête de réinitialisation de mot de passe") -public class PasswordResetRequestDTO implements Serializable { - @Schema(description = "Nouveau mot de passe", required = true) - private String password; - - @Schema(description = "Indique si le mot de passe est temporaire", defaultValue = "true") - @Builder.Default - private boolean temporary = true; -} +package dev.lions.user.manager.dto.user; + +import io.quarkus.runtime.annotations.RegisterForReflection; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.eclipse.microprofile.openapi.annotations.media.Schema; + +import java.io.Serializable; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@RegisterForReflection +@Schema(description = "Requête de réinitialisation de mot de passe") +public class PasswordResetRequestDTO implements Serializable { + @Schema(description = "Nouveau mot de passe", required = true) + private String password; + + @Schema(description = "Indique si le mot de passe est temporaire", defaultValue = "true") + @Builder.Default + private boolean temporary = true; +} diff --git a/src/main/java/dev/lions/user/manager/dto/user/SessionsRevokedDTO.java b/src/main/java/dev/lions/user/manager/dto/user/SessionsRevokedDTO.java index 15dee6f..8975b45 100644 --- a/src/main/java/dev/lions/user/manager/dto/user/SessionsRevokedDTO.java +++ b/src/main/java/dev/lions/user/manager/dto/user/SessionsRevokedDTO.java @@ -1,21 +1,21 @@ -package dev.lions.user.manager.dto.user; - -import io.quarkus.runtime.annotations.RegisterForReflection; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.eclipse.microprofile.openapi.annotations.media.Schema; - -import java.io.Serializable; - -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -@RegisterForReflection -@Schema(description = "Réponse de révocation de sessions") -public class SessionsRevokedDTO implements Serializable { - @Schema(description = "Nombre de sessions révoquées") - private int count; -} +package dev.lions.user.manager.dto.user; + +import io.quarkus.runtime.annotations.RegisterForReflection; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.eclipse.microprofile.openapi.annotations.media.Schema; + +import java.io.Serializable; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@RegisterForReflection +@Schema(description = "Réponse de révocation de sessions") +public class SessionsRevokedDTO implements Serializable { + @Schema(description = "Nombre de sessions révoquées") + private int count; +} diff --git a/src/main/java/dev/lions/user/manager/dto/user/UserDTO.java b/src/main/java/dev/lions/user/manager/dto/user/UserDTO.java index 520b01a..da9d5f5 100644 --- a/src/main/java/dev/lions/user/manager/dto/user/UserDTO.java +++ b/src/main/java/dev/lions/user/manager/dto/user/UserDTO.java @@ -1,211 +1,211 @@ -package dev.lions.user.manager.dto.user; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonInclude; -import dev.lions.user.manager.dto.base.BaseDTO; -import dev.lions.user.manager.enums.user.StatutUser; -import jakarta.validation.constraints.Email; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.Pattern; -import jakarta.validation.constraints.Size; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; -import lombok.experimental.SuperBuilder; -import org.eclipse.microprofile.openapi.annotations.media.Schema; -import io.quarkus.runtime.annotations.RegisterForReflection; - -import java.time.LocalDateTime; -import java.util.List; -import java.util.Map; - -/** - * DTO représentant un utilisateur Keycloak - * Mappé depuis la représentation UserRepresentation de Keycloak Admin API - */ -@Data -@SuperBuilder -@NoArgsConstructor -@AllArgsConstructor -@EqualsAndHashCode(callSuper = true) -@JsonInclude(JsonInclude.Include.NON_NULL) -@Schema(description = "Utilisateur Keycloak") -@RegisterForReflection -public class UserDTO extends BaseDTO { - - private static final long serialVersionUID = 1L; - - // Informations de base - @NotBlank(message = "Le nom d'utilisateur est obligatoire") - @Size(min = 3, max = 100, message = "Le nom d'utilisateur doit contenir entre 3 et 100 caractères") - @Pattern(regexp = "^[a-zA-Z0-9._-]+$", message = "Le nom d'utilisateur ne peut contenir que des lettres, chiffres, points, tirets et underscores") - @Schema(description = "Nom d'utilisateur unique", example = "jdupont", required = true) - private String username; - - @NotBlank(message = "L'email est obligatoire") - @Email(message = "Format d'email invalide") - @Schema(description = "Adresse email", example = "jean.dupont@lions.dev", required = true) - private String email; - - @Schema(description = "Email vérifié", example = "true") - private Boolean emailVerified; - - @NotBlank(message = "Le prénom est obligatoire") - @Size(min = 2, max = 100, message = "Le prénom doit contenir entre 2 et 100 caractères") - @Schema(description = "Prénom", example = "Jean", required = true) - private String prenom; - - @NotBlank(message = "Le nom est obligatoire") - @Size(min = 2, max = 100, message = "Le nom doit contenir entre 2 et 100 caractères") - @Schema(description = "Nom de famille", example = "Dupont", required = true) - private String nom; - - // Statut - @Schema(description = "Statut de l'utilisateur", example = "ACTIF") - private StatutUser statut; - - @Schema(description = "Compte activé", example = "true") - private Boolean enabled; - - // Informations supplémentaires - @Schema(description = "Numéro de téléphone", example = "+225 07 12 34 56 78") - private String telephone; - - @Schema(description = "Organisation/Entreprise", example = "Lions Dev") - private String organisation; - - @Schema(description = "Département", example = "IT") - private String departement; - - @Schema(description = "Fonction/Poste", example = "Développeur Senior") - private String fonction; - - @Schema(description = "Pays", example = "Côte d'Ivoire") - private String pays; - - @Schema(description = "Ville", example = "Abidjan") - private String ville; - - @Schema(description = "Langue préférée", example = "fr") - private String langue; - - @Schema(description = "Fuseau horaire", example = "Africa/Abidjan") - private String timezone; - - // Realm et rôles - @Schema(description = "Realm Keycloak", example = "btpxpress") - private String realmName; - - @Schema(description = "Liste des rôles Realm assignés") - private List realmRoles; - - @Schema(description = "Liste des rôles Client assignés") - private Map> clientRoles; - - @Schema(description = "Liste des groupes auxquels appartient l'utilisateur") - private List groups; - - // Dates importantes - @Schema(description = "Date de dernière connexion", example = "2025-01-15T10:30:00") - @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") - private LocalDateTime derniereConnexion; - - @Schema(description = "Date d'expiration du compte", example = "2026-01-15T23:59:59") - @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") - private LocalDateTime dateExpiration; - - @Schema(description = "Date de verrouillage du compte", example = "2025-01-15T16:00:00") - @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") - private LocalDateTime dateVerrouillage; - - // Attributs personnalisés Keycloak - @Schema(description = "Attributs personnalisés Keycloak") - private Map> attributes; - - // Actions requises - @Schema(description = "Actions requises (ex: UPDATE_PASSWORD, VERIFY_EMAIL)") - private List requiredActions; - - // Fédération - @Schema(description = "Fournisseur d'identité fédéré", example = "google") - private String federatedIdentityProvider; - - @Schema(description = "Lien d'identité fédérée") - private List federatedIdentities; - - // Crédentiels temporaires - @Schema(description = "Mot de passe temporaire (création uniquement)") - private String temporaryPassword; - - @Schema(description = "Indique si le mot de passe est temporaire") - private Boolean temporaryPasswordFlag; - - // Informations de session - @Schema(description = "Nombre de sessions actives", example = "2") - private Integer activeSessions; - - @Schema(description = "Nombre d'échecs de connexion", example = "0") - private Integer failedLoginAttempts; - - // Audit - @Schema(description = "Raison de la dernière modification") - private String raisonModification; - - @Schema(description = "Commentaires administratifs") - private String commentaires; - - /** - * Retourne le nom complet de l'utilisateur - * @return prénom + nom - */ - public String getNomComplet() { - if (prenom != null && nom != null) { - return prenom + " " + nom; - } - return username; - } - - /** - * Détermine si l'utilisateur est actif - * @return true si statut ACTIF et enabled - */ - public boolean isActif() { - return statut == StatutUser.ACTIF && Boolean.TRUE.equals(enabled); - } - - /** - * Détermine si le compte a expiré - * @return true si dateExpiration est passée - */ - public boolean isExpire() { - return dateExpiration != null && dateExpiration.isBefore(LocalDateTime.now()); - } - - /** - * Détermine si l'utilisateur a des actions requises - * @return true si des actions sont requises - */ - public boolean hasRequiredActions() { - return requiredActions != null && !requiredActions.isEmpty(); - } - - /** - * DTO pour identité fédérée - */ - @Data - @NoArgsConstructor - @AllArgsConstructor - @SuperBuilder - @Schema(description = "Identité fédérée") - public static class FederatedIdentityDTO { - @Schema(description = "Fournisseur d'identité", example = "google") - private String identityProvider; - - @Schema(description = "ID utilisateur chez le fournisseur") - private String userId; - - @Schema(description = "Nom d'utilisateur chez le fournisseur") - private String userName; - } -} +package dev.lions.user.manager.dto.user; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonInclude; +import dev.lions.user.manager.dto.base.BaseDTO; +import dev.lions.user.manager.enums.user.StatutUser; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; +import org.eclipse.microprofile.openapi.annotations.media.Schema; +import io.quarkus.runtime.annotations.RegisterForReflection; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; + +/** + * DTO représentant un utilisateur Keycloak + * Mappé depuis la représentation UserRepresentation de Keycloak Admin API + */ +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +@Schema(description = "Utilisateur Keycloak") +@RegisterForReflection +public class UserDTO extends BaseDTO { + + private static final long serialVersionUID = 1L; + + // Informations de base + @NotBlank(message = "Le nom d'utilisateur est obligatoire") + @Size(min = 3, max = 100, message = "Le nom d'utilisateur doit contenir entre 3 et 100 caractères") + @Pattern(regexp = "^[a-zA-Z0-9._-]+$", message = "Le nom d'utilisateur ne peut contenir que des lettres, chiffres, points, tirets et underscores") + @Schema(description = "Nom d'utilisateur unique", example = "jdupont", required = true) + private String username; + + @NotBlank(message = "L'email est obligatoire") + @Email(message = "Format d'email invalide") + @Schema(description = "Adresse email", example = "jean.dupont@lions.dev", required = true) + private String email; + + @Schema(description = "Email vérifié", example = "true") + private Boolean emailVerified; + + @NotBlank(message = "Le prénom est obligatoire") + @Size(min = 2, max = 100, message = "Le prénom doit contenir entre 2 et 100 caractères") + @Schema(description = "Prénom", example = "Jean", required = true) + private String prenom; + + @NotBlank(message = "Le nom est obligatoire") + @Size(min = 2, max = 100, message = "Le nom doit contenir entre 2 et 100 caractères") + @Schema(description = "Nom de famille", example = "Dupont", required = true) + private String nom; + + // Statut + @Schema(description = "Statut de l'utilisateur", example = "ACTIF") + private StatutUser statut; + + @Schema(description = "Compte activé", example = "true") + private Boolean enabled; + + // Informations supplémentaires + @Schema(description = "Numéro de téléphone", example = "+225 07 12 34 56 78") + private String telephone; + + @Schema(description = "Organisation/Entreprise", example = "Lions Dev") + private String organisation; + + @Schema(description = "Département", example = "IT") + private String departement; + + @Schema(description = "Fonction/Poste", example = "Développeur Senior") + private String fonction; + + @Schema(description = "Pays", example = "Côte d'Ivoire") + private String pays; + + @Schema(description = "Ville", example = "Abidjan") + private String ville; + + @Schema(description = "Langue préférée", example = "fr") + private String langue; + + @Schema(description = "Fuseau horaire", example = "Africa/Abidjan") + private String timezone; + + // Realm et rôles + @Schema(description = "Realm Keycloak", example = "btpxpress") + private String realmName; + + @Schema(description = "Liste des rôles Realm assignés") + private List realmRoles; + + @Schema(description = "Liste des rôles Client assignés") + private Map> clientRoles; + + @Schema(description = "Liste des groupes auxquels appartient l'utilisateur") + private List groups; + + // Dates importantes + @Schema(description = "Date de dernière connexion", example = "2025-01-15T10:30:00") + @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") + private LocalDateTime derniereConnexion; + + @Schema(description = "Date d'expiration du compte", example = "2026-01-15T23:59:59") + @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") + private LocalDateTime dateExpiration; + + @Schema(description = "Date de verrouillage du compte", example = "2025-01-15T16:00:00") + @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") + private LocalDateTime dateVerrouillage; + + // Attributs personnalisés Keycloak + @Schema(description = "Attributs personnalisés Keycloak") + private Map> attributes; + + // Actions requises + @Schema(description = "Actions requises (ex: UPDATE_PASSWORD, VERIFY_EMAIL)") + private List requiredActions; + + // Fédération + @Schema(description = "Fournisseur d'identité fédéré", example = "google") + private String federatedIdentityProvider; + + @Schema(description = "Lien d'identité fédérée") + private List federatedIdentities; + + // Crédentiels temporaires + @Schema(description = "Mot de passe temporaire (création uniquement)") + private String temporaryPassword; + + @Schema(description = "Indique si le mot de passe est temporaire") + private Boolean temporaryPasswordFlag; + + // Informations de session + @Schema(description = "Nombre de sessions actives", example = "2") + private Integer activeSessions; + + @Schema(description = "Nombre d'échecs de connexion", example = "0") + private Integer failedLoginAttempts; + + // Audit + @Schema(description = "Raison de la dernière modification") + private String raisonModification; + + @Schema(description = "Commentaires administratifs") + private String commentaires; + + /** + * Retourne le nom complet de l'utilisateur + * @return prénom + nom + */ + public String getNomComplet() { + if (prenom != null && nom != null) { + return prenom + " " + nom; + } + return username; + } + + /** + * Détermine si l'utilisateur est actif + * @return true si statut ACTIF et enabled + */ + public boolean isActif() { + return statut == StatutUser.ACTIF && Boolean.TRUE.equals(enabled); + } + + /** + * Détermine si le compte a expiré + * @return true si dateExpiration est passée + */ + public boolean isExpire() { + return dateExpiration != null && dateExpiration.isBefore(LocalDateTime.now()); + } + + /** + * Détermine si l'utilisateur a des actions requises + * @return true si des actions sont requises + */ + public boolean hasRequiredActions() { + return requiredActions != null && !requiredActions.isEmpty(); + } + + /** + * DTO pour identité fédérée + */ + @Data + @NoArgsConstructor + @AllArgsConstructor + @SuperBuilder + @Schema(description = "Identité fédérée") + public static class FederatedIdentityDTO { + @Schema(description = "Fournisseur d'identité", example = "google") + private String identityProvider; + + @Schema(description = "ID utilisateur chez le fournisseur") + private String userId; + + @Schema(description = "Nom d'utilisateur chez le fournisseur") + private String userName; + } +} diff --git a/src/main/java/dev/lions/user/manager/dto/user/UserSearchCriteriaDTO.java b/src/main/java/dev/lions/user/manager/dto/user/UserSearchCriteriaDTO.java index 0fe5a2f..9596e62 100644 --- a/src/main/java/dev/lions/user/manager/dto/user/UserSearchCriteriaDTO.java +++ b/src/main/java/dev/lions/user/manager/dto/user/UserSearchCriteriaDTO.java @@ -1,193 +1,193 @@ -package dev.lions.user.manager.dto.user; - -import com.fasterxml.jackson.annotation.JsonInclude; -import dev.lions.user.manager.enums.user.StatutUser; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.eclipse.microprofile.openapi.annotations.media.Schema; - -import java.io.Serializable; -import java.time.LocalDateTime; -import java.util.List; - -/** - * Critères de recherche pour les utilisateurs - * Utilisé pour filtrer les utilisateurs via l'API Keycloak Admin - */ -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -@JsonInclude(JsonInclude.Include.NON_NULL) -@Schema(description = "Critères de recherche d'utilisateurs") -public class UserSearchCriteriaDTO implements Serializable { - - private static final long serialVersionUID = 1L; - - // Recherche textuelle - @Schema(description = "Terme de recherche générale (username, email, nom, prénom)", example = "dupont") - private String searchTerm; - - @Schema(description = "Nom d'utilisateur exact", example = "jdupont") - private String username; - - @Schema(description = "Email exact", example = "jean.dupont@lions.dev") - private String email; - - @Schema(description = "Prénom", example = "Jean") - private String prenom; - - @Schema(description = "Nom de famille", example = "Dupont") - private String nom; - - @Schema(description = "Numéro de téléphone", example = "+225 01 02 03 04 05") - private String telephone; - - // Filtres de statut - @Schema(description = "Statut de l'utilisateur", example = "ACTIF") - private StatutUser statut; - - @Schema(description = "Compte activé", example = "true") - private Boolean enabled; - - @Schema(description = "Email vérifié", example = "true") - private Boolean emailVerified; - - // Filtres de rôle et groupe - @Schema(description = "Liste des rôles Realm à filtrer") - private List realmRoles; - - @Schema(description = "Liste des rôles Client à filtrer") - private List clientRoles; - - @Schema(description = "Liste des groupes à filtrer") - private List groups; - - @Schema(description = "Nom du client pour filtrer par rôles client", example = "btpxpress-app") - private String clientName; - - // Filtres organisationnels - @Schema(description = "Organisation/Entreprise", example = "Lions Dev") - private String organisation; - - @Schema(description = "Département", example = "IT") - private String departement; - - @Schema(description = "Fonction/Poste", example = "Développeur") - private String fonction; - - @Schema(description = "Pays", example = "Côte d'Ivoire") - private String pays; - - @Schema(description = "Ville", example = "Abidjan") - private String ville; - - // Filtres temporels - @Schema(description = "Date de création minimum", example = "2025-01-01T00:00:00") - private LocalDateTime dateCreationMin; - - @Schema(description = "Date de création maximum", example = "2025-12-31T23:59:59") - private LocalDateTime dateCreationMax; - - @Schema(description = "Date de dernière connexion minimum", example = "2025-01-01T00:00:00") - private LocalDateTime derniereConnexionMin; - - @Schema(description = "Date de dernière connexion maximum", example = "2025-01-31T23:59:59") - private LocalDateTime derniereConnexionMax; - - // Filtres spéciaux - @Schema(description = "Utilisateurs avec actions requises uniquement", example = "true") - private Boolean hasRequiredActions; - - @Schema(description = "Utilisateurs verrouillés uniquement", example = "false") - private Boolean isLocked; - - @Schema(description = "Utilisateurs expirés uniquement", example = "false") - private Boolean isExpired; - - @Schema(description = "Utilisateurs avec sessions actives uniquement", example = "true") - private Boolean hasActiveSessions; - - // Realm - @Schema(description = "Nom du Realm à filtrer", example = "btpxpress") - private String realmName; - - // Pagination - @Schema(description = "Numéro de page (commence à 0)", example = "0", defaultValue = "0") - @Builder.Default - private Integer page = 0; - - @Schema(description = "Taille de la page", example = "20", defaultValue = "20") - @Builder.Default - private Integer pageSize = 20; - - @Schema(description = "Nombre maximum de résultats", example = "100") - private Integer maxResults; - - // Tri - @Schema(description = "Champ de tri (username, email, prenom, nom, dateCreation, derniereConnexion)", example = "username") - @Builder.Default - private String sortBy = "username"; - - @Schema(description = "Ordre de tri (ASC ou DESC)", example = "ASC") - @Builder.Default - private String sortOrder = "ASC"; - - // Options d'inclusion - @Schema(description = "Inclure les rôles dans les résultats", example = "true") - @Builder.Default - private Boolean includeRoles = false; - - @Schema(description = "Inclure les groupes dans les résultats", example = "true") - @Builder.Default - private Boolean includeGroups = false; - - @Schema(description = "Inclure les attributs personnalisés", example = "false") - @Builder.Default - private Boolean includeAttributes = false; - - @Schema(description = "Inclure les informations de session", example = "false") - @Builder.Default - private Boolean includeSessionInfo = false; - - /** - * Détermine si des filtres de recherche sont appliqués - * @return true si au moins un filtre est défini - */ - public boolean hasFilters() { - return searchTerm != null - || username != null - || email != null - || prenom != null - || nom != null - || statut != null - || enabled != null - || emailVerified != null - || (realmRoles != null && !realmRoles.isEmpty()) - || (clientRoles != null && !clientRoles.isEmpty()) - || (groups != null && !groups.isEmpty()) - || organisation != null - || departement != null - || fonction != null - || pays != null - || ville != null - || dateCreationMin != null - || dateCreationMax != null - || derniereConnexionMin != null - || derniereConnexionMax != null - || hasRequiredActions != null - || isLocked != null - || isExpired != null - || hasActiveSessions != null; - } - - /** - * Calcule l'offset pour la pagination Keycloak - * @return offset calculé à partir de page et pageSize - */ - public int getOffset() { - return page * pageSize; - } -} +package dev.lions.user.manager.dto.user; + +import com.fasterxml.jackson.annotation.JsonInclude; +import dev.lions.user.manager.enums.user.StatutUser; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.eclipse.microprofile.openapi.annotations.media.Schema; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.util.List; + +/** + * Critères de recherche pour les utilisateurs + * Utilisé pour filtrer les utilisateurs via l'API Keycloak Admin + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@Schema(description = "Critères de recherche d'utilisateurs") +public class UserSearchCriteriaDTO implements Serializable { + + private static final long serialVersionUID = 1L; + + // Recherche textuelle + @Schema(description = "Terme de recherche générale (username, email, nom, prénom)", example = "dupont") + private String searchTerm; + + @Schema(description = "Nom d'utilisateur exact", example = "jdupont") + private String username; + + @Schema(description = "Email exact", example = "jean.dupont@lions.dev") + private String email; + + @Schema(description = "Prénom", example = "Jean") + private String prenom; + + @Schema(description = "Nom de famille", example = "Dupont") + private String nom; + + @Schema(description = "Numéro de téléphone", example = "+225 01 02 03 04 05") + private String telephone; + + // Filtres de statut + @Schema(description = "Statut de l'utilisateur", example = "ACTIF") + private StatutUser statut; + + @Schema(description = "Compte activé", example = "true") + private Boolean enabled; + + @Schema(description = "Email vérifié", example = "true") + private Boolean emailVerified; + + // Filtres de rôle et groupe + @Schema(description = "Liste des rôles Realm à filtrer") + private List realmRoles; + + @Schema(description = "Liste des rôles Client à filtrer") + private List clientRoles; + + @Schema(description = "Liste des groupes à filtrer") + private List groups; + + @Schema(description = "Nom du client pour filtrer par rôles client", example = "btpxpress-app") + private String clientName; + + // Filtres organisationnels + @Schema(description = "Organisation/Entreprise", example = "Lions Dev") + private String organisation; + + @Schema(description = "Département", example = "IT") + private String departement; + + @Schema(description = "Fonction/Poste", example = "Développeur") + private String fonction; + + @Schema(description = "Pays", example = "Côte d'Ivoire") + private String pays; + + @Schema(description = "Ville", example = "Abidjan") + private String ville; + + // Filtres temporels + @Schema(description = "Date de création minimum", example = "2025-01-01T00:00:00") + private LocalDateTime dateCreationMin; + + @Schema(description = "Date de création maximum", example = "2025-12-31T23:59:59") + private LocalDateTime dateCreationMax; + + @Schema(description = "Date de dernière connexion minimum", example = "2025-01-01T00:00:00") + private LocalDateTime derniereConnexionMin; + + @Schema(description = "Date de dernière connexion maximum", example = "2025-01-31T23:59:59") + private LocalDateTime derniereConnexionMax; + + // Filtres spéciaux + @Schema(description = "Utilisateurs avec actions requises uniquement", example = "true") + private Boolean hasRequiredActions; + + @Schema(description = "Utilisateurs verrouillés uniquement", example = "false") + private Boolean isLocked; + + @Schema(description = "Utilisateurs expirés uniquement", example = "false") + private Boolean isExpired; + + @Schema(description = "Utilisateurs avec sessions actives uniquement", example = "true") + private Boolean hasActiveSessions; + + // Realm + @Schema(description = "Nom du Realm à filtrer", example = "btpxpress") + private String realmName; + + // Pagination + @Schema(description = "Numéro de page (commence à 0)", example = "0", defaultValue = "0") + @Builder.Default + private Integer page = 0; + + @Schema(description = "Taille de la page", example = "20", defaultValue = "20") + @Builder.Default + private Integer pageSize = 20; + + @Schema(description = "Nombre maximum de résultats", example = "100") + private Integer maxResults; + + // Tri + @Schema(description = "Champ de tri (username, email, prenom, nom, dateCreation, derniereConnexion)", example = "username") + @Builder.Default + private String sortBy = "username"; + + @Schema(description = "Ordre de tri (ASC ou DESC)", example = "ASC") + @Builder.Default + private String sortOrder = "ASC"; + + // Options d'inclusion + @Schema(description = "Inclure les rôles dans les résultats", example = "true") + @Builder.Default + private Boolean includeRoles = false; + + @Schema(description = "Inclure les groupes dans les résultats", example = "true") + @Builder.Default + private Boolean includeGroups = false; + + @Schema(description = "Inclure les attributs personnalisés", example = "false") + @Builder.Default + private Boolean includeAttributes = false; + + @Schema(description = "Inclure les informations de session", example = "false") + @Builder.Default + private Boolean includeSessionInfo = false; + + /** + * Détermine si des filtres de recherche sont appliqués + * @return true si au moins un filtre est défini + */ + public boolean hasFilters() { + return searchTerm != null + || username != null + || email != null + || prenom != null + || nom != null + || statut != null + || enabled != null + || emailVerified != null + || (realmRoles != null && !realmRoles.isEmpty()) + || (clientRoles != null && !clientRoles.isEmpty()) + || (groups != null && !groups.isEmpty()) + || organisation != null + || departement != null + || fonction != null + || pays != null + || ville != null + || dateCreationMin != null + || dateCreationMax != null + || derniereConnexionMin != null + || derniereConnexionMax != null + || hasRequiredActions != null + || isLocked != null + || isExpired != null + || hasActiveSessions != null; + } + + /** + * Calcule l'offset pour la pagination Keycloak + * @return offset calculé à partir de page et pageSize + */ + public int getOffset() { + return page * pageSize; + } +} diff --git a/src/main/java/dev/lions/user/manager/dto/user/UserSearchResultDTO.java b/src/main/java/dev/lions/user/manager/dto/user/UserSearchResultDTO.java index d96661e..3e018c3 100644 --- a/src/main/java/dev/lions/user/manager/dto/user/UserSearchResultDTO.java +++ b/src/main/java/dev/lions/user/manager/dto/user/UserSearchResultDTO.java @@ -1,107 +1,107 @@ -package dev.lions.user.manager.dto.user; - -import com.fasterxml.jackson.annotation.JsonInclude; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.eclipse.microprofile.openapi.annotations.media.Schema; -import io.quarkus.runtime.annotations.RegisterForReflection; - -import java.io.Serializable; -import java.util.List; - -/** - * Résultat paginé de recherche d'utilisateurs - * Contient la liste des utilisateurs et les métadonnées de pagination - */ -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -@JsonInclude(JsonInclude.Include.NON_NULL) -@Schema(description = "Résultat paginé de recherche d'utilisateurs") -@RegisterForReflection -public class UserSearchResultDTO implements Serializable { - - private static final long serialVersionUID = 1L; - - @Schema(description = "Liste des utilisateurs trouvés") - private List users; - - @Schema(description = "Nombre total d'utilisateurs correspondant aux critères", example = "156") - private Long totalCount; - - @Schema(description = "Numéro de la page actuelle (commence à 0)", example = "0") - private Integer currentPage; - - @Schema(description = "Taille de la page", example = "20") - private Integer pageSize; - - @Schema(description = "Nombre total de pages", example = "8") - private Integer totalPages; - - @Schema(description = "Indique s'il y a une page suivante", example = "true") - private Boolean hasNextPage; - - @Schema(description = "Indique s'il y a une page précédente", example = "false") - private Boolean hasPreviousPage; - - @Schema(description = "Index du premier élément de la page", example = "0") - private Integer firstElement; - - @Schema(description = "Index du dernier élément de la page", example = "19") - private Integer lastElement; - - @Schema(description = "Indique si la page est vide", example = "false") - private Boolean isEmpty; - - @Schema(description = "Indique si c'est la première page", example = "true") - private Boolean isFirstPage; - - @Schema(description = "Indique si c'est la dernière page", example = "false") - private Boolean isLastPage; - - @Schema(description = "Critères de recherche utilisés") - private UserSearchCriteriaDTO criteria; - - @Schema(description = "Temps d'exécution de la recherche en millisecondes", example = "145") - private Long executionTimeMs; - - /** - * Construit un résultat de recherche à partir d'une liste d'utilisateurs - * @param users liste des utilisateurs - * @param criteria critères de recherche - * @param totalCount nombre total de résultats - * @return UserSearchResultDTO - */ - public static UserSearchResultDTO of(List users, UserSearchCriteriaDTO criteria, Long totalCount) { - int pageSize = criteria.getPageSize(); - int currentPage = criteria.getPage(); - long totalPages = (totalCount + pageSize - 1) / pageSize; - - return UserSearchResultDTO.builder() - .users(users) - .totalCount(totalCount) - .currentPage(currentPage) - .pageSize(pageSize) - .totalPages((int) totalPages) - .hasNextPage(currentPage < totalPages - 1) - .hasPreviousPage(currentPage > 0) - .firstElement(currentPage * pageSize) - .lastElement(Math.min((currentPage + 1) * pageSize - 1, totalCount.intValue())) - .isEmpty(users == null || users.isEmpty()) - .isFirstPage(currentPage == 0) - .isLastPage(currentPage >= totalPages - 1) - .criteria(criteria) - .build(); - } - - /** - * Retourne le nombre d'utilisateurs dans la page courante - * @return nombre d'utilisateurs - */ - public int getCurrentPageSize() { - return users != null ? users.size() : 0; - } -} +package dev.lions.user.manager.dto.user; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.eclipse.microprofile.openapi.annotations.media.Schema; +import io.quarkus.runtime.annotations.RegisterForReflection; + +import java.io.Serializable; +import java.util.List; + +/** + * Résultat paginé de recherche d'utilisateurs + * Contient la liste des utilisateurs et les métadonnées de pagination + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@Schema(description = "Résultat paginé de recherche d'utilisateurs") +@RegisterForReflection +public class UserSearchResultDTO implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "Liste des utilisateurs trouvés") + private List users; + + @Schema(description = "Nombre total d'utilisateurs correspondant aux critères", example = "156") + private Long totalCount; + + @Schema(description = "Numéro de la page actuelle (commence à 0)", example = "0") + private Integer currentPage; + + @Schema(description = "Taille de la page", example = "20") + private Integer pageSize; + + @Schema(description = "Nombre total de pages", example = "8") + private Integer totalPages; + + @Schema(description = "Indique s'il y a une page suivante", example = "true") + private Boolean hasNextPage; + + @Schema(description = "Indique s'il y a une page précédente", example = "false") + private Boolean hasPreviousPage; + + @Schema(description = "Index du premier élément de la page", example = "0") + private Integer firstElement; + + @Schema(description = "Index du dernier élément de la page", example = "19") + private Integer lastElement; + + @Schema(description = "Indique si la page est vide", example = "false") + private Boolean isEmpty; + + @Schema(description = "Indique si c'est la première page", example = "true") + private Boolean isFirstPage; + + @Schema(description = "Indique si c'est la dernière page", example = "false") + private Boolean isLastPage; + + @Schema(description = "Critères de recherche utilisés") + private UserSearchCriteriaDTO criteria; + + @Schema(description = "Temps d'exécution de la recherche en millisecondes", example = "145") + private Long executionTimeMs; + + /** + * Construit un résultat de recherche à partir d'une liste d'utilisateurs + * @param users liste des utilisateurs + * @param criteria critères de recherche + * @param totalCount nombre total de résultats + * @return UserSearchResultDTO + */ + public static UserSearchResultDTO of(List users, UserSearchCriteriaDTO criteria, Long totalCount) { + int pageSize = criteria.getPageSize(); + int currentPage = criteria.getPage(); + long totalPages = (totalCount + pageSize - 1) / pageSize; + + return UserSearchResultDTO.builder() + .users(users) + .totalCount(totalCount) + .currentPage(currentPage) + .pageSize(pageSize) + .totalPages((int) totalPages) + .hasNextPage(currentPage < totalPages - 1) + .hasPreviousPage(currentPage > 0) + .firstElement(currentPage * pageSize) + .lastElement(Math.min((currentPage + 1) * pageSize - 1, totalCount.intValue())) + .isEmpty(users == null || users.isEmpty()) + .isFirstPage(currentPage == 0) + .isLastPage(currentPage >= totalPages - 1) + .criteria(criteria) + .build(); + } + + /** + * Retourne le nombre d'utilisateurs dans la page courante + * @return nombre d'utilisateurs + */ + public int getCurrentPageSize() { + return users != null ? users.size() : 0; + } +} diff --git a/src/main/java/dev/lions/user/manager/enums/audit/TypeActionAudit.java b/src/main/java/dev/lions/user/manager/enums/audit/TypeActionAudit.java index b2c9a5a..2c3cb8f 100644 --- a/src/main/java/dev/lions/user/manager/enums/audit/TypeActionAudit.java +++ b/src/main/java/dev/lions/user/manager/enums/audit/TypeActionAudit.java @@ -1,116 +1,116 @@ -package dev.lions.user.manager.enums.audit; - -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import org.eclipse.microprofile.openapi.annotations.media.Schema; - -/** - * Type d'action effectuée sur une ressource - * Utilisé pour l'audit trail - */ -@Getter -@RequiredArgsConstructor -@Schema(description = "Type d'action pour l'audit") -public enum TypeActionAudit { - - // Actions Utilisateur - USER_CREATE("Création utilisateur", "USER", "CREATE"), - USER_UPDATE("Modification utilisateur", "USER", "UPDATE"), - USER_DELETE("Suppression utilisateur", "USER", "DELETE"), - USER_ACTIVATE("Activation utilisateur", "USER", "ACTIVATE"), - USER_DEACTIVATE("Désactivation utilisateur", "USER", "DEACTIVATE"), - USER_SUSPEND("Suspension utilisateur", "USER", "SUSPEND"), - USER_UNLOCK("Déverrouillage utilisateur", "USER", "UNLOCK"), - USER_PASSWORD_RESET("Réinitialisation mot de passe", "USER", "PASSWORD_RESET"), - USER_EMAIL_VERIFY("Vérification email", "USER", "EMAIL_VERIFY"), - USER_FORCE_LOGOUT("Déconnexion forcée", "USER", "FORCE_LOGOUT"), - USER_IMPORT("Import utilisateurs CSV", "USER", "IMPORT"), // Ajout - - // Actions Rôle - ROLE_CREATE("Création rôle", "ROLE", "CREATE"), - ROLE_UPDATE("Modification rôle", "ROLE", "UPDATE"), - ROLE_DELETE("Suppression rôle", "ROLE", "DELETE"), - ROLE_ASSIGN("Attribution rôle", "ROLE", "ASSIGN"), - ROLE_REVOKE("Révocation rôle", "ROLE", "REVOKE"), - ROLE_ADD_COMPOSITE("Ajout rôle composite", "ROLE", "ADD_COMPOSITE"), - ROLE_REMOVE_COMPOSITE("Retrait rôle composite", "ROLE", "REMOVE_COMPOSITE"), - - // Actions Groupe - GROUP_CREATE("Création groupe", "GROUP", "CREATE"), - GROUP_UPDATE("Modification groupe", "GROUP", "UPDATE"), - GROUP_DELETE("Suppression groupe", "GROUP", "DELETE"), - GROUP_ADD_MEMBER("Ajout membre groupe", "GROUP", "ADD_MEMBER"), - GROUP_REMOVE_MEMBER("Retrait membre groupe", "GROUP", "REMOVE_MEMBER"), - - // Actions Realm & Sync - REALM_SYNC("Synchronisation realm (Général)", "REALM", "SYNC"), - SYNC_USERS("Synchronisation utilisateurs", "REALM", "SYNC_USERS"), // Ajout - SYNC_ROLES("Synchronisation rôles", "REALM", "SYNC_ROLES"), // Ajout - REALM_EXPORT("Export realm", "REALM", "EXPORT"), - REALM_IMPORT("Import realm", "REALM", "IMPORT"), - REALM_ASSIGN("Assignation realm", "REALM", "ASSIGN"), - REALM_REVOKE("Révocation realm", "REALM", "REVOKE"), - REALM_ACTIVATE("Activation assignation realm", "REALM", "ACTIVATE"), - REALM_DEACTIVATE("Désactivation assignation realm", "REALM", "DEACTIVATE"), - REALM_SET_SUPER_ADMIN("Définition super admin", "REALM", "SET_SUPER_ADMIN"), - - // Actions Session - SESSION_CREATE("Création session", "SESSION", "CREATE"), - SESSION_DELETE("Suppression session", "SESSION", "DELETE"), - SESSION_REVOKE_ALL("Révocation toutes sessions", "SESSION", "REVOKE_ALL"), - - // Actions Système - SYSTEM_BACKUP("Sauvegarde système", "SYSTEM", "BACKUP"), - SYSTEM_RESTORE("Restauration système", "SYSTEM", "RESTORE"), - SYSTEM_CONFIG_CHANGE("Modification configuration", "SYSTEM", "CONFIG_CHANGE"); - - private final String libelle; - private final String ressourceType; - private final String actionType; - - /** - * Détermine si l'action concerne un utilisateur - */ - public boolean isUserAction() { - return ressourceType.equals("USER"); - } - - /** - * Détermine si l'action concerne un rôle - */ - public boolean isRoleAction() { - return ressourceType.equals("ROLE"); - } - - /** - * Détermine si l'action est une création - */ - public boolean isCreateAction() { - return actionType.equals("CREATE"); - } - - /** - * Détermine si l'action est une modification - */ - public boolean isUpdateAction() { - return actionType.equals("UPDATE"); - } - - /** - * Détermine si l'action est une suppression - */ - public boolean isDeleteAction() { - return actionType.equals("DELETE"); - } - - /** - * Détermine si l'action est critique (nécessite alerte) - */ - public boolean isCritical() { - return this == USER_DELETE - || this == ROLE_DELETE - || this == USER_SUSPEND - || this == SESSION_REVOKE_ALL - || this == SYSTEM_RESTORE; - } -} +package dev.lions.user.manager.enums.audit; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.eclipse.microprofile.openapi.annotations.media.Schema; + +/** + * Type d'action effectuée sur une ressource + * Utilisé pour l'audit trail + */ +@Getter +@RequiredArgsConstructor +@Schema(description = "Type d'action pour l'audit") +public enum TypeActionAudit { + + // Actions Utilisateur + USER_CREATE("Création utilisateur", "USER", "CREATE"), + USER_UPDATE("Modification utilisateur", "USER", "UPDATE"), + USER_DELETE("Suppression utilisateur", "USER", "DELETE"), + USER_ACTIVATE("Activation utilisateur", "USER", "ACTIVATE"), + USER_DEACTIVATE("Désactivation utilisateur", "USER", "DEACTIVATE"), + USER_SUSPEND("Suspension utilisateur", "USER", "SUSPEND"), + USER_UNLOCK("Déverrouillage utilisateur", "USER", "UNLOCK"), + USER_PASSWORD_RESET("Réinitialisation mot de passe", "USER", "PASSWORD_RESET"), + USER_EMAIL_VERIFY("Vérification email", "USER", "EMAIL_VERIFY"), + USER_FORCE_LOGOUT("Déconnexion forcée", "USER", "FORCE_LOGOUT"), + USER_IMPORT("Import utilisateurs CSV", "USER", "IMPORT"), // Ajout + + // Actions Rôle + ROLE_CREATE("Création rôle", "ROLE", "CREATE"), + ROLE_UPDATE("Modification rôle", "ROLE", "UPDATE"), + ROLE_DELETE("Suppression rôle", "ROLE", "DELETE"), + ROLE_ASSIGN("Attribution rôle", "ROLE", "ASSIGN"), + ROLE_REVOKE("Révocation rôle", "ROLE", "REVOKE"), + ROLE_ADD_COMPOSITE("Ajout rôle composite", "ROLE", "ADD_COMPOSITE"), + ROLE_REMOVE_COMPOSITE("Retrait rôle composite", "ROLE", "REMOVE_COMPOSITE"), + + // Actions Groupe + GROUP_CREATE("Création groupe", "GROUP", "CREATE"), + GROUP_UPDATE("Modification groupe", "GROUP", "UPDATE"), + GROUP_DELETE("Suppression groupe", "GROUP", "DELETE"), + GROUP_ADD_MEMBER("Ajout membre groupe", "GROUP", "ADD_MEMBER"), + GROUP_REMOVE_MEMBER("Retrait membre groupe", "GROUP", "REMOVE_MEMBER"), + + // Actions Realm & Sync + REALM_SYNC("Synchronisation realm (Général)", "REALM", "SYNC"), + SYNC_USERS("Synchronisation utilisateurs", "REALM", "SYNC_USERS"), // Ajout + SYNC_ROLES("Synchronisation rôles", "REALM", "SYNC_ROLES"), // Ajout + REALM_EXPORT("Export realm", "REALM", "EXPORT"), + REALM_IMPORT("Import realm", "REALM", "IMPORT"), + REALM_ASSIGN("Assignation realm", "REALM", "ASSIGN"), + REALM_REVOKE("Révocation realm", "REALM", "REVOKE"), + REALM_ACTIVATE("Activation assignation realm", "REALM", "ACTIVATE"), + REALM_DEACTIVATE("Désactivation assignation realm", "REALM", "DEACTIVATE"), + REALM_SET_SUPER_ADMIN("Définition super admin", "REALM", "SET_SUPER_ADMIN"), + + // Actions Session + SESSION_CREATE("Création session", "SESSION", "CREATE"), + SESSION_DELETE("Suppression session", "SESSION", "DELETE"), + SESSION_REVOKE_ALL("Révocation toutes sessions", "SESSION", "REVOKE_ALL"), + + // Actions Système + SYSTEM_BACKUP("Sauvegarde système", "SYSTEM", "BACKUP"), + SYSTEM_RESTORE("Restauration système", "SYSTEM", "RESTORE"), + SYSTEM_CONFIG_CHANGE("Modification configuration", "SYSTEM", "CONFIG_CHANGE"); + + private final String libelle; + private final String ressourceType; + private final String actionType; + + /** + * Détermine si l'action concerne un utilisateur + */ + public boolean isUserAction() { + return ressourceType.equals("USER"); + } + + /** + * Détermine si l'action concerne un rôle + */ + public boolean isRoleAction() { + return ressourceType.equals("ROLE"); + } + + /** + * Détermine si l'action est une création + */ + public boolean isCreateAction() { + return actionType.equals("CREATE"); + } + + /** + * Détermine si l'action est une modification + */ + public boolean isUpdateAction() { + return actionType.equals("UPDATE"); + } + + /** + * Détermine si l'action est une suppression + */ + public boolean isDeleteAction() { + return actionType.equals("DELETE"); + } + + /** + * Détermine si l'action est critique (nécessite alerte) + */ + public boolean isCritical() { + return this == USER_DELETE + || this == ROLE_DELETE + || this == USER_SUSPEND + || this == SESSION_REVOKE_ALL + || this == SYSTEM_RESTORE; + } +} diff --git a/src/main/java/dev/lions/user/manager/enums/role/TypeRole.java b/src/main/java/dev/lions/user/manager/enums/role/TypeRole.java index d1cc603..b1e8869 100644 --- a/src/main/java/dev/lions/user/manager/enums/role/TypeRole.java +++ b/src/main/java/dev/lions/user/manager/enums/role/TypeRole.java @@ -1,60 +1,60 @@ -package dev.lions.user.manager.enums.role; - -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import org.eclipse.microprofile.openapi.annotations.media.Schema; - -/** - * Type de rôle dans Keycloak - * Distingue les rôles au niveau Realm vs Client - */ -@Getter -@RequiredArgsConstructor -@Schema(description = "Type de rôle Keycloak") -public enum TypeRole { - - /** - * Rôle global au niveau du Realm - * Applicable à tous les clients du realm - */ - REALM_ROLE("Realm Role", "Rôle global applicable à tous les clients du realm", "realm-role"), - - /** - * Rôle spécifique à un client - * Limité au scope d'un client particulier - */ - CLIENT_ROLE("Client Role", "Rôle spécifique à un client particulier", "client-role"), - - /** - * Rôle composite (contient d'autres rôles) - */ - COMPOSITE_ROLE("Composite Role", "Rôle composite contenant d'autres rôles", "composite-role"); - - private final String libelle; - private final String description; - private final String codeKeycloak; - - /** - * Détermine si le rôle est au niveau realm - * @return true si c'est un realm role - */ - public boolean isRealmRole() { - return this == REALM_ROLE; - } - - /** - * Détermine si le rôle est au niveau client - * @return true si c'est un client role - */ - public boolean isClientRole() { - return this == CLIENT_ROLE; - } - - /** - * Détermine si le rôle est composite - * @return true si c'est un composite role - */ - public boolean isComposite() { - return this == COMPOSITE_ROLE; - } -} +package dev.lions.user.manager.enums.role; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.eclipse.microprofile.openapi.annotations.media.Schema; + +/** + * Type de rôle dans Keycloak + * Distingue les rôles au niveau Realm vs Client + */ +@Getter +@RequiredArgsConstructor +@Schema(description = "Type de rôle Keycloak") +public enum TypeRole { + + /** + * Rôle global au niveau du Realm + * Applicable à tous les clients du realm + */ + REALM_ROLE("Realm Role", "Rôle global applicable à tous les clients du realm", "realm-role"), + + /** + * Rôle spécifique à un client + * Limité au scope d'un client particulier + */ + CLIENT_ROLE("Client Role", "Rôle spécifique à un client particulier", "client-role"), + + /** + * Rôle composite (contient d'autres rôles) + */ + COMPOSITE_ROLE("Composite Role", "Rôle composite contenant d'autres rôles", "composite-role"); + + private final String libelle; + private final String description; + private final String codeKeycloak; + + /** + * Détermine si le rôle est au niveau realm + * @return true si c'est un realm role + */ + public boolean isRealmRole() { + return this == REALM_ROLE; + } + + /** + * Détermine si le rôle est au niveau client + * @return true si c'est un client role + */ + public boolean isClientRole() { + return this == CLIENT_ROLE; + } + + /** + * Détermine si le rôle est composite + * @return true si c'est un composite role + */ + public boolean isComposite() { + return this == COMPOSITE_ROLE; + } +} diff --git a/src/main/java/dev/lions/user/manager/enums/user/StatutUser.java b/src/main/java/dev/lions/user/manager/enums/user/StatutUser.java index bcf0834..6a3ec58 100644 --- a/src/main/java/dev/lions/user/manager/enums/user/StatutUser.java +++ b/src/main/java/dev/lions/user/manager/enums/user/StatutUser.java @@ -1,79 +1,79 @@ -package dev.lions.user.manager.enums.user; - -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import org.eclipse.microprofile.openapi.annotations.media.Schema; - -/** - * Statut d'un utilisateur dans Keycloak - * Mappé depuis le champ "enabled" et attributs personnalisés - */ -@Getter -@RequiredArgsConstructor -@Schema(description = "Statut d'un utilisateur") -public enum StatutUser { - - /** - * Utilisateur actif et opérationnel - */ - ACTIF("Actif", "Utilisateur actif avec accès complet", true), - - /** - * Utilisateur désactivé temporairement (peut être réactivé) - */ - INACTIF("Inactif", "Utilisateur désactivé temporairement", false), - - /** - * Utilisateur suspendu suite à une action administrative - */ - SUSPENDU("Suspendu", "Compte suspendu par un administrateur", false), - - /** - * Utilisateur en attente de validation - */ - EN_ATTENTE("En attente", "Compte en attente de validation", false), - - /** - * Utilisateur verrouillé suite à des tentatives échouées - */ - VERROUILLE("Verrouillé", "Compte verrouillé suite à plusieurs échecs d'authentification", false), - - /** - * Utilisateur dont le compte a expiré - */ - EXPIRE("Expiré", "Compte expiré et nécessite une réactivation", false), - - /** - * Utilisateur supprimé (soft delete) - */ - SUPPRIME("Supprimé", "Compte supprimé logiquement", false); - - private final String libelle; - private final String description; - private final boolean enabled; - - /** - * Convertit un statut Keycloak "enabled" en StatutUser - * @param enabled état enabled de Keycloak - * @return ACTIF si enabled=true, INACTIF sinon - */ - public static StatutUser fromEnabled(boolean enabled) { - return enabled ? ACTIF : INACTIF; - } - - /** - * Détermine si l'utilisateur peut se connecter - * @return true si le statut permet la connexion - */ - public boolean peutSeConnecter() { - return this == ACTIF; - } - - /** - * Détermine si l'utilisateur peut être réactivé - * @return true si le statut permet la réactivation - */ - public boolean peutEtreReactive() { - return this == INACTIF || this == SUSPENDU || this == EXPIRE; - } -} +package dev.lions.user.manager.enums.user; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.eclipse.microprofile.openapi.annotations.media.Schema; + +/** + * Statut d'un utilisateur dans Keycloak + * Mappé depuis le champ "enabled" et attributs personnalisés + */ +@Getter +@RequiredArgsConstructor +@Schema(description = "Statut d'un utilisateur") +public enum StatutUser { + + /** + * Utilisateur actif et opérationnel + */ + ACTIF("Actif", "Utilisateur actif avec accès complet", true), + + /** + * Utilisateur désactivé temporairement (peut être réactivé) + */ + INACTIF("Inactif", "Utilisateur désactivé temporairement", false), + + /** + * Utilisateur suspendu suite à une action administrative + */ + SUSPENDU("Suspendu", "Compte suspendu par un administrateur", false), + + /** + * Utilisateur en attente de validation + */ + EN_ATTENTE("En attente", "Compte en attente de validation", false), + + /** + * Utilisateur verrouillé suite à des tentatives échouées + */ + VERROUILLE("Verrouillé", "Compte verrouillé suite à plusieurs échecs d'authentification", false), + + /** + * Utilisateur dont le compte a expiré + */ + EXPIRE("Expiré", "Compte expiré et nécessite une réactivation", false), + + /** + * Utilisateur supprimé (soft delete) + */ + SUPPRIME("Supprimé", "Compte supprimé logiquement", false); + + private final String libelle; + private final String description; + private final boolean enabled; + + /** + * Convertit un statut Keycloak "enabled" en StatutUser + * @param enabled état enabled de Keycloak + * @return ACTIF si enabled=true, INACTIF sinon + */ + public static StatutUser fromEnabled(boolean enabled) { + return enabled ? ACTIF : INACTIF; + } + + /** + * Détermine si l'utilisateur peut se connecter + * @return true si le statut permet la connexion + */ + public boolean peutSeConnecter() { + return this == ACTIF; + } + + /** + * Détermine si l'utilisateur peut être réactivé + * @return true si le statut permet la réactivation + */ + public boolean peutEtreReactive() { + return this == INACTIF || this == SUSPENDU || this == EXPIRE; + } +} diff --git a/src/main/java/dev/lions/user/manager/service/AuditService.java b/src/main/java/dev/lions/user/manager/service/AuditService.java index ee6d729..64b0729 100644 --- a/src/main/java/dev/lions/user/manager/service/AuditService.java +++ b/src/main/java/dev/lions/user/manager/service/AuditService.java @@ -1,219 +1,219 @@ -package dev.lions.user.manager.service; - -import dev.lions.user.manager.dto.audit.AuditLogDTO; -import dev.lions.user.manager.enums.audit.TypeActionAudit; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; - -import java.time.LocalDateTime; -import java.util.List; -import java.util.Map; - -/** - * Service de gestion des logs d'audit - * Enregistre toutes les actions effectuées via l'API - */ -public interface AuditService { - - /** - * Enregistre une entrée d'audit - * @param auditLog entrée d'audit - * @return entrée enregistrée avec son ID - */ - AuditLogDTO logAction(@Valid @NotNull AuditLogDTO auditLog); - - /** - * Enregistre une action réussie - * @param typeAction type d'action - * @param ressourceType type de ressource - * @param ressourceId ID de la ressource - * @param ressourceName nom de la ressource - * @param realmName nom du realm - * @param acteurUserId ID de l'acteur - * @param description description - */ - void logSuccess(@NotNull TypeActionAudit typeAction, - @NotBlank String ressourceType, - String ressourceId, - String ressourceName, - @NotBlank String realmName, - @NotBlank String acteurUserId, - String description); - - /** - * Enregistre une action échouée - * @param typeAction type d'action - * @param ressourceType type de ressource - * @param ressourceId ID de la ressource - * @param ressourceName nom de la ressource - * @param realmName nom du realm - * @param acteurUserId ID de l'acteur - * @param errorCode code d'erreur - * @param errorMessage message d'erreur - */ - void logFailure(@NotNull TypeActionAudit typeAction, - @NotBlank String ressourceType, - String ressourceId, - String ressourceName, - @NotBlank String realmName, - @NotBlank String acteurUserId, - String errorCode, - String errorMessage); - - /** - * Recherche les logs d'audit par utilisateur acteur - * @param acteurUserId ID de l'utilisateur acteur - * @param dateDebut date de début - * @param dateFin date de fin - * @param page numéro de page - * @param pageSize taille de la page - * @return liste des logs - */ - List findByActeur(@NotBlank String acteurUserId, - LocalDateTime dateDebut, - LocalDateTime dateFin, - int page, - int pageSize); - - /** - * Recherche les logs d'audit par ressource - * @param ressourceType type de ressource - * @param ressourceId ID de la ressource - * @param dateDebut date de début - * @param dateFin date de fin - * @param page numéro de page - * @param pageSize taille de la page - * @return liste des logs - */ - List findByRessource(@NotBlank String ressourceType, - @NotBlank String ressourceId, - LocalDateTime dateDebut, - LocalDateTime dateFin, - int page, - int pageSize); - - /** - * Recherche les logs d'audit par type d'action - * @param typeAction type d'action - * @param realmName nom du realm - * @param dateDebut date de début - * @param dateFin date de fin - * @param page numéro de page - * @param pageSize taille de la page - * @return liste des logs - */ - List findByTypeAction(@NotNull TypeActionAudit typeAction, - @NotBlank String realmName, - LocalDateTime dateDebut, - LocalDateTime dateFin, - int page, - int pageSize); - - /** - * Recherche les logs d'audit par realm - * @param realmName nom du realm - * @param dateDebut date de début - * @param dateFin date de fin - * @param page numéro de page - * @param pageSize taille de la page - * @return liste des logs - */ - List findByRealm(@NotBlank String realmName, - LocalDateTime dateDebut, - LocalDateTime dateFin, - int page, - int pageSize); - - /** - * Recherche les actions échouées - * @param realmName nom du realm - * @param dateDebut date de début - * @param dateFin date de fin - * @param page numéro de page - * @param pageSize taille de la page - * @return liste des logs d'échec - */ - List findFailures(@NotBlank String realmName, - LocalDateTime dateDebut, - LocalDateTime dateFin, - int page, - int pageSize); - - /** - * Recherche les actions critiques - * @param realmName nom du realm - * @param dateDebut date de début - * @param dateFin date de fin - * @param page numéro de page - * @param pageSize taille de la page - * @return liste des logs critiques - */ - List findCriticalActions(@NotBlank String realmName, - LocalDateTime dateDebut, - LocalDateTime dateFin, - int page, - int pageSize); - - /** - * Compte les actions par type - * @param realmName nom du realm - * @param dateDebut date de début - * @param dateFin date de fin - * @return map type d'action -> nombre - */ - Map countByActionType(@NotBlank String realmName, - LocalDateTime dateDebut, - LocalDateTime dateFin); - - /** - * Compte les actions par utilisateur - * @param realmName nom du realm - * @param dateDebut date de début - * @param dateFin date de fin - * @return map username -> nombre d'actions - */ - Map countByActeur(@NotBlank String realmName, - LocalDateTime dateDebut, - LocalDateTime dateFin); - - /** - * Compte les actions réussies vs échouées - * @param realmName nom du realm - * @param dateDebut date de début - * @param dateFin date de fin - * @return map "success" -> count, "failure" -> count - */ - Map countSuccessVsFailure(@NotBlank String realmName, - LocalDateTime dateDebut, - LocalDateTime dateFin); - - /** - * Exporte les logs d'audit au format CSV - * @param realmName nom du realm - * @param dateDebut date de début - * @param dateFin date de fin - * @return contenu CSV - */ - String exportToCSV(@NotBlank String realmName, - LocalDateTime dateDebut, - LocalDateTime dateFin); - - /** - * Supprime les logs d'audit plus anciens qu'une date - * @param dateLimite date limite (logs antérieurs seront supprimés) - * @return nombre de logs supprimés - */ - long purgeOldLogs(@NotNull LocalDateTime dateLimite); - - /** - * Récupère les statistiques d'audit pour un dashboard - * @param realmName nom du realm - * @param dateDebut date de début - * @param dateFin date de fin - * @return map de statistiques - */ - Map getAuditStatistics(@NotBlank String realmName, - LocalDateTime dateDebut, - LocalDateTime dateFin); -} +package dev.lions.user.manager.service; + +import dev.lions.user.manager.dto.audit.AuditLogDTO; +import dev.lions.user.manager.enums.audit.TypeActionAudit; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; + +/** + * Service de gestion des logs d'audit + * Enregistre toutes les actions effectuées via l'API + */ +public interface AuditService { + + /** + * Enregistre une entrée d'audit + * @param auditLog entrée d'audit + * @return entrée enregistrée avec son ID + */ + AuditLogDTO logAction(@Valid @NotNull AuditLogDTO auditLog); + + /** + * Enregistre une action réussie + * @param typeAction type d'action + * @param ressourceType type de ressource + * @param ressourceId ID de la ressource + * @param ressourceName nom de la ressource + * @param realmName nom du realm + * @param acteurUserId ID de l'acteur + * @param description description + */ + void logSuccess(@NotNull TypeActionAudit typeAction, + @NotBlank String ressourceType, + String ressourceId, + String ressourceName, + @NotBlank String realmName, + @NotBlank String acteurUserId, + String description); + + /** + * Enregistre une action échouée + * @param typeAction type d'action + * @param ressourceType type de ressource + * @param ressourceId ID de la ressource + * @param ressourceName nom de la ressource + * @param realmName nom du realm + * @param acteurUserId ID de l'acteur + * @param errorCode code d'erreur + * @param errorMessage message d'erreur + */ + void logFailure(@NotNull TypeActionAudit typeAction, + @NotBlank String ressourceType, + String ressourceId, + String ressourceName, + @NotBlank String realmName, + @NotBlank String acteurUserId, + String errorCode, + String errorMessage); + + /** + * Recherche les logs d'audit par utilisateur acteur + * @param acteurUserId ID de l'utilisateur acteur + * @param dateDebut date de début + * @param dateFin date de fin + * @param page numéro de page + * @param pageSize taille de la page + * @return liste des logs + */ + List findByActeur(@NotBlank String acteurUserId, + LocalDateTime dateDebut, + LocalDateTime dateFin, + int page, + int pageSize); + + /** + * Recherche les logs d'audit par ressource + * @param ressourceType type de ressource + * @param ressourceId ID de la ressource + * @param dateDebut date de début + * @param dateFin date de fin + * @param page numéro de page + * @param pageSize taille de la page + * @return liste des logs + */ + List findByRessource(@NotBlank String ressourceType, + @NotBlank String ressourceId, + LocalDateTime dateDebut, + LocalDateTime dateFin, + int page, + int pageSize); + + /** + * Recherche les logs d'audit par type d'action + * @param typeAction type d'action + * @param realmName nom du realm + * @param dateDebut date de début + * @param dateFin date de fin + * @param page numéro de page + * @param pageSize taille de la page + * @return liste des logs + */ + List findByTypeAction(@NotNull TypeActionAudit typeAction, + @NotBlank String realmName, + LocalDateTime dateDebut, + LocalDateTime dateFin, + int page, + int pageSize); + + /** + * Recherche les logs d'audit par realm + * @param realmName nom du realm + * @param dateDebut date de début + * @param dateFin date de fin + * @param page numéro de page + * @param pageSize taille de la page + * @return liste des logs + */ + List findByRealm(@NotBlank String realmName, + LocalDateTime dateDebut, + LocalDateTime dateFin, + int page, + int pageSize); + + /** + * Recherche les actions échouées + * @param realmName nom du realm + * @param dateDebut date de début + * @param dateFin date de fin + * @param page numéro de page + * @param pageSize taille de la page + * @return liste des logs d'échec + */ + List findFailures(@NotBlank String realmName, + LocalDateTime dateDebut, + LocalDateTime dateFin, + int page, + int pageSize); + + /** + * Recherche les actions critiques + * @param realmName nom du realm + * @param dateDebut date de début + * @param dateFin date de fin + * @param page numéro de page + * @param pageSize taille de la page + * @return liste des logs critiques + */ + List findCriticalActions(@NotBlank String realmName, + LocalDateTime dateDebut, + LocalDateTime dateFin, + int page, + int pageSize); + + /** + * Compte les actions par type + * @param realmName nom du realm + * @param dateDebut date de début + * @param dateFin date de fin + * @return map type d'action -> nombre + */ + Map countByActionType(@NotBlank String realmName, + LocalDateTime dateDebut, + LocalDateTime dateFin); + + /** + * Compte les actions par utilisateur + * @param realmName nom du realm + * @param dateDebut date de début + * @param dateFin date de fin + * @return map username -> nombre d'actions + */ + Map countByActeur(@NotBlank String realmName, + LocalDateTime dateDebut, + LocalDateTime dateFin); + + /** + * Compte les actions réussies vs échouées + * @param realmName nom du realm + * @param dateDebut date de début + * @param dateFin date de fin + * @return map "success" -> count, "failure" -> count + */ + Map countSuccessVsFailure(@NotBlank String realmName, + LocalDateTime dateDebut, + LocalDateTime dateFin); + + /** + * Exporte les logs d'audit au format CSV + * @param realmName nom du realm + * @param dateDebut date de début + * @param dateFin date de fin + * @return contenu CSV + */ + String exportToCSV(@NotBlank String realmName, + LocalDateTime dateDebut, + LocalDateTime dateFin); + + /** + * Supprime les logs d'audit plus anciens qu'une date + * @param dateLimite date limite (logs antérieurs seront supprimés) + * @return nombre de logs supprimés + */ + long purgeOldLogs(@NotNull LocalDateTime dateLimite); + + /** + * Récupère les statistiques d'audit pour un dashboard + * @param realmName nom du realm + * @param dateDebut date de début + * @param dateFin date de fin + * @return map de statistiques + */ + Map getAuditStatistics(@NotBlank String realmName, + LocalDateTime dateDebut, + LocalDateTime dateFin); +} diff --git a/src/main/java/dev/lions/user/manager/service/RealmAuthorizationService.java b/src/main/java/dev/lions/user/manager/service/RealmAuthorizationService.java index 527ad63..e921543 100644 --- a/src/main/java/dev/lions/user/manager/service/RealmAuthorizationService.java +++ b/src/main/java/dev/lions/user/manager/service/RealmAuthorizationService.java @@ -1,132 +1,132 @@ -package dev.lions.user.manager.service; - -import dev.lions.user.manager.dto.realm.RealmAssignmentDTO; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; - -import java.util.List; -import java.util.Optional; - -/** - * Service de gestion des autorisations multi-tenant par realm - * Permet de contrôler quels utilisateurs peuvent administrer quels realms - */ -public interface RealmAuthorizationService { - - /** - * Récupère toutes les assignations de realms - * @return liste de toutes les assignations - */ - List getAllAssignments(); - - /** - * Récupère les assignations pour un utilisateur spécifique - * @param userId ID de l'utilisateur Keycloak - * @return liste des realms assignés à cet utilisateur - */ - List getAssignmentsByUser(@NotBlank String userId); - - /** - * Récupère les assignations pour un realm spécifique - * @param realmName nom du realm - * @return liste des utilisateurs ayant accès à ce realm - */ - List getAssignmentsByRealm(@NotBlank String realmName); - - /** - * Récupère une assignation spécifique - * @param assignmentId ID de l'assignation - * @return assignation ou Optional vide - */ - Optional getAssignmentById(@NotBlank String assignmentId); - - /** - * Vérifie si un utilisateur peut administrer un realm donné - * @param userId ID de l'utilisateur - * @param realmName nom du realm - * @return true si l'utilisateur peut administrer ce realm - */ - boolean canManageRealm(@NotBlank String userId, @NotBlank String realmName); - - /** - * Vérifie si un utilisateur est super admin (peut tout gérer) - * @param userId ID de l'utilisateur - * @return true si super admin - */ - boolean isSuperAdmin(@NotBlank String userId); - - /** - * Récupère la liste des realms qu'un utilisateur peut administrer - * @param userId ID de l'utilisateur - * @return liste des noms de realms, ou liste vide si super admin (peut tout gérer) - */ - List getAuthorizedRealms(@NotBlank String userId); - - /** - * Assigne un realm à un utilisateur - * @param assignment données de l'assignation - * @return assignation créée - */ - RealmAssignmentDTO assignRealmToUser(@Valid @NotNull RealmAssignmentDTO assignment); - - /** - * Retire l'accès d'un utilisateur à un realm - * @param userId ID de l'utilisateur - * @param realmName nom du realm - */ - void revokeRealmFromUser(@NotBlank String userId, @NotBlank String realmName); - - /** - * Retire toutes les assignations d'un utilisateur - * @param userId ID de l'utilisateur - */ - void revokeAllRealmsFromUser(@NotBlank String userId); - - /** - * Retire toutes les assignations pour un realm - * @param realmName nom du realm - */ - void revokeAllUsersFromRealm(@NotBlank String realmName); - - /** - * Définit un utilisateur comme super admin - * @param userId ID de l'utilisateur - * @param superAdmin true pour définir comme super admin, false pour retirer - */ - void setSuperAdmin(@NotBlank String userId, boolean superAdmin); - - /** - * Désactive une assignation (sans la supprimer) - * @param assignmentId ID de l'assignation - */ - void deactivateAssignment(@NotBlank String assignmentId); - - /** - * Réactive une assignation - * @param assignmentId ID de l'assignation - */ - void activateAssignment(@NotBlank String assignmentId); - - /** - * Compte le nombre d'assignations pour un utilisateur - * @param userId ID de l'utilisateur - * @return nombre d'assignations actives - */ - long countAssignmentsByUser(@NotBlank String userId); - - /** - * Compte le nombre d'utilisateurs ayant accès à un realm - * @param realmName nom du realm - * @return nombre d'utilisateurs - */ - long countUsersByRealm(@NotBlank String realmName); - - /** - * Vérifie si une assignation existe - * @param userId ID de l'utilisateur - * @param realmName nom du realm - * @return true si l'assignation existe - */ - boolean assignmentExists(@NotBlank String userId, @NotBlank String realmName); -} +package dev.lions.user.manager.service; + +import dev.lions.user.manager.dto.realm.RealmAssignmentDTO; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; + +import java.util.List; +import java.util.Optional; + +/** + * Service de gestion des autorisations multi-tenant par realm + * Permet de contrôler quels utilisateurs peuvent administrer quels realms + */ +public interface RealmAuthorizationService { + + /** + * Récupère toutes les assignations de realms + * @return liste de toutes les assignations + */ + List getAllAssignments(); + + /** + * Récupère les assignations pour un utilisateur spécifique + * @param userId ID de l'utilisateur Keycloak + * @return liste des realms assignés à cet utilisateur + */ + List getAssignmentsByUser(@NotBlank String userId); + + /** + * Récupère les assignations pour un realm spécifique + * @param realmName nom du realm + * @return liste des utilisateurs ayant accès à ce realm + */ + List getAssignmentsByRealm(@NotBlank String realmName); + + /** + * Récupère une assignation spécifique + * @param assignmentId ID de l'assignation + * @return assignation ou Optional vide + */ + Optional getAssignmentById(@NotBlank String assignmentId); + + /** + * Vérifie si un utilisateur peut administrer un realm donné + * @param userId ID de l'utilisateur + * @param realmName nom du realm + * @return true si l'utilisateur peut administrer ce realm + */ + boolean canManageRealm(@NotBlank String userId, @NotBlank String realmName); + + /** + * Vérifie si un utilisateur est super admin (peut tout gérer) + * @param userId ID de l'utilisateur + * @return true si super admin + */ + boolean isSuperAdmin(@NotBlank String userId); + + /** + * Récupère la liste des realms qu'un utilisateur peut administrer + * @param userId ID de l'utilisateur + * @return liste des noms de realms, ou liste vide si super admin (peut tout gérer) + */ + List getAuthorizedRealms(@NotBlank String userId); + + /** + * Assigne un realm à un utilisateur + * @param assignment données de l'assignation + * @return assignation créée + */ + RealmAssignmentDTO assignRealmToUser(@Valid @NotNull RealmAssignmentDTO assignment); + + /** + * Retire l'accès d'un utilisateur à un realm + * @param userId ID de l'utilisateur + * @param realmName nom du realm + */ + void revokeRealmFromUser(@NotBlank String userId, @NotBlank String realmName); + + /** + * Retire toutes les assignations d'un utilisateur + * @param userId ID de l'utilisateur + */ + void revokeAllRealmsFromUser(@NotBlank String userId); + + /** + * Retire toutes les assignations pour un realm + * @param realmName nom du realm + */ + void revokeAllUsersFromRealm(@NotBlank String realmName); + + /** + * Définit un utilisateur comme super admin + * @param userId ID de l'utilisateur + * @param superAdmin true pour définir comme super admin, false pour retirer + */ + void setSuperAdmin(@NotBlank String userId, boolean superAdmin); + + /** + * Désactive une assignation (sans la supprimer) + * @param assignmentId ID de l'assignation + */ + void deactivateAssignment(@NotBlank String assignmentId); + + /** + * Réactive une assignation + * @param assignmentId ID de l'assignation + */ + void activateAssignment(@NotBlank String assignmentId); + + /** + * Compte le nombre d'assignations pour un utilisateur + * @param userId ID de l'utilisateur + * @return nombre d'assignations actives + */ + long countAssignmentsByUser(@NotBlank String userId); + + /** + * Compte le nombre d'utilisateurs ayant accès à un realm + * @param realmName nom du realm + * @return nombre d'utilisateurs + */ + long countUsersByRealm(@NotBlank String realmName); + + /** + * Vérifie si une assignation existe + * @param userId ID de l'utilisateur + * @param realmName nom du realm + * @return true si l'assignation existe + */ + boolean assignmentExists(@NotBlank String userId, @NotBlank String realmName); +} diff --git a/src/main/java/dev/lions/user/manager/service/RoleService.java b/src/main/java/dev/lions/user/manager/service/RoleService.java index b38d361..1813a9f 100644 --- a/src/main/java/dev/lions/user/manager/service/RoleService.java +++ b/src/main/java/dev/lions/user/manager/service/RoleService.java @@ -1,226 +1,226 @@ -package dev.lions.user.manager.service; - -import dev.lions.user.manager.dto.role.RoleAssignmentDTO; -import dev.lions.user.manager.dto.role.RoleDTO; -import dev.lions.user.manager.enums.role.TypeRole; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; - -import java.util.List; -import java.util.Optional; - -/** - * Service de gestion des rôles Keycloak - * Utilise uniquement l'API Admin Keycloak (AUCUN accès direct à la DB) - */ -public interface RoleService { - - /** - * Récupère tous les rôles d'un realm - * @param realmName nom du realm - * @return liste des rôles - */ - List getAllRealmRoles(@NotBlank String realmName); - - /** - * Récupère tous les rôles d'un client - * @param realmName nom du realm - * @param clientName nom du client - * @return liste des rôles - */ - List getAllClientRoles(@NotBlank String realmName, @NotBlank String clientName); - - /** - * Récupère un rôle par son ID - * @param roleId ID du rôle - * @param realmName nom du realm - * @param typeRole type de rôle (REALM ou CLIENT) - * @param clientName nom du client (si CLIENT_ROLE) - * @return rôle ou Optional vide - */ - Optional getRoleById(@NotBlank String roleId, - @NotBlank String realmName, - @NotNull TypeRole typeRole, - String clientName); - - /** - * Récupère un rôle par son nom - * @param roleName nom du rôle - * @param realmName nom du realm - * @param typeRole type de rôle (REALM ou CLIENT) - * @param clientName nom du client (si CLIENT_ROLE) - * @return rôle ou Optional vide - */ - Optional getRoleByName(@NotBlank String roleName, - @NotBlank String realmName, - @NotNull TypeRole typeRole, - String clientName); - - /** - * Crée un nouveau rôle realm - * @param role données du rôle - * @param realmName nom du realm - * @return rôle créé - */ - RoleDTO createRealmRole(@Valid @NotNull RoleDTO role, @NotBlank String realmName); - - /** - * Crée un nouveau rôle client - * @param role données du rôle - * @param realmName nom du realm - * @param clientName nom du client - * @return rôle créé - */ - RoleDTO createClientRole(@Valid @NotNull RoleDTO role, - @NotBlank String realmName, - @NotBlank String clientName); - - /** - * Met à jour un rôle - * @param roleId ID du rôle - * @param role données modifiées - * @param realmName nom du realm - * @param typeRole type de rôle - * @param clientName nom du client (si CLIENT_ROLE) - * @return rôle mis à jour - */ - RoleDTO updateRole(@NotBlank String roleId, - @Valid @NotNull RoleDTO role, - @NotBlank String realmName, - @NotNull TypeRole typeRole, - String clientName); - - /** - * Supprime un rôle - * @param roleId ID du rôle - * @param realmName nom du realm - * @param typeRole type de rôle - * @param clientName nom du client (si CLIENT_ROLE) - */ - void deleteRole(@NotBlank String roleId, - @NotBlank String realmName, - @NotNull TypeRole typeRole, - String clientName); - - /** - * Assigne des rôles à un utilisateur - * @param assignment données d'attribution - */ - void assignRolesToUser(@Valid @NotNull RoleAssignmentDTO assignment); - - /** - * Révoque des rôles d'un utilisateur - * @param assignment données de révocation - */ - void revokeRolesFromUser(@Valid @NotNull RoleAssignmentDTO assignment); - - /** - * Récupère les rôles realm d'un utilisateur - * @param userId ID de l'utilisateur - * @param realmName nom du realm - * @return liste des rôles - */ - List getUserRealmRoles(@NotBlank String userId, @NotBlank String realmName); - - /** - * Récupère les rôles client d'un utilisateur - * @param userId ID de l'utilisateur - * @param realmName nom du realm - * @param clientName nom du client - * @return liste des rôles - */ - List getUserClientRoles(@NotBlank String userId, - @NotBlank String realmName, - @NotBlank String clientName); - - /** - * Récupère tous les rôles d'un utilisateur (realm + clients) - * @param userId ID de l'utilisateur - * @param realmName nom du realm - * @return liste des rôles - */ - List getAllUserRoles(@NotBlank String userId, @NotBlank String realmName); - - /** - * Ajoute un rôle composite - * @param parentRoleId ID du rôle parent - * @param childRoleIds IDs des rôles enfants à ajouter - * @param realmName nom du realm - * @param typeRole type du rôle parent - * @param clientName nom du client (si CLIENT_ROLE) - */ - void addCompositeRoles(@NotBlank String parentRoleId, - @NotNull List childRoleIds, - @NotBlank String realmName, - @NotNull TypeRole typeRole, - String clientName); - - /** - * Retire un rôle composite - * @param parentRoleId ID du rôle parent - * @param childRoleIds IDs des rôles enfants à retirer - * @param realmName nom du realm - * @param typeRole type du rôle parent - * @param clientName nom du client (si CLIENT_ROLE) - */ - void removeCompositeRoles(@NotBlank String parentRoleId, - @NotNull List childRoleIds, - @NotBlank String realmName, - @NotNull TypeRole typeRole, - String clientName); - - /** - * Récupère les rôles composites d'un rôle - * @param roleId ID du rôle - * @param realmName nom du realm - * @param typeRole type de rôle - * @param clientName nom du client (si CLIENT_ROLE) - * @return liste des rôles composites - */ - List getCompositeRoles(@NotBlank String roleId, - @NotBlank String realmName, - @NotNull TypeRole typeRole, - String clientName); - - /** - * Compte le nombre d'utilisateurs ayant un rôle - * @param roleId ID du rôle - * @param realmName nom du realm - * @param typeRole type de rôle - * @param clientName nom du client (si CLIENT_ROLE) - * @return nombre d'utilisateurs - */ - long countUsersWithRole(@NotBlank String roleId, - @NotBlank String realmName, - @NotNull TypeRole typeRole, - String clientName); - - /** - * Vérifie si un rôle existe - * @param roleName nom du rôle - * @param realmName nom du realm - * @param typeRole type de rôle - * @param clientName nom du client (si CLIENT_ROLE) - * @return true si existe - */ - boolean roleExists(@NotBlank String roleName, - @NotBlank String realmName, - @NotNull TypeRole typeRole, - String clientName); - - /** - * Vérifie si un utilisateur a un rôle spécifique - * @param userId ID de l'utilisateur - * @param roleName nom du rôle - * @param realmName nom du realm - * @param typeRole type de rôle - * @param clientName nom du client (si CLIENT_ROLE) - * @return true si l'utilisateur a le rôle - */ - boolean userHasRole(@NotBlank String userId, - @NotBlank String roleName, - @NotBlank String realmName, - @NotNull TypeRole typeRole, - String clientName); -} +package dev.lions.user.manager.service; + +import dev.lions.user.manager.dto.role.RoleAssignmentDTO; +import dev.lions.user.manager.dto.role.RoleDTO; +import dev.lions.user.manager.enums.role.TypeRole; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; + +import java.util.List; +import java.util.Optional; + +/** + * Service de gestion des rôles Keycloak + * Utilise uniquement l'API Admin Keycloak (AUCUN accès direct à la DB) + */ +public interface RoleService { + + /** + * Récupère tous les rôles d'un realm + * @param realmName nom du realm + * @return liste des rôles + */ + List getAllRealmRoles(@NotBlank String realmName); + + /** + * Récupère tous les rôles d'un client + * @param realmName nom du realm + * @param clientName nom du client + * @return liste des rôles + */ + List getAllClientRoles(@NotBlank String realmName, @NotBlank String clientName); + + /** + * Récupère un rôle par son ID + * @param roleId ID du rôle + * @param realmName nom du realm + * @param typeRole type de rôle (REALM ou CLIENT) + * @param clientName nom du client (si CLIENT_ROLE) + * @return rôle ou Optional vide + */ + Optional getRoleById(@NotBlank String roleId, + @NotBlank String realmName, + @NotNull TypeRole typeRole, + String clientName); + + /** + * Récupère un rôle par son nom + * @param roleName nom du rôle + * @param realmName nom du realm + * @param typeRole type de rôle (REALM ou CLIENT) + * @param clientName nom du client (si CLIENT_ROLE) + * @return rôle ou Optional vide + */ + Optional getRoleByName(@NotBlank String roleName, + @NotBlank String realmName, + @NotNull TypeRole typeRole, + String clientName); + + /** + * Crée un nouveau rôle realm + * @param role données du rôle + * @param realmName nom du realm + * @return rôle créé + */ + RoleDTO createRealmRole(@Valid @NotNull RoleDTO role, @NotBlank String realmName); + + /** + * Crée un nouveau rôle client + * @param role données du rôle + * @param realmName nom du realm + * @param clientName nom du client + * @return rôle créé + */ + RoleDTO createClientRole(@Valid @NotNull RoleDTO role, + @NotBlank String realmName, + @NotBlank String clientName); + + /** + * Met à jour un rôle + * @param roleId ID du rôle + * @param role données modifiées + * @param realmName nom du realm + * @param typeRole type de rôle + * @param clientName nom du client (si CLIENT_ROLE) + * @return rôle mis à jour + */ + RoleDTO updateRole(@NotBlank String roleId, + @Valid @NotNull RoleDTO role, + @NotBlank String realmName, + @NotNull TypeRole typeRole, + String clientName); + + /** + * Supprime un rôle + * @param roleId ID du rôle + * @param realmName nom du realm + * @param typeRole type de rôle + * @param clientName nom du client (si CLIENT_ROLE) + */ + void deleteRole(@NotBlank String roleId, + @NotBlank String realmName, + @NotNull TypeRole typeRole, + String clientName); + + /** + * Assigne des rôles à un utilisateur + * @param assignment données d'attribution + */ + void assignRolesToUser(@Valid @NotNull RoleAssignmentDTO assignment); + + /** + * Révoque des rôles d'un utilisateur + * @param assignment données de révocation + */ + void revokeRolesFromUser(@Valid @NotNull RoleAssignmentDTO assignment); + + /** + * Récupère les rôles realm d'un utilisateur + * @param userId ID de l'utilisateur + * @param realmName nom du realm + * @return liste des rôles + */ + List getUserRealmRoles(@NotBlank String userId, @NotBlank String realmName); + + /** + * Récupère les rôles client d'un utilisateur + * @param userId ID de l'utilisateur + * @param realmName nom du realm + * @param clientName nom du client + * @return liste des rôles + */ + List getUserClientRoles(@NotBlank String userId, + @NotBlank String realmName, + @NotBlank String clientName); + + /** + * Récupère tous les rôles d'un utilisateur (realm + clients) + * @param userId ID de l'utilisateur + * @param realmName nom du realm + * @return liste des rôles + */ + List getAllUserRoles(@NotBlank String userId, @NotBlank String realmName); + + /** + * Ajoute un rôle composite + * @param parentRoleId ID du rôle parent + * @param childRoleIds IDs des rôles enfants à ajouter + * @param realmName nom du realm + * @param typeRole type du rôle parent + * @param clientName nom du client (si CLIENT_ROLE) + */ + void addCompositeRoles(@NotBlank String parentRoleId, + @NotNull List childRoleIds, + @NotBlank String realmName, + @NotNull TypeRole typeRole, + String clientName); + + /** + * Retire un rôle composite + * @param parentRoleId ID du rôle parent + * @param childRoleIds IDs des rôles enfants à retirer + * @param realmName nom du realm + * @param typeRole type du rôle parent + * @param clientName nom du client (si CLIENT_ROLE) + */ + void removeCompositeRoles(@NotBlank String parentRoleId, + @NotNull List childRoleIds, + @NotBlank String realmName, + @NotNull TypeRole typeRole, + String clientName); + + /** + * Récupère les rôles composites d'un rôle + * @param roleId ID du rôle + * @param realmName nom du realm + * @param typeRole type de rôle + * @param clientName nom du client (si CLIENT_ROLE) + * @return liste des rôles composites + */ + List getCompositeRoles(@NotBlank String roleId, + @NotBlank String realmName, + @NotNull TypeRole typeRole, + String clientName); + + /** + * Compte le nombre d'utilisateurs ayant un rôle + * @param roleId ID du rôle + * @param realmName nom du realm + * @param typeRole type de rôle + * @param clientName nom du client (si CLIENT_ROLE) + * @return nombre d'utilisateurs + */ + long countUsersWithRole(@NotBlank String roleId, + @NotBlank String realmName, + @NotNull TypeRole typeRole, + String clientName); + + /** + * Vérifie si un rôle existe + * @param roleName nom du rôle + * @param realmName nom du realm + * @param typeRole type de rôle + * @param clientName nom du client (si CLIENT_ROLE) + * @return true si existe + */ + boolean roleExists(@NotBlank String roleName, + @NotBlank String realmName, + @NotNull TypeRole typeRole, + String clientName); + + /** + * Vérifie si un utilisateur a un rôle spécifique + * @param userId ID de l'utilisateur + * @param roleName nom du rôle + * @param realmName nom du realm + * @param typeRole type de rôle + * @param clientName nom du client (si CLIENT_ROLE) + * @return true si l'utilisateur a le rôle + */ + boolean userHasRole(@NotBlank String userId, + @NotBlank String roleName, + @NotBlank String realmName, + @NotNull TypeRole typeRole, + String clientName); +} diff --git a/src/main/java/dev/lions/user/manager/service/SyncService.java b/src/main/java/dev/lions/user/manager/service/SyncService.java index b0cfb91..b9600ab 100644 --- a/src/main/java/dev/lions/user/manager/service/SyncService.java +++ b/src/main/java/dev/lions/user/manager/service/SyncService.java @@ -1,65 +1,65 @@ -package dev.lions.user.manager.service; - -import jakarta.validation.constraints.NotBlank; - -import java.util.Map; - -/** - * Service de synchronisation avec Keycloak - * Permet la synchronisation des données entre différents realms - */ -public interface SyncService { - - /** - * Synchronise les utilisateurs d'un realm - * @param realmName nom du realm à synchroniser - * @return nombre d'utilisateurs synchronisés - */ - int syncUsersFromRealm(@NotBlank String realmName); - - /** - * Synchronise les rôles d'un realm - * @param realmName nom du realm à synchroniser - * @return nombre de rôles synchronisés - */ - int syncRolesFromRealm(@NotBlank String realmName); - - /** - * Synchronise tous les realms configurés - * @return map realm -> nombre d'éléments synchronisés - */ - Map syncAllRealms(); - - /** - * Vérifie la cohérence des données entre cache local et Keycloak - * @param realmName nom du realm - * @return rapport de cohérence - */ - Map checkDataConsistency(@NotBlank String realmName); - - /** - * Force la resynchronisation complète d'un realm - * @param realmName nom du realm - * @return statistiques de synchronisation - */ - Map forceSyncRealm(@NotBlank String realmName); - - /** - * Récupère le statut de la dernière synchronisation - * @param realmName nom du realm - * @return statut de synchronisation - */ - Map getLastSyncStatus(@NotBlank String realmName); - - /** - * Vérifie la disponibilité de Keycloak - * @return true si Keycloak est disponible - */ - boolean isKeycloakAvailable(); - - /** - * Récupère les informations de santé de Keycloak - * @return informations de santé - */ - Map getKeycloakHealthInfo(); -} +package dev.lions.user.manager.service; + +import jakarta.validation.constraints.NotBlank; + +import java.util.Map; + +/** + * Service de synchronisation avec Keycloak + * Permet la synchronisation des données entre différents realms + */ +public interface SyncService { + + /** + * Synchronise les utilisateurs d'un realm + * @param realmName nom du realm à synchroniser + * @return nombre d'utilisateurs synchronisés + */ + int syncUsersFromRealm(@NotBlank String realmName); + + /** + * Synchronise les rôles d'un realm + * @param realmName nom du realm à synchroniser + * @return nombre de rôles synchronisés + */ + int syncRolesFromRealm(@NotBlank String realmName); + + /** + * Synchronise tous les realms configurés + * @return map realm -> nombre d'éléments synchronisés + */ + Map syncAllRealms(); + + /** + * Vérifie la cohérence des données entre cache local et Keycloak + * @param realmName nom du realm + * @return rapport de cohérence + */ + Map checkDataConsistency(@NotBlank String realmName); + + /** + * Force la resynchronisation complète d'un realm + * @param realmName nom du realm + * @return statistiques de synchronisation + */ + Map forceSyncRealm(@NotBlank String realmName); + + /** + * Récupère le statut de la dernière synchronisation + * @param realmName nom du realm + * @return statut de synchronisation + */ + Map getLastSyncStatus(@NotBlank String realmName); + + /** + * Vérifie la disponibilité de Keycloak + * @return true si Keycloak est disponible + */ + boolean isKeycloakAvailable(); + + /** + * Récupère les informations de santé de Keycloak + * @return informations de santé + */ + Map getKeycloakHealthInfo(); +} diff --git a/src/main/java/dev/lions/user/manager/service/UserService.java b/src/main/java/dev/lions/user/manager/service/UserService.java index 8e26274..4f8236c 100644 --- a/src/main/java/dev/lions/user/manager/service/UserService.java +++ b/src/main/java/dev/lions/user/manager/service/UserService.java @@ -1,185 +1,185 @@ -package dev.lions.user.manager.service; - -import dev.lions.user.manager.dto.user.UserDTO; -import dev.lions.user.manager.dto.user.UserSearchCriteriaDTO; -import dev.lions.user.manager.dto.user.UserSearchResultDTO; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; - -import java.util.List; -import java.util.Optional; - -/** - * Service de gestion des utilisateurs Keycloak - * Utilise uniquement l'API Admin Keycloak (AUCUN accès direct à la DB) - */ -public interface UserService { - - /** - * Recherche des utilisateurs selon des critères - * @param criteria critères de recherche - * @return résultat paginé - */ - UserSearchResultDTO searchUsers(@Valid @NotNull UserSearchCriteriaDTO criteria); - - /** - * Récupère un utilisateur par son ID - * @param userId ID de l'utilisateur - * @param realmName nom du realm - * @return utilisateur ou Optional vide - */ - Optional getUserById(@NotBlank String userId, @NotBlank String realmName); - - /** - * Récupère un utilisateur par son username - * @param username username - * @param realmName nom du realm - * @return utilisateur ou Optional vide - */ - Optional getUserByUsername(@NotBlank String username, @NotBlank String realmName); - - /** - * Récupère un utilisateur par son email - * @param email email - * @param realmName nom du realm - * @return utilisateur ou Optional vide - */ - Optional getUserByEmail(@NotBlank String email, @NotBlank String realmName); - - /** - * Crée un nouvel utilisateur - * @param user données de l'utilisateur - * @param realmName nom du realm - * @return utilisateur créé avec son ID - */ - UserDTO createUser(@Valid @NotNull UserDTO user, @NotBlank String realmName); - - /** - * Met à jour un utilisateur existant - * @param userId ID de l'utilisateur - * @param user données modifiées - * @param realmName nom du realm - * @return utilisateur mis à jour - */ - UserDTO updateUser(@NotBlank String userId, @Valid @NotNull UserDTO user, @NotBlank String realmName); - - /** - * Supprime un utilisateur (soft ou hard delete selon configuration) - * @param userId ID de l'utilisateur - * @param realmName nom du realm - * @param hardDelete true pour suppression définitive, false pour soft delete - */ - void deleteUser(@NotBlank String userId, @NotBlank String realmName, boolean hardDelete); - - /** - * Active un utilisateur - * @param userId ID de l'utilisateur - * @param realmName nom du realm - */ - void activateUser(@NotBlank String userId, @NotBlank String realmName); - - /** - * Désactive un utilisateur - * @param userId ID de l'utilisateur - * @param realmName nom du realm - * @param raison raison de la désactivation - */ - void deactivateUser(@NotBlank String userId, @NotBlank String realmName, String raison); - - /** - * Suspend un utilisateur - * @param userId ID de l'utilisateur - * @param realmName nom du realm - * @param raison raison de la suspension - * @param duree durée de la suspension en jours (0 = indéfinie) - */ - void suspendUser(@NotBlank String userId, @NotBlank String realmName, String raison, int duree); - - /** - * Déverrouille un utilisateur - * @param userId ID de l'utilisateur - * @param realmName nom du realm - */ - void unlockUser(@NotBlank String userId, @NotBlank String realmName); - - /** - * Réinitialise le mot de passe d'un utilisateur - * @param userId ID de l'utilisateur - * @param realmName nom du realm - * @param temporaryPassword mot de passe temporaire - * @param temporary true si le mot de passe doit être changé à la prochaine connexion - */ - void resetPassword(@NotBlank String userId, @NotBlank String realmName, - @NotBlank String temporaryPassword, boolean temporary); - - /** - * Envoie un email de vérification - * @param userId ID de l'utilisateur - * @param realmName nom du realm - */ - void sendVerificationEmail(@NotBlank String userId, @NotBlank String realmName); - - /** - * Force la déconnexion de toutes les sessions d'un utilisateur - * @param userId ID de l'utilisateur - * @param realmName nom du realm - * @return nombre de sessions révoquées - */ - int logoutAllSessions(@NotBlank String userId, @NotBlank String realmName); - - /** - * Récupère les sessions actives d'un utilisateur - * @param userId ID de l'utilisateur - * @param realmName nom du realm - * @return liste des informations de session - */ - List getActiveSessions(@NotBlank String userId, @NotBlank String realmName); - - /** - * Compte le nombre d'utilisateurs selon des critères - * @param criteria critères de recherche - * @return nombre d'utilisateurs - */ - long countUsers(@NotNull UserSearchCriteriaDTO criteria); - - /** - * Récupère tous les utilisateurs d'un realm (avec pagination) - * @param realmName nom du realm - * @param page numéro de page - * @param pageSize taille de la page - * @return liste paginée d'utilisateurs - */ - UserSearchResultDTO getAllUsers(@NotBlank String realmName, int page, int pageSize); - - /** - * Vérifie si un username existe déjà - * @param username username à vérifier - * @param realmName nom du realm - * @return true si existe - */ - boolean usernameExists(@NotBlank String username, @NotBlank String realmName); - - /** - * Vérifie si un email existe déjà - * @param email email à vérifier - * @param realmName nom du realm - * @return true si existe - */ - boolean emailExists(@NotBlank String email, @NotBlank String realmName); - - /** - * Exporte les utilisateurs au format CSV - * @param criteria critères de recherche - * @return contenu CSV - */ - String exportUsersToCSV(@NotNull UserSearchCriteriaDTO criteria); - - /** - * Importe des utilisateurs depuis un CSV avec rapport détaillé - * @param csvContent contenu CSV - * @param realmName nom du realm - * @return résultat détaillé de l'import (succès, erreurs) - */ - dev.lions.user.manager.dto.importexport.ImportResultDTO importUsersFromCSV(@NotBlank String csvContent, @NotBlank String realmName); -} +package dev.lions.user.manager.service; + +import dev.lions.user.manager.dto.user.UserDTO; +import dev.lions.user.manager.dto.user.UserSearchCriteriaDTO; +import dev.lions.user.manager.dto.user.UserSearchResultDTO; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; + +import java.util.List; +import java.util.Optional; + +/** + * Service de gestion des utilisateurs Keycloak + * Utilise uniquement l'API Admin Keycloak (AUCUN accès direct à la DB) + */ +public interface UserService { + + /** + * Recherche des utilisateurs selon des critères + * @param criteria critères de recherche + * @return résultat paginé + */ + UserSearchResultDTO searchUsers(@Valid @NotNull UserSearchCriteriaDTO criteria); + + /** + * Récupère un utilisateur par son ID + * @param userId ID de l'utilisateur + * @param realmName nom du realm + * @return utilisateur ou Optional vide + */ + Optional getUserById(@NotBlank String userId, @NotBlank String realmName); + + /** + * Récupère un utilisateur par son username + * @param username username + * @param realmName nom du realm + * @return utilisateur ou Optional vide + */ + Optional getUserByUsername(@NotBlank String username, @NotBlank String realmName); + + /** + * Récupère un utilisateur par son email + * @param email email + * @param realmName nom du realm + * @return utilisateur ou Optional vide + */ + Optional getUserByEmail(@NotBlank String email, @NotBlank String realmName); + + /** + * Crée un nouvel utilisateur + * @param user données de l'utilisateur + * @param realmName nom du realm + * @return utilisateur créé avec son ID + */ + UserDTO createUser(@Valid @NotNull UserDTO user, @NotBlank String realmName); + + /** + * Met à jour un utilisateur existant + * @param userId ID de l'utilisateur + * @param user données modifiées + * @param realmName nom du realm + * @return utilisateur mis à jour + */ + UserDTO updateUser(@NotBlank String userId, @Valid @NotNull UserDTO user, @NotBlank String realmName); + + /** + * Supprime un utilisateur (soft ou hard delete selon configuration) + * @param userId ID de l'utilisateur + * @param realmName nom du realm + * @param hardDelete true pour suppression définitive, false pour soft delete + */ + void deleteUser(@NotBlank String userId, @NotBlank String realmName, boolean hardDelete); + + /** + * Active un utilisateur + * @param userId ID de l'utilisateur + * @param realmName nom du realm + */ + void activateUser(@NotBlank String userId, @NotBlank String realmName); + + /** + * Désactive un utilisateur + * @param userId ID de l'utilisateur + * @param realmName nom du realm + * @param raison raison de la désactivation + */ + void deactivateUser(@NotBlank String userId, @NotBlank String realmName, String raison); + + /** + * Suspend un utilisateur + * @param userId ID de l'utilisateur + * @param realmName nom du realm + * @param raison raison de la suspension + * @param duree durée de la suspension en jours (0 = indéfinie) + */ + void suspendUser(@NotBlank String userId, @NotBlank String realmName, String raison, int duree); + + /** + * Déverrouille un utilisateur + * @param userId ID de l'utilisateur + * @param realmName nom du realm + */ + void unlockUser(@NotBlank String userId, @NotBlank String realmName); + + /** + * Réinitialise le mot de passe d'un utilisateur + * @param userId ID de l'utilisateur + * @param realmName nom du realm + * @param temporaryPassword mot de passe temporaire + * @param temporary true si le mot de passe doit être changé à la prochaine connexion + */ + void resetPassword(@NotBlank String userId, @NotBlank String realmName, + @NotBlank String temporaryPassword, boolean temporary); + + /** + * Envoie un email de vérification + * @param userId ID de l'utilisateur + * @param realmName nom du realm + */ + void sendVerificationEmail(@NotBlank String userId, @NotBlank String realmName); + + /** + * Force la déconnexion de toutes les sessions d'un utilisateur + * @param userId ID de l'utilisateur + * @param realmName nom du realm + * @return nombre de sessions révoquées + */ + int logoutAllSessions(@NotBlank String userId, @NotBlank String realmName); + + /** + * Récupère les sessions actives d'un utilisateur + * @param userId ID de l'utilisateur + * @param realmName nom du realm + * @return liste des informations de session + */ + List getActiveSessions(@NotBlank String userId, @NotBlank String realmName); + + /** + * Compte le nombre d'utilisateurs selon des critères + * @param criteria critères de recherche + * @return nombre d'utilisateurs + */ + long countUsers(@NotNull UserSearchCriteriaDTO criteria); + + /** + * Récupère tous les utilisateurs d'un realm (avec pagination) + * @param realmName nom du realm + * @param page numéro de page + * @param pageSize taille de la page + * @return liste paginée d'utilisateurs + */ + UserSearchResultDTO getAllUsers(@NotBlank String realmName, int page, int pageSize); + + /** + * Vérifie si un username existe déjà + * @param username username à vérifier + * @param realmName nom du realm + * @return true si existe + */ + boolean usernameExists(@NotBlank String username, @NotBlank String realmName); + + /** + * Vérifie si un email existe déjà + * @param email email à vérifier + * @param realmName nom du realm + * @return true si existe + */ + boolean emailExists(@NotBlank String email, @NotBlank String realmName); + + /** + * Exporte les utilisateurs au format CSV + * @param criteria critères de recherche + * @return contenu CSV + */ + String exportUsersToCSV(@NotNull UserSearchCriteriaDTO criteria); + + /** + * Importe des utilisateurs depuis un CSV avec rapport détaillé + * @param csvContent contenu CSV + * @param realmName nom du realm + * @return résultat détaillé de l'import (succès, erreurs) + */ + dev.lions.user.manager.dto.importexport.ImportResultDTO importUsersFromCSV(@NotBlank String csvContent, @NotBlank String realmName); +} diff --git a/src/main/java/dev/lions/user/manager/validation/ValidationConstants.java b/src/main/java/dev/lions/user/manager/validation/ValidationConstants.java index 54b007d..41d9725 100644 --- a/src/main/java/dev/lions/user/manager/validation/ValidationConstants.java +++ b/src/main/java/dev/lions/user/manager/validation/ValidationConstants.java @@ -1,72 +1,72 @@ -package dev.lions.user.manager.validation; - -/** - * Constantes de validation pour les DTOs - * Centralise les règles de validation communes - */ -public final class ValidationConstants { - - private ValidationConstants() { - // Classe utilitaire, pas d'instanciation - } - - // Username - public static final int USERNAME_MIN_LENGTH = 3; - public static final int USERNAME_MAX_LENGTH = 100; - public static final String USERNAME_PATTERN = "^[a-zA-Z0-9._-]+$"; - public static final String USERNAME_PATTERN_MESSAGE = "Le nom d'utilisateur ne peut contenir que des lettres, chiffres, points, tirets et underscores"; - - // Email - public static final String EMAIL_PATTERN = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"; - public static final String EMAIL_PATTERN_MESSAGE = "Format d'email invalide"; - - // Nom et Prénom - public static final int NAME_MIN_LENGTH = 2; - public static final int NAME_MAX_LENGTH = 100; - public static final String NAME_PATTERN = "^[a-zA-ZÀ-ÿ\\s'-]+$"; - public static final String NAME_PATTERN_MESSAGE = "Le nom ne peut contenir que des lettres, espaces, apostrophes et tirets"; - - // Téléphone - public static final String PHONE_PATTERN = "^\\+?[0-9\\s.-]{8,20}$"; - public static final String PHONE_PATTERN_MESSAGE = "Format de téléphone invalide"; - - // Mot de passe - public static final int PASSWORD_MIN_LENGTH = 8; - public static final int PASSWORD_MAX_LENGTH = 100; - public static final String PASSWORD_PATTERN = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,}$"; - public static final String PASSWORD_PATTERN_MESSAGE = "Le mot de passe doit contenir au moins 8 caractères, une majuscule, une minuscule, un chiffre et un caractère spécial"; - - // Role - public static final int ROLE_NAME_MIN_LENGTH = 2; - public static final int ROLE_NAME_MAX_LENGTH = 100; - public static final String ROLE_NAME_PATTERN = "^[a-zA-Z0-9_-]+$"; - public static final String ROLE_NAME_PATTERN_MESSAGE = "Le nom du rôle ne peut contenir que des lettres, chiffres, underscores et tirets"; - - // Realm - public static final String REALM_NAME_PATTERN = "^[a-zA-Z0-9_-]+$"; - public static final String REALM_NAME_PATTERN_MESSAGE = "Le nom du realm ne peut contenir que des lettres, chiffres, underscores et tirets"; - - // UUID - public static final String UUID_PATTERN = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"; - public static final String UUID_PATTERN_MESSAGE = "Format UUID invalide"; - - // Messages d'erreur génériques - public static final String REQUIRED_FIELD = "Ce champ est obligatoire"; - public static final String INVALID_FORMAT = "Format invalide"; - public static final String TOO_SHORT = "Valeur trop courte"; - public static final String TOO_LONG = "Valeur trop longue"; - - // Pagination - public static final int DEFAULT_PAGE_SIZE = 20; - public static final int MAX_PAGE_SIZE = 100; - public static final int MIN_PAGE_SIZE = 1; - - // Audit - public static final int MAX_DESCRIPTION_LENGTH = 500; - public static final int MAX_COMMENT_LENGTH = 1000; - public static final int MAX_ERROR_MESSAGE_LENGTH = 2000; - - // IP Address - public static final String IP_ADDRESS_PATTERN = "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"; - public static final String IP_ADDRESS_PATTERN_MESSAGE = "Format d'adresse IP invalide"; -} +package dev.lions.user.manager.validation; + +/** + * Constantes de validation pour les DTOs + * Centralise les règles de validation communes + */ +public final class ValidationConstants { + + private ValidationConstants() { + // Classe utilitaire, pas d'instanciation + } + + // Username + public static final int USERNAME_MIN_LENGTH = 3; + public static final int USERNAME_MAX_LENGTH = 100; + public static final String USERNAME_PATTERN = "^[a-zA-Z0-9._-]+$"; + public static final String USERNAME_PATTERN_MESSAGE = "Le nom d'utilisateur ne peut contenir que des lettres, chiffres, points, tirets et underscores"; + + // Email + public static final String EMAIL_PATTERN = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"; + public static final String EMAIL_PATTERN_MESSAGE = "Format d'email invalide"; + + // Nom et Prénom + public static final int NAME_MIN_LENGTH = 2; + public static final int NAME_MAX_LENGTH = 100; + public static final String NAME_PATTERN = "^[a-zA-ZÀ-ÿ\\s'-]+$"; + public static final String NAME_PATTERN_MESSAGE = "Le nom ne peut contenir que des lettres, espaces, apostrophes et tirets"; + + // Téléphone + public static final String PHONE_PATTERN = "^\\+?[0-9\\s.-]{8,20}$"; + public static final String PHONE_PATTERN_MESSAGE = "Format de téléphone invalide"; + + // Mot de passe + public static final int PASSWORD_MIN_LENGTH = 8; + public static final int PASSWORD_MAX_LENGTH = 100; + public static final String PASSWORD_PATTERN = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,}$"; + public static final String PASSWORD_PATTERN_MESSAGE = "Le mot de passe doit contenir au moins 8 caractères, une majuscule, une minuscule, un chiffre et un caractère spécial"; + + // Role + public static final int ROLE_NAME_MIN_LENGTH = 2; + public static final int ROLE_NAME_MAX_LENGTH = 100; + public static final String ROLE_NAME_PATTERN = "^[a-zA-Z0-9_-]+$"; + public static final String ROLE_NAME_PATTERN_MESSAGE = "Le nom du rôle ne peut contenir que des lettres, chiffres, underscores et tirets"; + + // Realm + public static final String REALM_NAME_PATTERN = "^[a-zA-Z0-9_-]+$"; + public static final String REALM_NAME_PATTERN_MESSAGE = "Le nom du realm ne peut contenir que des lettres, chiffres, underscores et tirets"; + + // UUID + public static final String UUID_PATTERN = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"; + public static final String UUID_PATTERN_MESSAGE = "Format UUID invalide"; + + // Messages d'erreur génériques + public static final String REQUIRED_FIELD = "Ce champ est obligatoire"; + public static final String INVALID_FORMAT = "Format invalide"; + public static final String TOO_SHORT = "Valeur trop courte"; + public static final String TOO_LONG = "Valeur trop longue"; + + // Pagination + public static final int DEFAULT_PAGE_SIZE = 20; + public static final int MAX_PAGE_SIZE = 100; + public static final int MIN_PAGE_SIZE = 1; + + // Audit + public static final int MAX_DESCRIPTION_LENGTH = 500; + public static final int MAX_COMMENT_LENGTH = 1000; + public static final int MAX_ERROR_MESSAGE_LENGTH = 2000; + + // IP Address + public static final String IP_ADDRESS_PATTERN = "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"; + public static final String IP_ADDRESS_PATTERN_MESSAGE = "Format d'adresse IP invalide"; +} diff --git a/src/test/java/dev/lions/user/manager/dto/audit/AuditLogDTOTest.java b/src/test/java/dev/lions/user/manager/dto/audit/AuditLogDTOTest.java index ee4f990..fd98377 100644 --- a/src/test/java/dev/lions/user/manager/dto/audit/AuditLogDTOTest.java +++ b/src/test/java/dev/lions/user/manager/dto/audit/AuditLogDTOTest.java @@ -1,119 +1,119 @@ -package dev.lions.user.manager.dto.audit; - -import dev.lions.user.manager.enums.audit.TypeActionAudit; -import org.junit.jupiter.api.Test; - -import java.time.LocalDateTime; - -import static org.junit.jupiter.api.Assertions.*; - -/** - * Tests unitaires pour AuditLogDTO - */ -class AuditLogDTOTest { - - @Test - void testBuilder() { - LocalDateTime now = LocalDateTime.now(); - AuditLogDTO log = AuditLogDTO.builder() - .id("log-123") - .typeAction(TypeActionAudit.USER_CREATE) - .acteurUsername("admin") - .acteurUserId("admin-123") - .ressourceType("USER") - .ressourceId("user-123") - .ressourceName("testuser") - .realmName("test-realm") - .success(true) - .description("User created") - .dateAction(now) - .ipAddress("192.168.1.1") - .build(); - - assertNotNull(log); - assertEquals("log-123", log.getId()); - assertEquals(TypeActionAudit.USER_CREATE, log.getTypeAction()); - assertEquals("admin", log.getActeurUsername()); - assertEquals("admin-123", log.getActeurUserId()); - assertEquals("USER", log.getRessourceType()); - assertEquals("user-123", log.getRessourceId()); - assertEquals("testuser", log.getRessourceName()); - assertEquals("test-realm", log.getRealmName()); - assertTrue(log.isSuccessful()); - assertEquals("User created", log.getDescription()); - assertEquals(now, log.getDateAction()); - assertEquals("192.168.1.1", log.getIpAddress()); - } - - @Test - void testNoArgsConstructor() { - AuditLogDTO log = new AuditLogDTO(); - - assertNotNull(log); - assertNull(log.getId()); - assertNull(log.getTypeAction()); - assertNull(log.getActeurUsername()); - } - - @Test - void testSettersAndGetters() { - AuditLogDTO log = new AuditLogDTO(); - LocalDateTime now = LocalDateTime.now(); - - log.setId("log-456"); - log.setTypeAction(TypeActionAudit.USER_UPDATE); - log.setActeurUsername("user1"); - log.setActeurUserId("user1-123"); - log.setRessourceType("USER"); - log.setRessourceId("user-456"); - log.setRessourceName("user2"); - log.setRealmName("realm2"); - log.setSuccess(false); - log.setDescription("Update failed"); - log.setDateAction(now); - log.setIpAddress("10.0.0.1"); - - assertEquals("log-456", log.getId()); - assertEquals(TypeActionAudit.USER_UPDATE, log.getTypeAction()); - assertEquals("user1", log.getActeurUsername()); - assertEquals("user1-123", log.getActeurUserId()); - assertEquals("USER", log.getRessourceType()); - assertEquals("user-456", log.getRessourceId()); - assertEquals("user2", log.getRessourceName()); - assertEquals("realm2", log.getRealmName()); - assertFalse(log.isSuccessful()); - assertEquals("Update failed", log.getDescription()); - assertEquals(now, log.getDateAction()); - assertEquals("10.0.0.1", log.getIpAddress()); - } - - @Test - void testEqualsAndHashCode() { - LocalDateTime now = LocalDateTime.now(); - AuditLogDTO log1 = AuditLogDTO.builder() - .id("log-123") - .typeAction(TypeActionAudit.USER_CREATE) - .dateAction(now) - .build(); - - AuditLogDTO log2 = AuditLogDTO.builder() - .id("log-123") - .typeAction(TypeActionAudit.USER_CREATE) - .dateAction(now) - .build(); - - assertEquals(log1, log2); - assertEquals(log1.hashCode(), log2.hashCode()); - } - - @Test - void testToString() { - AuditLogDTO log = AuditLogDTO.builder() - .id("log-123") - .typeAction(TypeActionAudit.USER_CREATE) - .build(); - - String toString = log.toString(); - assertNotNull(toString); - } -} +package dev.lions.user.manager.dto.audit; + +import dev.lions.user.manager.enums.audit.TypeActionAudit; +import org.junit.jupiter.api.Test; + +import java.time.LocalDateTime; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Tests unitaires pour AuditLogDTO + */ +class AuditLogDTOTest { + + @Test + void testBuilder() { + LocalDateTime now = LocalDateTime.now(); + AuditLogDTO log = AuditLogDTO.builder() + .id("log-123") + .typeAction(TypeActionAudit.USER_CREATE) + .acteurUsername("admin") + .acteurUserId("admin-123") + .ressourceType("USER") + .ressourceId("user-123") + .ressourceName("testuser") + .realmName("test-realm") + .success(true) + .description("User created") + .dateAction(now) + .ipAddress("192.168.1.1") + .build(); + + assertNotNull(log); + assertEquals("log-123", log.getId()); + assertEquals(TypeActionAudit.USER_CREATE, log.getTypeAction()); + assertEquals("admin", log.getActeurUsername()); + assertEquals("admin-123", log.getActeurUserId()); + assertEquals("USER", log.getRessourceType()); + assertEquals("user-123", log.getRessourceId()); + assertEquals("testuser", log.getRessourceName()); + assertEquals("test-realm", log.getRealmName()); + assertTrue(log.isSuccessful()); + assertEquals("User created", log.getDescription()); + assertEquals(now, log.getDateAction()); + assertEquals("192.168.1.1", log.getIpAddress()); + } + + @Test + void testNoArgsConstructor() { + AuditLogDTO log = new AuditLogDTO(); + + assertNotNull(log); + assertNull(log.getId()); + assertNull(log.getTypeAction()); + assertNull(log.getActeurUsername()); + } + + @Test + void testSettersAndGetters() { + AuditLogDTO log = new AuditLogDTO(); + LocalDateTime now = LocalDateTime.now(); + + log.setId("log-456"); + log.setTypeAction(TypeActionAudit.USER_UPDATE); + log.setActeurUsername("user1"); + log.setActeurUserId("user1-123"); + log.setRessourceType("USER"); + log.setRessourceId("user-456"); + log.setRessourceName("user2"); + log.setRealmName("realm2"); + log.setSuccess(false); + log.setDescription("Update failed"); + log.setDateAction(now); + log.setIpAddress("10.0.0.1"); + + assertEquals("log-456", log.getId()); + assertEquals(TypeActionAudit.USER_UPDATE, log.getTypeAction()); + assertEquals("user1", log.getActeurUsername()); + assertEquals("user1-123", log.getActeurUserId()); + assertEquals("USER", log.getRessourceType()); + assertEquals("user-456", log.getRessourceId()); + assertEquals("user2", log.getRessourceName()); + assertEquals("realm2", log.getRealmName()); + assertFalse(log.isSuccessful()); + assertEquals("Update failed", log.getDescription()); + assertEquals(now, log.getDateAction()); + assertEquals("10.0.0.1", log.getIpAddress()); + } + + @Test + void testEqualsAndHashCode() { + LocalDateTime now = LocalDateTime.now(); + AuditLogDTO log1 = AuditLogDTO.builder() + .id("log-123") + .typeAction(TypeActionAudit.USER_CREATE) + .dateAction(now) + .build(); + + AuditLogDTO log2 = AuditLogDTO.builder() + .id("log-123") + .typeAction(TypeActionAudit.USER_CREATE) + .dateAction(now) + .build(); + + assertEquals(log1, log2); + assertEquals(log1.hashCode(), log2.hashCode()); + } + + @Test + void testToString() { + AuditLogDTO log = AuditLogDTO.builder() + .id("log-123") + .typeAction(TypeActionAudit.USER_CREATE) + .build(); + + String toString = log.toString(); + assertNotNull(toString); + } +} diff --git a/src/test/java/dev/lions/user/manager/dto/base/BaseDTOTest.java b/src/test/java/dev/lions/user/manager/dto/base/BaseDTOTest.java index c8c1997..9a1a479 100644 --- a/src/test/java/dev/lions/user/manager/dto/base/BaseDTOTest.java +++ b/src/test/java/dev/lions/user/manager/dto/base/BaseDTOTest.java @@ -1,134 +1,134 @@ -package dev.lions.user.manager.dto.base; - -import org.junit.jupiter.api.Test; - -import java.time.LocalDateTime; - -import static org.junit.jupiter.api.Assertions.*; - -class BaseDTOTest { - - // Concrete implementation for testing abstract class - static class TestDTO extends BaseDTO { - private static final long serialVersionUID = 1L; - } - - @Test - void testSettersAndGetters() { - TestDTO dto = new TestDTO(); - LocalDateTime now = LocalDateTime.now(); - - dto.setId("uuid-123"); - dto.setDateCreation(now); - dto.setDateModification(now); - dto.setCreeParUsername("admin"); - dto.setModifieParUsername("superadmin"); - dto.setVersion(1L); - - assertEquals("uuid-123", dto.getId()); - assertEquals(now, dto.getDateCreation()); - assertEquals(now, dto.getDateModification()); - assertEquals("admin", dto.getCreeParUsername()); - assertEquals("superadmin", dto.getModifieParUsername()); - assertEquals(1L, dto.getVersion()); - } - - @Test - void testEqualsAndHashCode() { - TestDTO dto1 = new TestDTO(); - dto1.setId("uuid-123"); - dto1.setVersion(1L); - - TestDTO dto2 = new TestDTO(); - dto2.setId("uuid-123"); - dto2.setVersion(1L); - - TestDTO dto3 = new TestDTO(); - dto3.setId("uuid-456"); - dto3.setVersion(2L); - - assertEquals(dto1, dto2); - assertEquals(dto1.hashCode(), dto2.hashCode()); - assertNotEquals(dto1, dto3); - } - - @Test - void testToString() { - TestDTO dto = new TestDTO(); - dto.setId("uuid-123"); - dto.setCreeParUsername("admin"); - - String str = dto.toString(); - assertNotNull(str); - assertTrue(str.contains("uuid-123")); - assertTrue(str.contains("admin")); - } - - @Test - void testNoArgsConstructor() { - TestDTO dto = new TestDTO(); - assertNull(dto.getId()); - assertNull(dto.getDateCreation()); - assertNull(dto.getDateModification()); - assertNull(dto.getCreeParUsername()); - assertNull(dto.getModifieParUsername()); - assertNull(dto.getVersion()); - } - - @Test - void testAllFields() { - LocalDateTime creationTime = LocalDateTime.of(2025, 1, 15, 10, 30); - LocalDateTime modificationTime = LocalDateTime.of(2025, 1, 15, 14, 20); - - TestDTO dto = new TestDTO(); - dto.setId("f47ac10b-58cc-4372-a567-0e02b2c3d479"); - dto.setDateCreation(creationTime); - dto.setDateModification(modificationTime); - dto.setCreeParUsername("admin@lions.dev"); - dto.setModifieParUsername("superadmin@lions.dev"); - dto.setVersion(5L); - - assertEquals("f47ac10b-58cc-4372-a567-0e02b2c3d479", dto.getId()); - assertEquals(creationTime, dto.getDateCreation()); - assertEquals(modificationTime, dto.getDateModification()); - assertEquals("admin@lions.dev", dto.getCreeParUsername()); - assertEquals("superadmin@lions.dev", dto.getModifieParUsername()); - assertEquals(5L, dto.getVersion()); - } - - @Test - void testEqualsWithNull() { - TestDTO dto = new TestDTO(); - dto.setId("uuid-123"); - - assertNotEquals(null, dto); - } - - @Test - void testEqualsWithDifferentClass() { - TestDTO dto = new TestDTO(); - dto.setId("uuid-123"); - - assertNotEquals("string", dto); - } - - @Test - void testEqualsSameObject() { - TestDTO dto = new TestDTO(); - dto.setId("uuid-123"); - - assertEquals(dto, dto); - } - - @Test - void testHashCodeConsistency() { - TestDTO dto = new TestDTO(); - dto.setId("uuid-123"); - dto.setVersion(1L); - - int hash1 = dto.hashCode(); - int hash2 = dto.hashCode(); - - assertEquals(hash1, hash2); - } -} +package dev.lions.user.manager.dto.base; + +import org.junit.jupiter.api.Test; + +import java.time.LocalDateTime; + +import static org.junit.jupiter.api.Assertions.*; + +class BaseDTOTest { + + // Concrete implementation for testing abstract class + static class TestDTO extends BaseDTO { + private static final long serialVersionUID = 1L; + } + + @Test + void testSettersAndGetters() { + TestDTO dto = new TestDTO(); + LocalDateTime now = LocalDateTime.now(); + + dto.setId("uuid-123"); + dto.setDateCreation(now); + dto.setDateModification(now); + dto.setCreeParUsername("admin"); + dto.setModifieParUsername("superadmin"); + dto.setVersion(1L); + + assertEquals("uuid-123", dto.getId()); + assertEquals(now, dto.getDateCreation()); + assertEquals(now, dto.getDateModification()); + assertEquals("admin", dto.getCreeParUsername()); + assertEquals("superadmin", dto.getModifieParUsername()); + assertEquals(1L, dto.getVersion()); + } + + @Test + void testEqualsAndHashCode() { + TestDTO dto1 = new TestDTO(); + dto1.setId("uuid-123"); + dto1.setVersion(1L); + + TestDTO dto2 = new TestDTO(); + dto2.setId("uuid-123"); + dto2.setVersion(1L); + + TestDTO dto3 = new TestDTO(); + dto3.setId("uuid-456"); + dto3.setVersion(2L); + + assertEquals(dto1, dto2); + assertEquals(dto1.hashCode(), dto2.hashCode()); + assertNotEquals(dto1, dto3); + } + + @Test + void testToString() { + TestDTO dto = new TestDTO(); + dto.setId("uuid-123"); + dto.setCreeParUsername("admin"); + + String str = dto.toString(); + assertNotNull(str); + assertTrue(str.contains("uuid-123")); + assertTrue(str.contains("admin")); + } + + @Test + void testNoArgsConstructor() { + TestDTO dto = new TestDTO(); + assertNull(dto.getId()); + assertNull(dto.getDateCreation()); + assertNull(dto.getDateModification()); + assertNull(dto.getCreeParUsername()); + assertNull(dto.getModifieParUsername()); + assertNull(dto.getVersion()); + } + + @Test + void testAllFields() { + LocalDateTime creationTime = LocalDateTime.of(2025, 1, 15, 10, 30); + LocalDateTime modificationTime = LocalDateTime.of(2025, 1, 15, 14, 20); + + TestDTO dto = new TestDTO(); + dto.setId("f47ac10b-58cc-4372-a567-0e02b2c3d479"); + dto.setDateCreation(creationTime); + dto.setDateModification(modificationTime); + dto.setCreeParUsername("admin@lions.dev"); + dto.setModifieParUsername("superadmin@lions.dev"); + dto.setVersion(5L); + + assertEquals("f47ac10b-58cc-4372-a567-0e02b2c3d479", dto.getId()); + assertEquals(creationTime, dto.getDateCreation()); + assertEquals(modificationTime, dto.getDateModification()); + assertEquals("admin@lions.dev", dto.getCreeParUsername()); + assertEquals("superadmin@lions.dev", dto.getModifieParUsername()); + assertEquals(5L, dto.getVersion()); + } + + @Test + void testEqualsWithNull() { + TestDTO dto = new TestDTO(); + dto.setId("uuid-123"); + + assertNotEquals(null, dto); + } + + @Test + void testEqualsWithDifferentClass() { + TestDTO dto = new TestDTO(); + dto.setId("uuid-123"); + + assertNotEquals("string", dto); + } + + @Test + void testEqualsSameObject() { + TestDTO dto = new TestDTO(); + dto.setId("uuid-123"); + + assertEquals(dto, dto); + } + + @Test + void testHashCodeConsistency() { + TestDTO dto = new TestDTO(); + dto.setId("uuid-123"); + dto.setVersion(1L); + + int hash1 = dto.hashCode(); + int hash2 = dto.hashCode(); + + assertEquals(hash1, hash2); + } +} diff --git a/src/test/java/dev/lions/user/manager/dto/realm/RealmAssignmentDTOTest.java b/src/test/java/dev/lions/user/manager/dto/realm/RealmAssignmentDTOTest.java index d085f72..accc119 100644 --- a/src/test/java/dev/lions/user/manager/dto/realm/RealmAssignmentDTOTest.java +++ b/src/test/java/dev/lions/user/manager/dto/realm/RealmAssignmentDTOTest.java @@ -1,184 +1,184 @@ -package dev.lions.user.manager.dto.realm; - -import org.junit.jupiter.api.Test; - -import java.time.LocalDateTime; - -import static org.junit.jupiter.api.Assertions.*; - -/** - * Tests unitaires pour RealmAssignmentDTO - */ -class RealmAssignmentDTOTest { - - @Test - void testBuilder() { - LocalDateTime now = LocalDateTime.now(); - RealmAssignmentDTO dto = RealmAssignmentDTO.builder() - .id("assignment-1") - .userId("user-1") - .username("testuser") - .email("test@example.com") - .realmName("realm1") - .isSuperAdmin(false) - .active(true) - .temporaire(false) - .assignedAt(now) - .assignedBy("admin") - .raison("Test assignment") - .commentaires("Test comments") - .dateCreation(now) - .dateModification(now) - .dateExpiration(now.plusDays(30)) - .build(); - - assertEquals("assignment-1", dto.getId()); - assertEquals("user-1", dto.getUserId()); - assertEquals("testuser", dto.getUsername()); - assertEquals("test@example.com", dto.getEmail()); - assertEquals("realm1", dto.getRealmName()); - assertFalse(dto.isSuperAdmin()); - assertTrue(dto.isActive()); - assertFalse(dto.getTemporaire()); - assertEquals(now, dto.getAssignedAt()); - assertEquals("admin", dto.getAssignedBy()); - assertEquals("Test assignment", dto.getRaison()); - assertEquals("Test comments", dto.getCommentaires()); - } - - @Test - void testNoArgsConstructor() { - RealmAssignmentDTO dto = new RealmAssignmentDTO(); - assertNotNull(dto); - } - - @Test - void testSettersAndGetters() { - RealmAssignmentDTO dto = new RealmAssignmentDTO(); - LocalDateTime now = LocalDateTime.now(); - - dto.setId("assignment-1"); - dto.setUserId("user-1"); - dto.setUsername("testuser"); - dto.setEmail("test@example.com"); - dto.setRealmName("realm1"); - dto.setIsSuperAdmin(true); - dto.setActive(true); - dto.setTemporaire(false); - dto.setAssignedAt(now); - dto.setAssignedBy("admin"); - dto.setRaison("Test"); - dto.setCommentaires("Comments"); - dto.setDateCreation(now); - dto.setDateModification(now); - dto.setDateExpiration(now.plusDays(30)); - - assertEquals("assignment-1", dto.getId()); - assertEquals("user-1", dto.getUserId()); - assertEquals("testuser", dto.getUsername()); - assertEquals("test@example.com", dto.getEmail()); - assertEquals("realm1", dto.getRealmName()); - assertTrue(dto.isSuperAdmin()); - assertTrue(dto.isActive()); - assertFalse(dto.getTemporaire()); - assertEquals(now, dto.getAssignedAt()); - assertEquals("admin", dto.getAssignedBy()); - } - - @Test - void testIsExpired_NotExpired() { - RealmAssignmentDTO dto = RealmAssignmentDTO.builder() - .temporaire(true) // Doit être temporaire pour que isExpired() fonctionne - .dateExpiration(LocalDateTime.now().plusDays(1)) - .build(); - - assertFalse(dto.isExpired()); - } - - @Test - void testIsExpired_Expired() { - RealmAssignmentDTO dto = RealmAssignmentDTO.builder() - .temporaire(true) // Doit être temporaire pour que isExpired() fonctionne - .dateExpiration(LocalDateTime.now().minusDays(1)) - .build(); - - assertTrue(dto.isExpired()); - } - - @Test - void testIsExpired_NoExpiration() { - RealmAssignmentDTO dto = RealmAssignmentDTO.builder() - .temporaire(true) - .dateExpiration(null) - .build(); - - assertFalse(dto.isExpired()); - } - - @Test - void testIsExpired_NotTemporary() { - RealmAssignmentDTO dto = RealmAssignmentDTO.builder() - .temporaire(false) // Si pas temporaire, isExpired() retourne false - .dateExpiration(LocalDateTime.now().minusDays(1)) - .build(); - - assertFalse(dto.isExpired()); - } - - @Test - void testIsTemporaire() { - RealmAssignmentDTO dto = RealmAssignmentDTO.builder() - .temporaire(true) - .build(); - - assertTrue(dto.isTemporaire()); - } - - @Test - void testIsActive() { - RealmAssignmentDTO dto = RealmAssignmentDTO.builder() - .active(true) - .build(); - - assertTrue(dto.isActive()); - } - - @Test - void testIsSuperAdmin() { - RealmAssignmentDTO dto = RealmAssignmentDTO.builder() - .isSuperAdmin(true) - .build(); - - assertTrue(dto.isSuperAdmin()); - } - - @Test - void testGetSummary() { - RealmAssignmentDTO dto = RealmAssignmentDTO.builder() - .realmName("test-realm") - .username("testuser") - .temporaire(true) - .build(); - - String summary = dto.getSummary(); - assertNotNull(summary); - assertTrue(summary.contains("test-realm")); - assertTrue(summary.contains("testuser")); - assertTrue(summary.contains("temporaire")); - } - - @Test - void testGetSummary_WithUserId() { - RealmAssignmentDTO dto = RealmAssignmentDTO.builder() - .realmName("test-realm") - .userId("user-123") - .temporaire(false) - .build(); - - String summary = dto.getSummary(); - assertNotNull(summary); - assertTrue(summary.contains("test-realm")); - assertTrue(summary.contains("user-123")); - } -} - +package dev.lions.user.manager.dto.realm; + +import org.junit.jupiter.api.Test; + +import java.time.LocalDateTime; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Tests unitaires pour RealmAssignmentDTO + */ +class RealmAssignmentDTOTest { + + @Test + void testBuilder() { + LocalDateTime now = LocalDateTime.now(); + RealmAssignmentDTO dto = RealmAssignmentDTO.builder() + .id("assignment-1") + .userId("user-1") + .username("testuser") + .email("test@example.com") + .realmName("realm1") + .isSuperAdmin(false) + .active(true) + .temporaire(false) + .assignedAt(now) + .assignedBy("admin") + .raison("Test assignment") + .commentaires("Test comments") + .dateCreation(now) + .dateModification(now) + .dateExpiration(now.plusDays(30)) + .build(); + + assertEquals("assignment-1", dto.getId()); + assertEquals("user-1", dto.getUserId()); + assertEquals("testuser", dto.getUsername()); + assertEquals("test@example.com", dto.getEmail()); + assertEquals("realm1", dto.getRealmName()); + assertFalse(dto.isSuperAdmin()); + assertTrue(dto.isActive()); + assertFalse(dto.getTemporaire()); + assertEquals(now, dto.getAssignedAt()); + assertEquals("admin", dto.getAssignedBy()); + assertEquals("Test assignment", dto.getRaison()); + assertEquals("Test comments", dto.getCommentaires()); + } + + @Test + void testNoArgsConstructor() { + RealmAssignmentDTO dto = new RealmAssignmentDTO(); + assertNotNull(dto); + } + + @Test + void testSettersAndGetters() { + RealmAssignmentDTO dto = new RealmAssignmentDTO(); + LocalDateTime now = LocalDateTime.now(); + + dto.setId("assignment-1"); + dto.setUserId("user-1"); + dto.setUsername("testuser"); + dto.setEmail("test@example.com"); + dto.setRealmName("realm1"); + dto.setIsSuperAdmin(true); + dto.setActive(true); + dto.setTemporaire(false); + dto.setAssignedAt(now); + dto.setAssignedBy("admin"); + dto.setRaison("Test"); + dto.setCommentaires("Comments"); + dto.setDateCreation(now); + dto.setDateModification(now); + dto.setDateExpiration(now.plusDays(30)); + + assertEquals("assignment-1", dto.getId()); + assertEquals("user-1", dto.getUserId()); + assertEquals("testuser", dto.getUsername()); + assertEquals("test@example.com", dto.getEmail()); + assertEquals("realm1", dto.getRealmName()); + assertTrue(dto.isSuperAdmin()); + assertTrue(dto.isActive()); + assertFalse(dto.getTemporaire()); + assertEquals(now, dto.getAssignedAt()); + assertEquals("admin", dto.getAssignedBy()); + } + + @Test + void testIsExpired_NotExpired() { + RealmAssignmentDTO dto = RealmAssignmentDTO.builder() + .temporaire(true) // Doit être temporaire pour que isExpired() fonctionne + .dateExpiration(LocalDateTime.now().plusDays(1)) + .build(); + + assertFalse(dto.isExpired()); + } + + @Test + void testIsExpired_Expired() { + RealmAssignmentDTO dto = RealmAssignmentDTO.builder() + .temporaire(true) // Doit être temporaire pour que isExpired() fonctionne + .dateExpiration(LocalDateTime.now().minusDays(1)) + .build(); + + assertTrue(dto.isExpired()); + } + + @Test + void testIsExpired_NoExpiration() { + RealmAssignmentDTO dto = RealmAssignmentDTO.builder() + .temporaire(true) + .dateExpiration(null) + .build(); + + assertFalse(dto.isExpired()); + } + + @Test + void testIsExpired_NotTemporary() { + RealmAssignmentDTO dto = RealmAssignmentDTO.builder() + .temporaire(false) // Si pas temporaire, isExpired() retourne false + .dateExpiration(LocalDateTime.now().minusDays(1)) + .build(); + + assertFalse(dto.isExpired()); + } + + @Test + void testIsTemporaire() { + RealmAssignmentDTO dto = RealmAssignmentDTO.builder() + .temporaire(true) + .build(); + + assertTrue(dto.isTemporaire()); + } + + @Test + void testIsActive() { + RealmAssignmentDTO dto = RealmAssignmentDTO.builder() + .active(true) + .build(); + + assertTrue(dto.isActive()); + } + + @Test + void testIsSuperAdmin() { + RealmAssignmentDTO dto = RealmAssignmentDTO.builder() + .isSuperAdmin(true) + .build(); + + assertTrue(dto.isSuperAdmin()); + } + + @Test + void testGetSummary() { + RealmAssignmentDTO dto = RealmAssignmentDTO.builder() + .realmName("test-realm") + .username("testuser") + .temporaire(true) + .build(); + + String summary = dto.getSummary(); + assertNotNull(summary); + assertTrue(summary.contains("test-realm")); + assertTrue(summary.contains("testuser")); + assertTrue(summary.contains("temporaire")); + } + + @Test + void testGetSummary_WithUserId() { + RealmAssignmentDTO dto = RealmAssignmentDTO.builder() + .realmName("test-realm") + .userId("user-123") + .temporaire(false) + .build(); + + String summary = dto.getSummary(); + assertNotNull(summary); + assertTrue(summary.contains("test-realm")); + assertTrue(summary.contains("user-123")); + } +} + diff --git a/src/test/java/dev/lions/user/manager/dto/role/RoleAssignmentDTOTest.java b/src/test/java/dev/lions/user/manager/dto/role/RoleAssignmentDTOTest.java index b016753..6604f16 100644 --- a/src/test/java/dev/lions/user/manager/dto/role/RoleAssignmentDTOTest.java +++ b/src/test/java/dev/lions/user/manager/dto/role/RoleAssignmentDTOTest.java @@ -1,147 +1,147 @@ -package dev.lions.user.manager.dto.role; - -import org.junit.jupiter.api.Test; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.*; - -/** - * Tests unitaires pour RoleAssignmentDTO - */ -class RoleAssignmentDTOTest { - - @Test - void testBuilder() { - RoleAssignmentDTO assignment = RoleAssignmentDTO.builder() - .userId("user-123") - .realmName("test-realm") - .roleNames(Arrays.asList("admin", "user")) - .build(); - - assertNotNull(assignment); - assertEquals("user-123", assignment.getUserId()); - assertEquals("test-realm", assignment.getRealmName()); - assertEquals(2, assignment.getRoleNames().size()); - assertTrue(assignment.getRoleNames().contains("admin")); - assertTrue(assignment.getRoleNames().contains("user")); - } - - @Test - void testNoArgsConstructor() { - RoleAssignmentDTO assignment = new RoleAssignmentDTO(); - - assertNotNull(assignment); - assertNull(assignment.getUserId()); - assertNull(assignment.getRealmName()); - assertNull(assignment.getRoleNames()); - } - - @Test - void testAllArgsConstructor() { - // Le constructeur AllArgsConstructor nécessite tous les champs - // On utilise plutôt le builder pour ce test - List roles = Arrays.asList("admin", "user"); - RoleAssignmentDTO assignment = RoleAssignmentDTO.builder() - .userId("user-123") - .realmName("test-realm") - .roleNames(roles) - .build(); - - assertNotNull(assignment); - assertEquals("user-123", assignment.getUserId()); - assertEquals("test-realm", assignment.getRealmName()); - assertEquals(2, assignment.getRoleNames().size()); - } - - @Test - void testSettersAndGetters() { - RoleAssignmentDTO assignment = new RoleAssignmentDTO(); - - assignment.setUserId("user-456"); - assignment.setRealmName("realm2"); - assignment.setRoleNames(Collections.singletonList("admin")); - - assertEquals("user-456", assignment.getUserId()); - assertEquals("realm2", assignment.getRealmName()); - assertEquals(1, assignment.getRoleNames().size()); - assertEquals("admin", assignment.getRoleNames().get(0)); - } - - @Test - void testEqualsAndHashCode() { - RoleAssignmentDTO assignment1 = RoleAssignmentDTO.builder() - .userId("user-123") - .realmName("test-realm") - .roleNames(Arrays.asList("admin")) - .typeRole(dev.lions.user.manager.enums.role.TypeRole.REALM_ROLE) - .build(); - - RoleAssignmentDTO assignment2 = RoleAssignmentDTO.builder() - .userId("user-123") - .realmName("test-realm") - .roleNames(Arrays.asList("admin")) - .typeRole(dev.lions.user.manager.enums.role.TypeRole.REALM_ROLE) - .build(); - - assertEquals(assignment1, assignment2); - assertEquals(assignment1.hashCode(), assignment2.hashCode()); - } - - @Test - void testIsValidForClientRole() { - RoleAssignmentDTO assignment = RoleAssignmentDTO.builder() - .typeRole(dev.lions.user.manager.enums.role.TypeRole.CLIENT_ROLE) - .clientName("test-client") - .build(); - - assertTrue(assignment.isValidForClientRole()); - } - - @Test - void testIsValidForRealmRole() { - RoleAssignmentDTO assignment = RoleAssignmentDTO.builder() - .typeRole(dev.lions.user.manager.enums.role.TypeRole.REALM_ROLE) - .build(); - - assertTrue(assignment.isValidForRealmRole()); - } - - @Test - void testGetRoleCount() { - RoleAssignmentDTO assignment = RoleAssignmentDTO.builder() - .roleNames(Arrays.asList("admin", "user", "viewer")) - .build(); - - assertEquals(3, assignment.getRoleCount()); - } - - @Test - void testGetRoleCount_Empty() { - RoleAssignmentDTO assignment = RoleAssignmentDTO.builder() - .roleNames(Collections.emptyList()) - .build(); - - assertEquals(0, assignment.getRoleCount()); - } - - @Test - void testGetRoleCount_Null() { - RoleAssignmentDTO assignment = new RoleAssignmentDTO(); - - assertEquals(0, assignment.getRoleCount()); - } - - @Test - void testToString() { - RoleAssignmentDTO assignment = RoleAssignmentDTO.builder() - .userId("user-123") - .realmName("test-realm") - .build(); - - String toString = assignment.toString(); - assertNotNull(toString); - } -} +package dev.lions.user.manager.dto.role; + +import org.junit.jupiter.api.Test; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Tests unitaires pour RoleAssignmentDTO + */ +class RoleAssignmentDTOTest { + + @Test + void testBuilder() { + RoleAssignmentDTO assignment = RoleAssignmentDTO.builder() + .userId("user-123") + .realmName("test-realm") + .roleNames(Arrays.asList("admin", "user")) + .build(); + + assertNotNull(assignment); + assertEquals("user-123", assignment.getUserId()); + assertEquals("test-realm", assignment.getRealmName()); + assertEquals(2, assignment.getRoleNames().size()); + assertTrue(assignment.getRoleNames().contains("admin")); + assertTrue(assignment.getRoleNames().contains("user")); + } + + @Test + void testNoArgsConstructor() { + RoleAssignmentDTO assignment = new RoleAssignmentDTO(); + + assertNotNull(assignment); + assertNull(assignment.getUserId()); + assertNull(assignment.getRealmName()); + assertNull(assignment.getRoleNames()); + } + + @Test + void testAllArgsConstructor() { + // Le constructeur AllArgsConstructor nécessite tous les champs + // On utilise plutôt le builder pour ce test + List roles = Arrays.asList("admin", "user"); + RoleAssignmentDTO assignment = RoleAssignmentDTO.builder() + .userId("user-123") + .realmName("test-realm") + .roleNames(roles) + .build(); + + assertNotNull(assignment); + assertEquals("user-123", assignment.getUserId()); + assertEquals("test-realm", assignment.getRealmName()); + assertEquals(2, assignment.getRoleNames().size()); + } + + @Test + void testSettersAndGetters() { + RoleAssignmentDTO assignment = new RoleAssignmentDTO(); + + assignment.setUserId("user-456"); + assignment.setRealmName("realm2"); + assignment.setRoleNames(Collections.singletonList("admin")); + + assertEquals("user-456", assignment.getUserId()); + assertEquals("realm2", assignment.getRealmName()); + assertEquals(1, assignment.getRoleNames().size()); + assertEquals("admin", assignment.getRoleNames().get(0)); + } + + @Test + void testEqualsAndHashCode() { + RoleAssignmentDTO assignment1 = RoleAssignmentDTO.builder() + .userId("user-123") + .realmName("test-realm") + .roleNames(Arrays.asList("admin")) + .typeRole(dev.lions.user.manager.enums.role.TypeRole.REALM_ROLE) + .build(); + + RoleAssignmentDTO assignment2 = RoleAssignmentDTO.builder() + .userId("user-123") + .realmName("test-realm") + .roleNames(Arrays.asList("admin")) + .typeRole(dev.lions.user.manager.enums.role.TypeRole.REALM_ROLE) + .build(); + + assertEquals(assignment1, assignment2); + assertEquals(assignment1.hashCode(), assignment2.hashCode()); + } + + @Test + void testIsValidForClientRole() { + RoleAssignmentDTO assignment = RoleAssignmentDTO.builder() + .typeRole(dev.lions.user.manager.enums.role.TypeRole.CLIENT_ROLE) + .clientName("test-client") + .build(); + + assertTrue(assignment.isValidForClientRole()); + } + + @Test + void testIsValidForRealmRole() { + RoleAssignmentDTO assignment = RoleAssignmentDTO.builder() + .typeRole(dev.lions.user.manager.enums.role.TypeRole.REALM_ROLE) + .build(); + + assertTrue(assignment.isValidForRealmRole()); + } + + @Test + void testGetRoleCount() { + RoleAssignmentDTO assignment = RoleAssignmentDTO.builder() + .roleNames(Arrays.asList("admin", "user", "viewer")) + .build(); + + assertEquals(3, assignment.getRoleCount()); + } + + @Test + void testGetRoleCount_Empty() { + RoleAssignmentDTO assignment = RoleAssignmentDTO.builder() + .roleNames(Collections.emptyList()) + .build(); + + assertEquals(0, assignment.getRoleCount()); + } + + @Test + void testGetRoleCount_Null() { + RoleAssignmentDTO assignment = new RoleAssignmentDTO(); + + assertEquals(0, assignment.getRoleCount()); + } + + @Test + void testToString() { + RoleAssignmentDTO assignment = RoleAssignmentDTO.builder() + .userId("user-123") + .realmName("test-realm") + .build(); + + String toString = assignment.toString(); + assertNotNull(toString); + } +} diff --git a/src/test/java/dev/lions/user/manager/dto/role/RoleDTOTest.java b/src/test/java/dev/lions/user/manager/dto/role/RoleDTOTest.java index 482bcce..177f977 100644 --- a/src/test/java/dev/lions/user/manager/dto/role/RoleDTOTest.java +++ b/src/test/java/dev/lions/user/manager/dto/role/RoleDTOTest.java @@ -1,318 +1,318 @@ -package dev.lions.user.manager.dto.role; - -import dev.lions.user.manager.enums.role.TypeRole; -import org.junit.jupiter.api.Test; - -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static org.junit.jupiter.api.Assertions.*; - -class RoleDTOTest { - - @Test - void testIsRealmRole_true() { - RoleDTO role = new RoleDTO(); - role.setTypeRole(TypeRole.REALM_ROLE); - assertTrue(role.isRealmRole()); - assertFalse(role.isClientRole()); - } - - @Test - void testIsRealmRole_false() { - RoleDTO role = new RoleDTO(); - role.setTypeRole(TypeRole.CLIENT_ROLE); - assertFalse(role.isRealmRole()); - } - - @Test - void testIsRealmRole_null() { - RoleDTO role = new RoleDTO(); - role.setTypeRole(null); - assertFalse(role.isRealmRole()); - } - - @Test - void testIsClientRole_true() { - RoleDTO role = new RoleDTO(); - role.setTypeRole(TypeRole.CLIENT_ROLE); - assertTrue(role.isClientRole()); - assertFalse(role.isRealmRole()); - } - - @Test - void testIsClientRole_false() { - RoleDTO role = new RoleDTO(); - role.setTypeRole(TypeRole.REALM_ROLE); - assertFalse(role.isClientRole()); - } - - @Test - void testIsClientRole_null() { - RoleDTO role = new RoleDTO(); - role.setTypeRole(null); - assertFalse(role.isClientRole()); - } - - @Test - void testIsComposite_withCompositeRoles() { - RoleDTO role = new RoleDTO(); - role.setComposite(true); - role.setCompositeRoles(Arrays.asList("role1", "role2")); - assertTrue(role.isComposite()); - } - - @Test - void testIsComposite_withCompositeRealmRoles() { - RoleDTO role = new RoleDTO(); - role.setComposite(true); - role.setCompositeRoles(null); - role.setCompositeRealmRoles(Collections.singletonList(new RoleDTO.RoleCompositeDTO())); - assertTrue(role.isComposite()); - } - - @Test - void testIsComposite_withCompositeClientRoles() { - RoleDTO role = new RoleDTO(); - role.setComposite(true); - role.setCompositeRoles(null); - role.setCompositeRealmRoles(null); - Map> clientRoles = new HashMap<>(); - clientRoles.put("client", Collections.singletonList(new RoleDTO.RoleCompositeDTO())); - role.setCompositeClientRoles(clientRoles); - assertTrue(role.isComposite()); - } - - @Test - void testIsComposite_falseWhenCompositeFalse() { - RoleDTO role = new RoleDTO(); - role.setComposite(false); - role.setCompositeRoles(Arrays.asList("role1")); - assertFalse(role.isComposite()); - } - - @Test - void testIsComposite_falseWhenCompositeNull() { - RoleDTO role = new RoleDTO(); - role.setComposite(null); - role.setCompositeRoles(Arrays.asList("role1")); - assertFalse(role.isComposite()); - } - - @Test - void testIsComposite_falseWhenNoRoles() { - RoleDTO role = new RoleDTO(); - role.setComposite(true); - role.setCompositeRoles(null); - role.setCompositeRealmRoles(null); - role.setCompositeClientRoles(null); - assertFalse(role.isComposite()); - } - - @Test - void testIsComposite_falseWhenEmptyRoles() { - RoleDTO role = new RoleDTO(); - role.setComposite(true); - role.setCompositeRoles(Collections.emptyList()); - role.setCompositeRealmRoles(Collections.emptyList()); - role.setCompositeClientRoles(Collections.emptyMap()); - assertFalse(role.isComposite()); - } - - @Test - void testGetFullName_realmRole() { - RoleDTO role = new RoleDTO(); - role.setName("admin"); - role.setTypeRole(TypeRole.REALM_ROLE); - assertEquals("admin", role.getFullName()); - } - - @Test - void testGetFullName_clientRole() { - RoleDTO role = new RoleDTO(); - role.setName("admin"); - role.setTypeRole(TypeRole.CLIENT_ROLE); - role.setClientName("app"); - assertEquals("app:admin", role.getFullName()); - } - - @Test - void testGetFullName_clientRoleNullClientName() { - RoleDTO role = new RoleDTO(); - role.setName("admin"); - role.setTypeRole(TypeRole.CLIENT_ROLE); - role.setClientName(null); - assertEquals("admin", role.getFullName()); - } - - @Test - void testGetFullName_nullTypeRole() { - RoleDTO role = new RoleDTO(); - role.setName("admin"); - role.setTypeRole(null); - assertEquals("admin", role.getFullName()); - } - - @Test - void testRoleCompositeDTO_builder() { - RoleDTO.RoleCompositeDTO comp = RoleDTO.RoleCompositeDTO.builder() - .id("1") - .name("role") - .description("desc") - .typeRole(TypeRole.REALM_ROLE) - .clientName("client") - .build(); - - assertEquals("1", comp.getId()); - assertEquals("role", comp.getName()); - assertEquals("desc", comp.getDescription()); - assertEquals(TypeRole.REALM_ROLE, comp.getTypeRole()); - assertEquals("client", comp.getClientName()); - } - - @Test - void testRoleCompositeDTO_settersGetters() { - RoleDTO.RoleCompositeDTO comp = new RoleDTO.RoleCompositeDTO(); - comp.setId("id"); - comp.setName("name"); - comp.setDescription("desc"); - comp.setTypeRole(TypeRole.CLIENT_ROLE); - comp.setClientName("client"); - - assertEquals("id", comp.getId()); - assertEquals("name", comp.getName()); - assertEquals("desc", comp.getDescription()); - assertEquals(TypeRole.CLIENT_ROLE, comp.getTypeRole()); - assertEquals("client", comp.getClientName()); - } - - @Test - void testRoleCompositeDTO_allArgsConstructor() { - RoleDTO.RoleCompositeDTO comp = new RoleDTO.RoleCompositeDTO("id", "name", "desc", TypeRole.REALM_ROLE, - "client"); - assertEquals("id", comp.getId()); - assertEquals("name", comp.getName()); - assertEquals("desc", comp.getDescription()); - assertEquals(TypeRole.REALM_ROLE, comp.getTypeRole()); - assertEquals("client", comp.getClientName()); - } - - @Test - void testRoleCompositeDTO_equalsAndHashCode() { - RoleDTO.RoleCompositeDTO comp1 = RoleDTO.RoleCompositeDTO.builder().id("1").name("role").build(); - RoleDTO.RoleCompositeDTO comp2 = RoleDTO.RoleCompositeDTO.builder().id("1").name("role").build(); - RoleDTO.RoleCompositeDTO comp3 = RoleDTO.RoleCompositeDTO.builder().id("2").name("other").build(); - - assertEquals(comp1, comp2); - assertEquals(comp1.hashCode(), comp2.hashCode()); - assertNotEquals(comp1, comp3); - } - - @Test - void testRoleCompositeDTO_toString() { - RoleDTO.RoleCompositeDTO comp = RoleDTO.RoleCompositeDTO.builder().id("1").name("role").build(); - String str = comp.toString(); - assertNotNull(str); - assertTrue(str.contains("role")); - } - - @Test - void testBuilderAndAllFields() { - Map> attrs = new HashMap<>(); - attrs.put("key", Collections.singletonList("value")); - Map> clientComposites = new HashMap<>(); - clientComposites.put("client", - Collections.singletonList(RoleDTO.RoleCompositeDTO.builder().name("subclient").build())); - - RoleDTO role = RoleDTO.builder() - .id("uuid-123") - .name("admin") - .description("Administrator role") - .typeRole(TypeRole.REALM_ROLE) - .composite(true) - .containerId("container") - .realmName("realm") - .clientName("client") - .clientId("clientId") - .compositeRoles(Arrays.asList("role1", "role2")) - .compositeRealmRoles( - Collections.singletonList(RoleDTO.RoleCompositeDTO.builder().name("subrealm").build())) - .compositeClientRoles(clientComposites) - .attributes(attrs) - .userCount(10) - .systemRole(false) - .deletable(true) - .build(); - - assertEquals("uuid-123", role.getId()); - assertEquals("admin", role.getName()); - assertEquals("Administrator role", role.getDescription()); - assertEquals(TypeRole.REALM_ROLE, role.getTypeRole()); - assertTrue(role.getComposite()); - assertEquals("container", role.getContainerId()); - assertEquals("realm", role.getRealmName()); - assertEquals("client", role.getClientName()); - assertEquals("clientId", role.getClientId()); - assertEquals(2, role.getCompositeRoles().size()); - assertEquals(1, role.getCompositeRealmRoles().size()); - assertEquals(1, role.getCompositeClientRoles().size()); - assertEquals(1, role.getAttributes().size()); - assertEquals(10, role.getUserCount()); - assertFalse(role.getSystemRole()); - assertTrue(role.getDeletable()); - } - - @Test - void testEqualsAndHashCode() { - RoleDTO role1 = RoleDTO.builder().id("uuid-123").name("admin").build(); - RoleDTO role2 = RoleDTO.builder().id("uuid-123").name("admin").build(); - RoleDTO role3 = RoleDTO.builder().id("uuid-456").name("user").build(); - - assertEquals(role1, role2); - assertEquals(role1.hashCode(), role2.hashCode()); - assertNotEquals(role1, role3); - } - - @Test - void testToString() { - RoleDTO role = RoleDTO.builder().name("admin").description("Admin role").build(); - String str = role.toString(); - assertNotNull(str); - assertTrue(str.contains("admin")); - } - - @Test - void testNoArgsConstructor() { - RoleDTO role = new RoleDTO(); - assertNull(role.getName()); - assertNull(role.getDescription()); - } - - @Test - void testAllArgsConstructor() { - Map> attrs = new HashMap<>(); - Map> clientComposites = new HashMap<>(); - List compositeRoles = Collections.emptyList(); - List realmComposites = Collections.emptyList(); - - RoleDTO role = new RoleDTO( - "name", "desc", TypeRole.REALM_ROLE, true, "container", "realm", - "clientName", "clientId", compositeRoles, realmComposites, clientComposites, - attrs, 5, true, false); - - assertEquals("name", role.getName()); - assertEquals("desc", role.getDescription()); - assertEquals(TypeRole.REALM_ROLE, role.getTypeRole()); - assertTrue(role.getComposite()); - assertEquals("container", role.getContainerId()); - assertEquals("realm", role.getRealmName()); - assertEquals("clientName", role.getClientName()); - assertEquals("clientId", role.getClientId()); - assertEquals(5, role.getUserCount()); - assertTrue(role.getSystemRole()); - assertFalse(role.getDeletable()); - } -} +package dev.lions.user.manager.dto.role; + +import dev.lions.user.manager.enums.role.TypeRole; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.*; + +class RoleDTOTest { + + @Test + void testIsRealmRole_true() { + RoleDTO role = new RoleDTO(); + role.setTypeRole(TypeRole.REALM_ROLE); + assertTrue(role.isRealmRole()); + assertFalse(role.isClientRole()); + } + + @Test + void testIsRealmRole_false() { + RoleDTO role = new RoleDTO(); + role.setTypeRole(TypeRole.CLIENT_ROLE); + assertFalse(role.isRealmRole()); + } + + @Test + void testIsRealmRole_null() { + RoleDTO role = new RoleDTO(); + role.setTypeRole(null); + assertFalse(role.isRealmRole()); + } + + @Test + void testIsClientRole_true() { + RoleDTO role = new RoleDTO(); + role.setTypeRole(TypeRole.CLIENT_ROLE); + assertTrue(role.isClientRole()); + assertFalse(role.isRealmRole()); + } + + @Test + void testIsClientRole_false() { + RoleDTO role = new RoleDTO(); + role.setTypeRole(TypeRole.REALM_ROLE); + assertFalse(role.isClientRole()); + } + + @Test + void testIsClientRole_null() { + RoleDTO role = new RoleDTO(); + role.setTypeRole(null); + assertFalse(role.isClientRole()); + } + + @Test + void testIsComposite_withCompositeRoles() { + RoleDTO role = new RoleDTO(); + role.setComposite(true); + role.setCompositeRoles(Arrays.asList("role1", "role2")); + assertTrue(role.isComposite()); + } + + @Test + void testIsComposite_withCompositeRealmRoles() { + RoleDTO role = new RoleDTO(); + role.setComposite(true); + role.setCompositeRoles(null); + role.setCompositeRealmRoles(Collections.singletonList(new RoleDTO.RoleCompositeDTO())); + assertTrue(role.isComposite()); + } + + @Test + void testIsComposite_withCompositeClientRoles() { + RoleDTO role = new RoleDTO(); + role.setComposite(true); + role.setCompositeRoles(null); + role.setCompositeRealmRoles(null); + Map> clientRoles = new HashMap<>(); + clientRoles.put("client", Collections.singletonList(new RoleDTO.RoleCompositeDTO())); + role.setCompositeClientRoles(clientRoles); + assertTrue(role.isComposite()); + } + + @Test + void testIsComposite_falseWhenCompositeFalse() { + RoleDTO role = new RoleDTO(); + role.setComposite(false); + role.setCompositeRoles(Arrays.asList("role1")); + assertFalse(role.isComposite()); + } + + @Test + void testIsComposite_falseWhenCompositeNull() { + RoleDTO role = new RoleDTO(); + role.setComposite(null); + role.setCompositeRoles(Arrays.asList("role1")); + assertFalse(role.isComposite()); + } + + @Test + void testIsComposite_falseWhenNoRoles() { + RoleDTO role = new RoleDTO(); + role.setComposite(true); + role.setCompositeRoles(null); + role.setCompositeRealmRoles(null); + role.setCompositeClientRoles(null); + assertFalse(role.isComposite()); + } + + @Test + void testIsComposite_falseWhenEmptyRoles() { + RoleDTO role = new RoleDTO(); + role.setComposite(true); + role.setCompositeRoles(Collections.emptyList()); + role.setCompositeRealmRoles(Collections.emptyList()); + role.setCompositeClientRoles(Collections.emptyMap()); + assertFalse(role.isComposite()); + } + + @Test + void testGetFullName_realmRole() { + RoleDTO role = new RoleDTO(); + role.setName("admin"); + role.setTypeRole(TypeRole.REALM_ROLE); + assertEquals("admin", role.getFullName()); + } + + @Test + void testGetFullName_clientRole() { + RoleDTO role = new RoleDTO(); + role.setName("admin"); + role.setTypeRole(TypeRole.CLIENT_ROLE); + role.setClientName("app"); + assertEquals("app:admin", role.getFullName()); + } + + @Test + void testGetFullName_clientRoleNullClientName() { + RoleDTO role = new RoleDTO(); + role.setName("admin"); + role.setTypeRole(TypeRole.CLIENT_ROLE); + role.setClientName(null); + assertEquals("admin", role.getFullName()); + } + + @Test + void testGetFullName_nullTypeRole() { + RoleDTO role = new RoleDTO(); + role.setName("admin"); + role.setTypeRole(null); + assertEquals("admin", role.getFullName()); + } + + @Test + void testRoleCompositeDTO_builder() { + RoleDTO.RoleCompositeDTO comp = RoleDTO.RoleCompositeDTO.builder() + .id("1") + .name("role") + .description("desc") + .typeRole(TypeRole.REALM_ROLE) + .clientName("client") + .build(); + + assertEquals("1", comp.getId()); + assertEquals("role", comp.getName()); + assertEquals("desc", comp.getDescription()); + assertEquals(TypeRole.REALM_ROLE, comp.getTypeRole()); + assertEquals("client", comp.getClientName()); + } + + @Test + void testRoleCompositeDTO_settersGetters() { + RoleDTO.RoleCompositeDTO comp = new RoleDTO.RoleCompositeDTO(); + comp.setId("id"); + comp.setName("name"); + comp.setDescription("desc"); + comp.setTypeRole(TypeRole.CLIENT_ROLE); + comp.setClientName("client"); + + assertEquals("id", comp.getId()); + assertEquals("name", comp.getName()); + assertEquals("desc", comp.getDescription()); + assertEquals(TypeRole.CLIENT_ROLE, comp.getTypeRole()); + assertEquals("client", comp.getClientName()); + } + + @Test + void testRoleCompositeDTO_allArgsConstructor() { + RoleDTO.RoleCompositeDTO comp = new RoleDTO.RoleCompositeDTO("id", "name", "desc", TypeRole.REALM_ROLE, + "client"); + assertEquals("id", comp.getId()); + assertEquals("name", comp.getName()); + assertEquals("desc", comp.getDescription()); + assertEquals(TypeRole.REALM_ROLE, comp.getTypeRole()); + assertEquals("client", comp.getClientName()); + } + + @Test + void testRoleCompositeDTO_equalsAndHashCode() { + RoleDTO.RoleCompositeDTO comp1 = RoleDTO.RoleCompositeDTO.builder().id("1").name("role").build(); + RoleDTO.RoleCompositeDTO comp2 = RoleDTO.RoleCompositeDTO.builder().id("1").name("role").build(); + RoleDTO.RoleCompositeDTO comp3 = RoleDTO.RoleCompositeDTO.builder().id("2").name("other").build(); + + assertEquals(comp1, comp2); + assertEquals(comp1.hashCode(), comp2.hashCode()); + assertNotEquals(comp1, comp3); + } + + @Test + void testRoleCompositeDTO_toString() { + RoleDTO.RoleCompositeDTO comp = RoleDTO.RoleCompositeDTO.builder().id("1").name("role").build(); + String str = comp.toString(); + assertNotNull(str); + assertTrue(str.contains("role")); + } + + @Test + void testBuilderAndAllFields() { + Map> attrs = new HashMap<>(); + attrs.put("key", Collections.singletonList("value")); + Map> clientComposites = new HashMap<>(); + clientComposites.put("client", + Collections.singletonList(RoleDTO.RoleCompositeDTO.builder().name("subclient").build())); + + RoleDTO role = RoleDTO.builder() + .id("uuid-123") + .name("admin") + .description("Administrator role") + .typeRole(TypeRole.REALM_ROLE) + .composite(true) + .containerId("container") + .realmName("realm") + .clientName("client") + .clientId("clientId") + .compositeRoles(Arrays.asList("role1", "role2")) + .compositeRealmRoles( + Collections.singletonList(RoleDTO.RoleCompositeDTO.builder().name("subrealm").build())) + .compositeClientRoles(clientComposites) + .attributes(attrs) + .userCount(10) + .systemRole(false) + .deletable(true) + .build(); + + assertEquals("uuid-123", role.getId()); + assertEquals("admin", role.getName()); + assertEquals("Administrator role", role.getDescription()); + assertEquals(TypeRole.REALM_ROLE, role.getTypeRole()); + assertTrue(role.getComposite()); + assertEquals("container", role.getContainerId()); + assertEquals("realm", role.getRealmName()); + assertEquals("client", role.getClientName()); + assertEquals("clientId", role.getClientId()); + assertEquals(2, role.getCompositeRoles().size()); + assertEquals(1, role.getCompositeRealmRoles().size()); + assertEquals(1, role.getCompositeClientRoles().size()); + assertEquals(1, role.getAttributes().size()); + assertEquals(10, role.getUserCount()); + assertFalse(role.getSystemRole()); + assertTrue(role.getDeletable()); + } + + @Test + void testEqualsAndHashCode() { + RoleDTO role1 = RoleDTO.builder().id("uuid-123").name("admin").build(); + RoleDTO role2 = RoleDTO.builder().id("uuid-123").name("admin").build(); + RoleDTO role3 = RoleDTO.builder().id("uuid-456").name("user").build(); + + assertEquals(role1, role2); + assertEquals(role1.hashCode(), role2.hashCode()); + assertNotEquals(role1, role3); + } + + @Test + void testToString() { + RoleDTO role = RoleDTO.builder().name("admin").description("Admin role").build(); + String str = role.toString(); + assertNotNull(str); + assertTrue(str.contains("admin")); + } + + @Test + void testNoArgsConstructor() { + RoleDTO role = new RoleDTO(); + assertNull(role.getName()); + assertNull(role.getDescription()); + } + + @Test + void testAllArgsConstructor() { + Map> attrs = new HashMap<>(); + Map> clientComposites = new HashMap<>(); + List compositeRoles = Collections.emptyList(); + List realmComposites = Collections.emptyList(); + + RoleDTO role = new RoleDTO( + "name", "desc", TypeRole.REALM_ROLE, true, "container", "realm", + "clientName", "clientId", compositeRoles, realmComposites, clientComposites, + attrs, 5, true, false); + + assertEquals("name", role.getName()); + assertEquals("desc", role.getDescription()); + assertEquals(TypeRole.REALM_ROLE, role.getTypeRole()); + assertTrue(role.getComposite()); + assertEquals("container", role.getContainerId()); + assertEquals("realm", role.getRealmName()); + assertEquals("clientName", role.getClientName()); + assertEquals("clientId", role.getClientId()); + assertEquals(5, role.getUserCount()); + assertTrue(role.getSystemRole()); + assertFalse(role.getDeletable()); + } +} diff --git a/src/test/java/dev/lions/user/manager/dto/sync/HealthStatusDTOTest.java b/src/test/java/dev/lions/user/manager/dto/sync/HealthStatusDTOTest.java index c6bcaee..cf2320c 100644 --- a/src/test/java/dev/lions/user/manager/dto/sync/HealthStatusDTOTest.java +++ b/src/test/java/dev/lions/user/manager/dto/sync/HealthStatusDTOTest.java @@ -1,125 +1,125 @@ -package dev.lions.user.manager.dto.sync; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - -class HealthStatusDTOTest { - - @Test - void testBuilderAndAllFields() { - HealthStatusDTO dto = HealthStatusDTO.builder() - .timestamp(1699545600000L) - .keycloakAccessible(true) - .keycloakVersion("23.0.3") - .realmsAccessible(true) - .realmsCount(5) - .overallHealthy(true) - .errorMessage(null) - .build(); - - assertEquals(1699545600000L, dto.getTimestamp()); - assertTrue(dto.isKeycloakAccessible()); - assertEquals("23.0.3", dto.getKeycloakVersion()); - assertTrue(dto.isRealmsAccessible()); - assertEquals(5, dto.getRealmsCount()); - assertTrue(dto.isOverallHealthy()); - assertNull(dto.getErrorMessage()); - } - - @Test - void testBuilderWithError() { - HealthStatusDTO dto = HealthStatusDTO.builder() - .timestamp(System.currentTimeMillis()) - .keycloakAccessible(false) - .realmsAccessible(false) - .overallHealthy(false) - .errorMessage("Connection refused") - .build(); - - assertFalse(dto.isKeycloakAccessible()); - assertFalse(dto.isRealmsAccessible()); - assertFalse(dto.isOverallHealthy()); - assertEquals("Connection refused", dto.getErrorMessage()); - } - - @Test - void testSettersAndGetters() { - HealthStatusDTO dto = new HealthStatusDTO(); - dto.setTimestamp(12345L); - dto.setKeycloakAccessible(true); - dto.setKeycloakVersion("24.0.0"); - dto.setRealmsAccessible(true); - dto.setRealmsCount(3); - dto.setOverallHealthy(true); - dto.setErrorMessage("warning"); - - assertEquals(12345L, dto.getTimestamp()); - assertTrue(dto.isKeycloakAccessible()); - assertEquals("24.0.0", dto.getKeycloakVersion()); - assertTrue(dto.isRealmsAccessible()); - assertEquals(3, dto.getRealmsCount()); - assertTrue(dto.isOverallHealthy()); - assertEquals("warning", dto.getErrorMessage()); - } - - @Test - void testEqualsAndHashCode() { - HealthStatusDTO dto1 = HealthStatusDTO.builder() - .timestamp(1000L) - .keycloakVersion("23.0.3") - .overallHealthy(true) - .build(); - HealthStatusDTO dto2 = HealthStatusDTO.builder() - .timestamp(1000L) - .keycloakVersion("23.0.3") - .overallHealthy(true) - .build(); - HealthStatusDTO dto3 = HealthStatusDTO.builder() - .timestamp(2000L) - .keycloakVersion("24.0.0") - .overallHealthy(false) - .build(); - - assertEquals(dto1, dto2); - assertEquals(dto1.hashCode(), dto2.hashCode()); - assertNotEquals(dto1, dto3); - } - - @Test - void testToString() { - HealthStatusDTO dto = HealthStatusDTO.builder() - .keycloakVersion("23.0.3") - .overallHealthy(true) - .build(); - String str = dto.toString(); - assertNotNull(str); - assertTrue(str.contains("23.0.3")); - } - - @Test - void testNoArgsConstructor() { - HealthStatusDTO dto = new HealthStatusDTO(); - assertEquals(0L, dto.getTimestamp()); - assertFalse(dto.isKeycloakAccessible()); - assertNull(dto.getKeycloakVersion()); - assertFalse(dto.isRealmsAccessible()); - assertEquals(0, dto.getRealmsCount()); - assertFalse(dto.isOverallHealthy()); - assertNull(dto.getErrorMessage()); - } - - @Test - void testAllArgsConstructor() { - HealthStatusDTO dto = new HealthStatusDTO( - 1000L, true, "23.0.3", true, 5, true, null); - - assertEquals(1000L, dto.getTimestamp()); - assertTrue(dto.isKeycloakAccessible()); - assertEquals("23.0.3", dto.getKeycloakVersion()); - assertTrue(dto.isRealmsAccessible()); - assertEquals(5, dto.getRealmsCount()); - assertTrue(dto.isOverallHealthy()); - assertNull(dto.getErrorMessage()); - } -} +package dev.lions.user.manager.dto.sync; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class HealthStatusDTOTest { + + @Test + void testBuilderAndAllFields() { + HealthStatusDTO dto = HealthStatusDTO.builder() + .timestamp(1699545600000L) + .keycloakAccessible(true) + .keycloakVersion("23.0.3") + .realmsAccessible(true) + .realmsCount(5) + .overallHealthy(true) + .errorMessage(null) + .build(); + + assertEquals(1699545600000L, dto.getTimestamp()); + assertTrue(dto.isKeycloakAccessible()); + assertEquals("23.0.3", dto.getKeycloakVersion()); + assertTrue(dto.isRealmsAccessible()); + assertEquals(5, dto.getRealmsCount()); + assertTrue(dto.isOverallHealthy()); + assertNull(dto.getErrorMessage()); + } + + @Test + void testBuilderWithError() { + HealthStatusDTO dto = HealthStatusDTO.builder() + .timestamp(System.currentTimeMillis()) + .keycloakAccessible(false) + .realmsAccessible(false) + .overallHealthy(false) + .errorMessage("Connection refused") + .build(); + + assertFalse(dto.isKeycloakAccessible()); + assertFalse(dto.isRealmsAccessible()); + assertFalse(dto.isOverallHealthy()); + assertEquals("Connection refused", dto.getErrorMessage()); + } + + @Test + void testSettersAndGetters() { + HealthStatusDTO dto = new HealthStatusDTO(); + dto.setTimestamp(12345L); + dto.setKeycloakAccessible(true); + dto.setKeycloakVersion("24.0.0"); + dto.setRealmsAccessible(true); + dto.setRealmsCount(3); + dto.setOverallHealthy(true); + dto.setErrorMessage("warning"); + + assertEquals(12345L, dto.getTimestamp()); + assertTrue(dto.isKeycloakAccessible()); + assertEquals("24.0.0", dto.getKeycloakVersion()); + assertTrue(dto.isRealmsAccessible()); + assertEquals(3, dto.getRealmsCount()); + assertTrue(dto.isOverallHealthy()); + assertEquals("warning", dto.getErrorMessage()); + } + + @Test + void testEqualsAndHashCode() { + HealthStatusDTO dto1 = HealthStatusDTO.builder() + .timestamp(1000L) + .keycloakVersion("23.0.3") + .overallHealthy(true) + .build(); + HealthStatusDTO dto2 = HealthStatusDTO.builder() + .timestamp(1000L) + .keycloakVersion("23.0.3") + .overallHealthy(true) + .build(); + HealthStatusDTO dto3 = HealthStatusDTO.builder() + .timestamp(2000L) + .keycloakVersion("24.0.0") + .overallHealthy(false) + .build(); + + assertEquals(dto1, dto2); + assertEquals(dto1.hashCode(), dto2.hashCode()); + assertNotEquals(dto1, dto3); + } + + @Test + void testToString() { + HealthStatusDTO dto = HealthStatusDTO.builder() + .keycloakVersion("23.0.3") + .overallHealthy(true) + .build(); + String str = dto.toString(); + assertNotNull(str); + assertTrue(str.contains("23.0.3")); + } + + @Test + void testNoArgsConstructor() { + HealthStatusDTO dto = new HealthStatusDTO(); + assertEquals(0L, dto.getTimestamp()); + assertFalse(dto.isKeycloakAccessible()); + assertNull(dto.getKeycloakVersion()); + assertFalse(dto.isRealmsAccessible()); + assertEquals(0, dto.getRealmsCount()); + assertFalse(dto.isOverallHealthy()); + assertNull(dto.getErrorMessage()); + } + + @Test + void testAllArgsConstructor() { + HealthStatusDTO dto = new HealthStatusDTO( + 1000L, true, "23.0.3", true, 5, true, null); + + assertEquals(1000L, dto.getTimestamp()); + assertTrue(dto.isKeycloakAccessible()); + assertEquals("23.0.3", dto.getKeycloakVersion()); + assertTrue(dto.isRealmsAccessible()); + assertEquals(5, dto.getRealmsCount()); + assertTrue(dto.isOverallHealthy()); + assertNull(dto.getErrorMessage()); + } +} diff --git a/src/test/java/dev/lions/user/manager/dto/sync/SyncResultDTOTest.java b/src/test/java/dev/lions/user/manager/dto/sync/SyncResultDTOTest.java index 0be3a91..4704f63 100644 --- a/src/test/java/dev/lions/user/manager/dto/sync/SyncResultDTOTest.java +++ b/src/test/java/dev/lions/user/manager/dto/sync/SyncResultDTOTest.java @@ -1,127 +1,127 @@ -package dev.lions.user.manager.dto.sync; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - -class SyncResultDTOTest { - - @Test - void testGetDurationMs() { - SyncResultDTO dto = SyncResultDTO.builder() - .startTime(1000L) - .endTime(5000L) - .build(); - assertEquals(4000L, dto.getDurationMs()); - } - - @Test - void testGetDurationMs_sameTime() { - SyncResultDTO dto = SyncResultDTO.builder() - .startTime(1000L) - .endTime(1000L) - .build(); - assertEquals(0L, dto.getDurationMs()); - } - - @Test - void testBuilderAndAllFields() { - SyncResultDTO dto = SyncResultDTO.builder() - .realmName("btpxpress") - .usersCount(150) - .realmRolesCount(25) - .clientRolesCount(50) - .success(true) - .errorMessage(null) - .startTime(1699545600000L) - .endTime(1699545615000L) - .build(); - - assertEquals("btpxpress", dto.getRealmName()); - assertEquals(150, dto.getUsersCount()); - assertEquals(25, dto.getRealmRolesCount()); - assertEquals(50, dto.getClientRolesCount()); - assertTrue(dto.isSuccess()); - assertNull(dto.getErrorMessage()); - assertEquals(1699545600000L, dto.getStartTime()); - assertEquals(1699545615000L, dto.getEndTime()); - assertEquals(15000L, dto.getDurationMs()); - } - - @Test - void testBuilderWithError() { - SyncResultDTO dto = SyncResultDTO.builder() - .realmName("btpxpress") - .success(false) - .errorMessage("Connection failed") - .build(); - - assertEquals("btpxpress", dto.getRealmName()); - assertFalse(dto.isSuccess()); - assertEquals("Connection failed", dto.getErrorMessage()); - } - - @Test - void testSettersAndGetters() { - SyncResultDTO dto = new SyncResultDTO(); - dto.setRealmName("realm"); - dto.setUsersCount(10); - dto.setRealmRolesCount(5); - dto.setClientRolesCount(3); - dto.setSuccess(true); - dto.setErrorMessage("error"); - dto.setStartTime(100L); - dto.setEndTime(200L); - - assertEquals("realm", dto.getRealmName()); - assertEquals(10, dto.getUsersCount()); - assertEquals(5, dto.getRealmRolesCount()); - assertEquals(3, dto.getClientRolesCount()); - assertTrue(dto.isSuccess()); - assertEquals("error", dto.getErrorMessage()); - assertEquals(100L, dto.getStartTime()); - assertEquals(200L, dto.getEndTime()); - } - - @Test - void testEqualsAndHashCode() { - SyncResultDTO dto1 = SyncResultDTO.builder().realmName("realm").usersCount(10).build(); - SyncResultDTO dto2 = SyncResultDTO.builder().realmName("realm").usersCount(10).build(); - SyncResultDTO dto3 = SyncResultDTO.builder().realmName("other").usersCount(5).build(); - - assertEquals(dto1, dto2); - assertEquals(dto1.hashCode(), dto2.hashCode()); - assertNotEquals(dto1, dto3); - } - - @Test - void testToString() { - SyncResultDTO dto = SyncResultDTO.builder().realmName("realm").success(true).build(); - String str = dto.toString(); - assertNotNull(str); - assertTrue(str.contains("realm")); - } - - @Test - void testNoArgsConstructor() { - SyncResultDTO dto = new SyncResultDTO(); - assertNull(dto.getRealmName()); - assertEquals(0, dto.getUsersCount()); - assertFalse(dto.isSuccess()); - } - - @Test - void testAllArgsConstructor() { - SyncResultDTO dto = new SyncResultDTO( - "realm", 100, 20, 30, true, null, 1000L, 2000L); - - assertEquals("realm", dto.getRealmName()); - assertEquals(100, dto.getUsersCount()); - assertEquals(20, dto.getRealmRolesCount()); - assertEquals(30, dto.getClientRolesCount()); - assertTrue(dto.isSuccess()); - assertNull(dto.getErrorMessage()); - assertEquals(1000L, dto.getStartTime()); - assertEquals(2000L, dto.getEndTime()); - } -} +package dev.lions.user.manager.dto.sync; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class SyncResultDTOTest { + + @Test + void testGetDurationMs() { + SyncResultDTO dto = SyncResultDTO.builder() + .startTime(1000L) + .endTime(5000L) + .build(); + assertEquals(4000L, dto.getDurationMs()); + } + + @Test + void testGetDurationMs_sameTime() { + SyncResultDTO dto = SyncResultDTO.builder() + .startTime(1000L) + .endTime(1000L) + .build(); + assertEquals(0L, dto.getDurationMs()); + } + + @Test + void testBuilderAndAllFields() { + SyncResultDTO dto = SyncResultDTO.builder() + .realmName("btpxpress") + .usersCount(150) + .realmRolesCount(25) + .clientRolesCount(50) + .success(true) + .errorMessage(null) + .startTime(1699545600000L) + .endTime(1699545615000L) + .build(); + + assertEquals("btpxpress", dto.getRealmName()); + assertEquals(150, dto.getUsersCount()); + assertEquals(25, dto.getRealmRolesCount()); + assertEquals(50, dto.getClientRolesCount()); + assertTrue(dto.isSuccess()); + assertNull(dto.getErrorMessage()); + assertEquals(1699545600000L, dto.getStartTime()); + assertEquals(1699545615000L, dto.getEndTime()); + assertEquals(15000L, dto.getDurationMs()); + } + + @Test + void testBuilderWithError() { + SyncResultDTO dto = SyncResultDTO.builder() + .realmName("btpxpress") + .success(false) + .errorMessage("Connection failed") + .build(); + + assertEquals("btpxpress", dto.getRealmName()); + assertFalse(dto.isSuccess()); + assertEquals("Connection failed", dto.getErrorMessage()); + } + + @Test + void testSettersAndGetters() { + SyncResultDTO dto = new SyncResultDTO(); + dto.setRealmName("realm"); + dto.setUsersCount(10); + dto.setRealmRolesCount(5); + dto.setClientRolesCount(3); + dto.setSuccess(true); + dto.setErrorMessage("error"); + dto.setStartTime(100L); + dto.setEndTime(200L); + + assertEquals("realm", dto.getRealmName()); + assertEquals(10, dto.getUsersCount()); + assertEquals(5, dto.getRealmRolesCount()); + assertEquals(3, dto.getClientRolesCount()); + assertTrue(dto.isSuccess()); + assertEquals("error", dto.getErrorMessage()); + assertEquals(100L, dto.getStartTime()); + assertEquals(200L, dto.getEndTime()); + } + + @Test + void testEqualsAndHashCode() { + SyncResultDTO dto1 = SyncResultDTO.builder().realmName("realm").usersCount(10).build(); + SyncResultDTO dto2 = SyncResultDTO.builder().realmName("realm").usersCount(10).build(); + SyncResultDTO dto3 = SyncResultDTO.builder().realmName("other").usersCount(5).build(); + + assertEquals(dto1, dto2); + assertEquals(dto1.hashCode(), dto2.hashCode()); + assertNotEquals(dto1, dto3); + } + + @Test + void testToString() { + SyncResultDTO dto = SyncResultDTO.builder().realmName("realm").success(true).build(); + String str = dto.toString(); + assertNotNull(str); + assertTrue(str.contains("realm")); + } + + @Test + void testNoArgsConstructor() { + SyncResultDTO dto = new SyncResultDTO(); + assertNull(dto.getRealmName()); + assertEquals(0, dto.getUsersCount()); + assertFalse(dto.isSuccess()); + } + + @Test + void testAllArgsConstructor() { + SyncResultDTO dto = new SyncResultDTO( + "realm", 100, 20, 30, true, null, 1000L, 2000L); + + assertEquals("realm", dto.getRealmName()); + assertEquals(100, dto.getUsersCount()); + assertEquals(20, dto.getRealmRolesCount()); + assertEquals(30, dto.getClientRolesCount()); + assertTrue(dto.isSuccess()); + assertNull(dto.getErrorMessage()); + assertEquals(1000L, dto.getStartTime()); + assertEquals(2000L, dto.getEndTime()); + } +} diff --git a/src/test/java/dev/lions/user/manager/dto/user/UserDTOTest.java b/src/test/java/dev/lions/user/manager/dto/user/UserDTOTest.java index d421f21..37ff878 100644 --- a/src/test/java/dev/lions/user/manager/dto/user/UserDTOTest.java +++ b/src/test/java/dev/lions/user/manager/dto/user/UserDTOTest.java @@ -1,305 +1,305 @@ -package dev.lions.user.manager.dto.user; - -import dev.lions.user.manager.enums.user.StatutUser; -import org.junit.jupiter.api.Test; - -import java.time.LocalDateTime; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static org.junit.jupiter.api.Assertions.*; - -class UserDTOTest { - - @Test - void testGetNomComplet_withPrenomAndNom() { - UserDTO user = new UserDTO(); - user.setPrenom("Jean"); - user.setNom("Dupont"); - user.setUsername("jdupont"); - assertEquals("Jean Dupont", user.getNomComplet()); - } - - @Test - void testGetNomComplet_withNullPrenom() { - UserDTO user = new UserDTO(); - user.setPrenom(null); - user.setNom("Dupont"); - user.setUsername("jdupont"); - assertEquals("jdupont", user.getNomComplet()); - } - - @Test - void testGetNomComplet_withNullNom() { - UserDTO user = new UserDTO(); - user.setPrenom("Jean"); - user.setNom(null); - user.setUsername("jdupont"); - assertEquals("jdupont", user.getNomComplet()); - } - - @Test - void testGetNomComplet_withBothNull() { - UserDTO user = new UserDTO(); - user.setPrenom(null); - user.setNom(null); - user.setUsername("jdupont"); - assertEquals("jdupont", user.getNomComplet()); - } - - @Test - void testIsActif_true() { - UserDTO user = new UserDTO(); - user.setStatut(StatutUser.ACTIF); - user.setEnabled(true); - assertTrue(user.isActif()); - } - - @Test - void testIsActif_falseWhenNotActif() { - UserDTO user = new UserDTO(); - user.setStatut(StatutUser.INACTIF); - user.setEnabled(true); - assertFalse(user.isActif()); - } - - @Test - void testIsActif_falseWhenNotEnabled() { - UserDTO user = new UserDTO(); - user.setStatut(StatutUser.ACTIF); - user.setEnabled(false); - assertFalse(user.isActif()); - } - - @Test - void testIsActif_falseWhenEnabledNull() { - UserDTO user = new UserDTO(); - user.setStatut(StatutUser.ACTIF); - user.setEnabled(null); - assertFalse(user.isActif()); - } - - @Test - void testIsExpire_true() { - UserDTO user = new UserDTO(); - user.setDateExpiration(LocalDateTime.now().minusDays(1)); - assertTrue(user.isExpire()); - } - - @Test - void testIsExpire_false() { - UserDTO user = new UserDTO(); - user.setDateExpiration(LocalDateTime.now().plusDays(1)); - assertFalse(user.isExpire()); - } - - @Test - void testIsExpire_nullDate() { - UserDTO user = new UserDTO(); - user.setDateExpiration(null); - assertFalse(user.isExpire()); - } - - @Test - void testHasRequiredActions_true() { - UserDTO user = new UserDTO(); - user.setRequiredActions(Arrays.asList("UPDATE_PASSWORD", "VERIFY_EMAIL")); - assertTrue(user.hasRequiredActions()); - } - - @Test - void testHasRequiredActions_empty() { - UserDTO user = new UserDTO(); - user.setRequiredActions(Collections.emptyList()); - assertFalse(user.hasRequiredActions()); - } - - @Test - void testHasRequiredActions_null() { - UserDTO user = new UserDTO(); - user.setRequiredActions(null); - assertFalse(user.hasRequiredActions()); - } - - @Test - void testBuilderAndAllFields() { - LocalDateTime now = LocalDateTime.now(); - Map> clientRoles = new HashMap<>(); - clientRoles.put("app", Arrays.asList("user", "admin")); - Map> attributes = new HashMap<>(); - attributes.put("custom", Collections.singletonList("value")); - - List fedIds = Collections.singletonList( - UserDTO.FederatedIdentityDTO.builder() - .identityProvider("google") - .userId("google-123") - .userName("user@gmail.com") - .build()); - - UserDTO user = UserDTO.builder() - .id("uuid-123") - .dateCreation(now) - .dateModification(now) - .creeParUsername("admin") - .modifieParUsername("admin") - .version(1L) - .username("jdupont") - .email("jean.dupont@lions.dev") - .emailVerified(true) - .prenom("Jean") - .nom("Dupont") - .statut(StatutUser.ACTIF) - .enabled(true) - .telephone("+225 07 12 34 56 78") - .organisation("Lions Dev") - .departement("IT") - .fonction("Developer") - .pays("Côte d'Ivoire") - .ville("Abidjan") - .langue("fr") - .timezone("Africa/Abidjan") - .realmName("btpxpress") - .realmRoles(Arrays.asList("user", "admin")) - .clientRoles(clientRoles) - .groups(Arrays.asList("group1", "group2")) - .derniereConnexion(now) - .dateExpiration(now.plusYears(1)) - .dateVerrouillage(null) - .attributes(attributes) - .requiredActions(Collections.singletonList("UPDATE_PASSWORD")) - .federatedIdentityProvider("google") - .federatedIdentities(fedIds) - .temporaryPassword("temp123") - .temporaryPasswordFlag(true) - .activeSessions(2) - .failedLoginAttempts(0) - .raisonModification("Update") - .commentaires("Test user") - .build(); - - assertEquals("uuid-123", user.getId()); - assertNotNull(user.getDateCreation()); - assertNotNull(user.getDateModification()); - assertEquals("admin", user.getCreeParUsername()); - assertEquals("admin", user.getModifieParUsername()); - assertEquals(1L, user.getVersion()); - assertEquals("jdupont", user.getUsername()); - assertEquals("jean.dupont@lions.dev", user.getEmail()); - assertTrue(user.getEmailVerified()); - assertEquals("Jean", user.getPrenom()); - assertEquals("Dupont", user.getNom()); - assertEquals(StatutUser.ACTIF, user.getStatut()); - assertTrue(user.getEnabled()); - assertEquals("+225 07 12 34 56 78", user.getTelephone()); - assertEquals("Lions Dev", user.getOrganisation()); - assertEquals("IT", user.getDepartement()); - assertEquals("Developer", user.getFonction()); - assertEquals("Côte d'Ivoire", user.getPays()); - assertEquals("Abidjan", user.getVille()); - assertEquals("fr", user.getLangue()); - assertEquals("Africa/Abidjan", user.getTimezone()); - assertEquals("btpxpress", user.getRealmName()); - assertEquals(2, user.getRealmRoles().size()); - assertEquals(1, user.getClientRoles().size()); - assertEquals(2, user.getGroups().size()); - assertNotNull(user.getDerniereConnexion()); - assertNotNull(user.getDateExpiration()); - assertNull(user.getDateVerrouillage()); - assertEquals(1, user.getAttributes().size()); - assertEquals(1, user.getRequiredActions().size()); - assertEquals("google", user.getFederatedIdentityProvider()); - assertEquals(1, user.getFederatedIdentities().size()); - assertEquals("temp123", user.getTemporaryPassword()); - assertTrue(user.getTemporaryPasswordFlag()); - assertEquals(2, user.getActiveSessions()); - assertEquals(0, user.getFailedLoginAttempts()); - assertEquals("Update", user.getRaisonModification()); - assertEquals("Test user", user.getCommentaires()); - } - - @Test - void testEqualsAndHashCode() { - UserDTO user1 = UserDTO.builder().id("uuid-123").username("jdupont").build(); - UserDTO user2 = UserDTO.builder().id("uuid-123").username("jdupont").build(); - UserDTO user3 = UserDTO.builder().id("uuid-456").username("other").build(); - - assertEquals(user1, user2); - assertEquals(user1.hashCode(), user2.hashCode()); - assertNotEquals(user1, user3); - } - - @Test - void testToString() { - UserDTO user = UserDTO.builder().username("jdupont").email("test@test.com").build(); - String str = user.toString(); - assertNotNull(str); - assertTrue(str.contains("jdupont")); - assertTrue(str.contains("test@test.com")); - } - - @Test - void testFederatedIdentityDTO() { - UserDTO.FederatedIdentityDTO fed = new UserDTO.FederatedIdentityDTO(); - fed.setIdentityProvider("google"); - fed.setUserId("user-123"); - fed.setUserName("user@gmail.com"); - - assertEquals("google", fed.getIdentityProvider()); - assertEquals("user-123", fed.getUserId()); - assertEquals("user@gmail.com", fed.getUserName()); - - // Test equals/hashCode/toString - UserDTO.FederatedIdentityDTO fed2 = UserDTO.FederatedIdentityDTO.builder() - .identityProvider("google") - .userId("user-123") - .userName("user@gmail.com") - .build(); - assertEquals(fed, fed2); - assertEquals(fed.hashCode(), fed2.hashCode()); - assertNotNull(fed.toString()); - } - - @Test - void testFederatedIdentityDTO_AllArgsConstructor() { - UserDTO.FederatedIdentityDTO fed = new UserDTO.FederatedIdentityDTO("google", "user-123", "user@gmail.com"); - assertEquals("google", fed.getIdentityProvider()); - assertEquals("user-123", fed.getUserId()); - assertEquals("user@gmail.com", fed.getUserName()); - } - - @Test - void testNoArgsConstructor() { - UserDTO user = new UserDTO(); - assertNull(user.getUsername()); - assertNull(user.getEmail()); - } - - @Test - void testAllArgsConstructor() { - LocalDateTime now = LocalDateTime.now(); - Map> clientRoles = new HashMap<>(); - Map> attributes = new HashMap<>(); - List fedIds = Collections.emptyList(); - List roles = Collections.emptyList(); - List groups = Collections.emptyList(); - List actions = Collections.emptyList(); - - UserDTO user = new UserDTO( - "username", "email@test.com", true, "Jean", "Dupont", - StatutUser.ACTIF, true, "phone", "org", "dept", "func", - "pays", "ville", "fr", "UTC", "realm", roles, clientRoles, - groups, now, now, now, attributes, actions, "google", fedIds, - "temppass", true, 1, 0, "reason", "comments"); - - assertEquals("username", user.getUsername()); - assertEquals("email@test.com", user.getEmail()); - assertTrue(user.getEmailVerified()); - assertEquals("Jean", user.getPrenom()); - assertEquals("Dupont", user.getNom()); - assertEquals(StatutUser.ACTIF, user.getStatut()); - assertTrue(user.getEnabled()); - } -} +package dev.lions.user.manager.dto.user; + +import dev.lions.user.manager.enums.user.StatutUser; +import org.junit.jupiter.api.Test; + +import java.time.LocalDateTime; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.*; + +class UserDTOTest { + + @Test + void testGetNomComplet_withPrenomAndNom() { + UserDTO user = new UserDTO(); + user.setPrenom("Jean"); + user.setNom("Dupont"); + user.setUsername("jdupont"); + assertEquals("Jean Dupont", user.getNomComplet()); + } + + @Test + void testGetNomComplet_withNullPrenom() { + UserDTO user = new UserDTO(); + user.setPrenom(null); + user.setNom("Dupont"); + user.setUsername("jdupont"); + assertEquals("jdupont", user.getNomComplet()); + } + + @Test + void testGetNomComplet_withNullNom() { + UserDTO user = new UserDTO(); + user.setPrenom("Jean"); + user.setNom(null); + user.setUsername("jdupont"); + assertEquals("jdupont", user.getNomComplet()); + } + + @Test + void testGetNomComplet_withBothNull() { + UserDTO user = new UserDTO(); + user.setPrenom(null); + user.setNom(null); + user.setUsername("jdupont"); + assertEquals("jdupont", user.getNomComplet()); + } + + @Test + void testIsActif_true() { + UserDTO user = new UserDTO(); + user.setStatut(StatutUser.ACTIF); + user.setEnabled(true); + assertTrue(user.isActif()); + } + + @Test + void testIsActif_falseWhenNotActif() { + UserDTO user = new UserDTO(); + user.setStatut(StatutUser.INACTIF); + user.setEnabled(true); + assertFalse(user.isActif()); + } + + @Test + void testIsActif_falseWhenNotEnabled() { + UserDTO user = new UserDTO(); + user.setStatut(StatutUser.ACTIF); + user.setEnabled(false); + assertFalse(user.isActif()); + } + + @Test + void testIsActif_falseWhenEnabledNull() { + UserDTO user = new UserDTO(); + user.setStatut(StatutUser.ACTIF); + user.setEnabled(null); + assertFalse(user.isActif()); + } + + @Test + void testIsExpire_true() { + UserDTO user = new UserDTO(); + user.setDateExpiration(LocalDateTime.now().minusDays(1)); + assertTrue(user.isExpire()); + } + + @Test + void testIsExpire_false() { + UserDTO user = new UserDTO(); + user.setDateExpiration(LocalDateTime.now().plusDays(1)); + assertFalse(user.isExpire()); + } + + @Test + void testIsExpire_nullDate() { + UserDTO user = new UserDTO(); + user.setDateExpiration(null); + assertFalse(user.isExpire()); + } + + @Test + void testHasRequiredActions_true() { + UserDTO user = new UserDTO(); + user.setRequiredActions(Arrays.asList("UPDATE_PASSWORD", "VERIFY_EMAIL")); + assertTrue(user.hasRequiredActions()); + } + + @Test + void testHasRequiredActions_empty() { + UserDTO user = new UserDTO(); + user.setRequiredActions(Collections.emptyList()); + assertFalse(user.hasRequiredActions()); + } + + @Test + void testHasRequiredActions_null() { + UserDTO user = new UserDTO(); + user.setRequiredActions(null); + assertFalse(user.hasRequiredActions()); + } + + @Test + void testBuilderAndAllFields() { + LocalDateTime now = LocalDateTime.now(); + Map> clientRoles = new HashMap<>(); + clientRoles.put("app", Arrays.asList("user", "admin")); + Map> attributes = new HashMap<>(); + attributes.put("custom", Collections.singletonList("value")); + + List fedIds = Collections.singletonList( + UserDTO.FederatedIdentityDTO.builder() + .identityProvider("google") + .userId("google-123") + .userName("user@gmail.com") + .build()); + + UserDTO user = UserDTO.builder() + .id("uuid-123") + .dateCreation(now) + .dateModification(now) + .creeParUsername("admin") + .modifieParUsername("admin") + .version(1L) + .username("jdupont") + .email("jean.dupont@lions.dev") + .emailVerified(true) + .prenom("Jean") + .nom("Dupont") + .statut(StatutUser.ACTIF) + .enabled(true) + .telephone("+225 07 12 34 56 78") + .organisation("Lions Dev") + .departement("IT") + .fonction("Developer") + .pays("Côte d'Ivoire") + .ville("Abidjan") + .langue("fr") + .timezone("Africa/Abidjan") + .realmName("btpxpress") + .realmRoles(Arrays.asList("user", "admin")) + .clientRoles(clientRoles) + .groups(Arrays.asList("group1", "group2")) + .derniereConnexion(now) + .dateExpiration(now.plusYears(1)) + .dateVerrouillage(null) + .attributes(attributes) + .requiredActions(Collections.singletonList("UPDATE_PASSWORD")) + .federatedIdentityProvider("google") + .federatedIdentities(fedIds) + .temporaryPassword("temp123") + .temporaryPasswordFlag(true) + .activeSessions(2) + .failedLoginAttempts(0) + .raisonModification("Update") + .commentaires("Test user") + .build(); + + assertEquals("uuid-123", user.getId()); + assertNotNull(user.getDateCreation()); + assertNotNull(user.getDateModification()); + assertEquals("admin", user.getCreeParUsername()); + assertEquals("admin", user.getModifieParUsername()); + assertEquals(1L, user.getVersion()); + assertEquals("jdupont", user.getUsername()); + assertEquals("jean.dupont@lions.dev", user.getEmail()); + assertTrue(user.getEmailVerified()); + assertEquals("Jean", user.getPrenom()); + assertEquals("Dupont", user.getNom()); + assertEquals(StatutUser.ACTIF, user.getStatut()); + assertTrue(user.getEnabled()); + assertEquals("+225 07 12 34 56 78", user.getTelephone()); + assertEquals("Lions Dev", user.getOrganisation()); + assertEquals("IT", user.getDepartement()); + assertEquals("Developer", user.getFonction()); + assertEquals("Côte d'Ivoire", user.getPays()); + assertEquals("Abidjan", user.getVille()); + assertEquals("fr", user.getLangue()); + assertEquals("Africa/Abidjan", user.getTimezone()); + assertEquals("btpxpress", user.getRealmName()); + assertEquals(2, user.getRealmRoles().size()); + assertEquals(1, user.getClientRoles().size()); + assertEquals(2, user.getGroups().size()); + assertNotNull(user.getDerniereConnexion()); + assertNotNull(user.getDateExpiration()); + assertNull(user.getDateVerrouillage()); + assertEquals(1, user.getAttributes().size()); + assertEquals(1, user.getRequiredActions().size()); + assertEquals("google", user.getFederatedIdentityProvider()); + assertEquals(1, user.getFederatedIdentities().size()); + assertEquals("temp123", user.getTemporaryPassword()); + assertTrue(user.getTemporaryPasswordFlag()); + assertEquals(2, user.getActiveSessions()); + assertEquals(0, user.getFailedLoginAttempts()); + assertEquals("Update", user.getRaisonModification()); + assertEquals("Test user", user.getCommentaires()); + } + + @Test + void testEqualsAndHashCode() { + UserDTO user1 = UserDTO.builder().id("uuid-123").username("jdupont").build(); + UserDTO user2 = UserDTO.builder().id("uuid-123").username("jdupont").build(); + UserDTO user3 = UserDTO.builder().id("uuid-456").username("other").build(); + + assertEquals(user1, user2); + assertEquals(user1.hashCode(), user2.hashCode()); + assertNotEquals(user1, user3); + } + + @Test + void testToString() { + UserDTO user = UserDTO.builder().username("jdupont").email("test@test.com").build(); + String str = user.toString(); + assertNotNull(str); + assertTrue(str.contains("jdupont")); + assertTrue(str.contains("test@test.com")); + } + + @Test + void testFederatedIdentityDTO() { + UserDTO.FederatedIdentityDTO fed = new UserDTO.FederatedIdentityDTO(); + fed.setIdentityProvider("google"); + fed.setUserId("user-123"); + fed.setUserName("user@gmail.com"); + + assertEquals("google", fed.getIdentityProvider()); + assertEquals("user-123", fed.getUserId()); + assertEquals("user@gmail.com", fed.getUserName()); + + // Test equals/hashCode/toString + UserDTO.FederatedIdentityDTO fed2 = UserDTO.FederatedIdentityDTO.builder() + .identityProvider("google") + .userId("user-123") + .userName("user@gmail.com") + .build(); + assertEquals(fed, fed2); + assertEquals(fed.hashCode(), fed2.hashCode()); + assertNotNull(fed.toString()); + } + + @Test + void testFederatedIdentityDTO_AllArgsConstructor() { + UserDTO.FederatedIdentityDTO fed = new UserDTO.FederatedIdentityDTO("google", "user-123", "user@gmail.com"); + assertEquals("google", fed.getIdentityProvider()); + assertEquals("user-123", fed.getUserId()); + assertEquals("user@gmail.com", fed.getUserName()); + } + + @Test + void testNoArgsConstructor() { + UserDTO user = new UserDTO(); + assertNull(user.getUsername()); + assertNull(user.getEmail()); + } + + @Test + void testAllArgsConstructor() { + LocalDateTime now = LocalDateTime.now(); + Map> clientRoles = new HashMap<>(); + Map> attributes = new HashMap<>(); + List fedIds = Collections.emptyList(); + List roles = Collections.emptyList(); + List groups = Collections.emptyList(); + List actions = Collections.emptyList(); + + UserDTO user = new UserDTO( + "username", "email@test.com", true, "Jean", "Dupont", + StatutUser.ACTIF, true, "phone", "org", "dept", "func", + "pays", "ville", "fr", "UTC", "realm", roles, clientRoles, + groups, now, now, now, attributes, actions, "google", fedIds, + "temppass", true, 1, 0, "reason", "comments"); + + assertEquals("username", user.getUsername()); + assertEquals("email@test.com", user.getEmail()); + assertTrue(user.getEmailVerified()); + assertEquals("Jean", user.getPrenom()); + assertEquals("Dupont", user.getNom()); + assertEquals(StatutUser.ACTIF, user.getStatut()); + assertTrue(user.getEnabled()); + } +} diff --git a/src/test/java/dev/lions/user/manager/dto/user/UserSearchCriteriaDTOTest.java b/src/test/java/dev/lions/user/manager/dto/user/UserSearchCriteriaDTOTest.java index de5253b..c202dfb 100644 --- a/src/test/java/dev/lions/user/manager/dto/user/UserSearchCriteriaDTOTest.java +++ b/src/test/java/dev/lions/user/manager/dto/user/UserSearchCriteriaDTOTest.java @@ -1,145 +1,145 @@ -package dev.lions.user.manager.dto.user; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - -/** - * Tests unitaires pour UserSearchCriteriaDTO - */ -class UserSearchCriteriaDTOTest { - - @Test - void testBuilder() { - UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder() - .realmName("test-realm") - .username("testuser") - .email("test@example.com") - .enabled(true) - .page(0) - .pageSize(20) - .build(); - - assertNotNull(criteria); - assertEquals("test-realm", criteria.getRealmName()); - assertEquals("testuser", criteria.getUsername()); - assertEquals("test@example.com", criteria.getEmail()); - assertTrue(criteria.getEnabled()); - assertEquals(0, criteria.getPage()); - assertEquals(20, criteria.getPageSize()); - } - - @Test - void testNoArgsConstructor() { - UserSearchCriteriaDTO criteria = new UserSearchCriteriaDTO(); - - assertNotNull(criteria); - assertNull(criteria.getRealmName()); - assertNull(criteria.getUsername()); - assertNull(criteria.getEmail()); - assertNull(criteria.getEnabled()); - } - - @Test - void testAllArgsConstructor() { - // Le constructeur AllArgsConstructor nécessite tous les champs - // On utilise plutôt le builder pour ce test - UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder() - .realmName("test-realm") - .username("testuser") - .email("test@example.com") - .enabled(true) - .page(0) - .pageSize(20) - .build(); - - assertNotNull(criteria); - assertEquals("test-realm", criteria.getRealmName()); - assertEquals("testuser", criteria.getUsername()); - assertEquals("test@example.com", criteria.getEmail()); - assertTrue(criteria.getEnabled()); - assertEquals(0, criteria.getPage()); - assertEquals(20, criteria.getPageSize()); - } - - @Test - void testSettersAndGetters() { - UserSearchCriteriaDTO criteria = new UserSearchCriteriaDTO(); - - criteria.setRealmName("realm1"); - criteria.setUsername("user1"); - criteria.setEmail("user1@example.com"); - criteria.setEnabled(false); - criteria.setPage(1); - criteria.setPageSize(10); - - assertEquals("realm1", criteria.getRealmName()); - assertEquals("user1", criteria.getUsername()); - assertEquals("user1@example.com", criteria.getEmail()); - assertFalse(criteria.getEnabled()); - assertEquals(1, criteria.getPage()); - assertEquals(10, criteria.getPageSize()); - } - - @Test - void testEqualsAndHashCode() { - UserSearchCriteriaDTO criteria1 = UserSearchCriteriaDTO.builder() - .realmName("test-realm") - .username("testuser") - .build(); - - UserSearchCriteriaDTO criteria2 = UserSearchCriteriaDTO.builder() - .realmName("test-realm") - .username("testuser") - .build(); - - assertEquals(criteria1, criteria2); - assertEquals(criteria1.hashCode(), criteria2.hashCode()); - } - - @Test - void testToString() { - UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder() - .realmName("test-realm") - .username("testuser") - .build(); - - String toString = criteria.toString(); - assertNotNull(toString); - assertTrue(toString.contains("test-realm") || toString.contains("testuser")); - } - - @Test - void testHasFilters_WithFilters() { - UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder() - .username("testuser") - .enabled(true) - .build(); - - assertTrue(criteria.hasFilters()); - } - - @Test - void testHasFilters_NoFilters() { - UserSearchCriteriaDTO criteria = new UserSearchCriteriaDTO(); - - assertFalse(criteria.hasFilters()); - } - - @Test - void testGetOffset() { - UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder() - .page(2) - .pageSize(20) - .build(); - - assertEquals(40, criteria.getOffset()); - } - - @Test - void testGetOffset_Default() { - UserSearchCriteriaDTO criteria = new UserSearchCriteriaDTO(); - - assertEquals(0, criteria.getOffset()); - } -} +package dev.lions.user.manager.dto.user; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Tests unitaires pour UserSearchCriteriaDTO + */ +class UserSearchCriteriaDTOTest { + + @Test + void testBuilder() { + UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder() + .realmName("test-realm") + .username("testuser") + .email("test@example.com") + .enabled(true) + .page(0) + .pageSize(20) + .build(); + + assertNotNull(criteria); + assertEquals("test-realm", criteria.getRealmName()); + assertEquals("testuser", criteria.getUsername()); + assertEquals("test@example.com", criteria.getEmail()); + assertTrue(criteria.getEnabled()); + assertEquals(0, criteria.getPage()); + assertEquals(20, criteria.getPageSize()); + } + + @Test + void testNoArgsConstructor() { + UserSearchCriteriaDTO criteria = new UserSearchCriteriaDTO(); + + assertNotNull(criteria); + assertNull(criteria.getRealmName()); + assertNull(criteria.getUsername()); + assertNull(criteria.getEmail()); + assertNull(criteria.getEnabled()); + } + + @Test + void testAllArgsConstructor() { + // Le constructeur AllArgsConstructor nécessite tous les champs + // On utilise plutôt le builder pour ce test + UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder() + .realmName("test-realm") + .username("testuser") + .email("test@example.com") + .enabled(true) + .page(0) + .pageSize(20) + .build(); + + assertNotNull(criteria); + assertEquals("test-realm", criteria.getRealmName()); + assertEquals("testuser", criteria.getUsername()); + assertEquals("test@example.com", criteria.getEmail()); + assertTrue(criteria.getEnabled()); + assertEquals(0, criteria.getPage()); + assertEquals(20, criteria.getPageSize()); + } + + @Test + void testSettersAndGetters() { + UserSearchCriteriaDTO criteria = new UserSearchCriteriaDTO(); + + criteria.setRealmName("realm1"); + criteria.setUsername("user1"); + criteria.setEmail("user1@example.com"); + criteria.setEnabled(false); + criteria.setPage(1); + criteria.setPageSize(10); + + assertEquals("realm1", criteria.getRealmName()); + assertEquals("user1", criteria.getUsername()); + assertEquals("user1@example.com", criteria.getEmail()); + assertFalse(criteria.getEnabled()); + assertEquals(1, criteria.getPage()); + assertEquals(10, criteria.getPageSize()); + } + + @Test + void testEqualsAndHashCode() { + UserSearchCriteriaDTO criteria1 = UserSearchCriteriaDTO.builder() + .realmName("test-realm") + .username("testuser") + .build(); + + UserSearchCriteriaDTO criteria2 = UserSearchCriteriaDTO.builder() + .realmName("test-realm") + .username("testuser") + .build(); + + assertEquals(criteria1, criteria2); + assertEquals(criteria1.hashCode(), criteria2.hashCode()); + } + + @Test + void testToString() { + UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder() + .realmName("test-realm") + .username("testuser") + .build(); + + String toString = criteria.toString(); + assertNotNull(toString); + assertTrue(toString.contains("test-realm") || toString.contains("testuser")); + } + + @Test + void testHasFilters_WithFilters() { + UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder() + .username("testuser") + .enabled(true) + .build(); + + assertTrue(criteria.hasFilters()); + } + + @Test + void testHasFilters_NoFilters() { + UserSearchCriteriaDTO criteria = new UserSearchCriteriaDTO(); + + assertFalse(criteria.hasFilters()); + } + + @Test + void testGetOffset() { + UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder() + .page(2) + .pageSize(20) + .build(); + + assertEquals(40, criteria.getOffset()); + } + + @Test + void testGetOffset_Default() { + UserSearchCriteriaDTO criteria = new UserSearchCriteriaDTO(); + + assertEquals(0, criteria.getOffset()); + } +} diff --git a/src/test/java/dev/lions/user/manager/dto/user/UserSearchResultDTOTest.java b/src/test/java/dev/lions/user/manager/dto/user/UserSearchResultDTOTest.java index b68480c..2fb9c6a 100644 --- a/src/test/java/dev/lions/user/manager/dto/user/UserSearchResultDTOTest.java +++ b/src/test/java/dev/lions/user/manager/dto/user/UserSearchResultDTOTest.java @@ -1,279 +1,279 @@ -package dev.lions.user.manager.dto.user; - -import org.junit.jupiter.api.Test; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.*; - -class UserSearchResultDTOTest { - - @Test - void testOf_firstPage() { - List users = Arrays.asList( - UserDTO.builder().username("user1").build(), - UserDTO.builder().username("user2").build()); - UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder() - .page(0) - .pageSize(10) - .build(); - - UserSearchResultDTO result = UserSearchResultDTO.of(users, criteria, 25L); - - assertEquals(2, result.getUsers().size()); - assertEquals(25L, result.getTotalCount()); - assertEquals(0, result.getCurrentPage()); - assertEquals(10, result.getPageSize()); - assertEquals(3, result.getTotalPages()); - assertTrue(result.getHasNextPage()); - assertFalse(result.getHasPreviousPage()); - assertEquals(0, result.getFirstElement()); - assertEquals(9, result.getLastElement()); - assertFalse(result.getIsEmpty()); - assertTrue(result.getIsFirstPage()); - assertFalse(result.getIsLastPage()); - assertEquals(criteria, result.getCriteria()); - } - - @Test - void testOf_middlePage() { - List users = Arrays.asList( - UserDTO.builder().username("user1").build()); - UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder() - .page(1) - .pageSize(10) - .build(); - - UserSearchResultDTO result = UserSearchResultDTO.of(users, criteria, 25L); - - assertEquals(1, result.getCurrentPage()); - assertTrue(result.getHasNextPage()); - assertTrue(result.getHasPreviousPage()); - assertFalse(result.getIsFirstPage()); - assertFalse(result.getIsLastPage()); - } - - @Test - void testOf_lastPage() { - List users = Arrays.asList( - UserDTO.builder().username("user1").build()); - UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder() - .page(2) - .pageSize(10) - .build(); - - UserSearchResultDTO result = UserSearchResultDTO.of(users, criteria, 25L); - - assertEquals(2, result.getCurrentPage()); - assertFalse(result.getHasNextPage()); - assertTrue(result.getHasPreviousPage()); - assertFalse(result.getIsFirstPage()); - assertTrue(result.getIsLastPage()); - } - - @Test - void testOf_emptyList() { - List users = Collections.emptyList(); - UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder() - .page(0) - .pageSize(20) - .build(); - - UserSearchResultDTO result = UserSearchResultDTO.of(users, criteria, 0L); - - assertTrue(result.getIsEmpty()); - assertEquals(0, result.getTotalCount()); - assertEquals(0, result.getTotalPages()); - } - - @Test - void testOf_nullList() { - UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder() - .page(0) - .pageSize(20) - .build(); - - UserSearchResultDTO result = UserSearchResultDTO.of(null, criteria, 0L); - - assertTrue(result.getIsEmpty()); - } - - @Test - void testOf_singlePage() { - List users = Arrays.asList( - UserDTO.builder().username("user1").build()); - UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder() - .page(0) - .pageSize(10) - .build(); - - UserSearchResultDTO result = UserSearchResultDTO.of(users, criteria, 5L); - - assertEquals(1, result.getTotalPages()); - assertFalse(result.getHasNextPage()); - assertFalse(result.getHasPreviousPage()); - assertTrue(result.getIsFirstPage()); - assertTrue(result.getIsLastPage()); - } - - @Test - void testGetCurrentPageSize_withUsers() { - UserSearchResultDTO result = UserSearchResultDTO.builder() - .users(Arrays.asList( - UserDTO.builder().username("u1").build(), - UserDTO.builder().username("u2").build(), - UserDTO.builder().username("u3").build())) - .build(); - - assertEquals(3, result.getCurrentPageSize()); - } - - @Test - void testGetCurrentPageSize_emptyUsers() { - UserSearchResultDTO result = UserSearchResultDTO.builder() - .users(Collections.emptyList()) - .build(); - - assertEquals(0, result.getCurrentPageSize()); - } - - @Test - void testGetCurrentPageSize_nullUsers() { - UserSearchResultDTO result = UserSearchResultDTO.builder() - .users(null) - .build(); - - assertEquals(0, result.getCurrentPageSize()); - } - - @Test - void testBuilderAndAllFields() { - List users = Collections.singletonList(UserDTO.builder().username("test").build()); - UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder().page(0).pageSize(20).build(); - - UserSearchResultDTO result = UserSearchResultDTO.builder() - .users(users) - .totalCount(100L) - .currentPage(0) - .pageSize(20) - .totalPages(5) - .hasNextPage(true) - .hasPreviousPage(false) - .firstElement(0) - .lastElement(19) - .isEmpty(false) - .isFirstPage(true) - .isLastPage(false) - .criteria(criteria) - .executionTimeMs(150L) - .build(); - - assertEquals(users, result.getUsers()); - assertEquals(100L, result.getTotalCount()); - assertEquals(0, result.getCurrentPage()); - assertEquals(20, result.getPageSize()); - assertEquals(5, result.getTotalPages()); - assertTrue(result.getHasNextPage()); - assertFalse(result.getHasPreviousPage()); - assertEquals(0, result.getFirstElement()); - assertEquals(19, result.getLastElement()); - assertFalse(result.getIsEmpty()); - assertTrue(result.getIsFirstPage()); - assertFalse(result.getIsLastPage()); - assertEquals(criteria, result.getCriteria()); - assertEquals(150L, result.getExecutionTimeMs()); - } - - @Test - void testSettersAndGetters() { - UserSearchResultDTO result = new UserSearchResultDTO(); - List users = Collections.singletonList(UserDTO.builder().username("test").build()); - UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder().build(); - - result.setUsers(users); - result.setTotalCount(50L); - result.setCurrentPage(1); - result.setPageSize(10); - result.setTotalPages(5); - result.setHasNextPage(true); - result.setHasPreviousPage(true); - result.setFirstElement(10); - result.setLastElement(19); - result.setIsEmpty(false); - result.setIsFirstPage(false); - result.setIsLastPage(false); - result.setCriteria(criteria); - result.setExecutionTimeMs(200L); - - assertEquals(users, result.getUsers()); - assertEquals(50L, result.getTotalCount()); - assertEquals(1, result.getCurrentPage()); - assertEquals(10, result.getPageSize()); - assertEquals(5, result.getTotalPages()); - assertTrue(result.getHasNextPage()); - assertTrue(result.getHasPreviousPage()); - assertEquals(10, result.getFirstElement()); - assertEquals(19, result.getLastElement()); - assertFalse(result.getIsEmpty()); - assertFalse(result.getIsFirstPage()); - assertFalse(result.getIsLastPage()); - assertEquals(criteria, result.getCriteria()); - assertEquals(200L, result.getExecutionTimeMs()); - } - - @Test - void testEqualsAndHashCode() { - UserSearchResultDTO dto1 = UserSearchResultDTO.builder().totalCount(10L).currentPage(0).build(); - UserSearchResultDTO dto2 = UserSearchResultDTO.builder().totalCount(10L).currentPage(0).build(); - UserSearchResultDTO dto3 = UserSearchResultDTO.builder().totalCount(20L).currentPage(1).build(); - - assertEquals(dto1, dto2); - assertEquals(dto1.hashCode(), dto2.hashCode()); - assertNotEquals(dto1, dto3); - } - - @Test - void testToString() { - UserSearchResultDTO result = UserSearchResultDTO.builder() - .totalCount(100L) - .currentPage(0) - .build(); - String str = result.toString(); - assertNotNull(str); - assertTrue(str.contains("100")); - } - - @Test - void testNoArgsConstructor() { - UserSearchResultDTO result = new UserSearchResultDTO(); - assertNull(result.getUsers()); - assertNull(result.getTotalCount()); - assertNull(result.getCurrentPage()); - } - - @Test - void testAllArgsConstructor() { - List users = Collections.singletonList(UserDTO.builder().username("test").build()); - UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder().build(); - - UserSearchResultDTO result = new UserSearchResultDTO( - users, 100L, 0, 20, 5, true, false, 0, 19, false, true, false, criteria, 150L); - - assertEquals(users, result.getUsers()); - assertEquals(100L, result.getTotalCount()); - assertEquals(0, result.getCurrentPage()); - assertEquals(20, result.getPageSize()); - assertEquals(5, result.getTotalPages()); - assertTrue(result.getHasNextPage()); - assertFalse(result.getHasPreviousPage()); - assertEquals(0, result.getFirstElement()); - assertEquals(19, result.getLastElement()); - assertFalse(result.getIsEmpty()); - assertTrue(result.getIsFirstPage()); - assertFalse(result.getIsLastPage()); - assertEquals(criteria, result.getCriteria()); - assertEquals(150L, result.getExecutionTimeMs()); - } -} +package dev.lions.user.manager.dto.user; + +import org.junit.jupiter.api.Test; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +class UserSearchResultDTOTest { + + @Test + void testOf_firstPage() { + List users = Arrays.asList( + UserDTO.builder().username("user1").build(), + UserDTO.builder().username("user2").build()); + UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder() + .page(0) + .pageSize(10) + .build(); + + UserSearchResultDTO result = UserSearchResultDTO.of(users, criteria, 25L); + + assertEquals(2, result.getUsers().size()); + assertEquals(25L, result.getTotalCount()); + assertEquals(0, result.getCurrentPage()); + assertEquals(10, result.getPageSize()); + assertEquals(3, result.getTotalPages()); + assertTrue(result.getHasNextPage()); + assertFalse(result.getHasPreviousPage()); + assertEquals(0, result.getFirstElement()); + assertEquals(9, result.getLastElement()); + assertFalse(result.getIsEmpty()); + assertTrue(result.getIsFirstPage()); + assertFalse(result.getIsLastPage()); + assertEquals(criteria, result.getCriteria()); + } + + @Test + void testOf_middlePage() { + List users = Arrays.asList( + UserDTO.builder().username("user1").build()); + UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder() + .page(1) + .pageSize(10) + .build(); + + UserSearchResultDTO result = UserSearchResultDTO.of(users, criteria, 25L); + + assertEquals(1, result.getCurrentPage()); + assertTrue(result.getHasNextPage()); + assertTrue(result.getHasPreviousPage()); + assertFalse(result.getIsFirstPage()); + assertFalse(result.getIsLastPage()); + } + + @Test + void testOf_lastPage() { + List users = Arrays.asList( + UserDTO.builder().username("user1").build()); + UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder() + .page(2) + .pageSize(10) + .build(); + + UserSearchResultDTO result = UserSearchResultDTO.of(users, criteria, 25L); + + assertEquals(2, result.getCurrentPage()); + assertFalse(result.getHasNextPage()); + assertTrue(result.getHasPreviousPage()); + assertFalse(result.getIsFirstPage()); + assertTrue(result.getIsLastPage()); + } + + @Test + void testOf_emptyList() { + List users = Collections.emptyList(); + UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder() + .page(0) + .pageSize(20) + .build(); + + UserSearchResultDTO result = UserSearchResultDTO.of(users, criteria, 0L); + + assertTrue(result.getIsEmpty()); + assertEquals(0, result.getTotalCount()); + assertEquals(0, result.getTotalPages()); + } + + @Test + void testOf_nullList() { + UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder() + .page(0) + .pageSize(20) + .build(); + + UserSearchResultDTO result = UserSearchResultDTO.of(null, criteria, 0L); + + assertTrue(result.getIsEmpty()); + } + + @Test + void testOf_singlePage() { + List users = Arrays.asList( + UserDTO.builder().username("user1").build()); + UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder() + .page(0) + .pageSize(10) + .build(); + + UserSearchResultDTO result = UserSearchResultDTO.of(users, criteria, 5L); + + assertEquals(1, result.getTotalPages()); + assertFalse(result.getHasNextPage()); + assertFalse(result.getHasPreviousPage()); + assertTrue(result.getIsFirstPage()); + assertTrue(result.getIsLastPage()); + } + + @Test + void testGetCurrentPageSize_withUsers() { + UserSearchResultDTO result = UserSearchResultDTO.builder() + .users(Arrays.asList( + UserDTO.builder().username("u1").build(), + UserDTO.builder().username("u2").build(), + UserDTO.builder().username("u3").build())) + .build(); + + assertEquals(3, result.getCurrentPageSize()); + } + + @Test + void testGetCurrentPageSize_emptyUsers() { + UserSearchResultDTO result = UserSearchResultDTO.builder() + .users(Collections.emptyList()) + .build(); + + assertEquals(0, result.getCurrentPageSize()); + } + + @Test + void testGetCurrentPageSize_nullUsers() { + UserSearchResultDTO result = UserSearchResultDTO.builder() + .users(null) + .build(); + + assertEquals(0, result.getCurrentPageSize()); + } + + @Test + void testBuilderAndAllFields() { + List users = Collections.singletonList(UserDTO.builder().username("test").build()); + UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder().page(0).pageSize(20).build(); + + UserSearchResultDTO result = UserSearchResultDTO.builder() + .users(users) + .totalCount(100L) + .currentPage(0) + .pageSize(20) + .totalPages(5) + .hasNextPage(true) + .hasPreviousPage(false) + .firstElement(0) + .lastElement(19) + .isEmpty(false) + .isFirstPage(true) + .isLastPage(false) + .criteria(criteria) + .executionTimeMs(150L) + .build(); + + assertEquals(users, result.getUsers()); + assertEquals(100L, result.getTotalCount()); + assertEquals(0, result.getCurrentPage()); + assertEquals(20, result.getPageSize()); + assertEquals(5, result.getTotalPages()); + assertTrue(result.getHasNextPage()); + assertFalse(result.getHasPreviousPage()); + assertEquals(0, result.getFirstElement()); + assertEquals(19, result.getLastElement()); + assertFalse(result.getIsEmpty()); + assertTrue(result.getIsFirstPage()); + assertFalse(result.getIsLastPage()); + assertEquals(criteria, result.getCriteria()); + assertEquals(150L, result.getExecutionTimeMs()); + } + + @Test + void testSettersAndGetters() { + UserSearchResultDTO result = new UserSearchResultDTO(); + List users = Collections.singletonList(UserDTO.builder().username("test").build()); + UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder().build(); + + result.setUsers(users); + result.setTotalCount(50L); + result.setCurrentPage(1); + result.setPageSize(10); + result.setTotalPages(5); + result.setHasNextPage(true); + result.setHasPreviousPage(true); + result.setFirstElement(10); + result.setLastElement(19); + result.setIsEmpty(false); + result.setIsFirstPage(false); + result.setIsLastPage(false); + result.setCriteria(criteria); + result.setExecutionTimeMs(200L); + + assertEquals(users, result.getUsers()); + assertEquals(50L, result.getTotalCount()); + assertEquals(1, result.getCurrentPage()); + assertEquals(10, result.getPageSize()); + assertEquals(5, result.getTotalPages()); + assertTrue(result.getHasNextPage()); + assertTrue(result.getHasPreviousPage()); + assertEquals(10, result.getFirstElement()); + assertEquals(19, result.getLastElement()); + assertFalse(result.getIsEmpty()); + assertFalse(result.getIsFirstPage()); + assertFalse(result.getIsLastPage()); + assertEquals(criteria, result.getCriteria()); + assertEquals(200L, result.getExecutionTimeMs()); + } + + @Test + void testEqualsAndHashCode() { + UserSearchResultDTO dto1 = UserSearchResultDTO.builder().totalCount(10L).currentPage(0).build(); + UserSearchResultDTO dto2 = UserSearchResultDTO.builder().totalCount(10L).currentPage(0).build(); + UserSearchResultDTO dto3 = UserSearchResultDTO.builder().totalCount(20L).currentPage(1).build(); + + assertEquals(dto1, dto2); + assertEquals(dto1.hashCode(), dto2.hashCode()); + assertNotEquals(dto1, dto3); + } + + @Test + void testToString() { + UserSearchResultDTO result = UserSearchResultDTO.builder() + .totalCount(100L) + .currentPage(0) + .build(); + String str = result.toString(); + assertNotNull(str); + assertTrue(str.contains("100")); + } + + @Test + void testNoArgsConstructor() { + UserSearchResultDTO result = new UserSearchResultDTO(); + assertNull(result.getUsers()); + assertNull(result.getTotalCount()); + assertNull(result.getCurrentPage()); + } + + @Test + void testAllArgsConstructor() { + List users = Collections.singletonList(UserDTO.builder().username("test").build()); + UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder().build(); + + UserSearchResultDTO result = new UserSearchResultDTO( + users, 100L, 0, 20, 5, true, false, 0, 19, false, true, false, criteria, 150L); + + assertEquals(users, result.getUsers()); + assertEquals(100L, result.getTotalCount()); + assertEquals(0, result.getCurrentPage()); + assertEquals(20, result.getPageSize()); + assertEquals(5, result.getTotalPages()); + assertTrue(result.getHasNextPage()); + assertFalse(result.getHasPreviousPage()); + assertEquals(0, result.getFirstElement()); + assertEquals(19, result.getLastElement()); + assertFalse(result.getIsEmpty()); + assertTrue(result.getIsFirstPage()); + assertFalse(result.getIsLastPage()); + assertEquals(criteria, result.getCriteria()); + assertEquals(150L, result.getExecutionTimeMs()); + } +} diff --git a/src/test/java/dev/lions/user/manager/enums/audit/TypeActionAuditTest.java b/src/test/java/dev/lions/user/manager/enums/audit/TypeActionAuditTest.java index ea615b2..020bc26 100644 --- a/src/test/java/dev/lions/user/manager/enums/audit/TypeActionAuditTest.java +++ b/src/test/java/dev/lions/user/manager/enums/audit/TypeActionAuditTest.java @@ -1,59 +1,59 @@ -package dev.lions.user.manager.enums.audit; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - -/** - * Tests unitaires pour TypeActionAudit - */ -class TypeActionAuditTest { - - @Test - void testValues() { - TypeActionAudit[] values = TypeActionAudit.values(); - - assertNotNull(values); - assertTrue(values.length > 0); - } - - @Test - void testValueOf() { - TypeActionAudit userCreate = TypeActionAudit.valueOf("USER_CREATE"); - TypeActionAudit userUpdate = TypeActionAudit.valueOf("USER_UPDATE"); - TypeActionAudit userDelete = TypeActionAudit.valueOf("USER_DELETE"); - TypeActionAudit roleCreate = TypeActionAudit.valueOf("ROLE_CREATE"); - TypeActionAudit roleUpdate = TypeActionAudit.valueOf("ROLE_UPDATE"); - TypeActionAudit roleDelete = TypeActionAudit.valueOf("ROLE_DELETE"); - TypeActionAudit roleAssign = TypeActionAudit.valueOf("ROLE_ASSIGN"); - TypeActionAudit roleRevoke = TypeActionAudit.valueOf("ROLE_REVOKE"); - - assertEquals(TypeActionAudit.USER_CREATE, userCreate); - assertEquals(TypeActionAudit.USER_UPDATE, userUpdate); - assertEquals(TypeActionAudit.USER_DELETE, userDelete); - assertEquals(TypeActionAudit.ROLE_CREATE, roleCreate); - assertEquals(TypeActionAudit.ROLE_UPDATE, roleUpdate); - assertEquals(TypeActionAudit.ROLE_DELETE, roleDelete); - assertEquals(TypeActionAudit.ROLE_ASSIGN, roleAssign); - assertEquals(TypeActionAudit.ROLE_REVOKE, roleRevoke); - } - - @Test - void testValueOf_Invalid() { - assertThrows(IllegalArgumentException.class, () -> { - TypeActionAudit.valueOf("INVALID"); - }); - } - - @Test - void testEnumValues() { - assertNotNull(TypeActionAudit.USER_CREATE); - assertNotNull(TypeActionAudit.USER_UPDATE); - assertNotNull(TypeActionAudit.USER_DELETE); - assertNotNull(TypeActionAudit.ROLE_CREATE); - assertNotNull(TypeActionAudit.ROLE_UPDATE); - assertNotNull(TypeActionAudit.ROLE_DELETE); - assertNotNull(TypeActionAudit.ROLE_ASSIGN); - assertNotNull(TypeActionAudit.ROLE_REVOKE); - } -} +package dev.lions.user.manager.enums.audit; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Tests unitaires pour TypeActionAudit + */ +class TypeActionAuditTest { + + @Test + void testValues() { + TypeActionAudit[] values = TypeActionAudit.values(); + + assertNotNull(values); + assertTrue(values.length > 0); + } + + @Test + void testValueOf() { + TypeActionAudit userCreate = TypeActionAudit.valueOf("USER_CREATE"); + TypeActionAudit userUpdate = TypeActionAudit.valueOf("USER_UPDATE"); + TypeActionAudit userDelete = TypeActionAudit.valueOf("USER_DELETE"); + TypeActionAudit roleCreate = TypeActionAudit.valueOf("ROLE_CREATE"); + TypeActionAudit roleUpdate = TypeActionAudit.valueOf("ROLE_UPDATE"); + TypeActionAudit roleDelete = TypeActionAudit.valueOf("ROLE_DELETE"); + TypeActionAudit roleAssign = TypeActionAudit.valueOf("ROLE_ASSIGN"); + TypeActionAudit roleRevoke = TypeActionAudit.valueOf("ROLE_REVOKE"); + + assertEquals(TypeActionAudit.USER_CREATE, userCreate); + assertEquals(TypeActionAudit.USER_UPDATE, userUpdate); + assertEquals(TypeActionAudit.USER_DELETE, userDelete); + assertEquals(TypeActionAudit.ROLE_CREATE, roleCreate); + assertEquals(TypeActionAudit.ROLE_UPDATE, roleUpdate); + assertEquals(TypeActionAudit.ROLE_DELETE, roleDelete); + assertEquals(TypeActionAudit.ROLE_ASSIGN, roleAssign); + assertEquals(TypeActionAudit.ROLE_REVOKE, roleRevoke); + } + + @Test + void testValueOf_Invalid() { + assertThrows(IllegalArgumentException.class, () -> { + TypeActionAudit.valueOf("INVALID"); + }); + } + + @Test + void testEnumValues() { + assertNotNull(TypeActionAudit.USER_CREATE); + assertNotNull(TypeActionAudit.USER_UPDATE); + assertNotNull(TypeActionAudit.USER_DELETE); + assertNotNull(TypeActionAudit.ROLE_CREATE); + assertNotNull(TypeActionAudit.ROLE_UPDATE); + assertNotNull(TypeActionAudit.ROLE_DELETE); + assertNotNull(TypeActionAudit.ROLE_ASSIGN); + assertNotNull(TypeActionAudit.ROLE_REVOKE); + } +} diff --git a/src/test/java/dev/lions/user/manager/enums/role/TypeRoleTest.java b/src/test/java/dev/lions/user/manager/enums/role/TypeRoleTest.java index 706497f..5ca7b9d 100644 --- a/src/test/java/dev/lions/user/manager/enums/role/TypeRoleTest.java +++ b/src/test/java/dev/lions/user/manager/enums/role/TypeRoleTest.java @@ -1,41 +1,41 @@ -package dev.lions.user.manager.enums.role; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - -/** - * Tests unitaires pour TypeRole - */ -class TypeRoleTest { - - @Test - void testValues() { - TypeRole[] values = TypeRole.values(); - - assertNotNull(values); - assertTrue(values.length > 0); - } - - @Test - void testValueOf() { - TypeRole realmRole = TypeRole.valueOf("REALM_ROLE"); - TypeRole clientRole = TypeRole.valueOf("CLIENT_ROLE"); - - assertEquals(TypeRole.REALM_ROLE, realmRole); - assertEquals(TypeRole.CLIENT_ROLE, clientRole); - } - - @Test - void testValueOf_Invalid() { - assertThrows(IllegalArgumentException.class, () -> { - TypeRole.valueOf("INVALID"); - }); - } - - @Test - void testEnumValues() { - assertNotNull(TypeRole.REALM_ROLE); - assertNotNull(TypeRole.CLIENT_ROLE); - } -} +package dev.lions.user.manager.enums.role; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Tests unitaires pour TypeRole + */ +class TypeRoleTest { + + @Test + void testValues() { + TypeRole[] values = TypeRole.values(); + + assertNotNull(values); + assertTrue(values.length > 0); + } + + @Test + void testValueOf() { + TypeRole realmRole = TypeRole.valueOf("REALM_ROLE"); + TypeRole clientRole = TypeRole.valueOf("CLIENT_ROLE"); + + assertEquals(TypeRole.REALM_ROLE, realmRole); + assertEquals(TypeRole.CLIENT_ROLE, clientRole); + } + + @Test + void testValueOf_Invalid() { + assertThrows(IllegalArgumentException.class, () -> { + TypeRole.valueOf("INVALID"); + }); + } + + @Test + void testEnumValues() { + assertNotNull(TypeRole.REALM_ROLE); + assertNotNull(TypeRole.CLIENT_ROLE); + } +} diff --git a/src/test/java/dev/lions/user/manager/enums/user/StatutUserTest.java b/src/test/java/dev/lions/user/manager/enums/user/StatutUserTest.java index 16e98ad..15ca4d4 100644 --- a/src/test/java/dev/lions/user/manager/enums/user/StatutUserTest.java +++ b/src/test/java/dev/lions/user/manager/enums/user/StatutUserTest.java @@ -1,44 +1,44 @@ -package dev.lions.user.manager.enums.user; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - -/** - * Tests unitaires pour StatutUser - */ -class StatutUserTest { - - @Test - void testValues() { - StatutUser[] values = StatutUser.values(); - - assertNotNull(values); - assertTrue(values.length > 0); - } - - @Test - void testValueOf() { - StatutUser actif = StatutUser.valueOf("ACTIF"); - StatutUser inactif = StatutUser.valueOf("INACTIF"); - StatutUser suspendu = StatutUser.valueOf("SUSPENDU"); - - assertEquals(StatutUser.ACTIF, actif); - assertEquals(StatutUser.INACTIF, inactif); - assertEquals(StatutUser.SUSPENDU, suspendu); - } - - @Test - void testValueOf_Invalid() { - assertThrows(IllegalArgumentException.class, () -> { - StatutUser.valueOf("INVALID"); - }); - } - - @Test - void testEnumValues() { - assertNotNull(StatutUser.ACTIF); - assertNotNull(StatutUser.INACTIF); - assertNotNull(StatutUser.SUSPENDU); - } -} +package dev.lions.user.manager.enums.user; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Tests unitaires pour StatutUser + */ +class StatutUserTest { + + @Test + void testValues() { + StatutUser[] values = StatutUser.values(); + + assertNotNull(values); + assertTrue(values.length > 0); + } + + @Test + void testValueOf() { + StatutUser actif = StatutUser.valueOf("ACTIF"); + StatutUser inactif = StatutUser.valueOf("INACTIF"); + StatutUser suspendu = StatutUser.valueOf("SUSPENDU"); + + assertEquals(StatutUser.ACTIF, actif); + assertEquals(StatutUser.INACTIF, inactif); + assertEquals(StatutUser.SUSPENDU, suspendu); + } + + @Test + void testValueOf_Invalid() { + assertThrows(IllegalArgumentException.class, () -> { + StatutUser.valueOf("INVALID"); + }); + } + + @Test + void testEnumValues() { + assertNotNull(StatutUser.ACTIF); + assertNotNull(StatutUser.INACTIF); + assertNotNull(StatutUser.SUSPENDU); + } +} diff --git a/src/test/java/dev/lions/user/manager/validation/ValidationConstantsTest.java b/src/test/java/dev/lions/user/manager/validation/ValidationConstantsTest.java index 282b798..b126bed 100644 --- a/src/test/java/dev/lions/user/manager/validation/ValidationConstantsTest.java +++ b/src/test/java/dev/lions/user/manager/validation/ValidationConstantsTest.java @@ -1,18 +1,18 @@ -package dev.lions.user.manager.validation; - -import org.junit.jupiter.api.Test; -import java.lang.reflect.Constructor; -import java.lang.reflect.Modifier; -import static org.junit.jupiter.api.Assertions.*; - -class ValidationConstantsTest { - - @Test - void testPrivateConstructor() throws Exception { - Constructor constructor = ValidationConstants.class.getDeclaredConstructor(); - assertTrue(Modifier.isPrivate(constructor.getModifiers())); - constructor.setAccessible(true); - ValidationConstants instance = constructor.newInstance(); - assertNotNull(instance); - } -} +package dev.lions.user.manager.validation; + +import org.junit.jupiter.api.Test; +import java.lang.reflect.Constructor; +import java.lang.reflect.Modifier; +import static org.junit.jupiter.api.Assertions.*; + +class ValidationConstantsTest { + + @Test + void testPrivateConstructor() throws Exception { + Constructor constructor = ValidationConstants.class.getDeclaredConstructor(); + assertTrue(Modifier.isPrivate(constructor.getModifiers())); + constructor.setAccessible(true); + ValidationConstants instance = constructor.newInstance(); + assertNotNull(instance); + } +}