feat: add endpoints to get tools per user

This commit is contained in:
Christopher Gondek 2025-10-09 16:23:29 +02:00
parent 4b75ffd70c
commit 2b5d7506d0
2 changed files with 134 additions and 0 deletions

View file

@ -890,3 +890,52 @@ async def update_tool(
logger.info(f"Successfully updated tool {tool_id}, fields: {updated_fields}")
return updated_fields
async def get_tools_for_user(*, user_id: str, session: AsyncSession) -> List[dict]:
"""Get all tools granted to a specific user.
Args:
user_id: The user ID to get tools for.
session: The database session for querying.
Returns:
List of tool dictionaries with all tool information.
"""
from modules.features.chatBot.database import Tool, UserToolMapping
logger.info(f"Fetching tools for user {user_id}")
# Query tools that are granted to the user
# Join UserToolMapping with Tool table
# Filter by user_id and active status
stmt = (
select(Tool)
.join(UserToolMapping, Tool.id == UserToolMapping.tool_id)
.where(
UserToolMapping.user_id == user_id,
UserToolMapping.is_active == True,
Tool.is_active == True,
)
.order_by(Tool.category, Tool.name)
)
result = await session.execute(stmt)
tools = result.scalars().all()
tool_list = []
for tool in tools:
tool_dict = {
"id": str(tool.id),
"tool_id": tool.tool_id,
"name": tool.name,
"label": tool.label,
"category": tool.category,
"description": tool.description,
"is_active": tool.is_active,
"date_created": tool.date_created.timestamp(),
"date_updated": tool.date_updated.timestamp(),
}
tool_list.append(tool_dict)
logger.info(f"Retrieved {len(tool_list)} tools for user {user_id}")
return tool_list

View file

@ -534,3 +534,88 @@ async def update_tool(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Failed to update tool: {type(e).__name__}: {str(e) or 'No error message provided'}",
)
@router.get("/tools/user/{user_id}", response_model=ToolListResponse)
@limiter.limit("30/minute")
async def get_tools_for_specific_user(
*,
request: Request,
user_id: str,
currentUser: User = Depends(getCurrentUser),
session: AsyncSession = Depends(get_async_db_session),
) -> ToolListResponse:
"""
Get all tools granted to a specific user.
Only accessible to system administrators.
"""
try:
# Check SYSADMIN permission
if currentUser.privilege != UserPrivilege.SYSADMIN:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Only system administrators can view user tools",
)
# Get tools for the specified user
tools_data = await chat_service.get_tools_for_user(
user_id=user_id, session=session
)
# Convert to ToolInfo objects
tools = [ToolInfo(**tool) for tool in tools_data]
logger.info(
f"User {currentUser.id} retrieved {len(tools)} tools for user {user_id}"
)
return ToolListResponse(tools=tools)
except HTTPException:
raise
except Exception as e:
logger.error(
f"Error retrieving tools for user {user_id}: {type(e).__name__}: {str(e)}",
exc_info=True,
)
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Failed to retrieve tools for user: {type(e).__name__}: {str(e) or 'No error message provided'}",
)
@router.get("/tools/me", response_model=ToolListResponse)
@limiter.limit("30/minute")
async def get_my_tools(
*,
request: Request,
currentUser: User = Depends(getCurrentUser),
session: AsyncSession = Depends(get_async_db_session),
) -> ToolListResponse:
"""
Get all tools the current user has access to.
"""
try:
# Get tools for the current user
tools_data = await chat_service.get_tools_for_user(
user_id=currentUser.id, session=session
)
# Convert to ToolInfo objects
tools = [ToolInfo(**tool) for tool in tools_data]
logger.info(
f"User {currentUser.id} retrieved {len(tools)} tools for themselves"
)
return ToolListResponse(tools=tools)
except Exception as e:
logger.error(
f"Error retrieving tools for user {currentUser.id}: {type(e).__name__}: {str(e)}",
exc_info=True,
)
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Failed to retrieve your tools: {type(e).__name__}: {str(e) or 'No error message provided'}",
)