fix: Freigegebene Ordner zeigen Dateien auch an

list_files filterte Kinder-Dateien nach owner_id=current_user, wodurch
in einem freigegebenen Ordner (der einem anderen User gehoert) keine
Dateien angezeigt wurden. Jetzt wird beim Betreten eines Ordners die
Zugriffsberechtigung geprueft; bei eigenem Ordner wie gehabt, bei
freigegebenem Ordner werden alle Kinder-Dateien gelistet.

_check_file_access laeuft jetzt auch den Ordner-Baum hoch, damit
eine Permission auf einem Vorfahren-Ordner automatisch Zugriff auf
alle Nachkommen gewaehrt.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Stefan Hacker 2026-04-12 10:13:35 +02:00
parent c63a52629d
commit b33e66cad9
1 changed files with 33 additions and 11 deletions

View File

@ -41,16 +41,22 @@ def _user_upload_dir(user_id):
def _check_file_access(file_obj, user, permission='read'):
"""Check if user has access to file. Owner always has full access."""
"""Check if user has access to file. Owner always has full access.
A permission on an ancestor folder also grants access to all descendants."""
if file_obj.owner_id == user.id:
return True
perm = FilePermission.query.filter_by(
file_id=file_obj.id, user_id=user.id
).first()
if not perm:
return False
perm_levels = {'read': 0, 'write': 1, 'admin': 2}
return perm_levels.get(perm.permission, -1) >= perm_levels.get(permission, 0)
needed = perm_levels.get(permission, 0)
# Walk up the tree looking for a permission on this file or any ancestor
cur = file_obj
while cur is not None:
perm = FilePermission.query.filter_by(
file_id=cur.id, user_id=user.id
).first()
if perm and perm_levels.get(perm.permission, -1) >= needed:
return True
cur = cur.parent
return False
def _get_file_or_403(file_id, user, permission='read'):
@ -78,9 +84,25 @@ def list_files():
user = request.current_user
parent_id = request.args.get('parent_id', None, type=int)
# Own files in this folder (exclude trashed)
query = File.query.filter_by(owner_id=user.id, parent_id=parent_id, is_trashed=False)
files = query.order_by(File.is_folder.desc(), File.name).all()
# When browsing into a folder, verify access first. If the folder is
# shared with us (directly or via an ancestor), list ALL its children
# - not just ones owned by us.
if parent_id is not None:
parent_folder, perr = _get_file_or_403(parent_id, user, 'read')
if perr:
return perr
if parent_folder.owner_id == user.id:
files = File.query.filter_by(
owner_id=user.id, parent_id=parent_id, is_trashed=False
).order_by(File.is_folder.desc(), File.name).all()
else:
files = File.query.filter_by(
parent_id=parent_id, is_trashed=False
).order_by(File.is_folder.desc(), File.name).all()
else:
files = File.query.filter_by(
owner_id=user.id, parent_id=None, is_trashed=False
).order_by(File.is_folder.desc(), File.name).all()
# Shared files at root level
shared = []
@ -90,7 +112,7 @@ def list_files():
if shared_file_ids:
shared = File.query.filter(
File.id.in_(shared_file_ids),
File.parent_id.is_(None)
File.is_trashed == False # noqa: E712
).order_by(File.is_folder.desc(), File.name).all()
result = []