diff --git a/ai-hub/app/api/dependencies.py b/ai-hub/app/api/dependencies.py index 0911d0a..4946e46 100644 --- a/ai-hub/app/api/dependencies.py +++ b/ai-hub/app/api/dependencies.py @@ -34,12 +34,11 @@ from app.config import settings if settings.SECRET_KEY and settings.SECRET_KEY not in ["dev", "generate-me"]: if not x_proxy_secret or x_proxy_secret != settings.SECRET_KEY: - # [NOTE] Temporarily downgraded to warning because Nginx is not yet configured to pass this header in all environments - logging.warning(f"Missing or invalid X-Proxy-Secret from {x_user_id}. Ignoring for now but this is a security risk if port 8000 is exposed.") - # raise HTTPException( - # status_code=status.HTTP_403_FORBIDDEN, - # detail="Invalid Proxy Secret. Identity claim rejected." - # ) + logging.warning(f"Invalid X-Proxy-Secret from {x_user_id}. Identity claim rejected.") + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, + detail="Invalid Proxy Secret. Identity claim rejected." + ) user = db.query(models.User).filter(models.User.id == x_user_id).first() if not user: @@ -77,8 +76,23 @@ def __init__(self): # Use a dictionary to store services, mapping their names to instances self._services = {} + # Explicitly declare known services self.document_service = None self.rag_service = None + self.orchestrator = None + self.settings = None + self.node_registry_service = None + self.browser_service = None + self.tool_service = None + self.stt_service = None + self.tts_service = None + self.prompt_service = None + self.session_service = None + self.user_service = None + self.mesh_service = None + self.auth_service = None + self.preference_service = None + self.agent_scheduler = None def with_service(self, name: str, service: Any): """ diff --git a/ai-hub/tests/api/test_dependencies.py b/ai-hub/tests/api/test_dependencies.py index 7edf391..0cf88d5 100644 --- a/ai-hub/tests/api/test_dependencies.py +++ b/ai-hub/tests/api/test_dependencies.py @@ -80,24 +80,51 @@ # --- Tests for get_current_user dependency --- -def test_get_current_user_with_valid_token(): - """ - Tests that get_current_user returns the expected user dictionary for a valid token. - """ - user = asyncio.run(get_current_user(token="valid_token")) - - assert user == {"email": "user@example.com", "id": 1} - - -def test_get_current_user_with_no_token(): - """ - Tests that get_current_user raises an HTTPException for a missing token. - """ +def test_get_current_user_missing_user_id(mock_session): with pytest.raises(HTTPException) as excinfo: - asyncio.run(get_current_user(token=None)) - + asyncio.run(get_current_user(db=mock_session, x_user_id=None)) assert excinfo.value.status_code == 401 - assert "Unauthorized" in str(excinfo.value.detail) + assert "X-User-ID header is missing" in str(excinfo.value.detail) + +@patch('app.api.dependencies.settings') +def test_get_current_user_valid_secret_required_but_missing(mock_settings, mock_session): + mock_settings.SECRET_KEY = "super_secret" + with pytest.raises(HTTPException) as excinfo: + asyncio.run(get_current_user(db=mock_session, x_user_id="test_user", x_proxy_secret=None)) + assert excinfo.value.status_code == 403 + assert "Invalid Proxy Secret" in str(excinfo.value.detail) + +@patch('app.api.dependencies.settings') +def test_get_current_user_invalid_secret(mock_settings, mock_session): + mock_settings.SECRET_KEY = "super_secret" + with pytest.raises(HTTPException) as excinfo: + asyncio.run(get_current_user(db=mock_session, x_user_id="test_user", x_proxy_secret="wrong_secret")) + assert excinfo.value.status_code == 403 + assert "Invalid Proxy Secret" in str(excinfo.value.detail) + +@patch('app.api.dependencies.settings') +def test_get_current_user_valid_secret(mock_settings, mock_session): + mock_settings.SECRET_KEY = "super_secret" + + mock_user = MagicMock() + mock_user.id = "test_user" + mock_user.password_hash = "some_hash" + mock_session.query.return_value.filter.return_value.first.return_value = mock_user + + user = asyncio.run(get_current_user(db=mock_session, x_user_id="test_user", x_proxy_secret="super_secret")) + assert user == mock_user + +@patch('app.api.dependencies.settings') +def test_get_current_user_secret_not_required(mock_settings, mock_session): + mock_settings.SECRET_KEY = "dev" + + mock_user = MagicMock() + mock_user.id = "test_user" + mock_user.password_hash = "some_hash" + mock_session.query.return_value.filter.return_value.first.return_value = mock_user + + user = asyncio.run(get_current_user(db=mock_session, x_user_id="test_user", x_proxy_secret=None)) + assert user == mock_user # --- Tests for ServiceContainer class --- diff --git a/ai-hub/tests/test_app.py b/ai-hub/tests/test_app.py index 757b178..31959a2 100644 --- a/ai-hub/tests/test_app.py +++ b/ai-hub/tests/test_app.py @@ -471,7 +471,6 @@ import yaml data = yaml.safe_load(response.text) - providers = data.get("llm_providers", {}).get("providers", {}) - custom_provider = providers.get("custom_provider", {}) - assert custom_provider.get("api_key") == "***" + llm_providers = data.get("llm_providers", {}) + assert llm_providers.get("custom_provider_api_key") == "***"