Implement row-level security (RLS) context management for database sessions. Refactor invoice processing and reverting tasks to utilize scoped database sessions with RLS context. Update middleware to extract and set company ID from requests. Enhance task dispatching to propagate RLS context via Celery headers. Update architecture documentation to reflect RLS implementation details.
This commit is contained in:
@@ -3,6 +3,8 @@ from typing import Any
|
||||
from celery import Task
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from core.database import rls_company_var, rls_tenant_var
|
||||
|
||||
from .service import TaskTrackerService
|
||||
|
||||
|
||||
@@ -21,7 +23,25 @@ def track_and_dispatch(
|
||||
task_id: str | None = None,
|
||||
meta_payload: dict[str, Any] | None = None,
|
||||
):
|
||||
celery_task = task.apply_async(args=args or [], kwargs=kwargs or {}, task_id=task_id)
|
||||
# Propaga contexto RLS vía Celery headers (leídos en task_prerun) y
|
||||
# ContextVars (para modo eager, donde before_task_publish no dispara).
|
||||
headers = {"rls_tenant_id": str(int(tenant_id))}
|
||||
if company_id is not None:
|
||||
headers["rls_company_id"] = str(int(company_id))
|
||||
|
||||
token_t = rls_tenant_var.set(int(tenant_id))
|
||||
token_c = rls_company_var.set(int(company_id) if company_id is not None else None)
|
||||
try:
|
||||
celery_task = task.apply_async(
|
||||
args=args or [],
|
||||
kwargs=kwargs or {},
|
||||
task_id=task_id,
|
||||
headers=headers,
|
||||
)
|
||||
finally:
|
||||
rls_tenant_var.reset(token_t)
|
||||
rls_company_var.reset(token_c)
|
||||
|
||||
tracker = TaskTrackerService(db)
|
||||
tracker.register_dispatch(
|
||||
task_id=celery_task.id,
|
||||
|
||||
Reference in New Issue
Block a user