import os from pathlib import Path from typing import Optional import logging from open_webui.models.users import Users, UserInfoResponse from open_webui.models.groups import ( Groups, GroupForm, GroupUpdateForm, GroupResponse, UserIdsForm, ) from open_webui.config import CACHE_DIR from open_webui.constants import ERROR_MESSAGES from fastapi import APIRouter, Depends, HTTPException, Request, status from open_webui.internal.db import get_session from sqlalchemy.orm import Session from open_webui.utils.auth import get_admin_user, get_verified_user log = logging.getLogger(__name__) router = APIRouter() ############################ # GetFunctions ############################ @router.get("/", response_model=list[GroupResponse]) async def get_groups( share: Optional[bool] = None, user=Depends(get_verified_user), db: Session = Depends(get_session), ): filter = {} if user.role != "admin": filter["member_id"] = user.id if share is not None: filter["share"] = share groups = Groups.get_groups(filter=filter, db=db) return groups ############################ # CreateNewGroup ############################ @router.post("/create", response_model=Optional[GroupResponse]) async def create_new_group( form_data: GroupForm, user=Depends(get_admin_user), db: Session = Depends(get_session), ): try: group = Groups.insert_new_group(user.id, form_data, db=db) if group: return GroupResponse( **group.model_dump(), member_count=Groups.get_group_member_count_by_id(group.id, db=db), ) else: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT("Error creating group"), ) except Exception as e: log.exception(f"Error creating a new group: {e}") raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT(e), ) ############################ # GetGroupById ############################ @router.get("/id/{id}", response_model=Optional[GroupResponse]) async def get_group_by_id( id: str, user=Depends(get_admin_user), db: Session = Depends(get_session) ): group = Groups.get_group_by_id(id, db=db) if group: return GroupResponse( **group.model_dump(), member_count=Groups.get_group_member_count_by_id(group.id, db=db), ) else: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail=ERROR_MESSAGES.NOT_FOUND, ) ############################ # ExportGroupById ############################ class GroupExportResponse(GroupResponse): user_ids: list[str] = [] pass @router.get("/id/{id}/export", response_model=Optional[GroupExportResponse]) async def export_group_by_id( id: str, user=Depends(get_admin_user), db: Session = Depends(get_session) ): group = Groups.get_group_by_id(id, db=db) if group: return GroupExportResponse( **group.model_dump(), member_count=Groups.get_group_member_count_by_id(group.id, db=db), user_ids=Groups.get_group_user_ids_by_id(group.id, db=db), ) else: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail=ERROR_MESSAGES.NOT_FOUND, ) ############################ # GetUsersInGroupById ############################ @router.post("/id/{id}/users", response_model=list[UserInfoResponse]) async def get_users_in_group( id: str, user=Depends(get_admin_user), db: Session = Depends(get_session) ): try: users = Users.get_users_by_group_id(id, db=db) return users except Exception as e: log.exception(f"Error adding users to group {id}: {e}") raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT(e), ) ############################ # UpdateGroupById ############################ @router.post("/id/{id}/update", response_model=Optional[GroupResponse]) async def update_group_by_id( id: str, form_data: GroupUpdateForm, user=Depends(get_admin_user), db: Session = Depends(get_session), ): try: group = Groups.update_group_by_id(id, form_data, db=db) if group: return GroupResponse( **group.model_dump(), member_count=Groups.get_group_member_count_by_id(group.id, db=db), ) else: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT("Error updating group"), ) except Exception as e: log.exception(f"Error updating group {id}: {e}") raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT(e), ) ############################ # AddUserToGroupByUserIdAndGroupId ############################ @router.post("/id/{id}/users/add", response_model=Optional[GroupResponse]) async def add_user_to_group( id: str, form_data: UserIdsForm, user=Depends(get_admin_user), db: Session = Depends(get_session), ): try: if form_data.user_ids: form_data.user_ids = Users.get_valid_user_ids(form_data.user_ids, db=db) group = Groups.add_users_to_group(id, form_data.user_ids, db=db) if group: return GroupResponse( **group.model_dump(), member_count=Groups.get_group_member_count_by_id(group.id, db=db), ) else: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT("Error adding users to group"), ) except Exception as e: log.exception(f"Error adding users to group {id}: {e}") raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT(e), ) @router.post("/id/{id}/users/remove", response_model=Optional[GroupResponse]) async def remove_users_from_group( id: str, form_data: UserIdsForm, user=Depends(get_admin_user), db: Session = Depends(get_session), ): try: group = Groups.remove_users_from_group(id, form_data.user_ids, db=db) if group: return GroupResponse( **group.model_dump(), member_count=Groups.get_group_member_count_by_id(group.id, db=db), ) else: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT("Error removing users from group"), ) except Exception as e: log.exception(f"Error removing users from group {id}: {e}") raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT(e), ) ############################ # DeleteGroupById ############################ @router.delete("/id/{id}/delete", response_model=bool) async def delete_group_by_id( id: str, user=Depends(get_admin_user), db: Session = Depends(get_session) ): try: result = Groups.delete_group_by_id(id, db=db) if result: return result else: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT("Error deleting group"), ) except Exception as e: log.exception(f"Error deleting group {id}: {e}") raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT(e), )