mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-12 23:01:41 +00:00
fix(team): reach the callback routes for a team id containing a colon
The route gate expands {team_id:path} to "[^:]+" so a colon-suffixed provider
route is not swallowed, which means the two entries added here matched a team
id with a slash but not one with a colon, while the router accepts both.
team_id is a free-form string, so a team whose id contains a colon kept the
old proxy-admin-only denial and its admin could not manage its own callbacks.
List both spellings rather than relaxing the shared matcher, which every
":path" route depends on. The comment claimed the two matchers agree; they do
not, so it now says what each placeholder actually accepts.
This commit is contained in:
parent
e64b6f6a68
commit
2e0d81a9da
2 changed files with 19 additions and 4 deletions
|
|
@ -832,10 +832,16 @@ class LiteLLMRoutes(enum.Enum):
|
|||
"/team/{team_id}/members/me",
|
||||
# POST/GET the team's logging callbacks, and DELETE one of them. Every
|
||||
# handler calls _verify_team_access, which admits only a proxy admin, an
|
||||
# org admin for the team, or an admin of this team. The :path converter
|
||||
# mirrors the route registration, which accepts a team id containing "/".
|
||||
# org admin for the team, or an admin of this team.
|
||||
#
|
||||
# Two spellings per route because neither placeholder alone covers every
|
||||
# team id the router accepts: the gate expands {x:path} to "[^:]+", which
|
||||
# takes a slash but not a colon, and {x} to "[^/]+", which takes a colon
|
||||
# but not a slash. team_id is a free-form string, so both are reachable.
|
||||
"/team/{team_id:path}/callback",
|
||||
"/team/{team_id:path}/callback/{callback_name}",
|
||||
"/team/{team_id}/callback",
|
||||
"/team/{team_id}/callback/{callback_name}",
|
||||
"/model/new",
|
||||
"/model/update",
|
||||
"/model/delete",
|
||||
|
|
|
|||
|
|
@ -3551,6 +3551,10 @@ TEAM_CALLBACK_ROUTES = (
|
|||
# contain a slash
|
||||
"/team/tenant/06bda574/callback",
|
||||
"/team/tenant/06bda574/callback/langfuse",
|
||||
# team_id is a free-form string, so it may also contain a colon, which the
|
||||
# gate's :path expansion excludes
|
||||
"/team/tenant:06bda574/callback",
|
||||
"/team/tenant:06bda574/callback/langfuse",
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -3590,8 +3594,13 @@ def test_team_callback_routes_are_self_managed():
|
|||
look identical for an internal_user while silently denying the org admins and
|
||||
view-only roles that list does not cover.
|
||||
"""
|
||||
assert "/team/{team_id:path}/callback" in LiteLLMRoutes.self_managed_routes.value
|
||||
assert "/team/{team_id:path}/callback/{callback_name}" in LiteLLMRoutes.self_managed_routes.value
|
||||
for template in (
|
||||
"/team/{team_id:path}/callback",
|
||||
"/team/{team_id:path}/callback/{callback_name}",
|
||||
"/team/{team_id}/callback",
|
||||
"/team/{team_id}/callback/{callback_name}",
|
||||
):
|
||||
assert template in LiteLLMRoutes.self_managed_routes.value
|
||||
|
||||
|
||||
@pytest.mark.parametrize("route", TEAM_CALLBACK_ROUTES)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue