From e4127f1e0480d7547f51044669084da5974b5982 Mon Sep 17 00:00:00 2001 From: Claudio Date: Sun, 26 Apr 2026 09:46:54 +0200 Subject: [PATCH] fix(library): scope source_dirs to current user in /stats Without this, a non-admin hitting /api/v1/library/stats would see every other user's active SourceRoot path in the response (e.g. muli would see /nextcloud-users/admin/files/Photos). Cross-user visibility into Nextcloud paths is a small info leak in a multi-user setup. Admins still get the global list when they pass scope=global. Co-Authored-By: Claude Opus 4.7 (1M context) --- backend/app/routers/library.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/backend/app/routers/library.py b/backend/app/routers/library.py index b406b84..4923db7 100644 --- a/backend/app/routers/library.py +++ b/backend/app/routers/library.py @@ -112,11 +112,14 @@ async def get_library_stats( size = (await db.execute(select(func.sum(Photo.file_size)).where(owner))).scalar() or 0 - # Source root directories (active ones only). + # Source root directories (active ones only). Scoped to the + # requesting user unless they're an admin asking for global view — + # otherwise the Settings panel would leak other users' NC paths. + sr_query = select(SourceRoot.path).where(SourceRoot.is_active.is_(True)) + if not (scope == "global" and current_user.role == "admin"): + sr_query = sr_query.where(SourceRoot.user_id == current_user.id) roots = ( - await db.execute( - select(SourceRoot.path).where(SourceRoot.is_active.is_(True)).order_by(SourceRoot.path) - ) + await db.execute(sr_query.order_by(SourceRoot.path)) ).scalars().all() return {