169 lines
6.7 KiB
Bash
Executable File
169 lines
6.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# =============================================================================
|
|
# Neutralisation des comptes de demonstration -- OUTIL DE SECOURS ET D'AUDIT
|
|
# =============================================================================
|
|
#
|
|
# LE CAS NOMINAL N'A PLUS BESOIN DE CE SCRIPT.
|
|
#
|
|
# Le traitement est desormais fait par les migrations, donc automatiquement et
|
|
# sans risque d'oubli :
|
|
#
|
|
# 1730000000007-SeedTestUsers ne s'execute plus en
|
|
# production (APP_ENV)
|
|
# 1756000000000-NeutralizeSeedAccountsInProduction filet de securite
|
|
# 1756000000001-BootstrapAdminFromEnv cree VOTRE administrateur
|
|
#
|
|
# Ce script reste utile dans trois situations :
|
|
#
|
|
# - une base de production migree AVANT l'ajout de la garde APP_ENV ;
|
|
# - un deploiement ou APP_ENV n'etait pas correctement positionne (le journal
|
|
# du Job de migration affiche alors "Seeded test users successfully") ;
|
|
# - une verification manuelle : il affiche l'etat des comptes sans rien
|
|
# changer s'il n'y a rien a changer.
|
|
#
|
|
# ssh deploy@<db-01>
|
|
# sudo bash /opt/xpeditis/infra-prod/scripts/harden-seed-data.sh
|
|
#
|
|
# RAPPEL DU PROBLEME
|
|
#
|
|
# La migration 1730000000007-SeedTestUsers cree trois comptes dont le mot de
|
|
# passe est ecrit en clair dans le depot :
|
|
#
|
|
# admin@xpeditis.com role ADMIN Password123!
|
|
# manager@xpeditis.com role MANAGER Password123!
|
|
# user@xpeditis.com role USER Password123!
|
|
#
|
|
# Sur une base de production, cela donne un acces complet a la plateforme a
|
|
# quiconque a lu le depot.
|
|
#
|
|
# SEULS les comptes dont le hash est encore celui de SeedTestUsers sont traites :
|
|
# un compte dont le mot de passe a ete change est un vrai compte, et le
|
|
# neutraliser verrouillerait l'administrateur reellement utilise. (Un compte
|
|
# remis a Password123! via "mot de passe oublie" aurait un autre sel : le test
|
|
# de connexion de preflight-check.sh le detecte.)
|
|
#
|
|
# Si le compte de demonstration est le SEUL administrateur actif, PostgreSQL
|
|
# refuse la neutralisation (declencheur trg_users_keep_active_admin, SQLSTATE
|
|
# XP001) et la transaction est annulee : creez ou promouvez d'abord votre
|
|
# administrateur, puis relancez ce script.
|
|
#
|
|
# Ce script ne SUPPRIME pas les lignes (des cles etrangeres peuvent y pointer,
|
|
# et une suppression en cascade dans audit_logs serait pire). Il :
|
|
# 1. renomme les adresses vers un domaine invalide -- ce qui libere au passage
|
|
# admin@xpeditis.com pour votre vrai compte ;
|
|
# 2. remplace le mot de passe par une valeur aleatoire inutilisable ;
|
|
# 3. desactive les comptes (is_active = false).
|
|
#
|
|
# Idempotent : peut etre relance sans risque.
|
|
set -euo pipefail
|
|
|
|
COMPOSE_DIR="${COMPOSE_DIR:-/opt/xpeditis/data-node}"
|
|
ENV_FILE="${ENV_FILE:-${COMPOSE_DIR}/.env.data}"
|
|
|
|
[[ -f "$ENV_FILE" ]] || { echo "Fichier d'environnement introuvable : $ENV_FILE" >&2; exit 1; }
|
|
# shellcheck disable=SC1090
|
|
set -a; source "$ENV_FILE"; set +a
|
|
|
|
psql_run() {
|
|
docker compose -f "${COMPOSE_DIR}/docker-compose.data.yml" --env-file "$ENV_FILE" \
|
|
exec -T -u postgres postgres psql -v ON_ERROR_STOP=1 -d "$POSTGRES_DB" "$@"
|
|
}
|
|
|
|
# Hash Argon2id de "Password123!" pose par la migration SeedTestUsers.
|
|
SEED_HASH='$argon2id$v=19$m=65536,t=3,p=4$Uj+yeQiaqgBFqyTJ5FX3Cw$wpRCYORyFwjQFSuO3gpmzh10gx9wjYFOCvVZ8TVaP8Q'
|
|
|
|
echo ">>> Etat avant intervention"
|
|
psql_run -v seed_hash="$SEED_HASH" <<'SQL'
|
|
SELECT email, role, is_active, password_hash = :'seed_hash' AS mot_de_passe_public
|
|
FROM users
|
|
WHERE email IN ('admin@xpeditis.com','manager@xpeditis.com','user@xpeditis.com');
|
|
SQL
|
|
|
|
echo
|
|
echo ">>> Neutralisation"
|
|
psql_run -v seed_hash="$SEED_HASH" <<'SQL'
|
|
BEGIN;
|
|
|
|
-- Mot de passe remplace par une valeur aleatoire : le format reste un hash
|
|
-- Argon2 valide en apparence, mais aucun mot de passe ne peut y correspondre.
|
|
UPDATE users
|
|
SET
|
|
email = 'seed-desactive-' || substr(id::text, 1, 8) || '@invalid.local',
|
|
-- md5(random()) plutot que gen_random_bytes : pas besoin de l'extension
|
|
-- pgcrypto, qui n'est pas installee sur cette base.
|
|
password_hash = '$argon2id$v=19$m=65536,t=3,p=4$' || md5(random()::text)
|
|
|| '$' || md5(random()::text) || md5(clock_timestamp()::text),
|
|
is_active = false,
|
|
updated_at = NOW()
|
|
WHERE email IN ('admin@xpeditis.com', 'manager@xpeditis.com', 'user@xpeditis.com')
|
|
AND password_hash = :'seed_hash';
|
|
|
|
COMMIT;
|
|
SQL
|
|
|
|
echo
|
|
echo ">>> Etat apres intervention"
|
|
psql_run -c "
|
|
SELECT email, role, is_active
|
|
FROM users
|
|
WHERE email LIKE 'seed-desactive-%@invalid.local';
|
|
"
|
|
|
|
echo
|
|
echo ">>> Controle : aucun compte ne doit garder le mot de passe public"
|
|
RESTE=$(psql_run -tA -v seed_hash="$SEED_HASH" <<'SQL'
|
|
SELECT count(*) FROM users
|
|
WHERE email IN ('admin@xpeditis.com','manager@xpeditis.com','user@xpeditis.com')
|
|
AND password_hash = :'seed_hash';
|
|
SQL
|
|
)
|
|
if [[ "$RESTE" != "0" ]]; then
|
|
echo "ECHEC : ${RESTE} compte(s) de demonstration acceptent encore Password123!." >&2
|
|
exit 1
|
|
fi
|
|
echo "OK : aucun compte de demonstration n'accepte le mot de passe public."
|
|
|
|
echo
|
|
echo ">>> Organisations de demonstration presentes (a examiner, non modifiees)"
|
|
# Non supprimees automatiquement : les comptes desactives y sont rattaches, et
|
|
# une suppression en cascade toucherait aussi audit_logs.
|
|
psql_run -c "
|
|
SELECT id, name, created_at
|
|
FROM organizations
|
|
WHERE name IN ('Test Freight Forwarder Inc.','Demo Shipping Company','Sample Shipper Ltd.');
|
|
"
|
|
|
|
cat <<'NEXT'
|
|
|
|
-----------------------------------------------------------------------------
|
|
Etape suivante : disposer d'un administrateur.
|
|
|
|
La migration 1756000000001-BootstrapAdminFromEnv s'en charge normalement, a
|
|
partir de BOOTSTRAP_ADMIN_EMAIL (ConfigMap). Si elle a ete ignoree parce qu'un
|
|
ADMIN actif existait alors -- typiquement le compte de demonstration que ce
|
|
script vient de neutraliser -- relancez simplement le Job de migration :
|
|
|
|
kubectl -n xpeditis-prod delete job -l app.kubernetes.io/name=xpeditis-migrate
|
|
# puis redeployez, ou rejouez le Job pour le tag courant
|
|
|
|
Elle ne rejouera pas les migrations deja appliquees ; pour forcer uniquement
|
|
l'amorcage, creez votre compte a la main :
|
|
|
|
1. Inscrivez-vous sur https://app.xpeditis.com/fr/register
|
|
2. Promouvez le compte :
|
|
UPDATE users SET role = 'ADMIN' WHERE email = '<votre adresse>';
|
|
|
|
Dans les deux cas, verifiez qu'il n'existe qu'un seul ADMIN actif :
|
|
|
|
SELECT email, role, is_active FROM users WHERE role = 'ADMIN';
|
|
|
|
Puis controlez depuis l'exterieur que l'ancien compte est bien mort :
|
|
|
|
curl -s -o /dev/null -w '%{http_code}\n' -X POST \
|
|
https://api.xpeditis.com/api/v1/auth/login \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"email":"admin@xpeditis.com","password":"Password123!"}'
|
|
# Attendu : 401 (et surtout pas 200 ni 201)
|
|
-----------------------------------------------------------------------------
|
|
NEXT
|