features/crud_entites #14

Merged
judaur2005 merged 2 commits from features/crud_entites into develop 2025-12-17 14:12:54 +00:00
11 changed files with 135 additions and 87 deletions

1
.env
View File

@@ -1,3 +1,2 @@
POSTGRES_DB=abomey_db POSTGRES_DB=abomey_db
POSTGRES_USER=infocad_user POSTGRES_USER=infocad_user
POSTGRES_PASSWORD=W5fwD({9*q53

View File

@@ -1,7 +1,7 @@
name: CD - Deploy on main name: CD - Deploy on main
on: on:
pull_request: push:
branches: branches:
- main - main
@@ -10,6 +10,7 @@ jobs:
runs-on: self-hosted runs-on: self-hosted
steps: steps:
# 1) S'assurer que Node.js est installé # 1) S'assurer que Node.js est installé
- name: Ensure Node.js is installed - name: Ensure Node.js is installed
shell: sh shell: sh
@@ -17,102 +18,97 @@ jobs:
if command -v node >/dev/null 2>&1; then if command -v node >/dev/null 2>&1; then
echo "Node.js already installed: $(node -v)" echo "Node.js already installed: $(node -v)"
else else
echo "Node.js not found, installing..."
apk update && apk add --no-cache nodejs apk update && apk add --no-cache nodejs
echo "Node.js installed: $(node -v)" echo "Node.js installed: $(node -v)"
fi 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 - name: Ensure Java & Maven are installed
shell: sh shell: sh
run: | run: |
if command -v java >/dev/null 2>&1; then if ! command -v java >/dev/null 2>&1; then
echo "Java already installed:"
java -version
else
echo "Java not found, installing OpenJDK 17..."
apk update && apk add --no-cache openjdk17-jdk apk update && apk add --no-cache openjdk17-jdk
echo "Java installed:" fi
java -version java -version
fi
if command -v mvn >/dev/null 2>&1; then if ! command -v mvn >/dev/null 2>&1; then
echo "Maven already installed:"
mvn -version
else
echo "Maven not found, installing Maven..."
apk update && apk add --no-cache maven apk update && apk add --no-cache maven
echo "Maven installed:"
mvn -version
fi fi
mvn -version
# 3) Détecter JAVA_HOME dynamiquement et le propager # 3) Détecter JAVA_HOME dynamiquement
- name: Detect JAVA_HOME dynamically - name: Detect JAVA_HOME dynamically
shell: sh shell: sh
run: | run: |
JAVA_BIN=$(readlink -f "$(command -v java)") JAVA_BIN=$(readlink -f "$(command -v java)")
JAVA_HOME=$(dirname "$(dirname "$JAVA_BIN")") JAVA_HOME=$(dirname "$(dirname "$JAVA_BIN")")
echo "Detected JAVA_HOME=$JAVA_HOME"
echo "JAVA_HOME=$JAVA_HOME" >> "$GITHUB_ENV" echo "JAVA_HOME=$JAVA_HOME" >> "$GITHUB_ENV"
# 4) Checkout du dépôt # 4) Checkout du dépôt
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v4
# 5) Afficher quelques infos utiles # 5) Informations de contexte (sans secrets)
- name: Show current commit and tools - name: Show context information
shell: sh shell: sh
run: | run: |
echo "Current commit:" echo "Commit:"
git rev-parse HEAD git rev-parse HEAD
echo "JAVA_HOME is: $JAVA_HOME" echo "JAVA_HOME=$JAVA_HOME"
java -version java -version
mvn -version mvn -version
# 6) S'assurer que le client Docker + docker-compose sont installés # 6) S'assurer que Docker CLI & docker-compose sont installés
- name: Ensure Docker CLI is installed - name: Ensure Docker & docker-compose are installed
shell: sh shell: sh
run: | run: |
if command -v docker >/dev/null 2>&1; then if command -v docker >/dev/null 2>&1; then
echo "Docker CLI already installed:"
docker version || true docker version || true
else else
echo "Docker CLI not found, installing..."
apk update && apk add --no-cache docker docker-compose apk update && apk add --no-cache docker docker-compose
echo "Docker CLI installed:"
docker version || true docker version || true
fi fi
# 7) Générer le .env utilisé par docker-compose-prod.yml # 7) Fournir la configuration NON sensible (OBLIGATOIRE)
- name: Generate .env from Gitea secrets # (POSTGRES_DB et POSTGRES_USER ne sont PAS des secrets)
- name: Export database configuration
shell: sh shell: sh
run: | run: |
cat > .env <<EOF echo "POSTGRES_DB_FISCAD=fiscad_db" >> "$GITHUB_ENV"
POSTGRES_DB_FISCAD=${{ secrets.POSTGRES_DB_FISCAD }} echo "POSTGRES_USER_FISCAD=fiscad_user" >> "$GITHUB_ENV"
POSTGRES_USER_FISCAD=${{ secrets.POSTGRES_USER_FISCAD }}
POSTGRES_PASSWORD_FISCAD=${{ secrets.POSTGRES_PASSWORD_FISCAD }}
EOF
echo "Generated .env:"
cat .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 - name: Build backend with Maven
shell: sh 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) - name: Deploy using docker-compose (prod)
shell: sh shell: sh
run: | run: |
# IMPORTANT : on fixe le nom du projet compose
export COMPOSE_PROJECT_NAME=fiscad 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 pull || true
docker-compose -f docker-compose-prod.yml down --remove-orphans docker-compose -f docker-compose-prod.yml down --remove-orphans
docker-compose -f docker-compose-prod.yml up -d --build docker-compose -f docker-compose-prod.yml up -d --build
# 10) Nettoyage des images non utilisées # 11) Nettoyage des secrets (OBLIGATOIRE)
- name: Cleanup unused images - 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 shell: sh
run: docker image prune -f || true run: docker image prune -f || true

View File

@@ -10,64 +10,69 @@ jobs:
runs-on: self-hosted runs-on: self-hosted
steps: 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 - name: Ensure Node.js is installed
shell: sh shell: sh
run: | run: |
if command -v node >/dev/null 2>&1; then if command -v node >/dev/null 2>&1; then
echo "Node.js already installed: $(node -v)" echo "Node.js already installed: $(node -v)"
else else
echo "Node.js not found, installing..."
apk update && apk add --no-cache nodejs apk update && apk add --no-cache nodejs
echo "Node.js installed: $(node -v)" echo "Node.js installed: $(node -v)"
fi fi
# 2) S'assurer que Java + Maven sont installés # 2) Java & Maven
- name: Ensure Java & Maven are installed - name: Ensure Java & Maven are installed
shell: sh shell: sh
run: | run: |
if command -v java >/dev/null 2>&1; then if ! command -v java >/dev/null 2>&1; then
echo "Java already installed:"
java -version
else
echo "Java not found, installing OpenJDK 17..."
apk update && apk add --no-cache openjdk17-jdk apk update && apk add --no-cache openjdk17-jdk
echo "Java installed:" fi
java -version java -version
fi
if command -v mvn >/dev/null 2>&1; then if ! command -v mvn >/dev/null 2>&1; then
echo "Maven already installed:"
mvn -version
else
echo "Maven not found, installing Maven..."
apk update && apk add --no-cache maven apk update && apk add --no-cache maven
echo "Maven installed:"
mvn -version
fi fi
mvn -version
# 3) Détecter automatiquement JAVA_HOME et le propager au reste du job # 3) JAVA_HOME
- name: Detect JAVA_HOME dynamically - name: Detect JAVA_HOME dynamically
shell: sh shell: sh
run: | run: |
JAVA_BIN=$(readlink -f "$(command -v java)") JAVA_BIN=$(readlink -f "$(command -v java)")
JAVA_HOME=$(dirname "$(dirname "$JAVA_BIN")") JAVA_HOME=$(dirname "$(dirname "$JAVA_BIN")")
echo "Detected JAVA_HOME=$JAVA_HOME"
echo "JAVA_HOME=$JAVA_HOME" >> "$GITHUB_ENV" 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 - name: Checkout repository
uses: actions/checkout@v4 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 - name: Show Java & Maven versions
shell: sh shell: sh
run: | run: |
echo "JAVA_HOME is: $JAVA_HOME" echo "JAVA_HOME=$JAVA_HOME"
java -version java -version
mvn -version mvn -version
# 6) Build Maven # 7) Build & tests
- name: Build with Maven - name: Build with Maven
shell: sh shell: sh
run: mvn -B clean verify run: mvn -B clean verify
# 8) Nettoyage
- name: Cleanup secrets
if: always()
shell: sh
run: rm -rf secrets

2
.gitignore vendored
View File

@@ -3,3 +3,5 @@ fiscad.log*
.DS_Store .DS_Store
target/* target/*
ansible ansible
secrets/
.env

View File

@@ -9,7 +9,7 @@ services:
environment: environment:
POSTGRES_DB: ${POSTGRES_DB_FISCAD} POSTGRES_DB: ${POSTGRES_DB_FISCAD}
POSTGRES_USER: ${POSTGRES_USER_FISCAD} POSTGRES_USER: ${POSTGRES_USER_FISCAD}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD_FISCAD} POSTGRES_PASSWORD_FILE: /run/secrets/postgresPassword
ports: ports:
- "5432:5432" - "5432:5432"
volumes: volumes:
@@ -30,7 +30,7 @@ services:
environment: environment:
SPRING_DATASOURCE_URL: jdbc:postgresql://db:5432/${POSTGRES_DB_FISCAD} SPRING_DATASOURCE_URL: jdbc:postgresql://db:5432/${POSTGRES_DB_FISCAD}
SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER_FISCAD} SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER_FISCAD}
SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD_FISCAD} SPRING_DATASOURCE_PASSWORD_FILE: /run/secrets/postgresPassword
SERVER_PORT: 8282 SERVER_PORT: 8282
IO_GMSS_FISCAD_PROFILE: abomey IO_GMSS_FISCAD_PROFILE: abomey
SPRING_PROFILES_ACTIVE: abomey SPRING_PROFILES_ACTIVE: abomey

View File

@@ -6,41 +6,73 @@ services:
image: postgres:15 image: postgres:15
container_name: fiscad-db container_name: fiscad-db
restart: always restart: always
environment: environment:
POSTGRES_DB: ${POSTGRES_DB} POSTGRES_DB: ${POSTGRES_DB_FISCAD}
POSTGRES_USER: ${POSTGRES_USER} POSTGRES_USER: ${POSTGRES_USER_FISCAD}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_PASSWORD_FILE: /run/secrets/postgresPassword
secrets:
- postgresPassword
ports: ports:
- "5432:5432" - "5432:5432"
volumes: volumes:
- db-data:/var/lib/postgresql/data - db-data:/var/lib/postgresql/data
healthcheck: healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"] test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
interval: 10s interval: 10s
timeout: 5s timeout: 5s
retries: 5 retries: 5
app: app:
build: build:
context: . context: .
dockerfile: Dockerfile dockerfile: Dockerfile
container_name: fiscad-app container_name: fiscad-app
restart: on-failure
depends_on: depends_on:
- db - db
environment: environment:
SPRING_DATASOURCE_URL: jdbc:postgresql://db:5432/${POSTGRES_DB} SPRING_DATASOURCE_URL: jdbc:postgresql://db:5432/${POSTGRES_DB_FISCAD}
SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER} SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER_FISCAD}
SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD} SPRING_DATASOURCE_PASSWORD_FILE: /run/secrets/postgresPassword
SERVER_PORT: 8282 SERVER_PORT: 8282
IO_GMSS_FISCAD_PROFILE: dgi IO_GMSS_FISCAD_PROFILE: dgi
SPRING_PROFILES_ACTIVE: 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: ports:
- "8282:8282" - "8282:8282"
volumes: volumes:
- ./uploads:/app/uploads - ./uploads:/app/uploads
- ./jasperReport:/app/jasperReport - ./jasperReport:/app/jasperReport
- ./logs:/app/logs - ./logs:/app/logs
restart: on-failure
volumes: volumes:
db-data: db-data:
secrets:
defaultUserName:
file: ./secrets/defaultUserName.txt
defaultUserPassword:
file: ./secrets/defaultUserPassword.txt
postgresPassword:
file: ./secrets/postgresPassword.txt

View File

@@ -0,0 +1 @@
infocad_admin

View File

@@ -0,0 +1 @@
admin@123

View File

@@ -20,8 +20,11 @@ public class DataLoadConfig {
private final UserRepository userRepository; private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder; private final PasswordEncoder passwordEncoder;
@Value("${app.sourcemind.env.defaultpassword}") @Value("${DEFAULT_USER_NAME_FILE}")
private String defaultPassword; private String usernameFile;
@Value("${DEFAULT_USER_PASSWORD_FILE}")
private String passwordFile;
public DataLoadConfig(RoleRepository roleRepository, UserRepository userRepository, PasswordEncoder passwordEncoder) { public DataLoadConfig(RoleRepository roleRepository, UserRepository userRepository, PasswordEncoder passwordEncoder) {
this.roleRepository = roleRepository; this.roleRepository = roleRepository;
@@ -52,14 +55,14 @@ public class DataLoadConfig {
} }
public void loadUsers() { public void loadUsers() {
if (userRepository.countAllByUsernameIsNotNull() == 0) { if (userRepository.existsByUsername(usernameFile) ) {
User admin = new User(); User admin = new User();
admin.setUsername("administrateur@infocad.bj"); admin.setUsername(usernameFile);
admin.setEmail("administrateur@infocad.bj"); admin.setEmail("administrateur@infocad.bj");
admin.setTel("N/A"); admin.setTel("N/A");
admin.setNom("Administrateur"); admin.setNom("Administrateur");
admin.setPrenom("Principal"); admin.setPrenom("Principal");
admin.setPassword(passwordEncoder.encode(defaultPassword)); admin.setPassword(passwordEncoder.encode(passwordFile));
admin.setActive(true); admin.setActive(true);
Set<Role> roles = new HashSet<>(); Set<Role> roles = new HashSet<>();
roles.add(roleRepository.findRoleByNom(UserRole.ROLE_ADMIN).get()); roles.add(roleRepository.findRoleByNom(UserRole.ROLE_ADMIN).get());

View File

@@ -14,6 +14,8 @@ public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByUsername(String username); Optional<User> findByUsername(String username);
boolean existsByUsername(String username);
long countAllByUsernameIsNotNull(); long countAllByUsernameIsNotNull();
List<User> findAllByStructureAndRolesIn(Structure structure, Set<Role> roleSet); List<User> findAllByStructureAndRolesIn(Structure structure, Set<Role> roleSet);

View File

@@ -11,7 +11,7 @@ jwt.jwtExpirationInMs=7776000000
spring.application.name=infocad spring.application.name=infocad
#logging.file.name=fiscad.log #logging.file.name=fiscad.log
logging.level.org.springframework.security=DEBUG logging.level.org.springframework.security=DEBUG
app.sourcemind.env.defaultpassword=1234567890
app.sourcemind.env.resetlink=http://localhost:4200/reset-password/ app.sourcemind.env.resetlink=http://localhost:4200/reset-password/
spring.mail.host=sandbox.smtp.mailtrap.io spring.mail.host=sandbox.smtp.mailtrap.io
spring.mail.port=587 spring.mail.port=587
@@ -42,6 +42,13 @@ file.upload_dir=./uploads
file.jasper-reports=./jasperReport file.jasper-reports=./jasperReport
logging.file.name=/app/logs/fiscad.log 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.root=${file.upload_dir}
app.upload.zips.received=${app.upload.root}/zips/received app.upload.zips.received=${app.upload.root}/zips/received
app.upload.zips.done=${app.upload.root}/zips/done app.upload.zips.done=${app.upload.root}/zips/done