From a88b57e53de56724a966458abcce6a0eb8d29e12 Mon Sep 17 00:00:00 2001 From: jesus Date: Sun, 1 Nov 2026 01:54:15 +0000 Subject: [PATCH] fix(proxy): drop unbounded IN from org admin check in /v2/user/info --- .../management_endpoints/internal_user_endpoints.py | 10 ++++------ .../test_internal_user_endpoints.py | 11 ++--------- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/litellm/proxy/management_endpoints/internal_user_endpoints.py b/litellm/proxy/management_endpoints/internal_user_endpoints.py index 95f30279bc8..d2aac9cae38 100644 --- a/litellm/proxy/management_endpoints/internal_user_endpoints.py +++ b/litellm/proxy/management_endpoints/internal_user_endpoints.py @@ -1111,13 +1111,11 @@ async def _target_in_caller_admin_org( ) if not admin_memberships: return False - shared_membership: Final = await prisma_client.db.litellm_organizationmembership.find_first( - where={ - "user_id": target_user_id, - "organization_id": {"in": [membership.organization_id for membership in admin_memberships]}, - } + admin_org_ids: Final = {membership.organization_id for membership in admin_memberships} + target_memberships: Final = await prisma_client.db.litellm_organizationmembership.find_many( + where={"user_id": target_user_id} ) - return shared_membership is not None + return any(membership.organization_id in admin_org_ids for membership in target_memberships) @router.get( diff --git a/tests/unit/proxy/management_endpoints/test_internal_user_endpoints.py b/tests/unit/proxy/management_endpoints/test_internal_user_endpoints.py index 6d6b6f8d4b4..d8aa0239e2d 100644 --- a/tests/unit/proxy/management_endpoints/test_internal_user_endpoints.py +++ b/tests/unit/proxy/management_endpoints/test_internal_user_endpoints.py @@ -3738,11 +3738,8 @@ _ORG_MEMBERSHIPS: Final = ( def _membership_matches(membership: SimpleNamespace, where: Mapping[str, object]) -> bool: - org_filter: Final = where.get("organization_id") - return ( - membership.user_id == where["user_id"] - and ("user_role" not in where or membership.user_role == where["user_role"]) - and (not isinstance(org_filter, dict) or membership.organization_id in org_filter["in"]) + return membership.user_id == where["user_id"] and ( + "user_role" not in where or membership.user_role == where["user_role"] ) @@ -3760,13 +3757,9 @@ def _org_admin_prisma(mocker: MockerFixture) -> MagicMock: async def find_many(**kwargs: Mapping[str, object]) -> list[SimpleNamespace]: return [m for m in _ORG_MEMBERSHIPS if _membership_matches(m, kwargs["where"])] - async def find_first(**kwargs: Mapping[str, object]) -> SimpleNamespace | None: - return next((m for m in _ORG_MEMBERSHIPS if _membership_matches(m, kwargs["where"])), None) - prisma: Final = mocker.MagicMock() prisma.db.litellm_usertable.find_unique = mocker.AsyncMock(side_effect=find_unique) prisma.db.litellm_organizationmembership.find_many = mocker.AsyncMock(side_effect=find_many) - prisma.db.litellm_organizationmembership.find_first = mocker.AsyncMock(side_effect=find_first) return prisma