fix: bucket name error
This commit is contained in:
@@ -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",
|
||||
]
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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()`` 的入参。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user