This commit is contained in:
@@ -20,6 +20,11 @@ class TokenInput(BaseModel):
|
||||
scopes: list[str] = Field(default_factory=lambda: ["research:read"], max_length=len(SCOPES))
|
||||
|
||||
|
||||
class TokenPermissionsInput(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
scopes: list[str] = Field(max_length=len(SCOPES))
|
||||
|
||||
|
||||
def token_output(row, account):
|
||||
"""Return public metadata only, including whether the current binding is usable."""
|
||||
def timestamp(value):
|
||||
@@ -69,6 +74,26 @@ async def issue_token(body: TokenInput, request: Request):
|
||||
return {**result, "token": secret}
|
||||
|
||||
|
||||
@router.patch("/{token_id}")
|
||||
async def update_token_permissions(token_id: str, body: TokenPermissionsInput, request: Request):
|
||||
"""Update owned active-token scopes without rotating or revealing its secret."""
|
||||
scopes = set(body.scopes)
|
||||
if not scopes <= SCOPES or "research:read" not in scopes:
|
||||
raise HTTPException(422, "权限无效;所有令牌必须包含 research:read")
|
||||
async with request.app.state.sessions.begin() as db:
|
||||
row = await db.scalar(select(MCPToken).where(
|
||||
MCPToken.id == token_id, MCPToken.admin_id == 1, MCPToken.account_id == 1,
|
||||
).with_for_update())
|
||||
if not row:
|
||||
raise HTTPException(404, "MCP Key 不存在")
|
||||
account = await db.get(Account, 1)
|
||||
if token_output(row, account)["status"] != "active":
|
||||
raise HTTPException(409, "仅有效的 MCP Key 可以编辑权限")
|
||||
row.scopes = sorted(scopes)
|
||||
result = token_output(row, account)
|
||||
return result
|
||||
|
||||
|
||||
@router.post("/{token_id}/revoke")
|
||||
async def revoke_token(token_id: str, request: Request):
|
||||
async with request.app.state.sessions.begin() as db:
|
||||
|
||||
Reference in New Issue
Block a user