mirror of
https://github.com/MaksTinyWorkshop/_Assistant_Lead_Tech
synced 2026-04-06 21:41:42 +02:00
Maj Scripts vers BitWarden
This commit is contained in:
@@ -1 +1 @@
|
|||||||
/srv/helpers/_Assistant_Lead_Tech/CLAUDE.md
|
/Users/maks/AI_RULES/_Assistant_Lead_Tech/CLAUDE.md
|
||||||
@@ -29,11 +29,11 @@ alias bmad-init="\"\$LEADTECH/scripts/bmad-init-project.sh\""
|
|||||||
|
|
||||||
alias projects='cd /Volumes/TeraSSD/Projets_Dev 2>/dev/null || cd /srv/projects'
|
alias projects='cd /Volumes/TeraSSD/Projets_Dev 2>/dev/null || cd /srv/projects'
|
||||||
|
|
||||||
# Load global secrets (KeePass → env)
|
# Load global secrets (Bitwarden → env)
|
||||||
alias loadg="source \"\$LEADTECH/scripts/load-global-secrets.sh\""
|
alias loadg="source \"\$LEADTECH/scripts/load-global-secrets.sh\""
|
||||||
|
|
||||||
# Sync service secrets (KeePass → service.env)
|
# Sync service secrets (Bitwarden → service.env)
|
||||||
alias sync-service="source \"\$LEADTECH/scripts/sync-service-secrets.sh\""
|
alias sync-service="source \"\$LEADTECH/scripts/sync-service-secrets.sh\""
|
||||||
|
|
||||||
# Sync project secrets (KeePass → .env du projet courant)
|
# Sync project secrets (Bitwarden → .env du projet courant)
|
||||||
alias sync-project="source \"\$LEADTECH/scripts/sync-project-secrets.sh\""
|
alias sync-project="source \"\$LEADTECH/scripts/sync-project-secrets.sh\""
|
||||||
|
|||||||
@@ -1,16 +1,4 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
case "$(uname -s)" in
|
export BW_SERVER_URL="https://vaultwarden.wyvern-snapper.ts.net"
|
||||||
Darwin)
|
export AUTO_SCRIPTS_DIR="$HOME/.config/auto-secrets"
|
||||||
export SECRETS_KDBX="/Volumes/TeraSSD/Max_Perso/Pièces Importantes/MDPs/env_and_co.kdbx"
|
|
||||||
export AUTO_SCRIPTS_DIR="$HOME/AI_RULES/Auto_scripts"
|
|
||||||
;;
|
|
||||||
Linux)
|
|
||||||
export SECRETS_KDBX="$HOME/.config/auto-secrets/env_and_co.kdbx"
|
|
||||||
export AUTO_SCRIPTS_DIR="$HOME/.config/auto-secrets"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "OS non supporté" >&2
|
|
||||||
return 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|||||||
@@ -3,48 +3,56 @@
|
|||||||
_load_global_secrets() {
|
_load_global_secrets() {
|
||||||
source "$LEADTECH/scripts/env_paths.sh" || { echo "env_paths.sh introuvable" >&2; return 1; }
|
source "$LEADTECH/scripts/env_paths.sh" || { echo "env_paths.sh introuvable" >&2; return 1; }
|
||||||
|
|
||||||
if [ ! -f "$SECRETS_KDBX" ]; then
|
if ! command -v bw >/dev/null 2>&1; then
|
||||||
echo "Coffre introuvable : $SECRETS_KDBX" >&2
|
echo "bw (Bitwarden CLI) introuvable" >&2
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! command -v keepassxc-cli >/dev/null 2>&1; then
|
# Configurer le serveur si pas déjà fait
|
||||||
echo "keepassxc-cli introuvable" >&2
|
bw config server "$BW_SERVER_URL" >/dev/null 2>&1
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "${KDBX_PASSWORD:-}" ]; then
|
# Demander le master password si pas en variable
|
||||||
printf "Mot de passe KeePassXC : " >&2
|
if [ -z "${BW_MASTER_PASSWORD:-}" ]; then
|
||||||
|
printf "Master password Bitwarden : " >&2
|
||||||
stty -echo
|
stty -echo
|
||||||
IFS= read -r KDBX_PASSWORD
|
IFS= read -r BW_MASTER_PASSWORD
|
||||||
stty echo
|
stty echo
|
||||||
printf '\n' >&2
|
printf '\n' >&2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Unlock et récupérer le session token
|
||||||
|
local session
|
||||||
|
session=$(BW_MASTER_PASSWORD="$BW_MASTER_PASSWORD" bw unlock --passwordenv BW_MASTER_PASSWORD --raw 2>/dev/null)
|
||||||
|
if [ -z "$session" ]; then
|
||||||
|
echo "Échec du déverrouillage Bitwarden." >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
export BW_SESSION="$session"
|
||||||
|
|
||||||
echo "Chargement des secrets globaux..." >&2
|
echo "Chargement des secrets globaux..." >&2
|
||||||
|
|
||||||
local csv
|
# Récupérer l'id du dossier "global"
|
||||||
csv=$(printf '%s\n' "$KDBX_PASSWORD" | keepassxc-cli export --format csv "$SECRETS_KDBX" 2>/dev/null) || {
|
local folder_id
|
||||||
echo "Impossible d'exporter le coffre." >&2
|
folder_id=$(bw list folders --session "$BW_SESSION" 2>/dev/null \
|
||||||
|
| python3 -c "import sys,json; folders=json.load(sys.stdin); print(next((f['id'] for f in folders if f['name']=='global'), ''))")
|
||||||
|
|
||||||
|
if [ -z "$folder_id" ]; then
|
||||||
|
echo "Dossier 'global' introuvable dans Bitwarden." >&2
|
||||||
return 1
|
return 1
|
||||||
}
|
fi
|
||||||
|
|
||||||
|
# Lister les items du dossier et extraire TITRE=password
|
||||||
local pairs
|
local pairs
|
||||||
pairs=$(printf '%s' "$csv" | python3 -c "
|
pairs=$(bw list items --folderid "$folder_id" --session "$BW_SESSION" 2>/dev/null \
|
||||||
import sys, csv, re, io
|
| python3 -c "
|
||||||
|
import sys, json, re
|
||||||
|
|
||||||
raw = sys.stdin.read()
|
items = json.load(sys.stdin)
|
||||||
start = raw.find('\"Group\"')
|
for item in items:
|
||||||
if start == -1:
|
title = item.get('name', '')
|
||||||
sys.exit(0)
|
password = (item.get('login') or {}).get('password') or ''
|
||||||
reader = csv.DictReader(io.StringIO(raw[start:]))
|
password = password.strip()
|
||||||
for row in reader:
|
if not re.match(r'^[A-Z_][A-Z0-9_]*$', title):
|
||||||
group = row.get('Group', '')
|
|
||||||
title = row.get('Title', '')
|
|
||||||
password = row.get('Password', '')
|
|
||||||
if group != 'Racine/global' and not group.startswith('Racine/global/'):
|
|
||||||
continue
|
|
||||||
if not re.match(r'^[A-Z_][A-Z0-9_]*\$', title):
|
|
||||||
continue
|
continue
|
||||||
if not password:
|
if not password:
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -3,64 +3,67 @@
|
|||||||
_sync_project_secrets() {
|
_sync_project_secrets() {
|
||||||
source "$LEADTECH/scripts/env_paths.sh" || { echo "env_paths.sh introuvable" >&2; return 1; }
|
source "$LEADTECH/scripts/env_paths.sh" || { echo "env_paths.sh introuvable" >&2; return 1; }
|
||||||
|
|
||||||
if [ ! -f "$SECRETS_KDBX" ]; then
|
if ! command -v bw >/dev/null 2>&1; then
|
||||||
echo "Coffre introuvable : $SECRETS_KDBX" >&2
|
echo "bw (Bitwarden CLI) introuvable" >&2
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! command -v keepassxc-cli >/dev/null 2>&1; then
|
bw config server "$BW_SERVER_URL" >/dev/null 2>&1
|
||||||
echo "keepassxc-cli introuvable" >&2
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! command -v expect >/dev/null 2>&1; then
|
|
||||||
echo "expect introuvable" >&2
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Nom du projet = nom du dossier courant
|
|
||||||
local project_name
|
local project_name
|
||||||
project_name="$(basename "$PWD")"
|
project_name="$(basename "$PWD")"
|
||||||
local entry_path="projects/$project_name"
|
|
||||||
local target_file="$PWD/.env"
|
local target_file="$PWD/.env"
|
||||||
|
|
||||||
echo "Projet détecté : $project_name" >&2
|
echo "Projet détecté : $project_name" >&2
|
||||||
echo "Entrée KeePass : $entry_path" >&2
|
|
||||||
|
|
||||||
if [ -z "${KDBX_PASSWORD:-}" ]; then
|
# Unlock si pas de session active
|
||||||
printf "Mot de passe KeePassXC : " >&2
|
if [ -z "${BW_SESSION:-}" ]; then
|
||||||
stty -echo
|
if [ -z "${BW_MASTER_PASSWORD:-}" ]; then
|
||||||
IFS= read -r KDBX_PASSWORD
|
printf "Master password Bitwarden : " >&2
|
||||||
stty echo
|
stty -echo
|
||||||
printf '\n' >&2
|
IFS= read -r BW_MASTER_PASSWORD
|
||||||
|
stty echo
|
||||||
|
printf '\n' >&2
|
||||||
|
fi
|
||||||
|
BW_SESSION=$(BW_MASTER_PASSWORD="$BW_MASTER_PASSWORD" bw unlock --passwordenv BW_MASTER_PASSWORD --raw 2>/dev/null)
|
||||||
|
if [ -z "$BW_SESSION" ]; then
|
||||||
|
echo "Échec du déverrouillage Bitwarden." >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
export BW_SESSION
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Récupération des secrets projet..." >&2
|
echo "Récupération des secrets projet..." >&2
|
||||||
|
|
||||||
# Lire le champ Notes de l'entrée — une seule ouverture du coffre
|
# Récupérer l'id du dossier "projects/<project_name>"
|
||||||
local notes
|
local folder_name="projects/$project_name"
|
||||||
notes=$(KDBX_PASSWORD="$KDBX_PASSWORD" SECRETS_KDBX="$SECRETS_KDBX" ENTRY_PATH="$entry_path" expect <<'EOF'
|
local folder_id
|
||||||
log_user 0
|
folder_id=$(bw list folders --session "$BW_SESSION" 2>/dev/null \
|
||||||
set timeout 15
|
| python3 -c "import sys,json; folders=json.load(sys.stdin); print(next((f['id'] for f in folders if f['name']=='$folder_name'), ''))")
|
||||||
spawn keepassxc-cli show -a notes $env(SECRETS_KDBX) $env(ENTRY_PATH)
|
|
||||||
expect "Saisir le mot de passe pour déverrouiller*"
|
|
||||||
send -- "$env(KDBX_PASSWORD)\r"
|
|
||||||
expect eof
|
|
||||||
catch wait result
|
|
||||||
puts -nonewline $expect_out(buffer)
|
|
||||||
exit [lindex $result 3]
|
|
||||||
EOF
|
|
||||||
) || {
|
|
||||||
echo "Impossible de lire l'entrée '$entry_path'." >&2
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
if [ -z "$notes" ]; then
|
if [ -z "$folder_id" ]; then
|
||||||
echo "Le champ Notes est vide pour '$project_name'." >&2
|
echo "Dossier '$folder_name' introuvable dans Bitwarden." >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Chercher l'item dont le nom == project_name dans ce dossier
|
||||||
|
local notes
|
||||||
|
notes=$(bw list items --folderid "$folder_id" --session "$BW_SESSION" 2>/dev/null \
|
||||||
|
| python3 -c "
|
||||||
|
import sys, json
|
||||||
|
|
||||||
|
items = json.load(sys.stdin)
|
||||||
|
for item in items:
|
||||||
|
if item.get('name') == '$project_name':
|
||||||
|
print((item.get('notes') or '').strip())
|
||||||
|
break
|
||||||
|
")
|
||||||
|
|
||||||
|
if [ -z "$notes" ]; then
|
||||||
|
echo "Aucune note trouvée pour '$project_name' dans Bitwarden." >&2
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Écrire le .env
|
|
||||||
printf '%s\n' "$notes" > "$target_file"
|
printf '%s\n' "$notes" > "$target_file"
|
||||||
chmod 600 "$target_file"
|
chmod 600 "$target_file"
|
||||||
|
|
||||||
|
|||||||
@@ -3,53 +3,59 @@
|
|||||||
_sync_service_secrets() {
|
_sync_service_secrets() {
|
||||||
source "$LEADTECH/scripts/env_paths.sh" || { echo "env_paths.sh introuvable" >&2; return 1; }
|
source "$LEADTECH/scripts/env_paths.sh" || { echo "env_paths.sh introuvable" >&2; return 1; }
|
||||||
|
|
||||||
if [ ! -f "$SECRETS_KDBX" ]; then
|
if ! command -v bw >/dev/null 2>&1; then
|
||||||
echo "Coffre introuvable : $SECRETS_KDBX" >&2
|
echo "bw (Bitwarden CLI) introuvable" >&2
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! command -v keepassxc-cli >/dev/null 2>&1; then
|
bw config server "$BW_SERVER_URL" >/dev/null 2>&1
|
||||||
echo "keepassxc-cli introuvable" >&2
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
local target_file="$HOME/.config/auto-secrets/service.env"
|
local target_file="$AUTO_SCRIPTS_DIR/service.env"
|
||||||
mkdir -p "$(dirname "$target_file")"
|
mkdir -p "$(dirname "$target_file")"
|
||||||
touch "$target_file"
|
touch "$target_file"
|
||||||
chmod 600 "$target_file"
|
chmod 600 "$target_file"
|
||||||
|
|
||||||
if [ -z "${KDBX_PASSWORD:-}" ]; then
|
# Unlock si pas de session active
|
||||||
printf "Mot de passe KeePassXC : " >&2
|
if [ -z "${BW_SESSION:-}" ]; then
|
||||||
stty -echo
|
if [ -z "${BW_MASTER_PASSWORD:-}" ]; then
|
||||||
IFS= read -r KDBX_PASSWORD
|
printf "Master password Bitwarden : " >&2
|
||||||
stty echo
|
stty -echo
|
||||||
printf '\n' >&2
|
IFS= read -r BW_MASTER_PASSWORD
|
||||||
|
stty echo
|
||||||
|
printf '\n' >&2
|
||||||
|
fi
|
||||||
|
BW_SESSION=$(BW_MASTER_PASSWORD="$BW_MASTER_PASSWORD" bw unlock --passwordenv BW_MASTER_PASSWORD --raw 2>/dev/null)
|
||||||
|
if [ -z "$BW_SESSION" ]; then
|
||||||
|
echo "Échec du déverrouillage Bitwarden." >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
export BW_SESSION
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Sync des secrets de service..." >&2
|
echo "Sync des secrets de service..." >&2
|
||||||
|
|
||||||
local csv
|
# Récupérer l'id du dossier "services"
|
||||||
csv=$(printf '%s\n' "$KDBX_PASSWORD" | keepassxc-cli export --format csv "$SECRETS_KDBX" 2>/dev/null) || {
|
local folder_id
|
||||||
echo "Impossible d'exporter le coffre." >&2
|
folder_id=$(bw list folders --session "$BW_SESSION" 2>/dev/null \
|
||||||
|
| python3 -c "import sys,json; folders=json.load(sys.stdin); print(next((f['id'] for f in folders if f['name']=='services'), ''))")
|
||||||
|
|
||||||
|
if [ -z "$folder_id" ]; then
|
||||||
|
echo "Dossier 'services' introuvable dans Bitwarden." >&2
|
||||||
return 1
|
return 1
|
||||||
}
|
fi
|
||||||
|
|
||||||
|
# Extraire TITRE=password pour chaque item dont le nom est une var d'env valide
|
||||||
local rendered_lines
|
local rendered_lines
|
||||||
rendered_lines=$(printf '%s' "$csv" | python3 -c "
|
rendered_lines=$(bw list items --folderid "$folder_id" --session "$BW_SESSION" 2>/dev/null \
|
||||||
import sys, csv, re, io
|
| python3 -c "
|
||||||
|
import sys, json, re
|
||||||
|
|
||||||
raw = sys.stdin.read()
|
items = json.load(sys.stdin)
|
||||||
start = raw.find('\"Group\"')
|
for item in items:
|
||||||
if start == -1:
|
title = item.get('name', '')
|
||||||
sys.exit(0)
|
password = (item.get('login') or {}).get('password') or ''
|
||||||
reader = csv.DictReader(io.StringIO(raw[start:]))
|
password = password.strip()
|
||||||
for row in reader:
|
if not re.match(r'^[A-Z_][A-Z0-9_]*$', title):
|
||||||
group = row.get('Group', '')
|
|
||||||
title = row.get('Title', '')
|
|
||||||
password = row.get('Password', '')
|
|
||||||
if group != 'Racine/services' and not group.startswith('Racine/services/'):
|
|
||||||
continue
|
|
||||||
if not re.match(r'^[A-Z_][A-Z0-9_]*\$', title):
|
|
||||||
continue
|
continue
|
||||||
if not password:
|
if not password:
|
||||||
continue
|
continue
|
||||||
|
|||||||
Reference in New Issue
Block a user