fix: bucket name error

This commit is contained in:
tao.chen
2026-08-05 16:01:28 +08:00
parent d851f98581
commit e997e6cf56
7 changed files with 153 additions and 54 deletions
+29
View File
@@ -22,6 +22,34 @@ class MembershipError(Exception):
"""Raised when the user is not an active member of the workspace."""
async def resolve_is_system_admin(
session: AsyncSession,
user: Users,
) -> bool:
"""Return True iff the user holds a platform-scoped admin role.
The check is: ``Users.status == 'active'`` AND
``Users.platform_role_id`` points to a ``Roles`` row whose
``role_code == 'admin'``. Any other shape (no platform_role_id,
disabled user, wrong role code) returns False — the frontend reads
this to decide whether to show the system-admin entry point.
System admins own the platform: they can address disabled workspaces,
bypass per-workspace membership checks, etc. Anything that wants to
gate "platform-only" behavior (deleting a workspace, soft-deleting
a user globally, …) should consult this flag — it is the single
source of truth.
"""
from sqlalchemy import select
if user.status != "active" or user.platform_role_id is None:
return False
platform_role = await session.scalar(
select(Roles).where(Roles.role_id == user.platform_role_id)
)
return platform_role is not None and platform_role.role_code == "admin"
async def load_active_membership(
session: AsyncSession,
user_id: str,
@@ -66,4 +94,5 @@ async def load_active_membership(
__all__ = [
"MembershipError",
"load_active_membership",
"resolve_is_system_admin",
]
+2
View File
@@ -22,6 +22,7 @@ from .base import AsyncStorageBackend, ObjectMeta, StorageBackend
from .factory import (
PURPOSE_BUCKETS,
RCLONE_REMOTE_NAME,
actual_bucket_name,
build_storage_config,
create_storage,
rclone_remote_spec,
@@ -32,6 +33,7 @@ from .registry import register_backend, registered_backends
__all__ = [
"create_storage",
"build_storage_config",
"actual_bucket_name",
"workspaces_root",
"rclone_remote_spec",
"RCLONE_REMOTE_NAME",
+16
View File
@@ -62,6 +62,22 @@ def create_storage(config: Dict[str, Any]) -> AnyStorageBackend:
PURPOSE_BUCKETS: tuple[str, ...] = ("workspace", "version", "run_log", "trash")
def actual_bucket_name(purpose: str) -> str:
"""把 purpose 名称解析成实际桶路径 / 名(runtime 数据会存在这个字符串里)。
- s3 模式:`settings.s3_<purpose>_bucket`(e.g. ``"versions"``)
- local 模式:`${local_storage_base_dir}/<purpose>`(e.g. ``"/data/version"``)
这是 ``app.state.object_stores`` 的 dict key——``UploadSessions.bucket_name``
和 ``StorageObjects.bucket_name`` 都存这个值,所以 dict 必须用这个串
做 key 才能在 ``object_stores[upload.bucket_name]`` 那里直接命中。
"""
from common.config import settings # 延迟 import 避免循环
if settings.storage_backend == "local":
return str(Path(settings.local_storage_base_dir) / purpose)
return getattr(settings, f"s3_{purpose}_bucket")
def build_storage_config(bucket_name: str) -> Dict[str, Any]:
"""根据 ``settings.storage_backend`` 构造 ``create_storage()`` 的入参。