vboxes fix

This commit is contained in:
2026-03-19 14:28:09 +01:00
parent b7f7c1f7c0
commit 06dfbfcbc4
30 changed files with 4405 additions and 166 deletions
+47 -6
View File
@@ -23,11 +23,13 @@ from fastapi import APIRouter, Query, status
from fastapi.responses import StreamingResponse
from sqlalchemy import func, or_, select
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload
from app.config import get_settings
from app.core.exceptions import ForbiddenError, NotFoundError
from app.database import get_db
from app.dependencies import CurrentUser, DB
from app.models.label import Label
from app.models.message import Attachment, Message
from app.schemas.message import (
AttachmentResponse,
@@ -107,12 +109,20 @@ async def _resolve_message(
current_user,
db: AsyncSession,
) -> Message:
"""Carica il messaggio e verifica i permessi di accesso."""
"""Carica il messaggio e verifica i permessi di accesso.
L'accesso è consentito se:
1. L'utente è admin del tenant, oppure
2. L'utente ha un permesso diretto can_read sulla casella, oppure
3. L'utente è assegnato a una Virtual Box attiva che include la casella.
"""
result = await db.execute(
select(Message).where(
select(Message)
.where(
Message.id == message_id,
Message.tenant_id == current_user.tenant_id,
)
.options(selectinload(Message.labels))
)
message = result.scalar_one_or_none()
if not message:
@@ -121,8 +131,39 @@ async def _resolve_message(
if not current_user.is_admin:
from app.services.permission_service import PermissionService
perm_svc = PermissionService(db)
if not await perm_svc.check_can_read(current_user, message.mailbox_id):
raise ForbiddenError("Accesso al messaggio non autorizzato")
has_direct_access = await perm_svc.check_can_read(current_user, message.mailbox_id)
if not has_direct_access:
# Verifica accesso tramite Virtual Box:
# l'utente deve essere assegnato a una VBox attiva
# che include la casella del messaggio.
from app.models.virtual_box import (
VirtualBox,
VirtualBoxAssignment,
virtual_box_mailboxes,
)
vbox_result = await db.execute(
select(VirtualBox.id)
.join(
VirtualBoxAssignment,
VirtualBox.id == VirtualBoxAssignment.virtual_box_id,
)
.join(
virtual_box_mailboxes,
VirtualBox.id == virtual_box_mailboxes.c.virtual_box_id,
)
.where(
VirtualBoxAssignment.user_id == current_user.id,
virtual_box_mailboxes.c.mailbox_id == message.mailbox_id,
VirtualBox.tenant_id == current_user.tenant_id,
VirtualBox.is_active == True,
)
.limit(1)
)
has_vbox_access = vbox_result.scalar_one_or_none() is not None
if not has_vbox_access:
raise ForbiddenError("Accesso al messaggio non autorizzato")
return message
@@ -160,7 +201,6 @@ async def list_messages(
# ── Filtro Virtual Box ────────────────────────────────────────────────────
vbox_rules: list = []
if vbox_id is not None:
from sqlalchemy.orm import selectinload
from app.models.virtual_box import VirtualBox, VirtualBoxAssignment
vbox_result = await db.execute(
@@ -258,7 +298,8 @@ async def list_messages(
# Ordinamento e paginazione
q = (
q.order_by(
q.options(selectinload(Message.labels))
.order_by(
Message.received_at.desc().nullslast(),
Message.created_at.desc(),
)