diff --git a/api_server.py b/api_server.py index 6506d9d..e18cd91 100644 --- a/api_server.py +++ b/api_server.py @@ -140,8 +140,10 @@ class EnvProcessor: self.variables = self._load_env_file(env_file) def _load_env_file(self, env_file: Path) -> Dict[str, str]: - """Charge le fichier .env""" + """Charge uniquement le fichier .env principal (pas les sous-répertoires)""" variables = {} + + # Charger uniquement le fichier .env principal if env_file.exists(): try: with open(env_file, 'r', encoding='utf-8') as f: @@ -150,8 +152,13 @@ class EnvProcessor: if line and not line.startswith('#') and '=' in line: key, value = line.split('=', 1) variables[key.strip()] = value.strip() + logger.info(f"Variables chargées depuis {env_file}: {len(variables)} variables") except Exception as e: logger.error(f"Erreur lors du chargement du fichier .env: {e}") + + # Note: Les fichiers .env des sous-répertoires ne sont PAS chargés + # car ils sont des configurations spécifiques aux services, pas des variables globales + return variables def _resolve_variable(self, var_name: str, visited: set = None) -> str: @@ -161,34 +168,54 @@ class EnvProcessor: if var_name in visited: logger.warning(f"Dépendance circulaire détectée pour {var_name}") - return f"${{{var_name}}}" + return f"${var_name}" if var_name not in self.variables: logger.warning(f"Variable non trouvée: {var_name}") - return f"${{{var_name}}}" + return f"${var_name}" visited.add(var_name) value = self.variables[var_name] - # Traitement des sous-variables - pattern = r'\$\{([^}]+)\}' - matches = re.findall(pattern, value) + # Traitement des sous-variables avec ${VAR} + pattern1 = r'\$\{([^}]+)\}' + matches1 = re.findall(pattern1, value) - for match in matches: + for match in matches1: resolved_value = self._resolve_variable(match, visited.copy()) value = value.replace(f"${{{match}}}", resolved_value) + # Traitement des sous-variables avec $VAR + pattern2 = r'\$([A-Za-z_][A-Za-z0-9_]*)' + matches2 = re.findall(pattern2, value) + + for match in matches2: + if match != var_name: # Éviter l'auto-référence + resolved_value = self._resolve_variable(match, visited.copy()) + value = value.replace(f"${match}", resolved_value) + return value def process_content(self, content: str) -> str: """Traite le contenu en résolvant les variables""" - pattern = r'\$\{([^}]+)\}' - matches = re.findall(pattern, content) + # Pattern pour ${VARIABLE} + pattern1 = r'\$\{([^}]+)\}' + matches1 = re.findall(pattern1, content) - for var_name in matches: + for var_name in matches1: resolved_value = self._resolve_variable(var_name) content = content.replace(f"${{{var_name}}}", resolved_value) + # Pattern pour $VARIABLE (syntaxe simple) + pattern2 = r'\$([A-Za-z_][A-Za-z0-9_]*)' + matches2 = re.findall(pattern2, content) + + for var_name in matches2: + # Éviter les variables déjà traitées avec ${} + if f"${{{var_name}}}" not in content: + resolved_value = self._resolve_variable(var_name) + content = content.replace(f"${var_name}", resolved_value) + return content class SecureVaultAPI: @@ -196,8 +223,18 @@ class SecureVaultAPI: def __init__(self): self.app = Flask(__name__) + # Initialisation des processeurs d'environnement pour chaque env + self.env_processors = {} self._setup_routes() + def _get_env_processor(self, env: str) -> EnvProcessor: + """Obtient le processeur d'environnement pour un environnement donné""" + if env not in self.env_processors: + env_file = STORAGE_ROOT / env / '.env' + self.env_processors[env] = EnvProcessor(env_file) + logger.info(f"Processeur d'environnement initialisé pour {env}") + return self.env_processors[env] + def _setup_routes(self): """Configure les routes de l'API""" @@ -338,8 +375,9 @@ class SecureVaultAPI: if file_content is None: return jsonify({"error": f"Fichier non trouvé: {env}/{file_path}"}), 404 - # Contenu du fichier sans traitement de variables d'environnement - processed_content = file_content + # Traitement des variables d'environnement (en mémoire, sans modifier le fichier) + env_processor = self._get_env_processor(env) + processed_content = env_processor.process_content(file_content) # Chiffrement avec la clé utilisateur pour cet environnement encrypted_content, next_key = self._encrypt_with_user_key_and_next(processed_content, user_id, env) diff --git a/sdk-client/src/index.ts b/sdk-client/src/index.ts index 42f4ba2..79c24f8 100644 --- a/sdk-client/src/index.ts +++ b/sdk-client/src/index.ts @@ -542,7 +542,7 @@ export class SecureVaultClient { try { // Convertir la clé base64 en Uint8Array const key = Buffer.from(keyToUse, 'base64'); - + // Déchiffrement ChaCha20-Poly1305 avec @noble/ciphers const cipher = chacha20poly1305(key, nonce); const decrypted = cipher.decrypt(ciphertext);