diff --git a/api/core/helper/model_provider_cache.py b/api/core/helper/model_provider_cache.py index 2b9e6613378..2b7d0d951f1 100644 --- a/api/core/helper/model_provider_cache.py +++ b/api/core/helper/model_provider_cache.py @@ -27,7 +27,7 @@ class ProviderCredentialsCache: try: cached_provider_credentials = cached_provider_credentials.decode("utf-8") cached_provider_credentials = json.loads(cached_provider_credentials) - except JSONDecodeError: + except (JSONDecodeError, UnicodeDecodeError): return None return dict(cached_provider_credentials) diff --git a/api/core/helper/provider_cache.py b/api/core/helper/provider_cache.py index a3b61887892..8e85d444d2c 100644 --- a/api/core/helper/provider_cache.py +++ b/api/core/helper/provider_cache.py @@ -24,7 +24,7 @@ class ProviderCredentialsCache(ABC): try: cached_credentials = cached_credentials.decode("utf-8") return dict(json.loads(cached_credentials)) - except JSONDecodeError: + except (JSONDecodeError, UnicodeDecodeError): return None return None diff --git a/api/core/helper/tool_parameter_cache.py b/api/core/helper/tool_parameter_cache.py index 2650eb0c2c2..6dfe9359d1f 100644 --- a/api/core/helper/tool_parameter_cache.py +++ b/api/core/helper/tool_parameter_cache.py @@ -30,7 +30,7 @@ class ToolParameterCache: try: cached_tool_parameter = cached_tool_parameter.decode("utf-8") cached_tool_parameter = json.loads(cached_tool_parameter) - except JSONDecodeError: + except (JSONDecodeError, UnicodeDecodeError): return None return dict(cached_tool_parameter) diff --git a/api/tests/unit_tests/core/helper/test_model_provider_cache.py b/api/tests/unit_tests/core/helper/test_model_provider_cache.py new file mode 100644 index 00000000000..e66d58a4e9f --- /dev/null +++ b/api/tests/unit_tests/core/helper/test_model_provider_cache.py @@ -0,0 +1,32 @@ +import json + +from pytest_mock import MockerFixture + +from core.helper.model_provider_cache import ProviderCredentialsCache, ProviderCredentialsCacheType + + +def test_model_provider_credentials_cache_get_returns_decoded_dict(mocker: MockerFixture) -> None: + redis_client_mock = mocker.patch("core.helper.model_provider_cache.redis_client") + cache = ProviderCredentialsCache( + tenant_id="tenant", + identity_id="identity", + cache_type=ProviderCredentialsCacheType.PROVIDER, + ) + payload = {"api_key": "secret"} + + redis_client_mock.get.return_value = json.dumps(payload).encode("utf-8") + + assert cache.get() == payload + + +def test_model_provider_credentials_cache_get_returns_none_for_invalid_utf8(mocker: MockerFixture) -> None: + redis_client_mock = mocker.patch("core.helper.model_provider_cache.redis_client") + cache = ProviderCredentialsCache( + tenant_id="tenant", + identity_id="identity", + cache_type=ProviderCredentialsCacheType.PROVIDER, + ) + + redis_client_mock.get.return_value = b"\xff" + + assert cache.get() is None diff --git a/api/tests/unit_tests/core/helper/test_provider_cache.py b/api/tests/unit_tests/core/helper/test_provider_cache.py new file mode 100644 index 00000000000..cf9f9c456d7 --- /dev/null +++ b/api/tests/unit_tests/core/helper/test_provider_cache.py @@ -0,0 +1,24 @@ +import json + +from pytest_mock import MockerFixture + +from core.helper.provider_cache import ToolProviderCredentialsCache + + +def test_provider_credentials_cache_get_returns_decoded_dict(mocker: MockerFixture) -> None: + redis_client_mock = mocker.patch("core.helper.provider_cache.redis_client") + cache = ToolProviderCredentialsCache(tenant_id="tenant", provider="provider", credential_id="credential") + payload = {"api_key": "secret"} + + redis_client_mock.get.return_value = json.dumps(payload).encode("utf-8") + + assert cache.get() == payload + + +def test_provider_credentials_cache_get_returns_none_for_invalid_utf8(mocker: MockerFixture) -> None: + redis_client_mock = mocker.patch("core.helper.provider_cache.redis_client") + cache = ToolProviderCredentialsCache(tenant_id="tenant", provider="provider", credential_id="credential") + + redis_client_mock.get.return_value = b"\xff" + + assert cache.get() is None diff --git a/api/tests/unit_tests/core/helper/test_tool_parameter_cache.py b/api/tests/unit_tests/core/helper/test_tool_parameter_cache.py index 3c8b44d0101..54a9fe51009 100644 --- a/api/tests/unit_tests/core/helper/test_tool_parameter_cache.py +++ b/api/tests/unit_tests/core/helper/test_tool_parameter_cache.py @@ -38,6 +38,21 @@ def test_tool_parameter_cache_get_returns_none_for_invalid_json(mocker: MockerFi assert cache.get() is None +def test_tool_parameter_cache_get_returns_none_for_invalid_utf8(mocker: MockerFixture) -> None: + redis_client_mock = mocker.patch("core.helper.tool_parameter_cache.redis_client") + cache = ToolParameterCache( + tenant_id="tenant", + provider="provider", + tool_name="tool", + cache_type=ToolParameterCacheType.PARAMETER, + identity_id="identity", + ) + + redis_client_mock.get.return_value = b"\xff" + + assert cache.get() is None + + def test_tool_parameter_cache_get_returns_none_when_key_is_missing(mocker: MockerFixture) -> None: redis_client_mock = mocker.patch("core.helper.tool_parameter_cache.redis_client") cache = ToolParameterCache(