Task 1.6 - Configuration application.properties

- Configuration complète de la sécurité GBCM (JWT, mots de passe, verrouillage)
- Profils dev, test, et production configurés
- Génération des clés RSA pour JWT
- Création de application-local.properties pour développement local
- Ajout de la dépendance H2 pour les profils dev et test
- Correction de User.getRoleString() pour Quarkus Security JPA
- Correction des endpoints @FormParam avec @Consumes dans AuthResource et UserResource
- Correction des données de test import.sql (ajout colonne deleted)
- Documentation complète dans CONFIGURATION.md
- Application démarre avec succès en mode dev
This commit is contained in:
dahoud
2025-10-06 21:34:59 +00:00
parent 5ec5e538cc
commit d82269c713
8 changed files with 205 additions and 19 deletions

108
CONFIGURATION.md Normal file
View File

@@ -0,0 +1,108 @@
# Configuration GBCM Server
## Vue d'ensemble
Le serveur GBCM utilise Quarkus avec des profils de configuration pour différents environnements.
## Profils disponibles
### Profil par défaut (Production)
- Base de données PostgreSQL
- JWT avec clés RSA
- Logs au niveau WARN
- Sécurité renforcée
### Profil `dev` (Développement)
- Base de données H2 en mémoire
- Logs au niveau DEBUG
- Sécurité allégée (BCrypt cost=4)
- Rechargement automatique
### Profil `test` (Tests)
- Base de données H2 en mémoire
- Configuration optimisée pour les tests
- Sécurité minimale pour rapidité
### Profil `local` (Développement local)
- Configuration personnalisable
- Utilise `application-local.properties`
## Variables d'environnement importantes
### Base de données (Production)
```bash
DATABASE_URL=jdbc:postgresql://localhost:5432/gbcm_prod
DB_USERNAME=gbcm_prod_user
DB_PASSWORD=secure_password
```
### JWT (Production)
```bash
JWT_SECRET=your-super-secure-jwt-secret-key-256-bits-minimum
```
### Email (Production)
```bash
SMTP_USERNAME=your-smtp-username
SMTP_PASSWORD=your-smtp-password
```
## Configuration de sécurité
### Paramètres JWT
- `gbcm.security.jwt.access-token.duration`: Durée de vie des tokens d'accès (défaut: 1h)
- `gbcm.security.jwt.refresh-token.duration`: Durée de vie des refresh tokens (défaut: 7j)
- `gbcm.security.jwt.reset-token.duration`: Durée de vie des tokens de reset (défaut: 2h)
### Paramètres de mot de passe
- `gbcm.security.password.bcrypt-cost`: Coût BCrypt (défaut: 12)
- `gbcm.security.password.min-length`: Longueur minimale (défaut: 8)
- `gbcm.security.password.max-age`: Âge maximum (défaut: 90j)
### Paramètres de compte
- `gbcm.security.account.max-failed-attempts`: Tentatives max (défaut: 5)
- `gbcm.security.account.lockout-duration`: Durée de verrouillage (défaut: 30min)
## Démarrage rapide
### Développement avec H2
```bash
mvn quarkus:dev
```
### Développement avec configuration locale
```bash
mvn quarkus:dev -Dquarkus.profile=local
```
### Tests
```bash
mvn test
```
### Production
```bash
java -jar target/quarkus-app/quarkus-run.jar -Dquarkus.profile=prod
```
## URLs importantes
- Application: http://localhost:8081
- Swagger UI: http://localhost:8081/swagger
- Health Check: http://localhost:8081/health
- Metrics: http://localhost:8081/q/metrics
## Sécurité
⚠️ **Important**:
- Changez toujours `JWT_SECRET` en production
- Utilisez des mots de passe forts pour la base de données
- Configurez HTTPS en production
- Limitez les origines CORS en production
## Logs
Les logs sont configurés par niveau :
- `com.gbcm`: DEBUG en développement, INFO en production
- `org.hibernate.SQL`: DEBUG en développement seulement
- Root level: DEBUG en dev, WARN en production

View File

@@ -65,6 +65,10 @@
<groupId>io.quarkus</groupId> <groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-postgresql</artifactId> <artifactId>quarkus-jdbc-postgresql</artifactId>
</dependency> </dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-h2</artifactId>
</dependency>
<dependency> <dependency>
<groupId>io.quarkus</groupId> <groupId>io.quarkus</groupId>
<artifactId>quarkus-flyway</artifactId> <artifactId>quarkus-flyway</artifactId>

View File

@@ -111,9 +111,17 @@ public class User extends BaseEntity {
@Enumerated(EnumType.STRING) @Enumerated(EnumType.STRING)
@Column(name = "role", nullable = false, length = 20) @Column(name = "role", nullable = false, length = 20)
@NotNull(message = "Le rôle est obligatoire") @NotNull(message = "Le rôle est obligatoire")
@Roles
private UserRole role; private UserRole role;
/**
* Rôle de l'utilisateur sous forme de String pour Quarkus Security JPA.
* Cette propriété est utilisée par le système de sécurité pour l'authentification.
*/
@Roles
public String getRoleString() {
return role != null ? role.name() : null;
}
/** /**
* Statut d'activation du compte utilisateur. * Statut d'activation du compte utilisateur.
* true = compte actif, false = compte désactivé. * true = compte actif, false = compte désactivé.

View File

@@ -165,6 +165,7 @@ public class AuthResource {
*/ */
@POST @POST
@Path("/refresh") @Path("/refresh")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Operation( @Operation(
summary = "Rafraîchissement du token", summary = "Rafraîchissement du token",
description = "Génère un nouveau token d'authentification à partir d'un refresh token" description = "Génère un nouveau token d'authentification à partir d'un refresh token"
@@ -257,6 +258,7 @@ public class AuthResource {
*/ */
@POST @POST
@Path("/forgot-password") @Path("/forgot-password")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Operation( @Operation(
summary = "Mot de passe oublié", summary = "Mot de passe oublié",
description = "Envoie un email de réinitialisation de mot de passe à l'utilisateur" description = "Envoie un email de réinitialisation de mot de passe à l'utilisateur"
@@ -300,6 +302,7 @@ public class AuthResource {
*/ */
@POST @POST
@Path("/reset-password") @Path("/reset-password")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Operation( @Operation(
summary = "Réinitialisation du mot de passe", summary = "Réinitialisation du mot de passe",
description = "Réinitialise le mot de passe avec un token de réinitialisation" description = "Réinitialise le mot de passe avec un token de réinitialisation"
@@ -346,6 +349,7 @@ public class AuthResource {
*/ */
@PUT @PUT
@Path("/change-password") @Path("/change-password")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Operation( @Operation(
summary = "Changement de mot de passe", summary = "Changement de mot de passe",
description = "Change le mot de passe d'un utilisateur authentifié" description = "Change le mot de passe d'un utilisateur authentifié"

View File

@@ -368,6 +368,7 @@ public class UserResource {
*/ */
@PUT @PUT
@Path("/{id}/status") @Path("/{id}/status")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@RolesAllowed({"ADMIN", "MANAGER"}) @RolesAllowed({"ADMIN", "MANAGER"})
@Operation( @Operation(
summary = "Changer le statut d'un utilisateur", summary = "Changer le statut d'un utilisateur",

View File

@@ -0,0 +1,38 @@
# Configuration locale pour développement GBCM
# Ce fichier peut être utilisé pour surcharger les configurations par défaut
# Copiez ce fichier vers application-local.properties et modifiez selon vos besoins
# Base de données locale PostgreSQL (optionnel)
# Décommentez et modifiez si vous voulez utiliser PostgreSQL en local
#quarkus.datasource.db-kind=postgresql
#quarkus.datasource.username=gbcm_local
#quarkus.datasource.password=gbcm_local_password
#quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5432/gbcm_local
#quarkus.hibernate-orm.database.generation=validate
#quarkus.flyway.migrate-at-start=true
# Configuration JWT locale
gbcm.security.jwt.secret=local-development-secret-key-change-me
gbcm.security.jwt.access-token.duration=PT2H
gbcm.security.jwt.refresh-token.duration=P1D
# Configuration email locale (pour tests)
quarkus.mailer.mock=true
quarkus.mailer.from=dev@localhost
# Configuration de sécurité allégée pour développement
gbcm.security.password.bcrypt-cost=4
gbcm.security.account.max-failed-attempts=10
gbcm.security.account.lockout-duration=PT2M
# Logs détaillés pour développement
quarkus.log.category."com.gbcm.server.impl.service.security".level=TRACE
quarkus.log.category."com.gbcm.server.impl.service.notification".level=DEBUG
# CORS étendu pour développement
quarkus.http.cors.origins=http://localhost:3000,http://localhost:8080,http://localhost:4200
# Configuration OpenAPI étendue
mp.openapi.extensions.smallrye.info.description=API GBCM - Environnement de développement local
quarkus.swagger-ui.enable=true
quarkus.swagger-ui.always-include=true

View File

@@ -37,6 +37,21 @@ smallrye.jwt.new-token.issuer=https://gbcm.com
smallrye.jwt.new-token.audience=gbcm-users smallrye.jwt.new-token.audience=gbcm-users
smallrye.jwt.new-token.lifespan=3600 smallrye.jwt.new-token.lifespan=3600
# GBCM Security Configuration
gbcm.security.jwt.access-token.duration=PT1H
gbcm.security.jwt.refresh-token.duration=P7D
gbcm.security.jwt.reset-token.duration=PT2H
gbcm.security.jwt.secret=${JWT_SECRET:gbcm-super-secret-key-change-in-production}
gbcm.security.password.bcrypt-cost=12
gbcm.security.password.min-length=8
gbcm.security.password.require-uppercase=true
gbcm.security.password.require-lowercase=true
gbcm.security.password.require-digit=true
gbcm.security.password.require-special=true
gbcm.security.account.max-failed-attempts=5
gbcm.security.account.lockout-duration=PT30M
gbcm.security.password.max-age=P90D
# OpenAPI Configuration # OpenAPI Configuration
quarkus.smallrye-openapi.path=/swagger-ui quarkus.smallrye-openapi.path=/swagger-ui
quarkus.swagger-ui.always-include=true quarkus.swagger-ui.always-include=true
@@ -81,12 +96,20 @@ quarkus.log.category."org.hibernate.SQL".level=DEBUG
%dev.quarkus.datasource.db-kind=h2 %dev.quarkus.datasource.db-kind=h2
%dev.quarkus.hibernate-orm.database.generation=drop-and-create %dev.quarkus.hibernate-orm.database.generation=drop-and-create
%dev.quarkus.flyway.migrate-at-start=false %dev.quarkus.flyway.migrate-at-start=false
%dev.gbcm.security.jwt.secret=dev-secret-key-not-for-production
%dev.gbcm.security.password.bcrypt-cost=4
%dev.gbcm.security.account.max-failed-attempts=10
%dev.gbcm.security.account.lockout-duration=PT5M
# Test Profile # Test Profile
%test.quarkus.datasource.jdbc.url=jdbc:h2:mem:gbcm_server_test;DB_CLOSE_DELAY=-1 %test.quarkus.datasource.jdbc.url=jdbc:h2:mem:gbcm_server_test;DB_CLOSE_DELAY=-1
%test.quarkus.datasource.db-kind=h2 %test.quarkus.datasource.db-kind=h2
%test.quarkus.hibernate-orm.database.generation=drop-and-create %test.quarkus.hibernate-orm.database.generation=drop-and-create
%test.quarkus.flyway.migrate-at-start=false %test.quarkus.flyway.migrate-at-start=false
%test.gbcm.security.jwt.secret=test-secret-key-for-testing-only
%test.gbcm.security.password.bcrypt-cost=4
%test.gbcm.security.account.max-failed-attempts=3
%test.gbcm.security.account.lockout-duration=PT1M
# Production Profile # Production Profile
%prod.quarkus.log.level=WARN %prod.quarkus.log.level=WARN

View File

@@ -3,20 +3,20 @@
-- Insertion des utilisateurs de test -- Insertion des utilisateurs de test
-- Mot de passe pour tous: "password123" (hash BCrypt) -- Mot de passe pour tous: "password123" (hash BCrypt)
INSERT INTO users (first_name, last_name, email, password_hash, role, active, created_by) VALUES INSERT INTO users (first_name, last_name, email, password_hash, role, active, deleted, created_by) VALUES
('Admin', 'System', 'admin@gbcm.com', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9P8jW9TjnOvQF9G', 'ADMIN', true, 'system'), ('Admin', 'System', 'admin@gbcm.com', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9P8jW9TjnOvQF9G', 'ADMIN', true, false, 'system'),
('John', 'Manager', 'manager@gbcm.com', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9P8jW9TjnOvQF9G', 'MANAGER', true, 'system'), ('John', 'Manager', 'manager@gbcm.com', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9P8jW9TjnOvQF9G', 'MANAGER', true, false, 'system'),
('Sarah', 'Coach', 'sarah.coach@gbcm.com', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9P8jW9TjnOvQF9G', 'COACH', true, 'system'), ('Sarah', 'Coach', 'sarah.coach@gbcm.com', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9P8jW9TjnOvQF9G', 'COACH', true, false, 'system'),
('Michael', 'Expert', 'michael.expert@gbcm.com', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9P8jW9TjnOvQF9G', 'COACH', true, 'system'), ('Michael', 'Expert', 'michael.expert@gbcm.com', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9P8jW9TjnOvQF9G', 'COACH', true, false, 'system'),
('Emily', 'Johnson', 'emily.johnson@techcorp.com', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9P8jW9TjnOvQF9G', 'CLIENT', true, 'system'), ('Emily', 'Johnson', 'emily.johnson@techcorp.com', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9P8jW9TjnOvQF9G', 'CLIENT', true, false, 'system'),
('David', 'Smith', 'david.smith@innovate.com', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9P8jW9TjnOvQF9G', 'CLIENT', true, 'system'), ('David', 'Smith', 'david.smith@innovate.com', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9P8jW9TjnOvQF9G', 'CLIENT', true, false, 'system'),
('Lisa', 'Brown', 'lisa.brown@startup.com', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9P8jW9TjnOvQF9G', 'PROSPECT', true, 'system'), ('Lisa', 'Brown', 'lisa.brown@startup.com', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9P8jW9TjnOvQF9G', 'PROSPECT', true, false, 'system'),
('Robert', 'Wilson', 'robert.wilson@enterprise.com', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9P8jW9TjnOvQF9G', 'PROSPECT', true, 'system'); ('Robert', 'Wilson', 'robert.wilson@enterprise.com', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9P8jW9TjnOvQF9G', 'PROSPECT', true, false, 'system');
-- Insertion des coaches -- Insertion des coaches
INSERT INTO coaches (user_id, specialization, bio, years_of_experience, certifications, languages, hourly_rate, status, available_for_booking, working_hours_start, working_hours_end, working_days, timezone, start_date, average_rating, total_ratings, total_sessions, total_revenue, created_by) VALUES INSERT INTO coaches (user_id, specialization, bio, years_of_experience, certifications, languages, hourly_rate, status, available_for_booking, working_hours_start, working_hours_end, working_days, timezone, start_date, average_rating, total_ratings, total_sessions, total_revenue, deleted, created_by) VALUES
(3, 'Strategic Planning', 'Expert en planification stratégique avec plus de 10 ans d''expérience dans le conseil aux PME. Spécialisée dans la transformation digitale et l''optimisation des processus.', 10, 'Certified Management Consultant (CMC), PMP, Lean Six Sigma Black Belt', 'English, French, Spanish', 125.00, 'ACTIVE', true, '09:00:00', '17:00:00', 'MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY', 'America/New_York', '2020-01-15', 4.8, 45, 120, 15000.00, 'system'), (3, 'Strategic Planning', 'Expert en planification stratégique avec plus de 10 ans d''expérience dans le conseil aux PME. Spécialisée dans la transformation digitale et l''optimisation des processus.', 10, 'Certified Management Consultant (CMC), PMP, Lean Six Sigma Black Belt', 'English, French, Spanish', 125.00, 'ACTIVE', true, '09:00:00', '17:00:00', 'MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY', 'America/New_York', '2020-01-15', 4.8, 45, 120, 15000.00, false, 'system'),
(4, 'Business Development', 'Coach expérimenté en développement commercial et leadership. Aide les entrepreneurs à développer leurs compétences managériales et à faire croître leur entreprise.', 8, 'Certified Business Coach (CBC), MBA, Dale Carnegie Leadership Training', 'English, French', 100.00, 'ACTIVE', true, '08:00:00', '18:00:00', 'MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY', 'America/New_York', '2021-03-01', 4.9, 38, 95, 9500.00, 'system'); (4, 'Business Development', 'Coach expérimenté en développement commercial et leadership. Aide les entrepreneurs à développer leurs compétences managériales et à faire croître leur entreprise.', 8, 'Certified Business Coach (CBC), MBA, Dale Carnegie Leadership Training', 'English, French', 100.00, 'ACTIVE', true, '08:00:00', '18:00:00', 'MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY', 'America/New_York', '2021-03-01', 4.9, 38, 95, 9500.00, false, 'system');
-- Insertion des types de services pour les coaches -- Insertion des types de services pour les coaches
INSERT INTO coach_service_types (coach_id, service_type) VALUES INSERT INTO coach_service_types (coach_id, service_type) VALUES
@@ -28,11 +28,11 @@ INSERT INTO coach_service_types (coach_id, service_type) VALUES
(2, 'special_project'); (2, 'special_project');
-- Insertion des clients -- Insertion des clients
INSERT INTO clients (user_id, company_name, industry, company_size, annual_revenue, address_line1, city, state, postal_code, country, website, status, converted_at, primary_service_type, total_contract_value, relationship_start_date, acquisition_source, created_by) VALUES INSERT INTO clients (user_id, company_name, industry, company_size, annual_revenue, address_line1, city, state, postal_code, country, website, status, converted_at, primary_service_type, total_contract_value, relationship_start_date, acquisition_source, deleted, created_by) VALUES
(5, 'TechCorp Solutions', 'Technology', 50, 2500000.00, '123 Tech Street', 'Atlanta', 'GA', '30309', 'USA', 'https://techcorp.com', 'ACTIVE', '2023-06-15 10:30:00', 'strategic_workshop', 4000.00, '2023-06-15', 'Website', 'system'), (5, 'TechCorp Solutions', 'Technology', 50, 2500000.00, '123 Tech Street', 'Atlanta', 'GA', '30309', 'USA', 'https://techcorp.com', 'ACTIVE', '2023-06-15 10:30:00', 'strategic_workshop', 4000.00, '2023-06-15', 'Website', false, 'system'),
(6, 'Innovate Inc', 'Consulting', 25, 1200000.00, '456 Innovation Ave', 'Atlanta', 'GA', '30308', 'USA', 'https://innovate.com', 'ACTIVE', '2023-08-20 14:15:00', 'one_on_one_coaching', 2500.00, '2023-08-20', 'Referral', 'system'); (6, 'Innovate Inc', 'Consulting', 25, 1200000.00, '456 Innovation Ave', 'Atlanta', 'GA', '30308', 'USA', 'https://innovate.com', 'ACTIVE', '2023-08-20 14:15:00', 'one_on_one_coaching', 2500.00, '2023-08-20', 'Referral', false, 'system');
-- Insertion des prospects -- Insertion des prospects
INSERT INTO clients (user_id, company_name, industry, company_size, annual_revenue, address_line1, city, state, postal_code, country, website, status, acquisition_source, created_by) VALUES INSERT INTO clients (user_id, company_name, industry, company_size, annual_revenue, address_line1, city, state, postal_code, country, website, status, acquisition_source, deleted, created_by) VALUES
(7, 'StartupCo', 'E-commerce', 10, 500000.00, '789 Startup Blvd', 'Atlanta', 'GA', '30307', 'USA', 'https://startupco.com', 'PROSPECT', 'LinkedIn', 'system'), (7, 'StartupCo', 'E-commerce', 10, 500000.00, '789 Startup Blvd', 'Atlanta', 'GA', '30307', 'USA', 'https://startupco.com', 'PROSPECT', 'LinkedIn', false, 'system'),
(8, 'Enterprise Corp', 'Manufacturing', 200, 15000000.00, '321 Enterprise Way', 'Atlanta', 'GA', '30306', 'USA', 'https://enterprise.com', 'PROSPECT', 'Trade Show', 'system'); (8, 'Enterprise Corp', 'Manufacturing', 200, 15000000.00, '321 Enterprise Way', 'Atlanta', 'GA', '30306', 'USA', 'https://enterprise.com', 'PROSPECT', 'Trade Show', false, 'system');