xiaoqu-agent-service P2 权限层:自有库 7 表 + svc 数据源,/mcp ak 鉴权(401/ThreadLocal),tool 表启动同步 + scope 强制校验,行级数据权限引擎(移植 getByIsAgent),agent.list.query 基础版,audit_log 审计,种子数据与 curl 全流程实测通过
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
-- =============================================================
|
||||
-- xiaoqu-agent-service 自有库初始化(dev 环境)
|
||||
-- 设计文档:doc/agent-mcp-service-design.md §7
|
||||
-- 执行:mysql -h192.168.1.181 -uroot -p < sql/V1__init.sql
|
||||
-- =============================================================
|
||||
|
||||
CREATE DATABASE IF NOT EXISTS xiaoqu_agent_svc_d DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
|
||||
|
||||
USE xiaoqu_agent_svc_d;
|
||||
|
||||
-- token(ak):属于某个人(user_id 逻辑关联 m0.user),只存 SHA-256 哈希
|
||||
CREATE TABLE IF NOT EXISTS agent_api_key (
|
||||
id BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
user_id BIGINT NOT NULL COMMENT '所属人(m0.user.id)',
|
||||
key_prefix VARCHAR(16) NOT NULL COMMENT 'ak 前缀(展示用,如 xqak_abcd1234)',
|
||||
key_hash CHAR(64) NOT NULL COMMENT 'ak 明文 SHA-256 hex',
|
||||
memo VARCHAR(255) NULL COMMENT '用途备注(如 Kimi 用 / Claude 用)',
|
||||
status TINYINT NOT NULL DEFAULT 1 COMMENT '1=正常 0=禁用',
|
||||
expire_time DATETIME NULL COMMENT '过期时间,NULL=永久有效',
|
||||
last_used_time DATETIME NULL COMMENT '最后使用时间',
|
||||
create_id BIGINT NULL COMMENT '创建人',
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
modify_id BIGINT NULL COMMENT '修改人',
|
||||
modify_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
|
||||
soft_delete TINYINT NOT NULL DEFAULT 0 COMMENT '0=正常 1=删除',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_key_hash (key_hash),
|
||||
KEY idx_user_id (user_id)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT ='API token(ak)';
|
||||
|
||||
-- 作用域(避免使用疑似关键字的 scope 作为表名,定名 agent_scope)
|
||||
CREATE TABLE IF NOT EXISTS agent_scope (
|
||||
id BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
name VARCHAR(64) NOT NULL COMMENT '作用域名称(如 运营)',
|
||||
code VARCHAR(64) NOT NULL COMMENT '作用域编码(如 operation)',
|
||||
memo VARCHAR(255) NULL COMMENT '备注',
|
||||
status TINYINT NOT NULL DEFAULT 1 COMMENT '1=启用 0=停用',
|
||||
create_id BIGINT NULL COMMENT '创建人',
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
modify_id BIGINT NULL COMMENT '修改人',
|
||||
modify_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
|
||||
soft_delete TINYINT NOT NULL DEFAULT 0 COMMENT '0=正常 1=删除',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_code (code)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT ='作用域(工具集合)';
|
||||
|
||||
-- 工具注册表:启动时由服务端注册自动同步(只插不删)
|
||||
CREATE TABLE IF NOT EXISTS tool (
|
||||
id BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
name VARCHAR(128) NOT NULL COMMENT '工具名(如 agent.list.query)',
|
||||
category VARCHAR(64) NOT NULL COMMENT '分类(代码注册时声明,如 customer/system)',
|
||||
description VARCHAR(512) NULL COMMENT '工具描述',
|
||||
kind VARCHAR(8) NOT NULL DEFAULT 'read' COMMENT 'read=读 write=写',
|
||||
status TINYINT NOT NULL DEFAULT 1 COMMENT '1=启用 0=停用(全局紧急开关)',
|
||||
create_id BIGINT NULL COMMENT '创建人',
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
modify_id BIGINT NULL COMMENT '修改人',
|
||||
modify_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
|
||||
soft_delete TINYINT NOT NULL DEFAULT 0 COMMENT '0=正常 1=删除',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_name (name)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT ='工具注册表';
|
||||
|
||||
-- 作用域-工具
|
||||
CREATE TABLE IF NOT EXISTS scope_tool (
|
||||
id BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
scope_id BIGINT NOT NULL COMMENT 'agent_scope.id',
|
||||
tool_id BIGINT NOT NULL COMMENT 'tool.id',
|
||||
create_id BIGINT NULL COMMENT '创建人',
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
modify_id BIGINT NULL COMMENT '修改人',
|
||||
modify_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
|
||||
soft_delete TINYINT NOT NULL DEFAULT 0 COMMENT '0=正常 1=删除',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_scope_tool (scope_id, tool_id)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT ='作用域-工具关系';
|
||||
|
||||
-- token-作用域
|
||||
CREATE TABLE IF NOT EXISTS token_scope (
|
||||
id BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
token_id BIGINT NOT NULL COMMENT 'agent_api_key.id',
|
||||
scope_id BIGINT NOT NULL COMMENT 'agent_scope.id',
|
||||
create_id BIGINT NULL COMMENT '创建人',
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
modify_id BIGINT NULL COMMENT '修改人',
|
||||
modify_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
|
||||
soft_delete TINYINT NOT NULL DEFAULT 0 COMMENT '0=正常 1=删除',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_token_scope (token_id, scope_id)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT ='token-作用域关系';
|
||||
|
||||
-- 审计日志
|
||||
CREATE TABLE IF NOT EXISTS audit_log (
|
||||
id BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
user_id BIGINT NULL COMMENT '调用人(m0.user.id)',
|
||||
token_id BIGINT NULL COMMENT 'agent_api_key.id',
|
||||
tool_name VARCHAR(128) NOT NULL COMMENT '工具名',
|
||||
params_digest VARCHAR(500) NULL COMMENT '入参 JSON 摘要(截断 500 字,不含 ak)',
|
||||
result_status VARCHAR(16) NOT NULL COMMENT 'success/denied/error',
|
||||
result_message VARCHAR(500) NULL COMMENT '结果说明(拒绝原因/异常摘要)',
|
||||
cost_ms BIGINT NULL COMMENT '耗时毫秒',
|
||||
client_ip VARCHAR(64) NULL COMMENT '客户端 IP',
|
||||
client_type VARCHAR(32) NULL COMMENT 'mcp-kimi/mcp-claude/cli/unknown',
|
||||
create_id BIGINT NULL COMMENT '创建人',
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
modify_id BIGINT NULL COMMENT '修改人',
|
||||
modify_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
|
||||
soft_delete TINYINT NOT NULL DEFAULT 0 COMMENT '0=正常 1=删除',
|
||||
PRIMARY KEY (id),
|
||||
KEY idx_user_tool (user_id, tool_name),
|
||||
KEY idx_create_time (create_time)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT ='工具调用审计';
|
||||
|
||||
-- 后台管理员(P4 管理后台使用,与 ak 体系分离)
|
||||
CREATE TABLE IF NOT EXISTS admin_user (
|
||||
id BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
account VARCHAR(64) NOT NULL COMMENT '登录账号',
|
||||
password_hash CHAR(64) NOT NULL COMMENT '密码 SHA-256 hex',
|
||||
name VARCHAR(64) NULL COMMENT '姓名',
|
||||
status TINYINT NOT NULL DEFAULT 1 COMMENT '1=正常 0=禁用',
|
||||
create_id BIGINT NULL COMMENT '创建人',
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
modify_id BIGINT NULL COMMENT '修改人',
|
||||
modify_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
|
||||
soft_delete TINYINT NOT NULL DEFAULT 0 COMMENT '0=正常 1=删除',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_account (account)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT ='后台管理员';
|
||||
@@ -0,0 +1,53 @@
|
||||
-- =============================================================
|
||||
-- dev 种子数据(仅 dev 环境使用!)
|
||||
-- 用户:46=代理商管理端(isagent=0 总部视角, authority_id=1)
|
||||
-- 1000=斤斤计较(isagent=1 代理商视角, authority_id=108, agent_id=1 有 26 个直属下级)
|
||||
-- token:
|
||||
-- HQ user_id=46 xqak_1d21057ad83203dbeb767eb5069701046b27debdc08a733c
|
||||
-- AGENT user_id=1000 xqak_7df02ccee2133dc2cf951db12e3958557bdf2d30a91e7f08
|
||||
-- NOSCOPE user_id=1000 xqak_5bdc0eac8c1cab535f22dc3e9757f72b3127de43a14997a7 (未授权任何 scope,验证拒绝)
|
||||
-- 依赖:tool 表已由应用启动时 ToolSyncService 同步(sys.ping/agent.count/agent.list.query)
|
||||
-- =============================================================
|
||||
|
||||
USE xiaoqu_agent_svc_d;
|
||||
|
||||
START TRANSACTION;
|
||||
|
||||
-- token(ak 只存 SHA-256 哈希;明文只保留在本文件顶部注释,仅 dev)
|
||||
INSERT INTO agent_api_key (user_id, key_prefix, key_hash, memo, status, create_id)
|
||||
SELECT 46, 'xqak_1d21', '9068d5a6406afdb853cdc9f5e45e16a5191255e2feb1aba171cd66ea13d5711c', 'dev 测试:总部视角(isagent=0)', 1, 0
|
||||
WHERE NOT EXISTS (SELECT 1 FROM agent_api_key WHERE key_hash = '9068d5a6406afdb853cdc9f5e45e16a5191255e2feb1aba171cd66ea13d5711c');
|
||||
|
||||
INSERT INTO agent_api_key (user_id, key_prefix, key_hash, memo, status, create_id)
|
||||
SELECT 1000, 'xqak_7df0', '00ab77ba18c11c8870500e1c09a9e25747e4cf0d8f1c88ae255a2beca6eef007', 'dev 测试:代理商视角(isagent=1)', 1, 0
|
||||
WHERE NOT EXISTS (SELECT 1 FROM agent_api_key WHERE key_hash = '00ab77ba18c11c8870500e1c09a9e25747e4cf0d8f1c88ae255a2beca6eef007');
|
||||
|
||||
INSERT INTO agent_api_key (user_id, key_prefix, key_hash, memo, status, create_id)
|
||||
SELECT 1000, 'xqak_5bdc', '85733c4eaab02e956bc555e0f25e5043629f9b8f8ad9ca39046735f5e817ca9c', 'dev 测试:无任何 scope 授权', 1, 0
|
||||
WHERE NOT EXISTS (SELECT 1 FROM agent_api_key WHERE key_hash = '85733c4eaab02e956bc555e0f25e5043629f9b8f8ad9ca39046735f5e817ca9c');
|
||||
|
||||
-- 作用域:运营
|
||||
INSERT INTO agent_scope (name, code, memo, status, create_id)
|
||||
SELECT '运营', 'operation', 'dev 种子:运营作用域', 1, 0
|
||||
WHERE NOT EXISTS (SELECT 1 FROM agent_scope WHERE code = 'operation');
|
||||
|
||||
-- 作用域-工具:sys.ping / agent.count / agent.list.query
|
||||
INSERT INTO scope_tool (scope_id, tool_id, create_id)
|
||||
SELECT s.id, t.id, 0 FROM agent_scope s JOIN tool t
|
||||
WHERE s.code = 'operation' AND t.name IN ('sys.ping', 'agent.count', 'agent.list.query')
|
||||
AND NOT EXISTS (SELECT 1 FROM scope_tool st WHERE st.scope_id = s.id AND st.tool_id = t.id);
|
||||
|
||||
-- token-作用域:HQ 与 AGENT 两把 token 授权"运营";NOSCOPE 不授权
|
||||
INSERT INTO token_scope (token_id, scope_id, create_id)
|
||||
SELECT k.id, s.id, 0 FROM agent_api_key k JOIN agent_scope s
|
||||
WHERE k.key_hash IN ('9068d5a6406afdb853cdc9f5e45e16a5191255e2feb1aba171cd66ea13d5711c',
|
||||
'00ab77ba18c11c8870500e1c09a9e25747e4cf0d8f1c88ae255a2beca6eef007')
|
||||
AND s.code = 'operation'
|
||||
AND NOT EXISTS (SELECT 1 FROM token_scope ts WHERE ts.token_id = k.id AND ts.scope_id = s.id);
|
||||
|
||||
COMMIT;
|
||||
|
||||
-- 校验
|
||||
SELECT k.id, k.user_id, k.key_prefix, k.memo FROM agent_api_key k ORDER BY k.id;
|
||||
SELECT s.id, s.code, t.name FROM agent_scope s JOIN scope_tool st ON s.id = st.scope_id JOIN tool t ON st.tool_id = t.id WHERE s.soft_delete = 0;
|
||||
SELECT ts.token_id, ts.scope_id FROM token_scope ts WHERE ts.soft_delete = 0;
|
||||
Reference in New Issue
Block a user