fix: harden agent startup and websocket auth

This commit is contained in:
root
2026-07-27 11:49:18 +03:00
parent a386a1fd5c
commit 3fd8525c4e
10 changed files with 283 additions and 29 deletions

View File

@@ -37,7 +37,7 @@ def _make_client(overrides: dict | None = None) -> tuple[TestClient, MagicMock]:
id="admin-1", username="admin", email="admin@x.com",
auth_source="LOCAL",
created_at=__import__("datetime").datetime.now(),
roles=[RoleSchema(id="r1", name="Admin", description="", permissions=[])],
roles=[RoleSchema(id="r1", name="Admin", description="", is_admin=True, permissions=[])],
)
mock_plugin_loader = MagicMock()

View File

@@ -9,11 +9,12 @@
from pathlib import Path
import sys
from types import SimpleNamespace
sys.path.insert(0, str(Path(__file__).parent.parent / "src"))
import pytest
from unittest.mock import AsyncMock, MagicMock, patch
from unittest.mock import MagicMock, patch
class TestAuthenticateWebsocket:
@@ -117,4 +118,47 @@ class TestAuthenticateWebsocketApiKeyException:
msl.return_value = db
assert await _authenticate_websocket(ws, "ws/logs") is False
# #endregion Test.AppModule.TestApikeyDbException
# #region Test.AppModule.AuthorizeWebsocket [C:3] [TYPE Class] [SEMANTICS test,app,ws,authorization,rbac]
# @BRIEF Verify WebSocket authorization grants access only through is_admin or explicit permissions.
# @RELATION BINDS_TO -> [App.AppModule.AuthorizeWebsocket]
class TestAuthorizeWebsocket:
def _authorize(self, user, resource="tasks", action="READ"):
from src.app import _authorize_websocket
ws = MagicMock()
ws.query_params = {"token": "valid.jwt"}
db = MagicMock()
db.query.return_value.filter.return_value.first.return_value = user
with (
patch("src.core.auth.jwt.decode_token", return_value={"sub": "testuser"}),
patch("src.core.database.SessionLocal", return_value=db),
):
result = _authorize_websocket(ws, resource, action)
db.close.assert_called_once()
return result
def test_is_admin_role_bypasses_permission_check(self):
user = SimpleNamespace(
is_active=True,
roles=[SimpleNamespace(name="Admin", is_admin=True, permissions=[])],
)
assert self._authorize(user) is True
def test_legacy_admin_name_without_flag_does_not_bypass_permissions(self):
user = SimpleNamespace(
is_active=True,
roles=[SimpleNamespace(name="Admin", is_admin=False, permissions=[])],
)
assert self._authorize(user) is False
def test_explicit_permission_allows_websocket_access(self):
permission = SimpleNamespace(resource="tasks", action="READ")
user = SimpleNamespace(
is_active=True,
roles=[SimpleNamespace(name="Operator", is_admin=False, permissions=[permission])],
)
assert self._authorize(user) is True
# #endregion Test.AppModule.AuthorizeWebsocket
# #endregion Test.AppModule.WsAuth