chore(quarkus-327): bump to Quarkus 3.27.3 LTS, make pom autonomous, bump to 1.1.0, add maven-compiler-plugin version

This commit is contained in:
2026-04-23 14:47:04 +00:00
parent 5b33384e9f
commit e40bebd120
58 changed files with 6124 additions and 6080 deletions

228
.gitignore vendored
View File

@@ -1,114 +1,114 @@
# ==================================== # ====================================
# GITIGNORE POUR SERVER API (Maven Library) # GITIGNORE POUR SERVER API (Maven Library)
# ==================================== # ====================================
# ===== MAVEN ===== # ===== MAVEN =====
target/ target/
pom.xml.tag pom.xml.tag
pom.xml.releaseBackup pom.xml.releaseBackup
pom.xml.versionsBackup pom.xml.versionsBackup
pom.xml.next pom.xml.next
release.properties release.properties
dependency-reduced-pom.xml dependency-reduced-pom.xml
buildNumber.properties buildNumber.properties
.mvn/timing.properties .mvn/timing.properties
.mvn/wrapper/maven-wrapper.jar .mvn/wrapper/maven-wrapper.jar
.flattened-pom.xml .flattened-pom.xml
# ===== JAVA COMPILED FILES ===== # ===== JAVA COMPILED FILES =====
*.class *.class
*.jar *.jar
*.war *.war
*.ear *.ear
*.nar *.nar
*.zip *.zip
*.tar.gz *.tar.gz
*.rar *.rar
# ===== IDE - ECLIPSE ===== # ===== IDE - ECLIPSE =====
.project .project
.classpath .classpath
.settings/ .settings/
.factorypath .factorypath
.metadata/ .metadata/
bin/ bin/
.apt_generated .apt_generated
.springBeans .springBeans
.sts4-cache .sts4-cache
# ===== IDE - INTELLIJ IDEA ===== # ===== IDE - INTELLIJ IDEA =====
.idea/ .idea/
*.iml *.iml
*.ipr *.ipr
*.iws *.iws
out/ out/
# ===== IDE - NETBEANS ===== # ===== IDE - NETBEANS =====
nbproject/ nbproject/
nbbuild/ nbbuild/
nbdist/ nbdist/
.nb-gradle/ .nb-gradle/
nb-configuration.xml nb-configuration.xml
nbactions.xml nbactions.xml
# ===== IDE - VS CODE ===== # ===== IDE - VS CODE =====
.vscode/ .vscode/
*.code-workspace *.code-workspace
# ===== OS SPECIFIC ===== # ===== OS SPECIFIC =====
.DS_Store .DS_Store
Thumbs.db Thumbs.db
ehthumbs.db ehthumbs.db
Desktop.ini Desktop.ini
$RECYCLE.BIN/ $RECYCLE.BIN/
*~ *~
# ===== LOGS ===== # ===== LOGS =====
*.log *.log
*.log.* *.log.*
logs/ logs/
log/ log/
# ===== TEMPORARY FILES ===== # ===== TEMPORARY FILES =====
*.tmp *.tmp
*.temp *.temp
*.bak *.bak
*.backup *.backup
*.old *.old
*.swp *.swp
*.swo *.swo
*.orig *.orig
*.rej *.rej
# ===== ENVIRONMENT & CONFIGURATION ===== # ===== ENVIRONMENT & CONFIGURATION =====
.env .env
.env.local .env.local
.env.* .env.*
*.local *.local
application-local.properties application-local.properties
# ===== SECURITY - KEYS & CERTIFICATES ===== # ===== SECURITY - KEYS & CERTIFICATES =====
*.key *.key
*.pem *.pem
*.crt *.crt
*.p12 *.p12
*.jks *.jks
*.keystore *.keystore
.certs/ .certs/
.certificates/ .certificates/
# ===== TEST COVERAGE ===== # ===== TEST COVERAGE =====
.jacoco/ .jacoco/
jacoco.exec jacoco.exec
coverage/ coverage/
.nyc_output/ .nyc_output/
# ===== GENERATED SOURCES ===== # ===== GENERATED SOURCES =====
src/gen/ src/gen/
generated-sources/ generated-sources/
generated-test-sources/ generated-test-sources/
# ===== BUILD ARTIFACTS ===== # ===== BUILD ARTIFACTS =====
dist/ dist/
build/ build/
out/ out/

248
README.md
View File

@@ -1,124 +1,124 @@
# lions-user-manager-server-api # lions-user-manager-server-api
> Contrats partagés entre le serveur et le client — DTOs, interfaces de services, enums, validations > Contrats partagés entre le serveur et le client — DTOs, interfaces de services, enums, validations
## Rôle ## 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. 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 ## Contenu
### DTOs ### DTOs
| DTO | Description | | DTO | Description |
|-----|-------------| |-----|-------------|
| `UserDTO` | Représentation complète d'un utilisateur Keycloak | | `UserDTO` | Représentation complète d'un utilisateur Keycloak |
| `UserCreationDTO` | Données de création d'un utilisateur | | `UserCreationDTO` | Données de création d'un utilisateur |
| `UserUpdateDTO` | Données de mise à jour | | `UserUpdateDTO` | Données de mise à jour |
| `RoleDTO` | Rôle Keycloak | | `RoleDTO` | Rôle Keycloak |
| `RealmDTO` | Realm Keycloak | | `RealmDTO` | Realm Keycloak |
| `RealmAssignmentDTO` | Assignation d'un utilisateur à un realm | | `RealmAssignmentDTO` | Assignation d'un utilisateur à un realm |
| `AuditLogDTO` | Entrée de journal d'audit | | `AuditLogDTO` | Entrée de journal d'audit |
| `SyncHistoryDTO` | Historique de synchronisation | | `SyncHistoryDTO` | Historique de synchronisation |
| `SyncConsistencyDTO` | Rapport de cohérence sync | | `SyncConsistencyDTO` | Rapport de cohérence sync |
| `ImportResultDTO` | Résultat d'import CSV | | `ImportResultDTO` | Résultat d'import CSV |
### Interfaces de services ### Interfaces de services
| Interface | Responsabilité | | Interface | Responsabilité |
|-----------|----------------| |-----------|----------------|
| `UserService` | CRUD utilisateurs, export/import CSV | | `UserService` | CRUD utilisateurs, export/import CSV |
| `RoleService` | Gestion des rôles par realm | | `RoleService` | Gestion des rôles par realm |
| `AuditService` | Consultation et export des logs d'audit | | `AuditService` | Consultation et export des logs d'audit |
| `SyncService` | Synchronisation Keycloak ↔ base de données | | `SyncService` | Synchronisation Keycloak ↔ base de données |
| `RealmAuthorizationService` | Gestion des realms autorisés | | `RealmAuthorizationService` | Gestion des realms autorisés |
### Interfaces de ressources (JAX-RS) ### Interfaces de ressources (JAX-RS)
| Interface | Path | | Interface | Path |
|-----------|------| |-----------|------|
| `UserResourceApi` | `/api/users` | | `UserResourceApi` | `/api/users` |
| `RoleResourceApi` | `/api/roles` | | `RoleResourceApi` | `/api/roles` |
| `AuditResourceApi` | `/api/audit` | | `AuditResourceApi` | `/api/audit` |
| `SyncResourceApi` | `/api/sync` | | `SyncResourceApi` | `/api/sync` |
| `RealmResourceApi` | `/api/realms` | | `RealmResourceApi` | `/api/realms` |
| `RealmAssignmentResourceApi` | `/api/realm-assignments` | | `RealmAssignmentResourceApi` | `/api/realm-assignments` |
### Enums ### Enums
- `StatutUser` — ACTIF, INACTIF, SUSPENDU - `StatutUser` — ACTIF, INACTIF, SUSPENDU
- `TypeRole` — ADMIN, USER, VIEWER - `TypeRole` — ADMIN, USER, VIEWER
- `TypeActionAudit` — CREATE, UPDATE, DELETE, LOGIN, LOGOUT, SYNC - `TypeActionAudit` — CREATE, UPDATE, DELETE, LOGIN, LOGOUT, SYNC
### Validations ### Validations
- `ValidationConstants` — Constantes partagées (longueurs, patterns regex) - `ValidationConstants` — Constantes partagées (longueurs, patterns regex)
--- ---
## Dépôt Git ## Dépôt Git
`https://git.lions.dev/lionsdev/lions-user-manager-server-api` `https://git.lions.dev/lionsdev/lions-user-manager-server-api`
--- ---
## Maven Registry ## Maven Registry
Le jar est disponible sur le **Gitea Package Registry** : Le jar est disponible sur le **Gitea Package Registry** :
``` ```
groupId : dev.lions.user.manager groupId : dev.lions.user.manager
artifactId : lions-user-manager-server-api artifactId : lions-user-manager-server-api
version : 1.0.0 version : 1.0.0
registry : https://git.lions.dev/api/packages/lionsdev/maven registry : https://git.lions.dev/api/packages/lionsdev/maven
``` ```
### Consommer ce module (server-impl / client) ### Consommer ce module (server-impl / client)
```xml ```xml
<dependency> <dependency>
<groupId>dev.lions.user.manager</groupId> <groupId>dev.lions.user.manager</groupId>
<artifactId>lions-user-manager-server-api</artifactId> <artifactId>lions-user-manager-server-api</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
</dependency> </dependency>
``` ```
```xml ```xml
<repositories> <repositories>
<repository> <repository>
<id>gitea-lionsdev</id> <id>gitea-lionsdev</id>
<url>https://git.lions.dev/api/packages/lionsdev/maven</url> <url>https://git.lions.dev/api/packages/lionsdev/maven</url>
</repository> </repository>
</repositories> </repositories>
``` ```
--- ---
## Publier une nouvelle version ## Publier une nouvelle version
1. Incrémenter la version dans `../pom.xml` (parent) 1. Incrémenter la version dans `../pom.xml` (parent)
2. Exécuter depuis la racine du monorepo : 2. Exécuter depuis la racine du monorepo :
```bash ```bash
# Windows # Windows
script\publish-api.bat script\publish-api.bat
# Linux / macOS # Linux / macOS
./script/publish-api.sh ./script/publish-api.sh
``` ```
--- ---
## Build local ## Build local
```bash ```bash
mvn clean install -DskipTests mvn clean install -DskipTests
``` ```
--- ---
## Licence ## Licence
Propriétaire — Lions Dev © 2025 Propriétaire — Lions Dev © 2025

View File

@@ -1,6 +1,6 @@
# This file configures Lombok for the project # This file configures Lombok for the project
# See https://projectlombok.org/features/configuration # See https://projectlombok.org/features/configuration
# Add @Generated annotation to all generated code # Add @Generated annotation to all generated code
# This allows JaCoCo to automatically exclude Lombok-generated code from coverage # This allows JaCoCo to automatically exclude Lombok-generated code from coverage
lombok.addLombokGeneratedAnnotation = true lombok.addLombokGeneratedAnnotation = true

View File

@@ -1,265 +1,266 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" <project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>dev.lions.user.manager</groupId> <groupId>dev.lions.user.manager</groupId>
<artifactId>lions-user-manager-parent</artifactId> <artifactId>lions-user-manager-parent</artifactId>
<version>1.0.0</version> <version>1.1.0</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>Lions User Manager - Parent</name> <name>Lions User Manager - Parent</name>
<description>Module de gestion centralisée des utilisateurs via Keycloak Admin API</description> <description>Module de gestion centralisée des utilisateurs via Keycloak Admin API</description>
<distributionManagement> <distributionManagement>
<repository> <repository>
<id>gitea-lionsdev</id> <id>gitea-lionsdev</id>
<url>https://git.lions.dev/api/packages/lionsdev/maven</url> <url>https://git.lions.dev/api/packages/lionsdev/maven</url>
</repository> </repository>
<snapshotRepository> <snapshotRepository>
<id>gitea-lionsdev</id> <id>gitea-lionsdev</id>
<url>https://git.lions.dev/api/packages/lionsdev/maven</url> <url>https://git.lions.dev/api/packages/lionsdev/maven</url>
</snapshotRepository> </snapshotRepository>
</distributionManagement> </distributionManagement>
<repositories> <repositories>
<repository> <repository>
<id>gitea-lionsdev</id> <id>gitea-lionsdev</id>
<url>https://git.lions.dev/api/packages/lionsdev/maven</url> <url>https://git.lions.dev/api/packages/lionsdev/maven</url>
<releases><enabled>true</enabled></releases> <releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots> <snapshots><enabled>true</enabled></snapshots>
</repository> </repository>
</repositories> </repositories>
<properties> <properties>
<maven.compiler.source>21</maven.compiler.source> <maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target> <maven.compiler.target>21</maven.compiler.target>
<maven.compiler.release>21</maven.compiler.release> <maven.compiler.release>21</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- Quarkus & Dependencies --> <!-- Quarkus & Dependencies — 3.27.3 LTS (Testcontainers 1.21.3, Hibernate ORM 7.0) -->
<quarkus.version>3.20.0</quarkus.version> <quarkus.version>3.27.3</quarkus.version>
<quarkus-primefaces.version>3.15.1</quarkus-primefaces.version> <quarkus-primefaces.version>3.15.1</quarkus-primefaces.version>
<primefaces.version>14.0.5</primefaces.version> <primefaces.version>14.0.5</primefaces.version>
<primefaces-freya-extension.version>1.0.0</primefaces-freya-extension.version> <primefaces-freya-extension.version>1.0.0</primefaces-freya-extension.version>
<keycloak.version>26.0.7</keycloak.version> <keycloak.version>26.0.7</keycloak.version>
<lombok.version>1.18.36</lombok.version> <lombok.version>1.18.38</lombok.version>
<mapstruct.version>1.6.3</mapstruct.version> <mapstruct.version>1.6.3</mapstruct.version>
<!-- Testing --> <!-- Testing — overrides BOM (BOM bundles TC 1.21.3 / docker-java 3.4.2) -->
<junit.version>5.11.4</junit.version> <junit.version>5.11.4</junit.version>
<mockito.version>5.14.2</mockito.version> <mockito.version>5.14.2</mockito.version>
<testcontainers.version>1.20.6</testcontainers.version> <testcontainers.version>1.21.4</testcontainers.version>
<rest-assured.version>5.5.0</rest-assured.version> <docker-java.version>3.4.2</docker-java.version>
<rest-assured.version>5.5.0</rest-assured.version>
<!-- Plugins -->
<maven-compiler-plugin.version>3.13.0</maven-compiler-plugin.version> <!-- Plugins -->
<maven-surefire-plugin.version>3.5.2</maven-surefire-plugin.version> <maven-compiler-plugin.version>3.13.0</maven-compiler-plugin.version>
<maven-failsafe-plugin.version>3.5.2</maven-failsafe-plugin.version> <maven-surefire-plugin.version>3.5.2</maven-surefire-plugin.version>
<jacoco-maven-plugin.version>0.8.12</jacoco-maven-plugin.version> <maven-failsafe-plugin.version>3.5.2</maven-failsafe-plugin.version>
</properties> <jacoco-maven-plugin.version>0.8.12</jacoco-maven-plugin.version>
</properties>
<modules>
<module>lions-user-manager-server-api</module> <modules>
<module>lions-user-manager-server-impl-quarkus</module> <module>lions-user-manager-server-api</module>
<module>lions-user-manager-client-quarkus-primefaces-freya</module> <module>lions-user-manager-server-impl-quarkus</module>
</modules> <module>lions-user-manager-client-quarkus-primefaces-freya</module>
</modules>
<dependencyManagement>
<dependencies> <dependencyManagement>
<!-- Quarkus BOM --> <dependencies>
<dependency> <!-- Quarkus BOM -->
<groupId>io.quarkus.platform</groupId> <dependency>
<artifactId>quarkus-bom</artifactId> <groupId>io.quarkus.platform</groupId>
<version>${quarkus.version}</version> <artifactId>quarkus-bom</artifactId>
<type>pom</type> <version>${quarkus.version}</version>
<scope>import</scope> <type>pom</type>
</dependency> <scope>import</scope>
</dependency>
<!-- Internal modules -->
<dependency> <!-- Internal modules -->
<groupId>dev.lions.user.manager</groupId> <dependency>
<artifactId>lions-user-manager-server-api</artifactId> <groupId>dev.lions.user.manager</groupId>
<version>${project.version}</version> <artifactId>lions-user-manager-server-api</artifactId>
</dependency> <version>${project.version}</version>
</dependency>
<!-- PrimeFaces Freya Extension -->
<dependency> <!-- PrimeFaces Freya Extension -->
<groupId>dev.lions</groupId> <dependency>
<artifactId>primefaces-freya-extension</artifactId> <groupId>dev.lions</groupId>
<version>${primefaces-freya-extension.version}</version> <artifactId>primefaces-freya-extension</artifactId>
</dependency> <version>${primefaces-freya-extension.version}</version>
</dependency>
<!-- Lombok -->
<dependency> <!-- Lombok -->
<groupId>org.projectlombok</groupId> <dependency>
<artifactId>lombok</artifactId> <groupId>org.projectlombok</groupId>
<version>${lombok.version}</version> <artifactId>lombok</artifactId>
<scope>provided</scope> <version>${lombok.version}</version>
</dependency> <scope>provided</scope>
</dependency>
<!-- MapStruct -->
<dependency> <!-- MapStruct -->
<groupId>org.mapstruct</groupId> <dependency>
<artifactId>mapstruct</artifactId> <groupId>org.mapstruct</groupId>
<version>${mapstruct.version}</version> <artifactId>mapstruct</artifactId>
</dependency> <version>${mapstruct.version}</version>
</dependency>
<!-- Testing -->
<dependency> <!-- Testing -->
<groupId>org.junit.jupiter</groupId> <dependency>
<artifactId>junit-jupiter</artifactId> <groupId>org.junit.jupiter</groupId>
<version>${junit.version}</version> <artifactId>junit-jupiter</artifactId>
<scope>test</scope> <version>${junit.version}</version>
</dependency> <scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId> <dependency>
<artifactId>testcontainers-bom</artifactId> <groupId>org.testcontainers</groupId>
<version>${testcontainers.version}</version> <artifactId>testcontainers-bom</artifactId>
<type>pom</type> <version>${testcontainers.version}</version>
<scope>import</scope> <type>pom</type>
</dependency> <scope>import</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId> <dependency>
<artifactId>rest-assured</artifactId> <groupId>io.rest-assured</groupId>
<version>${rest-assured.version}</version> <artifactId>rest-assured</artifactId>
<scope>test</scope> <version>${rest-assured.version}</version>
</dependency> <scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId> <dependency>
<artifactId>mockito-core</artifactId> <groupId>org.mockito</groupId>
<version>${mockito.version}</version> <artifactId>mockito-core</artifactId>
<scope>test</scope> <version>${mockito.version}</version>
</dependency> <scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId> <dependency>
<artifactId>mockito-junit-jupiter</artifactId> <groupId>org.mockito</groupId>
<version>${mockito.version}</version> <artifactId>mockito-junit-jupiter</artifactId>
</dependency> <version>${mockito.version}</version>
</dependency>
</dependencies>
</dependencyManagement> </dependencies>
</dependencyManagement>
<profiles>
<profile> <profiles>
<id>dev</id> <profile>
<activation> <id>dev</id>
<activeByDefault>true</activeByDefault> <activation>
</activation> <activeByDefault>true</activeByDefault>
<properties> </activation>
<quarkus.profile>dev</quarkus.profile> <properties>
</properties> <quarkus.profile>dev</quarkus.profile>
</profile> </properties>
<profile> </profile>
<id>prod</id> <profile>
<properties> <id>prod</id>
<quarkus.profile>prod</quarkus.profile> <properties>
</properties> <quarkus.profile>prod</quarkus.profile>
</profile> </properties>
<profile> </profile>
<id>native</id> <profile>
<properties> <id>native</id>
<quarkus.profile>prod</quarkus.profile> <properties>
<quarkus.package.jar.type>native</quarkus.package.jar.type> <quarkus.profile>prod</quarkus.profile>
</properties> <quarkus.package.jar.type>native</quarkus.package.jar.type>
<dependencies> </properties>
<dependency> <dependencies>
<groupId>io.quarkus</groupId> <dependency>
<artifactId>quarkus-junit5</artifactId> <groupId>io.quarkus</groupId>
<scope>test</scope> <artifactId>quarkus-junit5</artifactId>
</dependency> <scope>test</scope>
</dependencies> </dependency>
</profile> </dependencies>
</profiles> </profile>
</profiles>
<build>
<pluginManagement> <build>
<plugins> <pluginManagement>
<plugin> <plugins>
<groupId>org.apache.maven.plugins</groupId> <plugin>
<artifactId>maven-compiler-plugin</artifactId> <groupId>org.apache.maven.plugins</groupId>
<version>${maven-compiler-plugin.version}</version> <artifactId>maven-compiler-plugin</artifactId>
<configuration> <version>${maven-compiler-plugin.version}</version>
<annotationProcessorPaths> <configuration>
<path> <annotationProcessorPaths>
<groupId>org.projectlombok</groupId> <path>
<artifactId>lombok</artifactId> <groupId>org.projectlombok</groupId>
<version>${lombok.version}</version> <artifactId>lombok</artifactId>
</path> <version>${lombok.version}</version>
<path> </path>
<groupId>org.mapstruct</groupId> <path>
<artifactId>mapstruct-processor</artifactId> <groupId>org.mapstruct</groupId>
<version>${mapstruct.version}</version> <artifactId>mapstruct-processor</artifactId>
</path> <version>${mapstruct.version}</version>
</annotationProcessorPaths> </path>
</configuration> </annotationProcessorPaths>
</plugin> </configuration>
</plugin>
<plugin>
<groupId>io.quarkus.platform</groupId> <plugin>
<artifactId>quarkus-maven-plugin</artifactId> <groupId>io.quarkus.platform</groupId>
<version>${quarkus.version}</version> <artifactId>quarkus-maven-plugin</artifactId>
</plugin> <version>${quarkus.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId> <plugin>
<artifactId>maven-surefire-plugin</artifactId> <groupId>org.apache.maven.plugins</groupId>
<version>${maven-surefire-plugin.version}</version> <artifactId>maven-surefire-plugin</artifactId>
</plugin> <version>${maven-surefire-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId> <plugin>
<artifactId>maven-failsafe-plugin</artifactId> <groupId>org.apache.maven.plugins</groupId>
<version>${maven-failsafe-plugin.version}</version> <artifactId>maven-failsafe-plugin</artifactId>
</plugin> <version>${maven-failsafe-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.jacoco</groupId> <plugin>
<artifactId>jacoco-maven-plugin</artifactId> <groupId>org.jacoco</groupId>
<version>${jacoco-maven-plugin.version}</version> <artifactId>jacoco-maven-plugin</artifactId>
<executions> <version>${jacoco-maven-plugin.version}</version>
<execution> <executions>
<goals> <execution>
<goal>prepare-agent</goal> <goals>
</goals> <goal>prepare-agent</goal>
</execution> </goals>
<execution> </execution>
<id>report</id> <execution>
<phase>test</phase> <id>report</id>
<goals> <phase>test</phase>
<goal>report</goal> <goals>
</goals> <goal>report</goal>
</execution> </goals>
<execution> </execution>
<id>jacoco-check</id> <execution>
<goals> <id>jacoco-check</id>
<goal>check</goal> <goals>
</goals> <goal>check</goal>
<configuration> </goals>
<rules> <configuration>
<rule> <rules>
<element>PACKAGE</element> <rule>
<limits> <element>PACKAGE</element>
<limit> <limits>
<counter>LINE</counter> <limit>
<value>COVEREDRATIO</value> <counter>LINE</counter>
<minimum>0.80</minimum> <value>COVEREDRATIO</value>
</limit> <minimum>0.80</minimum>
</limits> </limit>
</rule> </limits>
</rules> </rule>
</configuration> </rules>
</execution> </configuration>
</executions> </execution>
</plugin> </executions>
</plugins> </plugin>
</pluginManagement> </plugins>
</build> </pluginManagement>
</project> </build>
</project>

225
pom.xml
View File

@@ -1,91 +1,134 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" <project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <groupId>dev.lions.user.manager</groupId>
<groupId>dev.lions.user.manager</groupId> <version>1.1.0</version>
<artifactId>lions-user-manager-parent</artifactId>
<version>1.0.0</version> <properties>
</parent> <java.version>21</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<artifactId>lions-user-manager-server-api</artifactId> <maven.compiler.target>${java.version}</maven.compiler.target>
<packaging>jar</packaging> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<quarkus.platform.version>3.27.3</quarkus.platform.version>
<name>Lions User Manager - Server API</name> <lombok.version>1.18.38</lombok.version>
<description>Contrats API: DTOs, interfaces de services, enums et validations</description> </properties>
<dependencies> <artifactId>lions-user-manager-server-api</artifactId>
<!-- Lombok --> <packaging>jar</packaging>
<dependency>
<groupId>org.projectlombok</groupId> <name>Lions User Manager - Server API</name>
<artifactId>lombok</artifactId> <description>Contrats API: DTOs, interfaces de services, enums et validations</description>
</dependency>
<distributionManagement>
<!-- Jakarta EE APIs --> <repository>
<dependency> <id>gitea-lionsdev</id>
<groupId>jakarta.validation</groupId> <url>https://git.lions.dev/api/packages/lionsdev/maven</url>
<artifactId>jakarta.validation-api</artifactId> </repository>
</dependency> </distributionManagement>
<dependency> <repositories>
<groupId>jakarta.ws.rs</groupId> <repository>
<artifactId>jakarta.ws.rs-api</artifactId> <id>gitea-lionsdev</id>
</dependency> <url>https://git.lions.dev/api/packages/lionsdev/maven</url>
<releases><enabled>true</enabled></releases>
<!-- Jackson for JSON --> <snapshots><enabled>true</enabled></snapshots>
<dependency> </repository>
<groupId>com.fasterxml.jackson.core</groupId> </repositories>
<artifactId>jackson-annotations</artifactId>
</dependency> <dependencyManagement>
<dependencies>
<!-- OpenAPI annotations --> <!-- Quarkus BOM : gère Jakarta, Jackson, MicroProfile OpenAPI, quarkus-core, JUnit -->
<dependency> <dependency>
<groupId>org.eclipse.microprofile.openapi</groupId> <groupId>io.quarkus.platform</groupId>
<artifactId>microprofile-openapi-api</artifactId> <artifactId>quarkus-bom</artifactId>
</dependency> <version>${quarkus.platform.version}</version>
<type>pom</type>
<!-- Quarkus Runtime API (pour @RegisterForReflection) --> <scope>import</scope>
<dependency> </dependency>
<groupId>io.quarkus</groupId> <!-- Lombok : pas dans Quarkus BOM -->
<artifactId>quarkus-core</artifactId> <dependency>
<scope>provided</scope> <groupId>org.projectlombok</groupId>
<optional>true</optional> <artifactId>lombok</artifactId>
</dependency> <version>${lombok.version}</version>
<scope>provided</scope>
<!-- Testing --> </dependency>
<dependency> </dependencies>
<groupId>org.junit.jupiter</groupId> </dependencyManagement>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope> <dependencies>
</dependency> <!-- Lombok -->
</dependencies> <dependency>
<groupId>org.projectlombok</groupId>
<build> <artifactId>lombok</artifactId>
<plugins> </dependency>
<plugin>
<groupId>org.apache.maven.plugins</groupId> <!-- Jakarta EE APIs -->
<artifactId>maven-compiler-plugin</artifactId> <dependency>
<configuration> <groupId>jakarta.validation</groupId>
<release>21</release> <artifactId>jakarta.validation-api</artifactId>
</configuration> </dependency>
</plugin>
<dependency>
<!-- Jandex Maven Plugin pour générer l'index Jandex --> <groupId>jakarta.ws.rs</groupId>
<plugin> <artifactId>jakarta.ws.rs-api</artifactId>
<groupId>io.smallrye</groupId> </dependency>
<artifactId>jandex-maven-plugin</artifactId>
<version>3.2.4</version> <!-- Jackson for JSON -->
<executions> <dependency>
<execution> <groupId>com.fasterxml.jackson.core</groupId>
<id>make-index</id> <artifactId>jackson-annotations</artifactId>
<goals> </dependency>
<goal>jandex</goal>
</goals> <!-- OpenAPI annotations -->
</execution> <dependency>
</executions> <groupId>org.eclipse.microprofile.openapi</groupId>
</plugin> <artifactId>microprofile-openapi-api</artifactId>
</plugins> </dependency>
</build>
</project> <!-- Quarkus Runtime API (pour @RegisterForReflection) -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-core</artifactId>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<!-- Testing -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<release>21</release>
</configuration>
</plugin>
<!-- Jandex Maven Plugin pour générer l'index Jandex -->
<plugin>
<groupId>io.smallrye</groupId>
<artifactId>jandex-maven-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<id>make-index</id>
<goals>
<goal>jandex</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -1,30 +1,30 @@
@echo off @echo off
REM Publie le parent pom + server-api sur le Gitea Package Registry REM Publie le parent pom + server-api sur le Gitea Package Registry
REM Usage : script\publish-api.bat REM Usage : script\publish-api.bat
REM Depuis : n'importe où dans le repo server-api REM Depuis : n'importe où dans le repo server-api
REM Prérequis: credentials dans %USERPROFILE%\.m2\settings.xml (server id: gitea-lionsdev) 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_URL=https://git.lions.dev/api/packages/lionsdev/maven
set REGISTRY_ID=gitea-lionsdev set REGISTRY_ID=gitea-lionsdev
cd /d "%~dp0.." cd /d "%~dp0.."
echo. echo.
echo [1/2] Publication du parent pom... echo [1/2] Publication du parent pom...
call mvn deploy:deploy-file ^ call mvn deploy:deploy-file ^
-DgroupId=dev.lions.user.manager ^ -DgroupId=dev.lions.user.manager ^
-DartifactId=lions-user-manager-parent ^ -DartifactId=lions-user-manager-parent ^
-Dversion=1.0.0 ^ -Dversion=1.0.0 ^
-Dpackaging=pom ^ -Dpackaging=pom ^
-Dfile=parent-pom.xml ^ -Dfile=parent-pom.xml ^
-DrepositoryId=%REGISTRY_ID% ^ -DrepositoryId=%REGISTRY_ID% ^
-Durl=%REGISTRY_URL% -Durl=%REGISTRY_URL%
if %errorlevel% neq 0 echo [WARN] Parent pom deja publie pour cette version (409), on continue. if %errorlevel% neq 0 echo [WARN] Parent pom deja publie pour cette version (409), on continue.
echo. echo.
echo [2/2] Publication du server-api... echo [2/2] Publication du server-api...
call mvn deploy -DskipTests call mvn deploy -DskipTests
if %errorlevel% neq 0 echo [WARN] Server-api deja publie pour cette version (409) - incrementer la version pour republier. if %errorlevel% neq 0 echo [WARN] Server-api deja publie pour cette version (409) - incrementer la version pour republier.
echo. echo.
echo Done -- https://git.lions.dev/lionsdev/-/packages echo Done -- https://git.lions.dev/lionsdev/-/packages

View File

@@ -1,32 +1,32 @@
#!/bin/bash #!/bin/bash
# Publie le parent pom + server-api sur le Gitea Package Registry # Publie le parent pom + server-api sur le Gitea Package Registry
# Usage : ./script/publish-api.sh # Usage : ./script/publish-api.sh
# Depuis : n'importe où dans le repo server-api # Depuis : n'importe où dans le repo server-api
# Prérequis: credentials dans ~/.m2/settings.xml (server id: gitea-lionsdev) # Prérequis: credentials dans ~/.m2/settings.xml (server id: gitea-lionsdev)
set -e set -e
REGISTRY_URL="https://git.lions.dev/api/packages/lionsdev/maven" REGISTRY_URL="https://git.lions.dev/api/packages/lionsdev/maven"
REGISTRY_ID="gitea-lionsdev" REGISTRY_ID="gitea-lionsdev"
cd "$(dirname "$0")/.." cd "$(dirname "$0")/.."
echo "" echo ""
echo "[1/2] Publication du parent pom..." echo "[1/2] Publication du parent pom..."
mvn deploy:deploy-file \ mvn deploy:deploy-file \
-DgroupId=dev.lions.user.manager \ -DgroupId=dev.lions.user.manager \
-DartifactId=lions-user-manager-parent \ -DartifactId=lions-user-manager-parent \
-Dversion=1.0.0 \ -Dversion=1.1.0 \
-Dpackaging=pom \ -Dpackaging=pom \
-Dfile=parent-pom.xml \ -Dfile=parent-pom.xml \
-DrepositoryId="${REGISTRY_ID}" \ -DrepositoryId="${REGISTRY_ID}" \
-Durl="${REGISTRY_URL}" \ -Durl="${REGISTRY_URL}" \
|| echo "[WARN] Parent pom deja publie pour cette version (409), on continue." || echo "[WARN] Parent pom deja publie pour cette version (409), on continue."
echo "" echo ""
echo "[2/2] Publication du server-api..." echo "[2/2] Publication du server-api..."
mvn deploy -DskipTests \ mvn deploy -DskipTests \
|| echo "[WARN] Server-api deja publie pour cette version (409) - incrementer la version pour republier." || echo "[WARN] Server-api deja publie pour cette version (409) - incrementer la version pour republier."
echo "" echo ""
echo "Done -- https://git.lions.dev/lionsdev/-/packages" echo "Done -- https://git.lions.dev/lionsdev/-/packages"

View File

@@ -1,111 +1,111 @@
package dev.lions.user.manager.api; package dev.lions.user.manager.api;
import dev.lions.user.manager.dto.audit.AuditLogDTO; import dev.lions.user.manager.dto.audit.AuditLogDTO;
import dev.lions.user.manager.dto.common.CountDTO; import dev.lions.user.manager.dto.common.CountDTO;
import dev.lions.user.manager.enums.audit.TypeActionAudit; import dev.lions.user.manager.enums.audit.TypeActionAudit;
import jakarta.ws.rs.*; import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response;
import org.eclipse.microprofile.openapi.annotations.Operation; import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.media.Content; import org.eclipse.microprofile.openapi.annotations.media.Content;
import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.eclipse.microprofile.openapi.annotations.media.Schema;
import org.eclipse.microprofile.openapi.annotations.parameters.Parameter; import org.eclipse.microprofile.openapi.annotations.parameters.Parameter;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponses; import org.eclipse.microprofile.openapi.annotations.responses.APIResponses;
import org.eclipse.microprofile.openapi.annotations.tags.Tag; import org.eclipse.microprofile.openapi.annotations.tags.Tag;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
* Interface JAX-RS pour l'API d'audit. * Interface JAX-RS pour l'API d'audit.
*/ */
@Path("/api/audit") @Path("/api/audit")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@Tag(name = "Audit", description = "Consultation des logs d'audit et statistiques") @Tag(name = "Audit", description = "Consultation des logs d'audit et statistiques")
public interface AuditResourceApi { public interface AuditResourceApi {
@POST @POST
@Path("/search") @Path("/search")
@Operation(summary = "Rechercher des logs d'audit", description = "Recherche avancée de logs selon critères") @Operation(summary = "Rechercher des logs d'audit", description = "Recherche avancée de logs selon critères")
@APIResponses({ @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 = "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") @APIResponse(responseCode = "500", description = "Erreur serveur")
}) })
List<AuditLogDTO> searchLogs( List<AuditLogDTO> searchLogs(
@QueryParam("acteur") String acteurUsername, @QueryParam("acteur") String acteurUsername,
@QueryParam("dateDebut") String dateDebut, @QueryParam("dateDebut") String dateDebut,
@QueryParam("dateFin") String dateFin, @QueryParam("dateFin") String dateFin,
@QueryParam("typeAction") TypeActionAudit typeAction, @QueryParam("typeAction") TypeActionAudit typeAction,
@QueryParam("ressourceType") String ressourceType, @QueryParam("ressourceType") String ressourceType,
@QueryParam("succes") Boolean succes, @QueryParam("succes") Boolean succes,
@QueryParam("page") @DefaultValue("0") int page, @QueryParam("page") @DefaultValue("0") int page,
@QueryParam("pageSize") @DefaultValue("50") int pageSize); @QueryParam("pageSize") @DefaultValue("50") int pageSize);
@GET @GET
@Path("/actor/{acteurUsername}") @Path("/actor/{acteurUsername}")
@Operation(summary = "Récupérer les logs d'un acteur", description = "Liste les derniers logs d'un utilisateur") @Operation(summary = "Récupérer les logs d'un acteur", description = "Liste les derniers logs d'un utilisateur")
List<AuditLogDTO> getLogsByActor( List<AuditLogDTO> getLogsByActor(
@Parameter(description = "Username de l'acteur") @PathParam("acteurUsername") String acteurUsername, @Parameter(description = "Username de l'acteur") @PathParam("acteurUsername") String acteurUsername,
@Parameter(description = "Nombre de logs à retourner") @QueryParam("limit") @DefaultValue("100") int limit); @Parameter(description = "Nombre de logs à retourner") @QueryParam("limit") @DefaultValue("100") int limit);
@GET @GET
@Path("/resource/{ressourceType}/{ressourceId}") @Path("/resource/{ressourceType}/{ressourceId}")
@Operation(summary = "Récupérer les logs d'une ressource", description = "Liste les derniers logs d'une ressource spécifique") @Operation(summary = "Récupérer les logs d'une ressource", description = "Liste les derniers logs d'une ressource spécifique")
List<AuditLogDTO> getLogsByResource( List<AuditLogDTO> getLogsByResource(
@PathParam("ressourceType") String ressourceType, @PathParam("ressourceType") String ressourceType,
@PathParam("ressourceId") String ressourceId, @PathParam("ressourceId") String ressourceId,
@QueryParam("limit") @DefaultValue("100") int limit); @QueryParam("limit") @DefaultValue("100") int limit);
@GET @GET
@Path("/action/{typeAction}") @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") @Operation(summary = "Récupérer les logs par type d'action", description = "Liste les logs d'un type d'action spécifique")
List<AuditLogDTO> getLogsByAction( List<AuditLogDTO> getLogsByAction(
@PathParam("typeAction") TypeActionAudit typeAction, @PathParam("typeAction") TypeActionAudit typeAction,
@QueryParam("dateDebut") String dateDebut, @QueryParam("dateDebut") String dateDebut,
@QueryParam("dateFin") String dateFin, @QueryParam("dateFin") String dateFin,
@QueryParam("limit") @DefaultValue("100") int limit); @QueryParam("limit") @DefaultValue("100") int limit);
@GET @GET
@Path("/stats/actions") @Path("/stats/actions")
@Operation(summary = "Statistiques par type d'action", description = "Retourne le nombre de logs par type d'action") @Operation(summary = "Statistiques par type d'action", description = "Retourne le nombre de logs par type d'action")
Map<TypeActionAudit, Long> getActionStatistics( Map<TypeActionAudit, Long> getActionStatistics(
@QueryParam("dateDebut") String dateDebut, @QueryParam("dateDebut") String dateDebut,
@QueryParam("dateFin") String dateFin); @QueryParam("dateFin") String dateFin);
@GET @GET
@Path("/stats/users") @Path("/stats/users")
@Operation(summary = "Statistiques par utilisateur", description = "Retourne le nombre d'actions par utilisateur") @Operation(summary = "Statistiques par utilisateur", description = "Retourne le nombre d'actions par utilisateur")
Map<String, Long> getUserActivityStatistics( Map<String, Long> getUserActivityStatistics(
@QueryParam("dateDebut") String dateDebut, @QueryParam("dateDebut") String dateDebut,
@QueryParam("dateFin") String dateFin); @QueryParam("dateFin") String dateFin);
@GET @GET
@Path("/stats/failures") @Path("/stats/failures")
@Operation(summary = "Comptage des échecs", description = "Retourne le nombre d'échecs sur une période") @Operation(summary = "Comptage des échecs", description = "Retourne le nombre d'échecs sur une période")
CountDTO getFailureCount( CountDTO getFailureCount(
@QueryParam("dateDebut") String dateDebut, @QueryParam("dateDebut") String dateDebut,
@QueryParam("dateFin") String dateFin); @QueryParam("dateFin") String dateFin);
@GET @GET
@Path("/stats/success") @Path("/stats/success")
@Operation(summary = "Comptage des succès", description = "Retourne le nombre de succès sur une période") @Operation(summary = "Comptage des succès", description = "Retourne le nombre de succès sur une période")
CountDTO getSuccessCount( CountDTO getSuccessCount(
@QueryParam("dateDebut") String dateDebut, @QueryParam("dateDebut") String dateDebut,
@QueryParam("dateFin") String dateFin); @QueryParam("dateFin") String dateFin);
@GET @GET
@Path("/export/csv") @Path("/export/csv")
@Produces(MediaType.TEXT_PLAIN) @Produces(MediaType.TEXT_PLAIN)
@Operation(summary = "Exporter les logs en CSV", description = "Génère un fichier CSV des logs d'audit") @Operation(summary = "Exporter les logs en CSV", description = "Génère un fichier CSV des logs d'audit")
Response exportLogsToCSV( Response exportLogsToCSV(
@QueryParam("dateDebut") String dateDebut, @QueryParam("dateDebut") String dateDebut,
@QueryParam("dateFin") String dateFin); @QueryParam("dateFin") String dateFin);
@DELETE @DELETE
@Path("/purge") @Path("/purge")
@Operation(summary = "Purger les anciens logs", description = "Supprime les logs de plus de X jours") @Operation(summary = "Purger les anciens logs", description = "Supprime les logs de plus de X jours")
void purgeOldLogs( void purgeOldLogs(
@QueryParam("joursAnciennete") @DefaultValue("90") int joursAnciennete); @QueryParam("joursAnciennete") @DefaultValue("90") int joursAnciennete);
} }

View File

@@ -1,103 +1,103 @@
package dev.lions.user.manager.api; package dev.lions.user.manager.api;
import dev.lions.user.manager.dto.realm.AuthorizedRealmsDTO; import dev.lions.user.manager.dto.realm.AuthorizedRealmsDTO;
import dev.lions.user.manager.dto.realm.RealmAccessCheckDTO; import dev.lions.user.manager.dto.realm.RealmAccessCheckDTO;
import dev.lions.user.manager.dto.realm.RealmAssignmentDTO; import dev.lions.user.manager.dto.realm.RealmAssignmentDTO;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.*; import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response;
import org.eclipse.microprofile.openapi.annotations.Operation; import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.media.Content; import org.eclipse.microprofile.openapi.annotations.media.Content;
import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.eclipse.microprofile.openapi.annotations.media.Schema;
import org.eclipse.microprofile.openapi.annotations.parameters.Parameter; import org.eclipse.microprofile.openapi.annotations.parameters.Parameter;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponses; import org.eclipse.microprofile.openapi.annotations.responses.APIResponses;
import org.eclipse.microprofile.openapi.annotations.tags.Tag; import org.eclipse.microprofile.openapi.annotations.tags.Tag;
import java.util.List; import java.util.List;
/** /**
* Interface JAX-RS pour l'API de gestion des affectations de realms. * Interface JAX-RS pour l'API de gestion des affectations de realms.
*/ */
@Path("/api/realm-assignments") @Path("/api/realm-assignments")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@Tag(name = "Realm Assignments", description = "Gestion des affectations de realms (contrôle d'accès multi-tenant)") @Tag(name = "Realm Assignments", description = "Gestion des affectations de realms (contrôle d'accès multi-tenant)")
public interface RealmAssignmentResourceApi { public interface RealmAssignmentResourceApi {
@GET @GET
@Operation(summary = "Lister toutes les affectations", description = "Liste toutes les affectations de realms") @Operation(summary = "Lister toutes les affectations", description = "Liste toutes les affectations de realms")
List<RealmAssignmentDTO> getAllAssignments(); List<RealmAssignmentDTO> getAllAssignments();
@GET @GET
@Path("/user/{userId}") @Path("/user/{userId}")
@Operation(summary = "Affectations par utilisateur", description = "Liste les realms assignés à un utilisateur") @Operation(summary = "Affectations par utilisateur", description = "Liste les realms assignés à un utilisateur")
List<RealmAssignmentDTO> getAssignmentsByUser( List<RealmAssignmentDTO> getAssignmentsByUser(
@Parameter(description = "ID de l'utilisateur") @PathParam("userId") String userId); @Parameter(description = "ID de l'utilisateur") @PathParam("userId") String userId);
@GET @GET
@Path("/realm/{realmName}") @Path("/realm/{realmName}")
@Operation(summary = "Affectations par realm", description = "Liste les utilisateurs ayant accès à un realm") @Operation(summary = "Affectations par realm", description = "Liste les utilisateurs ayant accès à un realm")
List<RealmAssignmentDTO> getAssignmentsByRealm( List<RealmAssignmentDTO> getAssignmentsByRealm(
@Parameter(description = "Nom du realm") @PathParam("realmName") String realmName); @Parameter(description = "Nom du realm") @PathParam("realmName") String realmName);
@GET @GET
@Path("/{assignmentId}") @Path("/{assignmentId}")
@Operation(summary = "Récupérer une affectation", description = "Récupère une affectation par son ID") @Operation(summary = "Récupérer une affectation", description = "Récupère une affectation par son ID")
RealmAssignmentDTO getAssignmentById( RealmAssignmentDTO getAssignmentById(
@Parameter(description = "ID de l'affectation") @PathParam("assignmentId") String assignmentId); @Parameter(description = "ID de l'affectation") @PathParam("assignmentId") String assignmentId);
@GET @GET
@Path("/check") @Path("/check")
@Operation(summary = "Vérifier l'accès", description = "Vérifie si un utilisateur peut gérer un realm") @Operation(summary = "Vérifier l'accès", description = "Vérifie si un utilisateur peut gérer un realm")
RealmAccessCheckDTO canManageRealm( RealmAccessCheckDTO canManageRealm(
@Parameter(description = "ID de l'utilisateur") @QueryParam("userId") String userId, @Parameter(description = "ID de l'utilisateur") @QueryParam("userId") String userId,
@Parameter(description = "Nom du realm") @QueryParam("realmName") String realmName); @Parameter(description = "Nom du realm") @QueryParam("realmName") String realmName);
@GET @GET
@Path("/authorized-realms/{userId}") @Path("/authorized-realms/{userId}")
@Operation(summary = "Realms autorisés", description = "Liste les realms qu'un utilisateur peut gérer") @Operation(summary = "Realms autorisés", description = "Liste les realms qu'un utilisateur peut gérer")
AuthorizedRealmsDTO getAuthorizedRealms( AuthorizedRealmsDTO getAuthorizedRealms(
@Parameter(description = "ID de l'utilisateur") @PathParam("userId") String userId); @Parameter(description = "ID de l'utilisateur") @PathParam("userId") String userId);
@POST @POST
@Operation(summary = "Assigner un realm", description = "Assigne un realm à un utilisateur") @Operation(summary = "Assigner un realm", description = "Assigne un realm à un utilisateur")
@APIResponses({ @APIResponses({
@APIResponse(responseCode = "201", description = "Affectation créée", content = @Content(schema = @Schema(implementation = RealmAssignmentDTO.class))) @APIResponse(responseCode = "201", description = "Affectation créée", content = @Content(schema = @Schema(implementation = RealmAssignmentDTO.class)))
}) })
Response assignRealmToUser(@Valid @NotNull RealmAssignmentDTO assignment); Response assignRealmToUser(@Valid @NotNull RealmAssignmentDTO assignment);
@DELETE @DELETE
@Path("/user/{userId}/realm/{realmName}") @Path("/user/{userId}/realm/{realmName}")
@Operation(summary = "Révoquer un realm", description = "Retire l'accès d'un utilisateur à un realm") @Operation(summary = "Révoquer un realm", description = "Retire l'accès d'un utilisateur à un realm")
void revokeRealmFromUser( void revokeRealmFromUser(
@Parameter(description = "ID de l'utilisateur") @PathParam("userId") String userId, @Parameter(description = "ID de l'utilisateur") @PathParam("userId") String userId,
@Parameter(description = "Nom du realm") @PathParam("realmName") String realmName); @Parameter(description = "Nom du realm") @PathParam("realmName") String realmName);
@DELETE @DELETE
@Path("/user/{userId}") @Path("/user/{userId}")
@Operation(summary = "Révoquer tous les realms", description = "Retire tous les accès d'un utilisateur") @Operation(summary = "Révoquer tous les realms", description = "Retire tous les accès d'un utilisateur")
void revokeAllRealmsFromUser( void revokeAllRealmsFromUser(
@Parameter(description = "ID de l'utilisateur") @PathParam("userId") String userId); @Parameter(description = "ID de l'utilisateur") @PathParam("userId") String userId);
@PUT @PUT
@Path("/{assignmentId}/deactivate") @Path("/{assignmentId}/deactivate")
@Operation(summary = "Désactiver une affectation", description = "Désactive une affectation sans la supprimer") @Operation(summary = "Désactiver une affectation", description = "Désactive une affectation sans la supprimer")
void deactivateAssignment( void deactivateAssignment(
@Parameter(description = "ID de l'affectation") @PathParam("assignmentId") String assignmentId); @Parameter(description = "ID de l'affectation") @PathParam("assignmentId") String assignmentId);
@PUT @PUT
@Path("/{assignmentId}/activate") @Path("/{assignmentId}/activate")
@Operation(summary = "Activer une affectation", description = "Réactive une affectation") @Operation(summary = "Activer une affectation", description = "Réactive une affectation")
void activateAssignment( void activateAssignment(
@Parameter(description = "ID de l'affectation") @PathParam("assignmentId") String assignmentId); @Parameter(description = "ID de l'affectation") @PathParam("assignmentId") String assignmentId);
@PUT @PUT
@Path("/super-admin/{userId}") @Path("/super-admin/{userId}")
@Operation(summary = "Définir super admin", description = "Définit ou retire le statut de super admin") @Operation(summary = "Définir super admin", description = "Définit ou retire le statut de super admin")
void setSuperAdmin( void setSuperAdmin(
@Parameter(description = "ID de l'utilisateur") @PathParam("userId") String userId, @Parameter(description = "ID de l'utilisateur") @PathParam("userId") String userId,
@Parameter(description = "Super admin (true/false)") @QueryParam("superAdmin") @NotNull Boolean superAdmin); @Parameter(description = "Super admin (true/false)") @QueryParam("superAdmin") @NotNull Boolean superAdmin);
} }

View File

@@ -1,44 +1,44 @@
package dev.lions.user.manager.api; package dev.lions.user.manager.api;
import jakarta.ws.rs.GET; import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path; import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam; import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces; import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.MediaType;
import org.eclipse.microprofile.openapi.annotations.parameters.Parameter; import org.eclipse.microprofile.openapi.annotations.parameters.Parameter;
import org.eclipse.microprofile.openapi.annotations.Operation; import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.media.Content; import org.eclipse.microprofile.openapi.annotations.media.Content;
import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.eclipse.microprofile.openapi.annotations.media.Schema;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponses; import org.eclipse.microprofile.openapi.annotations.responses.APIResponses;
import org.eclipse.microprofile.openapi.annotations.tags.Tag; import org.eclipse.microprofile.openapi.annotations.tags.Tag;
import java.util.List; import java.util.List;
/** /**
* Interface JAX-RS pour la gestion des realms Keycloak. * Interface JAX-RS pour la gestion des realms Keycloak.
*/ */
@Path("/api/realms") @Path("/api/realms")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@Tag(name = "Realms", description = "Gestion des realms Keycloak") @Tag(name = "Realms", description = "Gestion des realms Keycloak")
public interface RealmResourceApi { public interface RealmResourceApi {
@GET @GET
@Path("/list") @Path("/list")
@Operation(summary = "Lister tous les realms", description = "Récupère la liste de tous les realms disponibles dans Keycloak") @Operation(summary = "Lister tous les realms", description = "Récupère la liste de tous les realms disponibles dans Keycloak")
@APIResponses({ @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 = "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") @APIResponse(responseCode = "500", description = "Erreur serveur")
}) })
List<String> getAllRealms(); List<String> getAllRealms();
@GET @GET
@Path("/{realm}/clients") @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") @Operation(summary = "Lister les clients d'un realm", description = "Récupère la liste des clientId de tous les clients d'un realm")
@APIResponses({ @APIResponses({
@APIResponse(responseCode = "200", description = "Liste des clients"), @APIResponse(responseCode = "200", description = "Liste des clients"),
@APIResponse(responseCode = "500", description = "Erreur serveur") @APIResponse(responseCode = "500", description = "Erreur serveur")
}) })
List<String> getRealmClients( List<String> getRealmClients(
@Parameter(description = "Nom du realm") @PathParam("realm") String realmName); @Parameter(description = "Nom du realm") @PathParam("realm") String realmName);
} }

View File

@@ -1,163 +1,163 @@
package dev.lions.user.manager.api; package dev.lions.user.manager.api;
import dev.lions.user.manager.dto.role.RoleAssignmentRequestDTO; import dev.lions.user.manager.dto.role.RoleAssignmentRequestDTO;
import dev.lions.user.manager.dto.role.RoleDTO; import dev.lions.user.manager.dto.role.RoleDTO;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.*; import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response;
import org.eclipse.microprofile.openapi.annotations.Operation; import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.media.Content; import org.eclipse.microprofile.openapi.annotations.media.Content;
import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.eclipse.microprofile.openapi.annotations.media.Schema;
import org.eclipse.microprofile.openapi.annotations.parameters.Parameter; import org.eclipse.microprofile.openapi.annotations.parameters.Parameter;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponses; import org.eclipse.microprofile.openapi.annotations.responses.APIResponses;
import org.eclipse.microprofile.openapi.annotations.tags.Tag; import org.eclipse.microprofile.openapi.annotations.tags.Tag;
import java.util.List; import java.util.List;
/** /**
* Interface JAX-RS pour la gestion des rôles Keycloak. * Interface JAX-RS pour la gestion des rôles Keycloak.
*/ */
@Path("/api/roles") @Path("/api/roles")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@Tag(name = "Roles", description = "Gestion des rôles Keycloak (realm et client)") @Tag(name = "Roles", description = "Gestion des rôles Keycloak (realm et client)")
public interface RoleResourceApi { public interface RoleResourceApi {
// ==================== Endpoints Realm Roles ==================== // ==================== Endpoints Realm Roles ====================
@POST @POST
@Path("/realm") @Path("/realm")
@Operation(summary = "Créer un rôle realm", description = "Crée un nouveau rôle au niveau du realm") @Operation(summary = "Créer un rôle realm", description = "Crée un nouveau rôle au niveau du realm")
@APIResponses({ @APIResponses({
@APIResponse(responseCode = "201", description = "Rôle créé", content = @Content(schema = @Schema(implementation = RoleDTO.class))) @APIResponse(responseCode = "201", description = "Rôle créé", content = @Content(schema = @Schema(implementation = RoleDTO.class)))
}) })
Response createRealmRole( Response createRealmRole(
@Valid @NotNull RoleDTO roleDTO, @Valid @NotNull RoleDTO roleDTO,
@Parameter(description = "Nom du realm") @QueryParam("realm") String realmName); @Parameter(description = "Nom du realm") @QueryParam("realm") String realmName);
@GET @GET
@Path("/realm/{roleName}") @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") @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( RoleDTO getRealmRole(
@Parameter(description = "Nom du rôle") @PathParam("roleName") String roleName, @Parameter(description = "Nom du rôle") @PathParam("roleName") String roleName,
@Parameter(description = "Nom du realm") @QueryParam("realm") String realmName); @Parameter(description = "Nom du realm") @QueryParam("realm") String realmName);
@GET @GET
@Path("/realm") @Path("/realm")
@Operation(summary = "Lister tous les rôles realm", description = "Liste tous les rôles du realm") @Operation(summary = "Lister tous les rôles realm", description = "Liste tous les rôles du realm")
List<RoleDTO> getAllRealmRoles( List<RoleDTO> getAllRealmRoles(
@Parameter(description = "Nom du realm") @QueryParam("realm") String realmName); @Parameter(description = "Nom du realm") @QueryParam("realm") String realmName);
@PUT @PUT
@Path("/realm/{roleName}") @Path("/realm/{roleName}")
@Operation(summary = "Mettre à jour un rôle realm", description = "Met à jour les informations d'un rôle realm") @Operation(summary = "Mettre à jour un rôle realm", description = "Met à jour les informations d'un rôle realm")
RoleDTO updateRealmRole( RoleDTO updateRealmRole(
@PathParam("roleName") String roleName, @PathParam("roleName") String roleName,
@Valid @NotNull RoleDTO roleDTO, @Valid @NotNull RoleDTO roleDTO,
@QueryParam("realm") String realmName); @QueryParam("realm") String realmName);
@DELETE @DELETE
@Path("/realm/{roleName}") @Path("/realm/{roleName}")
@Operation(summary = "Supprimer un rôle realm", description = "Supprime un rôle realm") @Operation(summary = "Supprimer un rôle realm", description = "Supprime un rôle realm")
void deleteRealmRole( void deleteRealmRole(
@PathParam("roleName") String roleName, @PathParam("roleName") String roleName,
@QueryParam("realm") String realmName); @QueryParam("realm") String realmName);
// ==================== Endpoints Client Roles ==================== // ==================== Endpoints Client Roles ====================
@POST @POST
@Path("/client/{clientId}") @Path("/client/{clientId}")
@Operation(summary = "Créer un rôle client", description = "Crée un nouveau rôle pour un client spécifique") @Operation(summary = "Créer un rôle client", description = "Crée un nouveau rôle pour un client spécifique")
@APIResponses({ @APIResponses({
@APIResponse(responseCode = "201", description = "Rôle créé", content = @Content(schema = @Schema(implementation = RoleDTO.class))) @APIResponse(responseCode = "201", description = "Rôle créé", content = @Content(schema = @Schema(implementation = RoleDTO.class)))
}) })
Response createClientRole( Response createClientRole(
@PathParam("clientId") String clientId, @PathParam("clientId") String clientId,
@Valid @NotNull RoleDTO roleDTO, @Valid @NotNull RoleDTO roleDTO,
@QueryParam("realm") String realmName); @QueryParam("realm") String realmName);
@GET @GET
@Path("/client/{clientId}/{roleName}") @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") @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( RoleDTO getClientRole(
@PathParam("clientId") String clientId, @PathParam("clientId") String clientId,
@PathParam("roleName") String roleName, @PathParam("roleName") String roleName,
@QueryParam("realm") String realmName); @QueryParam("realm") String realmName);
@GET @GET
@Path("/client/{clientId}") @Path("/client/{clientId}")
@Operation(summary = "Lister tous les rôles d'un client", description = "Liste tous les rôles d'un client spécifique") @Operation(summary = "Lister tous les rôles d'un client", description = "Liste tous les rôles d'un client spécifique")
List<RoleDTO> getAllClientRoles( List<RoleDTO> getAllClientRoles(
@PathParam("clientId") String clientId, @PathParam("clientId") String clientId,
@QueryParam("realm") String realmName); @QueryParam("realm") String realmName);
@DELETE @DELETE
@Path("/client/{clientId}/{roleName}") @Path("/client/{clientId}/{roleName}")
@Operation(summary = "Supprimer un rôle client", description = "Supprime un rôle d'un client") @Operation(summary = "Supprimer un rôle client", description = "Supprime un rôle d'un client")
void deleteClientRole( void deleteClientRole(
@PathParam("clientId") String clientId, @PathParam("clientId") String clientId,
@PathParam("roleName") String roleName, @PathParam("roleName") String roleName,
@QueryParam("realm") String realmName); @QueryParam("realm") String realmName);
// ==================== Endpoints Attribution de rôles ==================== // ==================== Endpoints Attribution de rôles ====================
@POST @POST
@Path("/assign/realm/{userId}") @Path("/assign/realm/{userId}")
@Operation(summary = "Attribuer des rôles realm à un utilisateur", description = "Assigne un ou plusieurs rôles realm à un utilisateur") @Operation(summary = "Attribuer des rôles realm à un utilisateur", description = "Assigne un ou plusieurs rôles realm à un utilisateur")
void assignRealmRoles( void assignRealmRoles(
@PathParam("userId") String userId, @PathParam("userId") String userId,
@QueryParam("realm") String realmName, @QueryParam("realm") String realmName,
@NotNull RoleAssignmentRequestDTO request); @NotNull RoleAssignmentRequestDTO request);
@POST @POST
@Path("/revoke/realm/{userId}") @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") @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( void revokeRealmRoles(
@PathParam("userId") String userId, @PathParam("userId") String userId,
@QueryParam("realm") String realmName, @QueryParam("realm") String realmName,
@NotNull RoleAssignmentRequestDTO request); @NotNull RoleAssignmentRequestDTO request);
@POST @POST
@Path("/assign/client/{clientId}/{userId}") @Path("/assign/client/{clientId}/{userId}")
@Operation(summary = "Attribuer des rôles client à un utilisateur", description = "Assigne un ou plusieurs rôles client à un utilisateur") @Operation(summary = "Attribuer des rôles client à un utilisateur", description = "Assigne un ou plusieurs rôles client à un utilisateur")
void assignClientRoles( void assignClientRoles(
@PathParam("clientId") String clientId, @PathParam("clientId") String clientId,
@PathParam("userId") String userId, @PathParam("userId") String userId,
@QueryParam("realm") String realmName, @QueryParam("realm") String realmName,
@NotNull RoleAssignmentRequestDTO request); @NotNull RoleAssignmentRequestDTO request);
@GET @GET
@Path("/user/realm/{userId}") @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") @Operation(summary = "Récupérer les rôles realm d'un utilisateur", description = "Liste tous les rôles realm d'un utilisateur")
List<RoleDTO> getUserRealmRoles( List<RoleDTO> getUserRealmRoles(
@PathParam("userId") String userId, @PathParam("userId") String userId,
@QueryParam("realm") String realmName); @QueryParam("realm") String realmName);
@GET @GET
@Path("/user/client/{clientId}/{userId}") @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") @Operation(summary = "Récupérer les rôles client d'un utilisateur", description = "Liste tous les rôles client d'un utilisateur")
List<RoleDTO> getUserClientRoles( List<RoleDTO> getUserClientRoles(
@PathParam("clientId") String clientId, @PathParam("clientId") String clientId,
@PathParam("userId") String userId, @PathParam("userId") String userId,
@QueryParam("realm") String realmName); @QueryParam("realm") String realmName);
// ==================== Endpoints Rôles composites ==================== // ==================== Endpoints Rôles composites ====================
@POST @POST
@Path("/composite/{roleName}/add") @Path("/composite/{roleName}/add")
@Operation(summary = "Ajouter des rôles composites", description = "Ajoute des rôles composites à un rôle") @Operation(summary = "Ajouter des rôles composites", description = "Ajoute des rôles composites à un rôle")
void addComposites( void addComposites(
@PathParam("roleName") String roleName, @PathParam("roleName") String roleName,
@QueryParam("realm") String realmName, @QueryParam("realm") String realmName,
@NotNull RoleAssignmentRequestDTO request); @NotNull RoleAssignmentRequestDTO request);
@GET @GET
@Path("/composite/{roleName}") @Path("/composite/{roleName}")
@Operation(summary = "Récupérer les rôles composites", description = "Liste tous les rôles composites d'un rôle") @Operation(summary = "Récupérer les rôles composites", description = "Liste tous les rôles composites d'un rôle")
List<RoleDTO> getComposites( List<RoleDTO> getComposites(
@PathParam("roleName") String roleName, @PathParam("roleName") String roleName,
@QueryParam("realm") String realmName); @QueryParam("realm") String realmName);
} }

View File

@@ -1,54 +1,54 @@
package dev.lions.user.manager.api; package dev.lions.user.manager.api;
import dev.lions.user.manager.dto.sync.HealthStatusDTO; import dev.lions.user.manager.dto.sync.HealthStatusDTO;
import dev.lions.user.manager.dto.sync.SyncConsistencyDTO; import dev.lions.user.manager.dto.sync.SyncConsistencyDTO;
import dev.lions.user.manager.dto.sync.SyncHistoryDTO; import dev.lions.user.manager.dto.sync.SyncHistoryDTO;
import dev.lions.user.manager.dto.sync.SyncResultDTO; import dev.lions.user.manager.dto.sync.SyncResultDTO;
import jakarta.ws.rs.*; import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.MediaType;
import org.eclipse.microprofile.openapi.annotations.Operation; import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.tags.Tag; import org.eclipse.microprofile.openapi.annotations.tags.Tag;
/** /**
* Interface JAX-RS définissant le contrat de l'API de synchronisation. * 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 * Cette interface doit être implémentée par le serveur et utilisée par le
* client (via MicroProfile Rest Client). * client (via MicroProfile Rest Client).
*/ */
@Path("/api/sync") @Path("/api/sync")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@Tag(name = "Sync", description = "Synchronisation avec Keycloak et health checks") @Tag(name = "Sync", description = "Synchronisation avec Keycloak et health checks")
public interface SyncResourceApi { public interface SyncResourceApi {
@GET @GET
@Path("/health/keycloak") @Path("/health/keycloak")
@Operation(summary = "Vérifier la santé de Keycloak", description = "Retourne le statut de santé de Keycloak") @Operation(summary = "Vérifier la santé de Keycloak", description = "Retourne le statut de santé de Keycloak")
HealthStatusDTO checkKeycloakHealth(); HealthStatusDTO checkKeycloakHealth();
@POST @POST
@Path("/users") @Path("/users")
@Operation(summary = "Synchroniser les utilisateurs", description = "Synchronise tous les utilisateurs depuis Keycloak") @Operation(summary = "Synchroniser les utilisateurs", description = "Synchronise tous les utilisateurs depuis Keycloak")
SyncResultDTO syncUsers(@QueryParam("realm") String realmName); SyncResultDTO syncUsers(@QueryParam("realm") String realmName);
@POST @POST
@Path("/roles") @Path("/roles")
@Operation(summary = "Synchroniser les rôles", description = "Synchronise les rôles (realm et/ou client)") @Operation(summary = "Synchroniser les rôles", description = "Synchronise les rôles (realm et/ou client)")
SyncResultDTO syncRoles( SyncResultDTO syncRoles(
@QueryParam("realm") String realmName, @QueryParam("realm") String realmName,
@QueryParam("clientName") String clientName); @QueryParam("clientName") String clientName);
@GET @GET
@Path("/consistency") @Path("/consistency")
@Operation(summary = "Vérifier la cohérence des données", description = "Compare le cache local et Keycloak pour un realm") @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); SyncConsistencyDTO checkDataConsistency(@QueryParam("realm") String realmName);
@GET @GET
@Path("/status") @Path("/status")
@Operation(summary = "Statut de la dernière synchro", description = "Retourne le statut de la dernière synchronisation du realm") @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); SyncHistoryDTO getLastSyncStatus(@QueryParam("realm") String realmName);
@POST @POST
@Path("/force") @Path("/force")
@Operation(summary = "Forcer une synchro", description = "Lance une synchronisation complète du realm (users + roles)") @Operation(summary = "Forcer une synchro", description = "Lance une synchronisation complète du realm (users + roles)")
SyncHistoryDTO forceSyncRealm(@QueryParam("realm") String realmName); SyncHistoryDTO forceSyncRealm(@QueryParam("realm") String realmName);
} }

View File

@@ -1,32 +1,32 @@
package dev.lions.user.manager.api; package dev.lions.user.manager.api;
import dev.lions.user.manager.dto.common.UserSessionStatsDTO; import dev.lions.user.manager.dto.common.UserSessionStatsDTO;
import jakarta.ws.rs.GET; import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path; import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces; import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam; import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.MediaType;
import org.eclipse.microprofile.openapi.annotations.Operation; import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponses; import org.eclipse.microprofile.openapi.annotations.responses.APIResponses;
import org.eclipse.microprofile.openapi.annotations.tags.Tag; import org.eclipse.microprofile.openapi.annotations.tags.Tag;
/** /**
* API de métriques liées aux utilisateurs (sessions, utilisateurs en ligne, etc.). * API de métriques liées aux utilisateurs (sessions, utilisateurs en ligne, etc.).
*/ */
@Path("/api/metrics/users") @Path("/api/metrics/users")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@Tag(name = "User Metrics", description = "Statistiques sur les utilisateurs et leurs sessions") @Tag(name = "User Metrics", description = "Statistiques sur les utilisateurs et leurs sessions")
public interface UserMetricsResourceApi { public interface UserMetricsResourceApi {
@GET @GET
@Path("/sessions") @Path("/sessions")
@Operation(summary = "Statistiques de sessions utilisateurs", @Operation(summary = "Statistiques de sessions utilisateurs",
description = "Retourne des statistiques agrégées sur les utilisateurs et leurs sessions pour un realm") description = "Retourne des statistiques agrégées sur les utilisateurs et leurs sessions pour un realm")
@APIResponses({ @APIResponses({
@APIResponse(responseCode = "200", description = "Statistiques retournées avec succès"), @APIResponse(responseCode = "200", description = "Statistiques retournées avec succès"),
@APIResponse(responseCode = "500", description = "Erreur serveur") @APIResponse(responseCode = "500", description = "Erreur serveur")
}) })
UserSessionStatsDTO getUserSessionStats(@QueryParam("realm") String realmName); UserSessionStatsDTO getUserSessionStats(@QueryParam("realm") String realmName);
} }

View File

@@ -1,138 +1,138 @@
package dev.lions.user.manager.api; package dev.lions.user.manager.api;
import dev.lions.user.manager.dto.importexport.ImportResultDTO; import dev.lions.user.manager.dto.importexport.ImportResultDTO;
import dev.lions.user.manager.dto.user.*; import dev.lions.user.manager.dto.user.*;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.*; import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response;
import org.eclipse.microprofile.openapi.annotations.Operation; import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.media.Content; import org.eclipse.microprofile.openapi.annotations.media.Content;
import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.eclipse.microprofile.openapi.annotations.media.Schema;
import org.eclipse.microprofile.openapi.annotations.parameters.Parameter; import org.eclipse.microprofile.openapi.annotations.parameters.Parameter;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponses; import org.eclipse.microprofile.openapi.annotations.responses.APIResponses;
import org.eclipse.microprofile.openapi.annotations.tags.Tag; import org.eclipse.microprofile.openapi.annotations.tags.Tag;
import java.util.List; import java.util.List;
/** /**
* Interface JAX-RS pour la gestion des utilisateurs. * Interface JAX-RS pour la gestion des utilisateurs.
*/ */
@Path("/api/users") @Path("/api/users")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@Tag(name = "Users", description = "Gestion des utilisateurs Keycloak") @Tag(name = "Users", description = "Gestion des utilisateurs Keycloak")
public interface UserResourceApi { public interface UserResourceApi {
@POST @POST
@Path("/search") @Path("/search")
@Operation(summary = "Rechercher des utilisateurs", description = "Recherche d'utilisateurs selon des critères") @Operation(summary = "Rechercher des utilisateurs", description = "Recherche d'utilisateurs selon des critères")
UserSearchResultDTO searchUsers(@Valid @NotNull UserSearchCriteriaDTO criteria); UserSearchResultDTO searchUsers(@Valid @NotNull UserSearchCriteriaDTO criteria);
@GET @GET
@Path("/{userId}") @Path("/{userId}")
@Operation(summary = "Récupérer un utilisateur par ID", description = "Récupère les détails d'un utilisateur") @Operation(summary = "Récupérer un utilisateur par ID", description = "Récupère les détails d'un utilisateur")
UserDTO getUserById( UserDTO getUserById(
@Parameter(description = "ID de l'utilisateur") @PathParam("userId") String userId, @Parameter(description = "ID de l'utilisateur") @PathParam("userId") String userId,
@Parameter(description = "Nom du realm") @QueryParam("realm") String realmName); @Parameter(description = "Nom du realm") @QueryParam("realm") String realmName);
@GET @GET
@Operation(summary = "Lister tous les utilisateurs", description = "Liste paginée de tous les utilisateurs") @Operation(summary = "Lister tous les utilisateurs", description = "Liste paginée de tous les utilisateurs")
UserSearchResultDTO getAllUsers( UserSearchResultDTO getAllUsers(
@QueryParam("realm") String realmName, @QueryParam("realm") String realmName,
@QueryParam("page") @DefaultValue("0") int page, @QueryParam("page") @DefaultValue("0") int page,
@QueryParam("pageSize") @DefaultValue("20") int pageSize); @QueryParam("pageSize") @DefaultValue("20") int pageSize);
@POST @POST
@Operation(summary = "Créer un utilisateur", description = "Crée un nouvel utilisateur dans Keycloak") @Operation(summary = "Créer un utilisateur", description = "Crée un nouvel utilisateur dans Keycloak")
@APIResponses({ @APIResponses({
@APIResponse(responseCode = "201", description = "Utilisateur créé", content = @Content(schema = @Schema(implementation = UserDTO.class))) @APIResponse(responseCode = "201", description = "Utilisateur créé", content = @Content(schema = @Schema(implementation = UserDTO.class)))
}) })
Response createUser( Response createUser(
@Valid @NotNull UserDTO user, @Valid @NotNull UserDTO user,
@QueryParam("realm") String realmName); @QueryParam("realm") String realmName);
@PUT @PUT
@Path("/{userId}") @Path("/{userId}")
@Operation(summary = "Mettre à jour un utilisateur", description = "Met à jour les informations d'un utilisateur") @Operation(summary = "Mettre à jour un utilisateur", description = "Met à jour les informations d'un utilisateur")
UserDTO updateUser( UserDTO updateUser(
@PathParam("userId") String userId, @PathParam("userId") String userId,
@Valid @NotNull UserDTO user, @Valid @NotNull UserDTO user,
@QueryParam("realm") String realmName); @QueryParam("realm") String realmName);
@DELETE @DELETE
@Path("/{userId}") @Path("/{userId}")
@Operation(summary = "Supprimer un utilisateur", description = "Supprime un utilisateur (soft ou hard delete)") @Operation(summary = "Supprimer un utilisateur", description = "Supprime un utilisateur (soft ou hard delete)")
void deleteUser( void deleteUser(
@PathParam("userId") String userId, @PathParam("userId") String userId,
@QueryParam("realm") String realmName, @QueryParam("realm") String realmName,
@QueryParam("hardDelete") @DefaultValue("false") boolean hardDelete); @QueryParam("hardDelete") @DefaultValue("false") boolean hardDelete);
@POST @POST
@Path("/{userId}/activate") @Path("/{userId}/activate")
@Operation(summary = "Activer un utilisateur", description = "Active un utilisateur désactivé") @Operation(summary = "Activer un utilisateur", description = "Active un utilisateur désactivé")
void activateUser( void activateUser(
@PathParam("userId") String userId, @PathParam("userId") String userId,
@QueryParam("realm") String realmName); @QueryParam("realm") String realmName);
@POST @POST
@Path("/{userId}/deactivate") @Path("/{userId}/deactivate")
@Operation(summary = "Désactiver un utilisateur", description = "Désactive un utilisateur") @Operation(summary = "Désactiver un utilisateur", description = "Désactive un utilisateur")
void deactivateUser( void deactivateUser(
@PathParam("userId") String userId, @PathParam("userId") String userId,
@QueryParam("realm") String realmName, @QueryParam("realm") String realmName,
@QueryParam("raison") String raison); @QueryParam("raison") String raison);
@POST @POST
@Path("/{userId}/reset-password") @Path("/{userId}/reset-password")
@Operation(summary = "Réinitialiser le mot de passe", description = "Définit un nouveau mot de passe pour l'utilisateur") @Operation(summary = "Réinitialiser le mot de passe", description = "Définit un nouveau mot de passe pour l'utilisateur")
void resetPassword( void resetPassword(
@PathParam("userId") String userId, @PathParam("userId") String userId,
@QueryParam("realm") String realmName, @QueryParam("realm") String realmName,
@NotNull PasswordResetRequestDTO request); @NotNull PasswordResetRequestDTO request);
@POST @POST
@Path("/{userId}/send-verification-email") @Path("/{userId}/send-verification-email")
@Operation(summary = "Envoyer email de vérification", description = "Envoie un email de vérification à l'utilisateur") @Operation(summary = "Envoyer email de vérification", description = "Envoie un email de vérification à l'utilisateur")
@APIResponses({ @APIResponses({
@APIResponse(responseCode = "202", description = "Demande acceptée (email envoyé ou tentative effectuée)"), @APIResponse(responseCode = "202", description = "Demande acceptée (email envoyé ou tentative effectuée)"),
@APIResponse(responseCode = "404", description = "Utilisateur non trouvé") @APIResponse(responseCode = "404", description = "Utilisateur non trouvé")
}) })
Response sendVerificationEmail( Response sendVerificationEmail(
@PathParam("userId") String userId, @PathParam("userId") String userId,
@QueryParam("realm") String realmName); @QueryParam("realm") String realmName);
@POST @POST
@Path("/{userId}/logout-sessions") @Path("/{userId}/logout-sessions")
@Operation(summary = "Déconnecter toutes les sessions", description = "Révoque toutes les sessions actives de l'utilisateur") @Operation(summary = "Déconnecter toutes les sessions", description = "Révoque toutes les sessions actives de l'utilisateur")
SessionsRevokedDTO logoutAllSessions( SessionsRevokedDTO logoutAllSessions(
@PathParam("userId") String userId, @PathParam("userId") String userId,
@QueryParam("realm") String realmName); @QueryParam("realm") String realmName);
@GET @GET
@Path("/{userId}/sessions") @Path("/{userId}/sessions")
@Operation(summary = "Récupérer les sessions actives", description = "Liste les sessions actives de l'utilisateur") @Operation(summary = "Récupérer les sessions actives", description = "Liste les sessions actives de l'utilisateur")
@APIResponses({ @APIResponses({
@APIResponse(responseCode = "200", description = "Liste des sessions", content = @Content(schema = @Schema(type = org.eclipse.microprofile.openapi.annotations.enums.SchemaType.ARRAY, implementation = String.class))) @APIResponse(responseCode = "200", description = "Liste des sessions", content = @Content(schema = @Schema(type = org.eclipse.microprofile.openapi.annotations.enums.SchemaType.ARRAY, implementation = String.class)))
}) })
List<String> getActiveSessions( List<String> getActiveSessions(
@PathParam("userId") String userId, @PathParam("userId") String userId,
@QueryParam("realm") String realmName); @QueryParam("realm") String realmName);
@GET @GET
@Path("/export/csv") @Path("/export/csv")
@Produces("text/csv") @Produces("text/csv")
@Operation(summary = "Exporter les utilisateurs en CSV", description = "Exporte la liste des utilisateurs du realm au format 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); Response exportUsersToCSV(@QueryParam("realm") String realmName);
@POST @POST
@Path("/import/csv") @Path("/import/csv")
@Consumes(MediaType.TEXT_PLAIN) @Consumes(MediaType.TEXT_PLAIN)
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@Operation(summary = "Importer des utilisateurs depuis un CSV", description = "Importe des utilisateurs à partir d'un fichier CSV") @Operation(summary = "Importer des utilisateurs depuis un CSV", description = "Importe des utilisateurs à partir d'un fichier CSV")
ImportResultDTO importUsersFromCSV( ImportResultDTO importUsersFromCSV(
@QueryParam("realm") String realmName, @QueryParam("realm") String realmName,
String csvContent); String csvContent);
} }

View File

@@ -1,178 +1,178 @@
package dev.lions.user.manager.dto.audit; package dev.lions.user.manager.dto.audit;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import dev.lions.user.manager.dto.base.BaseDTO; import dev.lions.user.manager.dto.base.BaseDTO;
import dev.lions.user.manager.enums.audit.TypeActionAudit; import dev.lions.user.manager.enums.audit.TypeActionAudit;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder; import lombok.experimental.SuperBuilder;
import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.eclipse.microprofile.openapi.annotations.media.Schema;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Map; import java.util.Map;
/** /**
* DTO représentant une entrée d'audit * DTO représentant une entrée d'audit
* Enregistre toutes les actions effectuées via l'API de gestion * Enregistre toutes les actions effectuées via l'API de gestion
*/ */
@Data @Data
@SuperBuilder @SuperBuilder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
@Schema(description = "Entrée d'audit des actions utilisateur") @Schema(description = "Entrée d'audit des actions utilisateur")
public class AuditLogDTO extends BaseDTO { public class AuditLogDTO extends BaseDTO {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
// Qui a fait l'action // Qui a fait l'action
@Schema(description = "ID de l'utilisateur qui a effectué l'action", example = "f47ac10b-58cc-4372-a567-0e02b2c3d479") @Schema(description = "ID de l'utilisateur qui a effectué l'action", example = "f47ac10b-58cc-4372-a567-0e02b2c3d479")
private String acteurUserId; private String acteurUserId;
@Schema(description = "Username de l'utilisateur qui a effectué l'action", example = "admin@lions.dev") @Schema(description = "Username de l'utilisateur qui a effectué l'action", example = "admin@lions.dev")
private String acteurUsername; private String acteurUsername;
@Schema(description = "Nom complet de l'acteur", example = "Admin Principal") @Schema(description = "Nom complet de l'acteur", example = "Admin Principal")
private String acteurNomComplet; private String acteurNomComplet;
@Schema(description = "Rôles de l'acteur au moment de l'action") @Schema(description = "Rôles de l'acteur au moment de l'action")
private String acteurRoles; private String acteurRoles;
// Quand // Quand
@Schema(description = "Date et heure de l'action", example = "2025-01-15T10:30:00") @Schema(description = "Date et heure de l'action", example = "2025-01-15T10:30:00")
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
private LocalDateTime dateAction; private LocalDateTime dateAction;
// Quoi // Quoi
@Schema(description = "Type d'action effectuée", example = "USER_CREATE") @Schema(description = "Type d'action effectuée", example = "USER_CREATE")
private TypeActionAudit typeAction; private TypeActionAudit typeAction;
@Schema(description = "Type de ressource affectée", example = "USER") @Schema(description = "Type de ressource affectée", example = "USER")
private String ressourceType; private String ressourceType;
@Schema(description = "ID de la ressource affectée", example = "a1b2c3d4-e5f6-7890-1234-567890abcdef") @Schema(description = "ID de la ressource affectée", example = "a1b2c3d4-e5f6-7890-1234-567890abcdef")
private String ressourceId; private String ressourceId;
@Schema(description = "Nom/Identifiant de la ressource", example = "jdupont") @Schema(description = "Nom/Identifiant de la ressource", example = "jdupont")
private String ressourceName; private String ressourceName;
// Où // Où
@Schema(description = "Nom du Realm", example = "btpxpress") @Schema(description = "Nom du Realm", example = "btpxpress")
private String realmName; private String realmName;
@Schema(description = "Adresse IP de l'acteur", example = "192.168.1.100") @Schema(description = "Adresse IP de l'acteur", example = "192.168.1.100")
private String ipAddress; private String ipAddress;
@Schema(description = "User-Agent du client", example = "Mozilla/5.0...") @Schema(description = "User-Agent du client", example = "Mozilla/5.0...")
private String userAgent; private String userAgent;
@Schema(description = "Localisation géographique", example = "Abidjan, Côte d'Ivoire") @Schema(description = "Localisation géographique", example = "Abidjan, Côte d'Ivoire")
private String geolocation; private String geolocation;
// Comment // Comment
@Schema(description = "Endpoint API appelé", example = "/api/users/create") @Schema(description = "Endpoint API appelé", example = "/api/users/create")
private String apiEndpoint; private String apiEndpoint;
@Schema(description = "Méthode HTTP", example = "POST") @Schema(description = "Méthode HTTP", example = "POST")
private String httpMethod; private String httpMethod;
// Détails // Détails
@Schema(description = "Description de l'action", example = "Création d'un nouvel utilisateur") @Schema(description = "Description de l'action", example = "Création d'un nouvel utilisateur")
private String description; private String description;
@Schema(description = "Détails de l'action au format JSON") @Schema(description = "Détails de l'action au format JSON")
private String detailsJson; private String detailsJson;
@Schema(description = "Ancienne valeur (avant modification)") @Schema(description = "Ancienne valeur (avant modification)")
private String oldValue; private String oldValue;
@Schema(description = "Nouvelle valeur (après modification)") @Schema(description = "Nouvelle valeur (après modification)")
private String newValue; private String newValue;
@Schema(description = "Différences entre ancienne et nouvelle valeur") @Schema(description = "Différences entre ancienne et nouvelle valeur")
private String diff; private String diff;
// Résultat // Résultat
@Schema(description = "Succès de l'opération", example = "true") @Schema(description = "Succès de l'opération", example = "true")
private Boolean success; private Boolean success;
@Schema(description = "Code d'erreur (si échec)", example = "USER_ALREADY_EXISTS") @Schema(description = "Code d'erreur (si échec)", example = "USER_ALREADY_EXISTS")
private String errorCode; private String errorCode;
@Schema(description = "Message d'erreur (si échec)") @Schema(description = "Message d'erreur (si échec)")
private String errorMessage; private String errorMessage;
@Schema(description = "Trace d'erreur complète (si échec)") @Schema(description = "Trace d'erreur complète (si échec)")
private String stackTrace; private String stackTrace;
// Métadonnées // Métadonnées
@Schema(description = "Durée d'exécution en millisecondes", example = "145") @Schema(description = "Durée d'exécution en millisecondes", example = "145")
private Long executionTimeMs; private Long executionTimeMs;
@Schema(description = "ID de session/transaction", example = "sess_abc123") @Schema(description = "ID de session/transaction", example = "sess_abc123")
private String sessionId; private String sessionId;
@Schema(description = "ID de corrélation (pour tracer requêtes liées)", example = "corr_xyz789") @Schema(description = "ID de corrélation (pour tracer requêtes liées)", example = "corr_xyz789")
private String correlationId; private String correlationId;
@Schema(description = "Raison de l'action", example = "Demande du manager") @Schema(description = "Raison de l'action", example = "Demande du manager")
private String raison; private String raison;
@Schema(description = "Commentaires administratifs", example = "Promotion suite à évaluation annuelle") @Schema(description = "Commentaires administratifs", example = "Promotion suite à évaluation annuelle")
private String commentaires; private String commentaires;
@Schema(description = "Métadonnées supplémentaires") @Schema(description = "Métadonnées supplémentaires")
private Map<String, String> metadata; private Map<String, String> metadata;
// Flags // Flags
@Schema(description = "Indique si l'action est critique", example = "false") @Schema(description = "Indique si l'action est critique", example = "false")
private Boolean critique; private Boolean critique;
@Schema(description = "Indique si l'action nécessite une alerte", example = "false") @Schema(description = "Indique si l'action nécessite une alerte", example = "false")
private Boolean requiresAlert; private Boolean requiresAlert;
@Schema(description = "Indique si l'action a été notifiée", example = "true") @Schema(description = "Indique si l'action a été notifiée", example = "true")
private Boolean notified; private Boolean notified;
/** /**
* Détermine si l'action a réussi * Détermine si l'action a réussi
* @return true si success = true * @return true si success = true
*/ */
public boolean isSuccessful() { public boolean isSuccessful() {
return Boolean.TRUE.equals(success); return Boolean.TRUE.equals(success);
} }
/** /**
* Détermine si l'action a échoué * Détermine si l'action a échoué
* @return true si success = false * @return true si success = false
*/ */
public boolean isFailed() { public boolean isFailed() {
return Boolean.FALSE.equals(success); return Boolean.FALSE.equals(success);
} }
/** /**
* Détermine si l'action est critique * Détermine si l'action est critique
* @return true si critique = true ou si typeAction est critique * @return true si critique = true ou si typeAction est critique
*/ */
public boolean isCritique() { public boolean isCritique() {
return Boolean.TRUE.equals(critique) || (typeAction != null && typeAction.isCritical()); return Boolean.TRUE.equals(critique) || (typeAction != null && typeAction.isCritical());
} }
/** /**
* Retourne un résumé court de l'action * Retourne un résumé court de l'action
* @return résumé * @return résumé
*/ */
public String getSummary() { public String getSummary() {
return String.format("%s: %s effectué par %s sur %s %s", return String.format("%s: %s effectué par %s sur %s %s",
dateAction, dateAction,
typeAction != null ? typeAction.getLibelle() : "Action inconnue", typeAction != null ? typeAction.getLibelle() : "Action inconnue",
acteurUsername != null ? acteurUsername : "Inconnu", acteurUsername != null ? acteurUsername : "Inconnu",
ressourceType != null ? ressourceType : "Ressource", ressourceType != null ? ressourceType : "Ressource",
ressourceName != null ? ressourceName : ressourceId ressourceName != null ? ressourceName : ressourceId
); );
} }
} }

View File

@@ -1,47 +1,47 @@
package dev.lions.user.manager.dto.base; package dev.lions.user.manager.dto.base;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder; import lombok.experimental.SuperBuilder;
import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.eclipse.microprofile.openapi.annotations.media.Schema;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDateTime; import java.time.LocalDateTime;
/** /**
* DTO de base pour tous les objets métier * DTO de base pour tous les objets métier
* Contient les attributs communs (id, dates, audit) * Contient les attributs communs (id, dates, audit)
*/ */
@Data @Data
@SuperBuilder @SuperBuilder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
@Schema(description = "DTO de base contenant les attributs communs à tous les objets") @Schema(description = "DTO de base contenant les attributs communs à tous les objets")
public abstract class BaseDTO implements Serializable { public abstract class BaseDTO implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Schema(description = "Identifiant unique (UUID Keycloak)", example = "f47ac10b-58cc-4372-a567-0e02b2c3d479") @Schema(description = "Identifiant unique (UUID Keycloak)", example = "f47ac10b-58cc-4372-a567-0e02b2c3d479")
private String id; private String id;
@Schema(description = "Date de création", example = "2025-01-15T10:30:00") @Schema(description = "Date de création", example = "2025-01-15T10:30:00")
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
private LocalDateTime dateCreation; private LocalDateTime dateCreation;
@Schema(description = "Date de dernière modification", example = "2025-01-15T14:20:00") @Schema(description = "Date de dernière modification", example = "2025-01-15T14:20:00")
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
private LocalDateTime dateModification; private LocalDateTime dateModification;
@Schema(description = "Utilisateur ayant créé l'entité", example = "admin@lions.dev") @Schema(description = "Utilisateur ayant créé l'entité", example = "admin@lions.dev")
private String creeParUsername; private String creeParUsername;
@Schema(description = "Utilisateur ayant modifié l'entité", example = "superadmin@lions.dev") @Schema(description = "Utilisateur ayant modifié l'entité", example = "superadmin@lions.dev")
private String modifieParUsername; private String modifieParUsername;
@Schema(description = "Numéro de version pour gestion optimiste", example = "1") @Schema(description = "Numéro de version pour gestion optimiste", example = "1")
private Long version; private Long version;
} }

View File

@@ -1,21 +1,21 @@
package dev.lions.user.manager.dto.common; package dev.lions.user.manager.dto.common;
import io.quarkus.runtime.annotations.RegisterForReflection; import io.quarkus.runtime.annotations.RegisterForReflection;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.eclipse.microprofile.openapi.annotations.media.Schema;
import java.io.Serializable; import java.io.Serializable;
@Data @Data
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@RegisterForReflection @RegisterForReflection
@Schema(description = "Réponse d'erreur standard") @Schema(description = "Réponse d'erreur standard")
public class ApiErrorDTO implements Serializable { public class ApiErrorDTO implements Serializable {
@Schema(description = "Message d'erreur") @Schema(description = "Message d'erreur")
private String message; private String message;
} }

View File

@@ -1,21 +1,21 @@
package dev.lions.user.manager.dto.common; package dev.lions.user.manager.dto.common;
import io.quarkus.runtime.annotations.RegisterForReflection; import io.quarkus.runtime.annotations.RegisterForReflection;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.eclipse.microprofile.openapi.annotations.media.Schema;
import java.io.Serializable; import java.io.Serializable;
@Data @Data
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@RegisterForReflection @RegisterForReflection
@Schema(description = "Réponse de comptage générique") @Schema(description = "Réponse de comptage générique")
public class CountDTO implements Serializable { public class CountDTO implements Serializable {
@Schema(description = "Nombre d'éléments") @Schema(description = "Nombre d'éléments")
private long count; private long count;
} }

View File

@@ -1,32 +1,32 @@
package dev.lions.user.manager.dto.common; package dev.lions.user.manager.dto.common;
import io.quarkus.runtime.annotations.RegisterForReflection; import io.quarkus.runtime.annotations.RegisterForReflection;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.eclipse.microprofile.openapi.annotations.media.Schema;
import java.io.Serializable; import java.io.Serializable;
@Data @Data
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@RegisterForReflection @RegisterForReflection
@Schema(description = "Statistiques de sessions et d'utilisateurs en ligne pour un realm") @Schema(description = "Statistiques de sessions et d'utilisateurs en ligne pour un realm")
public class UserSessionStatsDTO implements Serializable { public class UserSessionStatsDTO implements Serializable {
@Schema(description = "Nom du realm concerné") @Schema(description = "Nom du realm concerné")
private String realmName; private String realmName;
@Schema(description = "Nombre total d'utilisateurs dans le realm") @Schema(description = "Nombre total d'utilisateurs dans le realm")
private long totalUsers; private long totalUsers;
@Schema(description = "Nombre total de sessions actives (approximation)") @Schema(description = "Nombre total de sessions actives (approximation)")
private long activeSessions; private long activeSessions;
@Schema(description = "Nombre d'utilisateurs considérés comme en ligne (approximation)") @Schema(description = "Nombre d'utilisateurs considérés comme en ligne (approximation)")
private long onlineUsers; private long onlineUsers;
} }

View File

@@ -1,123 +1,123 @@
package dev.lions.user.manager.dto.importexport; package dev.lions.user.manager.dto.importexport;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.eclipse.microprofile.openapi.annotations.media.Schema;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
* DTO représentant le résultat d'un import CSV d'utilisateurs * DTO représentant le résultat d'un import CSV d'utilisateurs
* Contient les statistiques et le détail des erreurs rencontrées * Contient les statistiques et le détail des erreurs rencontrées
* *
* @author Lions Development Team * @author Lions Development Team
* @version 1.0.0 * @version 1.0.0
* @since 2026-01-02 * @since 2026-01-02
*/ */
@Data @Data
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
@Schema(description = "Résultat d'un import CSV d'utilisateurs") @Schema(description = "Résultat d'un import CSV d'utilisateurs")
public class ImportResultDTO implements Serializable { public class ImportResultDTO implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Schema(description = "Nombre total de lignes traitées", example = "100") @Schema(description = "Nombre total de lignes traitées", example = "100")
private int totalLines; private int totalLines;
@Schema(description = "Nombre d'utilisateurs créés avec succès", example = "95") @Schema(description = "Nombre d'utilisateurs créés avec succès", example = "95")
private int successCount; private int successCount;
@Schema(description = "Nombre d'erreurs rencontrées", example = "5") @Schema(description = "Nombre d'erreurs rencontrées", example = "5")
private int errorCount; private int errorCount;
@Schema(description = "Message de statut global", example = "Import terminé: 95 utilisateurs créés, 5 erreurs") @Schema(description = "Message de statut global", example = "Import terminé: 95 utilisateurs créés, 5 erreurs")
private String message; private String message;
@Schema(description = "Liste des erreurs détaillées") @Schema(description = "Liste des erreurs détaillées")
@Builder.Default @Builder.Default
private List<ImportErrorDTO> errors = new ArrayList<>(); private List<ImportErrorDTO> errors = new ArrayList<>();
/** /**
* Ajoute une erreur au rapport * Ajoute une erreur au rapport
*/ */
public void addError(ImportErrorDTO error) { public void addError(ImportErrorDTO error) {
if (errors == null) { if (errors == null) {
errors = new ArrayList<>(); errors = new ArrayList<>();
} }
errors.add(error); errors.add(error);
errorCount = errors.size(); errorCount = errors.size();
} }
/** /**
* Génère le message de statut * Génère le message de statut
*/ */
public void generateMessage() { public void generateMessage() {
if (errorCount == 0) { if (errorCount == 0) {
message = String.format("✅ Import réussi: %d utilisateur(s) créé(s)", successCount); message = String.format("✅ Import réussi: %d utilisateur(s) créé(s)", successCount);
} else { } else {
message = String.format("⚠️ Import terminé avec erreurs: %d utilisateur(s) créé(s), %d erreur(s)", message = String.format("⚠️ Import terminé avec erreurs: %d utilisateur(s) créé(s), %d erreur(s)",
successCount, errorCount); successCount, errorCount);
} }
} }
/** /**
* DTO représentant une erreur d'import sur une ligne * DTO représentant une erreur d'import sur une ligne
*/ */
@Data @Data
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
@Schema(description = "Détail d'une erreur d'import") @Schema(description = "Détail d'une erreur d'import")
public static class ImportErrorDTO implements Serializable { public static class ImportErrorDTO implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Schema(description = "Numéro de ligne (1-indexed)", example = "42") @Schema(description = "Numéro de ligne (1-indexed)", example = "42")
private int lineNumber; private int lineNumber;
@Schema(description = "Contenu de la ligne en erreur", example = "john.doe,invalid-email,John,Doe,true") @Schema(description = "Contenu de la ligne en erreur", example = "john.doe,invalid-email,John,Doe,true")
private String lineContent; private String lineContent;
@Schema(description = "Type d'erreur", example = "VALIDATION_ERROR") @Schema(description = "Type d'erreur", example = "VALIDATION_ERROR")
private ErrorType errorType; private ErrorType errorType;
@Schema(description = "Champ concerné par l'erreur", example = "email") @Schema(description = "Champ concerné par l'erreur", example = "email")
private String field; private String field;
@Schema(description = "Message d'erreur descriptif", example = "Format d'email invalide") @Schema(description = "Message d'erreur descriptif", example = "Format d'email invalide")
private String message; private String message;
@Schema(description = "Détails techniques de l'erreur") @Schema(description = "Détails techniques de l'erreur")
private String details; private String details;
} }
/** /**
* Types d'erreurs possibles lors de l'import * Types d'erreurs possibles lors de l'import
*/ */
@Schema(description = "Type d'erreur d'import") @Schema(description = "Type d'erreur d'import")
public enum ErrorType { public enum ErrorType {
@Schema(description = "Ligne mal formée ou nombre de colonnes incorrect") @Schema(description = "Ligne mal formée ou nombre de colonnes incorrect")
INVALID_FORMAT, INVALID_FORMAT,
@Schema(description = "Erreur de validation des données") @Schema(description = "Erreur de validation des données")
VALIDATION_ERROR, VALIDATION_ERROR,
@Schema(description = "Utilisateur déjà existant") @Schema(description = "Utilisateur déjà existant")
DUPLICATE_USER, DUPLICATE_USER,
@Schema(description = "Erreur lors de la création de l'utilisateur") @Schema(description = "Erreur lors de la création de l'utilisateur")
CREATION_ERROR, CREATION_ERROR,
@Schema(description = "Erreur interne du système") @Schema(description = "Erreur interne du système")
SYSTEM_ERROR SYSTEM_ERROR
} }
} }

View File

@@ -1,25 +1,25 @@
package dev.lions.user.manager.dto.realm; package dev.lions.user.manager.dto.realm;
import io.quarkus.runtime.annotations.RegisterForReflection; import io.quarkus.runtime.annotations.RegisterForReflection;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.eclipse.microprofile.openapi.annotations.media.Schema;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;
@Data @Data
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@RegisterForReflection @RegisterForReflection
@Schema(description = "Liste des realms autorisés pour un utilisateur") @Schema(description = "Liste des realms autorisés pour un utilisateur")
public class AuthorizedRealmsDTO implements Serializable { public class AuthorizedRealmsDTO implements Serializable {
@Schema(description = "Liste des realms (peut être vide si super admin)") @Schema(description = "Liste des realms (peut être vide si super admin)")
private List<String> realms; private List<String> realms;
@Schema(description = "L'utilisateur est super admin") @Schema(description = "L'utilisateur est super admin")
private boolean isSuperAdmin; private boolean isSuperAdmin;
} }

View File

@@ -1,27 +1,27 @@
package dev.lions.user.manager.dto.realm; package dev.lions.user.manager.dto.realm;
import io.quarkus.runtime.annotations.RegisterForReflection; import io.quarkus.runtime.annotations.RegisterForReflection;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.eclipse.microprofile.openapi.annotations.media.Schema;
import java.io.Serializable; import java.io.Serializable;
@Data @Data
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@RegisterForReflection @RegisterForReflection
@Schema(description = "Réponse de vérification d'accès au realm") @Schema(description = "Réponse de vérification d'accès au realm")
public class RealmAccessCheckDTO implements Serializable { public class RealmAccessCheckDTO implements Serializable {
@Schema(description = "L'utilisateur peut gérer le realm") @Schema(description = "L'utilisateur peut gérer le realm")
private boolean canManage; private boolean canManage;
@Schema(description = "ID de l'utilisateur") @Schema(description = "ID de l'utilisateur")
private String userId; private String userId;
@Schema(description = "Nom du realm") @Schema(description = "Nom du realm")
private String realmName; private String realmName;
} }

View File

@@ -1,119 +1,119 @@
package dev.lions.user.manager.dto.realm; package dev.lions.user.manager.dto.realm;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import dev.lions.user.manager.dto.base.BaseDTO; import dev.lions.user.manager.dto.base.BaseDTO;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder; import lombok.experimental.SuperBuilder;
import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.eclipse.microprofile.openapi.annotations.media.Schema;
import io.quarkus.runtime.annotations.RegisterForReflection; import io.quarkus.runtime.annotations.RegisterForReflection;
import java.time.LocalDateTime; import java.time.LocalDateTime;
/** /**
* DTO pour assigner ou révoquer l'accès d'un utilisateur à un realm * DTO pour assigner ou révoquer l'accès d'un utilisateur à un realm
* Permet de gérer les permissions multi-tenant * Permet de gérer les permissions multi-tenant
*/ */
@Data @Data
@SuperBuilder @SuperBuilder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
@Schema(description = "Attribution ou révocation d'accès à un realm") @Schema(description = "Attribution ou révocation d'accès à un realm")
@RegisterForReflection @RegisterForReflection
public class RealmAssignmentDTO extends BaseDTO { public class RealmAssignmentDTO extends BaseDTO {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@NotBlank(message = "L'ID utilisateur est obligatoire") @NotBlank(message = "L'ID utilisateur est obligatoire")
@Schema(description = "ID de l'utilisateur Keycloak", example = "f47ac10b-58cc-4372-a567-0e02b2c3d479", required = true) @Schema(description = "ID de l'utilisateur Keycloak", example = "f47ac10b-58cc-4372-a567-0e02b2c3d479", required = true)
private String userId; private String userId;
@Schema(description = "Username de l'utilisateur", example = "jdupont") @Schema(description = "Username de l'utilisateur", example = "jdupont")
private String username; private String username;
@Schema(description = "Email de l'utilisateur", example = "jdupont@example.com") @Schema(description = "Email de l'utilisateur", example = "jdupont@example.com")
private String email; private String email;
@NotBlank(message = "Le nom du realm est obligatoire") @NotBlank(message = "Le nom du realm est obligatoire")
@Schema(description = "Nom du realm assigné", example = "btpxpress", required = true) @Schema(description = "Nom du realm assigné", example = "btpxpress", required = true)
private String realmName; private String realmName;
@Schema(description = "Indique si l'utilisateur est super admin (peut gérer tous les realms)", example = "false") @Schema(description = "Indique si l'utilisateur est super admin (peut gérer tous les realms)", example = "false")
private Boolean isSuperAdmin; private Boolean isSuperAdmin;
@Schema(description = "Date d'assignation", example = "2025-01-15T10:30:00") @Schema(description = "Date d'assignation", example = "2025-01-15T10:30:00")
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
private LocalDateTime assignedAt; private LocalDateTime assignedAt;
@Schema(description = "Username de l'administrateur qui a fait l'assignation", example = "admin@lions.dev") @Schema(description = "Username de l'administrateur qui a fait l'assignation", example = "admin@lions.dev")
private String assignedBy; private String assignedBy;
@Schema(description = "Raison de l'assignation", example = "Nouveau gestionnaire du realm client") @Schema(description = "Raison de l'assignation", example = "Nouveau gestionnaire du realm client")
private String raison; private String raison;
@Schema(description = "Commentaires administratifs", example = "Accès temporaire pour support") @Schema(description = "Commentaires administratifs", example = "Accès temporaire pour support")
private String commentaires; private String commentaires;
@Schema(description = "Indique si c'est une assignation temporaire", example = "false") @Schema(description = "Indique si c'est une assignation temporaire", example = "false")
private Boolean temporaire; private Boolean temporaire;
@Schema(description = "Date d'expiration de l'assignation temporaire", example = "2025-12-31T23:59:59") @Schema(description = "Date d'expiration de l'assignation temporaire", example = "2025-12-31T23:59:59")
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
private LocalDateTime dateExpiration; private LocalDateTime dateExpiration;
@Schema(description = "Indique si l'assignation est active", example = "true") @Schema(description = "Indique si l'assignation est active", example = "true")
private Boolean active; private Boolean active;
/** /**
* Vérifie si l'assignation est temporaire * Vérifie si l'assignation est temporaire
* @return true si temporaire * @return true si temporaire
*/ */
public boolean isTemporaire() { public boolean isTemporaire() {
return Boolean.TRUE.equals(temporaire); return Boolean.TRUE.equals(temporaire);
} }
/** /**
* Vérifie si l'assignation est active * Vérifie si l'assignation est active
* @return true si active * @return true si active
*/ */
public boolean isActive() { public boolean isActive() {
return Boolean.TRUE.equals(active); return Boolean.TRUE.equals(active);
} }
/** /**
* Vérifie si l'assignation a expiré * Vérifie si l'assignation a expiré
* @return true si expirée * @return true si expirée
*/ */
public boolean isExpired() { public boolean isExpired() {
if (!isTemporaire() || dateExpiration == null) { if (!isTemporaire() || dateExpiration == null) {
return false; return false;
} }
return LocalDateTime.now().isAfter(dateExpiration); return LocalDateTime.now().isAfter(dateExpiration);
} }
/** /**
* Vérifie si l'utilisateur est super admin * Vérifie si l'utilisateur est super admin
* @return true si super admin * @return true si super admin
*/ */
public boolean isSuperAdmin() { public boolean isSuperAdmin() {
return Boolean.TRUE.equals(isSuperAdmin); return Boolean.TRUE.equals(isSuperAdmin);
} }
/** /**
* Retourne un résumé de l'assignation * Retourne un résumé de l'assignation
* @return résumé * @return résumé
*/ */
public String getSummary() { public String getSummary() {
return String.format("Realm '%s' assigné à %s%s", return String.format("Realm '%s' assigné à %s%s",
realmName, realmName,
username != null ? username : userId, username != null ? username : userId,
isTemporaire() ? " (temporaire)" : "" isTemporaire() ? " (temporaire)" : ""
); );
} }
} }

View File

@@ -1,101 +1,101 @@
package dev.lions.user.manager.dto.role; package dev.lions.user.manager.dto.role;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import dev.lions.user.manager.enums.role.TypeRole; import dev.lions.user.manager.enums.role.TypeRole;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.eclipse.microprofile.openapi.annotations.media.Schema;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;
/** /**
* DTO pour assigner ou révoquer des rôles à un utilisateur * DTO pour assigner ou révoquer des rôles à un utilisateur
* Utilisé dans les opérations d'attribution de rôles * Utilisé dans les opérations d'attribution de rôles
*/ */
@Data @Data
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
@Schema(description = "Attribution ou révocation de rôles") @Schema(description = "Attribution ou révocation de rôles")
public class RoleAssignmentDTO implements Serializable { public class RoleAssignmentDTO implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@NotBlank(message = "L'ID utilisateur est obligatoire") @NotBlank(message = "L'ID utilisateur est obligatoire")
@Schema(description = "ID de l'utilisateur cible", example = "f47ac10b-58cc-4372-a567-0e02b2c3d479", required = true) @Schema(description = "ID de l'utilisateur cible", example = "f47ac10b-58cc-4372-a567-0e02b2c3d479", required = true)
private String userId; private String userId;
@Schema(description = "Username de l'utilisateur cible (optionnel)", example = "jdupont") @Schema(description = "Username de l'utilisateur cible (optionnel)", example = "jdupont")
private String username; private String username;
@NotEmpty(message = "Au moins un rôle doit être spécifié") @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) @Schema(description = "Liste des noms de rôles à attribuer ou révoquer", required = true)
private List<String> roleNames; private List<String> roleNames;
@Schema(description = "Liste des IDs de rôles à attribuer ou révoquer") @Schema(description = "Liste des IDs de rôles à attribuer ou révoquer")
private List<String> roleIds; private List<String> roleIds;
@NotNull(message = "Le type de rôle est obligatoire") @NotNull(message = "Le type de rôle est obligatoire")
@Schema(description = "Type de rôle", example = "REALM_ROLE", required = true) @Schema(description = "Type de rôle", example = "REALM_ROLE", required = true)
private TypeRole typeRole; private TypeRole typeRole;
@Schema(description = "Nom du Realm", example = "btpxpress") @Schema(description = "Nom du Realm", example = "btpxpress")
private String realmName; private String realmName;
@Schema(description = "Nom du Client (requis si typeRole = CLIENT_ROLE)", example = "btpxpress-app") @Schema(description = "Nom du Client (requis si typeRole = CLIENT_ROLE)", example = "btpxpress-app")
private String clientName; private String clientName;
@Schema(description = "ID du Client (optionnel)") @Schema(description = "ID du Client (optionnel)")
private String clientId; private String clientId;
@Schema(description = "Raison de l'attribution/révocation", example = "Promotion au poste de gestionnaire") @Schema(description = "Raison de l'attribution/révocation", example = "Promotion au poste de gestionnaire")
private String raison; private String raison;
@Schema(description = "Commentaires administratifs", example = "Demandé par le manager") @Schema(description = "Commentaires administratifs", example = "Demandé par le manager")
private String commentaires; private String commentaires;
@Schema(description = "Indique si c'est une attribution temporaire", example = "false") @Schema(description = "Indique si c'est une attribution temporaire", example = "false")
private Boolean temporaire; private Boolean temporaire;
@Schema(description = "Date d'expiration de l'attribution temporaire", example = "2025-12-31T23:59:59") @Schema(description = "Date d'expiration de l'attribution temporaire", example = "2025-12-31T23:59:59")
private String dateExpiration; private String dateExpiration;
@Schema(description = "Indique si les rôles composites doivent être inclus", example = "true") @Schema(description = "Indique si les rôles composites doivent être inclus", example = "true")
@Builder.Default @Builder.Default
private Boolean includeComposites = true; private Boolean includeComposites = true;
@Schema(description = "Indique si l'opération doit notifier l'utilisateur", example = "true") @Schema(description = "Indique si l'opération doit notifier l'utilisateur", example = "true")
@Builder.Default @Builder.Default
private Boolean notifyUser = false; private Boolean notifyUser = false;
/** /**
* Valide que les données nécessaires sont présentes pour un rôle client * Valide que les données nécessaires sont présentes pour un rôle client
* @return true si valide * @return true si valide
*/ */
public boolean isValidForClientRole() { public boolean isValidForClientRole() {
return typeRole == TypeRole.CLIENT_ROLE && clientName != null && !clientName.isBlank(); return typeRole == TypeRole.CLIENT_ROLE && clientName != null && !clientName.isBlank();
} }
/** /**
* Valide que les données nécessaires sont présentes pour un rôle realm * Valide que les données nécessaires sont présentes pour un rôle realm
* @return true si valide * @return true si valide
*/ */
public boolean isValidForRealmRole() { public boolean isValidForRealmRole() {
return typeRole == TypeRole.REALM_ROLE; return typeRole == TypeRole.REALM_ROLE;
} }
/** /**
* Retourne le nombre de rôles à assigner/révoquer * Retourne le nombre de rôles à assigner/révoquer
* @return nombre de rôles * @return nombre de rôles
*/ */
public int getRoleCount() { public int getRoleCount() {
return roleNames != null ? roleNames.size() : 0; return roleNames != null ? roleNames.size() : 0;
} }
} }

View File

@@ -1,22 +1,22 @@
package dev.lions.user.manager.dto.role; package dev.lions.user.manager.dto.role;
import io.quarkus.runtime.annotations.RegisterForReflection; import io.quarkus.runtime.annotations.RegisterForReflection;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.eclipse.microprofile.openapi.annotations.media.Schema;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;
@Data @Data
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@RegisterForReflection @RegisterForReflection
@Schema(description = "Requête d'attribution ou de révocation de rôles") @Schema(description = "Requête d'attribution ou de révocation de rôles")
public class RoleAssignmentRequestDTO implements Serializable { public class RoleAssignmentRequestDTO implements Serializable {
@Schema(description = "Liste des noms de rôles", required = true) @Schema(description = "Liste des noms de rôles", required = true)
private List<String> roleNames; private List<String> roleNames;
} }

View File

@@ -1,146 +1,146 @@
package dev.lions.user.manager.dto.role; package dev.lions.user.manager.dto.role;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import dev.lions.user.manager.dto.base.BaseDTO; import dev.lions.user.manager.dto.base.BaseDTO;
import dev.lions.user.manager.enums.role.TypeRole; import dev.lions.user.manager.enums.role.TypeRole;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern; import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size; import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder; import lombok.experimental.SuperBuilder;
import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.eclipse.microprofile.openapi.annotations.media.Schema;
import io.quarkus.runtime.annotations.RegisterForReflection; import io.quarkus.runtime.annotations.RegisterForReflection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
* DTO représentant un rôle Keycloak * DTO représentant un rôle Keycloak
* Mappé depuis RoleRepresentation de Keycloak Admin API * Mappé depuis RoleRepresentation de Keycloak Admin API
*/ */
@Data @Data
@SuperBuilder @SuperBuilder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
@Schema(description = "Rôle Keycloak (Realm ou Client)") @Schema(description = "Rôle Keycloak (Realm ou Client)")
@RegisterForReflection @RegisterForReflection
public class RoleDTO extends BaseDTO { public class RoleDTO extends BaseDTO {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@NotBlank(message = "Le nom du rôle est obligatoire") @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") @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") @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) @Schema(description = "Nom du rôle", example = "admin_btpxpress", required = true)
private String name; private String name;
@Schema(description = "Description du rôle", example = "Administrateur avec tous les privilèges") @Schema(description = "Description du rôle", example = "Administrateur avec tous les privilèges")
private String description; private String description;
@Schema(description = "Type de rôle", example = "REALM_ROLE") @Schema(description = "Type de rôle", example = "REALM_ROLE")
private TypeRole typeRole; private TypeRole typeRole;
@Schema(description = "Indique si c'est un rôle composite", example = "false") @Schema(description = "Indique si c'est un rôle composite", example = "false")
private Boolean composite; private Boolean composite;
@Schema(description = "ID du conteneur (Realm ou Client)", example = "btpxpress") @Schema(description = "ID du conteneur (Realm ou Client)", example = "btpxpress")
private String containerId; private String containerId;
@Schema(description = "Nom du Realm", example = "btpxpress") @Schema(description = "Nom du Realm", example = "btpxpress")
private String realmName; private String realmName;
@Schema(description = "Nom du Client (si rôle client)", example = "btpxpress-app") @Schema(description = "Nom du Client (si rôle client)", example = "btpxpress-app")
private String clientName; private String clientName;
@Schema(description = "ID du Client (si rôle client)") @Schema(description = "ID du Client (si rôle client)")
private String clientId; private String clientId;
@Schema(description = "Rôles composites inclus dans ce rôle") @Schema(description = "Rôles composites inclus dans ce rôle")
private List<String> compositeRoles; private List<String> compositeRoles;
@Schema(description = "Rôles Realm composites") @Schema(description = "Rôles Realm composites")
private List<RoleCompositeDTO> compositeRealmRoles; private List<RoleCompositeDTO> compositeRealmRoles;
@Schema(description = "Rôles Client composites par client") @Schema(description = "Rôles Client composites par client")
private Map<String, List<RoleCompositeDTO>> compositeClientRoles; private Map<String, List<RoleCompositeDTO>> compositeClientRoles;
@Schema(description = "Attributs personnalisés du rôle") @Schema(description = "Attributs personnalisés du rôle")
private Map<String, List<String>> attributes; private Map<String, List<String>> attributes;
@Schema(description = "Nombre d'utilisateurs ayant ce rôle", example = "15") @Schema(description = "Nombre d'utilisateurs ayant ce rôle", example = "15")
private Integer userCount; private Integer userCount;
@Schema(description = "Indique si le rôle est un rôle système", example = "false") @Schema(description = "Indique si le rôle est un rôle système", example = "false")
private Boolean systemRole; private Boolean systemRole;
@Schema(description = "Indique si le rôle peut être supprimé", example = "true") @Schema(description = "Indique si le rôle peut être supprimé", example = "true")
private Boolean deletable; private Boolean deletable;
/** /**
* Détermine si c'est un rôle Realm * Détermine si c'est un rôle Realm
* @return true si typeRole est REALM_ROLE * @return true si typeRole est REALM_ROLE
*/ */
public boolean isRealmRole() { public boolean isRealmRole() {
return typeRole == TypeRole.REALM_ROLE; return typeRole == TypeRole.REALM_ROLE;
} }
/** /**
* Détermine si c'est un rôle Client * Détermine si c'est un rôle Client
* @return true si typeRole est CLIENT_ROLE * @return true si typeRole est CLIENT_ROLE
*/ */
public boolean isClientRole() { public boolean isClientRole() {
return typeRole == TypeRole.CLIENT_ROLE; return typeRole == TypeRole.CLIENT_ROLE;
} }
/** /**
* Détermine si le rôle est composite * Détermine si le rôle est composite
* @return true si composite = true et a des rôles composites * @return true si composite = true et a des rôles composites
*/ */
public boolean isComposite() { public boolean isComposite() {
return Boolean.TRUE.equals(composite) return Boolean.TRUE.equals(composite)
&& ((compositeRoles != null && !compositeRoles.isEmpty()) && ((compositeRoles != null && !compositeRoles.isEmpty())
|| (compositeRealmRoles != null && !compositeRealmRoles.isEmpty()) || (compositeRealmRoles != null && !compositeRealmRoles.isEmpty())
|| (compositeClientRoles != null && !compositeClientRoles.isEmpty())); || (compositeClientRoles != null && !compositeClientRoles.isEmpty()));
} }
/** /**
* Retourne le nom complet du rôle (avec préfixe client si applicable) * Retourne le nom complet du rôle (avec préfixe client si applicable)
* @return nom complet * @return nom complet
*/ */
public String getFullName() { public String getFullName() {
if (isClientRole() && clientName != null) { if (isClientRole() && clientName != null) {
return clientName + ":" + name; return clientName + ":" + name;
} }
return name; return name;
} }
/** /**
* DTO pour rôle composite * DTO pour rôle composite
*/ */
@Data @Data
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@SuperBuilder @SuperBuilder
@Schema(description = "Rôle composite") @Schema(description = "Rôle composite")
public static class RoleCompositeDTO { public static class RoleCompositeDTO {
@Schema(description = "ID du rôle", example = "f47ac10b-58cc-4372-a567-0e02b2c3d479") @Schema(description = "ID du rôle", example = "f47ac10b-58cc-4372-a567-0e02b2c3d479")
private String id; private String id;
@Schema(description = "Nom du rôle", example = "gestionnaire") @Schema(description = "Nom du rôle", example = "gestionnaire")
private String name; private String name;
@Schema(description = "Description du rôle") @Schema(description = "Description du rôle")
private String description; private String description;
@Schema(description = "Type de rôle", example = "REALM_ROLE") @Schema(description = "Type de rôle", example = "REALM_ROLE")
private TypeRole typeRole; private TypeRole typeRole;
@Schema(description = "Nom du client (si client role)") @Schema(description = "Nom du client (si client role)")
private String clientName; private String clientName;
} }
} }

View File

@@ -1,46 +1,46 @@
package dev.lions.user.manager.dto.sync; package dev.lions.user.manager.dto.sync;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.eclipse.microprofile.openapi.annotations.media.Schema;
import java.io.Serializable; import java.io.Serializable;
/** /**
* DTO représentant le statut de santé de Keycloak * DTO représentant le statut de santé de Keycloak
*/ */
@Data @Data
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
@Schema(description = "Statut de santé de Keycloak") @Schema(description = "Statut de santé de Keycloak")
public class HealthStatusDTO implements Serializable { public class HealthStatusDTO implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Schema(description = "Timestamp du check de santé (millisecondes)", example = "1699545600000") @Schema(description = "Timestamp du check de santé (millisecondes)", example = "1699545600000")
private long timestamp; private long timestamp;
@Schema(description = "Indique si Keycloak est accessible", example = "true") @Schema(description = "Indique si Keycloak est accessible", example = "true")
private boolean keycloakAccessible; private boolean keycloakAccessible;
@Schema(description = "Version de Keycloak", example = "23.0.3") @Schema(description = "Version de Keycloak", example = "23.0.3")
private String keycloakVersion; private String keycloakVersion;
@Schema(description = "Indique si les realms sont accessibles", example = "true") @Schema(description = "Indique si les realms sont accessibles", example = "true")
private boolean realmsAccessible; private boolean realmsAccessible;
@Schema(description = "Nombre de realms disponibles", example = "5") @Schema(description = "Nombre de realms disponibles", example = "5")
private int realmsCount; private int realmsCount;
@Schema(description = "Indique si Keycloak est globalement en bonne santé", example = "true") @Schema(description = "Indique si Keycloak est globalement en bonne santé", example = "true")
private boolean overallHealthy; private boolean overallHealthy;
@Schema(description = "Message d'erreur si le check a échoué") @Schema(description = "Message d'erreur si le check a échoué")
private String errorMessage; private String errorMessage;
} }

View File

@@ -1,29 +1,29 @@
package dev.lions.user.manager.dto.sync; package dev.lions.user.manager.dto.sync;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import java.util.Set; import java.util.Set;
/** /**
* DTO rapport de cohérence entre données Keycloak et cache local. * DTO rapport de cohérence entre données Keycloak et cache local.
*/ */
@Data @Data
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class SyncConsistencyDTO { public class SyncConsistencyDTO {
private String realmName; private String realmName;
private String status; // OK, MISMATCH, ERROR private String status; // OK, MISMATCH, ERROR
private Integer usersKeycloakCount; private Integer usersKeycloakCount;
private Integer usersLocalCount; private Integer usersLocalCount;
private Set<String> missingUsersInLocal; private Set<String> missingUsersInLocal;
private Set<String> missingUsersInKeycloak; private Set<String> missingUsersInKeycloak;
private Integer rolesKeycloakCount; private Integer rolesKeycloakCount;
private Integer rolesLocalCount; private Integer rolesLocalCount;
private Set<String> missingRolesInLocal; private Set<String> missingRolesInLocal;
private Set<String> missingRolesInKeycloak; private Set<String> missingRolesInKeycloak;
private String error; private String error;
} }

View File

@@ -1,23 +1,23 @@
package dev.lions.user.manager.dto.sync; package dev.lions.user.manager.dto.sync;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@Data @Data
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class SyncHistoryDTO { public class SyncHistoryDTO {
private String id; private String id;
private String realmName; private String realmName;
private LocalDateTime syncDate; private LocalDateTime syncDate;
private String syncType; // FULL, PARTIAL, USER, ROLE private String syncType; // FULL, PARTIAL, USER, ROLE
private String status; // SUCCESS, FAILURE private String status; // SUCCESS, FAILURE
private Integer itemsProcessed; private Integer itemsProcessed;
private Long durationMs; private Long durationMs;
private String errorMessage; private String errorMessage;
} }

View File

@@ -1,57 +1,57 @@
package dev.lions.user.manager.dto.sync; package dev.lions.user.manager.dto.sync;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.eclipse.microprofile.openapi.annotations.media.Schema;
import java.io.Serializable; import java.io.Serializable;
/** /**
* DTO représentant le résultat d'une synchronisation * DTO représentant le résultat d'une synchronisation
*/ */
@Data @Data
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
@Schema(description = "Résultat d'une synchronisation avec Keycloak") @Schema(description = "Résultat d'une synchronisation avec Keycloak")
public class SyncResultDTO implements Serializable { public class SyncResultDTO implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Schema(description = "Nom du realm synchronisé", example = "lions") @Schema(description = "Nom du realm synchronisé", example = "lions")
private String realmName; private String realmName;
@Schema(description = "Nombre d'utilisateurs synchronisés", example = "150") @Schema(description = "Nombre d'utilisateurs synchronisés", example = "150")
private int usersCount; private int usersCount;
@Schema(description = "Nombre de rôles realm synchronisés", example = "25") @Schema(description = "Nombre de rôles realm synchronisés", example = "25")
private int realmRolesCount; private int realmRolesCount;
@Schema(description = "Nombre de rôles client synchronisés", example = "50") @Schema(description = "Nombre de rôles client synchronisés", example = "50")
private int clientRolesCount; private int clientRolesCount;
@Schema(description = "Indique si la synchronisation a réussi", example = "true") @Schema(description = "Indique si la synchronisation a réussi", example = "true")
private boolean success; private boolean success;
@Schema(description = "Message d'erreur si la synchronisation a échoué") @Schema(description = "Message d'erreur si la synchronisation a échoué")
private String errorMessage; private String errorMessage;
@Schema(description = "Timestamp de début de la synchronisation (millisecondes)", example = "1699545600000") @Schema(description = "Timestamp de début de la synchronisation (millisecondes)", example = "1699545600000")
private long startTime; private long startTime;
@Schema(description = "Timestamp de fin de la synchronisation (millisecondes)", example = "1699545615000") @Schema(description = "Timestamp de fin de la synchronisation (millisecondes)", example = "1699545615000")
private long endTime; private long endTime;
/** /**
* Retourne la durée de la synchronisation en millisecondes * Retourne la durée de la synchronisation en millisecondes
* @return durée en ms * @return durée en ms
*/ */
public long getDurationMs() { public long getDurationMs() {
return endTime - startTime; return endTime - startTime;
} }
} }

View File

@@ -1,25 +1,25 @@
package dev.lions.user.manager.dto.user; package dev.lions.user.manager.dto.user;
import io.quarkus.runtime.annotations.RegisterForReflection; import io.quarkus.runtime.annotations.RegisterForReflection;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.eclipse.microprofile.openapi.annotations.media.Schema;
import java.io.Serializable; import java.io.Serializable;
@Data @Data
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@RegisterForReflection @RegisterForReflection
@Schema(description = "Requête de réinitialisation de mot de passe") @Schema(description = "Requête de réinitialisation de mot de passe")
public class PasswordResetRequestDTO implements Serializable { public class PasswordResetRequestDTO implements Serializable {
@Schema(description = "Nouveau mot de passe", required = true) @Schema(description = "Nouveau mot de passe", required = true)
private String password; private String password;
@Schema(description = "Indique si le mot de passe est temporaire", defaultValue = "true") @Schema(description = "Indique si le mot de passe est temporaire", defaultValue = "true")
@Builder.Default @Builder.Default
private boolean temporary = true; private boolean temporary = true;
} }

View File

@@ -1,21 +1,21 @@
package dev.lions.user.manager.dto.user; package dev.lions.user.manager.dto.user;
import io.quarkus.runtime.annotations.RegisterForReflection; import io.quarkus.runtime.annotations.RegisterForReflection;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.eclipse.microprofile.openapi.annotations.media.Schema;
import java.io.Serializable; import java.io.Serializable;
@Data @Data
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@RegisterForReflection @RegisterForReflection
@Schema(description = "Réponse de révocation de sessions") @Schema(description = "Réponse de révocation de sessions")
public class SessionsRevokedDTO implements Serializable { public class SessionsRevokedDTO implements Serializable {
@Schema(description = "Nombre de sessions révoquées") @Schema(description = "Nombre de sessions révoquées")
private int count; private int count;
} }

View File

@@ -1,211 +1,211 @@
package dev.lions.user.manager.dto.user; package dev.lions.user.manager.dto.user;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import dev.lions.user.manager.dto.base.BaseDTO; import dev.lions.user.manager.dto.base.BaseDTO;
import dev.lions.user.manager.enums.user.StatutUser; import dev.lions.user.manager.enums.user.StatutUser;
import jakarta.validation.constraints.Email; import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern; import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size; import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder; import lombok.experimental.SuperBuilder;
import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.eclipse.microprofile.openapi.annotations.media.Schema;
import io.quarkus.runtime.annotations.RegisterForReflection; import io.quarkus.runtime.annotations.RegisterForReflection;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
* DTO représentant un utilisateur Keycloak * DTO représentant un utilisateur Keycloak
* Mappé depuis la représentation UserRepresentation de Keycloak Admin API * Mappé depuis la représentation UserRepresentation de Keycloak Admin API
*/ */
@Data @Data
@SuperBuilder @SuperBuilder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
@Schema(description = "Utilisateur Keycloak") @Schema(description = "Utilisateur Keycloak")
@RegisterForReflection @RegisterForReflection
public class UserDTO extends BaseDTO { public class UserDTO extends BaseDTO {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
// Informations de base // Informations de base
@NotBlank(message = "Le nom d'utilisateur est obligatoire") @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") @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") @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) @Schema(description = "Nom d'utilisateur unique", example = "jdupont", required = true)
private String username; private String username;
@NotBlank(message = "L'email est obligatoire") @NotBlank(message = "L'email est obligatoire")
@Email(message = "Format d'email invalide") @Email(message = "Format d'email invalide")
@Schema(description = "Adresse email", example = "jean.dupont@lions.dev", required = true) @Schema(description = "Adresse email", example = "jean.dupont@lions.dev", required = true)
private String email; private String email;
@Schema(description = "Email vérifié", example = "true") @Schema(description = "Email vérifié", example = "true")
private Boolean emailVerified; private Boolean emailVerified;
@NotBlank(message = "Le prénom est obligatoire") @NotBlank(message = "Le prénom est obligatoire")
@Size(min = 2, max = 100, message = "Le prénom doit contenir entre 2 et 100 caractères") @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) @Schema(description = "Prénom", example = "Jean", required = true)
private String prenom; private String prenom;
@NotBlank(message = "Le nom est obligatoire") @NotBlank(message = "Le nom est obligatoire")
@Size(min = 2, max = 100, message = "Le nom doit contenir entre 2 et 100 caractères") @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) @Schema(description = "Nom de famille", example = "Dupont", required = true)
private String nom; private String nom;
// Statut // Statut
@Schema(description = "Statut de l'utilisateur", example = "ACTIF") @Schema(description = "Statut de l'utilisateur", example = "ACTIF")
private StatutUser statut; private StatutUser statut;
@Schema(description = "Compte activé", example = "true") @Schema(description = "Compte activé", example = "true")
private Boolean enabled; private Boolean enabled;
// Informations supplémentaires // Informations supplémentaires
@Schema(description = "Numéro de téléphone", example = "+225 07 12 34 56 78") @Schema(description = "Numéro de téléphone", example = "+225 07 12 34 56 78")
private String telephone; private String telephone;
@Schema(description = "Organisation/Entreprise", example = "Lions Dev") @Schema(description = "Organisation/Entreprise", example = "Lions Dev")
private String organisation; private String organisation;
@Schema(description = "Département", example = "IT") @Schema(description = "Département", example = "IT")
private String departement; private String departement;
@Schema(description = "Fonction/Poste", example = "Développeur Senior") @Schema(description = "Fonction/Poste", example = "Développeur Senior")
private String fonction; private String fonction;
@Schema(description = "Pays", example = "Côte d'Ivoire") @Schema(description = "Pays", example = "Côte d'Ivoire")
private String pays; private String pays;
@Schema(description = "Ville", example = "Abidjan") @Schema(description = "Ville", example = "Abidjan")
private String ville; private String ville;
@Schema(description = "Langue préférée", example = "fr") @Schema(description = "Langue préférée", example = "fr")
private String langue; private String langue;
@Schema(description = "Fuseau horaire", example = "Africa/Abidjan") @Schema(description = "Fuseau horaire", example = "Africa/Abidjan")
private String timezone; private String timezone;
// Realm et rôles // Realm et rôles
@Schema(description = "Realm Keycloak", example = "btpxpress") @Schema(description = "Realm Keycloak", example = "btpxpress")
private String realmName; private String realmName;
@Schema(description = "Liste des rôles Realm assignés") @Schema(description = "Liste des rôles Realm assignés")
private List<String> realmRoles; private List<String> realmRoles;
@Schema(description = "Liste des rôles Client assignés") @Schema(description = "Liste des rôles Client assignés")
private Map<String, List<String>> clientRoles; private Map<String, List<String>> clientRoles;
@Schema(description = "Liste des groupes auxquels appartient l'utilisateur") @Schema(description = "Liste des groupes auxquels appartient l'utilisateur")
private List<String> groups; private List<String> groups;
// Dates importantes // Dates importantes
@Schema(description = "Date de dernière connexion", example = "2025-01-15T10:30:00") @Schema(description = "Date de dernière connexion", example = "2025-01-15T10:30:00")
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
private LocalDateTime derniereConnexion; private LocalDateTime derniereConnexion;
@Schema(description = "Date d'expiration du compte", example = "2026-01-15T23:59:59") @Schema(description = "Date d'expiration du compte", example = "2026-01-15T23:59:59")
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
private LocalDateTime dateExpiration; private LocalDateTime dateExpiration;
@Schema(description = "Date de verrouillage du compte", example = "2025-01-15T16:00:00") @Schema(description = "Date de verrouillage du compte", example = "2025-01-15T16:00:00")
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
private LocalDateTime dateVerrouillage; private LocalDateTime dateVerrouillage;
// Attributs personnalisés Keycloak // Attributs personnalisés Keycloak
@Schema(description = "Attributs personnalisés Keycloak") @Schema(description = "Attributs personnalisés Keycloak")
private Map<String, List<String>> attributes; private Map<String, List<String>> attributes;
// Actions requises // Actions requises
@Schema(description = "Actions requises (ex: UPDATE_PASSWORD, VERIFY_EMAIL)") @Schema(description = "Actions requises (ex: UPDATE_PASSWORD, VERIFY_EMAIL)")
private List<String> requiredActions; private List<String> requiredActions;
// Fédération // Fédération
@Schema(description = "Fournisseur d'identité fédéré", example = "google") @Schema(description = "Fournisseur d'identité fédéré", example = "google")
private String federatedIdentityProvider; private String federatedIdentityProvider;
@Schema(description = "Lien d'identité fédérée") @Schema(description = "Lien d'identité fédérée")
private List<FederatedIdentityDTO> federatedIdentities; private List<FederatedIdentityDTO> federatedIdentities;
// Crédentiels temporaires // Crédentiels temporaires
@Schema(description = "Mot de passe temporaire (création uniquement)") @Schema(description = "Mot de passe temporaire (création uniquement)")
private String temporaryPassword; private String temporaryPassword;
@Schema(description = "Indique si le mot de passe est temporaire") @Schema(description = "Indique si le mot de passe est temporaire")
private Boolean temporaryPasswordFlag; private Boolean temporaryPasswordFlag;
// Informations de session // Informations de session
@Schema(description = "Nombre de sessions actives", example = "2") @Schema(description = "Nombre de sessions actives", example = "2")
private Integer activeSessions; private Integer activeSessions;
@Schema(description = "Nombre d'échecs de connexion", example = "0") @Schema(description = "Nombre d'échecs de connexion", example = "0")
private Integer failedLoginAttempts; private Integer failedLoginAttempts;
// Audit // Audit
@Schema(description = "Raison de la dernière modification") @Schema(description = "Raison de la dernière modification")
private String raisonModification; private String raisonModification;
@Schema(description = "Commentaires administratifs") @Schema(description = "Commentaires administratifs")
private String commentaires; private String commentaires;
/** /**
* Retourne le nom complet de l'utilisateur * Retourne le nom complet de l'utilisateur
* @return prénom + nom * @return prénom + nom
*/ */
public String getNomComplet() { public String getNomComplet() {
if (prenom != null && nom != null) { if (prenom != null && nom != null) {
return prenom + " " + nom; return prenom + " " + nom;
} }
return username; return username;
} }
/** /**
* Détermine si l'utilisateur est actif * Détermine si l'utilisateur est actif
* @return true si statut ACTIF et enabled * @return true si statut ACTIF et enabled
*/ */
public boolean isActif() { public boolean isActif() {
return statut == StatutUser.ACTIF && Boolean.TRUE.equals(enabled); return statut == StatutUser.ACTIF && Boolean.TRUE.equals(enabled);
} }
/** /**
* Détermine si le compte a expiré * Détermine si le compte a expiré
* @return true si dateExpiration est passée * @return true si dateExpiration est passée
*/ */
public boolean isExpire() { public boolean isExpire() {
return dateExpiration != null && dateExpiration.isBefore(LocalDateTime.now()); return dateExpiration != null && dateExpiration.isBefore(LocalDateTime.now());
} }
/** /**
* Détermine si l'utilisateur a des actions requises * Détermine si l'utilisateur a des actions requises
* @return true si des actions sont requises * @return true si des actions sont requises
*/ */
public boolean hasRequiredActions() { public boolean hasRequiredActions() {
return requiredActions != null && !requiredActions.isEmpty(); return requiredActions != null && !requiredActions.isEmpty();
} }
/** /**
* DTO pour identité fédérée * DTO pour identité fédérée
*/ */
@Data @Data
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@SuperBuilder @SuperBuilder
@Schema(description = "Identité fédérée") @Schema(description = "Identité fédérée")
public static class FederatedIdentityDTO { public static class FederatedIdentityDTO {
@Schema(description = "Fournisseur d'identité", example = "google") @Schema(description = "Fournisseur d'identité", example = "google")
private String identityProvider; private String identityProvider;
@Schema(description = "ID utilisateur chez le fournisseur") @Schema(description = "ID utilisateur chez le fournisseur")
private String userId; private String userId;
@Schema(description = "Nom d'utilisateur chez le fournisseur") @Schema(description = "Nom d'utilisateur chez le fournisseur")
private String userName; private String userName;
} }
} }

View File

@@ -1,193 +1,193 @@
package dev.lions.user.manager.dto.user; package dev.lions.user.manager.dto.user;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import dev.lions.user.manager.enums.user.StatutUser; import dev.lions.user.manager.enums.user.StatutUser;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.eclipse.microprofile.openapi.annotations.media.Schema;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
/** /**
* Critères de recherche pour les utilisateurs * Critères de recherche pour les utilisateurs
* Utilisé pour filtrer les utilisateurs via l'API Keycloak Admin * Utilisé pour filtrer les utilisateurs via l'API Keycloak Admin
*/ */
@Data @Data
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
@Schema(description = "Critères de recherche d'utilisateurs") @Schema(description = "Critères de recherche d'utilisateurs")
public class UserSearchCriteriaDTO implements Serializable { public class UserSearchCriteriaDTO implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
// Recherche textuelle // Recherche textuelle
@Schema(description = "Terme de recherche générale (username, email, nom, prénom)", example = "dupont") @Schema(description = "Terme de recherche générale (username, email, nom, prénom)", example = "dupont")
private String searchTerm; private String searchTerm;
@Schema(description = "Nom d'utilisateur exact", example = "jdupont") @Schema(description = "Nom d'utilisateur exact", example = "jdupont")
private String username; private String username;
@Schema(description = "Email exact", example = "jean.dupont@lions.dev") @Schema(description = "Email exact", example = "jean.dupont@lions.dev")
private String email; private String email;
@Schema(description = "Prénom", example = "Jean") @Schema(description = "Prénom", example = "Jean")
private String prenom; private String prenom;
@Schema(description = "Nom de famille", example = "Dupont") @Schema(description = "Nom de famille", example = "Dupont")
private String nom; private String nom;
@Schema(description = "Numéro de téléphone", example = "+225 01 02 03 04 05") @Schema(description = "Numéro de téléphone", example = "+225 01 02 03 04 05")
private String telephone; private String telephone;
// Filtres de statut // Filtres de statut
@Schema(description = "Statut de l'utilisateur", example = "ACTIF") @Schema(description = "Statut de l'utilisateur", example = "ACTIF")
private StatutUser statut; private StatutUser statut;
@Schema(description = "Compte activé", example = "true") @Schema(description = "Compte activé", example = "true")
private Boolean enabled; private Boolean enabled;
@Schema(description = "Email vérifié", example = "true") @Schema(description = "Email vérifié", example = "true")
private Boolean emailVerified; private Boolean emailVerified;
// Filtres de rôle et groupe // Filtres de rôle et groupe
@Schema(description = "Liste des rôles Realm à filtrer") @Schema(description = "Liste des rôles Realm à filtrer")
private List<String> realmRoles; private List<String> realmRoles;
@Schema(description = "Liste des rôles Client à filtrer") @Schema(description = "Liste des rôles Client à filtrer")
private List<String> clientRoles; private List<String> clientRoles;
@Schema(description = "Liste des groupes à filtrer") @Schema(description = "Liste des groupes à filtrer")
private List<String> groups; private List<String> groups;
@Schema(description = "Nom du client pour filtrer par rôles client", example = "btpxpress-app") @Schema(description = "Nom du client pour filtrer par rôles client", example = "btpxpress-app")
private String clientName; private String clientName;
// Filtres organisationnels // Filtres organisationnels
@Schema(description = "Organisation/Entreprise", example = "Lions Dev") @Schema(description = "Organisation/Entreprise", example = "Lions Dev")
private String organisation; private String organisation;
@Schema(description = "Département", example = "IT") @Schema(description = "Département", example = "IT")
private String departement; private String departement;
@Schema(description = "Fonction/Poste", example = "Développeur") @Schema(description = "Fonction/Poste", example = "Développeur")
private String fonction; private String fonction;
@Schema(description = "Pays", example = "Côte d'Ivoire") @Schema(description = "Pays", example = "Côte d'Ivoire")
private String pays; private String pays;
@Schema(description = "Ville", example = "Abidjan") @Schema(description = "Ville", example = "Abidjan")
private String ville; private String ville;
// Filtres temporels // Filtres temporels
@Schema(description = "Date de création minimum", example = "2025-01-01T00:00:00") @Schema(description = "Date de création minimum", example = "2025-01-01T00:00:00")
private LocalDateTime dateCreationMin; private LocalDateTime dateCreationMin;
@Schema(description = "Date de création maximum", example = "2025-12-31T23:59:59") @Schema(description = "Date de création maximum", example = "2025-12-31T23:59:59")
private LocalDateTime dateCreationMax; private LocalDateTime dateCreationMax;
@Schema(description = "Date de dernière connexion minimum", example = "2025-01-01T00:00:00") @Schema(description = "Date de dernière connexion minimum", example = "2025-01-01T00:00:00")
private LocalDateTime derniereConnexionMin; private LocalDateTime derniereConnexionMin;
@Schema(description = "Date de dernière connexion maximum", example = "2025-01-31T23:59:59") @Schema(description = "Date de dernière connexion maximum", example = "2025-01-31T23:59:59")
private LocalDateTime derniereConnexionMax; private LocalDateTime derniereConnexionMax;
// Filtres spéciaux // Filtres spéciaux
@Schema(description = "Utilisateurs avec actions requises uniquement", example = "true") @Schema(description = "Utilisateurs avec actions requises uniquement", example = "true")
private Boolean hasRequiredActions; private Boolean hasRequiredActions;
@Schema(description = "Utilisateurs verrouillés uniquement", example = "false") @Schema(description = "Utilisateurs verrouillés uniquement", example = "false")
private Boolean isLocked; private Boolean isLocked;
@Schema(description = "Utilisateurs expirés uniquement", example = "false") @Schema(description = "Utilisateurs expirés uniquement", example = "false")
private Boolean isExpired; private Boolean isExpired;
@Schema(description = "Utilisateurs avec sessions actives uniquement", example = "true") @Schema(description = "Utilisateurs avec sessions actives uniquement", example = "true")
private Boolean hasActiveSessions; private Boolean hasActiveSessions;
// Realm // Realm
@Schema(description = "Nom du Realm à filtrer", example = "btpxpress") @Schema(description = "Nom du Realm à filtrer", example = "btpxpress")
private String realmName; private String realmName;
// Pagination // Pagination
@Schema(description = "Numéro de page (commence à 0)", example = "0", defaultValue = "0") @Schema(description = "Numéro de page (commence à 0)", example = "0", defaultValue = "0")
@Builder.Default @Builder.Default
private Integer page = 0; private Integer page = 0;
@Schema(description = "Taille de la page", example = "20", defaultValue = "20") @Schema(description = "Taille de la page", example = "20", defaultValue = "20")
@Builder.Default @Builder.Default
private Integer pageSize = 20; private Integer pageSize = 20;
@Schema(description = "Nombre maximum de résultats", example = "100") @Schema(description = "Nombre maximum de résultats", example = "100")
private Integer maxResults; private Integer maxResults;
// Tri // Tri
@Schema(description = "Champ de tri (username, email, prenom, nom, dateCreation, derniereConnexion)", example = "username") @Schema(description = "Champ de tri (username, email, prenom, nom, dateCreation, derniereConnexion)", example = "username")
@Builder.Default @Builder.Default
private String sortBy = "username"; private String sortBy = "username";
@Schema(description = "Ordre de tri (ASC ou DESC)", example = "ASC") @Schema(description = "Ordre de tri (ASC ou DESC)", example = "ASC")
@Builder.Default @Builder.Default
private String sortOrder = "ASC"; private String sortOrder = "ASC";
// Options d'inclusion // Options d'inclusion
@Schema(description = "Inclure les rôles dans les résultats", example = "true") @Schema(description = "Inclure les rôles dans les résultats", example = "true")
@Builder.Default @Builder.Default
private Boolean includeRoles = false; private Boolean includeRoles = false;
@Schema(description = "Inclure les groupes dans les résultats", example = "true") @Schema(description = "Inclure les groupes dans les résultats", example = "true")
@Builder.Default @Builder.Default
private Boolean includeGroups = false; private Boolean includeGroups = false;
@Schema(description = "Inclure les attributs personnalisés", example = "false") @Schema(description = "Inclure les attributs personnalisés", example = "false")
@Builder.Default @Builder.Default
private Boolean includeAttributes = false; private Boolean includeAttributes = false;
@Schema(description = "Inclure les informations de session", example = "false") @Schema(description = "Inclure les informations de session", example = "false")
@Builder.Default @Builder.Default
private Boolean includeSessionInfo = false; private Boolean includeSessionInfo = false;
/** /**
* Détermine si des filtres de recherche sont appliqués * Détermine si des filtres de recherche sont appliqués
* @return true si au moins un filtre est défini * @return true si au moins un filtre est défini
*/ */
public boolean hasFilters() { public boolean hasFilters() {
return searchTerm != null return searchTerm != null
|| username != null || username != null
|| email != null || email != null
|| prenom != null || prenom != null
|| nom != null || nom != null
|| statut != null || statut != null
|| enabled != null || enabled != null
|| emailVerified != null || emailVerified != null
|| (realmRoles != null && !realmRoles.isEmpty()) || (realmRoles != null && !realmRoles.isEmpty())
|| (clientRoles != null && !clientRoles.isEmpty()) || (clientRoles != null && !clientRoles.isEmpty())
|| (groups != null && !groups.isEmpty()) || (groups != null && !groups.isEmpty())
|| organisation != null || organisation != null
|| departement != null || departement != null
|| fonction != null || fonction != null
|| pays != null || pays != null
|| ville != null || ville != null
|| dateCreationMin != null || dateCreationMin != null
|| dateCreationMax != null || dateCreationMax != null
|| derniereConnexionMin != null || derniereConnexionMin != null
|| derniereConnexionMax != null || derniereConnexionMax != null
|| hasRequiredActions != null || hasRequiredActions != null
|| isLocked != null || isLocked != null
|| isExpired != null || isExpired != null
|| hasActiveSessions != null; || hasActiveSessions != null;
} }
/** /**
* Calcule l'offset pour la pagination Keycloak * Calcule l'offset pour la pagination Keycloak
* @return offset calculé à partir de page et pageSize * @return offset calculé à partir de page et pageSize
*/ */
public int getOffset() { public int getOffset() {
return page * pageSize; return page * pageSize;
} }
} }

View File

@@ -1,107 +1,107 @@
package dev.lions.user.manager.dto.user; package dev.lions.user.manager.dto.user;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.eclipse.microprofile.openapi.annotations.media.Schema;
import io.quarkus.runtime.annotations.RegisterForReflection; import io.quarkus.runtime.annotations.RegisterForReflection;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;
/** /**
* Résultat paginé de recherche d'utilisateurs * Résultat paginé de recherche d'utilisateurs
* Contient la liste des utilisateurs et les métadonnées de pagination * Contient la liste des utilisateurs et les métadonnées de pagination
*/ */
@Data @Data
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
@Schema(description = "Résultat paginé de recherche d'utilisateurs") @Schema(description = "Résultat paginé de recherche d'utilisateurs")
@RegisterForReflection @RegisterForReflection
public class UserSearchResultDTO implements Serializable { public class UserSearchResultDTO implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Schema(description = "Liste des utilisateurs trouvés") @Schema(description = "Liste des utilisateurs trouvés")
private List<UserDTO> users; private List<UserDTO> users;
@Schema(description = "Nombre total d'utilisateurs correspondant aux critères", example = "156") @Schema(description = "Nombre total d'utilisateurs correspondant aux critères", example = "156")
private Long totalCount; private Long totalCount;
@Schema(description = "Numéro de la page actuelle (commence à 0)", example = "0") @Schema(description = "Numéro de la page actuelle (commence à 0)", example = "0")
private Integer currentPage; private Integer currentPage;
@Schema(description = "Taille de la page", example = "20") @Schema(description = "Taille de la page", example = "20")
private Integer pageSize; private Integer pageSize;
@Schema(description = "Nombre total de pages", example = "8") @Schema(description = "Nombre total de pages", example = "8")
private Integer totalPages; private Integer totalPages;
@Schema(description = "Indique s'il y a une page suivante", example = "true") @Schema(description = "Indique s'il y a une page suivante", example = "true")
private Boolean hasNextPage; private Boolean hasNextPage;
@Schema(description = "Indique s'il y a une page précédente", example = "false") @Schema(description = "Indique s'il y a une page précédente", example = "false")
private Boolean hasPreviousPage; private Boolean hasPreviousPage;
@Schema(description = "Index du premier élément de la page", example = "0") @Schema(description = "Index du premier élément de la page", example = "0")
private Integer firstElement; private Integer firstElement;
@Schema(description = "Index du dernier élément de la page", example = "19") @Schema(description = "Index du dernier élément de la page", example = "19")
private Integer lastElement; private Integer lastElement;
@Schema(description = "Indique si la page est vide", example = "false") @Schema(description = "Indique si la page est vide", example = "false")
private Boolean isEmpty; private Boolean isEmpty;
@Schema(description = "Indique si c'est la première page", example = "true") @Schema(description = "Indique si c'est la première page", example = "true")
private Boolean isFirstPage; private Boolean isFirstPage;
@Schema(description = "Indique si c'est la dernière page", example = "false") @Schema(description = "Indique si c'est la dernière page", example = "false")
private Boolean isLastPage; private Boolean isLastPage;
@Schema(description = "Critères de recherche utilisés") @Schema(description = "Critères de recherche utilisés")
private UserSearchCriteriaDTO criteria; private UserSearchCriteriaDTO criteria;
@Schema(description = "Temps d'exécution de la recherche en millisecondes", example = "145") @Schema(description = "Temps d'exécution de la recherche en millisecondes", example = "145")
private Long executionTimeMs; private Long executionTimeMs;
/** /**
* Construit un résultat de recherche à partir d'une liste d'utilisateurs * Construit un résultat de recherche à partir d'une liste d'utilisateurs
* @param users liste des utilisateurs * @param users liste des utilisateurs
* @param criteria critères de recherche * @param criteria critères de recherche
* @param totalCount nombre total de résultats * @param totalCount nombre total de résultats
* @return UserSearchResultDTO * @return UserSearchResultDTO
*/ */
public static UserSearchResultDTO of(List<UserDTO> users, UserSearchCriteriaDTO criteria, Long totalCount) { public static UserSearchResultDTO of(List<UserDTO> users, UserSearchCriteriaDTO criteria, Long totalCount) {
int pageSize = criteria.getPageSize(); int pageSize = criteria.getPageSize();
int currentPage = criteria.getPage(); int currentPage = criteria.getPage();
long totalPages = (totalCount + pageSize - 1) / pageSize; long totalPages = (totalCount + pageSize - 1) / pageSize;
return UserSearchResultDTO.builder() return UserSearchResultDTO.builder()
.users(users) .users(users)
.totalCount(totalCount) .totalCount(totalCount)
.currentPage(currentPage) .currentPage(currentPage)
.pageSize(pageSize) .pageSize(pageSize)
.totalPages((int) totalPages) .totalPages((int) totalPages)
.hasNextPage(currentPage < totalPages - 1) .hasNextPage(currentPage < totalPages - 1)
.hasPreviousPage(currentPage > 0) .hasPreviousPage(currentPage > 0)
.firstElement(currentPage * pageSize) .firstElement(currentPage * pageSize)
.lastElement(Math.min((currentPage + 1) * pageSize - 1, totalCount.intValue())) .lastElement(Math.min((currentPage + 1) * pageSize - 1, totalCount.intValue()))
.isEmpty(users == null || users.isEmpty()) .isEmpty(users == null || users.isEmpty())
.isFirstPage(currentPage == 0) .isFirstPage(currentPage == 0)
.isLastPage(currentPage >= totalPages - 1) .isLastPage(currentPage >= totalPages - 1)
.criteria(criteria) .criteria(criteria)
.build(); .build();
} }
/** /**
* Retourne le nombre d'utilisateurs dans la page courante * Retourne le nombre d'utilisateurs dans la page courante
* @return nombre d'utilisateurs * @return nombre d'utilisateurs
*/ */
public int getCurrentPageSize() { public int getCurrentPageSize() {
return users != null ? users.size() : 0; return users != null ? users.size() : 0;
} }
} }

View File

@@ -1,116 +1,116 @@
package dev.lions.user.manager.enums.audit; package dev.lions.user.manager.enums.audit;
import lombok.Getter; import lombok.Getter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.eclipse.microprofile.openapi.annotations.media.Schema;
/** /**
* Type d'action effectuée sur une ressource * Type d'action effectuée sur une ressource
* Utilisé pour l'audit trail * Utilisé pour l'audit trail
*/ */
@Getter @Getter
@RequiredArgsConstructor @RequiredArgsConstructor
@Schema(description = "Type d'action pour l'audit") @Schema(description = "Type d'action pour l'audit")
public enum TypeActionAudit { public enum TypeActionAudit {
// Actions Utilisateur // Actions Utilisateur
USER_CREATE("Création utilisateur", "USER", "CREATE"), USER_CREATE("Création utilisateur", "USER", "CREATE"),
USER_UPDATE("Modification utilisateur", "USER", "UPDATE"), USER_UPDATE("Modification utilisateur", "USER", "UPDATE"),
USER_DELETE("Suppression utilisateur", "USER", "DELETE"), USER_DELETE("Suppression utilisateur", "USER", "DELETE"),
USER_ACTIVATE("Activation utilisateur", "USER", "ACTIVATE"), USER_ACTIVATE("Activation utilisateur", "USER", "ACTIVATE"),
USER_DEACTIVATE("Désactivation utilisateur", "USER", "DEACTIVATE"), USER_DEACTIVATE("Désactivation utilisateur", "USER", "DEACTIVATE"),
USER_SUSPEND("Suspension utilisateur", "USER", "SUSPEND"), USER_SUSPEND("Suspension utilisateur", "USER", "SUSPEND"),
USER_UNLOCK("Déverrouillage utilisateur", "USER", "UNLOCK"), USER_UNLOCK("Déverrouillage utilisateur", "USER", "UNLOCK"),
USER_PASSWORD_RESET("Réinitialisation mot de passe", "USER", "PASSWORD_RESET"), USER_PASSWORD_RESET("Réinitialisation mot de passe", "USER", "PASSWORD_RESET"),
USER_EMAIL_VERIFY("Vérification email", "USER", "EMAIL_VERIFY"), USER_EMAIL_VERIFY("Vérification email", "USER", "EMAIL_VERIFY"),
USER_FORCE_LOGOUT("Déconnexion forcée", "USER", "FORCE_LOGOUT"), USER_FORCE_LOGOUT("Déconnexion forcée", "USER", "FORCE_LOGOUT"),
USER_IMPORT("Import utilisateurs CSV", "USER", "IMPORT"), // Ajout USER_IMPORT("Import utilisateurs CSV", "USER", "IMPORT"), // Ajout
// Actions Rôle // Actions Rôle
ROLE_CREATE("Création rôle", "ROLE", "CREATE"), ROLE_CREATE("Création rôle", "ROLE", "CREATE"),
ROLE_UPDATE("Modification rôle", "ROLE", "UPDATE"), ROLE_UPDATE("Modification rôle", "ROLE", "UPDATE"),
ROLE_DELETE("Suppression rôle", "ROLE", "DELETE"), ROLE_DELETE("Suppression rôle", "ROLE", "DELETE"),
ROLE_ASSIGN("Attribution rôle", "ROLE", "ASSIGN"), ROLE_ASSIGN("Attribution rôle", "ROLE", "ASSIGN"),
ROLE_REVOKE("Révocation rôle", "ROLE", "REVOKE"), ROLE_REVOKE("Révocation rôle", "ROLE", "REVOKE"),
ROLE_ADD_COMPOSITE("Ajout rôle composite", "ROLE", "ADD_COMPOSITE"), ROLE_ADD_COMPOSITE("Ajout rôle composite", "ROLE", "ADD_COMPOSITE"),
ROLE_REMOVE_COMPOSITE("Retrait rôle composite", "ROLE", "REMOVE_COMPOSITE"), ROLE_REMOVE_COMPOSITE("Retrait rôle composite", "ROLE", "REMOVE_COMPOSITE"),
// Actions Groupe // Actions Groupe
GROUP_CREATE("Création groupe", "GROUP", "CREATE"), GROUP_CREATE("Création groupe", "GROUP", "CREATE"),
GROUP_UPDATE("Modification groupe", "GROUP", "UPDATE"), GROUP_UPDATE("Modification groupe", "GROUP", "UPDATE"),
GROUP_DELETE("Suppression groupe", "GROUP", "DELETE"), GROUP_DELETE("Suppression groupe", "GROUP", "DELETE"),
GROUP_ADD_MEMBER("Ajout membre groupe", "GROUP", "ADD_MEMBER"), GROUP_ADD_MEMBER("Ajout membre groupe", "GROUP", "ADD_MEMBER"),
GROUP_REMOVE_MEMBER("Retrait membre groupe", "GROUP", "REMOVE_MEMBER"), GROUP_REMOVE_MEMBER("Retrait membre groupe", "GROUP", "REMOVE_MEMBER"),
// Actions Realm & Sync // Actions Realm & Sync
REALM_SYNC("Synchronisation realm (Général)", "REALM", "SYNC"), REALM_SYNC("Synchronisation realm (Général)", "REALM", "SYNC"),
SYNC_USERS("Synchronisation utilisateurs", "REALM", "SYNC_USERS"), // Ajout SYNC_USERS("Synchronisation utilisateurs", "REALM", "SYNC_USERS"), // Ajout
SYNC_ROLES("Synchronisation rôles", "REALM", "SYNC_ROLES"), // Ajout SYNC_ROLES("Synchronisation rôles", "REALM", "SYNC_ROLES"), // Ajout
REALM_EXPORT("Export realm", "REALM", "EXPORT"), REALM_EXPORT("Export realm", "REALM", "EXPORT"),
REALM_IMPORT("Import realm", "REALM", "IMPORT"), REALM_IMPORT("Import realm", "REALM", "IMPORT"),
REALM_ASSIGN("Assignation realm", "REALM", "ASSIGN"), REALM_ASSIGN("Assignation realm", "REALM", "ASSIGN"),
REALM_REVOKE("Révocation realm", "REALM", "REVOKE"), REALM_REVOKE("Révocation realm", "REALM", "REVOKE"),
REALM_ACTIVATE("Activation assignation realm", "REALM", "ACTIVATE"), REALM_ACTIVATE("Activation assignation realm", "REALM", "ACTIVATE"),
REALM_DEACTIVATE("Désactivation assignation realm", "REALM", "DEACTIVATE"), REALM_DEACTIVATE("Désactivation assignation realm", "REALM", "DEACTIVATE"),
REALM_SET_SUPER_ADMIN("Définition super admin", "REALM", "SET_SUPER_ADMIN"), REALM_SET_SUPER_ADMIN("Définition super admin", "REALM", "SET_SUPER_ADMIN"),
// Actions Session // Actions Session
SESSION_CREATE("Création session", "SESSION", "CREATE"), SESSION_CREATE("Création session", "SESSION", "CREATE"),
SESSION_DELETE("Suppression session", "SESSION", "DELETE"), SESSION_DELETE("Suppression session", "SESSION", "DELETE"),
SESSION_REVOKE_ALL("Révocation toutes sessions", "SESSION", "REVOKE_ALL"), SESSION_REVOKE_ALL("Révocation toutes sessions", "SESSION", "REVOKE_ALL"),
// Actions Système // Actions Système
SYSTEM_BACKUP("Sauvegarde système", "SYSTEM", "BACKUP"), SYSTEM_BACKUP("Sauvegarde système", "SYSTEM", "BACKUP"),
SYSTEM_RESTORE("Restauration système", "SYSTEM", "RESTORE"), SYSTEM_RESTORE("Restauration système", "SYSTEM", "RESTORE"),
SYSTEM_CONFIG_CHANGE("Modification configuration", "SYSTEM", "CONFIG_CHANGE"); SYSTEM_CONFIG_CHANGE("Modification configuration", "SYSTEM", "CONFIG_CHANGE");
private final String libelle; private final String libelle;
private final String ressourceType; private final String ressourceType;
private final String actionType; private final String actionType;
/** /**
* Détermine si l'action concerne un utilisateur * Détermine si l'action concerne un utilisateur
*/ */
public boolean isUserAction() { public boolean isUserAction() {
return ressourceType.equals("USER"); return ressourceType.equals("USER");
} }
/** /**
* Détermine si l'action concerne un rôle * Détermine si l'action concerne un rôle
*/ */
public boolean isRoleAction() { public boolean isRoleAction() {
return ressourceType.equals("ROLE"); return ressourceType.equals("ROLE");
} }
/** /**
* Détermine si l'action est une création * Détermine si l'action est une création
*/ */
public boolean isCreateAction() { public boolean isCreateAction() {
return actionType.equals("CREATE"); return actionType.equals("CREATE");
} }
/** /**
* Détermine si l'action est une modification * Détermine si l'action est une modification
*/ */
public boolean isUpdateAction() { public boolean isUpdateAction() {
return actionType.equals("UPDATE"); return actionType.equals("UPDATE");
} }
/** /**
* Détermine si l'action est une suppression * Détermine si l'action est une suppression
*/ */
public boolean isDeleteAction() { public boolean isDeleteAction() {
return actionType.equals("DELETE"); return actionType.equals("DELETE");
} }
/** /**
* Détermine si l'action est critique (nécessite alerte) * Détermine si l'action est critique (nécessite alerte)
*/ */
public boolean isCritical() { public boolean isCritical() {
return this == USER_DELETE return this == USER_DELETE
|| this == ROLE_DELETE || this == ROLE_DELETE
|| this == USER_SUSPEND || this == USER_SUSPEND
|| this == SESSION_REVOKE_ALL || this == SESSION_REVOKE_ALL
|| this == SYSTEM_RESTORE; || this == SYSTEM_RESTORE;
} }
} }

View File

@@ -1,60 +1,60 @@
package dev.lions.user.manager.enums.role; package dev.lions.user.manager.enums.role;
import lombok.Getter; import lombok.Getter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.eclipse.microprofile.openapi.annotations.media.Schema;
/** /**
* Type de rôle dans Keycloak * Type de rôle dans Keycloak
* Distingue les rôles au niveau Realm vs Client * Distingue les rôles au niveau Realm vs Client
*/ */
@Getter @Getter
@RequiredArgsConstructor @RequiredArgsConstructor
@Schema(description = "Type de rôle Keycloak") @Schema(description = "Type de rôle Keycloak")
public enum TypeRole { public enum TypeRole {
/** /**
* Rôle global au niveau du Realm * Rôle global au niveau du Realm
* Applicable à tous les clients du realm * Applicable à tous les clients du realm
*/ */
REALM_ROLE("Realm Role", "Rôle global applicable à tous les clients du realm", "realm-role"), REALM_ROLE("Realm Role", "Rôle global applicable à tous les clients du realm", "realm-role"),
/** /**
* Rôle spécifique à un client * Rôle spécifique à un client
* Limité au scope d'un client particulier * Limité au scope d'un client particulier
*/ */
CLIENT_ROLE("Client Role", "Rôle spécifique à un client particulier", "client-role"), CLIENT_ROLE("Client Role", "Rôle spécifique à un client particulier", "client-role"),
/** /**
* Rôle composite (contient d'autres rôles) * Rôle composite (contient d'autres rôles)
*/ */
COMPOSITE_ROLE("Composite Role", "Rôle composite contenant d'autres rôles", "composite-role"); COMPOSITE_ROLE("Composite Role", "Rôle composite contenant d'autres rôles", "composite-role");
private final String libelle; private final String libelle;
private final String description; private final String description;
private final String codeKeycloak; private final String codeKeycloak;
/** /**
* Détermine si le rôle est au niveau realm * Détermine si le rôle est au niveau realm
* @return true si c'est un realm role * @return true si c'est un realm role
*/ */
public boolean isRealmRole() { public boolean isRealmRole() {
return this == REALM_ROLE; return this == REALM_ROLE;
} }
/** /**
* Détermine si le rôle est au niveau client * Détermine si le rôle est au niveau client
* @return true si c'est un client role * @return true si c'est un client role
*/ */
public boolean isClientRole() { public boolean isClientRole() {
return this == CLIENT_ROLE; return this == CLIENT_ROLE;
} }
/** /**
* Détermine si le rôle est composite * Détermine si le rôle est composite
* @return true si c'est un composite role * @return true si c'est un composite role
*/ */
public boolean isComposite() { public boolean isComposite() {
return this == COMPOSITE_ROLE; return this == COMPOSITE_ROLE;
} }
} }

View File

@@ -1,79 +1,79 @@
package dev.lions.user.manager.enums.user; package dev.lions.user.manager.enums.user;
import lombok.Getter; import lombok.Getter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.eclipse.microprofile.openapi.annotations.media.Schema;
/** /**
* Statut d'un utilisateur dans Keycloak * Statut d'un utilisateur dans Keycloak
* Mappé depuis le champ "enabled" et attributs personnalisés * Mappé depuis le champ "enabled" et attributs personnalisés
*/ */
@Getter @Getter
@RequiredArgsConstructor @RequiredArgsConstructor
@Schema(description = "Statut d'un utilisateur") @Schema(description = "Statut d'un utilisateur")
public enum StatutUser { public enum StatutUser {
/** /**
* Utilisateur actif et opérationnel * Utilisateur actif et opérationnel
*/ */
ACTIF("Actif", "Utilisateur actif avec accès complet", true), ACTIF("Actif", "Utilisateur actif avec accès complet", true),
/** /**
* Utilisateur désactivé temporairement (peut être réactivé) * Utilisateur désactivé temporairement (peut être réactivé)
*/ */
INACTIF("Inactif", "Utilisateur désactivé temporairement", false), INACTIF("Inactif", "Utilisateur désactivé temporairement", false),
/** /**
* Utilisateur suspendu suite à une action administrative * Utilisateur suspendu suite à une action administrative
*/ */
SUSPENDU("Suspendu", "Compte suspendu par un administrateur", false), SUSPENDU("Suspendu", "Compte suspendu par un administrateur", false),
/** /**
* Utilisateur en attente de validation * Utilisateur en attente de validation
*/ */
EN_ATTENTE("En attente", "Compte en attente de validation", false), EN_ATTENTE("En attente", "Compte en attente de validation", false),
/** /**
* Utilisateur verrouillé suite à des tentatives échouées * Utilisateur verrouillé suite à des tentatives échouées
*/ */
VERROUILLE("Verrouillé", "Compte verrouillé suite à plusieurs échecs d'authentification", false), VERROUILLE("Verrouillé", "Compte verrouillé suite à plusieurs échecs d'authentification", false),
/** /**
* Utilisateur dont le compte a expiré * Utilisateur dont le compte a expiré
*/ */
EXPIRE("Expiré", "Compte expiré et nécessite une réactivation", false), EXPIRE("Expiré", "Compte expiré et nécessite une réactivation", false),
/** /**
* Utilisateur supprimé (soft delete) * Utilisateur supprimé (soft delete)
*/ */
SUPPRIME("Supprimé", "Compte supprimé logiquement", false); SUPPRIME("Supprimé", "Compte supprimé logiquement", false);
private final String libelle; private final String libelle;
private final String description; private final String description;
private final boolean enabled; private final boolean enabled;
/** /**
* Convertit un statut Keycloak "enabled" en StatutUser * Convertit un statut Keycloak "enabled" en StatutUser
* @param enabled état enabled de Keycloak * @param enabled état enabled de Keycloak
* @return ACTIF si enabled=true, INACTIF sinon * @return ACTIF si enabled=true, INACTIF sinon
*/ */
public static StatutUser fromEnabled(boolean enabled) { public static StatutUser fromEnabled(boolean enabled) {
return enabled ? ACTIF : INACTIF; return enabled ? ACTIF : INACTIF;
} }
/** /**
* Détermine si l'utilisateur peut se connecter * Détermine si l'utilisateur peut se connecter
* @return true si le statut permet la connexion * @return true si le statut permet la connexion
*/ */
public boolean peutSeConnecter() { public boolean peutSeConnecter() {
return this == ACTIF; return this == ACTIF;
} }
/** /**
* Détermine si l'utilisateur peut être réactivé * Détermine si l'utilisateur peut être réactivé
* @return true si le statut permet la réactivation * @return true si le statut permet la réactivation
*/ */
public boolean peutEtreReactive() { public boolean peutEtreReactive() {
return this == INACTIF || this == SUSPENDU || this == EXPIRE; return this == INACTIF || this == SUSPENDU || this == EXPIRE;
} }
} }

View File

@@ -1,219 +1,219 @@
package dev.lions.user.manager.service; package dev.lions.user.manager.service;
import dev.lions.user.manager.dto.audit.AuditLogDTO; import dev.lions.user.manager.dto.audit.AuditLogDTO;
import dev.lions.user.manager.enums.audit.TypeActionAudit; import dev.lions.user.manager.enums.audit.TypeActionAudit;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
* Service de gestion des logs d'audit * Service de gestion des logs d'audit
* Enregistre toutes les actions effectuées via l'API * Enregistre toutes les actions effectuées via l'API
*/ */
public interface AuditService { public interface AuditService {
/** /**
* Enregistre une entrée d'audit * Enregistre une entrée d'audit
* @param auditLog entrée d'audit * @param auditLog entrée d'audit
* @return entrée enregistrée avec son ID * @return entrée enregistrée avec son ID
*/ */
AuditLogDTO logAction(@Valid @NotNull AuditLogDTO auditLog); AuditLogDTO logAction(@Valid @NotNull AuditLogDTO auditLog);
/** /**
* Enregistre une action réussie * Enregistre une action réussie
* @param typeAction type d'action * @param typeAction type d'action
* @param ressourceType type de ressource * @param ressourceType type de ressource
* @param ressourceId ID de la ressource * @param ressourceId ID de la ressource
* @param ressourceName nom de la ressource * @param ressourceName nom de la ressource
* @param realmName nom du realm * @param realmName nom du realm
* @param acteurUserId ID de l'acteur * @param acteurUserId ID de l'acteur
* @param description description * @param description description
*/ */
void logSuccess(@NotNull TypeActionAudit typeAction, void logSuccess(@NotNull TypeActionAudit typeAction,
@NotBlank String ressourceType, @NotBlank String ressourceType,
String ressourceId, String ressourceId,
String ressourceName, String ressourceName,
@NotBlank String realmName, @NotBlank String realmName,
@NotBlank String acteurUserId, @NotBlank String acteurUserId,
String description); String description);
/** /**
* Enregistre une action échouée * Enregistre une action échouée
* @param typeAction type d'action * @param typeAction type d'action
* @param ressourceType type de ressource * @param ressourceType type de ressource
* @param ressourceId ID de la ressource * @param ressourceId ID de la ressource
* @param ressourceName nom de la ressource * @param ressourceName nom de la ressource
* @param realmName nom du realm * @param realmName nom du realm
* @param acteurUserId ID de l'acteur * @param acteurUserId ID de l'acteur
* @param errorCode code d'erreur * @param errorCode code d'erreur
* @param errorMessage message d'erreur * @param errorMessage message d'erreur
*/ */
void logFailure(@NotNull TypeActionAudit typeAction, void logFailure(@NotNull TypeActionAudit typeAction,
@NotBlank String ressourceType, @NotBlank String ressourceType,
String ressourceId, String ressourceId,
String ressourceName, String ressourceName,
@NotBlank String realmName, @NotBlank String realmName,
@NotBlank String acteurUserId, @NotBlank String acteurUserId,
String errorCode, String errorCode,
String errorMessage); String errorMessage);
/** /**
* Recherche les logs d'audit par utilisateur acteur * Recherche les logs d'audit par utilisateur acteur
* @param acteurUserId ID de l'utilisateur acteur * @param acteurUserId ID de l'utilisateur acteur
* @param dateDebut date de début * @param dateDebut date de début
* @param dateFin date de fin * @param dateFin date de fin
* @param page numéro de page * @param page numéro de page
* @param pageSize taille de la page * @param pageSize taille de la page
* @return liste des logs * @return liste des logs
*/ */
List<AuditLogDTO> findByActeur(@NotBlank String acteurUserId, List<AuditLogDTO> findByActeur(@NotBlank String acteurUserId,
LocalDateTime dateDebut, LocalDateTime dateDebut,
LocalDateTime dateFin, LocalDateTime dateFin,
int page, int page,
int pageSize); int pageSize);
/** /**
* Recherche les logs d'audit par ressource * Recherche les logs d'audit par ressource
* @param ressourceType type de ressource * @param ressourceType type de ressource
* @param ressourceId ID de la ressource * @param ressourceId ID de la ressource
* @param dateDebut date de début * @param dateDebut date de début
* @param dateFin date de fin * @param dateFin date de fin
* @param page numéro de page * @param page numéro de page
* @param pageSize taille de la page * @param pageSize taille de la page
* @return liste des logs * @return liste des logs
*/ */
List<AuditLogDTO> findByRessource(@NotBlank String ressourceType, List<AuditLogDTO> findByRessource(@NotBlank String ressourceType,
@NotBlank String ressourceId, @NotBlank String ressourceId,
LocalDateTime dateDebut, LocalDateTime dateDebut,
LocalDateTime dateFin, LocalDateTime dateFin,
int page, int page,
int pageSize); int pageSize);
/** /**
* Recherche les logs d'audit par type d'action * Recherche les logs d'audit par type d'action
* @param typeAction type d'action * @param typeAction type d'action
* @param realmName nom du realm * @param realmName nom du realm
* @param dateDebut date de début * @param dateDebut date de début
* @param dateFin date de fin * @param dateFin date de fin
* @param page numéro de page * @param page numéro de page
* @param pageSize taille de la page * @param pageSize taille de la page
* @return liste des logs * @return liste des logs
*/ */
List<AuditLogDTO> findByTypeAction(@NotNull TypeActionAudit typeAction, List<AuditLogDTO> findByTypeAction(@NotNull TypeActionAudit typeAction,
@NotBlank String realmName, @NotBlank String realmName,
LocalDateTime dateDebut, LocalDateTime dateDebut,
LocalDateTime dateFin, LocalDateTime dateFin,
int page, int page,
int pageSize); int pageSize);
/** /**
* Recherche les logs d'audit par realm * Recherche les logs d'audit par realm
* @param realmName nom du realm * @param realmName nom du realm
* @param dateDebut date de début * @param dateDebut date de début
* @param dateFin date de fin * @param dateFin date de fin
* @param page numéro de page * @param page numéro de page
* @param pageSize taille de la page * @param pageSize taille de la page
* @return liste des logs * @return liste des logs
*/ */
List<AuditLogDTO> findByRealm(@NotBlank String realmName, List<AuditLogDTO> findByRealm(@NotBlank String realmName,
LocalDateTime dateDebut, LocalDateTime dateDebut,
LocalDateTime dateFin, LocalDateTime dateFin,
int page, int page,
int pageSize); int pageSize);
/** /**
* Recherche les actions échouées * Recherche les actions échouées
* @param realmName nom du realm * @param realmName nom du realm
* @param dateDebut date de début * @param dateDebut date de début
* @param dateFin date de fin * @param dateFin date de fin
* @param page numéro de page * @param page numéro de page
* @param pageSize taille de la page * @param pageSize taille de la page
* @return liste des logs d'échec * @return liste des logs d'échec
*/ */
List<AuditLogDTO> findFailures(@NotBlank String realmName, List<AuditLogDTO> findFailures(@NotBlank String realmName,
LocalDateTime dateDebut, LocalDateTime dateDebut,
LocalDateTime dateFin, LocalDateTime dateFin,
int page, int page,
int pageSize); int pageSize);
/** /**
* Recherche les actions critiques * Recherche les actions critiques
* @param realmName nom du realm * @param realmName nom du realm
* @param dateDebut date de début * @param dateDebut date de début
* @param dateFin date de fin * @param dateFin date de fin
* @param page numéro de page * @param page numéro de page
* @param pageSize taille de la page * @param pageSize taille de la page
* @return liste des logs critiques * @return liste des logs critiques
*/ */
List<AuditLogDTO> findCriticalActions(@NotBlank String realmName, List<AuditLogDTO> findCriticalActions(@NotBlank String realmName,
LocalDateTime dateDebut, LocalDateTime dateDebut,
LocalDateTime dateFin, LocalDateTime dateFin,
int page, int page,
int pageSize); int pageSize);
/** /**
* Compte les actions par type * Compte les actions par type
* @param realmName nom du realm * @param realmName nom du realm
* @param dateDebut date de début * @param dateDebut date de début
* @param dateFin date de fin * @param dateFin date de fin
* @return map type d'action -> nombre * @return map type d'action -> nombre
*/ */
Map<TypeActionAudit, Long> countByActionType(@NotBlank String realmName, Map<TypeActionAudit, Long> countByActionType(@NotBlank String realmName,
LocalDateTime dateDebut, LocalDateTime dateDebut,
LocalDateTime dateFin); LocalDateTime dateFin);
/** /**
* Compte les actions par utilisateur * Compte les actions par utilisateur
* @param realmName nom du realm * @param realmName nom du realm
* @param dateDebut date de début * @param dateDebut date de début
* @param dateFin date de fin * @param dateFin date de fin
* @return map username -> nombre d'actions * @return map username -> nombre d'actions
*/ */
Map<String, Long> countByActeur(@NotBlank String realmName, Map<String, Long> countByActeur(@NotBlank String realmName,
LocalDateTime dateDebut, LocalDateTime dateDebut,
LocalDateTime dateFin); LocalDateTime dateFin);
/** /**
* Compte les actions réussies vs échouées * Compte les actions réussies vs échouées
* @param realmName nom du realm * @param realmName nom du realm
* @param dateDebut date de début * @param dateDebut date de début
* @param dateFin date de fin * @param dateFin date de fin
* @return map "success" -> count, "failure" -> count * @return map "success" -> count, "failure" -> count
*/ */
Map<String, Long> countSuccessVsFailure(@NotBlank String realmName, Map<String, Long> countSuccessVsFailure(@NotBlank String realmName,
LocalDateTime dateDebut, LocalDateTime dateDebut,
LocalDateTime dateFin); LocalDateTime dateFin);
/** /**
* Exporte les logs d'audit au format CSV * Exporte les logs d'audit au format CSV
* @param realmName nom du realm * @param realmName nom du realm
* @param dateDebut date de début * @param dateDebut date de début
* @param dateFin date de fin * @param dateFin date de fin
* @return contenu CSV * @return contenu CSV
*/ */
String exportToCSV(@NotBlank String realmName, String exportToCSV(@NotBlank String realmName,
LocalDateTime dateDebut, LocalDateTime dateDebut,
LocalDateTime dateFin); LocalDateTime dateFin);
/** /**
* Supprime les logs d'audit plus anciens qu'une date * Supprime les logs d'audit plus anciens qu'une date
* @param dateLimite date limite (logs antérieurs seront supprimés) * @param dateLimite date limite (logs antérieurs seront supprimés)
* @return nombre de logs supprimés * @return nombre de logs supprimés
*/ */
long purgeOldLogs(@NotNull LocalDateTime dateLimite); long purgeOldLogs(@NotNull LocalDateTime dateLimite);
/** /**
* Récupère les statistiques d'audit pour un dashboard * Récupère les statistiques d'audit pour un dashboard
* @param realmName nom du realm * @param realmName nom du realm
* @param dateDebut date de début * @param dateDebut date de début
* @param dateFin date de fin * @param dateFin date de fin
* @return map de statistiques * @return map de statistiques
*/ */
Map<String, Object> getAuditStatistics(@NotBlank String realmName, Map<String, Object> getAuditStatistics(@NotBlank String realmName,
LocalDateTime dateDebut, LocalDateTime dateDebut,
LocalDateTime dateFin); LocalDateTime dateFin);
} }

View File

@@ -1,132 +1,132 @@
package dev.lions.user.manager.service; package dev.lions.user.manager.service;
import dev.lions.user.manager.dto.realm.RealmAssignmentDTO; import dev.lions.user.manager.dto.realm.RealmAssignmentDTO;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
/** /**
* Service de gestion des autorisations multi-tenant par realm * Service de gestion des autorisations multi-tenant par realm
* Permet de contrôler quels utilisateurs peuvent administrer quels realms * Permet de contrôler quels utilisateurs peuvent administrer quels realms
*/ */
public interface RealmAuthorizationService { public interface RealmAuthorizationService {
/** /**
* Récupère toutes les assignations de realms * Récupère toutes les assignations de realms
* @return liste de toutes les assignations * @return liste de toutes les assignations
*/ */
List<RealmAssignmentDTO> getAllAssignments(); List<RealmAssignmentDTO> getAllAssignments();
/** /**
* Récupère les assignations pour un utilisateur spécifique * Récupère les assignations pour un utilisateur spécifique
* @param userId ID de l'utilisateur Keycloak * @param userId ID de l'utilisateur Keycloak
* @return liste des realms assignés à cet utilisateur * @return liste des realms assignés à cet utilisateur
*/ */
List<RealmAssignmentDTO> getAssignmentsByUser(@NotBlank String userId); List<RealmAssignmentDTO> getAssignmentsByUser(@NotBlank String userId);
/** /**
* Récupère les assignations pour un realm spécifique * Récupère les assignations pour un realm spécifique
* @param realmName nom du realm * @param realmName nom du realm
* @return liste des utilisateurs ayant accès à ce realm * @return liste des utilisateurs ayant accès à ce realm
*/ */
List<RealmAssignmentDTO> getAssignmentsByRealm(@NotBlank String realmName); List<RealmAssignmentDTO> getAssignmentsByRealm(@NotBlank String realmName);
/** /**
* Récupère une assignation spécifique * Récupère une assignation spécifique
* @param assignmentId ID de l'assignation * @param assignmentId ID de l'assignation
* @return assignation ou Optional vide * @return assignation ou Optional vide
*/ */
Optional<RealmAssignmentDTO> getAssignmentById(@NotBlank String assignmentId); Optional<RealmAssignmentDTO> getAssignmentById(@NotBlank String assignmentId);
/** /**
* Vérifie si un utilisateur peut administrer un realm donné * Vérifie si un utilisateur peut administrer un realm donné
* @param userId ID de l'utilisateur * @param userId ID de l'utilisateur
* @param realmName nom du realm * @param realmName nom du realm
* @return true si l'utilisateur peut administrer ce realm * @return true si l'utilisateur peut administrer ce realm
*/ */
boolean canManageRealm(@NotBlank String userId, @NotBlank String realmName); boolean canManageRealm(@NotBlank String userId, @NotBlank String realmName);
/** /**
* Vérifie si un utilisateur est super admin (peut tout gérer) * Vérifie si un utilisateur est super admin (peut tout gérer)
* @param userId ID de l'utilisateur * @param userId ID de l'utilisateur
* @return true si super admin * @return true si super admin
*/ */
boolean isSuperAdmin(@NotBlank String userId); boolean isSuperAdmin(@NotBlank String userId);
/** /**
* Récupère la liste des realms qu'un utilisateur peut administrer * Récupère la liste des realms qu'un utilisateur peut administrer
* @param userId ID de l'utilisateur * @param userId ID de l'utilisateur
* @return liste des noms de realms, ou liste vide si super admin (peut tout gérer) * @return liste des noms de realms, ou liste vide si super admin (peut tout gérer)
*/ */
List<String> getAuthorizedRealms(@NotBlank String userId); List<String> getAuthorizedRealms(@NotBlank String userId);
/** /**
* Assigne un realm à un utilisateur * Assigne un realm à un utilisateur
* @param assignment données de l'assignation * @param assignment données de l'assignation
* @return assignation créée * @return assignation créée
*/ */
RealmAssignmentDTO assignRealmToUser(@Valid @NotNull RealmAssignmentDTO assignment); RealmAssignmentDTO assignRealmToUser(@Valid @NotNull RealmAssignmentDTO assignment);
/** /**
* Retire l'accès d'un utilisateur à un realm * Retire l'accès d'un utilisateur à un realm
* @param userId ID de l'utilisateur * @param userId ID de l'utilisateur
* @param realmName nom du realm * @param realmName nom du realm
*/ */
void revokeRealmFromUser(@NotBlank String userId, @NotBlank String realmName); void revokeRealmFromUser(@NotBlank String userId, @NotBlank String realmName);
/** /**
* Retire toutes les assignations d'un utilisateur * Retire toutes les assignations d'un utilisateur
* @param userId ID de l'utilisateur * @param userId ID de l'utilisateur
*/ */
void revokeAllRealmsFromUser(@NotBlank String userId); void revokeAllRealmsFromUser(@NotBlank String userId);
/** /**
* Retire toutes les assignations pour un realm * Retire toutes les assignations pour un realm
* @param realmName nom du realm * @param realmName nom du realm
*/ */
void revokeAllUsersFromRealm(@NotBlank String realmName); void revokeAllUsersFromRealm(@NotBlank String realmName);
/** /**
* Définit un utilisateur comme super admin * Définit un utilisateur comme super admin
* @param userId ID de l'utilisateur * @param userId ID de l'utilisateur
* @param superAdmin true pour définir comme super admin, false pour retirer * @param superAdmin true pour définir comme super admin, false pour retirer
*/ */
void setSuperAdmin(@NotBlank String userId, boolean superAdmin); void setSuperAdmin(@NotBlank String userId, boolean superAdmin);
/** /**
* Désactive une assignation (sans la supprimer) * Désactive une assignation (sans la supprimer)
* @param assignmentId ID de l'assignation * @param assignmentId ID de l'assignation
*/ */
void deactivateAssignment(@NotBlank String assignmentId); void deactivateAssignment(@NotBlank String assignmentId);
/** /**
* Réactive une assignation * Réactive une assignation
* @param assignmentId ID de l'assignation * @param assignmentId ID de l'assignation
*/ */
void activateAssignment(@NotBlank String assignmentId); void activateAssignment(@NotBlank String assignmentId);
/** /**
* Compte le nombre d'assignations pour un utilisateur * Compte le nombre d'assignations pour un utilisateur
* @param userId ID de l'utilisateur * @param userId ID de l'utilisateur
* @return nombre d'assignations actives * @return nombre d'assignations actives
*/ */
long countAssignmentsByUser(@NotBlank String userId); long countAssignmentsByUser(@NotBlank String userId);
/** /**
* Compte le nombre d'utilisateurs ayant accès à un realm * Compte le nombre d'utilisateurs ayant accès à un realm
* @param realmName nom du realm * @param realmName nom du realm
* @return nombre d'utilisateurs * @return nombre d'utilisateurs
*/ */
long countUsersByRealm(@NotBlank String realmName); long countUsersByRealm(@NotBlank String realmName);
/** /**
* Vérifie si une assignation existe * Vérifie si une assignation existe
* @param userId ID de l'utilisateur * @param userId ID de l'utilisateur
* @param realmName nom du realm * @param realmName nom du realm
* @return true si l'assignation existe * @return true si l'assignation existe
*/ */
boolean assignmentExists(@NotBlank String userId, @NotBlank String realmName); boolean assignmentExists(@NotBlank String userId, @NotBlank String realmName);
} }

View File

@@ -1,226 +1,226 @@
package dev.lions.user.manager.service; package dev.lions.user.manager.service;
import dev.lions.user.manager.dto.role.RoleAssignmentDTO; import dev.lions.user.manager.dto.role.RoleAssignmentDTO;
import dev.lions.user.manager.dto.role.RoleDTO; import dev.lions.user.manager.dto.role.RoleDTO;
import dev.lions.user.manager.enums.role.TypeRole; import dev.lions.user.manager.enums.role.TypeRole;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
/** /**
* Service de gestion des rôles Keycloak * Service de gestion des rôles Keycloak
* Utilise uniquement l'API Admin Keycloak (AUCUN accès direct à la DB) * Utilise uniquement l'API Admin Keycloak (AUCUN accès direct à la DB)
*/ */
public interface RoleService { public interface RoleService {
/** /**
* Récupère tous les rôles d'un realm * Récupère tous les rôles d'un realm
* @param realmName nom du realm * @param realmName nom du realm
* @return liste des rôles * @return liste des rôles
*/ */
List<RoleDTO> getAllRealmRoles(@NotBlank String realmName); List<RoleDTO> getAllRealmRoles(@NotBlank String realmName);
/** /**
* Récupère tous les rôles d'un client * Récupère tous les rôles d'un client
* @param realmName nom du realm * @param realmName nom du realm
* @param clientName nom du client * @param clientName nom du client
* @return liste des rôles * @return liste des rôles
*/ */
List<RoleDTO> getAllClientRoles(@NotBlank String realmName, @NotBlank String clientName); List<RoleDTO> getAllClientRoles(@NotBlank String realmName, @NotBlank String clientName);
/** /**
* Récupère un rôle par son ID * Récupère un rôle par son ID
* @param roleId ID du rôle * @param roleId ID du rôle
* @param realmName nom du realm * @param realmName nom du realm
* @param typeRole type de rôle (REALM ou CLIENT) * @param typeRole type de rôle (REALM ou CLIENT)
* @param clientName nom du client (si CLIENT_ROLE) * @param clientName nom du client (si CLIENT_ROLE)
* @return rôle ou Optional vide * @return rôle ou Optional vide
*/ */
Optional<RoleDTO> getRoleById(@NotBlank String roleId, Optional<RoleDTO> getRoleById(@NotBlank String roleId,
@NotBlank String realmName, @NotBlank String realmName,
@NotNull TypeRole typeRole, @NotNull TypeRole typeRole,
String clientName); String clientName);
/** /**
* Récupère un rôle par son nom * Récupère un rôle par son nom
* @param roleName nom du rôle * @param roleName nom du rôle
* @param realmName nom du realm * @param realmName nom du realm
* @param typeRole type de rôle (REALM ou CLIENT) * @param typeRole type de rôle (REALM ou CLIENT)
* @param clientName nom du client (si CLIENT_ROLE) * @param clientName nom du client (si CLIENT_ROLE)
* @return rôle ou Optional vide * @return rôle ou Optional vide
*/ */
Optional<RoleDTO> getRoleByName(@NotBlank String roleName, Optional<RoleDTO> getRoleByName(@NotBlank String roleName,
@NotBlank String realmName, @NotBlank String realmName,
@NotNull TypeRole typeRole, @NotNull TypeRole typeRole,
String clientName); String clientName);
/** /**
* Crée un nouveau rôle realm * Crée un nouveau rôle realm
* @param role données du rôle * @param role données du rôle
* @param realmName nom du realm * @param realmName nom du realm
* @return rôle créé * @return rôle créé
*/ */
RoleDTO createRealmRole(@Valid @NotNull RoleDTO role, @NotBlank String realmName); RoleDTO createRealmRole(@Valid @NotNull RoleDTO role, @NotBlank String realmName);
/** /**
* Crée un nouveau rôle client * Crée un nouveau rôle client
* @param role données du rôle * @param role données du rôle
* @param realmName nom du realm * @param realmName nom du realm
* @param clientName nom du client * @param clientName nom du client
* @return rôle créé * @return rôle créé
*/ */
RoleDTO createClientRole(@Valid @NotNull RoleDTO role, RoleDTO createClientRole(@Valid @NotNull RoleDTO role,
@NotBlank String realmName, @NotBlank String realmName,
@NotBlank String clientName); @NotBlank String clientName);
/** /**
* Met à jour un rôle * Met à jour un rôle
* @param roleId ID du rôle * @param roleId ID du rôle
* @param role données modifiées * @param role données modifiées
* @param realmName nom du realm * @param realmName nom du realm
* @param typeRole type de rôle * @param typeRole type de rôle
* @param clientName nom du client (si CLIENT_ROLE) * @param clientName nom du client (si CLIENT_ROLE)
* @return rôle mis à jour * @return rôle mis à jour
*/ */
RoleDTO updateRole(@NotBlank String roleId, RoleDTO updateRole(@NotBlank String roleId,
@Valid @NotNull RoleDTO role, @Valid @NotNull RoleDTO role,
@NotBlank String realmName, @NotBlank String realmName,
@NotNull TypeRole typeRole, @NotNull TypeRole typeRole,
String clientName); String clientName);
/** /**
* Supprime un rôle * Supprime un rôle
* @param roleId ID du rôle * @param roleId ID du rôle
* @param realmName nom du realm * @param realmName nom du realm
* @param typeRole type de rôle * @param typeRole type de rôle
* @param clientName nom du client (si CLIENT_ROLE) * @param clientName nom du client (si CLIENT_ROLE)
*/ */
void deleteRole(@NotBlank String roleId, void deleteRole(@NotBlank String roleId,
@NotBlank String realmName, @NotBlank String realmName,
@NotNull TypeRole typeRole, @NotNull TypeRole typeRole,
String clientName); String clientName);
/** /**
* Assigne des rôles à un utilisateur * Assigne des rôles à un utilisateur
* @param assignment données d'attribution * @param assignment données d'attribution
*/ */
void assignRolesToUser(@Valid @NotNull RoleAssignmentDTO assignment); void assignRolesToUser(@Valid @NotNull RoleAssignmentDTO assignment);
/** /**
* Révoque des rôles d'un utilisateur * Révoque des rôles d'un utilisateur
* @param assignment données de révocation * @param assignment données de révocation
*/ */
void revokeRolesFromUser(@Valid @NotNull RoleAssignmentDTO assignment); void revokeRolesFromUser(@Valid @NotNull RoleAssignmentDTO assignment);
/** /**
* Récupère les rôles realm d'un utilisateur * Récupère les rôles realm d'un utilisateur
* @param userId ID de l'utilisateur * @param userId ID de l'utilisateur
* @param realmName nom du realm * @param realmName nom du realm
* @return liste des rôles * @return liste des rôles
*/ */
List<RoleDTO> getUserRealmRoles(@NotBlank String userId, @NotBlank String realmName); List<RoleDTO> getUserRealmRoles(@NotBlank String userId, @NotBlank String realmName);
/** /**
* Récupère les rôles client d'un utilisateur * Récupère les rôles client d'un utilisateur
* @param userId ID de l'utilisateur * @param userId ID de l'utilisateur
* @param realmName nom du realm * @param realmName nom du realm
* @param clientName nom du client * @param clientName nom du client
* @return liste des rôles * @return liste des rôles
*/ */
List<RoleDTO> getUserClientRoles(@NotBlank String userId, List<RoleDTO> getUserClientRoles(@NotBlank String userId,
@NotBlank String realmName, @NotBlank String realmName,
@NotBlank String clientName); @NotBlank String clientName);
/** /**
* Récupère tous les rôles d'un utilisateur (realm + clients) * Récupère tous les rôles d'un utilisateur (realm + clients)
* @param userId ID de l'utilisateur * @param userId ID de l'utilisateur
* @param realmName nom du realm * @param realmName nom du realm
* @return liste des rôles * @return liste des rôles
*/ */
List<RoleDTO> getAllUserRoles(@NotBlank String userId, @NotBlank String realmName); List<RoleDTO> getAllUserRoles(@NotBlank String userId, @NotBlank String realmName);
/** /**
* Ajoute un rôle composite * Ajoute un rôle composite
* @param parentRoleId ID du rôle parent * @param parentRoleId ID du rôle parent
* @param childRoleIds IDs des rôles enfants à ajouter * @param childRoleIds IDs des rôles enfants à ajouter
* @param realmName nom du realm * @param realmName nom du realm
* @param typeRole type du rôle parent * @param typeRole type du rôle parent
* @param clientName nom du client (si CLIENT_ROLE) * @param clientName nom du client (si CLIENT_ROLE)
*/ */
void addCompositeRoles(@NotBlank String parentRoleId, void addCompositeRoles(@NotBlank String parentRoleId,
@NotNull List<String> childRoleIds, @NotNull List<String> childRoleIds,
@NotBlank String realmName, @NotBlank String realmName,
@NotNull TypeRole typeRole, @NotNull TypeRole typeRole,
String clientName); String clientName);
/** /**
* Retire un rôle composite * Retire un rôle composite
* @param parentRoleId ID du rôle parent * @param parentRoleId ID du rôle parent
* @param childRoleIds IDs des rôles enfants à retirer * @param childRoleIds IDs des rôles enfants à retirer
* @param realmName nom du realm * @param realmName nom du realm
* @param typeRole type du rôle parent * @param typeRole type du rôle parent
* @param clientName nom du client (si CLIENT_ROLE) * @param clientName nom du client (si CLIENT_ROLE)
*/ */
void removeCompositeRoles(@NotBlank String parentRoleId, void removeCompositeRoles(@NotBlank String parentRoleId,
@NotNull List<String> childRoleIds, @NotNull List<String> childRoleIds,
@NotBlank String realmName, @NotBlank String realmName,
@NotNull TypeRole typeRole, @NotNull TypeRole typeRole,
String clientName); String clientName);
/** /**
* Récupère les rôles composites d'un rôle * Récupère les rôles composites d'un rôle
* @param roleId ID du rôle * @param roleId ID du rôle
* @param realmName nom du realm * @param realmName nom du realm
* @param typeRole type de rôle * @param typeRole type de rôle
* @param clientName nom du client (si CLIENT_ROLE) * @param clientName nom du client (si CLIENT_ROLE)
* @return liste des rôles composites * @return liste des rôles composites
*/ */
List<RoleDTO> getCompositeRoles(@NotBlank String roleId, List<RoleDTO> getCompositeRoles(@NotBlank String roleId,
@NotBlank String realmName, @NotBlank String realmName,
@NotNull TypeRole typeRole, @NotNull TypeRole typeRole,
String clientName); String clientName);
/** /**
* Compte le nombre d'utilisateurs ayant un rôle * Compte le nombre d'utilisateurs ayant un rôle
* @param roleId ID du rôle * @param roleId ID du rôle
* @param realmName nom du realm * @param realmName nom du realm
* @param typeRole type de rôle * @param typeRole type de rôle
* @param clientName nom du client (si CLIENT_ROLE) * @param clientName nom du client (si CLIENT_ROLE)
* @return nombre d'utilisateurs * @return nombre d'utilisateurs
*/ */
long countUsersWithRole(@NotBlank String roleId, long countUsersWithRole(@NotBlank String roleId,
@NotBlank String realmName, @NotBlank String realmName,
@NotNull TypeRole typeRole, @NotNull TypeRole typeRole,
String clientName); String clientName);
/** /**
* Vérifie si un rôle existe * Vérifie si un rôle existe
* @param roleName nom du rôle * @param roleName nom du rôle
* @param realmName nom du realm * @param realmName nom du realm
* @param typeRole type de rôle * @param typeRole type de rôle
* @param clientName nom du client (si CLIENT_ROLE) * @param clientName nom du client (si CLIENT_ROLE)
* @return true si existe * @return true si existe
*/ */
boolean roleExists(@NotBlank String roleName, boolean roleExists(@NotBlank String roleName,
@NotBlank String realmName, @NotBlank String realmName,
@NotNull TypeRole typeRole, @NotNull TypeRole typeRole,
String clientName); String clientName);
/** /**
* Vérifie si un utilisateur a un rôle spécifique * Vérifie si un utilisateur a un rôle spécifique
* @param userId ID de l'utilisateur * @param userId ID de l'utilisateur
* @param roleName nom du rôle * @param roleName nom du rôle
* @param realmName nom du realm * @param realmName nom du realm
* @param typeRole type de rôle * @param typeRole type de rôle
* @param clientName nom du client (si CLIENT_ROLE) * @param clientName nom du client (si CLIENT_ROLE)
* @return true si l'utilisateur a le rôle * @return true si l'utilisateur a le rôle
*/ */
boolean userHasRole(@NotBlank String userId, boolean userHasRole(@NotBlank String userId,
@NotBlank String roleName, @NotBlank String roleName,
@NotBlank String realmName, @NotBlank String realmName,
@NotNull TypeRole typeRole, @NotNull TypeRole typeRole,
String clientName); String clientName);
} }

View File

@@ -1,65 +1,65 @@
package dev.lions.user.manager.service; package dev.lions.user.manager.service;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import java.util.Map; import java.util.Map;
/** /**
* Service de synchronisation avec Keycloak * Service de synchronisation avec Keycloak
* Permet la synchronisation des données entre différents realms * Permet la synchronisation des données entre différents realms
*/ */
public interface SyncService { public interface SyncService {
/** /**
* Synchronise les utilisateurs d'un realm * Synchronise les utilisateurs d'un realm
* @param realmName nom du realm à synchroniser * @param realmName nom du realm à synchroniser
* @return nombre d'utilisateurs synchronisés * @return nombre d'utilisateurs synchronisés
*/ */
int syncUsersFromRealm(@NotBlank String realmName); int syncUsersFromRealm(@NotBlank String realmName);
/** /**
* Synchronise les rôles d'un realm * Synchronise les rôles d'un realm
* @param realmName nom du realm à synchroniser * @param realmName nom du realm à synchroniser
* @return nombre de rôles synchronisés * @return nombre de rôles synchronisés
*/ */
int syncRolesFromRealm(@NotBlank String realmName); int syncRolesFromRealm(@NotBlank String realmName);
/** /**
* Synchronise tous les realms configurés * Synchronise tous les realms configurés
* @return map realm -> nombre d'éléments synchronisés * @return map realm -> nombre d'éléments synchronisés
*/ */
Map<String, Integer> syncAllRealms(); Map<String, Integer> syncAllRealms();
/** /**
* Vérifie la cohérence des données entre cache local et Keycloak * Vérifie la cohérence des données entre cache local et Keycloak
* @param realmName nom du realm * @param realmName nom du realm
* @return rapport de cohérence * @return rapport de cohérence
*/ */
Map<String, Object> checkDataConsistency(@NotBlank String realmName); Map<String, Object> checkDataConsistency(@NotBlank String realmName);
/** /**
* Force la resynchronisation complète d'un realm * Force la resynchronisation complète d'un realm
* @param realmName nom du realm * @param realmName nom du realm
* @return statistiques de synchronisation * @return statistiques de synchronisation
*/ */
Map<String, Object> forceSyncRealm(@NotBlank String realmName); Map<String, Object> forceSyncRealm(@NotBlank String realmName);
/** /**
* Récupère le statut de la dernière synchronisation * Récupère le statut de la dernière synchronisation
* @param realmName nom du realm * @param realmName nom du realm
* @return statut de synchronisation * @return statut de synchronisation
*/ */
Map<String, Object> getLastSyncStatus(@NotBlank String realmName); Map<String, Object> getLastSyncStatus(@NotBlank String realmName);
/** /**
* Vérifie la disponibilité de Keycloak * Vérifie la disponibilité de Keycloak
* @return true si Keycloak est disponible * @return true si Keycloak est disponible
*/ */
boolean isKeycloakAvailable(); boolean isKeycloakAvailable();
/** /**
* Récupère les informations de santé de Keycloak * Récupère les informations de santé de Keycloak
* @return informations de santé * @return informations de santé
*/ */
Map<String, Object> getKeycloakHealthInfo(); Map<String, Object> getKeycloakHealthInfo();
} }

View File

@@ -1,185 +1,185 @@
package dev.lions.user.manager.service; package dev.lions.user.manager.service;
import dev.lions.user.manager.dto.user.UserDTO; import dev.lions.user.manager.dto.user.UserDTO;
import dev.lions.user.manager.dto.user.UserSearchCriteriaDTO; import dev.lions.user.manager.dto.user.UserSearchCriteriaDTO;
import dev.lions.user.manager.dto.user.UserSearchResultDTO; import dev.lions.user.manager.dto.user.UserSearchResultDTO;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
/** /**
* Service de gestion des utilisateurs Keycloak * Service de gestion des utilisateurs Keycloak
* Utilise uniquement l'API Admin Keycloak (AUCUN accès direct à la DB) * Utilise uniquement l'API Admin Keycloak (AUCUN accès direct à la DB)
*/ */
public interface UserService { public interface UserService {
/** /**
* Recherche des utilisateurs selon des critères * Recherche des utilisateurs selon des critères
* @param criteria critères de recherche * @param criteria critères de recherche
* @return résultat paginé * @return résultat paginé
*/ */
UserSearchResultDTO searchUsers(@Valid @NotNull UserSearchCriteriaDTO criteria); UserSearchResultDTO searchUsers(@Valid @NotNull UserSearchCriteriaDTO criteria);
/** /**
* Récupère un utilisateur par son ID * Récupère un utilisateur par son ID
* @param userId ID de l'utilisateur * @param userId ID de l'utilisateur
* @param realmName nom du realm * @param realmName nom du realm
* @return utilisateur ou Optional vide * @return utilisateur ou Optional vide
*/ */
Optional<UserDTO> getUserById(@NotBlank String userId, @NotBlank String realmName); Optional<UserDTO> getUserById(@NotBlank String userId, @NotBlank String realmName);
/** /**
* Récupère un utilisateur par son username * Récupère un utilisateur par son username
* @param username username * @param username username
* @param realmName nom du realm * @param realmName nom du realm
* @return utilisateur ou Optional vide * @return utilisateur ou Optional vide
*/ */
Optional<UserDTO> getUserByUsername(@NotBlank String username, @NotBlank String realmName); Optional<UserDTO> getUserByUsername(@NotBlank String username, @NotBlank String realmName);
/** /**
* Récupère un utilisateur par son email * Récupère un utilisateur par son email
* @param email email * @param email email
* @param realmName nom du realm * @param realmName nom du realm
* @return utilisateur ou Optional vide * @return utilisateur ou Optional vide
*/ */
Optional<UserDTO> getUserByEmail(@NotBlank String email, @NotBlank String realmName); Optional<UserDTO> getUserByEmail(@NotBlank String email, @NotBlank String realmName);
/** /**
* Crée un nouvel utilisateur * Crée un nouvel utilisateur
* @param user données de l'utilisateur * @param user données de l'utilisateur
* @param realmName nom du realm * @param realmName nom du realm
* @return utilisateur créé avec son ID * @return utilisateur créé avec son ID
*/ */
UserDTO createUser(@Valid @NotNull UserDTO user, @NotBlank String realmName); UserDTO createUser(@Valid @NotNull UserDTO user, @NotBlank String realmName);
/** /**
* Met à jour un utilisateur existant * Met à jour un utilisateur existant
* @param userId ID de l'utilisateur * @param userId ID de l'utilisateur
* @param user données modifiées * @param user données modifiées
* @param realmName nom du realm * @param realmName nom du realm
* @return utilisateur mis à jour * @return utilisateur mis à jour
*/ */
UserDTO updateUser(@NotBlank String userId, @Valid @NotNull UserDTO user, @NotBlank String realmName); UserDTO updateUser(@NotBlank String userId, @Valid @NotNull UserDTO user, @NotBlank String realmName);
/** /**
* Supprime un utilisateur (soft ou hard delete selon configuration) * Supprime un utilisateur (soft ou hard delete selon configuration)
* @param userId ID de l'utilisateur * @param userId ID de l'utilisateur
* @param realmName nom du realm * @param realmName nom du realm
* @param hardDelete true pour suppression définitive, false pour soft delete * @param hardDelete true pour suppression définitive, false pour soft delete
*/ */
void deleteUser(@NotBlank String userId, @NotBlank String realmName, boolean hardDelete); void deleteUser(@NotBlank String userId, @NotBlank String realmName, boolean hardDelete);
/** /**
* Active un utilisateur * Active un utilisateur
* @param userId ID de l'utilisateur * @param userId ID de l'utilisateur
* @param realmName nom du realm * @param realmName nom du realm
*/ */
void activateUser(@NotBlank String userId, @NotBlank String realmName); void activateUser(@NotBlank String userId, @NotBlank String realmName);
/** /**
* Désactive un utilisateur * Désactive un utilisateur
* @param userId ID de l'utilisateur * @param userId ID de l'utilisateur
* @param realmName nom du realm * @param realmName nom du realm
* @param raison raison de la désactivation * @param raison raison de la désactivation
*/ */
void deactivateUser(@NotBlank String userId, @NotBlank String realmName, String raison); void deactivateUser(@NotBlank String userId, @NotBlank String realmName, String raison);
/** /**
* Suspend un utilisateur * Suspend un utilisateur
* @param userId ID de l'utilisateur * @param userId ID de l'utilisateur
* @param realmName nom du realm * @param realmName nom du realm
* @param raison raison de la suspension * @param raison raison de la suspension
* @param duree durée de la suspension en jours (0 = indéfinie) * @param duree durée de la suspension en jours (0 = indéfinie)
*/ */
void suspendUser(@NotBlank String userId, @NotBlank String realmName, String raison, int duree); void suspendUser(@NotBlank String userId, @NotBlank String realmName, String raison, int duree);
/** /**
* Déverrouille un utilisateur * Déverrouille un utilisateur
* @param userId ID de l'utilisateur * @param userId ID de l'utilisateur
* @param realmName nom du realm * @param realmName nom du realm
*/ */
void unlockUser(@NotBlank String userId, @NotBlank String realmName); void unlockUser(@NotBlank String userId, @NotBlank String realmName);
/** /**
* Réinitialise le mot de passe d'un utilisateur * Réinitialise le mot de passe d'un utilisateur
* @param userId ID de l'utilisateur * @param userId ID de l'utilisateur
* @param realmName nom du realm * @param realmName nom du realm
* @param temporaryPassword mot de passe temporaire * @param temporaryPassword mot de passe temporaire
* @param temporary true si le mot de passe doit être changé à la prochaine connexion * @param temporary true si le mot de passe doit être changé à la prochaine connexion
*/ */
void resetPassword(@NotBlank String userId, @NotBlank String realmName, void resetPassword(@NotBlank String userId, @NotBlank String realmName,
@NotBlank String temporaryPassword, boolean temporary); @NotBlank String temporaryPassword, boolean temporary);
/** /**
* Envoie un email de vérification * Envoie un email de vérification
* @param userId ID de l'utilisateur * @param userId ID de l'utilisateur
* @param realmName nom du realm * @param realmName nom du realm
*/ */
void sendVerificationEmail(@NotBlank String userId, @NotBlank String realmName); void sendVerificationEmail(@NotBlank String userId, @NotBlank String realmName);
/** /**
* Force la déconnexion de toutes les sessions d'un utilisateur * Force la déconnexion de toutes les sessions d'un utilisateur
* @param userId ID de l'utilisateur * @param userId ID de l'utilisateur
* @param realmName nom du realm * @param realmName nom du realm
* @return nombre de sessions révoquées * @return nombre de sessions révoquées
*/ */
int logoutAllSessions(@NotBlank String userId, @NotBlank String realmName); int logoutAllSessions(@NotBlank String userId, @NotBlank String realmName);
/** /**
* Récupère les sessions actives d'un utilisateur * Récupère les sessions actives d'un utilisateur
* @param userId ID de l'utilisateur * @param userId ID de l'utilisateur
* @param realmName nom du realm * @param realmName nom du realm
* @return liste des informations de session * @return liste des informations de session
*/ */
List<String> getActiveSessions(@NotBlank String userId, @NotBlank String realmName); List<String> getActiveSessions(@NotBlank String userId, @NotBlank String realmName);
/** /**
* Compte le nombre d'utilisateurs selon des critères * Compte le nombre d'utilisateurs selon des critères
* @param criteria critères de recherche * @param criteria critères de recherche
* @return nombre d'utilisateurs * @return nombre d'utilisateurs
*/ */
long countUsers(@NotNull UserSearchCriteriaDTO criteria); long countUsers(@NotNull UserSearchCriteriaDTO criteria);
/** /**
* Récupère tous les utilisateurs d'un realm (avec pagination) * Récupère tous les utilisateurs d'un realm (avec pagination)
* @param realmName nom du realm * @param realmName nom du realm
* @param page numéro de page * @param page numéro de page
* @param pageSize taille de la page * @param pageSize taille de la page
* @return liste paginée d'utilisateurs * @return liste paginée d'utilisateurs
*/ */
UserSearchResultDTO getAllUsers(@NotBlank String realmName, int page, int pageSize); UserSearchResultDTO getAllUsers(@NotBlank String realmName, int page, int pageSize);
/** /**
* Vérifie si un username existe déjà * Vérifie si un username existe déjà
* @param username username à vérifier * @param username username à vérifier
* @param realmName nom du realm * @param realmName nom du realm
* @return true si existe * @return true si existe
*/ */
boolean usernameExists(@NotBlank String username, @NotBlank String realmName); boolean usernameExists(@NotBlank String username, @NotBlank String realmName);
/** /**
* Vérifie si un email existe déjà * Vérifie si un email existe déjà
* @param email email à vérifier * @param email email à vérifier
* @param realmName nom du realm * @param realmName nom du realm
* @return true si existe * @return true si existe
*/ */
boolean emailExists(@NotBlank String email, @NotBlank String realmName); boolean emailExists(@NotBlank String email, @NotBlank String realmName);
/** /**
* Exporte les utilisateurs au format CSV * Exporte les utilisateurs au format CSV
* @param criteria critères de recherche * @param criteria critères de recherche
* @return contenu CSV * @return contenu CSV
*/ */
String exportUsersToCSV(@NotNull UserSearchCriteriaDTO criteria); String exportUsersToCSV(@NotNull UserSearchCriteriaDTO criteria);
/** /**
* Importe des utilisateurs depuis un CSV avec rapport détaillé * Importe des utilisateurs depuis un CSV avec rapport détaillé
* @param csvContent contenu CSV * @param csvContent contenu CSV
* @param realmName nom du realm * @param realmName nom du realm
* @return résultat détaillé de l'import (succès, erreurs) * @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); dev.lions.user.manager.dto.importexport.ImportResultDTO importUsersFromCSV(@NotBlank String csvContent, @NotBlank String realmName);
} }

View File

@@ -1,72 +1,72 @@
package dev.lions.user.manager.validation; package dev.lions.user.manager.validation;
/** /**
* Constantes de validation pour les DTOs * Constantes de validation pour les DTOs
* Centralise les règles de validation communes * Centralise les règles de validation communes
*/ */
public final class ValidationConstants { public final class ValidationConstants {
private ValidationConstants() { private ValidationConstants() {
// Classe utilitaire, pas d'instanciation // Classe utilitaire, pas d'instanciation
} }
// Username // Username
public static final int USERNAME_MIN_LENGTH = 3; public static final int USERNAME_MIN_LENGTH = 3;
public static final int USERNAME_MAX_LENGTH = 100; public static final int USERNAME_MAX_LENGTH = 100;
public static final String USERNAME_PATTERN = "^[a-zA-Z0-9._-]+$"; 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"; public static final String USERNAME_PATTERN_MESSAGE = "Le nom d'utilisateur ne peut contenir que des lettres, chiffres, points, tirets et underscores";
// Email // 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 = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$";
public static final String EMAIL_PATTERN_MESSAGE = "Format d'email invalide"; public static final String EMAIL_PATTERN_MESSAGE = "Format d'email invalide";
// Nom et Prénom // Nom et Prénom
public static final int NAME_MIN_LENGTH = 2; public static final int NAME_MIN_LENGTH = 2;
public static final int NAME_MAX_LENGTH = 100; public static final int NAME_MAX_LENGTH = 100;
public static final String NAME_PATTERN = "^[a-zA-ZÀ-ÿ\\s'-]+$"; 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"; public static final String NAME_PATTERN_MESSAGE = "Le nom ne peut contenir que des lettres, espaces, apostrophes et tirets";
// Téléphone // Téléphone
public static final String PHONE_PATTERN = "^\\+?[0-9\\s.-]{8,20}$"; public static final String PHONE_PATTERN = "^\\+?[0-9\\s.-]{8,20}$";
public static final String PHONE_PATTERN_MESSAGE = "Format de téléphone invalide"; public static final String PHONE_PATTERN_MESSAGE = "Format de téléphone invalide";
// Mot de passe // Mot de passe
public static final int PASSWORD_MIN_LENGTH = 8; public static final int PASSWORD_MIN_LENGTH = 8;
public static final int PASSWORD_MAX_LENGTH = 100; 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 = "^(?=.*[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"; 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 // Role
public static final int ROLE_NAME_MIN_LENGTH = 2; public static final int ROLE_NAME_MIN_LENGTH = 2;
public static final int ROLE_NAME_MAX_LENGTH = 100; 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 = "^[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"; public static final String ROLE_NAME_PATTERN_MESSAGE = "Le nom du rôle ne peut contenir que des lettres, chiffres, underscores et tirets";
// Realm // Realm
public static final String REALM_NAME_PATTERN = "^[a-zA-Z0-9_-]+$"; 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"; public static final String REALM_NAME_PATTERN_MESSAGE = "Le nom du realm ne peut contenir que des lettres, chiffres, underscores et tirets";
// UUID // 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 = "^[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"; public static final String UUID_PATTERN_MESSAGE = "Format UUID invalide";
// Messages d'erreur génériques // Messages d'erreur génériques
public static final String REQUIRED_FIELD = "Ce champ est obligatoire"; public static final String REQUIRED_FIELD = "Ce champ est obligatoire";
public static final String INVALID_FORMAT = "Format invalide"; public static final String INVALID_FORMAT = "Format invalide";
public static final String TOO_SHORT = "Valeur trop courte"; public static final String TOO_SHORT = "Valeur trop courte";
public static final String TOO_LONG = "Valeur trop longue"; public static final String TOO_LONG = "Valeur trop longue";
// Pagination // Pagination
public static final int DEFAULT_PAGE_SIZE = 20; public static final int DEFAULT_PAGE_SIZE = 20;
public static final int MAX_PAGE_SIZE = 100; public static final int MAX_PAGE_SIZE = 100;
public static final int MIN_PAGE_SIZE = 1; public static final int MIN_PAGE_SIZE = 1;
// Audit // Audit
public static final int MAX_DESCRIPTION_LENGTH = 500; public static final int MAX_DESCRIPTION_LENGTH = 500;
public static final int MAX_COMMENT_LENGTH = 1000; public static final int MAX_COMMENT_LENGTH = 1000;
public static final int MAX_ERROR_MESSAGE_LENGTH = 2000; public static final int MAX_ERROR_MESSAGE_LENGTH = 2000;
// IP Address // 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 = "^((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"; public static final String IP_ADDRESS_PATTERN_MESSAGE = "Format d'adresse IP invalide";
} }

View File

@@ -1,119 +1,119 @@
package dev.lions.user.manager.dto.audit; package dev.lions.user.manager.dto.audit;
import dev.lions.user.manager.enums.audit.TypeActionAudit; import dev.lions.user.manager.enums.audit.TypeActionAudit;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
/** /**
* Tests unitaires pour AuditLogDTO * Tests unitaires pour AuditLogDTO
*/ */
class AuditLogDTOTest { class AuditLogDTOTest {
@Test @Test
void testBuilder() { void testBuilder() {
LocalDateTime now = LocalDateTime.now(); LocalDateTime now = LocalDateTime.now();
AuditLogDTO log = AuditLogDTO.builder() AuditLogDTO log = AuditLogDTO.builder()
.id("log-123") .id("log-123")
.typeAction(TypeActionAudit.USER_CREATE) .typeAction(TypeActionAudit.USER_CREATE)
.acteurUsername("admin") .acteurUsername("admin")
.acteurUserId("admin-123") .acteurUserId("admin-123")
.ressourceType("USER") .ressourceType("USER")
.ressourceId("user-123") .ressourceId("user-123")
.ressourceName("testuser") .ressourceName("testuser")
.realmName("test-realm") .realmName("test-realm")
.success(true) .success(true)
.description("User created") .description("User created")
.dateAction(now) .dateAction(now)
.ipAddress("192.168.1.1") .ipAddress("192.168.1.1")
.build(); .build();
assertNotNull(log); assertNotNull(log);
assertEquals("log-123", log.getId()); assertEquals("log-123", log.getId());
assertEquals(TypeActionAudit.USER_CREATE, log.getTypeAction()); assertEquals(TypeActionAudit.USER_CREATE, log.getTypeAction());
assertEquals("admin", log.getActeurUsername()); assertEquals("admin", log.getActeurUsername());
assertEquals("admin-123", log.getActeurUserId()); assertEquals("admin-123", log.getActeurUserId());
assertEquals("USER", log.getRessourceType()); assertEquals("USER", log.getRessourceType());
assertEquals("user-123", log.getRessourceId()); assertEquals("user-123", log.getRessourceId());
assertEquals("testuser", log.getRessourceName()); assertEquals("testuser", log.getRessourceName());
assertEquals("test-realm", log.getRealmName()); assertEquals("test-realm", log.getRealmName());
assertTrue(log.isSuccessful()); assertTrue(log.isSuccessful());
assertEquals("User created", log.getDescription()); assertEquals("User created", log.getDescription());
assertEquals(now, log.getDateAction()); assertEquals(now, log.getDateAction());
assertEquals("192.168.1.1", log.getIpAddress()); assertEquals("192.168.1.1", log.getIpAddress());
} }
@Test @Test
void testNoArgsConstructor() { void testNoArgsConstructor() {
AuditLogDTO log = new AuditLogDTO(); AuditLogDTO log = new AuditLogDTO();
assertNotNull(log); assertNotNull(log);
assertNull(log.getId()); assertNull(log.getId());
assertNull(log.getTypeAction()); assertNull(log.getTypeAction());
assertNull(log.getActeurUsername()); assertNull(log.getActeurUsername());
} }
@Test @Test
void testSettersAndGetters() { void testSettersAndGetters() {
AuditLogDTO log = new AuditLogDTO(); AuditLogDTO log = new AuditLogDTO();
LocalDateTime now = LocalDateTime.now(); LocalDateTime now = LocalDateTime.now();
log.setId("log-456"); log.setId("log-456");
log.setTypeAction(TypeActionAudit.USER_UPDATE); log.setTypeAction(TypeActionAudit.USER_UPDATE);
log.setActeurUsername("user1"); log.setActeurUsername("user1");
log.setActeurUserId("user1-123"); log.setActeurUserId("user1-123");
log.setRessourceType("USER"); log.setRessourceType("USER");
log.setRessourceId("user-456"); log.setRessourceId("user-456");
log.setRessourceName("user2"); log.setRessourceName("user2");
log.setRealmName("realm2"); log.setRealmName("realm2");
log.setSuccess(false); log.setSuccess(false);
log.setDescription("Update failed"); log.setDescription("Update failed");
log.setDateAction(now); log.setDateAction(now);
log.setIpAddress("10.0.0.1"); log.setIpAddress("10.0.0.1");
assertEquals("log-456", log.getId()); assertEquals("log-456", log.getId());
assertEquals(TypeActionAudit.USER_UPDATE, log.getTypeAction()); assertEquals(TypeActionAudit.USER_UPDATE, log.getTypeAction());
assertEquals("user1", log.getActeurUsername()); assertEquals("user1", log.getActeurUsername());
assertEquals("user1-123", log.getActeurUserId()); assertEquals("user1-123", log.getActeurUserId());
assertEquals("USER", log.getRessourceType()); assertEquals("USER", log.getRessourceType());
assertEquals("user-456", log.getRessourceId()); assertEquals("user-456", log.getRessourceId());
assertEquals("user2", log.getRessourceName()); assertEquals("user2", log.getRessourceName());
assertEquals("realm2", log.getRealmName()); assertEquals("realm2", log.getRealmName());
assertFalse(log.isSuccessful()); assertFalse(log.isSuccessful());
assertEquals("Update failed", log.getDescription()); assertEquals("Update failed", log.getDescription());
assertEquals(now, log.getDateAction()); assertEquals(now, log.getDateAction());
assertEquals("10.0.0.1", log.getIpAddress()); assertEquals("10.0.0.1", log.getIpAddress());
} }
@Test @Test
void testEqualsAndHashCode() { void testEqualsAndHashCode() {
LocalDateTime now = LocalDateTime.now(); LocalDateTime now = LocalDateTime.now();
AuditLogDTO log1 = AuditLogDTO.builder() AuditLogDTO log1 = AuditLogDTO.builder()
.id("log-123") .id("log-123")
.typeAction(TypeActionAudit.USER_CREATE) .typeAction(TypeActionAudit.USER_CREATE)
.dateAction(now) .dateAction(now)
.build(); .build();
AuditLogDTO log2 = AuditLogDTO.builder() AuditLogDTO log2 = AuditLogDTO.builder()
.id("log-123") .id("log-123")
.typeAction(TypeActionAudit.USER_CREATE) .typeAction(TypeActionAudit.USER_CREATE)
.dateAction(now) .dateAction(now)
.build(); .build();
assertEquals(log1, log2); assertEquals(log1, log2);
assertEquals(log1.hashCode(), log2.hashCode()); assertEquals(log1.hashCode(), log2.hashCode());
} }
@Test @Test
void testToString() { void testToString() {
AuditLogDTO log = AuditLogDTO.builder() AuditLogDTO log = AuditLogDTO.builder()
.id("log-123") .id("log-123")
.typeAction(TypeActionAudit.USER_CREATE) .typeAction(TypeActionAudit.USER_CREATE)
.build(); .build();
String toString = log.toString(); String toString = log.toString();
assertNotNull(toString); assertNotNull(toString);
} }
} }

View File

@@ -1,134 +1,134 @@
package dev.lions.user.manager.dto.base; package dev.lions.user.manager.dto.base;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
class BaseDTOTest { class BaseDTOTest {
// Concrete implementation for testing abstract class // Concrete implementation for testing abstract class
static class TestDTO extends BaseDTO { static class TestDTO extends BaseDTO {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
} }
@Test @Test
void testSettersAndGetters() { void testSettersAndGetters() {
TestDTO dto = new TestDTO(); TestDTO dto = new TestDTO();
LocalDateTime now = LocalDateTime.now(); LocalDateTime now = LocalDateTime.now();
dto.setId("uuid-123"); dto.setId("uuid-123");
dto.setDateCreation(now); dto.setDateCreation(now);
dto.setDateModification(now); dto.setDateModification(now);
dto.setCreeParUsername("admin"); dto.setCreeParUsername("admin");
dto.setModifieParUsername("superadmin"); dto.setModifieParUsername("superadmin");
dto.setVersion(1L); dto.setVersion(1L);
assertEquals("uuid-123", dto.getId()); assertEquals("uuid-123", dto.getId());
assertEquals(now, dto.getDateCreation()); assertEquals(now, dto.getDateCreation());
assertEquals(now, dto.getDateModification()); assertEquals(now, dto.getDateModification());
assertEquals("admin", dto.getCreeParUsername()); assertEquals("admin", dto.getCreeParUsername());
assertEquals("superadmin", dto.getModifieParUsername()); assertEquals("superadmin", dto.getModifieParUsername());
assertEquals(1L, dto.getVersion()); assertEquals(1L, dto.getVersion());
} }
@Test @Test
void testEqualsAndHashCode() { void testEqualsAndHashCode() {
TestDTO dto1 = new TestDTO(); TestDTO dto1 = new TestDTO();
dto1.setId("uuid-123"); dto1.setId("uuid-123");
dto1.setVersion(1L); dto1.setVersion(1L);
TestDTO dto2 = new TestDTO(); TestDTO dto2 = new TestDTO();
dto2.setId("uuid-123"); dto2.setId("uuid-123");
dto2.setVersion(1L); dto2.setVersion(1L);
TestDTO dto3 = new TestDTO(); TestDTO dto3 = new TestDTO();
dto3.setId("uuid-456"); dto3.setId("uuid-456");
dto3.setVersion(2L); dto3.setVersion(2L);
assertEquals(dto1, dto2); assertEquals(dto1, dto2);
assertEquals(dto1.hashCode(), dto2.hashCode()); assertEquals(dto1.hashCode(), dto2.hashCode());
assertNotEquals(dto1, dto3); assertNotEquals(dto1, dto3);
} }
@Test @Test
void testToString() { void testToString() {
TestDTO dto = new TestDTO(); TestDTO dto = new TestDTO();
dto.setId("uuid-123"); dto.setId("uuid-123");
dto.setCreeParUsername("admin"); dto.setCreeParUsername("admin");
String str = dto.toString(); String str = dto.toString();
assertNotNull(str); assertNotNull(str);
assertTrue(str.contains("uuid-123")); assertTrue(str.contains("uuid-123"));
assertTrue(str.contains("admin")); assertTrue(str.contains("admin"));
} }
@Test @Test
void testNoArgsConstructor() { void testNoArgsConstructor() {
TestDTO dto = new TestDTO(); TestDTO dto = new TestDTO();
assertNull(dto.getId()); assertNull(dto.getId());
assertNull(dto.getDateCreation()); assertNull(dto.getDateCreation());
assertNull(dto.getDateModification()); assertNull(dto.getDateModification());
assertNull(dto.getCreeParUsername()); assertNull(dto.getCreeParUsername());
assertNull(dto.getModifieParUsername()); assertNull(dto.getModifieParUsername());
assertNull(dto.getVersion()); assertNull(dto.getVersion());
} }
@Test @Test
void testAllFields() { void testAllFields() {
LocalDateTime creationTime = LocalDateTime.of(2025, 1, 15, 10, 30); LocalDateTime creationTime = LocalDateTime.of(2025, 1, 15, 10, 30);
LocalDateTime modificationTime = LocalDateTime.of(2025, 1, 15, 14, 20); LocalDateTime modificationTime = LocalDateTime.of(2025, 1, 15, 14, 20);
TestDTO dto = new TestDTO(); TestDTO dto = new TestDTO();
dto.setId("f47ac10b-58cc-4372-a567-0e02b2c3d479"); dto.setId("f47ac10b-58cc-4372-a567-0e02b2c3d479");
dto.setDateCreation(creationTime); dto.setDateCreation(creationTime);
dto.setDateModification(modificationTime); dto.setDateModification(modificationTime);
dto.setCreeParUsername("admin@lions.dev"); dto.setCreeParUsername("admin@lions.dev");
dto.setModifieParUsername("superadmin@lions.dev"); dto.setModifieParUsername("superadmin@lions.dev");
dto.setVersion(5L); dto.setVersion(5L);
assertEquals("f47ac10b-58cc-4372-a567-0e02b2c3d479", dto.getId()); assertEquals("f47ac10b-58cc-4372-a567-0e02b2c3d479", dto.getId());
assertEquals(creationTime, dto.getDateCreation()); assertEquals(creationTime, dto.getDateCreation());
assertEquals(modificationTime, dto.getDateModification()); assertEquals(modificationTime, dto.getDateModification());
assertEquals("admin@lions.dev", dto.getCreeParUsername()); assertEquals("admin@lions.dev", dto.getCreeParUsername());
assertEquals("superadmin@lions.dev", dto.getModifieParUsername()); assertEquals("superadmin@lions.dev", dto.getModifieParUsername());
assertEquals(5L, dto.getVersion()); assertEquals(5L, dto.getVersion());
} }
@Test @Test
void testEqualsWithNull() { void testEqualsWithNull() {
TestDTO dto = new TestDTO(); TestDTO dto = new TestDTO();
dto.setId("uuid-123"); dto.setId("uuid-123");
assertNotEquals(null, dto); assertNotEquals(null, dto);
} }
@Test @Test
void testEqualsWithDifferentClass() { void testEqualsWithDifferentClass() {
TestDTO dto = new TestDTO(); TestDTO dto = new TestDTO();
dto.setId("uuid-123"); dto.setId("uuid-123");
assertNotEquals("string", dto); assertNotEquals("string", dto);
} }
@Test @Test
void testEqualsSameObject() { void testEqualsSameObject() {
TestDTO dto = new TestDTO(); TestDTO dto = new TestDTO();
dto.setId("uuid-123"); dto.setId("uuid-123");
assertEquals(dto, dto); assertEquals(dto, dto);
} }
@Test @Test
void testHashCodeConsistency() { void testHashCodeConsistency() {
TestDTO dto = new TestDTO(); TestDTO dto = new TestDTO();
dto.setId("uuid-123"); dto.setId("uuid-123");
dto.setVersion(1L); dto.setVersion(1L);
int hash1 = dto.hashCode(); int hash1 = dto.hashCode();
int hash2 = dto.hashCode(); int hash2 = dto.hashCode();
assertEquals(hash1, hash2); assertEquals(hash1, hash2);
} }
} }

View File

@@ -1,184 +1,184 @@
package dev.lions.user.manager.dto.realm; package dev.lions.user.manager.dto.realm;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
/** /**
* Tests unitaires pour RealmAssignmentDTO * Tests unitaires pour RealmAssignmentDTO
*/ */
class RealmAssignmentDTOTest { class RealmAssignmentDTOTest {
@Test @Test
void testBuilder() { void testBuilder() {
LocalDateTime now = LocalDateTime.now(); LocalDateTime now = LocalDateTime.now();
RealmAssignmentDTO dto = RealmAssignmentDTO.builder() RealmAssignmentDTO dto = RealmAssignmentDTO.builder()
.id("assignment-1") .id("assignment-1")
.userId("user-1") .userId("user-1")
.username("testuser") .username("testuser")
.email("test@example.com") .email("test@example.com")
.realmName("realm1") .realmName("realm1")
.isSuperAdmin(false) .isSuperAdmin(false)
.active(true) .active(true)
.temporaire(false) .temporaire(false)
.assignedAt(now) .assignedAt(now)
.assignedBy("admin") .assignedBy("admin")
.raison("Test assignment") .raison("Test assignment")
.commentaires("Test comments") .commentaires("Test comments")
.dateCreation(now) .dateCreation(now)
.dateModification(now) .dateModification(now)
.dateExpiration(now.plusDays(30)) .dateExpiration(now.plusDays(30))
.build(); .build();
assertEquals("assignment-1", dto.getId()); assertEquals("assignment-1", dto.getId());
assertEquals("user-1", dto.getUserId()); assertEquals("user-1", dto.getUserId());
assertEquals("testuser", dto.getUsername()); assertEquals("testuser", dto.getUsername());
assertEquals("test@example.com", dto.getEmail()); assertEquals("test@example.com", dto.getEmail());
assertEquals("realm1", dto.getRealmName()); assertEquals("realm1", dto.getRealmName());
assertFalse(dto.isSuperAdmin()); assertFalse(dto.isSuperAdmin());
assertTrue(dto.isActive()); assertTrue(dto.isActive());
assertFalse(dto.getTemporaire()); assertFalse(dto.getTemporaire());
assertEquals(now, dto.getAssignedAt()); assertEquals(now, dto.getAssignedAt());
assertEquals("admin", dto.getAssignedBy()); assertEquals("admin", dto.getAssignedBy());
assertEquals("Test assignment", dto.getRaison()); assertEquals("Test assignment", dto.getRaison());
assertEquals("Test comments", dto.getCommentaires()); assertEquals("Test comments", dto.getCommentaires());
} }
@Test @Test
void testNoArgsConstructor() { void testNoArgsConstructor() {
RealmAssignmentDTO dto = new RealmAssignmentDTO(); RealmAssignmentDTO dto = new RealmAssignmentDTO();
assertNotNull(dto); assertNotNull(dto);
} }
@Test @Test
void testSettersAndGetters() { void testSettersAndGetters() {
RealmAssignmentDTO dto = new RealmAssignmentDTO(); RealmAssignmentDTO dto = new RealmAssignmentDTO();
LocalDateTime now = LocalDateTime.now(); LocalDateTime now = LocalDateTime.now();
dto.setId("assignment-1"); dto.setId("assignment-1");
dto.setUserId("user-1"); dto.setUserId("user-1");
dto.setUsername("testuser"); dto.setUsername("testuser");
dto.setEmail("test@example.com"); dto.setEmail("test@example.com");
dto.setRealmName("realm1"); dto.setRealmName("realm1");
dto.setIsSuperAdmin(true); dto.setIsSuperAdmin(true);
dto.setActive(true); dto.setActive(true);
dto.setTemporaire(false); dto.setTemporaire(false);
dto.setAssignedAt(now); dto.setAssignedAt(now);
dto.setAssignedBy("admin"); dto.setAssignedBy("admin");
dto.setRaison("Test"); dto.setRaison("Test");
dto.setCommentaires("Comments"); dto.setCommentaires("Comments");
dto.setDateCreation(now); dto.setDateCreation(now);
dto.setDateModification(now); dto.setDateModification(now);
dto.setDateExpiration(now.plusDays(30)); dto.setDateExpiration(now.plusDays(30));
assertEquals("assignment-1", dto.getId()); assertEquals("assignment-1", dto.getId());
assertEquals("user-1", dto.getUserId()); assertEquals("user-1", dto.getUserId());
assertEquals("testuser", dto.getUsername()); assertEquals("testuser", dto.getUsername());
assertEquals("test@example.com", dto.getEmail()); assertEquals("test@example.com", dto.getEmail());
assertEquals("realm1", dto.getRealmName()); assertEquals("realm1", dto.getRealmName());
assertTrue(dto.isSuperAdmin()); assertTrue(dto.isSuperAdmin());
assertTrue(dto.isActive()); assertTrue(dto.isActive());
assertFalse(dto.getTemporaire()); assertFalse(dto.getTemporaire());
assertEquals(now, dto.getAssignedAt()); assertEquals(now, dto.getAssignedAt());
assertEquals("admin", dto.getAssignedBy()); assertEquals("admin", dto.getAssignedBy());
} }
@Test @Test
void testIsExpired_NotExpired() { void testIsExpired_NotExpired() {
RealmAssignmentDTO dto = RealmAssignmentDTO.builder() RealmAssignmentDTO dto = RealmAssignmentDTO.builder()
.temporaire(true) // Doit être temporaire pour que isExpired() fonctionne .temporaire(true) // Doit être temporaire pour que isExpired() fonctionne
.dateExpiration(LocalDateTime.now().plusDays(1)) .dateExpiration(LocalDateTime.now().plusDays(1))
.build(); .build();
assertFalse(dto.isExpired()); assertFalse(dto.isExpired());
} }
@Test @Test
void testIsExpired_Expired() { void testIsExpired_Expired() {
RealmAssignmentDTO dto = RealmAssignmentDTO.builder() RealmAssignmentDTO dto = RealmAssignmentDTO.builder()
.temporaire(true) // Doit être temporaire pour que isExpired() fonctionne .temporaire(true) // Doit être temporaire pour que isExpired() fonctionne
.dateExpiration(LocalDateTime.now().minusDays(1)) .dateExpiration(LocalDateTime.now().minusDays(1))
.build(); .build();
assertTrue(dto.isExpired()); assertTrue(dto.isExpired());
} }
@Test @Test
void testIsExpired_NoExpiration() { void testIsExpired_NoExpiration() {
RealmAssignmentDTO dto = RealmAssignmentDTO.builder() RealmAssignmentDTO dto = RealmAssignmentDTO.builder()
.temporaire(true) .temporaire(true)
.dateExpiration(null) .dateExpiration(null)
.build(); .build();
assertFalse(dto.isExpired()); assertFalse(dto.isExpired());
} }
@Test @Test
void testIsExpired_NotTemporary() { void testIsExpired_NotTemporary() {
RealmAssignmentDTO dto = RealmAssignmentDTO.builder() RealmAssignmentDTO dto = RealmAssignmentDTO.builder()
.temporaire(false) // Si pas temporaire, isExpired() retourne false .temporaire(false) // Si pas temporaire, isExpired() retourne false
.dateExpiration(LocalDateTime.now().minusDays(1)) .dateExpiration(LocalDateTime.now().minusDays(1))
.build(); .build();
assertFalse(dto.isExpired()); assertFalse(dto.isExpired());
} }
@Test @Test
void testIsTemporaire() { void testIsTemporaire() {
RealmAssignmentDTO dto = RealmAssignmentDTO.builder() RealmAssignmentDTO dto = RealmAssignmentDTO.builder()
.temporaire(true) .temporaire(true)
.build(); .build();
assertTrue(dto.isTemporaire()); assertTrue(dto.isTemporaire());
} }
@Test @Test
void testIsActive() { void testIsActive() {
RealmAssignmentDTO dto = RealmAssignmentDTO.builder() RealmAssignmentDTO dto = RealmAssignmentDTO.builder()
.active(true) .active(true)
.build(); .build();
assertTrue(dto.isActive()); assertTrue(dto.isActive());
} }
@Test @Test
void testIsSuperAdmin() { void testIsSuperAdmin() {
RealmAssignmentDTO dto = RealmAssignmentDTO.builder() RealmAssignmentDTO dto = RealmAssignmentDTO.builder()
.isSuperAdmin(true) .isSuperAdmin(true)
.build(); .build();
assertTrue(dto.isSuperAdmin()); assertTrue(dto.isSuperAdmin());
} }
@Test @Test
void testGetSummary() { void testGetSummary() {
RealmAssignmentDTO dto = RealmAssignmentDTO.builder() RealmAssignmentDTO dto = RealmAssignmentDTO.builder()
.realmName("test-realm") .realmName("test-realm")
.username("testuser") .username("testuser")
.temporaire(true) .temporaire(true)
.build(); .build();
String summary = dto.getSummary(); String summary = dto.getSummary();
assertNotNull(summary); assertNotNull(summary);
assertTrue(summary.contains("test-realm")); assertTrue(summary.contains("test-realm"));
assertTrue(summary.contains("testuser")); assertTrue(summary.contains("testuser"));
assertTrue(summary.contains("temporaire")); assertTrue(summary.contains("temporaire"));
} }
@Test @Test
void testGetSummary_WithUserId() { void testGetSummary_WithUserId() {
RealmAssignmentDTO dto = RealmAssignmentDTO.builder() RealmAssignmentDTO dto = RealmAssignmentDTO.builder()
.realmName("test-realm") .realmName("test-realm")
.userId("user-123") .userId("user-123")
.temporaire(false) .temporaire(false)
.build(); .build();
String summary = dto.getSummary(); String summary = dto.getSummary();
assertNotNull(summary); assertNotNull(summary);
assertTrue(summary.contains("test-realm")); assertTrue(summary.contains("test-realm"));
assertTrue(summary.contains("user-123")); assertTrue(summary.contains("user-123"));
} }
} }

View File

@@ -1,147 +1,147 @@
package dev.lions.user.manager.dto.role; package dev.lions.user.manager.dto.role;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
/** /**
* Tests unitaires pour RoleAssignmentDTO * Tests unitaires pour RoleAssignmentDTO
*/ */
class RoleAssignmentDTOTest { class RoleAssignmentDTOTest {
@Test @Test
void testBuilder() { void testBuilder() {
RoleAssignmentDTO assignment = RoleAssignmentDTO.builder() RoleAssignmentDTO assignment = RoleAssignmentDTO.builder()
.userId("user-123") .userId("user-123")
.realmName("test-realm") .realmName("test-realm")
.roleNames(Arrays.asList("admin", "user")) .roleNames(Arrays.asList("admin", "user"))
.build(); .build();
assertNotNull(assignment); assertNotNull(assignment);
assertEquals("user-123", assignment.getUserId()); assertEquals("user-123", assignment.getUserId());
assertEquals("test-realm", assignment.getRealmName()); assertEquals("test-realm", assignment.getRealmName());
assertEquals(2, assignment.getRoleNames().size()); assertEquals(2, assignment.getRoleNames().size());
assertTrue(assignment.getRoleNames().contains("admin")); assertTrue(assignment.getRoleNames().contains("admin"));
assertTrue(assignment.getRoleNames().contains("user")); assertTrue(assignment.getRoleNames().contains("user"));
} }
@Test @Test
void testNoArgsConstructor() { void testNoArgsConstructor() {
RoleAssignmentDTO assignment = new RoleAssignmentDTO(); RoleAssignmentDTO assignment = new RoleAssignmentDTO();
assertNotNull(assignment); assertNotNull(assignment);
assertNull(assignment.getUserId()); assertNull(assignment.getUserId());
assertNull(assignment.getRealmName()); assertNull(assignment.getRealmName());
assertNull(assignment.getRoleNames()); assertNull(assignment.getRoleNames());
} }
@Test @Test
void testAllArgsConstructor() { void testAllArgsConstructor() {
// Le constructeur AllArgsConstructor nécessite tous les champs // Le constructeur AllArgsConstructor nécessite tous les champs
// On utilise plutôt le builder pour ce test // On utilise plutôt le builder pour ce test
List<String> roles = Arrays.asList("admin", "user"); List<String> roles = Arrays.asList("admin", "user");
RoleAssignmentDTO assignment = RoleAssignmentDTO.builder() RoleAssignmentDTO assignment = RoleAssignmentDTO.builder()
.userId("user-123") .userId("user-123")
.realmName("test-realm") .realmName("test-realm")
.roleNames(roles) .roleNames(roles)
.build(); .build();
assertNotNull(assignment); assertNotNull(assignment);
assertEquals("user-123", assignment.getUserId()); assertEquals("user-123", assignment.getUserId());
assertEquals("test-realm", assignment.getRealmName()); assertEquals("test-realm", assignment.getRealmName());
assertEquals(2, assignment.getRoleNames().size()); assertEquals(2, assignment.getRoleNames().size());
} }
@Test @Test
void testSettersAndGetters() { void testSettersAndGetters() {
RoleAssignmentDTO assignment = new RoleAssignmentDTO(); RoleAssignmentDTO assignment = new RoleAssignmentDTO();
assignment.setUserId("user-456"); assignment.setUserId("user-456");
assignment.setRealmName("realm2"); assignment.setRealmName("realm2");
assignment.setRoleNames(Collections.singletonList("admin")); assignment.setRoleNames(Collections.singletonList("admin"));
assertEquals("user-456", assignment.getUserId()); assertEquals("user-456", assignment.getUserId());
assertEquals("realm2", assignment.getRealmName()); assertEquals("realm2", assignment.getRealmName());
assertEquals(1, assignment.getRoleNames().size()); assertEquals(1, assignment.getRoleNames().size());
assertEquals("admin", assignment.getRoleNames().get(0)); assertEquals("admin", assignment.getRoleNames().get(0));
} }
@Test @Test
void testEqualsAndHashCode() { void testEqualsAndHashCode() {
RoleAssignmentDTO assignment1 = RoleAssignmentDTO.builder() RoleAssignmentDTO assignment1 = RoleAssignmentDTO.builder()
.userId("user-123") .userId("user-123")
.realmName("test-realm") .realmName("test-realm")
.roleNames(Arrays.asList("admin")) .roleNames(Arrays.asList("admin"))
.typeRole(dev.lions.user.manager.enums.role.TypeRole.REALM_ROLE) .typeRole(dev.lions.user.manager.enums.role.TypeRole.REALM_ROLE)
.build(); .build();
RoleAssignmentDTO assignment2 = RoleAssignmentDTO.builder() RoleAssignmentDTO assignment2 = RoleAssignmentDTO.builder()
.userId("user-123") .userId("user-123")
.realmName("test-realm") .realmName("test-realm")
.roleNames(Arrays.asList("admin")) .roleNames(Arrays.asList("admin"))
.typeRole(dev.lions.user.manager.enums.role.TypeRole.REALM_ROLE) .typeRole(dev.lions.user.manager.enums.role.TypeRole.REALM_ROLE)
.build(); .build();
assertEquals(assignment1, assignment2); assertEquals(assignment1, assignment2);
assertEquals(assignment1.hashCode(), assignment2.hashCode()); assertEquals(assignment1.hashCode(), assignment2.hashCode());
} }
@Test @Test
void testIsValidForClientRole() { void testIsValidForClientRole() {
RoleAssignmentDTO assignment = RoleAssignmentDTO.builder() RoleAssignmentDTO assignment = RoleAssignmentDTO.builder()
.typeRole(dev.lions.user.manager.enums.role.TypeRole.CLIENT_ROLE) .typeRole(dev.lions.user.manager.enums.role.TypeRole.CLIENT_ROLE)
.clientName("test-client") .clientName("test-client")
.build(); .build();
assertTrue(assignment.isValidForClientRole()); assertTrue(assignment.isValidForClientRole());
} }
@Test @Test
void testIsValidForRealmRole() { void testIsValidForRealmRole() {
RoleAssignmentDTO assignment = RoleAssignmentDTO.builder() RoleAssignmentDTO assignment = RoleAssignmentDTO.builder()
.typeRole(dev.lions.user.manager.enums.role.TypeRole.REALM_ROLE) .typeRole(dev.lions.user.manager.enums.role.TypeRole.REALM_ROLE)
.build(); .build();
assertTrue(assignment.isValidForRealmRole()); assertTrue(assignment.isValidForRealmRole());
} }
@Test @Test
void testGetRoleCount() { void testGetRoleCount() {
RoleAssignmentDTO assignment = RoleAssignmentDTO.builder() RoleAssignmentDTO assignment = RoleAssignmentDTO.builder()
.roleNames(Arrays.asList("admin", "user", "viewer")) .roleNames(Arrays.asList("admin", "user", "viewer"))
.build(); .build();
assertEquals(3, assignment.getRoleCount()); assertEquals(3, assignment.getRoleCount());
} }
@Test @Test
void testGetRoleCount_Empty() { void testGetRoleCount_Empty() {
RoleAssignmentDTO assignment = RoleAssignmentDTO.builder() RoleAssignmentDTO assignment = RoleAssignmentDTO.builder()
.roleNames(Collections.emptyList()) .roleNames(Collections.emptyList())
.build(); .build();
assertEquals(0, assignment.getRoleCount()); assertEquals(0, assignment.getRoleCount());
} }
@Test @Test
void testGetRoleCount_Null() { void testGetRoleCount_Null() {
RoleAssignmentDTO assignment = new RoleAssignmentDTO(); RoleAssignmentDTO assignment = new RoleAssignmentDTO();
assertEquals(0, assignment.getRoleCount()); assertEquals(0, assignment.getRoleCount());
} }
@Test @Test
void testToString() { void testToString() {
RoleAssignmentDTO assignment = RoleAssignmentDTO.builder() RoleAssignmentDTO assignment = RoleAssignmentDTO.builder()
.userId("user-123") .userId("user-123")
.realmName("test-realm") .realmName("test-realm")
.build(); .build();
String toString = assignment.toString(); String toString = assignment.toString();
assertNotNull(toString); assertNotNull(toString);
} }
} }

View File

@@ -1,318 +1,318 @@
package dev.lions.user.manager.dto.role; package dev.lions.user.manager.dto.role;
import dev.lions.user.manager.enums.role.TypeRole; import dev.lions.user.manager.enums.role.TypeRole;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
class RoleDTOTest { class RoleDTOTest {
@Test @Test
void testIsRealmRole_true() { void testIsRealmRole_true() {
RoleDTO role = new RoleDTO(); RoleDTO role = new RoleDTO();
role.setTypeRole(TypeRole.REALM_ROLE); role.setTypeRole(TypeRole.REALM_ROLE);
assertTrue(role.isRealmRole()); assertTrue(role.isRealmRole());
assertFalse(role.isClientRole()); assertFalse(role.isClientRole());
} }
@Test @Test
void testIsRealmRole_false() { void testIsRealmRole_false() {
RoleDTO role = new RoleDTO(); RoleDTO role = new RoleDTO();
role.setTypeRole(TypeRole.CLIENT_ROLE); role.setTypeRole(TypeRole.CLIENT_ROLE);
assertFalse(role.isRealmRole()); assertFalse(role.isRealmRole());
} }
@Test @Test
void testIsRealmRole_null() { void testIsRealmRole_null() {
RoleDTO role = new RoleDTO(); RoleDTO role = new RoleDTO();
role.setTypeRole(null); role.setTypeRole(null);
assertFalse(role.isRealmRole()); assertFalse(role.isRealmRole());
} }
@Test @Test
void testIsClientRole_true() { void testIsClientRole_true() {
RoleDTO role = new RoleDTO(); RoleDTO role = new RoleDTO();
role.setTypeRole(TypeRole.CLIENT_ROLE); role.setTypeRole(TypeRole.CLIENT_ROLE);
assertTrue(role.isClientRole()); assertTrue(role.isClientRole());
assertFalse(role.isRealmRole()); assertFalse(role.isRealmRole());
} }
@Test @Test
void testIsClientRole_false() { void testIsClientRole_false() {
RoleDTO role = new RoleDTO(); RoleDTO role = new RoleDTO();
role.setTypeRole(TypeRole.REALM_ROLE); role.setTypeRole(TypeRole.REALM_ROLE);
assertFalse(role.isClientRole()); assertFalse(role.isClientRole());
} }
@Test @Test
void testIsClientRole_null() { void testIsClientRole_null() {
RoleDTO role = new RoleDTO(); RoleDTO role = new RoleDTO();
role.setTypeRole(null); role.setTypeRole(null);
assertFalse(role.isClientRole()); assertFalse(role.isClientRole());
} }
@Test @Test
void testIsComposite_withCompositeRoles() { void testIsComposite_withCompositeRoles() {
RoleDTO role = new RoleDTO(); RoleDTO role = new RoleDTO();
role.setComposite(true); role.setComposite(true);
role.setCompositeRoles(Arrays.asList("role1", "role2")); role.setCompositeRoles(Arrays.asList("role1", "role2"));
assertTrue(role.isComposite()); assertTrue(role.isComposite());
} }
@Test @Test
void testIsComposite_withCompositeRealmRoles() { void testIsComposite_withCompositeRealmRoles() {
RoleDTO role = new RoleDTO(); RoleDTO role = new RoleDTO();
role.setComposite(true); role.setComposite(true);
role.setCompositeRoles(null); role.setCompositeRoles(null);
role.setCompositeRealmRoles(Collections.singletonList(new RoleDTO.RoleCompositeDTO())); role.setCompositeRealmRoles(Collections.singletonList(new RoleDTO.RoleCompositeDTO()));
assertTrue(role.isComposite()); assertTrue(role.isComposite());
} }
@Test @Test
void testIsComposite_withCompositeClientRoles() { void testIsComposite_withCompositeClientRoles() {
RoleDTO role = new RoleDTO(); RoleDTO role = new RoleDTO();
role.setComposite(true); role.setComposite(true);
role.setCompositeRoles(null); role.setCompositeRoles(null);
role.setCompositeRealmRoles(null); role.setCompositeRealmRoles(null);
Map<String, List<RoleDTO.RoleCompositeDTO>> clientRoles = new HashMap<>(); Map<String, List<RoleDTO.RoleCompositeDTO>> clientRoles = new HashMap<>();
clientRoles.put("client", Collections.singletonList(new RoleDTO.RoleCompositeDTO())); clientRoles.put("client", Collections.singletonList(new RoleDTO.RoleCompositeDTO()));
role.setCompositeClientRoles(clientRoles); role.setCompositeClientRoles(clientRoles);
assertTrue(role.isComposite()); assertTrue(role.isComposite());
} }
@Test @Test
void testIsComposite_falseWhenCompositeFalse() { void testIsComposite_falseWhenCompositeFalse() {
RoleDTO role = new RoleDTO(); RoleDTO role = new RoleDTO();
role.setComposite(false); role.setComposite(false);
role.setCompositeRoles(Arrays.asList("role1")); role.setCompositeRoles(Arrays.asList("role1"));
assertFalse(role.isComposite()); assertFalse(role.isComposite());
} }
@Test @Test
void testIsComposite_falseWhenCompositeNull() { void testIsComposite_falseWhenCompositeNull() {
RoleDTO role = new RoleDTO(); RoleDTO role = new RoleDTO();
role.setComposite(null); role.setComposite(null);
role.setCompositeRoles(Arrays.asList("role1")); role.setCompositeRoles(Arrays.asList("role1"));
assertFalse(role.isComposite()); assertFalse(role.isComposite());
} }
@Test @Test
void testIsComposite_falseWhenNoRoles() { void testIsComposite_falseWhenNoRoles() {
RoleDTO role = new RoleDTO(); RoleDTO role = new RoleDTO();
role.setComposite(true); role.setComposite(true);
role.setCompositeRoles(null); role.setCompositeRoles(null);
role.setCompositeRealmRoles(null); role.setCompositeRealmRoles(null);
role.setCompositeClientRoles(null); role.setCompositeClientRoles(null);
assertFalse(role.isComposite()); assertFalse(role.isComposite());
} }
@Test @Test
void testIsComposite_falseWhenEmptyRoles() { void testIsComposite_falseWhenEmptyRoles() {
RoleDTO role = new RoleDTO(); RoleDTO role = new RoleDTO();
role.setComposite(true); role.setComposite(true);
role.setCompositeRoles(Collections.emptyList()); role.setCompositeRoles(Collections.emptyList());
role.setCompositeRealmRoles(Collections.emptyList()); role.setCompositeRealmRoles(Collections.emptyList());
role.setCompositeClientRoles(Collections.emptyMap()); role.setCompositeClientRoles(Collections.emptyMap());
assertFalse(role.isComposite()); assertFalse(role.isComposite());
} }
@Test @Test
void testGetFullName_realmRole() { void testGetFullName_realmRole() {
RoleDTO role = new RoleDTO(); RoleDTO role = new RoleDTO();
role.setName("admin"); role.setName("admin");
role.setTypeRole(TypeRole.REALM_ROLE); role.setTypeRole(TypeRole.REALM_ROLE);
assertEquals("admin", role.getFullName()); assertEquals("admin", role.getFullName());
} }
@Test @Test
void testGetFullName_clientRole() { void testGetFullName_clientRole() {
RoleDTO role = new RoleDTO(); RoleDTO role = new RoleDTO();
role.setName("admin"); role.setName("admin");
role.setTypeRole(TypeRole.CLIENT_ROLE); role.setTypeRole(TypeRole.CLIENT_ROLE);
role.setClientName("app"); role.setClientName("app");
assertEquals("app:admin", role.getFullName()); assertEquals("app:admin", role.getFullName());
} }
@Test @Test
void testGetFullName_clientRoleNullClientName() { void testGetFullName_clientRoleNullClientName() {
RoleDTO role = new RoleDTO(); RoleDTO role = new RoleDTO();
role.setName("admin"); role.setName("admin");
role.setTypeRole(TypeRole.CLIENT_ROLE); role.setTypeRole(TypeRole.CLIENT_ROLE);
role.setClientName(null); role.setClientName(null);
assertEquals("admin", role.getFullName()); assertEquals("admin", role.getFullName());
} }
@Test @Test
void testGetFullName_nullTypeRole() { void testGetFullName_nullTypeRole() {
RoleDTO role = new RoleDTO(); RoleDTO role = new RoleDTO();
role.setName("admin"); role.setName("admin");
role.setTypeRole(null); role.setTypeRole(null);
assertEquals("admin", role.getFullName()); assertEquals("admin", role.getFullName());
} }
@Test @Test
void testRoleCompositeDTO_builder() { void testRoleCompositeDTO_builder() {
RoleDTO.RoleCompositeDTO comp = RoleDTO.RoleCompositeDTO.builder() RoleDTO.RoleCompositeDTO comp = RoleDTO.RoleCompositeDTO.builder()
.id("1") .id("1")
.name("role") .name("role")
.description("desc") .description("desc")
.typeRole(TypeRole.REALM_ROLE) .typeRole(TypeRole.REALM_ROLE)
.clientName("client") .clientName("client")
.build(); .build();
assertEquals("1", comp.getId()); assertEquals("1", comp.getId());
assertEquals("role", comp.getName()); assertEquals("role", comp.getName());
assertEquals("desc", comp.getDescription()); assertEquals("desc", comp.getDescription());
assertEquals(TypeRole.REALM_ROLE, comp.getTypeRole()); assertEquals(TypeRole.REALM_ROLE, comp.getTypeRole());
assertEquals("client", comp.getClientName()); assertEquals("client", comp.getClientName());
} }
@Test @Test
void testRoleCompositeDTO_settersGetters() { void testRoleCompositeDTO_settersGetters() {
RoleDTO.RoleCompositeDTO comp = new RoleDTO.RoleCompositeDTO(); RoleDTO.RoleCompositeDTO comp = new RoleDTO.RoleCompositeDTO();
comp.setId("id"); comp.setId("id");
comp.setName("name"); comp.setName("name");
comp.setDescription("desc"); comp.setDescription("desc");
comp.setTypeRole(TypeRole.CLIENT_ROLE); comp.setTypeRole(TypeRole.CLIENT_ROLE);
comp.setClientName("client"); comp.setClientName("client");
assertEquals("id", comp.getId()); assertEquals("id", comp.getId());
assertEquals("name", comp.getName()); assertEquals("name", comp.getName());
assertEquals("desc", comp.getDescription()); assertEquals("desc", comp.getDescription());
assertEquals(TypeRole.CLIENT_ROLE, comp.getTypeRole()); assertEquals(TypeRole.CLIENT_ROLE, comp.getTypeRole());
assertEquals("client", comp.getClientName()); assertEquals("client", comp.getClientName());
} }
@Test @Test
void testRoleCompositeDTO_allArgsConstructor() { void testRoleCompositeDTO_allArgsConstructor() {
RoleDTO.RoleCompositeDTO comp = new RoleDTO.RoleCompositeDTO("id", "name", "desc", TypeRole.REALM_ROLE, RoleDTO.RoleCompositeDTO comp = new RoleDTO.RoleCompositeDTO("id", "name", "desc", TypeRole.REALM_ROLE,
"client"); "client");
assertEquals("id", comp.getId()); assertEquals("id", comp.getId());
assertEquals("name", comp.getName()); assertEquals("name", comp.getName());
assertEquals("desc", comp.getDescription()); assertEquals("desc", comp.getDescription());
assertEquals(TypeRole.REALM_ROLE, comp.getTypeRole()); assertEquals(TypeRole.REALM_ROLE, comp.getTypeRole());
assertEquals("client", comp.getClientName()); assertEquals("client", comp.getClientName());
} }
@Test @Test
void testRoleCompositeDTO_equalsAndHashCode() { void testRoleCompositeDTO_equalsAndHashCode() {
RoleDTO.RoleCompositeDTO comp1 = RoleDTO.RoleCompositeDTO.builder().id("1").name("role").build(); RoleDTO.RoleCompositeDTO comp1 = RoleDTO.RoleCompositeDTO.builder().id("1").name("role").build();
RoleDTO.RoleCompositeDTO comp2 = 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(); RoleDTO.RoleCompositeDTO comp3 = RoleDTO.RoleCompositeDTO.builder().id("2").name("other").build();
assertEquals(comp1, comp2); assertEquals(comp1, comp2);
assertEquals(comp1.hashCode(), comp2.hashCode()); assertEquals(comp1.hashCode(), comp2.hashCode());
assertNotEquals(comp1, comp3); assertNotEquals(comp1, comp3);
} }
@Test @Test
void testRoleCompositeDTO_toString() { void testRoleCompositeDTO_toString() {
RoleDTO.RoleCompositeDTO comp = RoleDTO.RoleCompositeDTO.builder().id("1").name("role").build(); RoleDTO.RoleCompositeDTO comp = RoleDTO.RoleCompositeDTO.builder().id("1").name("role").build();
String str = comp.toString(); String str = comp.toString();
assertNotNull(str); assertNotNull(str);
assertTrue(str.contains("role")); assertTrue(str.contains("role"));
} }
@Test @Test
void testBuilderAndAllFields() { void testBuilderAndAllFields() {
Map<String, List<String>> attrs = new HashMap<>(); Map<String, List<String>> attrs = new HashMap<>();
attrs.put("key", Collections.singletonList("value")); attrs.put("key", Collections.singletonList("value"));
Map<String, List<RoleDTO.RoleCompositeDTO>> clientComposites = new HashMap<>(); Map<String, List<RoleDTO.RoleCompositeDTO>> clientComposites = new HashMap<>();
clientComposites.put("client", clientComposites.put("client",
Collections.singletonList(RoleDTO.RoleCompositeDTO.builder().name("subclient").build())); Collections.singletonList(RoleDTO.RoleCompositeDTO.builder().name("subclient").build()));
RoleDTO role = RoleDTO.builder() RoleDTO role = RoleDTO.builder()
.id("uuid-123") .id("uuid-123")
.name("admin") .name("admin")
.description("Administrator role") .description("Administrator role")
.typeRole(TypeRole.REALM_ROLE) .typeRole(TypeRole.REALM_ROLE)
.composite(true) .composite(true)
.containerId("container") .containerId("container")
.realmName("realm") .realmName("realm")
.clientName("client") .clientName("client")
.clientId("clientId") .clientId("clientId")
.compositeRoles(Arrays.asList("role1", "role2")) .compositeRoles(Arrays.asList("role1", "role2"))
.compositeRealmRoles( .compositeRealmRoles(
Collections.singletonList(RoleDTO.RoleCompositeDTO.builder().name("subrealm").build())) Collections.singletonList(RoleDTO.RoleCompositeDTO.builder().name("subrealm").build()))
.compositeClientRoles(clientComposites) .compositeClientRoles(clientComposites)
.attributes(attrs) .attributes(attrs)
.userCount(10) .userCount(10)
.systemRole(false) .systemRole(false)
.deletable(true) .deletable(true)
.build(); .build();
assertEquals("uuid-123", role.getId()); assertEquals("uuid-123", role.getId());
assertEquals("admin", role.getName()); assertEquals("admin", role.getName());
assertEquals("Administrator role", role.getDescription()); assertEquals("Administrator role", role.getDescription());
assertEquals(TypeRole.REALM_ROLE, role.getTypeRole()); assertEquals(TypeRole.REALM_ROLE, role.getTypeRole());
assertTrue(role.getComposite()); assertTrue(role.getComposite());
assertEquals("container", role.getContainerId()); assertEquals("container", role.getContainerId());
assertEquals("realm", role.getRealmName()); assertEquals("realm", role.getRealmName());
assertEquals("client", role.getClientName()); assertEquals("client", role.getClientName());
assertEquals("clientId", role.getClientId()); assertEquals("clientId", role.getClientId());
assertEquals(2, role.getCompositeRoles().size()); assertEquals(2, role.getCompositeRoles().size());
assertEquals(1, role.getCompositeRealmRoles().size()); assertEquals(1, role.getCompositeRealmRoles().size());
assertEquals(1, role.getCompositeClientRoles().size()); assertEquals(1, role.getCompositeClientRoles().size());
assertEquals(1, role.getAttributes().size()); assertEquals(1, role.getAttributes().size());
assertEquals(10, role.getUserCount()); assertEquals(10, role.getUserCount());
assertFalse(role.getSystemRole()); assertFalse(role.getSystemRole());
assertTrue(role.getDeletable()); assertTrue(role.getDeletable());
} }
@Test @Test
void testEqualsAndHashCode() { void testEqualsAndHashCode() {
RoleDTO role1 = RoleDTO.builder().id("uuid-123").name("admin").build(); RoleDTO role1 = RoleDTO.builder().id("uuid-123").name("admin").build();
RoleDTO role2 = 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(); RoleDTO role3 = RoleDTO.builder().id("uuid-456").name("user").build();
assertEquals(role1, role2); assertEquals(role1, role2);
assertEquals(role1.hashCode(), role2.hashCode()); assertEquals(role1.hashCode(), role2.hashCode());
assertNotEquals(role1, role3); assertNotEquals(role1, role3);
} }
@Test @Test
void testToString() { void testToString() {
RoleDTO role = RoleDTO.builder().name("admin").description("Admin role").build(); RoleDTO role = RoleDTO.builder().name("admin").description("Admin role").build();
String str = role.toString(); String str = role.toString();
assertNotNull(str); assertNotNull(str);
assertTrue(str.contains("admin")); assertTrue(str.contains("admin"));
} }
@Test @Test
void testNoArgsConstructor() { void testNoArgsConstructor() {
RoleDTO role = new RoleDTO(); RoleDTO role = new RoleDTO();
assertNull(role.getName()); assertNull(role.getName());
assertNull(role.getDescription()); assertNull(role.getDescription());
} }
@Test @Test
void testAllArgsConstructor() { void testAllArgsConstructor() {
Map<String, List<String>> attrs = new HashMap<>(); Map<String, List<String>> attrs = new HashMap<>();
Map<String, List<RoleDTO.RoleCompositeDTO>> clientComposites = new HashMap<>(); Map<String, List<RoleDTO.RoleCompositeDTO>> clientComposites = new HashMap<>();
List<String> compositeRoles = Collections.emptyList(); List<String> compositeRoles = Collections.emptyList();
List<RoleDTO.RoleCompositeDTO> realmComposites = Collections.emptyList(); List<RoleDTO.RoleCompositeDTO> realmComposites = Collections.emptyList();
RoleDTO role = new RoleDTO( RoleDTO role = new RoleDTO(
"name", "desc", TypeRole.REALM_ROLE, true, "container", "realm", "name", "desc", TypeRole.REALM_ROLE, true, "container", "realm",
"clientName", "clientId", compositeRoles, realmComposites, clientComposites, "clientName", "clientId", compositeRoles, realmComposites, clientComposites,
attrs, 5, true, false); attrs, 5, true, false);
assertEquals("name", role.getName()); assertEquals("name", role.getName());
assertEquals("desc", role.getDescription()); assertEquals("desc", role.getDescription());
assertEquals(TypeRole.REALM_ROLE, role.getTypeRole()); assertEquals(TypeRole.REALM_ROLE, role.getTypeRole());
assertTrue(role.getComposite()); assertTrue(role.getComposite());
assertEquals("container", role.getContainerId()); assertEquals("container", role.getContainerId());
assertEquals("realm", role.getRealmName()); assertEquals("realm", role.getRealmName());
assertEquals("clientName", role.getClientName()); assertEquals("clientName", role.getClientName());
assertEquals("clientId", role.getClientId()); assertEquals("clientId", role.getClientId());
assertEquals(5, role.getUserCount()); assertEquals(5, role.getUserCount());
assertTrue(role.getSystemRole()); assertTrue(role.getSystemRole());
assertFalse(role.getDeletable()); assertFalse(role.getDeletable());
} }
} }

View File

@@ -1,125 +1,125 @@
package dev.lions.user.manager.dto.sync; package dev.lions.user.manager.dto.sync;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
class HealthStatusDTOTest { class HealthStatusDTOTest {
@Test @Test
void testBuilderAndAllFields() { void testBuilderAndAllFields() {
HealthStatusDTO dto = HealthStatusDTO.builder() HealthStatusDTO dto = HealthStatusDTO.builder()
.timestamp(1699545600000L) .timestamp(1699545600000L)
.keycloakAccessible(true) .keycloakAccessible(true)
.keycloakVersion("23.0.3") .keycloakVersion("23.0.3")
.realmsAccessible(true) .realmsAccessible(true)
.realmsCount(5) .realmsCount(5)
.overallHealthy(true) .overallHealthy(true)
.errorMessage(null) .errorMessage(null)
.build(); .build();
assertEquals(1699545600000L, dto.getTimestamp()); assertEquals(1699545600000L, dto.getTimestamp());
assertTrue(dto.isKeycloakAccessible()); assertTrue(dto.isKeycloakAccessible());
assertEquals("23.0.3", dto.getKeycloakVersion()); assertEquals("23.0.3", dto.getKeycloakVersion());
assertTrue(dto.isRealmsAccessible()); assertTrue(dto.isRealmsAccessible());
assertEquals(5, dto.getRealmsCount()); assertEquals(5, dto.getRealmsCount());
assertTrue(dto.isOverallHealthy()); assertTrue(dto.isOverallHealthy());
assertNull(dto.getErrorMessage()); assertNull(dto.getErrorMessage());
} }
@Test @Test
void testBuilderWithError() { void testBuilderWithError() {
HealthStatusDTO dto = HealthStatusDTO.builder() HealthStatusDTO dto = HealthStatusDTO.builder()
.timestamp(System.currentTimeMillis()) .timestamp(System.currentTimeMillis())
.keycloakAccessible(false) .keycloakAccessible(false)
.realmsAccessible(false) .realmsAccessible(false)
.overallHealthy(false) .overallHealthy(false)
.errorMessage("Connection refused") .errorMessage("Connection refused")
.build(); .build();
assertFalse(dto.isKeycloakAccessible()); assertFalse(dto.isKeycloakAccessible());
assertFalse(dto.isRealmsAccessible()); assertFalse(dto.isRealmsAccessible());
assertFalse(dto.isOverallHealthy()); assertFalse(dto.isOverallHealthy());
assertEquals("Connection refused", dto.getErrorMessage()); assertEquals("Connection refused", dto.getErrorMessage());
} }
@Test @Test
void testSettersAndGetters() { void testSettersAndGetters() {
HealthStatusDTO dto = new HealthStatusDTO(); HealthStatusDTO dto = new HealthStatusDTO();
dto.setTimestamp(12345L); dto.setTimestamp(12345L);
dto.setKeycloakAccessible(true); dto.setKeycloakAccessible(true);
dto.setKeycloakVersion("24.0.0"); dto.setKeycloakVersion("24.0.0");
dto.setRealmsAccessible(true); dto.setRealmsAccessible(true);
dto.setRealmsCount(3); dto.setRealmsCount(3);
dto.setOverallHealthy(true); dto.setOverallHealthy(true);
dto.setErrorMessage("warning"); dto.setErrorMessage("warning");
assertEquals(12345L, dto.getTimestamp()); assertEquals(12345L, dto.getTimestamp());
assertTrue(dto.isKeycloakAccessible()); assertTrue(dto.isKeycloakAccessible());
assertEquals("24.0.0", dto.getKeycloakVersion()); assertEquals("24.0.0", dto.getKeycloakVersion());
assertTrue(dto.isRealmsAccessible()); assertTrue(dto.isRealmsAccessible());
assertEquals(3, dto.getRealmsCount()); assertEquals(3, dto.getRealmsCount());
assertTrue(dto.isOverallHealthy()); assertTrue(dto.isOverallHealthy());
assertEquals("warning", dto.getErrorMessage()); assertEquals("warning", dto.getErrorMessage());
} }
@Test @Test
void testEqualsAndHashCode() { void testEqualsAndHashCode() {
HealthStatusDTO dto1 = HealthStatusDTO.builder() HealthStatusDTO dto1 = HealthStatusDTO.builder()
.timestamp(1000L) .timestamp(1000L)
.keycloakVersion("23.0.3") .keycloakVersion("23.0.3")
.overallHealthy(true) .overallHealthy(true)
.build(); .build();
HealthStatusDTO dto2 = HealthStatusDTO.builder() HealthStatusDTO dto2 = HealthStatusDTO.builder()
.timestamp(1000L) .timestamp(1000L)
.keycloakVersion("23.0.3") .keycloakVersion("23.0.3")
.overallHealthy(true) .overallHealthy(true)
.build(); .build();
HealthStatusDTO dto3 = HealthStatusDTO.builder() HealthStatusDTO dto3 = HealthStatusDTO.builder()
.timestamp(2000L) .timestamp(2000L)
.keycloakVersion("24.0.0") .keycloakVersion("24.0.0")
.overallHealthy(false) .overallHealthy(false)
.build(); .build();
assertEquals(dto1, dto2); assertEquals(dto1, dto2);
assertEquals(dto1.hashCode(), dto2.hashCode()); assertEquals(dto1.hashCode(), dto2.hashCode());
assertNotEquals(dto1, dto3); assertNotEquals(dto1, dto3);
} }
@Test @Test
void testToString() { void testToString() {
HealthStatusDTO dto = HealthStatusDTO.builder() HealthStatusDTO dto = HealthStatusDTO.builder()
.keycloakVersion("23.0.3") .keycloakVersion("23.0.3")
.overallHealthy(true) .overallHealthy(true)
.build(); .build();
String str = dto.toString(); String str = dto.toString();
assertNotNull(str); assertNotNull(str);
assertTrue(str.contains("23.0.3")); assertTrue(str.contains("23.0.3"));
} }
@Test @Test
void testNoArgsConstructor() { void testNoArgsConstructor() {
HealthStatusDTO dto = new HealthStatusDTO(); HealthStatusDTO dto = new HealthStatusDTO();
assertEquals(0L, dto.getTimestamp()); assertEquals(0L, dto.getTimestamp());
assertFalse(dto.isKeycloakAccessible()); assertFalse(dto.isKeycloakAccessible());
assertNull(dto.getKeycloakVersion()); assertNull(dto.getKeycloakVersion());
assertFalse(dto.isRealmsAccessible()); assertFalse(dto.isRealmsAccessible());
assertEquals(0, dto.getRealmsCount()); assertEquals(0, dto.getRealmsCount());
assertFalse(dto.isOverallHealthy()); assertFalse(dto.isOverallHealthy());
assertNull(dto.getErrorMessage()); assertNull(dto.getErrorMessage());
} }
@Test @Test
void testAllArgsConstructor() { void testAllArgsConstructor() {
HealthStatusDTO dto = new HealthStatusDTO( HealthStatusDTO dto = new HealthStatusDTO(
1000L, true, "23.0.3", true, 5, true, null); 1000L, true, "23.0.3", true, 5, true, null);
assertEquals(1000L, dto.getTimestamp()); assertEquals(1000L, dto.getTimestamp());
assertTrue(dto.isKeycloakAccessible()); assertTrue(dto.isKeycloakAccessible());
assertEquals("23.0.3", dto.getKeycloakVersion()); assertEquals("23.0.3", dto.getKeycloakVersion());
assertTrue(dto.isRealmsAccessible()); assertTrue(dto.isRealmsAccessible());
assertEquals(5, dto.getRealmsCount()); assertEquals(5, dto.getRealmsCount());
assertTrue(dto.isOverallHealthy()); assertTrue(dto.isOverallHealthy());
assertNull(dto.getErrorMessage()); assertNull(dto.getErrorMessage());
} }
} }

View File

@@ -1,127 +1,127 @@
package dev.lions.user.manager.dto.sync; package dev.lions.user.manager.dto.sync;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
class SyncResultDTOTest { class SyncResultDTOTest {
@Test @Test
void testGetDurationMs() { void testGetDurationMs() {
SyncResultDTO dto = SyncResultDTO.builder() SyncResultDTO dto = SyncResultDTO.builder()
.startTime(1000L) .startTime(1000L)
.endTime(5000L) .endTime(5000L)
.build(); .build();
assertEquals(4000L, dto.getDurationMs()); assertEquals(4000L, dto.getDurationMs());
} }
@Test @Test
void testGetDurationMs_sameTime() { void testGetDurationMs_sameTime() {
SyncResultDTO dto = SyncResultDTO.builder() SyncResultDTO dto = SyncResultDTO.builder()
.startTime(1000L) .startTime(1000L)
.endTime(1000L) .endTime(1000L)
.build(); .build();
assertEquals(0L, dto.getDurationMs()); assertEquals(0L, dto.getDurationMs());
} }
@Test @Test
void testBuilderAndAllFields() { void testBuilderAndAllFields() {
SyncResultDTO dto = SyncResultDTO.builder() SyncResultDTO dto = SyncResultDTO.builder()
.realmName("btpxpress") .realmName("btpxpress")
.usersCount(150) .usersCount(150)
.realmRolesCount(25) .realmRolesCount(25)
.clientRolesCount(50) .clientRolesCount(50)
.success(true) .success(true)
.errorMessage(null) .errorMessage(null)
.startTime(1699545600000L) .startTime(1699545600000L)
.endTime(1699545615000L) .endTime(1699545615000L)
.build(); .build();
assertEquals("btpxpress", dto.getRealmName()); assertEquals("btpxpress", dto.getRealmName());
assertEquals(150, dto.getUsersCount()); assertEquals(150, dto.getUsersCount());
assertEquals(25, dto.getRealmRolesCount()); assertEquals(25, dto.getRealmRolesCount());
assertEquals(50, dto.getClientRolesCount()); assertEquals(50, dto.getClientRolesCount());
assertTrue(dto.isSuccess()); assertTrue(dto.isSuccess());
assertNull(dto.getErrorMessage()); assertNull(dto.getErrorMessage());
assertEquals(1699545600000L, dto.getStartTime()); assertEquals(1699545600000L, dto.getStartTime());
assertEquals(1699545615000L, dto.getEndTime()); assertEquals(1699545615000L, dto.getEndTime());
assertEquals(15000L, dto.getDurationMs()); assertEquals(15000L, dto.getDurationMs());
} }
@Test @Test
void testBuilderWithError() { void testBuilderWithError() {
SyncResultDTO dto = SyncResultDTO.builder() SyncResultDTO dto = SyncResultDTO.builder()
.realmName("btpxpress") .realmName("btpxpress")
.success(false) .success(false)
.errorMessage("Connection failed") .errorMessage("Connection failed")
.build(); .build();
assertEquals("btpxpress", dto.getRealmName()); assertEquals("btpxpress", dto.getRealmName());
assertFalse(dto.isSuccess()); assertFalse(dto.isSuccess());
assertEquals("Connection failed", dto.getErrorMessage()); assertEquals("Connection failed", dto.getErrorMessage());
} }
@Test @Test
void testSettersAndGetters() { void testSettersAndGetters() {
SyncResultDTO dto = new SyncResultDTO(); SyncResultDTO dto = new SyncResultDTO();
dto.setRealmName("realm"); dto.setRealmName("realm");
dto.setUsersCount(10); dto.setUsersCount(10);
dto.setRealmRolesCount(5); dto.setRealmRolesCount(5);
dto.setClientRolesCount(3); dto.setClientRolesCount(3);
dto.setSuccess(true); dto.setSuccess(true);
dto.setErrorMessage("error"); dto.setErrorMessage("error");
dto.setStartTime(100L); dto.setStartTime(100L);
dto.setEndTime(200L); dto.setEndTime(200L);
assertEquals("realm", dto.getRealmName()); assertEquals("realm", dto.getRealmName());
assertEquals(10, dto.getUsersCount()); assertEquals(10, dto.getUsersCount());
assertEquals(5, dto.getRealmRolesCount()); assertEquals(5, dto.getRealmRolesCount());
assertEquals(3, dto.getClientRolesCount()); assertEquals(3, dto.getClientRolesCount());
assertTrue(dto.isSuccess()); assertTrue(dto.isSuccess());
assertEquals("error", dto.getErrorMessage()); assertEquals("error", dto.getErrorMessage());
assertEquals(100L, dto.getStartTime()); assertEquals(100L, dto.getStartTime());
assertEquals(200L, dto.getEndTime()); assertEquals(200L, dto.getEndTime());
} }
@Test @Test
void testEqualsAndHashCode() { void testEqualsAndHashCode() {
SyncResultDTO dto1 = SyncResultDTO.builder().realmName("realm").usersCount(10).build(); SyncResultDTO dto1 = SyncResultDTO.builder().realmName("realm").usersCount(10).build();
SyncResultDTO dto2 = 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(); SyncResultDTO dto3 = SyncResultDTO.builder().realmName("other").usersCount(5).build();
assertEquals(dto1, dto2); assertEquals(dto1, dto2);
assertEquals(dto1.hashCode(), dto2.hashCode()); assertEquals(dto1.hashCode(), dto2.hashCode());
assertNotEquals(dto1, dto3); assertNotEquals(dto1, dto3);
} }
@Test @Test
void testToString() { void testToString() {
SyncResultDTO dto = SyncResultDTO.builder().realmName("realm").success(true).build(); SyncResultDTO dto = SyncResultDTO.builder().realmName("realm").success(true).build();
String str = dto.toString(); String str = dto.toString();
assertNotNull(str); assertNotNull(str);
assertTrue(str.contains("realm")); assertTrue(str.contains("realm"));
} }
@Test @Test
void testNoArgsConstructor() { void testNoArgsConstructor() {
SyncResultDTO dto = new SyncResultDTO(); SyncResultDTO dto = new SyncResultDTO();
assertNull(dto.getRealmName()); assertNull(dto.getRealmName());
assertEquals(0, dto.getUsersCount()); assertEquals(0, dto.getUsersCount());
assertFalse(dto.isSuccess()); assertFalse(dto.isSuccess());
} }
@Test @Test
void testAllArgsConstructor() { void testAllArgsConstructor() {
SyncResultDTO dto = new SyncResultDTO( SyncResultDTO dto = new SyncResultDTO(
"realm", 100, 20, 30, true, null, 1000L, 2000L); "realm", 100, 20, 30, true, null, 1000L, 2000L);
assertEquals("realm", dto.getRealmName()); assertEquals("realm", dto.getRealmName());
assertEquals(100, dto.getUsersCount()); assertEquals(100, dto.getUsersCount());
assertEquals(20, dto.getRealmRolesCount()); assertEquals(20, dto.getRealmRolesCount());
assertEquals(30, dto.getClientRolesCount()); assertEquals(30, dto.getClientRolesCount());
assertTrue(dto.isSuccess()); assertTrue(dto.isSuccess());
assertNull(dto.getErrorMessage()); assertNull(dto.getErrorMessage());
assertEquals(1000L, dto.getStartTime()); assertEquals(1000L, dto.getStartTime());
assertEquals(2000L, dto.getEndTime()); assertEquals(2000L, dto.getEndTime());
} }
} }

View File

@@ -1,305 +1,305 @@
package dev.lions.user.manager.dto.user; package dev.lions.user.manager.dto.user;
import dev.lions.user.manager.enums.user.StatutUser; import dev.lions.user.manager.enums.user.StatutUser;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
class UserDTOTest { class UserDTOTest {
@Test @Test
void testGetNomComplet_withPrenomAndNom() { void testGetNomComplet_withPrenomAndNom() {
UserDTO user = new UserDTO(); UserDTO user = new UserDTO();
user.setPrenom("Jean"); user.setPrenom("Jean");
user.setNom("Dupont"); user.setNom("Dupont");
user.setUsername("jdupont"); user.setUsername("jdupont");
assertEquals("Jean Dupont", user.getNomComplet()); assertEquals("Jean Dupont", user.getNomComplet());
} }
@Test @Test
void testGetNomComplet_withNullPrenom() { void testGetNomComplet_withNullPrenom() {
UserDTO user = new UserDTO(); UserDTO user = new UserDTO();
user.setPrenom(null); user.setPrenom(null);
user.setNom("Dupont"); user.setNom("Dupont");
user.setUsername("jdupont"); user.setUsername("jdupont");
assertEquals("jdupont", user.getNomComplet()); assertEquals("jdupont", user.getNomComplet());
} }
@Test @Test
void testGetNomComplet_withNullNom() { void testGetNomComplet_withNullNom() {
UserDTO user = new UserDTO(); UserDTO user = new UserDTO();
user.setPrenom("Jean"); user.setPrenom("Jean");
user.setNom(null); user.setNom(null);
user.setUsername("jdupont"); user.setUsername("jdupont");
assertEquals("jdupont", user.getNomComplet()); assertEquals("jdupont", user.getNomComplet());
} }
@Test @Test
void testGetNomComplet_withBothNull() { void testGetNomComplet_withBothNull() {
UserDTO user = new UserDTO(); UserDTO user = new UserDTO();
user.setPrenom(null); user.setPrenom(null);
user.setNom(null); user.setNom(null);
user.setUsername("jdupont"); user.setUsername("jdupont");
assertEquals("jdupont", user.getNomComplet()); assertEquals("jdupont", user.getNomComplet());
} }
@Test @Test
void testIsActif_true() { void testIsActif_true() {
UserDTO user = new UserDTO(); UserDTO user = new UserDTO();
user.setStatut(StatutUser.ACTIF); user.setStatut(StatutUser.ACTIF);
user.setEnabled(true); user.setEnabled(true);
assertTrue(user.isActif()); assertTrue(user.isActif());
} }
@Test @Test
void testIsActif_falseWhenNotActif() { void testIsActif_falseWhenNotActif() {
UserDTO user = new UserDTO(); UserDTO user = new UserDTO();
user.setStatut(StatutUser.INACTIF); user.setStatut(StatutUser.INACTIF);
user.setEnabled(true); user.setEnabled(true);
assertFalse(user.isActif()); assertFalse(user.isActif());
} }
@Test @Test
void testIsActif_falseWhenNotEnabled() { void testIsActif_falseWhenNotEnabled() {
UserDTO user = new UserDTO(); UserDTO user = new UserDTO();
user.setStatut(StatutUser.ACTIF); user.setStatut(StatutUser.ACTIF);
user.setEnabled(false); user.setEnabled(false);
assertFalse(user.isActif()); assertFalse(user.isActif());
} }
@Test @Test
void testIsActif_falseWhenEnabledNull() { void testIsActif_falseWhenEnabledNull() {
UserDTO user = new UserDTO(); UserDTO user = new UserDTO();
user.setStatut(StatutUser.ACTIF); user.setStatut(StatutUser.ACTIF);
user.setEnabled(null); user.setEnabled(null);
assertFalse(user.isActif()); assertFalse(user.isActif());
} }
@Test @Test
void testIsExpire_true() { void testIsExpire_true() {
UserDTO user = new UserDTO(); UserDTO user = new UserDTO();
user.setDateExpiration(LocalDateTime.now().minusDays(1)); user.setDateExpiration(LocalDateTime.now().minusDays(1));
assertTrue(user.isExpire()); assertTrue(user.isExpire());
} }
@Test @Test
void testIsExpire_false() { void testIsExpire_false() {
UserDTO user = new UserDTO(); UserDTO user = new UserDTO();
user.setDateExpiration(LocalDateTime.now().plusDays(1)); user.setDateExpiration(LocalDateTime.now().plusDays(1));
assertFalse(user.isExpire()); assertFalse(user.isExpire());
} }
@Test @Test
void testIsExpire_nullDate() { void testIsExpire_nullDate() {
UserDTO user = new UserDTO(); UserDTO user = new UserDTO();
user.setDateExpiration(null); user.setDateExpiration(null);
assertFalse(user.isExpire()); assertFalse(user.isExpire());
} }
@Test @Test
void testHasRequiredActions_true() { void testHasRequiredActions_true() {
UserDTO user = new UserDTO(); UserDTO user = new UserDTO();
user.setRequiredActions(Arrays.asList("UPDATE_PASSWORD", "VERIFY_EMAIL")); user.setRequiredActions(Arrays.asList("UPDATE_PASSWORD", "VERIFY_EMAIL"));
assertTrue(user.hasRequiredActions()); assertTrue(user.hasRequiredActions());
} }
@Test @Test
void testHasRequiredActions_empty() { void testHasRequiredActions_empty() {
UserDTO user = new UserDTO(); UserDTO user = new UserDTO();
user.setRequiredActions(Collections.emptyList()); user.setRequiredActions(Collections.emptyList());
assertFalse(user.hasRequiredActions()); assertFalse(user.hasRequiredActions());
} }
@Test @Test
void testHasRequiredActions_null() { void testHasRequiredActions_null() {
UserDTO user = new UserDTO(); UserDTO user = new UserDTO();
user.setRequiredActions(null); user.setRequiredActions(null);
assertFalse(user.hasRequiredActions()); assertFalse(user.hasRequiredActions());
} }
@Test @Test
void testBuilderAndAllFields() { void testBuilderAndAllFields() {
LocalDateTime now = LocalDateTime.now(); LocalDateTime now = LocalDateTime.now();
Map<String, List<String>> clientRoles = new HashMap<>(); Map<String, List<String>> clientRoles = new HashMap<>();
clientRoles.put("app", Arrays.asList("user", "admin")); clientRoles.put("app", Arrays.asList("user", "admin"));
Map<String, List<String>> attributes = new HashMap<>(); Map<String, List<String>> attributes = new HashMap<>();
attributes.put("custom", Collections.singletonList("value")); attributes.put("custom", Collections.singletonList("value"));
List<UserDTO.FederatedIdentityDTO> fedIds = Collections.singletonList( List<UserDTO.FederatedIdentityDTO> fedIds = Collections.singletonList(
UserDTO.FederatedIdentityDTO.builder() UserDTO.FederatedIdentityDTO.builder()
.identityProvider("google") .identityProvider("google")
.userId("google-123") .userId("google-123")
.userName("user@gmail.com") .userName("user@gmail.com")
.build()); .build());
UserDTO user = UserDTO.builder() UserDTO user = UserDTO.builder()
.id("uuid-123") .id("uuid-123")
.dateCreation(now) .dateCreation(now)
.dateModification(now) .dateModification(now)
.creeParUsername("admin") .creeParUsername("admin")
.modifieParUsername("admin") .modifieParUsername("admin")
.version(1L) .version(1L)
.username("jdupont") .username("jdupont")
.email("jean.dupont@lions.dev") .email("jean.dupont@lions.dev")
.emailVerified(true) .emailVerified(true)
.prenom("Jean") .prenom("Jean")
.nom("Dupont") .nom("Dupont")
.statut(StatutUser.ACTIF) .statut(StatutUser.ACTIF)
.enabled(true) .enabled(true)
.telephone("+225 07 12 34 56 78") .telephone("+225 07 12 34 56 78")
.organisation("Lions Dev") .organisation("Lions Dev")
.departement("IT") .departement("IT")
.fonction("Developer") .fonction("Developer")
.pays("Côte d'Ivoire") .pays("Côte d'Ivoire")
.ville("Abidjan") .ville("Abidjan")
.langue("fr") .langue("fr")
.timezone("Africa/Abidjan") .timezone("Africa/Abidjan")
.realmName("btpxpress") .realmName("btpxpress")
.realmRoles(Arrays.asList("user", "admin")) .realmRoles(Arrays.asList("user", "admin"))
.clientRoles(clientRoles) .clientRoles(clientRoles)
.groups(Arrays.asList("group1", "group2")) .groups(Arrays.asList("group1", "group2"))
.derniereConnexion(now) .derniereConnexion(now)
.dateExpiration(now.plusYears(1)) .dateExpiration(now.plusYears(1))
.dateVerrouillage(null) .dateVerrouillage(null)
.attributes(attributes) .attributes(attributes)
.requiredActions(Collections.singletonList("UPDATE_PASSWORD")) .requiredActions(Collections.singletonList("UPDATE_PASSWORD"))
.federatedIdentityProvider("google") .federatedIdentityProvider("google")
.federatedIdentities(fedIds) .federatedIdentities(fedIds)
.temporaryPassword("temp123") .temporaryPassword("temp123")
.temporaryPasswordFlag(true) .temporaryPasswordFlag(true)
.activeSessions(2) .activeSessions(2)
.failedLoginAttempts(0) .failedLoginAttempts(0)
.raisonModification("Update") .raisonModification("Update")
.commentaires("Test user") .commentaires("Test user")
.build(); .build();
assertEquals("uuid-123", user.getId()); assertEquals("uuid-123", user.getId());
assertNotNull(user.getDateCreation()); assertNotNull(user.getDateCreation());
assertNotNull(user.getDateModification()); assertNotNull(user.getDateModification());
assertEquals("admin", user.getCreeParUsername()); assertEquals("admin", user.getCreeParUsername());
assertEquals("admin", user.getModifieParUsername()); assertEquals("admin", user.getModifieParUsername());
assertEquals(1L, user.getVersion()); assertEquals(1L, user.getVersion());
assertEquals("jdupont", user.getUsername()); assertEquals("jdupont", user.getUsername());
assertEquals("jean.dupont@lions.dev", user.getEmail()); assertEquals("jean.dupont@lions.dev", user.getEmail());
assertTrue(user.getEmailVerified()); assertTrue(user.getEmailVerified());
assertEquals("Jean", user.getPrenom()); assertEquals("Jean", user.getPrenom());
assertEquals("Dupont", user.getNom()); assertEquals("Dupont", user.getNom());
assertEquals(StatutUser.ACTIF, user.getStatut()); assertEquals(StatutUser.ACTIF, user.getStatut());
assertTrue(user.getEnabled()); assertTrue(user.getEnabled());
assertEquals("+225 07 12 34 56 78", user.getTelephone()); assertEquals("+225 07 12 34 56 78", user.getTelephone());
assertEquals("Lions Dev", user.getOrganisation()); assertEquals("Lions Dev", user.getOrganisation());
assertEquals("IT", user.getDepartement()); assertEquals("IT", user.getDepartement());
assertEquals("Developer", user.getFonction()); assertEquals("Developer", user.getFonction());
assertEquals("Côte d'Ivoire", user.getPays()); assertEquals("Côte d'Ivoire", user.getPays());
assertEquals("Abidjan", user.getVille()); assertEquals("Abidjan", user.getVille());
assertEquals("fr", user.getLangue()); assertEquals("fr", user.getLangue());
assertEquals("Africa/Abidjan", user.getTimezone()); assertEquals("Africa/Abidjan", user.getTimezone());
assertEquals("btpxpress", user.getRealmName()); assertEquals("btpxpress", user.getRealmName());
assertEquals(2, user.getRealmRoles().size()); assertEquals(2, user.getRealmRoles().size());
assertEquals(1, user.getClientRoles().size()); assertEquals(1, user.getClientRoles().size());
assertEquals(2, user.getGroups().size()); assertEquals(2, user.getGroups().size());
assertNotNull(user.getDerniereConnexion()); assertNotNull(user.getDerniereConnexion());
assertNotNull(user.getDateExpiration()); assertNotNull(user.getDateExpiration());
assertNull(user.getDateVerrouillage()); assertNull(user.getDateVerrouillage());
assertEquals(1, user.getAttributes().size()); assertEquals(1, user.getAttributes().size());
assertEquals(1, user.getRequiredActions().size()); assertEquals(1, user.getRequiredActions().size());
assertEquals("google", user.getFederatedIdentityProvider()); assertEquals("google", user.getFederatedIdentityProvider());
assertEquals(1, user.getFederatedIdentities().size()); assertEquals(1, user.getFederatedIdentities().size());
assertEquals("temp123", user.getTemporaryPassword()); assertEquals("temp123", user.getTemporaryPassword());
assertTrue(user.getTemporaryPasswordFlag()); assertTrue(user.getTemporaryPasswordFlag());
assertEquals(2, user.getActiveSessions()); assertEquals(2, user.getActiveSessions());
assertEquals(0, user.getFailedLoginAttempts()); assertEquals(0, user.getFailedLoginAttempts());
assertEquals("Update", user.getRaisonModification()); assertEquals("Update", user.getRaisonModification());
assertEquals("Test user", user.getCommentaires()); assertEquals("Test user", user.getCommentaires());
} }
@Test @Test
void testEqualsAndHashCode() { void testEqualsAndHashCode() {
UserDTO user1 = UserDTO.builder().id("uuid-123").username("jdupont").build(); UserDTO user1 = UserDTO.builder().id("uuid-123").username("jdupont").build();
UserDTO user2 = 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(); UserDTO user3 = UserDTO.builder().id("uuid-456").username("other").build();
assertEquals(user1, user2); assertEquals(user1, user2);
assertEquals(user1.hashCode(), user2.hashCode()); assertEquals(user1.hashCode(), user2.hashCode());
assertNotEquals(user1, user3); assertNotEquals(user1, user3);
} }
@Test @Test
void testToString() { void testToString() {
UserDTO user = UserDTO.builder().username("jdupont").email("test@test.com").build(); UserDTO user = UserDTO.builder().username("jdupont").email("test@test.com").build();
String str = user.toString(); String str = user.toString();
assertNotNull(str); assertNotNull(str);
assertTrue(str.contains("jdupont")); assertTrue(str.contains("jdupont"));
assertTrue(str.contains("test@test.com")); assertTrue(str.contains("test@test.com"));
} }
@Test @Test
void testFederatedIdentityDTO() { void testFederatedIdentityDTO() {
UserDTO.FederatedIdentityDTO fed = new UserDTO.FederatedIdentityDTO(); UserDTO.FederatedIdentityDTO fed = new UserDTO.FederatedIdentityDTO();
fed.setIdentityProvider("google"); fed.setIdentityProvider("google");
fed.setUserId("user-123"); fed.setUserId("user-123");
fed.setUserName("user@gmail.com"); fed.setUserName("user@gmail.com");
assertEquals("google", fed.getIdentityProvider()); assertEquals("google", fed.getIdentityProvider());
assertEquals("user-123", fed.getUserId()); assertEquals("user-123", fed.getUserId());
assertEquals("user@gmail.com", fed.getUserName()); assertEquals("user@gmail.com", fed.getUserName());
// Test equals/hashCode/toString // Test equals/hashCode/toString
UserDTO.FederatedIdentityDTO fed2 = UserDTO.FederatedIdentityDTO.builder() UserDTO.FederatedIdentityDTO fed2 = UserDTO.FederatedIdentityDTO.builder()
.identityProvider("google") .identityProvider("google")
.userId("user-123") .userId("user-123")
.userName("user@gmail.com") .userName("user@gmail.com")
.build(); .build();
assertEquals(fed, fed2); assertEquals(fed, fed2);
assertEquals(fed.hashCode(), fed2.hashCode()); assertEquals(fed.hashCode(), fed2.hashCode());
assertNotNull(fed.toString()); assertNotNull(fed.toString());
} }
@Test @Test
void testFederatedIdentityDTO_AllArgsConstructor() { void testFederatedIdentityDTO_AllArgsConstructor() {
UserDTO.FederatedIdentityDTO fed = new UserDTO.FederatedIdentityDTO("google", "user-123", "user@gmail.com"); UserDTO.FederatedIdentityDTO fed = new UserDTO.FederatedIdentityDTO("google", "user-123", "user@gmail.com");
assertEquals("google", fed.getIdentityProvider()); assertEquals("google", fed.getIdentityProvider());
assertEquals("user-123", fed.getUserId()); assertEquals("user-123", fed.getUserId());
assertEquals("user@gmail.com", fed.getUserName()); assertEquals("user@gmail.com", fed.getUserName());
} }
@Test @Test
void testNoArgsConstructor() { void testNoArgsConstructor() {
UserDTO user = new UserDTO(); UserDTO user = new UserDTO();
assertNull(user.getUsername()); assertNull(user.getUsername());
assertNull(user.getEmail()); assertNull(user.getEmail());
} }
@Test @Test
void testAllArgsConstructor() { void testAllArgsConstructor() {
LocalDateTime now = LocalDateTime.now(); LocalDateTime now = LocalDateTime.now();
Map<String, List<String>> clientRoles = new HashMap<>(); Map<String, List<String>> clientRoles = new HashMap<>();
Map<String, List<String>> attributes = new HashMap<>(); Map<String, List<String>> attributes = new HashMap<>();
List<UserDTO.FederatedIdentityDTO> fedIds = Collections.emptyList(); List<UserDTO.FederatedIdentityDTO> fedIds = Collections.emptyList();
List<String> roles = Collections.emptyList(); List<String> roles = Collections.emptyList();
List<String> groups = Collections.emptyList(); List<String> groups = Collections.emptyList();
List<String> actions = Collections.emptyList(); List<String> actions = Collections.emptyList();
UserDTO user = new UserDTO( UserDTO user = new UserDTO(
"username", "email@test.com", true, "Jean", "Dupont", "username", "email@test.com", true, "Jean", "Dupont",
StatutUser.ACTIF, true, "phone", "org", "dept", "func", StatutUser.ACTIF, true, "phone", "org", "dept", "func",
"pays", "ville", "fr", "UTC", "realm", roles, clientRoles, "pays", "ville", "fr", "UTC", "realm", roles, clientRoles,
groups, now, now, now, attributes, actions, "google", fedIds, groups, now, now, now, attributes, actions, "google", fedIds,
"temppass", true, 1, 0, "reason", "comments"); "temppass", true, 1, 0, "reason", "comments");
assertEquals("username", user.getUsername()); assertEquals("username", user.getUsername());
assertEquals("email@test.com", user.getEmail()); assertEquals("email@test.com", user.getEmail());
assertTrue(user.getEmailVerified()); assertTrue(user.getEmailVerified());
assertEquals("Jean", user.getPrenom()); assertEquals("Jean", user.getPrenom());
assertEquals("Dupont", user.getNom()); assertEquals("Dupont", user.getNom());
assertEquals(StatutUser.ACTIF, user.getStatut()); assertEquals(StatutUser.ACTIF, user.getStatut());
assertTrue(user.getEnabled()); assertTrue(user.getEnabled());
} }
} }

View File

@@ -1,145 +1,145 @@
package dev.lions.user.manager.dto.user; package dev.lions.user.manager.dto.user;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
/** /**
* Tests unitaires pour UserSearchCriteriaDTO * Tests unitaires pour UserSearchCriteriaDTO
*/ */
class UserSearchCriteriaDTOTest { class UserSearchCriteriaDTOTest {
@Test @Test
void testBuilder() { void testBuilder() {
UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder() UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder()
.realmName("test-realm") .realmName("test-realm")
.username("testuser") .username("testuser")
.email("test@example.com") .email("test@example.com")
.enabled(true) .enabled(true)
.page(0) .page(0)
.pageSize(20) .pageSize(20)
.build(); .build();
assertNotNull(criteria); assertNotNull(criteria);
assertEquals("test-realm", criteria.getRealmName()); assertEquals("test-realm", criteria.getRealmName());
assertEquals("testuser", criteria.getUsername()); assertEquals("testuser", criteria.getUsername());
assertEquals("test@example.com", criteria.getEmail()); assertEquals("test@example.com", criteria.getEmail());
assertTrue(criteria.getEnabled()); assertTrue(criteria.getEnabled());
assertEquals(0, criteria.getPage()); assertEquals(0, criteria.getPage());
assertEquals(20, criteria.getPageSize()); assertEquals(20, criteria.getPageSize());
} }
@Test @Test
void testNoArgsConstructor() { void testNoArgsConstructor() {
UserSearchCriteriaDTO criteria = new UserSearchCriteriaDTO(); UserSearchCriteriaDTO criteria = new UserSearchCriteriaDTO();
assertNotNull(criteria); assertNotNull(criteria);
assertNull(criteria.getRealmName()); assertNull(criteria.getRealmName());
assertNull(criteria.getUsername()); assertNull(criteria.getUsername());
assertNull(criteria.getEmail()); assertNull(criteria.getEmail());
assertNull(criteria.getEnabled()); assertNull(criteria.getEnabled());
} }
@Test @Test
void testAllArgsConstructor() { void testAllArgsConstructor() {
// Le constructeur AllArgsConstructor nécessite tous les champs // Le constructeur AllArgsConstructor nécessite tous les champs
// On utilise plutôt le builder pour ce test // On utilise plutôt le builder pour ce test
UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder() UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder()
.realmName("test-realm") .realmName("test-realm")
.username("testuser") .username("testuser")
.email("test@example.com") .email("test@example.com")
.enabled(true) .enabled(true)
.page(0) .page(0)
.pageSize(20) .pageSize(20)
.build(); .build();
assertNotNull(criteria); assertNotNull(criteria);
assertEquals("test-realm", criteria.getRealmName()); assertEquals("test-realm", criteria.getRealmName());
assertEquals("testuser", criteria.getUsername()); assertEquals("testuser", criteria.getUsername());
assertEquals("test@example.com", criteria.getEmail()); assertEquals("test@example.com", criteria.getEmail());
assertTrue(criteria.getEnabled()); assertTrue(criteria.getEnabled());
assertEquals(0, criteria.getPage()); assertEquals(0, criteria.getPage());
assertEquals(20, criteria.getPageSize()); assertEquals(20, criteria.getPageSize());
} }
@Test @Test
void testSettersAndGetters() { void testSettersAndGetters() {
UserSearchCriteriaDTO criteria = new UserSearchCriteriaDTO(); UserSearchCriteriaDTO criteria = new UserSearchCriteriaDTO();
criteria.setRealmName("realm1"); criteria.setRealmName("realm1");
criteria.setUsername("user1"); criteria.setUsername("user1");
criteria.setEmail("user1@example.com"); criteria.setEmail("user1@example.com");
criteria.setEnabled(false); criteria.setEnabled(false);
criteria.setPage(1); criteria.setPage(1);
criteria.setPageSize(10); criteria.setPageSize(10);
assertEquals("realm1", criteria.getRealmName()); assertEquals("realm1", criteria.getRealmName());
assertEquals("user1", criteria.getUsername()); assertEquals("user1", criteria.getUsername());
assertEquals("user1@example.com", criteria.getEmail()); assertEquals("user1@example.com", criteria.getEmail());
assertFalse(criteria.getEnabled()); assertFalse(criteria.getEnabled());
assertEquals(1, criteria.getPage()); assertEquals(1, criteria.getPage());
assertEquals(10, criteria.getPageSize()); assertEquals(10, criteria.getPageSize());
} }
@Test @Test
void testEqualsAndHashCode() { void testEqualsAndHashCode() {
UserSearchCriteriaDTO criteria1 = UserSearchCriteriaDTO.builder() UserSearchCriteriaDTO criteria1 = UserSearchCriteriaDTO.builder()
.realmName("test-realm") .realmName("test-realm")
.username("testuser") .username("testuser")
.build(); .build();
UserSearchCriteriaDTO criteria2 = UserSearchCriteriaDTO.builder() UserSearchCriteriaDTO criteria2 = UserSearchCriteriaDTO.builder()
.realmName("test-realm") .realmName("test-realm")
.username("testuser") .username("testuser")
.build(); .build();
assertEquals(criteria1, criteria2); assertEquals(criteria1, criteria2);
assertEquals(criteria1.hashCode(), criteria2.hashCode()); assertEquals(criteria1.hashCode(), criteria2.hashCode());
} }
@Test @Test
void testToString() { void testToString() {
UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder() UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder()
.realmName("test-realm") .realmName("test-realm")
.username("testuser") .username("testuser")
.build(); .build();
String toString = criteria.toString(); String toString = criteria.toString();
assertNotNull(toString); assertNotNull(toString);
assertTrue(toString.contains("test-realm") || toString.contains("testuser")); assertTrue(toString.contains("test-realm") || toString.contains("testuser"));
} }
@Test @Test
void testHasFilters_WithFilters() { void testHasFilters_WithFilters() {
UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder() UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder()
.username("testuser") .username("testuser")
.enabled(true) .enabled(true)
.build(); .build();
assertTrue(criteria.hasFilters()); assertTrue(criteria.hasFilters());
} }
@Test @Test
void testHasFilters_NoFilters() { void testHasFilters_NoFilters() {
UserSearchCriteriaDTO criteria = new UserSearchCriteriaDTO(); UserSearchCriteriaDTO criteria = new UserSearchCriteriaDTO();
assertFalse(criteria.hasFilters()); assertFalse(criteria.hasFilters());
} }
@Test @Test
void testGetOffset() { void testGetOffset() {
UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder() UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder()
.page(2) .page(2)
.pageSize(20) .pageSize(20)
.build(); .build();
assertEquals(40, criteria.getOffset()); assertEquals(40, criteria.getOffset());
} }
@Test @Test
void testGetOffset_Default() { void testGetOffset_Default() {
UserSearchCriteriaDTO criteria = new UserSearchCriteriaDTO(); UserSearchCriteriaDTO criteria = new UserSearchCriteriaDTO();
assertEquals(0, criteria.getOffset()); assertEquals(0, criteria.getOffset());
} }
} }

View File

@@ -1,279 +1,279 @@
package dev.lions.user.manager.dto.user; package dev.lions.user.manager.dto.user;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
class UserSearchResultDTOTest { class UserSearchResultDTOTest {
@Test @Test
void testOf_firstPage() { void testOf_firstPage() {
List<UserDTO> users = Arrays.asList( List<UserDTO> users = Arrays.asList(
UserDTO.builder().username("user1").build(), UserDTO.builder().username("user1").build(),
UserDTO.builder().username("user2").build()); UserDTO.builder().username("user2").build());
UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder() UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder()
.page(0) .page(0)
.pageSize(10) .pageSize(10)
.build(); .build();
UserSearchResultDTO result = UserSearchResultDTO.of(users, criteria, 25L); UserSearchResultDTO result = UserSearchResultDTO.of(users, criteria, 25L);
assertEquals(2, result.getUsers().size()); assertEquals(2, result.getUsers().size());
assertEquals(25L, result.getTotalCount()); assertEquals(25L, result.getTotalCount());
assertEquals(0, result.getCurrentPage()); assertEquals(0, result.getCurrentPage());
assertEquals(10, result.getPageSize()); assertEquals(10, result.getPageSize());
assertEquals(3, result.getTotalPages()); assertEquals(3, result.getTotalPages());
assertTrue(result.getHasNextPage()); assertTrue(result.getHasNextPage());
assertFalse(result.getHasPreviousPage()); assertFalse(result.getHasPreviousPage());
assertEquals(0, result.getFirstElement()); assertEquals(0, result.getFirstElement());
assertEquals(9, result.getLastElement()); assertEquals(9, result.getLastElement());
assertFalse(result.getIsEmpty()); assertFalse(result.getIsEmpty());
assertTrue(result.getIsFirstPage()); assertTrue(result.getIsFirstPage());
assertFalse(result.getIsLastPage()); assertFalse(result.getIsLastPage());
assertEquals(criteria, result.getCriteria()); assertEquals(criteria, result.getCriteria());
} }
@Test @Test
void testOf_middlePage() { void testOf_middlePage() {
List<UserDTO> users = Arrays.asList( List<UserDTO> users = Arrays.asList(
UserDTO.builder().username("user1").build()); UserDTO.builder().username("user1").build());
UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder() UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder()
.page(1) .page(1)
.pageSize(10) .pageSize(10)
.build(); .build();
UserSearchResultDTO result = UserSearchResultDTO.of(users, criteria, 25L); UserSearchResultDTO result = UserSearchResultDTO.of(users, criteria, 25L);
assertEquals(1, result.getCurrentPage()); assertEquals(1, result.getCurrentPage());
assertTrue(result.getHasNextPage()); assertTrue(result.getHasNextPage());
assertTrue(result.getHasPreviousPage()); assertTrue(result.getHasPreviousPage());
assertFalse(result.getIsFirstPage()); assertFalse(result.getIsFirstPage());
assertFalse(result.getIsLastPage()); assertFalse(result.getIsLastPage());
} }
@Test @Test
void testOf_lastPage() { void testOf_lastPage() {
List<UserDTO> users = Arrays.asList( List<UserDTO> users = Arrays.asList(
UserDTO.builder().username("user1").build()); UserDTO.builder().username("user1").build());
UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder() UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder()
.page(2) .page(2)
.pageSize(10) .pageSize(10)
.build(); .build();
UserSearchResultDTO result = UserSearchResultDTO.of(users, criteria, 25L); UserSearchResultDTO result = UserSearchResultDTO.of(users, criteria, 25L);
assertEquals(2, result.getCurrentPage()); assertEquals(2, result.getCurrentPage());
assertFalse(result.getHasNextPage()); assertFalse(result.getHasNextPage());
assertTrue(result.getHasPreviousPage()); assertTrue(result.getHasPreviousPage());
assertFalse(result.getIsFirstPage()); assertFalse(result.getIsFirstPage());
assertTrue(result.getIsLastPage()); assertTrue(result.getIsLastPage());
} }
@Test @Test
void testOf_emptyList() { void testOf_emptyList() {
List<UserDTO> users = Collections.emptyList(); List<UserDTO> users = Collections.emptyList();
UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder() UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder()
.page(0) .page(0)
.pageSize(20) .pageSize(20)
.build(); .build();
UserSearchResultDTO result = UserSearchResultDTO.of(users, criteria, 0L); UserSearchResultDTO result = UserSearchResultDTO.of(users, criteria, 0L);
assertTrue(result.getIsEmpty()); assertTrue(result.getIsEmpty());
assertEquals(0, result.getTotalCount()); assertEquals(0, result.getTotalCount());
assertEquals(0, result.getTotalPages()); assertEquals(0, result.getTotalPages());
} }
@Test @Test
void testOf_nullList() { void testOf_nullList() {
UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder() UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder()
.page(0) .page(0)
.pageSize(20) .pageSize(20)
.build(); .build();
UserSearchResultDTO result = UserSearchResultDTO.of(null, criteria, 0L); UserSearchResultDTO result = UserSearchResultDTO.of(null, criteria, 0L);
assertTrue(result.getIsEmpty()); assertTrue(result.getIsEmpty());
} }
@Test @Test
void testOf_singlePage() { void testOf_singlePage() {
List<UserDTO> users = Arrays.asList( List<UserDTO> users = Arrays.asList(
UserDTO.builder().username("user1").build()); UserDTO.builder().username("user1").build());
UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder() UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder()
.page(0) .page(0)
.pageSize(10) .pageSize(10)
.build(); .build();
UserSearchResultDTO result = UserSearchResultDTO.of(users, criteria, 5L); UserSearchResultDTO result = UserSearchResultDTO.of(users, criteria, 5L);
assertEquals(1, result.getTotalPages()); assertEquals(1, result.getTotalPages());
assertFalse(result.getHasNextPage()); assertFalse(result.getHasNextPage());
assertFalse(result.getHasPreviousPage()); assertFalse(result.getHasPreviousPage());
assertTrue(result.getIsFirstPage()); assertTrue(result.getIsFirstPage());
assertTrue(result.getIsLastPage()); assertTrue(result.getIsLastPage());
} }
@Test @Test
void testGetCurrentPageSize_withUsers() { void testGetCurrentPageSize_withUsers() {
UserSearchResultDTO result = UserSearchResultDTO.builder() UserSearchResultDTO result = UserSearchResultDTO.builder()
.users(Arrays.asList( .users(Arrays.asList(
UserDTO.builder().username("u1").build(), UserDTO.builder().username("u1").build(),
UserDTO.builder().username("u2").build(), UserDTO.builder().username("u2").build(),
UserDTO.builder().username("u3").build())) UserDTO.builder().username("u3").build()))
.build(); .build();
assertEquals(3, result.getCurrentPageSize()); assertEquals(3, result.getCurrentPageSize());
} }
@Test @Test
void testGetCurrentPageSize_emptyUsers() { void testGetCurrentPageSize_emptyUsers() {
UserSearchResultDTO result = UserSearchResultDTO.builder() UserSearchResultDTO result = UserSearchResultDTO.builder()
.users(Collections.emptyList()) .users(Collections.emptyList())
.build(); .build();
assertEquals(0, result.getCurrentPageSize()); assertEquals(0, result.getCurrentPageSize());
} }
@Test @Test
void testGetCurrentPageSize_nullUsers() { void testGetCurrentPageSize_nullUsers() {
UserSearchResultDTO result = UserSearchResultDTO.builder() UserSearchResultDTO result = UserSearchResultDTO.builder()
.users(null) .users(null)
.build(); .build();
assertEquals(0, result.getCurrentPageSize()); assertEquals(0, result.getCurrentPageSize());
} }
@Test @Test
void testBuilderAndAllFields() { void testBuilderAndAllFields() {
List<UserDTO> users = Collections.singletonList(UserDTO.builder().username("test").build()); List<UserDTO> users = Collections.singletonList(UserDTO.builder().username("test").build());
UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder().page(0).pageSize(20).build(); UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder().page(0).pageSize(20).build();
UserSearchResultDTO result = UserSearchResultDTO.builder() UserSearchResultDTO result = UserSearchResultDTO.builder()
.users(users) .users(users)
.totalCount(100L) .totalCount(100L)
.currentPage(0) .currentPage(0)
.pageSize(20) .pageSize(20)
.totalPages(5) .totalPages(5)
.hasNextPage(true) .hasNextPage(true)
.hasPreviousPage(false) .hasPreviousPage(false)
.firstElement(0) .firstElement(0)
.lastElement(19) .lastElement(19)
.isEmpty(false) .isEmpty(false)
.isFirstPage(true) .isFirstPage(true)
.isLastPage(false) .isLastPage(false)
.criteria(criteria) .criteria(criteria)
.executionTimeMs(150L) .executionTimeMs(150L)
.build(); .build();
assertEquals(users, result.getUsers()); assertEquals(users, result.getUsers());
assertEquals(100L, result.getTotalCount()); assertEquals(100L, result.getTotalCount());
assertEquals(0, result.getCurrentPage()); assertEquals(0, result.getCurrentPage());
assertEquals(20, result.getPageSize()); assertEquals(20, result.getPageSize());
assertEquals(5, result.getTotalPages()); assertEquals(5, result.getTotalPages());
assertTrue(result.getHasNextPage()); assertTrue(result.getHasNextPage());
assertFalse(result.getHasPreviousPage()); assertFalse(result.getHasPreviousPage());
assertEquals(0, result.getFirstElement()); assertEquals(0, result.getFirstElement());
assertEquals(19, result.getLastElement()); assertEquals(19, result.getLastElement());
assertFalse(result.getIsEmpty()); assertFalse(result.getIsEmpty());
assertTrue(result.getIsFirstPage()); assertTrue(result.getIsFirstPage());
assertFalse(result.getIsLastPage()); assertFalse(result.getIsLastPage());
assertEquals(criteria, result.getCriteria()); assertEquals(criteria, result.getCriteria());
assertEquals(150L, result.getExecutionTimeMs()); assertEquals(150L, result.getExecutionTimeMs());
} }
@Test @Test
void testSettersAndGetters() { void testSettersAndGetters() {
UserSearchResultDTO result = new UserSearchResultDTO(); UserSearchResultDTO result = new UserSearchResultDTO();
List<UserDTO> users = Collections.singletonList(UserDTO.builder().username("test").build()); List<UserDTO> users = Collections.singletonList(UserDTO.builder().username("test").build());
UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder().build(); UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder().build();
result.setUsers(users); result.setUsers(users);
result.setTotalCount(50L); result.setTotalCount(50L);
result.setCurrentPage(1); result.setCurrentPage(1);
result.setPageSize(10); result.setPageSize(10);
result.setTotalPages(5); result.setTotalPages(5);
result.setHasNextPage(true); result.setHasNextPage(true);
result.setHasPreviousPage(true); result.setHasPreviousPage(true);
result.setFirstElement(10); result.setFirstElement(10);
result.setLastElement(19); result.setLastElement(19);
result.setIsEmpty(false); result.setIsEmpty(false);
result.setIsFirstPage(false); result.setIsFirstPage(false);
result.setIsLastPage(false); result.setIsLastPage(false);
result.setCriteria(criteria); result.setCriteria(criteria);
result.setExecutionTimeMs(200L); result.setExecutionTimeMs(200L);
assertEquals(users, result.getUsers()); assertEquals(users, result.getUsers());
assertEquals(50L, result.getTotalCount()); assertEquals(50L, result.getTotalCount());
assertEquals(1, result.getCurrentPage()); assertEquals(1, result.getCurrentPage());
assertEquals(10, result.getPageSize()); assertEquals(10, result.getPageSize());
assertEquals(5, result.getTotalPages()); assertEquals(5, result.getTotalPages());
assertTrue(result.getHasNextPage()); assertTrue(result.getHasNextPage());
assertTrue(result.getHasPreviousPage()); assertTrue(result.getHasPreviousPage());
assertEquals(10, result.getFirstElement()); assertEquals(10, result.getFirstElement());
assertEquals(19, result.getLastElement()); assertEquals(19, result.getLastElement());
assertFalse(result.getIsEmpty()); assertFalse(result.getIsEmpty());
assertFalse(result.getIsFirstPage()); assertFalse(result.getIsFirstPage());
assertFalse(result.getIsLastPage()); assertFalse(result.getIsLastPage());
assertEquals(criteria, result.getCriteria()); assertEquals(criteria, result.getCriteria());
assertEquals(200L, result.getExecutionTimeMs()); assertEquals(200L, result.getExecutionTimeMs());
} }
@Test @Test
void testEqualsAndHashCode() { void testEqualsAndHashCode() {
UserSearchResultDTO dto1 = UserSearchResultDTO.builder().totalCount(10L).currentPage(0).build(); UserSearchResultDTO dto1 = UserSearchResultDTO.builder().totalCount(10L).currentPage(0).build();
UserSearchResultDTO dto2 = 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(); UserSearchResultDTO dto3 = UserSearchResultDTO.builder().totalCount(20L).currentPage(1).build();
assertEquals(dto1, dto2); assertEquals(dto1, dto2);
assertEquals(dto1.hashCode(), dto2.hashCode()); assertEquals(dto1.hashCode(), dto2.hashCode());
assertNotEquals(dto1, dto3); assertNotEquals(dto1, dto3);
} }
@Test @Test
void testToString() { void testToString() {
UserSearchResultDTO result = UserSearchResultDTO.builder() UserSearchResultDTO result = UserSearchResultDTO.builder()
.totalCount(100L) .totalCount(100L)
.currentPage(0) .currentPage(0)
.build(); .build();
String str = result.toString(); String str = result.toString();
assertNotNull(str); assertNotNull(str);
assertTrue(str.contains("100")); assertTrue(str.contains("100"));
} }
@Test @Test
void testNoArgsConstructor() { void testNoArgsConstructor() {
UserSearchResultDTO result = new UserSearchResultDTO(); UserSearchResultDTO result = new UserSearchResultDTO();
assertNull(result.getUsers()); assertNull(result.getUsers());
assertNull(result.getTotalCount()); assertNull(result.getTotalCount());
assertNull(result.getCurrentPage()); assertNull(result.getCurrentPage());
} }
@Test @Test
void testAllArgsConstructor() { void testAllArgsConstructor() {
List<UserDTO> users = Collections.singletonList(UserDTO.builder().username("test").build()); List<UserDTO> users = Collections.singletonList(UserDTO.builder().username("test").build());
UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder().build(); UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder().build();
UserSearchResultDTO result = new UserSearchResultDTO( UserSearchResultDTO result = new UserSearchResultDTO(
users, 100L, 0, 20, 5, true, false, 0, 19, false, true, false, criteria, 150L); users, 100L, 0, 20, 5, true, false, 0, 19, false, true, false, criteria, 150L);
assertEquals(users, result.getUsers()); assertEquals(users, result.getUsers());
assertEquals(100L, result.getTotalCount()); assertEquals(100L, result.getTotalCount());
assertEquals(0, result.getCurrentPage()); assertEquals(0, result.getCurrentPage());
assertEquals(20, result.getPageSize()); assertEquals(20, result.getPageSize());
assertEquals(5, result.getTotalPages()); assertEquals(5, result.getTotalPages());
assertTrue(result.getHasNextPage()); assertTrue(result.getHasNextPage());
assertFalse(result.getHasPreviousPage()); assertFalse(result.getHasPreviousPage());
assertEquals(0, result.getFirstElement()); assertEquals(0, result.getFirstElement());
assertEquals(19, result.getLastElement()); assertEquals(19, result.getLastElement());
assertFalse(result.getIsEmpty()); assertFalse(result.getIsEmpty());
assertTrue(result.getIsFirstPage()); assertTrue(result.getIsFirstPage());
assertFalse(result.getIsLastPage()); assertFalse(result.getIsLastPage());
assertEquals(criteria, result.getCriteria()); assertEquals(criteria, result.getCriteria());
assertEquals(150L, result.getExecutionTimeMs()); assertEquals(150L, result.getExecutionTimeMs());
} }
} }

View File

@@ -1,59 +1,59 @@
package dev.lions.user.manager.enums.audit; package dev.lions.user.manager.enums.audit;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
/** /**
* Tests unitaires pour TypeActionAudit * Tests unitaires pour TypeActionAudit
*/ */
class TypeActionAuditTest { class TypeActionAuditTest {
@Test @Test
void testValues() { void testValues() {
TypeActionAudit[] values = TypeActionAudit.values(); TypeActionAudit[] values = TypeActionAudit.values();
assertNotNull(values); assertNotNull(values);
assertTrue(values.length > 0); assertTrue(values.length > 0);
} }
@Test @Test
void testValueOf() { void testValueOf() {
TypeActionAudit userCreate = TypeActionAudit.valueOf("USER_CREATE"); TypeActionAudit userCreate = TypeActionAudit.valueOf("USER_CREATE");
TypeActionAudit userUpdate = TypeActionAudit.valueOf("USER_UPDATE"); TypeActionAudit userUpdate = TypeActionAudit.valueOf("USER_UPDATE");
TypeActionAudit userDelete = TypeActionAudit.valueOf("USER_DELETE"); TypeActionAudit userDelete = TypeActionAudit.valueOf("USER_DELETE");
TypeActionAudit roleCreate = TypeActionAudit.valueOf("ROLE_CREATE"); TypeActionAudit roleCreate = TypeActionAudit.valueOf("ROLE_CREATE");
TypeActionAudit roleUpdate = TypeActionAudit.valueOf("ROLE_UPDATE"); TypeActionAudit roleUpdate = TypeActionAudit.valueOf("ROLE_UPDATE");
TypeActionAudit roleDelete = TypeActionAudit.valueOf("ROLE_DELETE"); TypeActionAudit roleDelete = TypeActionAudit.valueOf("ROLE_DELETE");
TypeActionAudit roleAssign = TypeActionAudit.valueOf("ROLE_ASSIGN"); TypeActionAudit roleAssign = TypeActionAudit.valueOf("ROLE_ASSIGN");
TypeActionAudit roleRevoke = TypeActionAudit.valueOf("ROLE_REVOKE"); TypeActionAudit roleRevoke = TypeActionAudit.valueOf("ROLE_REVOKE");
assertEquals(TypeActionAudit.USER_CREATE, userCreate); assertEquals(TypeActionAudit.USER_CREATE, userCreate);
assertEquals(TypeActionAudit.USER_UPDATE, userUpdate); assertEquals(TypeActionAudit.USER_UPDATE, userUpdate);
assertEquals(TypeActionAudit.USER_DELETE, userDelete); assertEquals(TypeActionAudit.USER_DELETE, userDelete);
assertEquals(TypeActionAudit.ROLE_CREATE, roleCreate); assertEquals(TypeActionAudit.ROLE_CREATE, roleCreate);
assertEquals(TypeActionAudit.ROLE_UPDATE, roleUpdate); assertEquals(TypeActionAudit.ROLE_UPDATE, roleUpdate);
assertEquals(TypeActionAudit.ROLE_DELETE, roleDelete); assertEquals(TypeActionAudit.ROLE_DELETE, roleDelete);
assertEquals(TypeActionAudit.ROLE_ASSIGN, roleAssign); assertEquals(TypeActionAudit.ROLE_ASSIGN, roleAssign);
assertEquals(TypeActionAudit.ROLE_REVOKE, roleRevoke); assertEquals(TypeActionAudit.ROLE_REVOKE, roleRevoke);
} }
@Test @Test
void testValueOf_Invalid() { void testValueOf_Invalid() {
assertThrows(IllegalArgumentException.class, () -> { assertThrows(IllegalArgumentException.class, () -> {
TypeActionAudit.valueOf("INVALID"); TypeActionAudit.valueOf("INVALID");
}); });
} }
@Test @Test
void testEnumValues() { void testEnumValues() {
assertNotNull(TypeActionAudit.USER_CREATE); assertNotNull(TypeActionAudit.USER_CREATE);
assertNotNull(TypeActionAudit.USER_UPDATE); assertNotNull(TypeActionAudit.USER_UPDATE);
assertNotNull(TypeActionAudit.USER_DELETE); assertNotNull(TypeActionAudit.USER_DELETE);
assertNotNull(TypeActionAudit.ROLE_CREATE); assertNotNull(TypeActionAudit.ROLE_CREATE);
assertNotNull(TypeActionAudit.ROLE_UPDATE); assertNotNull(TypeActionAudit.ROLE_UPDATE);
assertNotNull(TypeActionAudit.ROLE_DELETE); assertNotNull(TypeActionAudit.ROLE_DELETE);
assertNotNull(TypeActionAudit.ROLE_ASSIGN); assertNotNull(TypeActionAudit.ROLE_ASSIGN);
assertNotNull(TypeActionAudit.ROLE_REVOKE); assertNotNull(TypeActionAudit.ROLE_REVOKE);
} }
} }

View File

@@ -1,41 +1,41 @@
package dev.lions.user.manager.enums.role; package dev.lions.user.manager.enums.role;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
/** /**
* Tests unitaires pour TypeRole * Tests unitaires pour TypeRole
*/ */
class TypeRoleTest { class TypeRoleTest {
@Test @Test
void testValues() { void testValues() {
TypeRole[] values = TypeRole.values(); TypeRole[] values = TypeRole.values();
assertNotNull(values); assertNotNull(values);
assertTrue(values.length > 0); assertTrue(values.length > 0);
} }
@Test @Test
void testValueOf() { void testValueOf() {
TypeRole realmRole = TypeRole.valueOf("REALM_ROLE"); TypeRole realmRole = TypeRole.valueOf("REALM_ROLE");
TypeRole clientRole = TypeRole.valueOf("CLIENT_ROLE"); TypeRole clientRole = TypeRole.valueOf("CLIENT_ROLE");
assertEquals(TypeRole.REALM_ROLE, realmRole); assertEquals(TypeRole.REALM_ROLE, realmRole);
assertEquals(TypeRole.CLIENT_ROLE, clientRole); assertEquals(TypeRole.CLIENT_ROLE, clientRole);
} }
@Test @Test
void testValueOf_Invalid() { void testValueOf_Invalid() {
assertThrows(IllegalArgumentException.class, () -> { assertThrows(IllegalArgumentException.class, () -> {
TypeRole.valueOf("INVALID"); TypeRole.valueOf("INVALID");
}); });
} }
@Test @Test
void testEnumValues() { void testEnumValues() {
assertNotNull(TypeRole.REALM_ROLE); assertNotNull(TypeRole.REALM_ROLE);
assertNotNull(TypeRole.CLIENT_ROLE); assertNotNull(TypeRole.CLIENT_ROLE);
} }
} }

View File

@@ -1,44 +1,44 @@
package dev.lions.user.manager.enums.user; package dev.lions.user.manager.enums.user;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
/** /**
* Tests unitaires pour StatutUser * Tests unitaires pour StatutUser
*/ */
class StatutUserTest { class StatutUserTest {
@Test @Test
void testValues() { void testValues() {
StatutUser[] values = StatutUser.values(); StatutUser[] values = StatutUser.values();
assertNotNull(values); assertNotNull(values);
assertTrue(values.length > 0); assertTrue(values.length > 0);
} }
@Test @Test
void testValueOf() { void testValueOf() {
StatutUser actif = StatutUser.valueOf("ACTIF"); StatutUser actif = StatutUser.valueOf("ACTIF");
StatutUser inactif = StatutUser.valueOf("INACTIF"); StatutUser inactif = StatutUser.valueOf("INACTIF");
StatutUser suspendu = StatutUser.valueOf("SUSPENDU"); StatutUser suspendu = StatutUser.valueOf("SUSPENDU");
assertEquals(StatutUser.ACTIF, actif); assertEquals(StatutUser.ACTIF, actif);
assertEquals(StatutUser.INACTIF, inactif); assertEquals(StatutUser.INACTIF, inactif);
assertEquals(StatutUser.SUSPENDU, suspendu); assertEquals(StatutUser.SUSPENDU, suspendu);
} }
@Test @Test
void testValueOf_Invalid() { void testValueOf_Invalid() {
assertThrows(IllegalArgumentException.class, () -> { assertThrows(IllegalArgumentException.class, () -> {
StatutUser.valueOf("INVALID"); StatutUser.valueOf("INVALID");
}); });
} }
@Test @Test
void testEnumValues() { void testEnumValues() {
assertNotNull(StatutUser.ACTIF); assertNotNull(StatutUser.ACTIF);
assertNotNull(StatutUser.INACTIF); assertNotNull(StatutUser.INACTIF);
assertNotNull(StatutUser.SUSPENDU); assertNotNull(StatutUser.SUSPENDU);
} }
} }

View File

@@ -1,18 +1,18 @@
package dev.lions.user.manager.validation; package dev.lions.user.manager.validation;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
class ValidationConstantsTest { class ValidationConstantsTest {
@Test @Test
void testPrivateConstructor() throws Exception { void testPrivateConstructor() throws Exception {
Constructor<ValidationConstants> constructor = ValidationConstants.class.getDeclaredConstructor(); Constructor<ValidationConstants> constructor = ValidationConstants.class.getDeclaredConstructor();
assertTrue(Modifier.isPrivate(constructor.getModifiers())); assertTrue(Modifier.isPrivate(constructor.getModifiers()));
constructor.setAccessible(true); constructor.setAccessible(true);
ValidationConstants instance = constructor.newInstance(); ValidationConstants instance = constructor.newInstance();
assertNotNull(instance); assertNotNull(instance);
} }
} }