From c34334376a5c6b6722df9a09c1a53d15c8af5194 Mon Sep 17 00:00:00 2001 From: Aurince AKAKPO Date: Wed, 17 Dec 2025 15:10:27 +0100 Subject: [PATCH 1/2] =?UTF-8?q?revu=20des=20secrets=20et=20.env=20pour=20d?= =?UTF-8?q?iff=C3=A9rencier?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 3 +- .gitea/workflows/cd-main.yml | 86 +++++++++---------- .gitea/workflows/ci-develop.yml | 53 ++++++------ .gitignore | 1 + docker-compose-prod.yml | 4 +- docker-compose.yml | 48 +++++++++-- secrets/defaultUserName.txt | 1 + secrets/defaultUserPassword.txt | 1 + .../gmss/fiscad/component/DataLoadConfig.java | 13 +-- .../repositories/user/UserRepository.java | 2 + src/main/resources/application.properties | 9 +- 11 files changed, 134 insertions(+), 87 deletions(-) create mode 100644 secrets/defaultUserName.txt create mode 100644 secrets/defaultUserPassword.txt diff --git a/.env b/.env index 00cde75..e056a1a 100644 --- a/.env +++ b/.env @@ -1,3 +1,2 @@ POSTGRES_DB=abomey_db -POSTGRES_USER=infocad_user -POSTGRES_PASSWORD=W5fwD({9*q53 \ No newline at end of file +POSTGRES_USER=infocad_user \ No newline at end of file diff --git a/.gitea/workflows/cd-main.yml b/.gitea/workflows/cd-main.yml index 6798f10..4132e04 100644 --- a/.gitea/workflows/cd-main.yml +++ b/.gitea/workflows/cd-main.yml @@ -1,7 +1,7 @@ name: CD - Deploy on main on: - pull_request: + push: branches: - main @@ -10,6 +10,7 @@ jobs: runs-on: self-hosted steps: + # 1) S'assurer que Node.js est installé - name: Ensure Node.js is installed shell: sh @@ -17,102 +18,97 @@ jobs: if command -v node >/dev/null 2>&1; then echo "Node.js already installed: $(node -v)" else - echo "Node.js not found, installing..." apk update && apk add --no-cache nodejs echo "Node.js installed: $(node -v)" fi - # 2) S'assurer que Java & Maven sont installés + # 2) S'assurer que Java 17 & Maven sont installés - name: Ensure Java & Maven are installed shell: sh run: | - if command -v java >/dev/null 2>&1; then - echo "Java already installed:" - java -version - else - echo "Java not found, installing OpenJDK 17..." + if ! command -v java >/dev/null 2>&1; then apk update && apk add --no-cache openjdk17-jdk - echo "Java installed:" - java -version fi + java -version - if command -v mvn >/dev/null 2>&1; then - echo "Maven already installed:" - mvn -version - else - echo "Maven not found, installing Maven..." + if ! command -v mvn >/dev/null 2>&1; then apk update && apk add --no-cache maven - echo "Maven installed:" - mvn -version fi + mvn -version - # 3) Détecter JAVA_HOME dynamiquement et le propager + # 3) Détecter JAVA_HOME dynamiquement - name: Detect JAVA_HOME dynamically shell: sh run: | JAVA_BIN=$(readlink -f "$(command -v java)") JAVA_HOME=$(dirname "$(dirname "$JAVA_BIN")") - echo "Detected JAVA_HOME=$JAVA_HOME" echo "JAVA_HOME=$JAVA_HOME" >> "$GITHUB_ENV" # 4) Checkout du dépôt - name: Checkout repository uses: actions/checkout@v4 - # 5) Afficher quelques infos utiles - - name: Show current commit and tools + # 5) Informations de contexte (sans secrets) + - name: Show context information shell: sh run: | - echo "Current commit:" + echo "Commit:" git rev-parse HEAD - echo "JAVA_HOME is: $JAVA_HOME" + echo "JAVA_HOME=$JAVA_HOME" java -version mvn -version - # 6) S'assurer que le client Docker + docker-compose sont installés - - name: Ensure Docker CLI is installed + # 6) S'assurer que Docker CLI & docker-compose sont installés + - name: Ensure Docker & docker-compose are installed shell: sh run: | if command -v docker >/dev/null 2>&1; then - echo "Docker CLI already installed:" docker version || true else - echo "Docker CLI not found, installing..." apk update && apk add --no-cache docker docker-compose - echo "Docker CLI installed:" docker version || true fi - # 7) Générer le .env utilisé par docker-compose-prod.yml - - name: Generate .env from Gitea secrets + # 7) Fournir la configuration NON sensible (OBLIGATOIRE) + # (POSTGRES_DB et POSTGRES_USER ne sont PAS des secrets) + - name: Export database configuration shell: sh run: | - cat > .env <> "$GITHUB_ENV" + echo "POSTGRES_USER_FISCAD=fiscad_user" >> "$GITHUB_ENV" - # 8) Build Maven pour générer le jar dans target/ + # 8) Création des secrets runtime (PRODUCTION) + - name: Create runtime secrets + shell: sh + run: | + mkdir -p secrets + echo "${{ secrets.DEFAULT_USER_NAME }}" > secrets/defaultUserName.txt + echo "${{ secrets.DEFAULT_USER_PASSWORD }}" > secrets/defaultUserPassword.txt + echo "${{ secrets.POSTGRES_PASSWORD_FISCAD }}" > secrets/postgresPassword.txt + chmod 600 secrets/* + + # 9) Build Maven (jar final) - name: Build backend with Maven shell: sh - run: mvn -B clean package + run: mvn -B clean package -DskipTests - # 9) Déploiement en prod avec docker-compose-prod.yml + # 10) Déploiement avec docker-compose (prod) - name: Deploy using docker-compose (prod) shell: sh run: | - # IMPORTANT : on fixe le nom du projet compose export COMPOSE_PROJECT_NAME=fiscad - - # Puis on déploie avec un nom de projet fixe + docker-compose -f docker-compose-prod.yml pull || true docker-compose -f docker-compose-prod.yml down --remove-orphans docker-compose -f docker-compose-prod.yml up -d --build - # 10) Nettoyage des images non utilisées - - name: Cleanup unused images + # 11) Nettoyage des secrets (OBLIGATOIRE) + - name: Cleanup secrets + if: always() + shell: sh + run: rm -rf secrets + + # 12) Nettoyage des images Docker inutilisées + - name: Cleanup unused Docker images shell: sh run: docker image prune -f || true \ No newline at end of file diff --git a/.gitea/workflows/ci-develop.yml b/.gitea/workflows/ci-develop.yml index 95e8aea..b2ee6f5 100644 --- a/.gitea/workflows/ci-develop.yml +++ b/.gitea/workflows/ci-develop.yml @@ -10,64 +10,69 @@ jobs: runs-on: self-hosted steps: - # 1) S'assurer que Node.js est installé (utile pour les actions JS comme actions/checkout) + + # 1) Node.js - name: Ensure Node.js is installed shell: sh run: | if command -v node >/dev/null 2>&1; then echo "Node.js already installed: $(node -v)" else - echo "Node.js not found, installing..." apk update && apk add --no-cache nodejs echo "Node.js installed: $(node -v)" fi - # 2) S'assurer que Java + Maven sont installés + # 2) Java & Maven - name: Ensure Java & Maven are installed shell: sh run: | - if command -v java >/dev/null 2>&1; then - echo "Java already installed:" - java -version - else - echo "Java not found, installing OpenJDK 17..." + if ! command -v java >/dev/null 2>&1; then apk update && apk add --no-cache openjdk17-jdk - echo "Java installed:" - java -version fi + java -version - if command -v mvn >/dev/null 2>&1; then - echo "Maven already installed:" - mvn -version - else - echo "Maven not found, installing Maven..." + if ! command -v mvn >/dev/null 2>&1; then apk update && apk add --no-cache maven - echo "Maven installed:" - mvn -version fi + mvn -version - # 3) Détecter automatiquement JAVA_HOME et le propager au reste du job + # 3) JAVA_HOME - name: Detect JAVA_HOME dynamically shell: sh run: | JAVA_BIN=$(readlink -f "$(command -v java)") JAVA_HOME=$(dirname "$(dirname "$JAVA_BIN")") - echo "Detected JAVA_HOME=$JAVA_HOME" echo "JAVA_HOME=$JAVA_HOME" >> "$GITHUB_ENV" - # 4) Checkout du dépôt (Node est déjà garanti à ce stade) + # 4) Checkout - name: Checkout repository uses: actions/checkout@v4 - # 5) Vérification des versions (pour les logs) + # 5) Secrets runtime (CI) + - name: Create runtime secrets + shell: sh + run: | + mkdir -p secrets + echo "${{ secrets.DEFAULT_USER_NAME }}" > secrets/defaultUserName.txt + echo "${{ secrets.DEFAULT_USER_PASSWORD }}" > secrets/defaultUserPassword.txt + echo "${{ secrets.POSTGRES_PASSWORD_FISCAD }}" > secrets/postgresPassword.txt + chmod 600 secrets/* + + # 6) Vérification outils - name: Show Java & Maven versions shell: sh run: | - echo "JAVA_HOME is: $JAVA_HOME" + echo "JAVA_HOME=$JAVA_HOME" java -version mvn -version - # 6) Build Maven + # 7) Build & tests - name: Build with Maven shell: sh - run: mvn -B clean verify \ No newline at end of file + run: mvn -B clean verify + + # 8) Nettoyage + - name: Cleanup secrets + if: always() + shell: sh + run: rm -rf secrets \ No newline at end of file diff --git a/.gitignore b/.gitignore index d6739fd..aeb74ae 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ fiscad.log* .DS_Store target/* ansible +secrets/ \ No newline at end of file diff --git a/docker-compose-prod.yml b/docker-compose-prod.yml index 23e1406..4b96665 100644 --- a/docker-compose-prod.yml +++ b/docker-compose-prod.yml @@ -9,7 +9,7 @@ services: environment: POSTGRES_DB: ${POSTGRES_DB_FISCAD} POSTGRES_USER: ${POSTGRES_USER_FISCAD} - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD_FISCAD} + POSTGRES_PASSWORD_FILE: /run/secrets/postgresPassword ports: - "5432:5432" volumes: @@ -30,7 +30,7 @@ services: environment: SPRING_DATASOURCE_URL: jdbc:postgresql://db:5432/${POSTGRES_DB_FISCAD} SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER_FISCAD} - SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD_FISCAD} + SPRING_DATASOURCE_PASSWORD_FILE: /run/secrets/postgresPassword SERVER_PORT: 8282 IO_GMSS_FISCAD_PROFILE: abomey SPRING_PROFILES_ACTIVE: abomey diff --git a/docker-compose.yml b/docker-compose.yml index edbc7e5..cce17e0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,41 +6,73 @@ services: image: postgres:15 container_name: fiscad-db restart: always + environment: - POSTGRES_DB: ${POSTGRES_DB} - POSTGRES_USER: ${POSTGRES_USER} - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + POSTGRES_DB: ${POSTGRES_DB_FISCAD} + POSTGRES_USER: ${POSTGRES_USER_FISCAD} + POSTGRES_PASSWORD_FILE: /run/secrets/postgresPassword + + secrets: + - postgresPassword + ports: - "5432:5432" + volumes: - db-data:/var/lib/postgresql/data + healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"] interval: 10s timeout: 5s retries: 5 + app: build: context: . dockerfile: Dockerfile container_name: fiscad-app + restart: on-failure + depends_on: - db + environment: - SPRING_DATASOURCE_URL: jdbc:postgresql://db:5432/${POSTGRES_DB} - SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER} - SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD} + SPRING_DATASOURCE_URL: jdbc:postgresql://db:5432/${POSTGRES_DB_FISCAD} + SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER_FISCAD} + SPRING_DATASOURCE_PASSWORD_FILE: /run/secrets/postgresPassword + SERVER_PORT: 8282 IO_GMSS_FISCAD_PROFILE: dgi SPRING_PROFILES_ACTIVE: dgi + + # 🔐 Secrets Spring (fichiers) + DEFAULT_USER_NAME_FILE: /run/secrets/defaultUserName + DEFAULT_USER_PASSWORD_FILE: /run/secrets/defaultUserPassword + + secrets: + - defaultUserName + - defaultUserPassword + - postgresPassword + ports: - "8282:8282" + volumes: - ./uploads:/app/uploads - ./jasperReport:/app/jasperReport - ./logs:/app/logs - restart: on-failure + volumes: - db-data: \ No newline at end of file + db-data: + + +secrets: + defaultUserName: + file: ./secrets/defaultUserName.txt + defaultUserPassword: + file: ./secrets/defaultUserPassword.txt + postgresPassword: + file: ./secrets/postgresPassword.txt \ No newline at end of file diff --git a/secrets/defaultUserName.txt b/secrets/defaultUserName.txt new file mode 100644 index 0000000..dce60ec --- /dev/null +++ b/secrets/defaultUserName.txt @@ -0,0 +1 @@ +infocad_admin \ No newline at end of file diff --git a/secrets/defaultUserPassword.txt b/secrets/defaultUserPassword.txt new file mode 100644 index 0000000..e7adc72 --- /dev/null +++ b/secrets/defaultUserPassword.txt @@ -0,0 +1 @@ +admin@123 \ No newline at end of file diff --git a/src/main/java/io/gmss/fiscad/component/DataLoadConfig.java b/src/main/java/io/gmss/fiscad/component/DataLoadConfig.java index 67467a1..119c678 100755 --- a/src/main/java/io/gmss/fiscad/component/DataLoadConfig.java +++ b/src/main/java/io/gmss/fiscad/component/DataLoadConfig.java @@ -20,8 +20,11 @@ public class DataLoadConfig { private final UserRepository userRepository; private final PasswordEncoder passwordEncoder; - @Value("${app.sourcemind.env.defaultpassword}") - private String defaultPassword; + @Value("${DEFAULT_USER_NAME_FILE}") + private String usernameFile; + + @Value("${DEFAULT_USER_PASSWORD_FILE}") + private String passwordFile; public DataLoadConfig(RoleRepository roleRepository, UserRepository userRepository, PasswordEncoder passwordEncoder) { this.roleRepository = roleRepository; @@ -52,14 +55,14 @@ public class DataLoadConfig { } public void loadUsers() { - if (userRepository.countAllByUsernameIsNotNull() == 0) { + if (userRepository.existsByUsername(usernameFile) ) { User admin = new User(); - admin.setUsername("administrateur@infocad.bj"); + admin.setUsername(usernameFile); admin.setEmail("administrateur@infocad.bj"); admin.setTel("N/A"); admin.setNom("Administrateur"); admin.setPrenom("Principal"); - admin.setPassword(passwordEncoder.encode(defaultPassword)); + admin.setPassword(passwordEncoder.encode(passwordFile)); admin.setActive(true); Set roles = new HashSet<>(); roles.add(roleRepository.findRoleByNom(UserRole.ROLE_ADMIN).get()); diff --git a/src/main/java/io/gmss/fiscad/repositories/user/UserRepository.java b/src/main/java/io/gmss/fiscad/repositories/user/UserRepository.java index 20e06dc..f0f5444 100755 --- a/src/main/java/io/gmss/fiscad/repositories/user/UserRepository.java +++ b/src/main/java/io/gmss/fiscad/repositories/user/UserRepository.java @@ -14,6 +14,8 @@ public interface UserRepository extends JpaRepository { Optional findByUsername(String username); + boolean existsByUsername(String username); + long countAllByUsernameIsNotNull(); List findAllByStructureAndRolesIn(Structure structure, Set roleSet); diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 4c86658..ee9f49f 100755 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -11,7 +11,7 @@ jwt.jwtExpirationInMs=7776000000 spring.application.name=infocad #logging.file.name=fiscad.log logging.level.org.springframework.security=DEBUG -app.sourcemind.env.defaultpassword=1234567890 + app.sourcemind.env.resetlink=http://localhost:4200/reset-password/ spring.mail.host=sandbox.smtp.mailtrap.io spring.mail.port=587 @@ -42,6 +42,13 @@ file.upload_dir=./uploads file.jasper-reports=./jasperReport logging.file.name=/app/logs/fiscad.log +#app.abs.env.defaultpassword = 1234567890 + +#app.abs.env.defaultuser = infocad_admin + +app.default-user.username=${DEFAULT_USER_NAME:} +app.default-user.password=${DEFAULT_USER_PASSWORD:} + app.upload.root=${file.upload_dir} app.upload.zips.received=${app.upload.root}/zips/received app.upload.zips.done=${app.upload.root}/zips/done From 4075fba99b4f006bf4b01d2808866e5345bfc4a3 Mon Sep 17 00:00:00 2001 From: Aurince AKAKPO Date: Wed, 17 Dec 2025 15:11:49 +0100 Subject: [PATCH 2/2] =?UTF-8?q?revu=20des=20secrets=20et=20.env=20pour=20d?= =?UTF-8?q?iff=C3=A9rencier?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index aeb74ae..d15810e 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ fiscad.log* .DS_Store target/* ansible -secrets/ \ No newline at end of file +secrets/ +.env \ No newline at end of file