"""读取与更新 .env 配置""" import os import re from pathlib import Path from cryptography.fernet import Fernet from dotenv import load_dotenv, set_key from werkzeug.security import check_password_hash, generate_password_hash BASE_DIR = Path(__file__).resolve().parent ENV_FILE = BASE_DIR / ".env" def _valid_fernet_key(value: str) -> bool: if not value or "请" in value or len(value) < 40: return False try: Fernet(value.encode()) return True except (ValueError, Exception): return False def ensure_env(): if not ENV_FILE.exists(): example = BASE_DIR / ".env.example" if example.exists(): ENV_FILE.write_text(example.read_text(encoding="utf-8"), encoding="utf-8") else: ENV_FILE.write_text("", encoding="utf-8") load_dotenv(ENV_FILE, override=True) changed = False if not os.getenv("SECRET_KEY") or "请" in os.getenv("SECRET_KEY", ""): set_key(str(ENV_FILE), "SECRET_KEY", os.urandom(32).hex()) changed = True if not _valid_fernet_key(os.getenv("DATA_ENCRYPTION_KEY", "")): set_key(str(ENV_FILE), "DATA_ENCRYPTION_KEY", Fernet.generate_key().decode()) changed = True if not os.getenv("AUTH_USERNAME"): set_key(str(ENV_FILE), "AUTH_USERNAME", "admin") changed = True if not os.getenv("AUTH_PASSWORD"): set_key(str(ENV_FILE), "AUTH_PASSWORD", generate_password_hash("admin123")) changed = True if changed: load_dotenv(ENV_FILE, override=True) def reload_env(): load_dotenv(ENV_FILE, override=True) def get_secret_key(): return os.getenv("SECRET_KEY", "dev-insecure-key") def get_encryption_key(): raw = os.getenv("DATA_ENCRYPTION_KEY", "") if not raw: raise ValueError("缺少 DATA_ENCRYPTION_KEY,请检查 .env") return raw.encode() if isinstance(raw, str) else raw def get_auth_username(): return os.getenv("AUTH_USERNAME", "admin") def verify_password(plain: str) -> bool: stored = os.getenv("AUTH_PASSWORD", "") if not stored: return False if stored.startswith("pbkdf2:") or stored.startswith("scrypt:"): return check_password_hash(stored, plain) return stored == plain def update_auth(username: str, password: str): ensure_env() set_key(str(ENV_FILE), "AUTH_USERNAME", username) set_key(str(ENV_FILE), "AUTH_PASSWORD", generate_password_hash(password)) reload_env()