mirror of
https://github.com/tiennm99/litellm.git
synced 2026-07-20 20:19:04 +00:00
fix(internal_user_endpoints.py): delete member from team table on /user/delete (#12926)
removes user from team when user is deleted
This commit is contained in:
@@ -1403,6 +1403,9 @@ async def delete_user(
|
||||
Parameters:
|
||||
- user_ids: List[str] - The list of user id's to be deleted.
|
||||
"""
|
||||
from litellm.proxy.management_endpoints.team_endpoints import (
|
||||
_cleanup_members_with_roles,
|
||||
)
|
||||
from litellm.proxy.proxy_server import (
|
||||
create_audit_log_for_update,
|
||||
litellm_proxy_admin_name,
|
||||
@@ -1451,6 +1454,34 @@ async def delete_user(
|
||||
)
|
||||
)
|
||||
|
||||
## CLEANUP MEMBERS_WITH_ROLES
|
||||
fetch_all_teams = await prisma_client.db.litellm_teamtable.find_many(
|
||||
where={"team_id": {"in": user_row.teams}}
|
||||
)
|
||||
teams_to_update = []
|
||||
for team in fetch_all_teams:
|
||||
is_member_in_team, new_team_members = _cleanup_members_with_roles(
|
||||
existing_team_row=LiteLLM_TeamTable(**team.model_dump()),
|
||||
data=TeamMemberDeleteRequest(
|
||||
team_id=team.team_id,
|
||||
user_id=user_row.user_id,
|
||||
user_email=user_row.user_email,
|
||||
),
|
||||
)
|
||||
if is_member_in_team:
|
||||
_db_new_team_members: List[dict] = [
|
||||
m.model_dump() for m in new_team_members
|
||||
]
|
||||
team.members_with_roles = json.dumps(_db_new_team_members)
|
||||
teams_to_update.append(team)
|
||||
|
||||
## update teams
|
||||
|
||||
for team in teams_to_update:
|
||||
await prisma_client.db.litellm_teamtable.update(
|
||||
where={"team_id": team.team_id},
|
||||
data={"members_with_roles": team.members_with_roles},
|
||||
)
|
||||
# End of Audit logging
|
||||
|
||||
## DELETE ASSOCIATED KEYS
|
||||
@@ -1468,6 +1499,11 @@ async def delete_user(
|
||||
where={"user_id": {"in": data.user_ids}}
|
||||
)
|
||||
|
||||
## DELETE ASSOCIATED TEAM MEMBERSHIPS
|
||||
await prisma_client.db.litellm_teammembership.delete_many(
|
||||
where={"user_id": {"in": data.user_ids}}
|
||||
)
|
||||
|
||||
## DELETE USERS
|
||||
deleted_users = await prisma_client.db.litellm_usertable.delete_many(
|
||||
where={"user_id": {"in": data.user_ids}}
|
||||
|
||||
@@ -1274,6 +1274,32 @@ async def team_member_add(
|
||||
)
|
||||
|
||||
|
||||
def _cleanup_members_with_roles(
|
||||
existing_team_row: LiteLLM_TeamTable,
|
||||
data: TeamMemberDeleteRequest,
|
||||
) -> Tuple[bool, List[Member]]:
|
||||
"""Cleanup members_with_roles list for a team."""
|
||||
is_member_in_team = False
|
||||
new_team_members: List[Member] = []
|
||||
for m in existing_team_row.members_with_roles:
|
||||
if (
|
||||
data.user_id is not None
|
||||
and m.user_id is not None
|
||||
and data.user_id == m.user_id
|
||||
):
|
||||
is_member_in_team = True
|
||||
continue
|
||||
elif (
|
||||
data.user_email is not None
|
||||
and m.user_email is not None
|
||||
and data.user_email == m.user_email
|
||||
):
|
||||
is_member_in_team = True
|
||||
continue
|
||||
new_team_members.append(m)
|
||||
return is_member_in_team, new_team_members
|
||||
|
||||
|
||||
@router.post(
|
||||
"/team/member_delete",
|
||||
tags=["team management"],
|
||||
@@ -1346,24 +1372,10 @@ async def team_member_delete(
|
||||
)
|
||||
|
||||
## DELETE MEMBER FROM TEAM
|
||||
is_member_in_team = False
|
||||
new_team_members: List[Member] = []
|
||||
for m in existing_team_row.members_with_roles:
|
||||
if (
|
||||
data.user_id is not None
|
||||
and m.user_id is not None
|
||||
and data.user_id == m.user_id
|
||||
):
|
||||
is_member_in_team = True
|
||||
continue
|
||||
elif (
|
||||
data.user_email is not None
|
||||
and m.user_email is not None
|
||||
and data.user_email == m.user_email
|
||||
):
|
||||
is_member_in_team = True
|
||||
continue
|
||||
new_team_members.append(m)
|
||||
is_member_in_team, new_team_members = _cleanup_members_with_roles(
|
||||
existing_team_row=existing_team_row,
|
||||
data=data,
|
||||
)
|
||||
|
||||
if not is_member_in_team:
|
||||
raise HTTPException(status_code=400, detail={"error": "User not found in team"})
|
||||
|
||||
+4
-8
@@ -3370,9 +3370,7 @@ class Router:
|
||||
):
|
||||
|
||||
def sync_wrapper(
|
||||
custom_llm_provider: Optional[
|
||||
str
|
||||
] = None,
|
||||
custom_llm_provider: Optional[str] = None,
|
||||
client: Optional[Any] = None,
|
||||
**kwargs,
|
||||
):
|
||||
@@ -3384,9 +3382,7 @@ class Router:
|
||||
|
||||
# Handle asynchronous call types
|
||||
async def async_wrapper(
|
||||
custom_llm_provider: Optional[
|
||||
str
|
||||
] = None,
|
||||
custom_llm_provider: Optional[str] = None,
|
||||
client: Optional[Any] = None,
|
||||
**kwargs,
|
||||
):
|
||||
@@ -3451,7 +3447,7 @@ class Router:
|
||||
)
|
||||
|
||||
return async_wrapper
|
||||
|
||||
|
||||
async def _init_vector_store_api_endpoints(
|
||||
self,
|
||||
original_function: Callable,
|
||||
@@ -5021,7 +5017,7 @@ class Router:
|
||||
return deployment
|
||||
except Exception as e:
|
||||
if self.ignore_invalid_deployments:
|
||||
verbose_router_logger.warning(
|
||||
verbose_router_logger.debug(
|
||||
f"Error upserting deployment: {e}, ignoring and continuing with other deployments."
|
||||
)
|
||||
return None
|
||||
|
||||
Reference in New Issue
Block a user