fix: scope category tree_count to requesting account

tree_count on GET /categories/{id} was including trees from all
accounts, leaking cross-tenant row counts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
chihlasm
2026-04-09 03:54:01 +00:00
parent 057c0abe16
commit 68eabf27f4

View File

@@ -12,6 +12,7 @@ from app.models.user import User
from app.schemas.category import CategoryCreate, CategoryUpdate, CategoryResponse, CategoryListResponse from app.schemas.category import CategoryCreate, CategoryUpdate, CategoryResponse, CategoryListResponse
from app.api.deps import get_current_active_user from app.api.deps import get_current_active_user
from app.core.permissions import can_manage_category, can_create_category from app.core.permissions import can_manage_category, can_create_category
from app.core.filters import tenant_filter
router = APIRouter(prefix="/categories", tags=["categories"]) router = APIRouter(prefix="/categories", tags=["categories"])
@@ -108,10 +109,12 @@ async def get_category(
detail="You don't have access to this category" detail="You don't have access to this category"
) )
# Get tree count # Get tree count — scoped to the requesting account so cross-account
# trees in shared categories are not counted.
count_query = select(func.count(Tree.id)).where( count_query = select(func.count(Tree.id)).where(
Tree.category_id == category.id, Tree.category_id == category.id,
Tree.is_active == True Tree.is_active == True,
tenant_filter(Tree, current_user.account_id),
) )
count_result = await db.execute(count_query) count_result = await db.execute(count_query)
tree_count = count_result.scalar() or 0 tree_count = count_result.scalar() or 0