Files
security-alert-center/backend/app/services/rdg_client_host.py
T
PapaTramp 75f4c475df feat: RDG qwinsta/logoff via WinRM on client workstation (0.11.6)
SAC resolves internal_ip to a registered Windows host and runs qwinsta/logoff synchronously over WinRM instead of queueing commands to the gateway agent.
2026-06-20 15:36:12 +10:00

51 lines
1.5 KiB
Python

"""Resolve RDG client workstation (session host) from event internal_ip."""
from __future__ import annotations
from sqlalchemy import or_, select
from sqlalchemy.orm import Session
from app.models import Event, Host
from app.services.rdg_session_flap import event_internal_ip
from app.services.winrm_connect import is_windows_host
class ClientWorkstationNotFoundError(Exception):
def __init__(self, internal_ip: str) -> None:
self.internal_ip = internal_ip
super().__init__(
f"Client workstation not found in SAC hosts for internal_ip={internal_ip}. "
"Ensure the PC is registered with matching ipv4."
)
def find_windows_host_by_ipv4(db: Session, ipv4: str) -> Host | None:
ip = (ipv4 or "").strip()
if not ip:
return None
rows = db.scalars(
select(Host)
.where(
Host.ipv4 == ip,
or_(
Host.os_family.ilike("windows"),
Host.product == "rdp-login-monitor",
),
)
.order_by(Host.last_seen_at.desc())
).all()
for host in rows:
if is_windows_host(host):
return host
return None
def resolve_client_workstation(db: Session, event: Event) -> Host:
internal_ip = event_internal_ip(event)
if not internal_ip:
raise ClientWorkstationNotFoundError("")
host = find_windows_host_by_ipv4(db, internal_ip)
if host is None:
raise ClientWorkstationNotFoundError(internal_ip)
return host