From 407ef37004b34f2c7c6f086d25f340fcce0fa7a0 Mon Sep 17 00:00:00 2001 From: PTah Date: Tue, 23 Jun 2026 16:30:16 +1000 Subject: [PATCH] fix: strict RDG 302/303 IP pairing keeps break button visible (0.3.6) Co-authored-by: Cursor --- backend/app/services/rdg_session_flap.py | 11 ++++++++- backend/app/version.py | 2 +- backend/tests/test_health.py | 4 +-- backend/tests/test_rdg_session_flap.py | 31 ++++++++++++++++++++++++ frontend/src/version.ts | 2 +- 5 files changed, 45 insertions(+), 5 deletions(-) diff --git a/backend/app/services/rdg_session_flap.py b/backend/app/services/rdg_session_flap.py index 892d5c3..f638246 100644 --- a/backend/app/services/rdg_session_flap.py +++ b/backend/app/services/rdg_session_flap.py @@ -47,6 +47,15 @@ def _internal_ips_compatible(end_event: Event, success_event: Event) -> bool: return end_ip == success_ip +def _internal_ips_match_strict(end_event: Event, success_event: Event) -> bool: + """Для «сессия завершена» — только при совпадении целевого ПК (оба IP заданы).""" + end_ip = _event_internal_ip(end_event) + success_ip = _event_internal_ip(success_event) + if not end_ip or not success_ip: + return False + return end_ip == success_ip + + def _as_utc(dt: datetime) -> datetime: if dt.tzinfo is None: return dt.replace(tzinfo=timezone.utc) @@ -195,7 +204,7 @@ def find_normal_rdg_end_after_success(db: Session, success_event: Event) -> Even for end in candidates: if not _users_match(end, success_event): continue - if not _internal_ips_compatible(end, success_event): + if not _internal_ips_match_strict(end, success_event): continue return end return None diff --git a/backend/app/version.py b/backend/app/version.py index 5bed2f6..7c5a79b 100644 --- a/backend/app/version.py +++ b/backend/app/version.py @@ -1,5 +1,5 @@ """Единый источник версии SAC (API, health, логи, OpenAPI).""" APP_NAME = "Security Alert Center" -APP_VERSION = "0.3.5" +APP_VERSION = "0.3.6" APP_VERSION_LABEL = f"{APP_NAME} v.{APP_VERSION}" diff --git a/backend/tests/test_health.py b/backend/tests/test_health.py index 1f5b003..146ecc9 100644 --- a/backend/tests/test_health.py +++ b/backend/tests/test_health.py @@ -4,6 +4,6 @@ from app.version import APP_NAME, APP_VERSION, APP_VERSION_LABEL def test_version_constants(): - assert APP_VERSION == "0.3.5" + assert APP_VERSION == "0.3.6" assert APP_NAME == "Security Alert Center" - assert APP_VERSION_LABEL == "Security Alert Center v.0.3.5" + assert APP_VERSION_LABEL == "Security Alert Center v.0.3.6" diff --git a/backend/tests/test_rdg_session_flap.py b/backend/tests/test_rdg_session_flap.py index ea632ec..4aef21a 100644 --- a/backend/tests/test_rdg_session_flap.py +++ b/backend/tests/test_rdg_session_flap.py @@ -261,3 +261,34 @@ def test_rdg_qwinsta_enabled_while_session_open(db_session, rdg_settings): assert resolve_rdg_qwinsta_enabled(db_session, start) is True assert event_to_summary(start, db_session).rdg_qwinsta_enabled is True + + +def test_rdg_qwinsta_stays_enabled_when_unrelated_303_without_internal_ip(db_session, rdg_settings): + t0 = datetime.now(timezone.utc) + user = "B26\\khodasevich" + details_302 = {"user": user, "internal_ip": "192.168.160.209"} + details_303_other = {"user": user} + + start = _ingest( + db_session, + t0, + type="rdg.connection.success", + category="auth", + severity="warning", + title="302", + summary="302", + details=details_302, + ) + _ingest( + db_session, + t0 + timedelta(minutes=5), + type="rdg.connection.disconnected", + category="auth", + severity="info", + title="303", + summary="303", + details=details_303_other, + ) + + assert resolve_rdg_qwinsta_enabled(db_session, start) is True + assert event_to_summary(start, db_session).rdg_qwinsta_enabled is True diff --git a/frontend/src/version.ts b/frontend/src/version.ts index 007237f..252474c 100644 --- a/frontend/src/version.ts +++ b/frontend/src/version.ts @@ -1,4 +1,4 @@ /** Fallback до загрузки /health; при релизе держите в sync с backend/app/version.py */ export const APP_NAME = "Security Alert Center"; -export const APP_VERSION = "0.3.5"; +export const APP_VERSION = "0.3.6"; export const APP_VERSION_LABEL = `${APP_NAME} v.${APP_VERSION}`;