fix(resources): enforce visibility on list + get (private invisible to non-owner)
回退 5483d19 的 workspace-wide 改动。用户真实语义:
- owner 永远可见自己的资源(含 private)
- 非 owner 只见别人 visibility in {workspace, public} 的资源
- admin 全部可见
can_view 与 list_resources 共享同一谓词。list 端点恢复
owner == me OR visibility in {workspace, public} 的过滤,
admin 跳过。get_resource / download_url / jupyter-relative-path
/ delete_resource 全部经 get_visible_resource → can_view,自然
收敛到同一语义。补 1 个 owner-看自己-private 测试,4 个
visibility 测试保持。
This commit is contained in:
@@ -20,7 +20,7 @@ from common.storage.schemas import (
|
||||
DownloadUrlRequest,
|
||||
)
|
||||
from fastapi import APIRouter, Depends, Header, HTTPException, Query, Request, status
|
||||
from sqlalchemy import func, select
|
||||
from sqlalchemy import func, or_, select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from backend.dependencies import (
|
||||
@@ -148,10 +148,14 @@ def resource_payload(
|
||||
|
||||
|
||||
def can_view(resource: DataResources, context: RequestContext) -> bool:
|
||||
# 2026-08-11: 同一 workspace 内成员可以查看彼此的资源(含 private);
|
||||
# 保留 visibility 字段仅作为上传/绑定时的语义标签,不再影响读取。
|
||||
# 还原: 加回 owner_user_id 检查。
|
||||
return True
|
||||
# 同一 workspace 内:owner 永远可见自己的资源(含 private);
|
||||
# 其他成员只见 visibility in {workspace, public} 的资源;
|
||||
# admin 全部可见。
|
||||
if resource.owner_user_id == context.user.user_id:
|
||||
return True
|
||||
if resource.visibility in {"workspace", "public"}:
|
||||
return True
|
||||
return context.is_admin
|
||||
|
||||
|
||||
# 根据当前脚本位置计算资源的相对路径,便于 Notebook 中用相对路径读取文件。
|
||||
@@ -413,16 +417,16 @@ async def list_resources(
|
||||
escape="\\",
|
||||
),
|
||||
)
|
||||
# 2026-08-11: 临时取消"用户间目录互相不可见"约束
|
||||
# 列表接口现在返回 workspace 内全部 active 资源(不再按 owner / visibility 过滤)。
|
||||
# 还原: 删除下面这段注释,恢复原来的 if not context.is_admin: ... 块。
|
||||
# if not context.is_admin:
|
||||
# statement = statement.where(
|
||||
# or_(
|
||||
# DataResources.owner_user_id == context.user.user_id,
|
||||
# DataResources.visibility.in_(["workspace", "public"]),
|
||||
# )
|
||||
# )
|
||||
# 只返回 owner 自己的资源(含 private),或 visibility 为
|
||||
# workspace/public 的其他成员资源;A 的 private 资源对非 owner 不可见。
|
||||
# admin 跳过过滤,全部可见。
|
||||
if not context.is_admin:
|
||||
statement = statement.where(
|
||||
or_(
|
||||
DataResources.owner_user_id == context.user.user_id,
|
||||
DataResources.visibility.in_(["workspace", "public"]),
|
||||
)
|
||||
)
|
||||
if visibility:
|
||||
if visibility not in {"private", "workspace", "public"}:
|
||||
raise HTTPException(
|
||||
|
||||
Reference in New Issue
Block a user