annator-command-center / tests /security /test_admin_authorization.py
techprotrade's picture
Deploy ATOM FastAPI command center runtime (part 9)
81e3673 verified
Raw
History Blame Contribute Delete
10.2 kB
"""
Admin Authorization Security Tests
Tests cover:
- Super admin role requirement for administrative endpoints
- Standard user access denial to admin endpoints
- WebSocket management authorization
- Rating sync authorization
- Conflict management authorization
"""
import pytest
from fastapi.testclient import TestClient
from sqlalchemy.orm import Session
from tests.factories.user_factory import UserFactory
from tests.security.conftest import create_test_token
class TestWebSocketManagementAuthorization:
"""Test WebSocket management endpoint authorization."""
def test_websocket_status_requires_super_admin(self, client: TestClient, db_session: Session):
"""Test that websocket status endpoint requires super_admin role."""
# Create a standard member user
standard_user = UserFactory(
email="standard@test.com",
role="member",
_session=db_session
)
# Try to access websocket status as standard user
response = client.get(
"/api/admin/websocket/status",
headers={"Authorization": f"Bearer {create_test_token(standard_user.id)}"}
)
# Should be denied with 403
assert response.status_code == 403
# Check that response contains permission/super_admin related error
error_detail = response.json()
if isinstance(error_detail, dict):
detail = error_detail.get("detail", "")
assert "super_admin" in str(detail).lower() or "permission" in str(detail).lower()
def test_websocket_disable_requires_super_admin(self, client: TestClient, db_session: Session):
"""Test that websocket disable endpoint requires super_admin role."""
standard_user = UserFactory(
email="standard@test.com",
role="member",
_session=db_session
)
response = client.post(
"/api/admin/websocket/disable",
headers={"Authorization": f"Bearer {create_test_token(standard_user.id)}"}
)
# Should be denied
assert response.status_code == 403
def test_websocket_enable_requires_super_admin(self, client: TestClient, db_session: Session):
"""Test that websocket enable endpoint requires super_admin role."""
standard_user = UserFactory(
email="standard@test.com",
role="member",
_session=db_session
)
response = client.post(
"/api/admin/websocket/enable",
headers={"Authorization": f"Bearer {create_test_token(standard_user.id)}"}
)
# Should be denied
assert response.status_code == 403
def test_websocket_reconnect_requires_super_admin(self, client: TestClient, db_session: Session):
"""Test that websocket reconnect endpoint requires super_admin role."""
standard_user = UserFactory(
email="standard@test.com",
role="member",
_session=db_session
)
response = client.post(
"/api/admin/websocket/reconnect",
headers={"Authorization": f"Bearer {create_test_token(standard_user.id)}"}
)
# Should be denied
assert response.status_code == 403
class TestRatingSyncAuthorization:
"""Test rating sync endpoint authorization."""
def test_trigger_rating_sync_requires_super_admin(self, client: TestClient, db_session: Session):
"""Test that rating sync endpoint requires super_admin role."""
standard_user = UserFactory(
email="standard@test.com",
role="member",
_session=db_session
)
response = client.post(
"/api/admin/sync/ratings",
json={"upload_all": False},
headers={"Authorization": f"Bearer {create_test_token(standard_user.id)}"}
)
# Should be denied
assert response.status_code == 403
def test_get_failed_rating_uploads_requires_super_admin(self, client: TestClient, db_session: Session):
"""Test that failed uploads endpoint requires super_admin role."""
standard_user = UserFactory(
email="standard@test.com",
role="member",
_session=db_session
)
response = client.get(
"/api/admin/ratings/failed-uploads",
headers={"Authorization": f"Bearer {create_test_token(standard_user.id)}"}
)
# Should be denied
assert response.status_code == 403
def test_retry_failed_rating_upload_requires_super_admin(self, client: TestClient, db_session: Session):
"""Test that retry upload endpoint requires super_admin role."""
standard_user = UserFactory(
email="standard@test.com",
role="member",
_session=db_session
)
response = client.post(
"/api/admin/ratings/failed-uploads/test-id/retry",
headers={"Authorization": f"Bearer {create_test_token(standard_user.id)}"}
)
# Should be denied
assert response.status_code == 403
class TestConflictManagementAuthorization:
"""Test conflict management endpoint authorization."""
def test_list_conflicts_requires_super_admin(self, client: TestClient, db_session: Session):
"""Test that list conflicts endpoint requires super_admin role."""
standard_user = UserFactory(
email="standard@test.com",
role="member",
_session=db_session
)
response = client.get(
"/api/admin/conflicts",
headers={"Authorization": f"Bearer {create_test_token(standard_user.id)}"}
)
# Should be denied
assert response.status_code == 403
def test_get_conflict_requires_super_admin(self, client: TestClient, db_session: Session):
"""Test that get conflict endpoint requires super_admin role."""
standard_user = UserFactory(
email="standard@test.com",
role="member",
_session=db_session
)
response = client.get(
"/api/admin/conflicts/1",
headers={"Authorization": f"Bearer {create_test_token(standard_user.id)}"}
)
# Should be denied
assert response.status_code == 403
def test_resolve_conflict_requires_super_admin(self, client: TestClient, db_session: Session):
"""Test that resolve conflict endpoint requires super_admin role."""
standard_user = UserFactory(
email="standard@test.com",
role="member",
_session=db_session
)
response = client.post(
"/api/admin/conflicts/1/resolve",
json={
"strategy": "remote_wins",
"resolved_by": "admin@example.com"
},
headers={"Authorization": f"Bearer {create_test_token(standard_user.id)}"}
)
# Should be denied
assert response.status_code == 403
def test_bulk_resolve_conflicts_requires_super_admin(self, client: TestClient, db_session: Session):
"""Test that bulk resolve conflicts endpoint requires super_admin role."""
standard_user = UserFactory(
email="standard@test.com",
role="member",
_session=db_session
)
response = client.post(
"/api/admin/conflicts/bulk-resolve",
json={
"conflict_ids": [1, 2, 3],
"strategy": "remote_wins",
"resolved_by": "admin@example.com"
},
headers={"Authorization": f"Bearer {create_test_token(standard_user.id)}"}
)
# Should be denied
assert response.status_code == 403
class TestAdminAuthorizationBypassAttempts:
"""Test that various user roles cannot bypass admin authorization."""
@pytest.mark.parametrize("role", ["member", "admin", "viewer", "editor"])
def test_non_super_admin_roles_denied_websocket_access(self, client: TestClient, db_session: Session, role: str):
"""Test that all non-super_admin roles are denied access to websocket endpoints."""
# Create user with different role
user = UserFactory(
email=f"{role}@test.com",
role=role,
_session=db_session
)
response = client.get(
"/api/admin/websocket/status",
headers={"Authorization": f"Bearer {create_test_token(user.id)}"}
)
# Should be denied for all non-super_admin roles
assert response.status_code == 403
@pytest.mark.parametrize("role", ["member", "admin", "viewer", "editor"])
def test_non_super_admin_roles_denied_conflict_access(self, client: TestClient, db_session: Session, role: str):
"""Test that all non-super_admin roles are denied access to conflict endpoints."""
user = UserFactory(
email=f"{role}@test.com",
role=role,
_session=db_session
)
response = client.get(
"/api/admin/conflicts",
headers={"Authorization": f"Bearer {create_test_token(user.id)}"}
)
# Should be denied for all non-super_admin roles
assert response.status_code == 403
class TestUnauthenticatedAccess:
"""Test that unauthenticated requests are denied."""
def test_websocket_status_requires_authentication(self, client: TestClient):
"""Test that websocket status endpoint requires authentication."""
response = client.get("/api/admin/websocket/status")
assert response.status_code in [401, 403]
def test_conflict_list_requires_authentication(self, client: TestClient):
"""Test that conflict list endpoint requires authentication."""
response = client.get("/api/admin/conflicts")
assert response.status_code in [401, 403]
def test_rating_sync_requires_authentication(self, client: TestClient):
"""Test that rating sync endpoint requires authentication."""
response = client.post("/api/admin/sync/ratings", json={})
assert response.status_code in [401, 403]