huoyan-enterprise/权限.html

278 lines
11 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>知识库权限说明</title>
<style>
:root {
--bg: #f6f8fa;
--card: #ffffff;
--border: #e1e4e8;
--hdr: #24292f;
--text: #333;
--muted: #6e7781;
--blue: #0969da;
--green: #1a7f37;
--orange: #bc4c00;
--red: #cf222e;
--purple: #8250df;
--tag-bg: #ddf4ff;
--tag-text: #0969da;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
background: var(--bg); color: var(--text); padding: 32px 24px; line-height: 1.6; }
h1 { font-size: 22px; color: var(--hdr); margin-bottom: 6px; }
.subtitle { color: var(--muted); font-size: 13px; margin-bottom: 32px; }
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 20px; }
.card { background: var(--card); border: 1px solid var(--border); border-radius: 10px; padding: 20px; }
.card h2 { font-size: 14px; font-weight: 600; color: var(--hdr); margin-bottom: 14px;
display: flex; align-items: center; gap: 6px; }
.card h2 .icon { width: 20px; height: 20px; border-radius: 5px; display: inline-flex;
align-items: center; justify-content: center; font-size: 12px; }
.icon-kb { background: #ddf4ff; color: var(--blue); }
.icon-file { background: #dafbe1; color: var(--green); }
.icon-role { background: #fff8c5; color: #9a6700; }
.icon-dept { background: #ffefe7; color: var(--orange); }
.icon-perm { background: #fbefff; color: var(--purple); }
.icon-audit{ background: #ffe4e4; color: var(--red); }
table { width: 100%; border-collapse: collapse; font-size: 13px; }
th { background: var(--bg); color: var(--muted); font-weight: 600;
text-align: left; padding: 6px 10px; border-bottom: 1px solid var(--border); }
td { padding: 7px 10px; border-bottom: 1px solid #f0f0f0; vertical-align: top; }
tr:last-child td { border-bottom: none; }
.badge { display: inline-block; padding: 1px 7px; border-radius: 20px; font-size: 11px; font-weight: 500; }
.b-blue { background: #ddf4ff; color: var(--blue); }
.b-green { background: #dafbe1; color: var(--green); }
.b-orange { background: #ffefe7; color: var(--orange); }
.b-red { background: #ffe4e4; color: var(--red); }
.b-purple { background: #fbefff; color: var(--purple); }
.b-gray { background: #f0f0f0; color: #555; }
.b-yellow { background: #fff8c5; color: #9a6700; }
.check { color: var(--green); font-weight: 700; }
.cross { color: var(--red); }
.note { font-size: 12px; color: var(--muted); margin-top: 10px; padding-top: 8px;
border-top: 1px dashed var(--border); }
.full { grid-column: 1 / -1; }
/* 矩阵表 */
.matrix th:not(:first-child), .matrix td:not(:first-child) { text-align: center; }
</style>
</head>
<body>
<h1>🔐 知识库权限说明</h1>
<p class="subtitle">方案 A — 基于角色 + 部门层级 + 可见性的多维权限体系</p>
<div class="grid">
<!-- 1. 角色定义 -->
<div class="card">
<h2><span class="icon icon-role">👤</span> 角色定义</h2>
<table>
<tr><th>角色</th><th>标识</th><th>说明</th></tr>
<tr><td>超级管理员</td><td><span class="badge b-red">admin</span></td><td>企业内全部权限,不受部门限制</td></tr>
<tr><td>部门领导</td><td><span class="badge b-blue">leader</span></td><td>管辖本部门及所有子孙部门</td></tr>
<tr><td>普通员工</td><td><span class="badge b-gray">employee</span></td><td>仅操作自己的资源</td></tr>
</table>
</div>
<!-- 2. 部门管辖范围 -->
<div class="card">
<h2><span class="icon icon-dept">🏢</span> 部门管辖范围</h2>
<table>
<tr><th>角色</th><th>可管辖的部门</th></tr>
<tr><td><span class="badge b-red">admin</span></td><td>企业所有部门</td></tr>
<tr>
<td><span class="badge b-blue">leader</span></td>
<td>
所在部门 + 全部子孙部门<br/>
<span style="color:var(--muted);font-size:12px">(递归 CTE 计算)</span>
</td>
</tr>
<tr><td><span class="badge b-gray">employee</span></td><td>无管辖,仅属于一个部门</td></tr>
</table>
<p class="note">示例:技术部领导 → 管辖 技术部、前端组、后端组(全子树)</p>
</div>
<!-- 3. 知识库可见性 -->
<div class="card">
<h2><span class="icon icon-kb">📚</span> 知识库可见性</h2>
<table>
<tr><th>visibility</th><th>可见范围</th></tr>
<tr><td><span class="badge b-gray">private</span></td><td>仅创建者本人</td></tr>
<tr><td><span class="badge b-blue">department</span></td><td>同部门所有成员 + admin</td></tr>
<tr><td><span class="badge b-green">enterprise</span></td><td>企业全员 + admin</td></tr>
</table>
<p class="note">leader 额外规则:本部门内任何可见性的知识库均可查看</p>
</div>
<!-- 4. 知识库操作权限矩阵 -->
<div class="card full">
<h2><span class="icon icon-kb">📋</span> 知识库操作权限矩阵</h2>
<table class="matrix">
<tr>
<th>操作</th>
<th>admin</th>
<th>leader本部门KB</th>
<th>leader子部门KB</th>
<th>employee自己创建</th>
<th>employee他人department/enterprise KB</th>
</tr>
<tr>
<td>查看知识库</td>
<td><span class="check"></span></td>
<td><span class="check"></span></td>
<td><span class="check"></span> 若可见性匹配</td>
<td><span class="check"></span></td>
<td><span class="check"></span></td>
</tr>
<tr>
<td>编辑/删除知识库</td>
<td><span class="check"></span></td>
<td>仅自己创建的</td>
<td>仅自己创建的</td>
<td><span class="check"></span></td>
<td><span class="cross"></span></td>
</tr>
<tr>
<td>上传文件</td>
<td>需 allow_kb_upload=true</td>
<td>需 allow_kb_upload=true</td>
<td></td>
<td>需 allow_kb_upload=true</td>
<td>需 allow_kb_upload=true</td>
</tr>
<tr>
<td>查看文件列表</td>
<td><span class="check">✓ 全部文件</span></td>
<td><span class="check">✓ 全部文件</span></td>
<td></td>
<td><span class="check">✓ 全部文件</span></td>
<td><span class="check">✓ 全部文件</span></td>
</tr>
</table>
</div>
<!-- 5. 文件删除权限 -->
<div class="card">
<h2><span class="icon icon-file">🗑️</span> 文件删除权限</h2>
<table>
<tr><th>谁能删</th><th>条件</th></tr>
<tr><td>文件上传者本人</td><td>无条件</td></tr>
<tr><td><span class="badge b-red">admin</span></td><td>同企业内任意文件</td></tr>
<tr>
<td><span class="badge b-blue">leader</span></td>
<td>上传者在其管辖子树内(即是其下属)</td>
</tr>
<tr><td><span class="badge b-gray">employee</span></td><td>仅自己上传的文件</td></tr>
</table>
</div>
<!-- 6. 上传权限控制 -->
<div class="card">
<h2><span class="icon icon-perm">🔒</span> 上传权限控制</h2>
<table>
<tr><th>条件</th><th>能否上传</th></tr>
<tr><td>allow_kb_upload = true <br/>且 能查看该 KB</td><td><span class="check">✓ 允许</span></td></tr>
<tr><td>allow_kb_upload = false</td><td><span class="cross">✗ 禁止</span>(不论角色)</td></tr>
<tr><td>无权查看 KB</td><td><span class="cross">✗ 禁止</span></td></tr>
</table>
<p class="note">
<b>谁能修改 allow_kb_upload</b><br/>
admin → 任意用户 &nbsp;&nbsp; leader → 自己管辖的下属
</p>
</div>
<!-- 7. 审计日志可见范围 -->
<div class="card">
<h2><span class="icon icon-audit">📝</span> 审计日志可见范围</h2>
<table>
<tr><th>角色</th><th>可查看的日志</th></tr>
<tr><td><span class="badge b-red">admin</span></td><td>企业全员所有操作日志</td></tr>
<tr>
<td><span class="badge b-blue">leader</span></td>
<td>本部门及子孙部门成员的操作日志</td>
</tr>
<tr><td><span class="badge b-gray">employee</span></td><td>无权查看审计日志</td></tr>
</table>
<p class="note">记录动作upload / download / delete / create_kb / delete_kb / permission_change</p>
</div>
<!-- 8. 团队管理入口 -->
<div class="card">
<h2><span class="icon icon-role">⚙️</span> 管理功能入口</h2>
<table>
<tr><th>功能</th><th>入口</th><th>谁能用</th></tr>
<tr>
<td>设置部门负责人</td>
<td><span class="badge b-gray">管理后台</span></td>
<td><span class="badge b-red">admin</span></td>
</tr>
<tr>
<td>修改任意用户上传权限</td>
<td><span class="badge b-gray">管理后台</span></td>
<td><span class="badge b-red">admin</span></td>
</tr>
<tr>
<td>修改下属上传权限</td>
<td><span class="badge b-blue">前台·团队管理</span></td>
<td><span class="badge b-blue">leader</span></td>
</tr>
<tr>
<td>查看团队操作日志</td>
<td><span class="badge b-blue">前台·团队管理</span></td>
<td><span class="badge b-blue">leader</span></td>
</tr>
<tr>
<td>查看全企业操作日志</td>
<td><span class="badge b-gray">管理后台</span></td>
<td><span class="badge b-red">admin</span></td>
</tr>
</table>
</div>
<!-- 9. 越级禁止 -->
<div class="card full">
<h2><span class="icon icon-perm">🚫</span> 越级操作一律拒绝</h2>
<table>
<tr><th>场景</th><th>结果</th><th>说明</th></tr>
<tr>
<td>leader 操作非下属用户的权限</td>
<td><span class="cross">403 Forbidden</span></td>
<td>is_subordinate() 检测不在子树内</td>
</tr>
<tr>
<td>leader 删除非下属上传的文件</td>
<td><span class="cross">403 Forbidden</span></td>
<td>can_delete_file() 返回 False</td>
</tr>
<tr>
<td>employee 访问 private KB非自己创建</td>
<td><span class="cross">403 Forbidden</span></td>
<td>can_view_kb() 返回 False</td>
</tr>
<tr>
<td>allow_kb_upload=false 的用户上传文件</td>
<td><span class="cross">400 Bad Request</span></td>
<td>can_upload_to_kb() 返回 False</td>
</tr>
<tr>
<td>跨企业访问任何资源</td>
<td><span class="cross">403 Forbidden</span></td>
<td>enterprise_id 强制校验</td>
</tr>
</table>
</div>
</div>
<p style="margin-top:28px; font-size:12px; color:var(--muted);">
实现位置:<code>backend/core/permissions.py</code> &nbsp;·&nbsp;
路由层:<code>backend/api/kb_file_router.py</code> &nbsp;·&nbsp;
团队 API<code>backend/api/team_router.py</code>
</p>
</body>
</html>