77 lines
2.5 KiB
Python
77 lines
2.5 KiB
Python
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
|
|
|
|
@dataclass
|
|
class ClientAccessScope:
|
|
tenant_id: int
|
|
branch_id: int | None
|
|
allow_cross_branch: bool
|
|
allow_cross_tenant: bool
|
|
allow_all_clients: bool
|
|
own_only: bool
|
|
locked_partner_id: int | None
|
|
can_assign_partner: bool
|
|
can_change_branch: bool
|
|
can_change_tenant: bool
|
|
|
|
|
|
def build_scope(request, user, permission_checker):
|
|
active_tenant_id = int(request.session.get("active_tenant_id") or user.tenant_id)
|
|
active_branch_value = request.session.get("active_branch_id")
|
|
active_branch_id = None if active_branch_value in (None, "", 0, "0") else int(active_branch_value)
|
|
|
|
allow_cross_branch = permission_checker("clients.cross_branch")
|
|
allow_cross_tenant = permission_checker("clients.cross_tenant")
|
|
can_assign_partner = permission_checker("clients.assign_partner")
|
|
own_only = permission_checker("clients.view.own_only")
|
|
|
|
allow_all_clients = bool((allow_cross_tenant and allow_cross_branch and not own_only) or permission_checker("clients.view.all"))
|
|
|
|
locked_partner_id = user.id if own_only else None
|
|
can_change_branch = allow_cross_branch
|
|
can_change_tenant = allow_cross_tenant
|
|
|
|
return ClientAccessScope(
|
|
tenant_id=active_tenant_id,
|
|
branch_id=active_branch_id or getattr(user, "branch_id", None),
|
|
allow_cross_branch=allow_cross_branch,
|
|
allow_cross_tenant=allow_cross_tenant,
|
|
allow_all_clients=allow_all_clients,
|
|
own_only=own_only,
|
|
locked_partner_id=locked_partner_id,
|
|
can_assign_partner=can_assign_partner,
|
|
can_change_branch=can_change_branch,
|
|
can_change_tenant=can_change_tenant,
|
|
)
|
|
|
|
|
|
def effective_partner_id(row: dict):
|
|
return row.get("assoc_partner_user_id") or row.get("partner_id")
|
|
|
|
|
|
def effective_tenant_id(row: dict):
|
|
return row.get("assoc_firm_tenant_id") or row.get("tenant_id")
|
|
|
|
|
|
def effective_branch_id(row: dict):
|
|
return row.get("branch_id")
|
|
|
|
|
|
def can_view_client_row(scope: ClientAccessScope, row: dict, *, user_id: int) -> bool:
|
|
if scope.allow_all_clients:
|
|
return True
|
|
|
|
if not scope.allow_cross_tenant and effective_tenant_id(row) != scope.tenant_id:
|
|
return False
|
|
|
|
branch_id = effective_branch_id(row)
|
|
if not scope.allow_cross_branch and scope.branch_id and branch_id and branch_id != scope.branch_id:
|
|
return False
|
|
|
|
if scope.own_only and scope.locked_partner_id and effective_partner_id(row) != scope.locked_partner_id:
|
|
return False
|
|
|
|
return True
|