diff --git a/backend/repository/brain/delete_brain.py b/backend/repository/brain/delete_brain.py new file mode 100644 index 000000000000..acfb418f2703 --- /dev/null +++ b/backend/repository/brain/delete_brain.py @@ -0,0 +1,36 @@ +from uuid import UUID + +from fastapi import HTTPException +from models.brain_entity import BrainType +from models.settings import get_supabase_db + +from repository.api_brain_definition.delete_api_brain_definition import ( + delete_api_brain_definition, +) +from repository.brain import get_brain_by_id +from repository.brain.delete_brain_secrets import delete_brain_secrets +from repository.knowledge.remove_brain_all_knowledge import ( + remove_brain_all_knowledge, +) + + +def delete_brain(brain_id: UUID) -> dict[str, str]: + supabase_db = get_supabase_db() + + brain_to_delete = get_brain_by_id(brain_id=brain_id) + if brain_to_delete is None: + raise HTTPException(status_code=404, detail="Brain not found.") + + if brain_to_delete.brain_type == BrainType.API: + delete_brain_secrets( + brain_id=brain_id, + ) + delete_api_brain_definition(brain_id=brain_id) + else: + remove_brain_all_knowledge(brain_id) + + supabase_db.delete_brain_vector(str(brain_id)) + supabase_db.delete_brain_users(str(brain_id)) + supabase_db.delete_brain(str(brain_id)) + + return {"message": "Brain deleted."} diff --git a/backend/repository/brain/delete_brain_secrets.py b/backend/repository/brain/delete_brain_secrets.py new file mode 100644 index 000000000000..76c9b7cddaca --- /dev/null +++ b/backend/repository/brain/delete_brain_secrets.py @@ -0,0 +1,30 @@ +from uuid import UUID + +from fastapi import HTTPException +from models.settings import get_supabase_db + +from repository.api_brain_definition.get_api_brain_definition import ( + get_api_brain_definition, +) +from repository.external_api_secret import delete_secret + + +def delete_brain_secrets(brain_id: UUID) -> None: + supabase_db = get_supabase_db() + + brain_definition = get_api_brain_definition(brain_id=brain_id) + + if brain_definition is None: + raise HTTPException(status_code=404, detail="Brain definition not found.") + + secrets = brain_definition.secrets + + if len(secrets) > 0: + brain_users = supabase_db.get_brain_users(brain_id=brain_id) + for user in brain_users: + for secret in secrets: + delete_secret( + user_id=user.user_id, + brain_id=brain_id, + secret_name=secret.name, + ) diff --git a/backend/repository/brain/delete_brain_user.py b/backend/repository/brain/delete_brain_user.py index c2f92b580517..8819c810f6bb 100644 --- a/backend/repository/brain/delete_brain_user.py +++ b/backend/repository/brain/delete_brain_user.py @@ -1,10 +1,34 @@ from uuid import UUID +from fastapi import HTTPException +from models.brain_entity import BrainType from models.settings import get_supabase_db +from repository.api_brain_definition.get_api_brain_definition import ( + get_api_brain_definition, +) +from repository.brain.get_brain_by_id import get_brain_by_id +from repository.external_api_secret.delete_secret import delete_secret + def delete_brain_user(user_id: UUID, brain_id: UUID) -> None: supabase_db = get_supabase_db() + brain_to_delete_user_from = get_brain_by_id(brain_id=brain_id) + if brain_to_delete_user_from is None: + raise HTTPException(status_code=404, detail="Brain not found.") + + if brain_to_delete_user_from.brain_type == BrainType.API: + brain_definition = get_api_brain_definition(brain_id=brain_id) + if brain_definition is None: + raise HTTPException(status_code=404, detail="Brain definition not found.") + secrets = brain_definition.secrets + for secret in secrets: + delete_secret( + user_id=user_id, + brain_id=brain_id, + secret_name=secret.name, + ) + supabase_db.delete_brain_user_by_id( user_id=user_id, brain_id=brain_id, diff --git a/backend/repository/brain/get_brain_users.py b/backend/repository/brain/get_brain_users.py new file mode 100644 index 000000000000..f419e261b980 --- /dev/null +++ b/backend/repository/brain/get_brain_users.py @@ -0,0 +1,10 @@ +from uuid import UUID + +from models.brain_entity import BrainUser +from models.settings import get_supabase_db + + +def get_brain_users(brain_id: UUID) -> list[BrainUser]: + supabase_db = get_supabase_db() + + return supabase_db.get_brain_users(brain_id) diff --git a/backend/repository/external_api_secret/delete_secret.py b/backend/repository/external_api_secret/delete_secret.py index d499238c8ecb..bcff88071bf1 100644 --- a/backend/repository/external_api_secret/delete_secret.py +++ b/backend/repository/external_api_secret/delete_secret.py @@ -10,7 +10,7 @@ def delete_secret(user_id: UUID, brain_id: UUID, secret_name: str) -> bool: response = supabase_client.rpc( "delete_secret", { - "name": build_secret_unique_name( + "secret_name": build_secret_unique_name( user_id=user_id, brain_id=brain_id, secret_name=secret_name ), }, diff --git a/backend/routes/subscription_routes.py b/backend/routes/subscription_routes.py index ac4d9d805115..f6531296a60a 100644 --- a/backend/routes/subscription_routes.py +++ b/backend/routes/subscription_routes.py @@ -3,7 +3,7 @@ from auth.auth_bearer import AuthBearer, get_current_user from fastapi import APIRouter, Depends, HTTPException -from models import Brain, BrainSubscription, PromptStatusEnum, UserIdentity +from models import BrainSubscription, PromptStatusEnum, UserIdentity from pydantic import BaseModel from repository.brain import ( create_brain_user, @@ -12,16 +12,15 @@ get_brain_for_user, update_brain_user_rights, ) +from repository.brain.delete_brain import delete_brain from repository.brain.delete_brain_user import delete_brain_user +from repository.brain.get_brain_users import get_brain_users from repository.brain_subscription import ( SubscriptionInvitationService, resend_invitation_email, ) -from repository.knowledge.remove_brain_all_knowledge import ( - remove_brain_all_knowledge, -) from repository.prompt import delete_prompt_by_id, get_prompt_by_id -from repository.user import get_user_email_by_user_id, get_user_id_by_user_email +from repository.user import get_user_id_by_user_email from routes.authorizations.brain_authorization import ( RoleEnum, @@ -99,29 +98,6 @@ def invite_users_to_brain( Depends(has_brain_authorization([RoleEnum.Owner, RoleEnum.Editor])), ], ) -def get_brain_users( - brain_id: UUID, -): - """ - Get all users for a brain - """ - brain = Brain( - id=brain_id, - ) - brain_users = brain.get_brain_users() - - brain_access_list = [] - - for brain_user in brain_users: - brain_access = {} - # TODO: find a way to fetch user email concurrently - brain_access["email"] = get_user_email_by_user_id(brain_user["user_id"]) - brain_access["rights"] = brain_user["rights"] - brain_access_list.append(brain_access) - - return brain_access_list - - @subscription_router.delete( "/brains/{brain_id}/subscription", ) @@ -139,9 +115,6 @@ async def remove_user_subscription( detail="Brain not found while trying to delete", ) - brain = Brain( - id=brain_id, - ) user_brain = get_brain_for_user(current_user.id, brain_id) if user_brain is None: raise HTTPException( @@ -150,21 +123,21 @@ async def remove_user_subscription( ) if user_brain.rights != "Owner": - brain.delete_user_from_brain(current_user.id) + delete_brain_user(current_user.id, brain_id) else: - brain_users = brain.get_brain_users() + brain_users = get_brain_users( + brain_id=brain_id, + ) brain_other_owners = [ brain for brain in brain_users - if brain["rights"] == "Owner" - and str(brain["user_id"]) != str(current_user.id) + if brain.rights == "Owner" and str(brain.user_id) != str(current_user.id) ] if len(brain_other_owners) == 0: - # Delete its prompt if it's private - - remove_brain_all_knowledge(brain_id) - brain.delete_brain(current_user.id) + delete_brain( + brain_id=brain_id, + ) if targeted_brain.prompt_id: brain_to_delete_prompt = get_prompt_by_id(targeted_brain.prompt_id) if brain_to_delete_prompt is not None and ( @@ -173,7 +146,10 @@ async def remove_user_subscription( delete_prompt_by_id(targeted_brain.prompt_id) else: - brain.delete_user_from_brain(current_user.id) + delete_brain_user( + current_user.id, + brain_id, + ) return {"message": f"Subscription removed successfully from brain {brain_id}"} @@ -321,10 +297,6 @@ def update_brain_subscription( detail="User not found", ) - brain = Brain( - id=brain_id, - ) - # check if user is an editor but trying to give high level permissions if subscription.rights == "Owner": try: @@ -363,7 +335,7 @@ def update_brain_subscription( current_user.id, RoleEnum.Owner, ) - brain.delete_user_from_brain(user_id) + delete_brain_user(user_id, brain_id) except HTTPException: raise HTTPException( status_code=403,