mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-10 22:41:41 +00:00
151 lines
4.8 KiB
Python
151 lines
4.8 KiB
Python
import pytest
|
|
from unittest.mock import MagicMock
|
|
|
|
from fastapi import HTTPException, Request
|
|
|
|
from litellm.proxy._types import (
|
|
LiteLLM_UserTable,
|
|
LiteLLMRoutes,
|
|
LitellmUserRoles,
|
|
UserAPIKeyAuth,
|
|
)
|
|
from litellm.proxy.auth.route_checks import RouteChecks
|
|
|
|
|
|
def test_info_route_identification():
|
|
"""Test that info routes are correctly identified"""
|
|
for route in LiteLLMRoutes.info_routes.value:
|
|
assert RouteChecks.is_info_route(route) is True
|
|
|
|
# Non-info routes should return False
|
|
assert RouteChecks.is_info_route("/chat/completions") is False
|
|
assert RouteChecks.is_info_route("/key/generate") is False
|
|
|
|
|
|
def test_key_info_route_access():
|
|
"""Test access control for /key/info route"""
|
|
# This route handles its own access control, so it should pass for any user
|
|
user_obj = LiteLLM_UserTable(
|
|
user_id="test_user",
|
|
user_email="test@example.com",
|
|
user_role=LitellmUserRoles.INTERNAL_USER,
|
|
)
|
|
valid_token = UserAPIKeyAuth(user_id="test_user")
|
|
request = MagicMock(spec=Request)
|
|
request.query_params = {}
|
|
|
|
# Should not raise exception as /key/info handles its own logic
|
|
RouteChecks.non_proxy_admin_allowed_routes_check(
|
|
user_obj=user_obj,
|
|
_user_role=LitellmUserRoles.INTERNAL_USER,
|
|
route="/key/info",
|
|
request=request,
|
|
valid_token=valid_token,
|
|
request_data={},
|
|
)
|
|
|
|
|
|
def test_user_info_route_access():
|
|
"""Test access control for /user/info route"""
|
|
user_obj = LiteLLM_UserTable(
|
|
user_id="test_user",
|
|
user_email="test@example.com",
|
|
user_role=LitellmUserRoles.INTERNAL_USER,
|
|
)
|
|
valid_token = UserAPIKeyAuth(user_id="test_user")
|
|
request = MagicMock(spec=Request)
|
|
request.query_params = {"user_id": "test_user"}
|
|
|
|
# Should not raise exception when user_id matches token's user_id
|
|
RouteChecks.non_proxy_admin_allowed_routes_check(
|
|
user_obj=user_obj,
|
|
_user_role=LitellmUserRoles.INTERNAL_USER,
|
|
route="/user/info",
|
|
request=request,
|
|
valid_token=valid_token,
|
|
request_data={},
|
|
)
|
|
|
|
# Should raise exception when user_id does not match
|
|
request.query_params = {"user_id": "different_user"}
|
|
with pytest.raises(HTTPException) as exc_info:
|
|
RouteChecks.non_proxy_admin_allowed_routes_check(
|
|
user_obj=user_obj,
|
|
_user_role=LitellmUserRoles.INTERNAL_USER,
|
|
route="/user/info",
|
|
request=request,
|
|
valid_token=valid_token,
|
|
request_data={},
|
|
)
|
|
assert exc_info.value.status_code == 403
|
|
|
|
|
|
def test_model_info_route_access():
|
|
"""Test access control for /model/info route"""
|
|
user_obj = LiteLLM_UserTable(
|
|
user_id="test_user",
|
|
user_email="test@example.com",
|
|
user_role=LitellmUserRoles.INTERNAL_USER,
|
|
)
|
|
valid_token = UserAPIKeyAuth(user_id="test_user")
|
|
request = MagicMock(spec=Request)
|
|
request.query_params = {}
|
|
|
|
# Should not raise exception as /model/info is accessible to show user's models
|
|
RouteChecks.non_proxy_admin_allowed_routes_check(
|
|
user_obj=user_obj,
|
|
_user_role=LitellmUserRoles.INTERNAL_USER,
|
|
route="/model/info",
|
|
request=request,
|
|
valid_token=valid_token,
|
|
request_data={},
|
|
)
|
|
|
|
|
|
def test_team_info_route_access():
|
|
"""Test access control for /team/info route"""
|
|
user_obj = LiteLLM_UserTable(
|
|
user_id="test_user",
|
|
user_email="test@example.com",
|
|
user_role=LitellmUserRoles.INTERNAL_USER,
|
|
)
|
|
valid_token = UserAPIKeyAuth(user_id="test_user")
|
|
request = MagicMock(spec=Request)
|
|
request.query_params = {}
|
|
|
|
# Should not raise exception as /team/info handles its own logic
|
|
RouteChecks.non_proxy_admin_allowed_routes_check(
|
|
user_obj=user_obj,
|
|
_user_role=LitellmUserRoles.INTERNAL_USER,
|
|
route="/team/info",
|
|
request=request,
|
|
valid_token=valid_token,
|
|
request_data={},
|
|
)
|
|
|
|
|
|
def test_v2_user_info_route_in_info_routes():
|
|
"""Test that /v2/user/info is in the info_routes list"""
|
|
assert "/v2/user/info" in LiteLLMRoutes.info_routes.value
|
|
|
|
|
|
def test_v2_user_info_route_access():
|
|
"""Test access control for /v2/user/info route - handled by endpoint itself"""
|
|
user_obj = LiteLLM_UserTable(
|
|
user_id="test_user",
|
|
user_email="test@example.com",
|
|
user_role=LitellmUserRoles.INTERNAL_USER,
|
|
)
|
|
valid_token = UserAPIKeyAuth(user_id="test_user")
|
|
request = MagicMock(spec=Request)
|
|
request.query_params = {"user_id": "other_user"}
|
|
|
|
# Should not raise exception as /v2/user/info handles its own RBAC logic in the handler
|
|
RouteChecks.non_proxy_admin_allowed_routes_check(
|
|
user_obj=user_obj,
|
|
_user_role=LitellmUserRoles.INTERNAL_USER,
|
|
route="/v2/user/info",
|
|
request=request,
|
|
valid_token=valid_token,
|
|
request_data={},
|
|
)
|