patchcenter/app/services/secrets_service.py
Khalid MOUTAOUAKIL 8277653c43 PatchCenter v2.0 — Initial commit
Modules: Dashboard, Serveurs, Campagnes, Planning, Specifiques, Settings, Users
Stack: FastAPI + Jinja2 + HTMX + Alpine.js + TailwindCSS + PostgreSQL
Features: Qualys sync, prereqs auto, planning annuel, server specifics, role-based access

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 03:00:12 +02:00

65 lines
2.1 KiB
Python

"""Service secrets — chiffrement Fernet pour credentials en base"""
import os
import base64
from cryptography.fernet import Fernet
from sqlalchemy import text
from ..config import SECRET_KEY
# Derive une cle Fernet 32 bytes depuis SECRET_KEY
_raw = SECRET_KEY.encode()[:32].ljust(32, b'\0')
_fernet_key = base64.urlsafe_b64encode(_raw)
_fernet = Fernet(_fernet_key)
def encrypt(value: str) -> str:
return _fernet.encrypt(value.encode()).decode()
def decrypt(value: str) -> str:
return _fernet.decrypt(value.encode()).decode()
def get_secret(db, key: str) -> str | None:
"""Recupere et dechiffre un secret depuis app_secrets"""
row = db.execute(text("SELECT value FROM app_secrets WHERE key = :k"), {"k": key}).fetchone()
if not row:
return None
try:
return decrypt(row.value)
except Exception:
return None
def set_secret(db, key: str, value: str, description: str = ""):
"""Chiffre et stocke un secret dans app_secrets"""
enc = encrypt(value)
db.execute(text("""
INSERT INTO app_secrets (key, value, description, updated_at)
VALUES (:k, :v, :d, now())
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value,
description = EXCLUDED.description, updated_at = now()
"""), {"k": key, "v": enc, "d": description})
db.commit()
def list_secrets(db):
"""Liste les cles (sans valeurs) des secrets"""
rows = db.execute(text(
"SELECT key, description, updated_at FROM app_secrets ORDER BY key"
)).fetchall()
return rows
def init_secrets_from_config(db):
"""Initialise les secrets depuis config si pas encore en base"""
from ..config import QUALYS_URL, QUALYS_USER, QUALYS_PASS
defaults = {
"qualys_url": (QUALYS_URL, "URL API Qualys"),
"qualys_user": (QUALYS_USER, "Utilisateur Qualys"),
"qualys_pass": (QUALYS_PASS, "Mot de passe Qualys"),
"qualys_proxy": ("http://proxy.sanef.fr:8080", "Proxy Qualys"),
}
for key, (val, desc) in defaults.items():
if val and not get_secret(db, key):
set_secret(db, key, val, desc)