Add user delete process
This commit is contained in:
@@ -8,7 +8,7 @@ from fastapi import APIRouter, Depends, HTTPException, status, Path, Query
|
||||
from typing import List, Dict, Any
|
||||
from uuid import UUID
|
||||
|
||||
from app.schemas.tenants import TenantMemberResponse, AddMemberWithUserCreate
|
||||
from app.schemas.tenants import TenantMemberResponse, AddMemberWithUserCreate, TenantResponse
|
||||
from app.services.tenant_service import EnhancedTenantService
|
||||
from shared.auth.decorators import get_current_user_dep
|
||||
from shared.routing.route_builder import RouteBuilder
|
||||
@@ -269,3 +269,157 @@ async def remove_team_member(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail="Failed to remove team member"
|
||||
)
|
||||
|
||||
@router.delete(route_builder.build_base_route("user/{user_id}/memberships", include_tenant_prefix=False))
|
||||
@track_endpoint_metrics("user_memberships_delete")
|
||||
async def delete_user_memberships(
|
||||
user_id: str = Path(..., description="User ID"),
|
||||
current_user: Dict[str, Any] = Depends(get_current_user_dep),
|
||||
tenant_service: EnhancedTenantService = Depends(get_enhanced_tenant_service)
|
||||
):
|
||||
"""
|
||||
Delete all tenant memberships for a user.
|
||||
Used by auth service when deleting a user account.
|
||||
Only accessible by internal services.
|
||||
"""
|
||||
|
||||
logger.info(
|
||||
"Delete user memberships request received",
|
||||
user_id=user_id,
|
||||
requesting_service=current_user.get("service", "unknown"),
|
||||
is_service=current_user.get("type") == "service"
|
||||
)
|
||||
|
||||
# Only allow internal service calls
|
||||
if current_user.get("type") != "service":
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="This endpoint is only accessible to internal services"
|
||||
)
|
||||
|
||||
try:
|
||||
result = await tenant_service.delete_user_memberships(user_id)
|
||||
|
||||
logger.info(
|
||||
"User memberships deleted successfully",
|
||||
user_id=user_id,
|
||||
deleted_count=result.get("deleted_count"),
|
||||
total_memberships=result.get("total_memberships")
|
||||
)
|
||||
|
||||
return {
|
||||
"message": "User memberships deleted successfully",
|
||||
"summary": result
|
||||
}
|
||||
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error("Delete user memberships failed",
|
||||
user_id=user_id,
|
||||
error=str(e))
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail="Failed to delete user memberships"
|
||||
)
|
||||
|
||||
@router.post(route_builder.build_base_route("{tenant_id}/transfer-ownership", include_tenant_prefix=False), response_model=TenantResponse)
|
||||
@track_endpoint_metrics("tenant_transfer_ownership")
|
||||
async def transfer_ownership(
|
||||
new_owner_id: str,
|
||||
tenant_id: UUID = Path(..., description="Tenant ID"),
|
||||
current_user: Dict[str, Any] = Depends(get_current_user_dep),
|
||||
tenant_service: EnhancedTenantService = Depends(get_enhanced_tenant_service)
|
||||
):
|
||||
"""
|
||||
Transfer tenant ownership to another admin.
|
||||
Only the current owner or internal services can perform this action.
|
||||
"""
|
||||
|
||||
logger.info(
|
||||
"Transfer ownership request received",
|
||||
tenant_id=str(tenant_id),
|
||||
new_owner_id=new_owner_id,
|
||||
requesting_user=current_user.get("user_id"),
|
||||
is_service=current_user.get("type") == "service"
|
||||
)
|
||||
|
||||
try:
|
||||
# Get current tenant to find current owner
|
||||
tenant_info = await tenant_service.get_tenant_by_id(str(tenant_id))
|
||||
if not tenant_info:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Tenant not found"
|
||||
)
|
||||
|
||||
current_owner_id = tenant_info.owner_id
|
||||
|
||||
result = await tenant_service.transfer_tenant_ownership(
|
||||
str(tenant_id),
|
||||
current_owner_id,
|
||||
new_owner_id,
|
||||
requesting_user_id=current_user.get("user_id")
|
||||
)
|
||||
|
||||
logger.info(
|
||||
"Ownership transferred successfully",
|
||||
tenant_id=str(tenant_id),
|
||||
from_owner=current_owner_id,
|
||||
to_owner=new_owner_id
|
||||
)
|
||||
|
||||
return result
|
||||
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error("Transfer ownership failed",
|
||||
tenant_id=str(tenant_id),
|
||||
new_owner_id=new_owner_id,
|
||||
error=str(e))
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail="Failed to transfer ownership"
|
||||
)
|
||||
|
||||
@router.get(route_builder.build_base_route("{tenant_id}/admins", include_tenant_prefix=False), response_model=List[TenantMemberResponse])
|
||||
@track_endpoint_metrics("tenant_get_admins")
|
||||
async def get_tenant_admins(
|
||||
tenant_id: UUID = Path(..., description="Tenant ID"),
|
||||
current_user: Dict[str, Any] = Depends(get_current_user_dep),
|
||||
tenant_service: EnhancedTenantService = Depends(get_enhanced_tenant_service)
|
||||
):
|
||||
"""
|
||||
Get all admins (owner + admins) for a tenant.
|
||||
Used by auth service to check for other admins before tenant deletion.
|
||||
"""
|
||||
|
||||
logger.info(
|
||||
"Get tenant admins request received",
|
||||
tenant_id=str(tenant_id),
|
||||
requesting_user=current_user.get("user_id"),
|
||||
is_service=current_user.get("type") == "service"
|
||||
)
|
||||
|
||||
try:
|
||||
admins = await tenant_service.get_tenant_admins(str(tenant_id))
|
||||
|
||||
logger.info(
|
||||
"Retrieved tenant admins",
|
||||
tenant_id=str(tenant_id),
|
||||
admin_count=len(admins)
|
||||
)
|
||||
|
||||
return admins
|
||||
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error("Get tenant admins failed",
|
||||
tenant_id=str(tenant_id),
|
||||
error=str(e))
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail="Failed to get tenant admins"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user