mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-13 08:52:02 +00:00
fix(alerts): honor explicit parent route grants
This commit is contained in:
parent
d8d98d0133
commit
a363f68c3c
3 changed files with 19 additions and 3 deletions
|
|
@ -49,6 +49,8 @@ ScopeId: TypeAlias = Annotated[str | None, Query(min_length=1, max_length=1024)]
|
|||
def _allows_write(grant: str, route: str) -> bool:
|
||||
if grant == "info_routes":
|
||||
return False
|
||||
if route == grant or route.startswith(grant + "/"):
|
||||
return True
|
||||
paths: Final = (
|
||||
TypeAdapter(tuple[str, ...]).validate_python(LiteLLMRoutes[grant].value)
|
||||
if grant in LiteLLMRoutes.__members__
|
||||
|
|
|
|||
|
|
@ -39,12 +39,13 @@ async def test_alert_resource_labels_bound_legacy_display_values(db: ManagementD
|
|||
await repository.database.query_raw('DELETE FROM "LiteLLM_UserTable" WHERE user_id=$1', identity)
|
||||
|
||||
|
||||
def test_scoped_rules_use_real_management_auth_and_preserve_read_only_roles(gateway: Gateway) -> None:
|
||||
@pytest.mark.parametrize("grant", ["management_routes", "/usage", "/usage/alert-rules"])
|
||||
def test_scoped_rules_use_real_management_auth_and_preserve_read_only_roles(gateway: Gateway, grant: str) -> None:
|
||||
with gateway.scenario() as scenario:
|
||||
owner: Final = scenario.user(user_role="internal_user")
|
||||
outsider: Final = scenario.user(user_role="internal_user")
|
||||
viewer: Final = scenario.user(user_role="proxy_admin_viewer")
|
||||
owner_key: Final = scenario.key(user_id=owner, key_type="management")
|
||||
owner_key: Final = scenario.key(user_id=owner, key_type="default", allowed_routes=[grant])
|
||||
outsider_key: Final = scenario.key(user_id=outsider, key_type="management")
|
||||
viewer_key: Final = scenario.key(user_id=viewer, key_type="read_only")
|
||||
inference_key: Final = scenario.key(user_id=owner, key_type="llm_api")
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import pytest
|
|||
from fastapi import HTTPException
|
||||
|
||||
from litellm.proxy._types import UserAPIKeyAuth
|
||||
from litellm.proxy.alerting_endpoints.usage_alerts import require_scope, require_write_access
|
||||
from litellm.proxy.alerting_endpoints.usage_alerts import _allows_write, require_scope, require_write_access
|
||||
from litellm.repositories.usage_alerts import UsageAlertsRepository, activity_path
|
||||
from litellm.types.proxy.auth.user_roles import LitellmUserRoles
|
||||
|
||||
|
|
@ -25,6 +25,19 @@ def test_info_grants_do_not_authorize_mutations(role: LitellmUserRoles, key_type
|
|||
assert error.value.status_code == 403
|
||||
|
||||
|
||||
@pytest.mark.parametrize("grant", ["management_routes", "/usage", "/usage/alert-rules", "/usage/*"])
|
||||
def test_explicit_route_grants_authorize_alert_mutations(grant: str) -> None:
|
||||
assert _allows_write(grant, "/usage/alert-rules/example") is True
|
||||
|
||||
|
||||
@pytest.mark.parametrize("grant", ["/usag", "/usage/alert-rule", "/usage/alerts"])
|
||||
def test_route_grants_require_a_complete_path_segment(grant: str) -> None:
|
||||
user: Final = UserAPIKeyAuth(user_role=LitellmUserRoles.INTERNAL_USER, allowed_routes=[grant])
|
||||
with pytest.raises(HTTPException) as error:
|
||||
require_write_access(user, "/usage/alert-rules/example")
|
||||
assert error.value.status_code == 403
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize(
|
||||
"role,key_type,write",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue