refactorisation pour correction de sécurité
Tests / Backend Tests (Python) (3.10) (push) Has been cancelled
Tests / Backend Tests (Python) (3.11) (push) Has been cancelled
Tests / Backend Tests (Python) (3.12) (push) Has been cancelled
Tests / Frontend Tests (JS) (push) Has been cancelled
Tests / Integration Tests (push) Has been cancelled
Tests / All Tests Passed (push) Has been cancelled
Tests / Backend Tests (Python) (3.10) (push) Has been cancelled
Tests / Backend Tests (Python) (3.11) (push) Has been cancelled
Tests / Backend Tests (Python) (3.12) (push) Has been cancelled
Tests / Frontend Tests (JS) (push) Has been cancelled
Tests / Integration Tests (push) Has been cancelled
Tests / All Tests Passed (push) Has been cancelled
This commit is contained in:
@@ -12,6 +12,7 @@ from time import perf_counter
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
import yaml
|
||||
from cachetools import TTLCache
|
||||
|
||||
from app.core.config import settings
|
||||
from app.schemas.host_api import AnsibleInventoryHost
|
||||
@@ -28,27 +29,23 @@ class AnsibleService:
|
||||
self.ssh_key_path = ssh_key_path or settings.ssh_key_path
|
||||
self.ssh_user = ssh_user or settings.ssh_user
|
||||
|
||||
# Cache
|
||||
self._inventory_cache: Optional[Dict] = None
|
||||
self._inventory_cache_time: float = 0
|
||||
self._playbooks_cache: Optional[List[PlaybookInfo]] = None
|
||||
self._playbooks_cache_time: float = 0
|
||||
self._cache_ttl = settings.inventory_cache_ttl
|
||||
# Cache with automatic TTL eviction (replaces hand-rolled cache)
|
||||
cache_ttl = settings.inventory_cache_ttl
|
||||
self._inventory_cache: TTLCache = TTLCache(maxsize=16, ttl=cache_ttl)
|
||||
self._playbooks_cache: TTLCache = TTLCache(maxsize=16, ttl=cache_ttl)
|
||||
|
||||
def invalidate_cache(self):
|
||||
"""Invalide les caches."""
|
||||
self._inventory_cache = None
|
||||
self._playbooks_cache = None
|
||||
self._inventory_cache.clear()
|
||||
self._playbooks_cache.clear()
|
||||
|
||||
# ===== PLAYBOOKS =====
|
||||
|
||||
def get_playbooks(self) -> List[Dict[str, Any]]:
|
||||
"""Récupère la liste des playbooks disponibles."""
|
||||
import time
|
||||
current_time = time.time()
|
||||
|
||||
if self._playbooks_cache and (current_time - self._playbooks_cache_time) < self._cache_ttl:
|
||||
return self._playbooks_cache
|
||||
cache_key = "all"
|
||||
if cache_key in self._playbooks_cache:
|
||||
return self._playbooks_cache[cache_key]
|
||||
|
||||
playbooks = []
|
||||
|
||||
@@ -78,8 +75,7 @@ class AnsibleService:
|
||||
if pb:
|
||||
playbooks.append(pb)
|
||||
|
||||
self._playbooks_cache = playbooks
|
||||
self._playbooks_cache_time = current_time
|
||||
self._playbooks_cache[cache_key] = playbooks
|
||||
return playbooks
|
||||
|
||||
def _parse_playbook_file(self, file_path: Path, category: str, subcategory: str) -> Optional[Dict[str, Any]]:
|
||||
@@ -179,11 +175,9 @@ class AnsibleService:
|
||||
|
||||
def load_inventory(self) -> Dict:
|
||||
"""Charge l'inventaire Ansible depuis le fichier YAML."""
|
||||
import time
|
||||
current_time = time.time()
|
||||
|
||||
if self._inventory_cache and (current_time - self._inventory_cache_time) < self._cache_ttl:
|
||||
return self._inventory_cache
|
||||
cache_key = "inventory"
|
||||
if cache_key in self._inventory_cache:
|
||||
return self._inventory_cache[cache_key]
|
||||
|
||||
if not self.inventory_path.exists():
|
||||
return {}
|
||||
@@ -191,8 +185,7 @@ class AnsibleService:
|
||||
try:
|
||||
with open(self.inventory_path, 'r', encoding='utf-8') as f:
|
||||
inventory = yaml.safe_load(f) or {}
|
||||
self._inventory_cache = inventory
|
||||
self._inventory_cache_time = current_time
|
||||
self._inventory_cache[cache_key] = inventory
|
||||
return inventory
|
||||
except Exception:
|
||||
return {}
|
||||
@@ -204,8 +197,8 @@ class AnsibleService:
|
||||
with open(self.inventory_path, 'w', encoding='utf-8') as f:
|
||||
yaml.dump(inventory, f, default_flow_style=False, allow_unicode=True)
|
||||
|
||||
# Invalider le cache
|
||||
self._inventory_cache = None
|
||||
# Invalider le cache inventaire
|
||||
self._inventory_cache.clear()
|
||||
|
||||
def get_hosts_from_inventory(self, group_filter: str = None) -> List[AnsibleInventoryHost]:
|
||||
"""Récupère les hôtes depuis l'inventaire Ansible."""
|
||||
|
||||
@@ -11,15 +11,16 @@ from datetime import datetime, timedelta, timezone
|
||||
from typing import Optional
|
||||
|
||||
import bcrypt
|
||||
from jose import JWTError, jwt
|
||||
import jwt
|
||||
|
||||
from app.core.config import settings
|
||||
from app.models.user import User
|
||||
from app.schemas.auth import TokenData
|
||||
|
||||
# Configuration from environment variables
|
||||
SECRET_KEY = os.environ.get("JWT_SECRET_KEY", "homelab-secret-key-change-in-production")
|
||||
ALGORITHM = "HS256"
|
||||
ACCESS_TOKEN_EXPIRE_MINUTES = int(os.environ.get("JWT_EXPIRE_MINUTES", "1440")) # 24 hours default
|
||||
# Configuration from centralized settings (single source of truth)
|
||||
SECRET_KEY = settings.jwt_secret_key
|
||||
ALGORITHM = settings.jwt_algorithm
|
||||
ACCESS_TOKEN_EXPIRE_MINUTES = settings.jwt_expire_minutes
|
||||
|
||||
|
||||
class AuthService:
|
||||
@@ -83,7 +84,7 @@ class AuthService:
|
||||
return None
|
||||
|
||||
return TokenData(username=username, user_id=user_id, role=role)
|
||||
except JWTError:
|
||||
except (jwt.PyJWTError, jwt.ExpiredSignatureError, jwt.DecodeError):
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
|
||||
Reference in New Issue
Block a user