Skip to main content
Glama
requests_routes.py9.21 kB
from fastapi import APIRouter, Depends, HTTPException from typing import List from app.auth import get_current_user from app.utils.dependencies import get_rbac_data from app.utils.request_manager import ( create_access_request, get_request_by_id, get_requests_by_user, get_pending_requests_by_admin, review_access_request, apply_approved_request ) from app.models.requests import ( GroupAccessRequestCreate, GroupAccessRequestResponse, GroupAccessRequestReview, RequestStatus ) import logging logger = logging.getLogger(__name__) router = APIRouter( prefix="/requests", tags=["Solicitações"], responses={404: {"description": "Item não encontrado"}} ) @router.post("/", response_model=GroupAccessRequestResponse, summary="Criar solicitação de acesso", description="Cria uma nova solicitação de acesso a um grupo") async def create_request(request: GroupAccessRequestCreate, user=Depends(get_current_user)): """ Cria uma nova solicitação de acesso a um grupo. Os usuários não podem solicitar acesso a grupos que já participam. """ rbac = get_rbac_data() username = user["username"] grupo = request.grupo # Verificar se grupo existe if grupo not in rbac["grupos"]: logger.warning(f"Solicitação para grupo inexistente: {grupo} por {username}") raise HTTPException(status_code=404, detail=f"Grupo '{grupo}' não encontrado") # Verificar se usuário já pertence ao grupo if grupo in rbac["usuarios"][username]["grupos"]: logger.warning(f"Usuário {username} já pertence ao grupo {grupo}") raise HTTPException(status_code=400, detail=f"Você já pertence ao grupo '{grupo}'") # Criar solicitação access_request = create_access_request(username, grupo, request.justificativa) # Converter para modelo de resposta return GroupAccessRequestResponse( request_id=access_request.request_id, username=access_request.username, grupo=access_request.grupo, status=access_request.status, justificativa=access_request.justificativa, created_at=access_request.created_at, updated_at=access_request.updated_at, reviewed_by=access_request.reviewed_by, review_comment=access_request.review_comment ) @router.get("/me", response_model=List[GroupAccessRequestResponse], summary="Minhas solicitações", description="Lista todas as solicitações do usuário atual") async def get_my_requests(user=Depends(get_current_user)): """ Lista todas as solicitações de acesso feitas pelo usuário atual. """ username = user["username"] user_requests = get_requests_by_user(username) # Converter para modelo de resposta return [ GroupAccessRequestResponse( request_id=req.request_id, username=req.username, grupo=req.grupo, status=req.status, justificativa=req.justificativa, created_at=req.created_at, updated_at=req.updated_at, reviewed_by=req.reviewed_by, review_comment=req.review_comment ) for req in user_requests ] @router.get("/admin", response_model=List[GroupAccessRequestResponse], summary="Solicitações pendentes", description="Lista solicitações pendentes para grupos onde o usuário é admin") async def get_admin_requests(user=Depends(get_current_user)): """ Lista todas as solicitações pendentes para grupos onde o usuário é administrador. Administradores globais podem ver solicitações para todos os grupos. """ username = user["username"] rbac = get_rbac_data() # Verificar se usuário é admin (global ou de grupo) if user["papel"] not in ["admin", "global_admin"]: raise HTTPException(status_code=403, detail="Acesso restrito a administradores") # Obter solicitações pendentes para os grupos do admin admin_requests = get_pending_requests_by_admin(username, rbac) # Converter para modelo de resposta return [ GroupAccessRequestResponse( request_id=req.request_id, username=req.username, grupo=req.grupo, status=req.status, justificativa=req.justificativa, created_at=req.created_at, updated_at=req.updated_at, reviewed_by=req.reviewed_by, review_comment=req.review_comment ) for req in admin_requests ] @router.get("/{request_id}", response_model=GroupAccessRequestResponse, summary="Detalhes da solicitação", description="Obtém detalhes de uma solicitação específica") async def get_request(request_id: str, user=Depends(get_current_user)): """ Obtém detalhes de uma solicitação específica. Usuários só podem ver suas próprias solicitações. Administradores podem ver solicitações dos grupos que administram. """ username = user["username"] rbac = get_rbac_data() # Buscar solicitação request = get_request_by_id(request_id) if not request: raise HTTPException(status_code=404, detail="Solicitação não encontrada") # Verificar permissão: usuário só pode ver suas próprias solicitações if request.username != username: # A menos que seja admin do grupo ou global_admin if user["papel"] == "global_admin": pass # Global admin pode ver qualquer solicitação elif user["papel"] == "admin": # Admin de grupo só pode ver solicitações do seu grupo grupo_admins = rbac["grupos"].get(request.grupo, {}).get("admins", []) if username not in grupo_admins: raise HTTPException(status_code=403, detail="Sem permissão para acessar esta solicitação") else: # Usuário comum tentando acessar solicitação de outro raise HTTPException(status_code=403, detail="Sem permissão para acessar esta solicitação") # Converter para modelo de resposta return GroupAccessRequestResponse( request_id=request.request_id, username=request.username, grupo=request.grupo, status=request.status, justificativa=request.justificativa, created_at=request.created_at, updated_at=request.updated_at, reviewed_by=request.reviewed_by, review_comment=request.review_comment ) @router.post("/{request_id}/review", response_model=GroupAccessRequestResponse, summary="Revisar solicitação", description="Aprova ou rejeita uma solicitação de acesso") async def review_request(request_id: str, review: GroupAccessRequestReview, user=Depends(get_current_user)): """ Aprova ou rejeita uma solicitação de acesso a grupo. Apenas admins do grupo ou admins globais podem revisar solicitações. """ username = user["username"] rbac = get_rbac_data() # Verificar se usuário é admin (global ou de grupo) if user["papel"] not in ["admin", "global_admin"]: raise HTTPException(status_code=403, detail="Acesso restrito a administradores") # Buscar solicitação request = get_request_by_id(request_id) if not request: raise HTTPException(status_code=404, detail="Solicitação não encontrada") # Verificar se solicitação já foi aprovada/rejeitada if request.status != RequestStatus.PENDING: raise HTTPException(status_code=400, detail=f"Solicitação já foi {request.status}") # Verificar se admin tem permissão neste grupo if user["papel"] == "admin": grupo_admins = rbac["grupos"].get(request.grupo, {}).get("admins", []) if username not in grupo_admins: raise HTTPException(status_code=403, detail="Sem permissão para administrar este grupo") # Processar revisão updated_request = review_access_request( request_id=request_id, reviewer=username, status=review.status, comment=review.comment ) if not updated_request: raise HTTPException(status_code=500, detail="Erro ao processar revisão") # Se aprovado, adicionar usuário ao grupo if review.status == RequestStatus.APPROVED: if not apply_approved_request(request_id, rbac): # A solicitação foi aprovada, mas houve erro ao adicionar ao grupo logger.error(f"Erro ao adicionar usuário {request.username} ao grupo {request.grupo}") raise HTTPException( status_code=500, detail="Solicitação aprovada, mas houve erro ao adicionar usuário ao grupo" ) # Converter para modelo de resposta return GroupAccessRequestResponse( request_id=updated_request.request_id, username=updated_request.username, grupo=updated_request.grupo, status=updated_request.status, justificativa=updated_request.justificativa, created_at=updated_request.created_at, updated_at=updated_request.updated_at, reviewed_by=updated_request.reviewed_by, review_comment=updated_request.review_comment )

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jowpereira/mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server