diff --git a/backend/app/api/v1/events.py b/backend/app/api/v1/events.py index eb9d9cc..48fc293 100644 --- a/backend/app/api/v1/events.py +++ b/backend/app/api/v1/events.py @@ -21,11 +21,13 @@ from app.services.notify_dispatch import ( AUTH_LOGIN_SUCCESS_TYPES, DAILY_REPORT_EVENT_TYPES, LIFECYCLE_EVENT_TYPE, + RDG_CONNECTION_TYPES, notify_auth_login, notify_daily_report, notify_event, notify_lifecycle, notify_problem, + notify_rdg_connection, ) router = APIRouter(prefix="/events", tags=["events"]) @@ -79,6 +81,8 @@ def post_event( notify_lifecycle(event, db=db) elif event.type in AUTH_LOGIN_SUCCESS_TYPES: notify_auth_login(event, db=db) + elif event.type in RDG_CONNECTION_TYPES: + notify_rdg_connection(event, db=db) else: notify_event(event, db=db) if problem is not None and problem_created: diff --git a/backend/app/services/notify_dispatch.py b/backend/app/services/notify_dispatch.py index 05cf25b..6cc1fd5 100644 --- a/backend/app/services/notify_dispatch.py +++ b/backend/app/services/notify_dispatch.py @@ -15,6 +15,11 @@ logger = logging.getLogger(__name__) LIFECYCLE_EVENT_TYPE = "agent.lifecycle" DAILY_REPORT_EVENT_TYPES = frozenset({"report.daily.ssh", "report.daily.rdp"}) AUTH_LOGIN_SUCCESS_TYPES = frozenset({"rdp.login.success", "ssh.login.success"}) +RDG_CONNECTION_TYPES = frozenset({ + "rdg.connection.success", + "rdg.connection.disconnected", + "rdg.connection.failed", +}) def _event_telegram_via_agent(event: Event) -> bool: @@ -94,3 +99,11 @@ def notify_auth_login(event: Event, *, db: Session | None = None) -> None: if not should_notify_event(event, db): return _dispatch_lifecycle_channels(event, db=db, policy=policy) + + +def notify_rdg_connection(event: Event, *, db: Session | None = None) -> None: + """RD Gateway 302/303 — ingest всегда; Telegram SAC вне min_severity (как auth login).""" + policy = get_effective_notification_policy(db) + if not should_notify_event(event, db): + return + _dispatch_lifecycle_channels(event, db=db, policy=policy) diff --git a/backend/app/services/telegram_templates.py b/backend/app/services/telegram_templates.py index 5d9703b..a776064 100644 --- a/backend/app/services/telegram_templates.py +++ b/backend/app/services/telegram_templates.py @@ -428,8 +428,12 @@ def format_event_telegram_html(event: Event) -> str: def _format_rdg_html(event: Event) -> str: details = _details_dict(event) - ok = event.type.endswith(".success") - header = "✅ RD Gateway: подключение" if ok else "❌ RD Gateway: ошибка" + if event.type.endswith(".success"): + header = "✅ RD Gateway: подключение" + elif event.type.endswith(".disconnected"): + header = "ℹ️ RD Gateway: отключение" + else: + header = "❌ RD Gateway: ошибка" msg = f"{header}\n" msg += _line("👤", "Пользователь", html_escape(_detail(details, "user", "username"))) msg += _line("🏢", "Хост", host_label(event.host)) diff --git a/backend/tests/test_notify_dispatch.py b/backend/tests/test_notify_dispatch.py index c33e52b..d250ef2 100644 --- a/backend/tests/test_notify_dispatch.py +++ b/backend/tests/test_notify_dispatch.py @@ -116,6 +116,33 @@ def test_notify_auth_login_bypasses_min_severity(): mock_tg.notify_event.assert_called_once() +def test_notify_rdg_connection_bypasses_min_severity(): + event = Event( + event_id="00000000-0000-4000-8000-000000000603", + host_id=1, + occurred_at=datetime(2026, 5, 31, 18, 36, tzinfo=timezone.utc), + category="auth", + type="rdg.connection.success", + severity="info", + title="RD Gateway event 302", + summary="RDG 302 papatramp -> 192.168.160.3", + details={"telegram_via": "sac"}, + payload={}, + ) + policy = NotificationPolicyConfig( + min_severity="warning", + use_telegram=True, + use_webhook=False, + use_email=False, + source="db", + ) + with patch.object(notify_dispatch, "get_effective_notification_policy", return_value=policy): + with patch.object(notify_dispatch, "should_notify_event", return_value=True): + with patch.object(notify_dispatch, "telegram_notify") as mock_tg: + notify_dispatch.notify_rdg_connection(event) + mock_tg.notify_event.assert_called_once() + + def test_notify_auth_login_skips_telegram_when_via_agent(): event = Event( event_id="00000000-0000-4000-8000-000000000602", diff --git a/schemas/event-schema-v1.json b/schemas/event-schema-v1.json index 35631ba..d5004d4 100644 --- a/schemas/event-schema-v1.json +++ b/schemas/event-schema-v1.json @@ -99,6 +99,8 @@ "rdp.shadow.control.permission", "winrm.session.started", "rdg.connection.success", + "rdg.connection.disconnected", + "rdg.connection.failed", "report.daily.ssh", "agent.heartbeat", "agent.test"