M9:桌面壳与收口——镜匣最小壳、器谱登记、发布证据落位、重写计划功成身退
- 镜匣 desktop/(Tauri v2 最小壳):WebView 承载琉璃镜(frontend/out 或 devUrl);能力桥最小命令(通知);乾坤通道 HMAC 短期凭证构造(与 sandbox/src/auth.rs 验签同算法,密钥仅经 SANDBOX_AUTH_SECRET 环境注入——二进制零平台密钥,静态审计钉死);hard_stop/resume 本地硬急停原子断路(全部通道命令过 ensure_not_halted,本地最高优先级不经云端);tantivy 依赖与 capabilities/ 目录预留;updater 插件位预留;cargo check 通过 - 器谱域 domains/tianzai(迁移 010):devices/device_grants——一次配对(密钥指纹登记)、逐项授契(可授面显式枚举,未知能力键拒)、撤回立即生效、设备撤销连带全部授契失效且不可再授;/devices 器谱 API 组 - 发布收口:release-evidence.md 落位重写期 RW-* 证据包(M0–M9 十里程碑验收自动化套件与结果物);能力矩阵 M9 行收官;rewrite-plan.md 按计划删除(M0–M9 全部完成,能力矩阵与证据台账接棒),全库引用清理 - 验收(test_m9_jingxia 四用例):器谱未授契 403 留痕/撤回即效/设备撤销连带;镜匣零平台密钥(rg 审计源码与配置为空);硬急停语义钉死(通道命令全检查+resume 唯一恢复+HMAC 无密钥不出凭证) - 五套件终检全绿:后端 349、前端 203、BFF 4、神识 5 包、镜匣 cargo check(2 个预存环境失败历次 HEAD 复验与本周期无关);Compose nginx profile 配置校验通过
This commit is contained in:
1 parent
c63b75152a
commit
2483a25f63
29 files changed
+10533
-179
No files matched your search
@@ -0,0 +1,66 @@
|
||||
"""器谱 API:设备配对/撤销、逐项授契/撤回、可用性裁决。"""
|
||||
|
||||
from fastapi import APIRouter, Depends
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from app.api.v1.deps import get_current_user
|
||||
from app.domains.tianzai import service
|
||||
from app.schemas.auth import CurrentUser
|
||||
|
||||
device_router = APIRouter(prefix="/devices", tags=["tianzai"])
|
||||
|
||||
|
||||
class PairRequest(BaseModel):
|
||||
kind: str = "desktop_shell"
|
||||
name: str = Field(default="", max_length=120)
|
||||
key_fingerprint: str = Field(min_length=8, max_length=128)
|
||||
|
||||
|
||||
class GrantRequest(BaseModel):
|
||||
capability: str
|
||||
scope: dict = Field(default_factory=dict)
|
||||
|
||||
|
||||
@device_router.post("", status_code=201)
|
||||
async def pair_device_api(payload: PairRequest, user: CurrentUser = Depends(get_current_user)) -> dict:
|
||||
return await service.pair_device(
|
||||
owner_scope=user.owner_scope, kind=payload.kind,
|
||||
name=payload.name, key_fingerprint=payload.key_fingerprint,
|
||||
)
|
||||
|
||||
|
||||
@device_router.get("")
|
||||
async def list_devices_api(user: CurrentUser = Depends(get_current_user)) -> list[dict]:
|
||||
return await service.list_devices(user.owner_scope)
|
||||
|
||||
|
||||
@device_router.post("/{device_id}/revoke")
|
||||
async def revoke_device_api(device_id: str, user: CurrentUser = Depends(get_current_user)) -> dict:
|
||||
return await service.revoke_device(device_id, user.owner_scope)
|
||||
|
||||
|
||||
@device_router.post("/{device_id}/grants", status_code=201)
|
||||
async def grant_api(
|
||||
device_id: str, payload: GrantRequest, user: CurrentUser = Depends(get_current_user)
|
||||
) -> dict:
|
||||
return await service.grant(
|
||||
device_id, user.owner_scope, capability=payload.capability, scope=payload.scope
|
||||
)
|
||||
|
||||
|
||||
@device_router.get("/{device_id}/grants")
|
||||
async def list_grants_api(device_id: str, user: CurrentUser = Depends(get_current_user)) -> list[dict]:
|
||||
return await service.list_grants(device_id, user.owner_scope)
|
||||
|
||||
|
||||
@device_router.post("/{device_id}/assert/{capability}")
|
||||
async def assert_grant_api(
|
||||
device_id: str, capability: str, user: CurrentUser = Depends(get_current_user)
|
||||
) -> dict:
|
||||
"""能力使用前置裁决(未授契 403)。"""
|
||||
return await service.assert_granted(device_id, user.owner_scope, capability)
|
||||
|
||||
|
||||
@device_router.post("/grants/{grant_id}/revoke")
|
||||
async def revoke_grant_api(grant_id: str, user: CurrentUser = Depends(get_current_user)) -> dict:
|
||||
return await service.revoke_grant(grant_id, user.owner_scope)
|
||||
Reference in new issue
Block a user