Permiso vistas implementados
This commit is contained in:
130
backend/app/api/v1/endpoints/permissions.py
Normal file
130
backend/app/api/v1/endpoints/permissions.py
Normal file
@@ -0,0 +1,130 @@
|
||||
"""Permissions endpoints - ServiceManagerWeb"""
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import select, delete
|
||||
from typing import Dict
|
||||
import uuid
|
||||
|
||||
from app.core.database import get_db
|
||||
from app.api.deps import get_current_user
|
||||
from app.models.user import User, UserRole
|
||||
from app.models.permission import TenantPermission, DEFAULT_PERMISSIONS, CLIENT_PERMISSIONS
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/my")
|
||||
async def get_my_permissions(
|
||||
db: AsyncSession = Depends(get_db),
|
||||
current_user: User = Depends(get_current_user),
|
||||
) -> Dict[str, bool]:
|
||||
"""Obtener permisos efectivos del usuario actual."""
|
||||
if current_user.role.is_global:
|
||||
# Staff interno — devolver permisos del rol por defecto
|
||||
role_defaults = DEFAULT_PERMISSIONS.get(current_user.role.value, {})
|
||||
return role_defaults
|
||||
|
||||
# Buscar overrides individuales primero
|
||||
result = await db.execute(
|
||||
select(TenantPermission).where(
|
||||
TenantPermission.tenant_id == current_user.tenant_id,
|
||||
TenantPermission.user_id == current_user.id,
|
||||
)
|
||||
)
|
||||
user_overrides = {p.permission: p.granted for p in result.scalars().all()}
|
||||
|
||||
# Buscar defaults del rol
|
||||
result = await db.execute(
|
||||
select(TenantPermission).where(
|
||||
TenantPermission.tenant_id == current_user.tenant_id,
|
||||
TenantPermission.user_id == None,
|
||||
TenantPermission.role == current_user.role.value,
|
||||
)
|
||||
)
|
||||
role_defaults = {p.permission: p.granted for p in result.scalars().all()}
|
||||
|
||||
# Merge: override individual > default del rol > system default
|
||||
system_defaults = DEFAULT_PERMISSIONS.get(current_user.role.value, {})
|
||||
effective = {**system_defaults, **role_defaults, **user_overrides}
|
||||
return effective
|
||||
|
||||
|
||||
@router.get("/user/{user_id}")
|
||||
async def get_user_permissions(
|
||||
user_id: uuid.UUID,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
current_user: User = Depends(get_current_user),
|
||||
) -> Dict[str, bool]:
|
||||
"""Obtener permisos efectivos de un usuario específico."""
|
||||
if current_user.role not in (UserRole.ADMIN, UserRole.SUPPORT_MANAGER, UserRole.CLIENT_ADMIN):
|
||||
raise HTTPException(status_code=403, detail="Sin permisos")
|
||||
|
||||
target = await db.get(User, user_id)
|
||||
if not target:
|
||||
raise HTTPException(status_code=404, detail="Usuario no encontrado")
|
||||
|
||||
# Buscar overrides individuales
|
||||
result = await db.execute(
|
||||
select(TenantPermission).where(
|
||||
TenantPermission.user_id == user_id,
|
||||
)
|
||||
)
|
||||
user_overrides = {p.permission: p.granted for p in result.scalars().all()}
|
||||
|
||||
# Buscar defaults del rol en el tenant
|
||||
result = await db.execute(
|
||||
select(TenantPermission).where(
|
||||
TenantPermission.tenant_id == target.tenant_id,
|
||||
TenantPermission.user_id == None,
|
||||
TenantPermission.role == target.role.value,
|
||||
)
|
||||
)
|
||||
role_defaults = {p.permission: p.granted for p in result.scalars().all()}
|
||||
|
||||
system_defaults = DEFAULT_PERMISSIONS.get(target.role.value, {})
|
||||
effective = {**system_defaults, **role_defaults, **user_overrides}
|
||||
return effective
|
||||
|
||||
|
||||
@router.put("/user/{user_id}")
|
||||
async def update_user_permissions(
|
||||
user_id: uuid.UUID,
|
||||
data: Dict[str, bool],
|
||||
db: AsyncSession = Depends(get_db),
|
||||
current_user: User = Depends(get_current_user),
|
||||
):
|
||||
"""
|
||||
Actualizar permisos individuales de un usuario.
|
||||
Solo ADMIN, SUPPORT_MANAGER o CLIENT_ADMIN pueden hacerlo.
|
||||
"""
|
||||
if current_user.role not in (UserRole.ADMIN, UserRole.SUPPORT_MANAGER, UserRole.CLIENT_ADMIN):
|
||||
raise HTTPException(status_code=403, detail="Sin permisos")
|
||||
|
||||
target = await db.get(User, user_id)
|
||||
if not target:
|
||||
raise HTTPException(status_code=404, detail="Usuario no encontrado")
|
||||
|
||||
# Borrar overrides existentes del usuario
|
||||
await db.execute(
|
||||
delete(TenantPermission).where(
|
||||
TenantPermission.user_id == user_id,
|
||||
)
|
||||
)
|
||||
|
||||
# Insertar nuevos overrides
|
||||
from datetime import datetime
|
||||
now = datetime.utcnow()
|
||||
for permission, granted in data.items():
|
||||
db.add(TenantPermission(
|
||||
id=uuid.uuid4(),
|
||||
tenant_id=target.tenant_id,
|
||||
user_id=user_id,
|
||||
role=target.role.value,
|
||||
permission=permission,
|
||||
granted=granted,
|
||||
created_at=now,
|
||||
updated_at=now,
|
||||
))
|
||||
|
||||
await db.commit()
|
||||
return {"message": "Permisos actualizados"}
|
||||
Reference in New Issue
Block a user