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:
@@ -4,6 +4,6 @@ from app.version import APP_NAME, APP_VERSION, APP_VERSION_LABEL
|
||||
|
||||
|
||||
def test_version_constants():
|
||||
assert APP_VERSION == "0.3.3"
|
||||
assert APP_VERSION == "0.3.4"
|
||||
assert APP_NAME == "Security Alert Center"
|
||||
assert APP_VERSION_LABEL == "Security Alert Center v.0.3.3"
|
||||
assert APP_VERSION_LABEL == "Security Alert Center v.0.3.4"
|
||||
|
||||
@@ -111,7 +111,15 @@ def test_event_supports_rdg_client_qwinsta_without_flap(db_session):
|
||||
db_session.add(gw)
|
||||
db_session.commit()
|
||||
event = _rdg_event(db_session, gw=gw)
|
||||
assert event_supports_rdg_client_qwinsta(event) is True
|
||||
assert event_supports_rdg_client_qwinsta(event, db_session) is True
|
||||
|
||||
|
||||
def test_event_supports_rdg_client_qwinsta_not_on_disconnect(db_session):
|
||||
gw = Host(hostname="K6A-DC3", os_family="windows", product="rdp-login-monitor", ipv4="192.168.160.40")
|
||||
db_session.add(gw)
|
||||
db_session.commit()
|
||||
event = _rdg_event(db_session, gw=gw, event_type="rdg.connection.disconnected", win_id=303)
|
||||
assert event_supports_rdg_client_qwinsta(event, db_session) is False
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -125,4 +133,4 @@ def test_event_supports_rdg_client_qwinsta_requires_internal_ip(db_session, inte
|
||||
event = _rdg_event(db_session, gw=gw, internal_ip=internal_ip or "")
|
||||
if internal_ip is None:
|
||||
event.details = {k: v for k, v in event.details.items() if k != "internal_ip"}
|
||||
assert event_supports_rdg_client_qwinsta(event) is False
|
||||
assert event_supports_rdg_client_qwinsta(event, db_session) is False
|
||||
|
||||
@@ -15,6 +15,7 @@ from app.services.rdg_session_flap import (
|
||||
event_has_rdg_flap,
|
||||
find_rdg_success_before_end,
|
||||
resolve_rdg_flap_summary,
|
||||
resolve_rdg_qwinsta_enabled,
|
||||
)
|
||||
from app.services.event_summary import event_to_summary
|
||||
from tests.test_ingest import VALID_EVENT
|
||||
@@ -193,14 +194,70 @@ def test_resolve_rdg_flap_summary_for_302_and_303(db_session, rdg_settings):
|
||||
|
||||
assert end_flap is True
|
||||
assert end_pair == start.id
|
||||
assert end_qwinsta == end.id
|
||||
assert end_qwinsta == start.id
|
||||
|
||||
assert start_flap is True
|
||||
assert start_pair == end.id
|
||||
assert start_qwinsta == end.id
|
||||
assert start_qwinsta == start.id
|
||||
|
||||
end_summary = event_to_summary(end, db_session)
|
||||
start_summary = event_to_summary(start, db_session)
|
||||
assert end_summary.rdg_flap is True
|
||||
assert start_summary.rdg_flap is True
|
||||
assert start_summary.rdg_flap_qwinsta_event_id == end.id
|
||||
assert start_summary.rdg_flap_qwinsta_event_id == start.id
|
||||
assert start_summary.rdg_qwinsta_enabled is True
|
||||
assert end_summary.rdg_qwinsta_enabled is False
|
||||
|
||||
|
||||
def test_rdg_qwinsta_disabled_after_normal_session_end(db_session, rdg_settings):
|
||||
t0 = datetime.now(timezone.utc)
|
||||
user = "B26\\normal.user"
|
||||
details = {"user": user, "internal_ip": "192.168.163.49"}
|
||||
|
||||
start = _ingest(
|
||||
db_session,
|
||||
t0,
|
||||
type="rdg.connection.success",
|
||||
category="auth",
|
||||
severity="info",
|
||||
title="302",
|
||||
summary="302",
|
||||
details=details,
|
||||
)
|
||||
end = _ingest(
|
||||
db_session,
|
||||
t0 + timedelta(minutes=20),
|
||||
type="rdg.connection.disconnected",
|
||||
category="auth",
|
||||
severity="info",
|
||||
title="303",
|
||||
summary="303",
|
||||
details=details,
|
||||
)
|
||||
|
||||
assert resolve_rdg_qwinsta_enabled(db_session, start) is False
|
||||
assert resolve_rdg_qwinsta_enabled(db_session, end) is False
|
||||
|
||||
start_summary = event_to_summary(start, db_session)
|
||||
end_summary = event_to_summary(end, db_session)
|
||||
assert start_summary.rdg_qwinsta_enabled is False
|
||||
assert end_summary.rdg_qwinsta_enabled is False
|
||||
|
||||
|
||||
def test_rdg_qwinsta_enabled_while_session_open(db_session, rdg_settings):
|
||||
t0 = datetime.now(timezone.utc)
|
||||
details = {"user": r"B26\active.user", "internal_ip": "192.168.163.50"}
|
||||
|
||||
start = _ingest(
|
||||
db_session,
|
||||
t0,
|
||||
type="rdg.connection.success",
|
||||
category="auth",
|
||||
severity="info",
|
||||
title="302",
|
||||
summary="302",
|
||||
details=details,
|
||||
)
|
||||
|
||||
assert resolve_rdg_qwinsta_enabled(db_session, start) is True
|
||||
assert event_to_summary(start, db_session).rdg_qwinsta_enabled is True
|
||||
|
||||
@@ -9,22 +9,21 @@ from app.models import Event, Host
|
||||
from app.services.winrm_connect import WinRmCmdResult
|
||||
|
||||
|
||||
def _flap_event(db_session, *, gw: Host, ws: Host) -> Event:
|
||||
def _rdg_success_event(db_session, *, gw: Host, ws: Host) -> Event:
|
||||
event = Event(
|
||||
event_id="ev-flap-1",
|
||||
event_id="ev-rdg-302",
|
||||
host_id=gw.id,
|
||||
occurred_at=datetime.now(timezone.utc),
|
||||
received_at=datetime.now(timezone.utc),
|
||||
category="auth",
|
||||
type="rdg.connection.disconnected",
|
||||
type="rdg.connection.success",
|
||||
severity="info",
|
||||
title="RD Gateway event 303",
|
||||
title="RD Gateway event 302",
|
||||
summary="",
|
||||
payload={},
|
||||
details={
|
||||
"user": r"B26\papatramp",
|
||||
"internal_ip": ws.ipv4,
|
||||
"rdg_flap": True,
|
||||
},
|
||||
)
|
||||
db_session.add(event)
|
||||
@@ -50,7 +49,7 @@ def test_qwinsta_via_winrm_on_client_host(jwt_headers, client, db_session, monke
|
||||
db_session.add_all([ws, gw])
|
||||
db_session.commit()
|
||||
ws_id = ws.id
|
||||
event = _flap_event(db_session, gw=gw, ws=ws)
|
||||
event = _rdg_success_event(db_session, gw=gw, ws=ws)
|
||||
|
||||
qwinsta_out = " SESSIONNAME USERNAME ID STATE\r\n rdp-tcp#0 B26\\papatramp 2 Active\r\n"
|
||||
|
||||
@@ -96,12 +95,12 @@ def test_qwinsta_client_not_in_hosts(jwt_headers, client, db_session, monkeypatc
|
||||
occurred_at=datetime.now(timezone.utc),
|
||||
received_at=datetime.now(timezone.utc),
|
||||
category="auth",
|
||||
type="rdg.connection.disconnected",
|
||||
type="rdg.connection.success",
|
||||
severity="info",
|
||||
title="303",
|
||||
title="302",
|
||||
summary="",
|
||||
payload={},
|
||||
details={"user": r"B26\user", "internal_ip": "192.168.160.999", "rdg_flap": True},
|
||||
details={"user": r"B26\user", "internal_ip": "192.168.160.999"},
|
||||
)
|
||||
db_session.add(event)
|
||||
db_session.commit()
|
||||
@@ -185,3 +184,40 @@ def test_qwinsta_rejects_rdg_without_internal_ip(jwt_headers, client, db_session
|
||||
response = client.post(f"/api/v1/events/{event.id}/actions/qwinsta", headers=jwt_headers)
|
||||
assert response.status_code == 400
|
||||
assert "internal_ip" in response.json()["detail"].lower()
|
||||
|
||||
|
||||
def test_qwinsta_rejects_rdg_303_disconnect(jwt_headers, client, db_session, monkeypatch):
|
||||
monkeypatch.setenv("SAC_WIN_ADMIN_USER", r"B26\admin")
|
||||
monkeypatch.setenv("SAC_WIN_ADMIN_PASSWORD", "pw")
|
||||
from app.config import get_settings
|
||||
|
||||
get_settings.cache_clear()
|
||||
|
||||
ws = Host(
|
||||
hostname="Andrisonova-PC",
|
||||
os_family="windows",
|
||||
product="rdp-login-monitor",
|
||||
ipv4="192.168.160.113",
|
||||
)
|
||||
gw = Host(hostname="K6A-DC3", os_family="windows", product="rdp-login-monitor", ipv4="192.168.160.40")
|
||||
db_session.add_all([ws, gw])
|
||||
db_session.commit()
|
||||
|
||||
event = Event(
|
||||
event_id="ev-rdg-303",
|
||||
host_id=gw.id,
|
||||
occurred_at=datetime.now(timezone.utc),
|
||||
received_at=datetime.now(timezone.utc),
|
||||
category="auth",
|
||||
type="rdg.connection.disconnected",
|
||||
severity="info",
|
||||
title="303",
|
||||
summary="",
|
||||
payload={},
|
||||
details={"user": r"B26\papatramp", "internal_ip": ws.ipv4},
|
||||
)
|
||||
db_session.add(event)
|
||||
db_session.commit()
|
||||
|
||||
response = client.post(f"/api/v1/events/{event.id}/actions/qwinsta", headers=jwt_headers)
|
||||
assert response.status_code == 400
|
||||
|
||||
Reference in New Issue
Block a user