"""Effective Windows domain admin credentials (DB overrides env).""" from __future__ import annotations from dataclasses import dataclass from sqlalchemy.orm import Session from app.config import get_settings from app.models.ui_settings import UI_SETTINGS_ROW_ID, UiSettings @dataclass(frozen=True) class WinAdminConfig: user: str password: str source: str # env | db @property def configured(self) -> bool: return bool(self.user.strip() and self.password.strip()) def normalize_win_admin_user(user: str) -> str: """DOMAIN\\user — один обратный слэш; убрать лишнее экранирование из env/UI.""" text = user.strip() if not text: return "" text = text.replace("\\\\", "\\") if "\\" not in text and "@" not in text and "/" not in text: # NETBIOS\user без слэша — не трогаем (оператор допишет в UI) return text return text def _win_admin_from_env() -> WinAdminConfig: settings = get_settings() return WinAdminConfig( user=normalize_win_admin_user(settings.sac_win_admin_user), password=settings.sac_win_admin_password, source="env", ) def get_effective_win_admin_config(db: Session | None = None) -> WinAdminConfig: if db is None: from app.database import SessionLocal session = SessionLocal() try: return get_effective_win_admin_config(session) finally: session.close() row = db.get(UiSettings, UI_SETTINGS_ROW_ID) env_cfg = _win_admin_from_env() if row is None: return env_cfg user = normalize_win_admin_user((row.win_admin_user or "").strip() or env_cfg.user) password = (row.win_admin_password or "") or env_cfg.password has_db_values = bool((row.win_admin_user or "").strip() or (row.win_admin_password or "").strip()) return WinAdminConfig( user=user, password=password, source="db" if has_db_values else env_cfg.source, ) def upsert_win_admin_settings( db: Session, *, user: str | None = None, password: str | None = None, ) -> WinAdminConfig: row = db.get(UiSettings, UI_SETTINGS_ROW_ID) env_cfg = _win_admin_from_env() if row is None: row = UiSettings( id=UI_SETTINGS_ROW_ID, show_sidebar_system_stats=True, win_admin_user=env_cfg.user or None, win_admin_password=env_cfg.password or None, ) db.add(row) if user is not None and user.strip(): row.win_admin_user = normalize_win_admin_user(user) if password is not None and password.strip(): row.win_admin_password = password db.commit() db.refresh(row) return get_effective_win_admin_config(db)