fix: FCM must not break ingest; add requests dependency (0.9.3)
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -69,7 +69,12 @@ def _fcm_access_token(service_account_path: str) -> str:
|
||||
from google.oauth2 import service_account
|
||||
from google.auth.transport.requests import Request
|
||||
except ImportError as exc:
|
||||
raise MobileNotConfiguredError("google-auth package is required for FCM") from exc
|
||||
msg = str(exc).lower()
|
||||
if "requests" in msg:
|
||||
raise MobileNotConfiguredError(
|
||||
"FCM: установите пакет requests (pip install requests)"
|
||||
) from exc
|
||||
raise MobileNotConfiguredError("FCM: установите google-auth") from exc
|
||||
|
||||
creds = service_account.Credentials.from_service_account_file(
|
||||
service_account_path,
|
||||
@@ -116,7 +121,19 @@ def _send_fcm_data(
|
||||
raise MobileNotConfiguredError("FCM не настроен на сервере")
|
||||
return
|
||||
|
||||
try:
|
||||
access_token = _fcm_access_token(cfg.service_account_path)
|
||||
except (MobileNotConfiguredError, MobileSendError) as exc:
|
||||
logger.warning("FCM skipped: %s", exc)
|
||||
if require_success:
|
||||
raise
|
||||
return
|
||||
except Exception:
|
||||
logger.exception("FCM token acquisition failed")
|
||||
if require_success:
|
||||
raise MobileSendError("Failed to obtain FCM access token", status_code=502)
|
||||
return
|
||||
|
||||
url = f"https://fcm.googleapis.com/v1/projects/{cfg.project_id}/messages:send"
|
||||
headers = {
|
||||
"Authorization": f"Bearer {access_token}",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"""Единый источник версии SAC (API, health, логи, OpenAPI)."""
|
||||
|
||||
APP_NAME = "Security Alert Center"
|
||||
APP_VERSION = "0.9.2"
|
||||
APP_VERSION = "0.9.3"
|
||||
APP_VERSION_LABEL = f"{APP_NAME} v.{APP_VERSION}"
|
||||
|
||||
@@ -11,6 +11,7 @@ passlib[bcrypt]>=1.7.4,<2
|
||||
python-jose[cryptography]>=3.3.0,<4
|
||||
httpx>=0.28.0,<1
|
||||
google-auth>=2.36.0,<3
|
||||
requests>=2.32.0,<3
|
||||
psutil>=6.1.0,<8
|
||||
|
||||
# dev
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
"""FCM push must not break event ingest."""
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from app.services.mobile_notify import MobileNotConfiguredError, _send_fcm_data
|
||||
|
||||
|
||||
def test_send_fcm_data_swallows_token_errors_by_default():
|
||||
with patch(
|
||||
"app.services.mobile_notify._fcm_access_token",
|
||||
side_effect=MobileNotConfiguredError("FCM: install requests"),
|
||||
):
|
||||
with patch("app.services.mobile_notify.get_effective_fcm_config") as mock_cfg:
|
||||
mock_cfg.return_value.enabled = True
|
||||
mock_cfg.return_value.project_id = "proj"
|
||||
mock_cfg.return_value.service_account_path = "/etc/fcm.json"
|
||||
mock_cfg.return_value.configured = True
|
||||
mock_cfg.return_value.active = True
|
||||
_send_fcm_data(["token"], {"kind": "test"}, title="t", body="b")
|
||||
|
||||
|
||||
def test_send_fcm_data_raises_token_errors_when_required():
|
||||
with patch(
|
||||
"app.services.mobile_notify._fcm_access_token",
|
||||
side_effect=MobileNotConfiguredError("FCM: install requests"),
|
||||
):
|
||||
with patch("app.services.mobile_notify.get_effective_fcm_config") as mock_cfg:
|
||||
mock_cfg.return_value.enabled = True
|
||||
mock_cfg.return_value.project_id = "proj"
|
||||
mock_cfg.return_value.service_account_path = "/etc/fcm.json"
|
||||
mock_cfg.return_value.configured = True
|
||||
mock_cfg.return_value.active = True
|
||||
with pytest.raises(MobileNotConfiguredError):
|
||||
_send_fcm_data(
|
||||
["token"],
|
||||
{"kind": "test"},
|
||||
title="t",
|
||||
body="b",
|
||||
require_success=True,
|
||||
)
|
||||
Reference in New Issue
Block a user