mirror of
https://github.com/tiennm99/litellm.git
synced 2026-08-02 14:22:16 +00:00
fix: populate user_id and user_info for admin users in /user/info (#22239)
* fix: populate user_id and user_info for admin users in /user/info endpoint Fixes #22179 When admin users call /user/info without a user_id parameter, the endpoint was returning null for both user_id and user_info fields. This broke budgeting tooling that relies on /user/info to look up current budget and spend. Changes: - Modified _get_user_info_for_proxy_admin() to accept user_api_key_dict parameter - Added logic to fetch admin's own user info from database - Updated function to return admin's user_id and user_info instead of null - Updated unit test to verify admin user_id is populated The fix ensures admin users get their own user information just like regular users. * test: make mock get_data signature match real method - Updated MockPrismaClientDB.get_data() to accept all parameters that the real method accepts - Makes mock more robust against future refactors - Added datetime and Union imports - Mock now returns None when user_id is not provided
This commit is contained in:
@@ -2,7 +2,8 @@ import asyncio
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from typing import Any, Dict, List, Optional
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict, List, Optional, Union
|
||||
from unittest.mock import Mock
|
||||
|
||||
import pytest
|
||||
@@ -1486,12 +1487,46 @@ class MockPrismaClientDB:
|
||||
mock_key_data,
|
||||
):
|
||||
self.db = MockDb(mock_team_data, mock_key_data)
|
||||
|
||||
async def get_data(
|
||||
self,
|
||||
token: Optional[Union[str, list]] = None,
|
||||
user_id: Optional[str] = None,
|
||||
user_id_list: Optional[list] = None,
|
||||
team_id: Optional[str] = None,
|
||||
team_id_list: Optional[list] = None,
|
||||
key_val: Optional[dict] = None,
|
||||
table_name: Optional[str] = None,
|
||||
query_type: str = "find_unique",
|
||||
expires: Optional[datetime] = None,
|
||||
reset_at: Optional[datetime] = None,
|
||||
offset: Optional[int] = None,
|
||||
limit: Optional[int] = None,
|
||||
):
|
||||
"""Mock get_data method to return user info for admin"""
|
||||
from litellm.proxy._types import LiteLLM_UserTable
|
||||
|
||||
# Return a proper LiteLLM_UserTable object when querying by user_id
|
||||
if user_id:
|
||||
return LiteLLM_UserTable(
|
||||
user_id=user_id,
|
||||
user_role="proxy_admin",
|
||||
spend=0.0,
|
||||
max_budget=None,
|
||||
)
|
||||
return None
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_user_info_for_proxy_admin(mock_team_data, mock_key_data):
|
||||
# Patch the prisma_client import
|
||||
from litellm.proxy._types import UserInfoResponse
|
||||
from litellm.proxy._types import UserAPIKeyAuth, UserInfoResponse
|
||||
|
||||
# Create a mock user_api_key_dict for admin user
|
||||
mock_user_api_key_dict = UserAPIKeyAuth(
|
||||
user_id="admin_user_123",
|
||||
user_role="proxy_admin",
|
||||
)
|
||||
|
||||
with patch(
|
||||
"litellm.proxy.proxy_server.prisma_client",
|
||||
@@ -1502,11 +1537,18 @@ async def test_get_user_info_for_proxy_admin(mock_team_data, mock_key_data):
|
||||
)
|
||||
|
||||
# Execute the function
|
||||
result = await _get_user_info_for_proxy_admin()
|
||||
result = await _get_user_info_for_proxy_admin(
|
||||
user_api_key_dict=mock_user_api_key_dict
|
||||
)
|
||||
|
||||
# Verify the result structure
|
||||
assert isinstance(result, UserInfoResponse)
|
||||
assert len(result.keys) == 2
|
||||
# Verify admin's user_id is populated
|
||||
assert result.user_id == "admin_user_123"
|
||||
# Verify admin's user_info is populated
|
||||
assert result.user_info is not None
|
||||
assert result.user_info["user_id"] == "admin_user_123"
|
||||
|
||||
|
||||
def test_custom_openid_response():
|
||||
|
||||
Reference in New Issue
Block a user