fix: harden agent startup and websocket auth
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user