diff --git a/tests/unit_tests/mcp_service/test_auth_api_key.py b/tests/unit_tests/mcp_service/test_auth_api_key.py index 7fa9b293481..b53e624e83a 100644 --- a/tests/unit_tests/mcp_service/test_auth_api_key.py +++ b/tests/unit_tests/mcp_service/test_auth_api_key.py @@ -22,6 +22,7 @@ from unittest.mock import MagicMock, patch import pytest from flask import g +from superset.app import SupersetApp from superset.mcp_service.auth import ( _resolve_user_from_jwt_context, get_user_from_request, @@ -229,7 +230,7 @@ def test_relationship_reload_failure_returns_original_user(app, mock_user) -> No @pytest.mark.usefixtures("_enable_api_keys") -def test_non_matching_bearer_token_skips_api_key_auth(app) -> None: +def test_non_matching_bearer_token_skips_api_key_auth(app: SupersetApp) -> None: """When a Bearer token is present but does not match FAB_API_KEY_PREFIXES (e.g., a JWT token), extract_api_key_from_request returns None and API key auth is skipped, falling through to the next auth method.""" @@ -254,7 +255,7 @@ def test_non_matching_bearer_token_skips_api_key_auth(app) -> None: # -- API key pass-through from CompositeTokenVerifier -- -def test_jwt_context_with_api_key_passthrough_returns_none(app) -> None: +def test_jwt_context_with_api_key_passthrough_returns_none(app: SupersetApp) -> None: """When CompositeTokenVerifier passes through an API key token, _resolve_user_from_jwt_context should detect the _api_key_passthrough claim and return None so get_user_from_request falls through to @@ -274,7 +275,7 @@ def test_jwt_context_with_api_key_passthrough_returns_none(app) -> None: # -- SecurityManager method name regression test -- -def test_security_manager_has_expected_api_key_methods(app) -> None: +def test_security_manager_has_expected_api_key_methods(app: SupersetApp) -> None: """Regression test: verify the SecurityManager method names referenced in auth._resolve_user_from_api_key() actually exist on the FAB SecurityManager class. This catches future renames before they silently break API key auth diff --git a/tests/unit_tests/mcp_service/test_composite_token_verifier.py b/tests/unit_tests/mcp_service/test_composite_token_verifier.py index 537fe4d8f07..8f496305a1c 100644 --- a/tests/unit_tests/mcp_service/test_composite_token_verifier.py +++ b/tests/unit_tests/mcp_service/test_composite_token_verifier.py @@ -26,7 +26,7 @@ from superset.mcp_service.composite_token_verifier import CompositeTokenVerifier @pytest.fixture -def mock_jwt_verifier(): +def mock_jwt_verifier() -> MagicMock: verifier = MagicMock() verifier.required_scopes = [] verifier.verify_token = AsyncMock() @@ -34,7 +34,7 @@ def mock_jwt_verifier(): @pytest.fixture -def composite_verifier(mock_jwt_verifier): +def composite_verifier(mock_jwt_verifier: MagicMock) -> CompositeTokenVerifier: return CompositeTokenVerifier( jwt_verifier=mock_jwt_verifier, api_key_prefixes=["sst_", "pat_"], @@ -42,7 +42,9 @@ def composite_verifier(mock_jwt_verifier): @pytest.mark.asyncio -async def test_api_key_token_returns_passthrough(composite_verifier) -> None: +async def test_api_key_token_returns_passthrough( + composite_verifier: CompositeTokenVerifier, +) -> None: """Tokens matching an API key prefix return a pass-through AccessToken.""" api_key = "sst_abc123secret" # noqa: S105 result = await composite_verifier.verify_token(api_key) @@ -54,7 +56,9 @@ async def test_api_key_token_returns_passthrough(composite_verifier) -> None: @pytest.mark.asyncio -async def test_second_prefix_matches(composite_verifier) -> None: +async def test_second_prefix_matches( + composite_verifier: CompositeTokenVerifier, +) -> None: """All configured prefixes are checked, not just the first.""" result = await composite_verifier.verify_token("pat_mytoken") @@ -64,7 +68,7 @@ async def test_second_prefix_matches(composite_verifier) -> None: @pytest.mark.asyncio async def test_jwt_token_delegates_to_wrapped_verifier( - composite_verifier, mock_jwt_verifier + composite_verifier: CompositeTokenVerifier, mock_jwt_verifier: MagicMock ) -> None: """Non-API-key tokens are delegated to the wrapped JWT verifier.""" jwt_token = "eyJhbGciOiJSUzI1NiJ9.jwt_payload" # noqa: S105 @@ -85,7 +89,9 @@ async def test_jwt_token_delegates_to_wrapped_verifier( @pytest.mark.asyncio -async def test_invalid_jwt_returns_none(composite_verifier, mock_jwt_verifier) -> None: +async def test_invalid_jwt_returns_none( + composite_verifier: CompositeTokenVerifier, mock_jwt_verifier: MagicMock +) -> None: """When the JWT verifier rejects a token, None is returned.""" mock_jwt_verifier.verify_token.return_value = None @@ -97,7 +103,7 @@ async def test_invalid_jwt_returns_none(composite_verifier, mock_jwt_verifier) - @pytest.mark.asyncio async def test_api_key_does_not_call_jwt_verifier( - composite_verifier, mock_jwt_verifier + composite_verifier: CompositeTokenVerifier, mock_jwt_verifier: MagicMock ) -> None: """API key tokens bypass the JWT verifier entirely.""" await composite_verifier.verify_token("sst_test_key")