fix: show RDS break only on active or flap 302 events (0.3.4)
Hide Obryv RDS on 303 and on 302 after normal session end; keep for open sessions and RDG flap. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -9,7 +9,7 @@ from sqlalchemy.orm import Session
|
||||
from app.config import get_settings
|
||||
from app.models import Event
|
||||
from app.services.rdg_client_host import find_windows_host_by_ipv4
|
||||
from app.services.rdg_session_flap import event_internal_ip
|
||||
from app.services.rdg_session_flap import event_internal_ip, resolve_rdg_qwinsta_enabled
|
||||
|
||||
RDG_TYPES = frozenset(
|
||||
{
|
||||
@@ -115,7 +115,7 @@ def build_rdg_display(event: Event, db: Session | None = None) -> RdgDisplayInfo
|
||||
summary_parts.append(win_note)
|
||||
summary = " · ".join(summary_parts)
|
||||
|
||||
qwinsta_enabled = bool(internal_ip)
|
||||
qwinsta_enabled = resolve_rdg_qwinsta_enabled(db, event)
|
||||
|
||||
return RdgDisplayInfo(
|
||||
title=title,
|
||||
@@ -126,7 +126,7 @@ def build_rdg_display(event: Event, db: Session | None = None) -> RdgDisplayInfo
|
||||
)
|
||||
|
||||
|
||||
def event_supports_rdg_client_qwinsta(event: Event) -> bool:
|
||||
if event.type not in RDG_TYPES:
|
||||
return False
|
||||
return bool(event_internal_ip(event))
|
||||
def event_supports_rdg_client_qwinsta(event: Event, db: Session | None = None) -> bool:
|
||||
from app.services.rdg_session_flap import resolve_rdg_qwinsta_enabled
|
||||
|
||||
return resolve_rdg_qwinsta_enabled(db, event)
|
||||
|
||||
@@ -172,25 +172,73 @@ def find_rdg_end_after_success(db: Session, success_event: Event) -> Event | Non
|
||||
return None
|
||||
|
||||
|
||||
def find_normal_rdg_end_after_success(db: Session, success_event: Event) -> Event | None:
|
||||
"""303 после 302 с паузой больше flap-окна — штатное завершение сессии."""
|
||||
if success_event.type != RDG_SUCCESS_TYPE:
|
||||
return None
|
||||
settings = get_settings()
|
||||
max_sec = settings.sac_rdg_flap_window_max_sec
|
||||
start_at = _as_utc(success_event.occurred_at)
|
||||
after_flap = start_at + timedelta(seconds=max_sec)
|
||||
|
||||
candidates = db.scalars(
|
||||
select(Event)
|
||||
.where(
|
||||
Event.host_id == success_event.host_id,
|
||||
Event.type.in_(RDG_END_TYPES),
|
||||
Event.occurred_at > after_flap,
|
||||
Event.id != success_event.id,
|
||||
)
|
||||
.order_by(Event.occurred_at.asc())
|
||||
).all()
|
||||
|
||||
for end in candidates:
|
||||
if not _users_match(end, success_event):
|
||||
continue
|
||||
if not _internal_ips_compatible(end, success_event):
|
||||
continue
|
||||
return end
|
||||
return None
|
||||
|
||||
|
||||
def resolve_rdg_qwinsta_enabled(db: Session | None, event: Event) -> bool:
|
||||
"""Кнопка qwinsta/logoff только на 302, пока сессия может быть активна (или RDG flap)."""
|
||||
if event.type in RDG_END_TYPES:
|
||||
return False
|
||||
if event.type != RDG_SUCCESS_TYPE:
|
||||
return False
|
||||
if not _event_internal_ip(event):
|
||||
return False
|
||||
if db is None:
|
||||
return True
|
||||
if find_rdg_end_after_success(db, event) is not None:
|
||||
return True
|
||||
if find_normal_rdg_end_after_success(db, event) is not None:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def resolve_rdg_flap_summary(
|
||||
db: Session, event: Event
|
||||
) -> tuple[bool, int | None, int | None]:
|
||||
"""
|
||||
(rdg_flap, pair_event_id, qwinsta_event_id).
|
||||
qwinsta_event_id — всегда 303; для 302 указывает на связанный end-event.
|
||||
qwinsta_event_id — id события 302 для qwinsta (на 303 кнопку не показываем).
|
||||
"""
|
||||
if event_has_rdg_flap(event):
|
||||
pair_id = _stored_flap_pair_id(event)
|
||||
return True, pair_id, event.id
|
||||
if event.type == RDG_SUCCESS_TYPE:
|
||||
return True, pair_id, event.id
|
||||
return True, pair_id, pair_id
|
||||
|
||||
if event.type in RDG_END_TYPES:
|
||||
prior = find_rdg_success_before_end(db, event)
|
||||
if prior is not None:
|
||||
return True, prior.id, event.id
|
||||
return True, prior.id, prior.id
|
||||
|
||||
if event.type == RDG_SUCCESS_TYPE:
|
||||
end = find_rdg_end_after_success(db, event)
|
||||
if end is not None:
|
||||
return True, end.id, end.id
|
||||
return True, end.id, event.id
|
||||
|
||||
return False, None, None
|
||||
|
||||
@@ -31,8 +31,8 @@ def _require_win_admin(db: Session):
|
||||
return cfg
|
||||
|
||||
|
||||
def _require_rdg_client_qwinsta(event: Event) -> None:
|
||||
if event_supports_rdg_client_qwinsta(event):
|
||||
def _require_rdg_client_qwinsta(db: Session, event: Event) -> None:
|
||||
if event_supports_rdg_client_qwinsta(event, db):
|
||||
return
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
@@ -92,7 +92,7 @@ def _persist_command(
|
||||
|
||||
|
||||
def execute_qwinsta_via_winrm(db: Session, event: Event, *, requested_by: str) -> AgentCommand:
|
||||
_require_rdg_client_qwinsta(event)
|
||||
_require_rdg_client_qwinsta(db, event)
|
||||
cfg = _require_win_admin(db)
|
||||
client_host = _resolve_client(db, event)
|
||||
|
||||
@@ -135,7 +135,7 @@ def execute_logoff_via_winrm(
|
||||
session_id: int,
|
||||
requested_by: str,
|
||||
) -> AgentCommand:
|
||||
_require_rdg_client_qwinsta(event)
|
||||
_require_rdg_client_qwinsta(db, event)
|
||||
cfg = _require_win_admin(db)
|
||||
client_host = _resolve_client(db, event)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user