Compare commits
5 Commits
e45a95505a
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dedfe0be4c | ||
|
|
98215b8395 | ||
|
|
c54a34de2d | ||
|
|
a289516a22 | ||
|
|
dcae4756ac |
109
.gitignore
vendored
109
.gitignore
vendored
@@ -1,109 +0,0 @@
|
|||||||
# ============================================================================
|
|
||||||
# Lions User Manager - Server API - .gitignore
|
|
||||||
# ============================================================================
|
|
||||||
|
|
||||||
# Maven
|
|
||||||
target/
|
|
||||||
pom.xml.tag
|
|
||||||
pom.xml.releaseBackup
|
|
||||||
pom.xml.versionsBackup
|
|
||||||
pom.xml.next
|
|
||||||
release.properties
|
|
||||||
dependency-reduced-pom.xml
|
|
||||||
buildNumber.properties
|
|
||||||
.mvn/timing.properties
|
|
||||||
.mvn/wrapper/maven-wrapper.jar
|
|
||||||
|
|
||||||
# Build artifacts
|
|
||||||
*.jar
|
|
||||||
*.war
|
|
||||||
*.ear
|
|
||||||
*.class
|
|
||||||
*.idx
|
|
||||||
|
|
||||||
# Eclipse
|
|
||||||
.project
|
|
||||||
.classpath
|
|
||||||
.settings/
|
|
||||||
.metadata/
|
|
||||||
bin/
|
|
||||||
|
|
||||||
# IntelliJ IDEA
|
|
||||||
.idea/
|
|
||||||
*.iml
|
|
||||||
*.iws
|
|
||||||
*.ipr
|
|
||||||
out/
|
|
||||||
|
|
||||||
# NetBeans
|
|
||||||
nbproject/
|
|
||||||
nbbuild/
|
|
||||||
nbdist/
|
|
||||||
.nb-gradle/
|
|
||||||
|
|
||||||
# VS Code
|
|
||||||
.vscode/
|
|
||||||
*.code-workspace
|
|
||||||
|
|
||||||
# Mac
|
|
||||||
.DS_Store
|
|
||||||
|
|
||||||
# Windows
|
|
||||||
Thumbs.db
|
|
||||||
ehthumbs.db
|
|
||||||
Desktop.ini
|
|
||||||
|
|
||||||
# Logs
|
|
||||||
logs/
|
|
||||||
*.log
|
|
||||||
*.log.*
|
|
||||||
hs_err_pid*.log
|
|
||||||
|
|
||||||
# Temporary files
|
|
||||||
*.tmp
|
|
||||||
*.bak
|
|
||||||
*.swp
|
|
||||||
*~
|
|
||||||
*.orig
|
|
||||||
|
|
||||||
# Test files and reports
|
|
||||||
test_output*.txt
|
|
||||||
surefire-reports/
|
|
||||||
failsafe-reports/
|
|
||||||
*.dump
|
|
||||||
*.dumpstream
|
|
||||||
|
|
||||||
# Test coverage
|
|
||||||
.jacoco/
|
|
||||||
jacoco.exec
|
|
||||||
coverage/
|
|
||||||
target/site/jacoco/
|
|
||||||
|
|
||||||
# Generated sources
|
|
||||||
generated-sources/
|
|
||||||
generated-test-sources/
|
|
||||||
|
|
||||||
# Maven status
|
|
||||||
maven-status/
|
|
||||||
|
|
||||||
# Build metrics
|
|
||||||
build-metrics.json
|
|
||||||
|
|
||||||
# IDE specific
|
|
||||||
*.sublime-project
|
|
||||||
*.sublime-workspace
|
|
||||||
|
|
||||||
# OS specific
|
|
||||||
.DS_Store?
|
|
||||||
._*
|
|
||||||
.Spotlight-V100
|
|
||||||
.Trashes
|
|
||||||
|
|
||||||
# Lombok configuration (généré automatiquement)
|
|
||||||
lombok.config
|
|
||||||
|
|
||||||
# Environment files
|
|
||||||
.env
|
|
||||||
.env.local
|
|
||||||
.env.*.local
|
|
||||||
|
|
||||||
124
README.md
Normal file
124
README.md
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
# lions-user-manager-server-api
|
||||||
|
|
||||||
|
> Contrats partagés entre le serveur et le client — DTOs, interfaces de services, enums, validations
|
||||||
|
|
||||||
|
## Rôle
|
||||||
|
|
||||||
|
Ce module constitue la couche de contrats (API layer) du projet Lions User Manager. Il est compilé en JAR et publié sur le **Gitea Package Registry** pour être consommé par `server-impl` et `client` comme dépendance Maven.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Contenu
|
||||||
|
|
||||||
|
### DTOs
|
||||||
|
|
||||||
|
| DTO | Description |
|
||||||
|
|-----|-------------|
|
||||||
|
| `UserDTO` | Représentation complète d'un utilisateur Keycloak |
|
||||||
|
| `UserCreationDTO` | Données de création d'un utilisateur |
|
||||||
|
| `UserUpdateDTO` | Données de mise à jour |
|
||||||
|
| `RoleDTO` | Rôle Keycloak |
|
||||||
|
| `RealmDTO` | Realm Keycloak |
|
||||||
|
| `RealmAssignmentDTO` | Assignation d'un utilisateur à un realm |
|
||||||
|
| `AuditLogDTO` | Entrée de journal d'audit |
|
||||||
|
| `SyncHistoryDTO` | Historique de synchronisation |
|
||||||
|
| `SyncConsistencyDTO` | Rapport de cohérence sync |
|
||||||
|
| `ImportResultDTO` | Résultat d'import CSV |
|
||||||
|
|
||||||
|
### Interfaces de services
|
||||||
|
|
||||||
|
| Interface | Responsabilité |
|
||||||
|
|-----------|----------------|
|
||||||
|
| `UserService` | CRUD utilisateurs, export/import CSV |
|
||||||
|
| `RoleService` | Gestion des rôles par realm |
|
||||||
|
| `AuditService` | Consultation et export des logs d'audit |
|
||||||
|
| `SyncService` | Synchronisation Keycloak ↔ base de données |
|
||||||
|
| `RealmAuthorizationService` | Gestion des realms autorisés |
|
||||||
|
|
||||||
|
### Interfaces de ressources (JAX-RS)
|
||||||
|
|
||||||
|
| Interface | Path |
|
||||||
|
|-----------|------|
|
||||||
|
| `UserResourceApi` | `/api/users` |
|
||||||
|
| `RoleResourceApi` | `/api/roles` |
|
||||||
|
| `AuditResourceApi` | `/api/audit` |
|
||||||
|
| `SyncResourceApi` | `/api/sync` |
|
||||||
|
| `RealmResourceApi` | `/api/realms` |
|
||||||
|
| `RealmAssignmentResourceApi` | `/api/realm-assignments` |
|
||||||
|
|
||||||
|
### Enums
|
||||||
|
|
||||||
|
- `StatutUser` — ACTIF, INACTIF, SUSPENDU
|
||||||
|
- `TypeRole` — ADMIN, USER, VIEWER
|
||||||
|
- `TypeActionAudit` — CREATE, UPDATE, DELETE, LOGIN, LOGOUT, SYNC
|
||||||
|
|
||||||
|
### Validations
|
||||||
|
|
||||||
|
- `ValidationConstants` — Constantes partagées (longueurs, patterns regex)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Dépôt Git
|
||||||
|
|
||||||
|
`https://git.lions.dev/lionsdev/lions-user-manager-server-api`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Maven Registry
|
||||||
|
|
||||||
|
Le jar est disponible sur le **Gitea Package Registry** :
|
||||||
|
|
||||||
|
```
|
||||||
|
groupId : dev.lions.user.manager
|
||||||
|
artifactId : lions-user-manager-server-api
|
||||||
|
version : 1.0.0
|
||||||
|
registry : https://git.lions.dev/api/packages/lionsdev/maven
|
||||||
|
```
|
||||||
|
|
||||||
|
### Consommer ce module (server-impl / client)
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<dependency>
|
||||||
|
<groupId>dev.lions.user.manager</groupId>
|
||||||
|
<artifactId>lions-user-manager-server-api</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>gitea-lionsdev</id>
|
||||||
|
<url>https://git.lions.dev/api/packages/lionsdev/maven</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Publier une nouvelle version
|
||||||
|
|
||||||
|
1. Incrémenter la version dans `../pom.xml` (parent)
|
||||||
|
2. Exécuter depuis la racine du monorepo :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Windows
|
||||||
|
script\publish-api.bat
|
||||||
|
|
||||||
|
# Linux / macOS
|
||||||
|
./script/publish-api.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Build local
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mvn clean install -DskipTests
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Licence
|
||||||
|
|
||||||
|
Propriétaire — Lions Dev © 2025
|
||||||
6
lombok.config
Normal file
6
lombok.config
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# This file configures Lombok for the project
|
||||||
|
# See https://projectlombok.org/features/configuration
|
||||||
|
|
||||||
|
# Add @Generated annotation to all generated code
|
||||||
|
# This allows JaCoCo to automatically exclude Lombok-generated code from coverage
|
||||||
|
lombok.addLombokGeneratedAnnotation = true
|
||||||
264
parent-pom.xml
Normal file
264
parent-pom.xml
Normal file
@@ -0,0 +1,264 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
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">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>dev.lions.user.manager</groupId>
|
||||||
|
<artifactId>lions-user-manager-parent</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
|
<name>Lions User Manager - Parent</name>
|
||||||
|
<description>Module de gestion centralisée des utilisateurs via Keycloak Admin API</description>
|
||||||
|
|
||||||
|
<distributionManagement>
|
||||||
|
<repository>
|
||||||
|
<id>gitea-lionsdev</id>
|
||||||
|
<url>https://git.lions.dev/api/packages/lionsdev/maven</url>
|
||||||
|
</repository>
|
||||||
|
<snapshotRepository>
|
||||||
|
<id>gitea-lionsdev</id>
|
||||||
|
<url>https://git.lions.dev/api/packages/lionsdev/maven</url>
|
||||||
|
</snapshotRepository>
|
||||||
|
</distributionManagement>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>gitea-lionsdev</id>
|
||||||
|
<url>https://git.lions.dev/api/packages/lionsdev/maven</url>
|
||||||
|
<releases><enabled>true</enabled></releases>
|
||||||
|
<snapshots><enabled>true</enabled></snapshots>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>17</maven.compiler.source>
|
||||||
|
<maven.compiler.target>17</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
|
|
||||||
|
<!-- Quarkus & Dependencies -->
|
||||||
|
<quarkus.version>3.17.8</quarkus.version>
|
||||||
|
<quarkus-primefaces.version>3.15.1</quarkus-primefaces.version>
|
||||||
|
<primefaces.version>14.0.5</primefaces.version>
|
||||||
|
<primefaces-freya-extension.version>1.0.0</primefaces-freya-extension.version>
|
||||||
|
<keycloak.version>26.0.7</keycloak.version>
|
||||||
|
<lombok.version>1.18.30</lombok.version>
|
||||||
|
<mapstruct.version>1.5.5.Final</mapstruct.version>
|
||||||
|
|
||||||
|
<!-- Testing -->
|
||||||
|
<junit.version>5.10.1</junit.version>
|
||||||
|
<mockito.version>5.11.0</mockito.version>
|
||||||
|
<testcontainers.version>1.19.3</testcontainers.version>
|
||||||
|
<rest-assured.version>5.4.0</rest-assured.version>
|
||||||
|
|
||||||
|
<!-- Plugins -->
|
||||||
|
<maven-compiler-plugin.version>3.11.0</maven-compiler-plugin.version>
|
||||||
|
<maven-surefire-plugin.version>3.2.2</maven-surefire-plugin.version>
|
||||||
|
<maven-failsafe-plugin.version>3.2.2</maven-failsafe-plugin.version>
|
||||||
|
<jacoco-maven-plugin.version>0.8.11</jacoco-maven-plugin.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<modules>
|
||||||
|
<module>lions-user-manager-server-api</module>
|
||||||
|
<module>lions-user-manager-server-impl-quarkus</module>
|
||||||
|
<module>lions-user-manager-client-quarkus-primefaces-freya</module>
|
||||||
|
</modules>
|
||||||
|
|
||||||
|
<dependencyManagement>
|
||||||
|
<dependencies>
|
||||||
|
<!-- Quarkus BOM -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.quarkus.platform</groupId>
|
||||||
|
<artifactId>quarkus-bom</artifactId>
|
||||||
|
<version>${quarkus.version}</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Internal modules -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>dev.lions.user.manager</groupId>
|
||||||
|
<artifactId>lions-user-manager-server-api</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- PrimeFaces Freya Extension -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>dev.lions</groupId>
|
||||||
|
<artifactId>primefaces-freya-extension</artifactId>
|
||||||
|
<version>${primefaces-freya-extension.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Lombok -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>${lombok.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- MapStruct -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mapstruct</groupId>
|
||||||
|
<artifactId>mapstruct</artifactId>
|
||||||
|
<version>${mapstruct.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Testing -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter</artifactId>
|
||||||
|
<version>${junit.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.testcontainers</groupId>
|
||||||
|
<artifactId>testcontainers-bom</artifactId>
|
||||||
|
<version>${testcontainers.version}</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.rest-assured</groupId>
|
||||||
|
<artifactId>rest-assured</artifactId>
|
||||||
|
<version>${rest-assured.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mockito</groupId>
|
||||||
|
<artifactId>mockito-core</artifactId>
|
||||||
|
<version>${mockito.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mockito</groupId>
|
||||||
|
<artifactId>mockito-junit-jupiter</artifactId>
|
||||||
|
<version>${mockito.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
</dependencyManagement>
|
||||||
|
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>dev</id>
|
||||||
|
<activation>
|
||||||
|
<activeByDefault>true</activeByDefault>
|
||||||
|
</activation>
|
||||||
|
<properties>
|
||||||
|
<quarkus.profile>dev</quarkus.profile>
|
||||||
|
</properties>
|
||||||
|
</profile>
|
||||||
|
<profile>
|
||||||
|
<id>prod</id>
|
||||||
|
<properties>
|
||||||
|
<quarkus.profile>prod</quarkus.profile>
|
||||||
|
</properties>
|
||||||
|
</profile>
|
||||||
|
<profile>
|
||||||
|
<id>native</id>
|
||||||
|
<properties>
|
||||||
|
<quarkus.profile>prod</quarkus.profile>
|
||||||
|
<quarkus.package.jar.type>native</quarkus.package.jar.type>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.quarkus</groupId>
|
||||||
|
<artifactId>quarkus-junit5</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<pluginManagement>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>${maven-compiler-plugin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<annotationProcessorPaths>
|
||||||
|
<path>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>${lombok.version}</version>
|
||||||
|
</path>
|
||||||
|
<path>
|
||||||
|
<groupId>org.mapstruct</groupId>
|
||||||
|
<artifactId>mapstruct-processor</artifactId>
|
||||||
|
<version>${mapstruct.version}</version>
|
||||||
|
</path>
|
||||||
|
</annotationProcessorPaths>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>io.quarkus.platform</groupId>
|
||||||
|
<artifactId>quarkus-maven-plugin</artifactId>
|
||||||
|
<version>${quarkus.version}</version>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>${maven-surefire-plugin.version}</version>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-failsafe-plugin</artifactId>
|
||||||
|
<version>${maven-failsafe-plugin.version}</version>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.jacoco</groupId>
|
||||||
|
<artifactId>jacoco-maven-plugin</artifactId>
|
||||||
|
<version>${jacoco-maven-plugin.version}</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>prepare-agent</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>report</id>
|
||||||
|
<phase>test</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>report</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>jacoco-check</id>
|
||||||
|
<goals>
|
||||||
|
<goal>check</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<rules>
|
||||||
|
<rule>
|
||||||
|
<element>PACKAGE</element>
|
||||||
|
<limits>
|
||||||
|
<limit>
|
||||||
|
<counter>LINE</counter>
|
||||||
|
<value>COVEREDRATIO</value>
|
||||||
|
<minimum>0.80</minimum>
|
||||||
|
</limit>
|
||||||
|
</limits>
|
||||||
|
</rule>
|
||||||
|
</rules>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</pluginManagement>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
30
script/publish-api.bat
Normal file
30
script/publish-api.bat
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
@echo off
|
||||||
|
REM Publie le parent pom + server-api sur le Gitea Package Registry
|
||||||
|
REM Usage : script\publish-api.bat
|
||||||
|
REM Depuis : n'importe où dans le repo server-api
|
||||||
|
REM Prérequis: credentials dans %USERPROFILE%\.m2\settings.xml (server id: gitea-lionsdev)
|
||||||
|
|
||||||
|
set REGISTRY_URL=https://git.lions.dev/api/packages/lionsdev/maven
|
||||||
|
set REGISTRY_ID=gitea-lionsdev
|
||||||
|
|
||||||
|
cd /d "%~dp0.."
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo [1/2] Publication du parent pom...
|
||||||
|
call mvn deploy:deploy-file ^
|
||||||
|
-DgroupId=dev.lions.user.manager ^
|
||||||
|
-DartifactId=lions-user-manager-parent ^
|
||||||
|
-Dversion=1.0.0 ^
|
||||||
|
-Dpackaging=pom ^
|
||||||
|
-Dfile=parent-pom.xml ^
|
||||||
|
-DrepositoryId=%REGISTRY_ID% ^
|
||||||
|
-Durl=%REGISTRY_URL%
|
||||||
|
if %errorlevel% neq 0 echo [WARN] Parent pom deja publie pour cette version (409), on continue.
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo [2/2] Publication du server-api...
|
||||||
|
call mvn deploy -DskipTests
|
||||||
|
if %errorlevel% neq 0 echo [WARN] Server-api deja publie pour cette version (409) - incrementer la version pour republier.
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo Done -- https://git.lions.dev/lionsdev/-/packages
|
||||||
32
script/publish-api.sh
Normal file
32
script/publish-api.sh
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Publie le parent pom + server-api sur le Gitea Package Registry
|
||||||
|
# Usage : ./script/publish-api.sh
|
||||||
|
# Depuis : n'importe où dans le repo server-api
|
||||||
|
# Prérequis: credentials dans ~/.m2/settings.xml (server id: gitea-lionsdev)
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
REGISTRY_URL="https://git.lions.dev/api/packages/lionsdev/maven"
|
||||||
|
REGISTRY_ID="gitea-lionsdev"
|
||||||
|
|
||||||
|
cd "$(dirname "$0")/.."
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "[1/2] Publication du parent pom..."
|
||||||
|
mvn deploy:deploy-file \
|
||||||
|
-DgroupId=dev.lions.user.manager \
|
||||||
|
-DartifactId=lions-user-manager-parent \
|
||||||
|
-Dversion=1.0.0 \
|
||||||
|
-Dpackaging=pom \
|
||||||
|
-Dfile=parent-pom.xml \
|
||||||
|
-DrepositoryId="${REGISTRY_ID}" \
|
||||||
|
-Durl="${REGISTRY_URL}" \
|
||||||
|
|| echo "[WARN] Parent pom deja publie pour cette version (409), on continue."
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "[2/2] Publication du server-api..."
|
||||||
|
mvn deploy -DskipTests \
|
||||||
|
|| echo "[WARN] Server-api deja publie pour cette version (409) - incrementer la version pour republier."
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Done -- https://git.lions.dev/lionsdev/-/packages"
|
||||||
111
src/main/java/dev/lions/user/manager/api/AuditResourceApi.java
Normal file
111
src/main/java/dev/lions/user/manager/api/AuditResourceApi.java
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
package dev.lions.user.manager.api;
|
||||||
|
|
||||||
|
import dev.lions.user.manager.dto.audit.AuditLogDTO;
|
||||||
|
import dev.lions.user.manager.dto.common.CountDTO;
|
||||||
|
import dev.lions.user.manager.enums.audit.TypeActionAudit;
|
||||||
|
import jakarta.ws.rs.*;
|
||||||
|
import jakarta.ws.rs.core.MediaType;
|
||||||
|
import jakarta.ws.rs.core.Response;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.Operation;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.media.Content;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.media.Schema;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.parameters.Parameter;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.responses.APIResponses;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.tags.Tag;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface JAX-RS pour l'API d'audit.
|
||||||
|
*/
|
||||||
|
@Path("/api/audit")
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Tag(name = "Audit", description = "Consultation des logs d'audit et statistiques")
|
||||||
|
public interface AuditResourceApi {
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/search")
|
||||||
|
@Operation(summary = "Rechercher des logs d'audit", description = "Recherche avancée de logs selon critères")
|
||||||
|
@APIResponses({
|
||||||
|
@APIResponse(responseCode = "200", description = "Résultats de recherche", content = @Content(schema = @Schema(implementation = AuditLogDTO.class, type = org.eclipse.microprofile.openapi.annotations.enums.SchemaType.ARRAY))),
|
||||||
|
@APIResponse(responseCode = "500", description = "Erreur serveur")
|
||||||
|
})
|
||||||
|
List<AuditLogDTO> searchLogs(
|
||||||
|
@QueryParam("acteur") String acteurUsername,
|
||||||
|
@QueryParam("dateDebut") String dateDebut,
|
||||||
|
@QueryParam("dateFin") String dateFin,
|
||||||
|
@QueryParam("typeAction") TypeActionAudit typeAction,
|
||||||
|
@QueryParam("ressourceType") String ressourceType,
|
||||||
|
@QueryParam("succes") Boolean succes,
|
||||||
|
@QueryParam("page") @DefaultValue("0") int page,
|
||||||
|
@QueryParam("pageSize") @DefaultValue("50") int pageSize);
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/actor/{acteurUsername}")
|
||||||
|
@Operation(summary = "Récupérer les logs d'un acteur", description = "Liste les derniers logs d'un utilisateur")
|
||||||
|
List<AuditLogDTO> getLogsByActor(
|
||||||
|
@Parameter(description = "Username de l'acteur") @PathParam("acteurUsername") String acteurUsername,
|
||||||
|
@Parameter(description = "Nombre de logs à retourner") @QueryParam("limit") @DefaultValue("100") int limit);
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/resource/{ressourceType}/{ressourceId}")
|
||||||
|
@Operation(summary = "Récupérer les logs d'une ressource", description = "Liste les derniers logs d'une ressource spécifique")
|
||||||
|
List<AuditLogDTO> getLogsByResource(
|
||||||
|
@PathParam("ressourceType") String ressourceType,
|
||||||
|
@PathParam("ressourceId") String ressourceId,
|
||||||
|
@QueryParam("limit") @DefaultValue("100") int limit);
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/action/{typeAction}")
|
||||||
|
@Operation(summary = "Récupérer les logs par type d'action", description = "Liste les logs d'un type d'action spécifique")
|
||||||
|
List<AuditLogDTO> getLogsByAction(
|
||||||
|
@PathParam("typeAction") TypeActionAudit typeAction,
|
||||||
|
@QueryParam("dateDebut") String dateDebut,
|
||||||
|
@QueryParam("dateFin") String dateFin,
|
||||||
|
@QueryParam("limit") @DefaultValue("100") int limit);
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/stats/actions")
|
||||||
|
@Operation(summary = "Statistiques par type d'action", description = "Retourne le nombre de logs par type d'action")
|
||||||
|
Map<TypeActionAudit, Long> getActionStatistics(
|
||||||
|
@QueryParam("dateDebut") String dateDebut,
|
||||||
|
@QueryParam("dateFin") String dateFin);
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/stats/users")
|
||||||
|
@Operation(summary = "Statistiques par utilisateur", description = "Retourne le nombre d'actions par utilisateur")
|
||||||
|
Map<String, Long> getUserActivityStatistics(
|
||||||
|
@QueryParam("dateDebut") String dateDebut,
|
||||||
|
@QueryParam("dateFin") String dateFin);
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/stats/failures")
|
||||||
|
@Operation(summary = "Comptage des échecs", description = "Retourne le nombre d'échecs sur une période")
|
||||||
|
CountDTO getFailureCount(
|
||||||
|
@QueryParam("dateDebut") String dateDebut,
|
||||||
|
@QueryParam("dateFin") String dateFin);
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/stats/success")
|
||||||
|
@Operation(summary = "Comptage des succès", description = "Retourne le nombre de succès sur une période")
|
||||||
|
CountDTO getSuccessCount(
|
||||||
|
@QueryParam("dateDebut") String dateDebut,
|
||||||
|
@QueryParam("dateFin") String dateFin);
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/export/csv")
|
||||||
|
@Produces(MediaType.TEXT_PLAIN)
|
||||||
|
@Operation(summary = "Exporter les logs en CSV", description = "Génère un fichier CSV des logs d'audit")
|
||||||
|
Response exportLogsToCSV(
|
||||||
|
@QueryParam("dateDebut") String dateDebut,
|
||||||
|
@QueryParam("dateFin") String dateFin);
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
@Path("/purge")
|
||||||
|
@Operation(summary = "Purger les anciens logs", description = "Supprime les logs de plus de X jours")
|
||||||
|
void purgeOldLogs(
|
||||||
|
@QueryParam("joursAnciennete") @DefaultValue("90") int joursAnciennete);
|
||||||
|
}
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
package dev.lions.user.manager.api;
|
||||||
|
|
||||||
|
import dev.lions.user.manager.dto.realm.AuthorizedRealmsDTO;
|
||||||
|
import dev.lions.user.manager.dto.realm.RealmAccessCheckDTO;
|
||||||
|
import dev.lions.user.manager.dto.realm.RealmAssignmentDTO;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import jakarta.ws.rs.*;
|
||||||
|
import jakarta.ws.rs.core.MediaType;
|
||||||
|
import jakarta.ws.rs.core.Response;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.Operation;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.media.Content;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.media.Schema;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.parameters.Parameter;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.responses.APIResponses;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.tags.Tag;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface JAX-RS pour l'API de gestion des affectations de realms.
|
||||||
|
*/
|
||||||
|
@Path("/api/realm-assignments")
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Tag(name = "Realm Assignments", description = "Gestion des affectations de realms (contrôle d'accès multi-tenant)")
|
||||||
|
public interface RealmAssignmentResourceApi {
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Operation(summary = "Lister toutes les affectations", description = "Liste toutes les affectations de realms")
|
||||||
|
List<RealmAssignmentDTO> getAllAssignments();
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/user/{userId}")
|
||||||
|
@Operation(summary = "Affectations par utilisateur", description = "Liste les realms assignés à un utilisateur")
|
||||||
|
List<RealmAssignmentDTO> getAssignmentsByUser(
|
||||||
|
@Parameter(description = "ID de l'utilisateur") @PathParam("userId") String userId);
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/realm/{realmName}")
|
||||||
|
@Operation(summary = "Affectations par realm", description = "Liste les utilisateurs ayant accès à un realm")
|
||||||
|
List<RealmAssignmentDTO> getAssignmentsByRealm(
|
||||||
|
@Parameter(description = "Nom du realm") @PathParam("realmName") String realmName);
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/{assignmentId}")
|
||||||
|
@Operation(summary = "Récupérer une affectation", description = "Récupère une affectation par son ID")
|
||||||
|
RealmAssignmentDTO getAssignmentById(
|
||||||
|
@Parameter(description = "ID de l'affectation") @PathParam("assignmentId") String assignmentId);
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/check")
|
||||||
|
@Operation(summary = "Vérifier l'accès", description = "Vérifie si un utilisateur peut gérer un realm")
|
||||||
|
RealmAccessCheckDTO canManageRealm(
|
||||||
|
@Parameter(description = "ID de l'utilisateur") @QueryParam("userId") String userId,
|
||||||
|
@Parameter(description = "Nom du realm") @QueryParam("realmName") String realmName);
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/authorized-realms/{userId}")
|
||||||
|
@Operation(summary = "Realms autorisés", description = "Liste les realms qu'un utilisateur peut gérer")
|
||||||
|
AuthorizedRealmsDTO getAuthorizedRealms(
|
||||||
|
@Parameter(description = "ID de l'utilisateur") @PathParam("userId") String userId);
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Operation(summary = "Assigner un realm", description = "Assigne un realm à un utilisateur")
|
||||||
|
@APIResponses({
|
||||||
|
@APIResponse(responseCode = "201", description = "Affectation créée", content = @Content(schema = @Schema(implementation = RealmAssignmentDTO.class)))
|
||||||
|
})
|
||||||
|
Response assignRealmToUser(@Valid @NotNull RealmAssignmentDTO assignment);
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
@Path("/user/{userId}/realm/{realmName}")
|
||||||
|
@Operation(summary = "Révoquer un realm", description = "Retire l'accès d'un utilisateur à un realm")
|
||||||
|
void revokeRealmFromUser(
|
||||||
|
@Parameter(description = "ID de l'utilisateur") @PathParam("userId") String userId,
|
||||||
|
@Parameter(description = "Nom du realm") @PathParam("realmName") String realmName);
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
@Path("/user/{userId}")
|
||||||
|
@Operation(summary = "Révoquer tous les realms", description = "Retire tous les accès d'un utilisateur")
|
||||||
|
void revokeAllRealmsFromUser(
|
||||||
|
@Parameter(description = "ID de l'utilisateur") @PathParam("userId") String userId);
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Path("/{assignmentId}/deactivate")
|
||||||
|
@Operation(summary = "Désactiver une affectation", description = "Désactive une affectation sans la supprimer")
|
||||||
|
void deactivateAssignment(
|
||||||
|
@Parameter(description = "ID de l'affectation") @PathParam("assignmentId") String assignmentId);
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Path("/{assignmentId}/activate")
|
||||||
|
@Operation(summary = "Activer une affectation", description = "Réactive une affectation")
|
||||||
|
void activateAssignment(
|
||||||
|
@Parameter(description = "ID de l'affectation") @PathParam("assignmentId") String assignmentId);
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Path("/super-admin/{userId}")
|
||||||
|
@Operation(summary = "Définir super admin", description = "Définit ou retire le statut de super admin")
|
||||||
|
void setSuperAdmin(
|
||||||
|
@Parameter(description = "ID de l'utilisateur") @PathParam("userId") String userId,
|
||||||
|
@Parameter(description = "Super admin (true/false)") @QueryParam("superAdmin") @NotNull Boolean superAdmin);
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package dev.lions.user.manager.api;
|
||||||
|
|
||||||
|
import jakarta.ws.rs.GET;
|
||||||
|
import jakarta.ws.rs.Path;
|
||||||
|
import jakarta.ws.rs.PathParam;
|
||||||
|
import jakarta.ws.rs.Produces;
|
||||||
|
import jakarta.ws.rs.core.MediaType;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.parameters.Parameter;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.Operation;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.media.Content;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.media.Schema;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.responses.APIResponses;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.tags.Tag;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface JAX-RS pour la gestion des realms Keycloak.
|
||||||
|
*/
|
||||||
|
@Path("/api/realms")
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@Tag(name = "Realms", description = "Gestion des realms Keycloak")
|
||||||
|
public interface RealmResourceApi {
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/list")
|
||||||
|
@Operation(summary = "Lister tous les realms", description = "Récupère la liste de tous les realms disponibles dans Keycloak")
|
||||||
|
@APIResponses({
|
||||||
|
@APIResponse(responseCode = "200", description = "Liste des realms", content = @Content(schema = @Schema(type = org.eclipse.microprofile.openapi.annotations.enums.SchemaType.ARRAY, implementation = String.class))),
|
||||||
|
@APIResponse(responseCode = "500", description = "Erreur serveur")
|
||||||
|
})
|
||||||
|
List<String> getAllRealms();
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/{realm}/clients")
|
||||||
|
@Operation(summary = "Lister les clients d'un realm", description = "Récupère la liste des clientId de tous les clients d'un realm")
|
||||||
|
@APIResponses({
|
||||||
|
@APIResponse(responseCode = "200", description = "Liste des clients"),
|
||||||
|
@APIResponse(responseCode = "500", description = "Erreur serveur")
|
||||||
|
})
|
||||||
|
List<String> getRealmClients(
|
||||||
|
@Parameter(description = "Nom du realm") @PathParam("realm") String realmName);
|
||||||
|
}
|
||||||
163
src/main/java/dev/lions/user/manager/api/RoleResourceApi.java
Normal file
163
src/main/java/dev/lions/user/manager/api/RoleResourceApi.java
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
package dev.lions.user.manager.api;
|
||||||
|
|
||||||
|
import dev.lions.user.manager.dto.role.RoleAssignmentRequestDTO;
|
||||||
|
import dev.lions.user.manager.dto.role.RoleDTO;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import jakarta.ws.rs.*;
|
||||||
|
import jakarta.ws.rs.core.MediaType;
|
||||||
|
import jakarta.ws.rs.core.Response;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.Operation;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.media.Content;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.media.Schema;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.parameters.Parameter;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.responses.APIResponses;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.tags.Tag;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface JAX-RS pour la gestion des rôles Keycloak.
|
||||||
|
*/
|
||||||
|
@Path("/api/roles")
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Tag(name = "Roles", description = "Gestion des rôles Keycloak (realm et client)")
|
||||||
|
public interface RoleResourceApi {
|
||||||
|
|
||||||
|
// ==================== Endpoints Realm Roles ====================
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/realm")
|
||||||
|
@Operation(summary = "Créer un rôle realm", description = "Crée un nouveau rôle au niveau du realm")
|
||||||
|
@APIResponses({
|
||||||
|
@APIResponse(responseCode = "201", description = "Rôle créé", content = @Content(schema = @Schema(implementation = RoleDTO.class)))
|
||||||
|
})
|
||||||
|
Response createRealmRole(
|
||||||
|
@Valid @NotNull RoleDTO roleDTO,
|
||||||
|
@Parameter(description = "Nom du realm") @QueryParam("realm") String realmName);
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/realm/{roleName}")
|
||||||
|
@Operation(summary = "Récupérer un rôle realm par nom", description = "Récupère les détails d'un rôle realm")
|
||||||
|
RoleDTO getRealmRole(
|
||||||
|
@Parameter(description = "Nom du rôle") @PathParam("roleName") String roleName,
|
||||||
|
@Parameter(description = "Nom du realm") @QueryParam("realm") String realmName);
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/realm")
|
||||||
|
@Operation(summary = "Lister tous les rôles realm", description = "Liste tous les rôles du realm")
|
||||||
|
List<RoleDTO> getAllRealmRoles(
|
||||||
|
@Parameter(description = "Nom du realm") @QueryParam("realm") String realmName);
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Path("/realm/{roleName}")
|
||||||
|
@Operation(summary = "Mettre à jour un rôle realm", description = "Met à jour les informations d'un rôle realm")
|
||||||
|
RoleDTO updateRealmRole(
|
||||||
|
@PathParam("roleName") String roleName,
|
||||||
|
@Valid @NotNull RoleDTO roleDTO,
|
||||||
|
@QueryParam("realm") String realmName);
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
@Path("/realm/{roleName}")
|
||||||
|
@Operation(summary = "Supprimer un rôle realm", description = "Supprime un rôle realm")
|
||||||
|
void deleteRealmRole(
|
||||||
|
@PathParam("roleName") String roleName,
|
||||||
|
@QueryParam("realm") String realmName);
|
||||||
|
|
||||||
|
// ==================== Endpoints Client Roles ====================
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/client/{clientId}")
|
||||||
|
@Operation(summary = "Créer un rôle client", description = "Crée un nouveau rôle pour un client spécifique")
|
||||||
|
@APIResponses({
|
||||||
|
@APIResponse(responseCode = "201", description = "Rôle créé", content = @Content(schema = @Schema(implementation = RoleDTO.class)))
|
||||||
|
})
|
||||||
|
Response createClientRole(
|
||||||
|
@PathParam("clientId") String clientId,
|
||||||
|
@Valid @NotNull RoleDTO roleDTO,
|
||||||
|
@QueryParam("realm") String realmName);
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/client/{clientId}/{roleName}")
|
||||||
|
@Operation(summary = "Récupérer un rôle client par nom", description = "Récupère les détails d'un rôle client")
|
||||||
|
RoleDTO getClientRole(
|
||||||
|
@PathParam("clientId") String clientId,
|
||||||
|
@PathParam("roleName") String roleName,
|
||||||
|
@QueryParam("realm") String realmName);
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/client/{clientId}")
|
||||||
|
@Operation(summary = "Lister tous les rôles d'un client", description = "Liste tous les rôles d'un client spécifique")
|
||||||
|
List<RoleDTO> getAllClientRoles(
|
||||||
|
@PathParam("clientId") String clientId,
|
||||||
|
@QueryParam("realm") String realmName);
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
@Path("/client/{clientId}/{roleName}")
|
||||||
|
@Operation(summary = "Supprimer un rôle client", description = "Supprime un rôle d'un client")
|
||||||
|
void deleteClientRole(
|
||||||
|
@PathParam("clientId") String clientId,
|
||||||
|
@PathParam("roleName") String roleName,
|
||||||
|
@QueryParam("realm") String realmName);
|
||||||
|
|
||||||
|
// ==================== Endpoints Attribution de rôles ====================
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/assign/realm/{userId}")
|
||||||
|
@Operation(summary = "Attribuer des rôles realm à un utilisateur", description = "Assigne un ou plusieurs rôles realm à un utilisateur")
|
||||||
|
void assignRealmRoles(
|
||||||
|
@PathParam("userId") String userId,
|
||||||
|
@QueryParam("realm") String realmName,
|
||||||
|
@NotNull RoleAssignmentRequestDTO request);
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/revoke/realm/{userId}")
|
||||||
|
@Operation(summary = "Révoquer des rôles realm d'un utilisateur", description = "Révoque un ou plusieurs rôles realm d'un utilisateur")
|
||||||
|
void revokeRealmRoles(
|
||||||
|
@PathParam("userId") String userId,
|
||||||
|
@QueryParam("realm") String realmName,
|
||||||
|
@NotNull RoleAssignmentRequestDTO request);
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/assign/client/{clientId}/{userId}")
|
||||||
|
@Operation(summary = "Attribuer des rôles client à un utilisateur", description = "Assigne un ou plusieurs rôles client à un utilisateur")
|
||||||
|
void assignClientRoles(
|
||||||
|
@PathParam("clientId") String clientId,
|
||||||
|
@PathParam("userId") String userId,
|
||||||
|
@QueryParam("realm") String realmName,
|
||||||
|
@NotNull RoleAssignmentRequestDTO request);
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/user/realm/{userId}")
|
||||||
|
@Operation(summary = "Récupérer les rôles realm d'un utilisateur", description = "Liste tous les rôles realm d'un utilisateur")
|
||||||
|
List<RoleDTO> getUserRealmRoles(
|
||||||
|
@PathParam("userId") String userId,
|
||||||
|
@QueryParam("realm") String realmName);
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/user/client/{clientId}/{userId}")
|
||||||
|
@Operation(summary = "Récupérer les rôles client d'un utilisateur", description = "Liste tous les rôles client d'un utilisateur")
|
||||||
|
List<RoleDTO> getUserClientRoles(
|
||||||
|
@PathParam("clientId") String clientId,
|
||||||
|
@PathParam("userId") String userId,
|
||||||
|
@QueryParam("realm") String realmName);
|
||||||
|
|
||||||
|
// ==================== Endpoints Rôles composites ====================
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/composite/{roleName}/add")
|
||||||
|
@Operation(summary = "Ajouter des rôles composites", description = "Ajoute des rôles composites à un rôle")
|
||||||
|
void addComposites(
|
||||||
|
@PathParam("roleName") String roleName,
|
||||||
|
@QueryParam("realm") String realmName,
|
||||||
|
@NotNull RoleAssignmentRequestDTO request);
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/composite/{roleName}")
|
||||||
|
@Operation(summary = "Récupérer les rôles composites", description = "Liste tous les rôles composites d'un rôle")
|
||||||
|
List<RoleDTO> getComposites(
|
||||||
|
@PathParam("roleName") String roleName,
|
||||||
|
@QueryParam("realm") String realmName);
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package dev.lions.user.manager.api;
|
||||||
|
|
||||||
|
import dev.lions.user.manager.dto.sync.HealthStatusDTO;
|
||||||
|
import dev.lions.user.manager.dto.sync.SyncConsistencyDTO;
|
||||||
|
import dev.lions.user.manager.dto.sync.SyncHistoryDTO;
|
||||||
|
import dev.lions.user.manager.dto.sync.SyncResultDTO;
|
||||||
|
import jakarta.ws.rs.*;
|
||||||
|
import jakarta.ws.rs.core.MediaType;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.Operation;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.tags.Tag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface JAX-RS définissant le contrat de l'API de synchronisation.
|
||||||
|
* Cette interface doit être implémentée par le serveur et utilisée par le
|
||||||
|
* client (via MicroProfile Rest Client).
|
||||||
|
*/
|
||||||
|
@Path("/api/sync")
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Tag(name = "Sync", description = "Synchronisation avec Keycloak et health checks")
|
||||||
|
public interface SyncResourceApi {
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/health/keycloak")
|
||||||
|
@Operation(summary = "Vérifier la santé de Keycloak", description = "Retourne le statut de santé de Keycloak")
|
||||||
|
HealthStatusDTO checkKeycloakHealth();
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/users")
|
||||||
|
@Operation(summary = "Synchroniser les utilisateurs", description = "Synchronise tous les utilisateurs depuis Keycloak")
|
||||||
|
SyncResultDTO syncUsers(@QueryParam("realm") String realmName);
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/roles")
|
||||||
|
@Operation(summary = "Synchroniser les rôles", description = "Synchronise les rôles (realm et/ou client)")
|
||||||
|
SyncResultDTO syncRoles(
|
||||||
|
@QueryParam("realm") String realmName,
|
||||||
|
@QueryParam("clientName") String clientName);
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/consistency")
|
||||||
|
@Operation(summary = "Vérifier la cohérence des données", description = "Compare le cache local et Keycloak pour un realm")
|
||||||
|
SyncConsistencyDTO checkDataConsistency(@QueryParam("realm") String realmName);
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/status")
|
||||||
|
@Operation(summary = "Statut de la dernière synchro", description = "Retourne le statut de la dernière synchronisation du realm")
|
||||||
|
SyncHistoryDTO getLastSyncStatus(@QueryParam("realm") String realmName);
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/force")
|
||||||
|
@Operation(summary = "Forcer une synchro", description = "Lance une synchronisation complète du realm (users + roles)")
|
||||||
|
SyncHistoryDTO forceSyncRealm(@QueryParam("realm") String realmName);
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package dev.lions.user.manager.api;
|
||||||
|
|
||||||
|
import dev.lions.user.manager.dto.common.UserSessionStatsDTO;
|
||||||
|
import jakarta.ws.rs.GET;
|
||||||
|
import jakarta.ws.rs.Path;
|
||||||
|
import jakarta.ws.rs.Produces;
|
||||||
|
import jakarta.ws.rs.QueryParam;
|
||||||
|
import jakarta.ws.rs.core.MediaType;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.Operation;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.responses.APIResponses;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.tags.Tag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API de métriques liées aux utilisateurs (sessions, utilisateurs en ligne, etc.).
|
||||||
|
*/
|
||||||
|
@Path("/api/metrics/users")
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@Tag(name = "User Metrics", description = "Statistiques sur les utilisateurs et leurs sessions")
|
||||||
|
public interface UserMetricsResourceApi {
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/sessions")
|
||||||
|
@Operation(summary = "Statistiques de sessions utilisateurs",
|
||||||
|
description = "Retourne des statistiques agrégées sur les utilisateurs et leurs sessions pour un realm")
|
||||||
|
@APIResponses({
|
||||||
|
@APIResponse(responseCode = "200", description = "Statistiques retournées avec succès"),
|
||||||
|
@APIResponse(responseCode = "500", description = "Erreur serveur")
|
||||||
|
})
|
||||||
|
UserSessionStatsDTO getUserSessionStats(@QueryParam("realm") String realmName);
|
||||||
|
}
|
||||||
|
|
||||||
134
src/main/java/dev/lions/user/manager/api/UserResourceApi.java
Normal file
134
src/main/java/dev/lions/user/manager/api/UserResourceApi.java
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
package dev.lions.user.manager.api;
|
||||||
|
|
||||||
|
import dev.lions.user.manager.dto.importexport.ImportResultDTO;
|
||||||
|
import dev.lions.user.manager.dto.user.*;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import jakarta.ws.rs.*;
|
||||||
|
import jakarta.ws.rs.core.MediaType;
|
||||||
|
import jakarta.ws.rs.core.Response;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.Operation;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.media.Content;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.media.Schema;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.parameters.Parameter;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.responses.APIResponses;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.tags.Tag;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface JAX-RS pour la gestion des utilisateurs.
|
||||||
|
*/
|
||||||
|
@Path("/api/users")
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Tag(name = "Users", description = "Gestion des utilisateurs Keycloak")
|
||||||
|
public interface UserResourceApi {
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/search")
|
||||||
|
@Operation(summary = "Rechercher des utilisateurs", description = "Recherche d'utilisateurs selon des critères")
|
||||||
|
UserSearchResultDTO searchUsers(@Valid @NotNull UserSearchCriteriaDTO criteria);
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/{userId}")
|
||||||
|
@Operation(summary = "Récupérer un utilisateur par ID", description = "Récupère les détails d'un utilisateur")
|
||||||
|
UserDTO getUserById(
|
||||||
|
@Parameter(description = "ID de l'utilisateur") @PathParam("userId") String userId,
|
||||||
|
@Parameter(description = "Nom du realm") @QueryParam("realm") String realmName);
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Operation(summary = "Lister tous les utilisateurs", description = "Liste paginée de tous les utilisateurs")
|
||||||
|
UserSearchResultDTO getAllUsers(
|
||||||
|
@QueryParam("realm") String realmName,
|
||||||
|
@QueryParam("page") @DefaultValue("0") int page,
|
||||||
|
@QueryParam("pageSize") @DefaultValue("20") int pageSize);
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Operation(summary = "Créer un utilisateur", description = "Crée un nouvel utilisateur dans Keycloak")
|
||||||
|
@APIResponses({
|
||||||
|
@APIResponse(responseCode = "201", description = "Utilisateur créé", content = @Content(schema = @Schema(implementation = UserDTO.class)))
|
||||||
|
})
|
||||||
|
Response createUser(
|
||||||
|
@Valid @NotNull UserDTO user,
|
||||||
|
@QueryParam("realm") String realmName);
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Path("/{userId}")
|
||||||
|
@Operation(summary = "Mettre à jour un utilisateur", description = "Met à jour les informations d'un utilisateur")
|
||||||
|
UserDTO updateUser(
|
||||||
|
@PathParam("userId") String userId,
|
||||||
|
@Valid @NotNull UserDTO user,
|
||||||
|
@QueryParam("realm") String realmName);
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
@Path("/{userId}")
|
||||||
|
@Operation(summary = "Supprimer un utilisateur", description = "Supprime un utilisateur (soft ou hard delete)")
|
||||||
|
void deleteUser(
|
||||||
|
@PathParam("userId") String userId,
|
||||||
|
@QueryParam("realm") String realmName,
|
||||||
|
@QueryParam("hardDelete") @DefaultValue("false") boolean hardDelete);
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/{userId}/activate")
|
||||||
|
@Operation(summary = "Activer un utilisateur", description = "Active un utilisateur désactivé")
|
||||||
|
void activateUser(
|
||||||
|
@PathParam("userId") String userId,
|
||||||
|
@QueryParam("realm") String realmName);
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/{userId}/deactivate")
|
||||||
|
@Operation(summary = "Désactiver un utilisateur", description = "Désactive un utilisateur")
|
||||||
|
void deactivateUser(
|
||||||
|
@PathParam("userId") String userId,
|
||||||
|
@QueryParam("realm") String realmName,
|
||||||
|
@QueryParam("raison") String raison);
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/{userId}/reset-password")
|
||||||
|
@Operation(summary = "Réinitialiser le mot de passe", description = "Définit un nouveau mot de passe pour l'utilisateur")
|
||||||
|
void resetPassword(
|
||||||
|
@PathParam("userId") String userId,
|
||||||
|
@QueryParam("realm") String realmName,
|
||||||
|
@NotNull PasswordResetRequestDTO request);
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/{userId}/send-verification-email")
|
||||||
|
@Operation(summary = "Envoyer email de vérification", description = "Envoie un email de vérification à l'utilisateur")
|
||||||
|
void sendVerificationEmail(
|
||||||
|
@PathParam("userId") String userId,
|
||||||
|
@QueryParam("realm") String realmName);
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/{userId}/logout-sessions")
|
||||||
|
@Operation(summary = "Déconnecter toutes les sessions", description = "Révoque toutes les sessions actives de l'utilisateur")
|
||||||
|
SessionsRevokedDTO logoutAllSessions(
|
||||||
|
@PathParam("userId") String userId,
|
||||||
|
@QueryParam("realm") String realmName);
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/{userId}/sessions")
|
||||||
|
@Operation(summary = "Récupérer les sessions actives", description = "Liste les sessions actives de l'utilisateur")
|
||||||
|
@APIResponses({
|
||||||
|
@APIResponse(responseCode = "200", description = "Liste des sessions", content = @Content(schema = @Schema(type = org.eclipse.microprofile.openapi.annotations.enums.SchemaType.ARRAY, implementation = String.class)))
|
||||||
|
})
|
||||||
|
List<String> getActiveSessions(
|
||||||
|
@PathParam("userId") String userId,
|
||||||
|
@QueryParam("realm") String realmName);
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/export/csv")
|
||||||
|
@Produces("text/csv")
|
||||||
|
@Operation(summary = "Exporter les utilisateurs en CSV", description = "Exporte la liste des utilisateurs du realm au format CSV")
|
||||||
|
Response exportUsersToCSV(@QueryParam("realm") String realmName);
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/import/csv")
|
||||||
|
@Consumes(MediaType.TEXT_PLAIN)
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@Operation(summary = "Importer des utilisateurs depuis un CSV", description = "Importe des utilisateurs à partir d'un fichier CSV")
|
||||||
|
ImportResultDTO importUsersFromCSV(
|
||||||
|
@QueryParam("realm") String realmName,
|
||||||
|
String csvContent);
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package dev.lions.user.manager.dto.common;
|
||||||
|
|
||||||
|
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.media.Schema;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@RegisterForReflection
|
||||||
|
@Schema(description = "Réponse d'erreur standard")
|
||||||
|
public class ApiErrorDTO implements Serializable {
|
||||||
|
@Schema(description = "Message d'erreur")
|
||||||
|
private String message;
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package dev.lions.user.manager.dto.common;
|
||||||
|
|
||||||
|
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.media.Schema;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@RegisterForReflection
|
||||||
|
@Schema(description = "Réponse de comptage générique")
|
||||||
|
public class CountDTO implements Serializable {
|
||||||
|
@Schema(description = "Nombre d'éléments")
|
||||||
|
private long count;
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package dev.lions.user.manager.dto.common;
|
||||||
|
|
||||||
|
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.media.Schema;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@RegisterForReflection
|
||||||
|
@Schema(description = "Statistiques de sessions et d'utilisateurs en ligne pour un realm")
|
||||||
|
public class UserSessionStatsDTO implements Serializable {
|
||||||
|
|
||||||
|
@Schema(description = "Nom du realm concerné")
|
||||||
|
private String realmName;
|
||||||
|
|
||||||
|
@Schema(description = "Nombre total d'utilisateurs dans le realm")
|
||||||
|
private long totalUsers;
|
||||||
|
|
||||||
|
@Schema(description = "Nombre total de sessions actives (approximation)")
|
||||||
|
private long activeSessions;
|
||||||
|
|
||||||
|
@Schema(description = "Nombre d'utilisateurs considérés comme en ligne (approximation)")
|
||||||
|
private long onlineUsers;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package dev.lions.user.manager.dto.realm;
|
||||||
|
|
||||||
|
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.media.Schema;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@RegisterForReflection
|
||||||
|
@Schema(description = "Liste des realms autorisés pour un utilisateur")
|
||||||
|
public class AuthorizedRealmsDTO implements Serializable {
|
||||||
|
@Schema(description = "Liste des realms (peut être vide si super admin)")
|
||||||
|
private List<String> realms;
|
||||||
|
|
||||||
|
@Schema(description = "L'utilisateur est super admin")
|
||||||
|
private boolean isSuperAdmin;
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package dev.lions.user.manager.dto.realm;
|
||||||
|
|
||||||
|
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.media.Schema;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@RegisterForReflection
|
||||||
|
@Schema(description = "Réponse de vérification d'accès au realm")
|
||||||
|
public class RealmAccessCheckDTO implements Serializable {
|
||||||
|
@Schema(description = "L'utilisateur peut gérer le realm")
|
||||||
|
private boolean canManage;
|
||||||
|
|
||||||
|
@Schema(description = "ID de l'utilisateur")
|
||||||
|
private String userId;
|
||||||
|
|
||||||
|
@Schema(description = "Nom du realm")
|
||||||
|
private String realmName;
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package dev.lions.user.manager.dto.role;
|
||||||
|
|
||||||
|
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.media.Schema;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@RegisterForReflection
|
||||||
|
@Schema(description = "Requête d'attribution ou de révocation de rôles")
|
||||||
|
public class RoleAssignmentRequestDTO implements Serializable {
|
||||||
|
@Schema(description = "Liste des noms de rôles", required = true)
|
||||||
|
private List<String> roleNames;
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package dev.lions.user.manager.dto.sync;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DTO rapport de cohérence entre données Keycloak et cache local.
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class SyncConsistencyDTO {
|
||||||
|
private String realmName;
|
||||||
|
private String status; // OK, MISMATCH, ERROR
|
||||||
|
private Integer usersKeycloakCount;
|
||||||
|
private Integer usersLocalCount;
|
||||||
|
private Set<String> missingUsersInLocal;
|
||||||
|
private Set<String> missingUsersInKeycloak;
|
||||||
|
private Integer rolesKeycloakCount;
|
||||||
|
private Integer rolesLocalCount;
|
||||||
|
private Set<String> missingRolesInLocal;
|
||||||
|
private Set<String> missingRolesInKeycloak;
|
||||||
|
private String error;
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package dev.lions.user.manager.dto.sync;
|
||||||
|
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class SyncHistoryDTO {
|
||||||
|
private String id;
|
||||||
|
private String realmName;
|
||||||
|
private LocalDateTime syncDate;
|
||||||
|
private String syncType; // FULL, PARTIAL, USER, ROLE
|
||||||
|
private String status; // SUCCESS, FAILURE
|
||||||
|
private Integer itemsProcessed;
|
||||||
|
private Long durationMs;
|
||||||
|
private String errorMessage;
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package dev.lions.user.manager.dto.user;
|
||||||
|
|
||||||
|
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.media.Schema;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@RegisterForReflection
|
||||||
|
@Schema(description = "Requête de réinitialisation de mot de passe")
|
||||||
|
public class PasswordResetRequestDTO implements Serializable {
|
||||||
|
@Schema(description = "Nouveau mot de passe", required = true)
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
@Schema(description = "Indique si le mot de passe est temporaire", defaultValue = "true")
|
||||||
|
@Builder.Default
|
||||||
|
private boolean temporary = true;
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package dev.lions.user.manager.dto.user;
|
||||||
|
|
||||||
|
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.media.Schema;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@RegisterForReflection
|
||||||
|
@Schema(description = "Réponse de révocation de sessions")
|
||||||
|
public class SessionsRevokedDTO implements Serializable {
|
||||||
|
@Schema(description = "Nombre de sessions révoquées")
|
||||||
|
private int count;
|
||||||
|
}
|
||||||
@@ -24,6 +24,7 @@ public enum TypeActionAudit {
|
|||||||
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
|
||||||
|
|
||||||
// Actions Rôle
|
// Actions Rôle
|
||||||
ROLE_CREATE("Création rôle", "ROLE", "CREATE"),
|
ROLE_CREATE("Création rôle", "ROLE", "CREATE"),
|
||||||
@@ -41,8 +42,10 @@ public enum TypeActionAudit {
|
|||||||
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
|
// Actions Realm & Sync
|
||||||
REALM_SYNC("Synchronisation realm", "REALM", "SYNC"),
|
REALM_SYNC("Synchronisation realm (Général)", "REALM", "SYNC"),
|
||||||
|
SYNC_USERS("Synchronisation utilisateurs", "REALM", "SYNC_USERS"), // Ajout
|
||||||
|
SYNC_ROLES("Synchronisation rôles", "REALM", "SYNC_ROLES"), // Ajout
|
||||||
REALM_EXPORT("Export realm", "REALM", "EXPORT"),
|
REALM_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"),
|
||||||
@@ -105,9 +108,9 @@ public enum TypeActionAudit {
|
|||||||
*/
|
*/
|
||||||
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user