fix(proxy): allow internal users to view their own spend-log detail

This commit is contained in:
oopsoonk 2026-05-11 17:12:08 +08:00
parent aa587bd9d3
commit 36962d0cb0
2 changed files with 49 additions and 1 deletions

View file

@ -596,6 +596,7 @@ class LiteLLMRoutes(enum.Enum):
"/spend/calculate",
"/spend/logs",
"/spend/logs/ui",
"/spend/logs/ui/{request_id}",
"/spend/logs/session/ui",
"/cost/estimate",
]
@ -772,7 +773,6 @@ class LiteLLMRoutes(enum.Enum):
"/customer/info",
# UI Logs page detail drawer (single + session). The list endpoint
# `/spend/logs/ui` is covered via spend_tracking_routes below.
"/spend/logs/ui/{logId}",
"/spend/logs/session/ui",
# Settings / observability read endpoints exposed in admin-only
# sidebar groups (Logging & Alerts, Admin Settings, Budgets,

View file

@ -2102,3 +2102,51 @@ async def test_initialize_pass_through_registers_wildcard_for_auth_subpath():
)
for k in registered:
InitPassThroughEndpointHelpers.remove_endpoint_routes(k.split(":")[0])
# ── Regression: internal-user roles can view their own spend-log detail ──────
#
# `/spend/logs/ui/<request_id>` (the detail-drawer endpoint behind row clicks
# on the dashboard Logs page) was previously missing from
# `spend_tracking_routes`, which feeds both `internal_user_routes` and
# `internal_user_view_only_routes`. That meant every non-admin click on a log
# row produced a 401, wrapped by `_raise_admin_only_route_exception` into the
# misleading "Only proxy admin can be used to..." message.
@pytest.mark.parametrize(
"route",
[
"/spend/logs/ui",
"/spend/logs/ui/2fb2085b-6703-4ed4-81aa-0a586d0affeb",
"/spend/logs/session/ui",
],
)
@pytest.mark.parametrize(
"role",
[
LitellmUserRoles.INTERNAL_USER,
LitellmUserRoles.INTERNAL_USER_VIEW_ONLY,
],
)
def test_internal_user_roles_can_view_own_log_detail(route, role):
"""Internal users (read-write and view-only) must reach the per-user log
handlers; the handlers themselves enforce per-user filtering."""
user_obj = LiteLLM_UserTable(
user_id="some-user-id",
user_email="user@example.com",
user_role=role.value,
)
valid_token = UserAPIKeyAuth(user_id="some-user-id", user_role=role.value)
request = MagicMock(spec=Request)
request.query_params = {}
try:
RouteChecks.non_proxy_admin_allowed_routes_check(
user_obj=user_obj,
_user_role=role.value,
route=route,
request=request,
valid_token=valid_token,
request_data={},
)
except Exception as e:
pytest.fail(f"{role.value} should access {route}; got: {e}")