This commit is contained in:
2026-03-19 15:47:42 +01:00
parent 4e19090f0f
commit 7fc9108d2a
9 changed files with 194 additions and 30 deletions
+21
View File
@@ -94,6 +94,27 @@ async def my_virtual_boxes(
return [_to_response(v) for v in items]
@router.get(
"/my/mailboxes",
response_model=list[MailboxBriefResponse],
summary="Caselle PEC da cui l'utente può inviare tramite Virtual Box",
description=(
"Restituisce le caselle PEC attive associate alle Virtual Box "
"a cui l'utente corrente è assegnato. "
"Usato dalla pagina di composizione per mostrare le caselle mittente disponibili."
),
)
async def my_sendable_mailboxes(
current_user: CurrentUser,
db: DB,
) -> list[MailboxBriefResponse]:
service = VirtualBoxService(db)
mailboxes = await service.get_user_sendable_mailboxes(
current_user.id, current_user.tenant_id
)
return [MailboxBriefResponse.model_validate(m) for m in mailboxes]
@router.get(
"/{vbox_id}",
response_model=VirtualBoxResponse,
+1
View File
@@ -42,6 +42,7 @@ class MailboxBriefResponse(BaseModel):
id: uuid.UUID
email_address: str
display_name: str | None
status: str = "active"
model_config = {"from_attributes": True}
+50 -2
View File
@@ -61,12 +61,23 @@ class PermissionService:
async def check_can_send(
self, user: User, mailbox_id: uuid.UUID
) -> bool:
"""Verifica se l'utente può inviare dalla casella."""
"""
Verifica se l'utente può inviare dalla casella.
L'accesso in invio è concesso se:
1. L'utente è admin del tenant, oppure
2. L'utente ha un permesso diretto can_send sulla casella, oppure
3. L'utente è assegnato a una Virtual Box attiva che include la casella.
"""
if user.role in ("super_admin", "admin"):
return await self._mailbox_belongs_to_tenant(mailbox_id, user.tenant_id)
perm = await self._get_permission(user.id, mailbox_id)
return perm is not None and perm.can_send
if perm is not None and perm.can_send:
return True
# Fallback: verifica accesso tramite Virtual Box
return await self._check_vbox_mailbox_access(user.id, mailbox_id, user.tenant_id)
async def check_can_manage(
self, user: User, mailbox_id: uuid.UUID
@@ -234,3 +245,40 @@ class PermissionService:
)
)
return result.scalar_one_or_none() is not None
async def _check_vbox_mailbox_access(
self,
user_id: uuid.UUID,
mailbox_id: uuid.UUID,
tenant_id: uuid.UUID,
) -> bool:
"""
Verifica se l'utente ha accesso a una casella tramite Virtual Box.
Restituisce True se l'utente è assegnato ad almeno una VBox attiva
che include la casella specificata.
"""
from app.models.virtual_box import (
VirtualBox,
VirtualBoxAssignment,
virtual_box_mailboxes,
)
result = await self.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 == user_id,
virtual_box_mailboxes.c.mailbox_id == mailbox_id,
VirtualBox.tenant_id == tenant_id,
VirtualBox.is_active == True,
)
.limit(1)
)
return result.scalar_one_or_none() is not None
@@ -341,6 +341,33 @@ class VirtualBoxService:
)
return list(result.scalars().all())
async def get_user_sendable_mailboxes(
self,
user_id: uuid.UUID,
tenant_id: uuid.UUID,
) -> list[Mailbox]:
"""
Restituisce le caselle PEC da cui l'utente può inviare tramite VBox.
Aggregazione delle caselle associate a tutte le VBox attive a cui
l'utente è assegnato. Filtra solo caselle in stato 'active'.
"""
result = await self.db.execute(
select(Mailbox)
.join(virtual_box_mailboxes, Mailbox.id == virtual_box_mailboxes.c.mailbox_id)
.join(VirtualBox, virtual_box_mailboxes.c.virtual_box_id == VirtualBox.id)
.join(VirtualBoxAssignment, VirtualBox.id == VirtualBoxAssignment.virtual_box_id)
.where(
VirtualBoxAssignment.user_id == user_id,
VirtualBox.tenant_id == tenant_id,
VirtualBox.is_active == True,
Mailbox.status == "active",
)
.distinct()
.order_by(Mailbox.email_address)
)
return list(result.scalars().all())
# ─── Private ─────────────────────────────────────────────────────────────
async def _load_full(self, vbox_id: uuid.UUID) -> VirtualBox | None: