T2 token 管理(src/api/mcp_tokens.rs):create/list/reveal/revoke + get_mcp_client_configs
服务端函数,均经 get_current_admin_user 鉴权;TokenLifetime 枚举(1/7/30/90天/永不过期)。
src/mcp/config.rs 生成 4 种客户端配置(Claude Code/Cursor/Cline/通用 + CLI)。
src/pages/admin/mcp.rs 令牌管理页:列表 + 新建表单 + 一次性明文展示/重查 + 撤销 +
配置片段卡片。路由 /admin/mcp,导航项加入 admin_layout。
T3 read 工具 + Resources(tools/read.rs, resources.rs):search_posts/get_post/list_tags
(read 作用域,仅已发布);published-post Resources(post://{slug},游标分页)。
search_published 提取为共享函数。
T4 write 工具(tools/{posts,comments,tags,media}.rs):create/update/publish/trash/delete_post、
评论审核、标签 CRUD、媒体 base64 上传(WebP 转码 + 去重)。复用既有 helper 的 SQL 与
缓存失效(moka + ssr_cache)。write 作用域,可读草稿。
T5 admin 工具(tools/{settings,runner}.rs):get/update_settings、run_code(沙箱执行)。
admin 作用域。
合并(server.rs):用 rmcp tool_router 的「命名路由 + 组合」模式,7 个工具组在
YggMcpServer 上 impl,combined_router 用 + 合并成单一 ServerHandler。各工具组鉴权
独立,经 Extension<Parts> 读 McpPrincipal + scope.grants 校验。
新增依赖 base64 0.22(媒体上传解码)。验证:server/web 双目标编译通过、clippy
--all-features -D warnings 干净、659 单测 + 1 集成全绿(+20 新测试)。
40 lines
2.1 KiB
Markdown
40 lines
2.1 KiB
Markdown
# T2 — Token management server fns + admin UI
|
|
|
|
## Blocking edges
|
|
- **Blocks:** T7 (integration verification needs a usable UI).
|
|
- **Blocked by:** T1 (token model + crypto must exist).
|
|
|
|
## Target files
|
|
- `src/api/mcp_tokens.rs` — `#[server]` fns.
|
|
- `src/api/mod.rs` — `pub mod mcp_tokens;` + re-exports.
|
|
- `src/models/mcp_token.rs` — DTOs (shared with T1).
|
|
- `src/pages/admin/mcp.rs` — token management + config generator page.
|
|
- `src/router.rs` — route `/admin/mcp`.
|
|
- admin layout/nav — link to `/admin/mcp`.
|
|
- `src/mcp/config.rs` — config generation (4 formats).
|
|
|
|
## Change
|
|
1. `create_mcp_token(name, scope, lifetime)` (admin-guarded via
|
|
`get_current_admin_user().await?`): generate opaque `ygg_...` token, AES-GCM encrypt,
|
|
store hash + ciphertext, set `expires_at` from the preset menu
|
|
(1d/7d/30d/90d/None). Return `CreateTokenResponse { summary, plaintext }`.
|
|
2. `list_mcp_tokens()` → `Vec<McpTokenSummary>` (no secret): name, scope, created,
|
|
expires, last_used, revoked.
|
|
3. `reveal_mcp_token(id)` → decrypt `token_enc` → return plaintext (retrievable, per
|
|
decision 8). Admin-guarded.
|
|
4. `revoke_mcp_token(id)` → set `revoked_at = now()`.
|
|
5. `src/mcp/config.rs`: `generate_client_configs(base_url, token)` → struct with 4
|
|
ready-to-paste snippets: Claude Code/Cursor JSON, Cline JSON (`streamableHttp`),
|
|
generic raw JSON, and a `claude mcp add` CLI one-liner (see research §"Client-config").
|
|
6. `/admin/mcp` page: token list table, "create token" form (name + scope dropdown +
|
|
lifetime preset), one-time plaintext reveal + "reveal again" button, revoke button,
|
|
and the 4 config snippets with copy buttons. Base URL from `APP_BASE_URL`.
|
|
|
|
## Acceptance
|
|
- Admin can create a token with chosen scope + lifetime; plaintext shown once and
|
|
re-revealable; token appears in the list with correct metadata; revoke works.
|
|
- All 4 config snippets are valid JSON / shell and contain the correct bearer header.
|
|
- Non-admin calling these server fns → 401/403.
|
|
- `last_used_at` does NOT leak plaintext; plaintext never persisted unencrypted.
|
|
- Compiles on both targets; clippy clean; existing tests pass.
|