Skip to content

Commit a4f0f25

Browse files
authored
fix: Fix issue causing masking of empty loop or thread check while loading tool/toolset (#227)
* chore: Add unit test cases * chore: Delint * feat: Warn on insecure tool invocation with authentication This change introduces a warning that is displayed immediately before a tool invocation if: 1. The invocation includes an authentication header. 2. The connection is being made over non-secure HTTP. > [!IMPORTANT] The purpose of this warning is to alert the user to the security risk of sending credentials over an unencrypted channel and to encourage the use of HTTPS. * fix!: Warn about https only during tool initialization * fix: Fix issue causing masking of emtpy loop or thread check while loading tool/toolset * chore: Remove unused condition in client test mocks
1 parent 787ba5d commit a4f0f25

File tree

2 files changed

+8
-11
lines changed

2 files changed

+8
-11
lines changed

packages/toolbox-core/src/toolbox_core/sync_client.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
1516
import asyncio
1617
from threading import Thread
1718
from typing import Any, Callable, Coroutine, Mapping, Optional, TypeVar, Union
@@ -59,7 +60,7 @@ async def create_client():
5960

6061
# Ignoring type since we're already checking the existence of a loop above.
6162
self.__async_client = asyncio.run_coroutine_threadsafe(
62-
create_client(), self.__class__.__loop # type: ignore
63+
create_client(), self.__class__.__loop
6364
).result()
6465

6566
def close(self):
@@ -101,11 +102,10 @@ def load_tool(
101102
"""
102103
coro = self.__async_client.load_tool(name, auth_token_getters, bound_params)
103104

104-
# We have already created a new loop in the init method in case it does not already exist
105-
async_tool = asyncio.run_coroutine_threadsafe(coro, self.__loop).result() # type: ignore
106-
107105
if not self.__loop or not self.__thread:
108106
raise ValueError("Background loop or thread cannot be None.")
107+
108+
async_tool = asyncio.run_coroutine_threadsafe(coro, self.__loop).result()
109109
return ToolboxSyncTool(async_tool, self.__loop, self.__thread)
110110

111111
def load_toolset(
@@ -130,11 +130,10 @@ def load_toolset(
130130
"""
131131
coro = self.__async_client.load_toolset(name, auth_token_getters, bound_params)
132132

133-
# We have already created a new loop in the init method in case it does not already exist
134-
async_tools = asyncio.run_coroutine_threadsafe(coro, self.__loop).result() # type: ignore
135-
136133
if not self.__loop or not self.__thread:
137134
raise ValueError("Background loop or thread cannot be None.")
135+
136+
async_tools = asyncio.run_coroutine_threadsafe(coro, self.__loop).result() # type: ignore
138137
return [
139138
ToolboxSyncTool(async_tool, self.__loop, self.__thread)
140139
for async_tool in async_tools

packages/toolbox-core/tests/test_client.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -301,10 +301,8 @@ async def client(self, aioresponses, test_tool_auth, tool_name, expected_header)
301301

302302
# mock tool INVOKE call
303303
def require_headers(url, **kwargs):
304-
if kwargs["headers"].get("my-auth-service_token") == expected_header:
305-
return CallbackResult(status=200, body="{}")
306-
else:
307-
return CallbackResult(status=400, body="{}")
304+
assert kwargs["headers"].get("my-auth-service_token") == expected_header
305+
return CallbackResult(status=200, body="{}")
308306

309307
aioresponses.post(
310308
f"{TEST_BASE_URL}/api/tool/{tool_name}/invoke",

0 commit comments

Comments
 (0)