news 2026/9/15 22:29:51

Frappe v6.2.0 用户权限行为变更解析:从“静默放行“到“严格过滤“的权限语义

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Frappe v6.2.0 用户权限行为变更解析:从“静默放行“到“严格过滤“的权限语义

Frappe v6.2.0 用户权限行为变更解析:从"静默放行"到"严格过滤"的权限语义

【免费下载链接】frappeLow code web framework for real world applications, in Python and Javascript项目地址: https://gitcode.com/GitHub_Trending/fr/frappe

导读

本文围绕 frappe/change_log/v6/v6_2_0.md 中记录的 v6.2.0 权限行为变更展开:当某个 DocType 存在 User Permission(用户权限)规则、但用户尚不满足该规则时,系统默认不再展示不匹配的记录,只有在 System Settings 中勾选Ignore User Permissions If Missing时才允许放行。读完本文,你将掌握这一变更的确切含义、它在源码与测试中的实现形态、如何在 System Settings 中配置,以及如何基于文档、测试与字段定义准确理解这一行为。

说明:本文基于当前仓库(Frappe 现代版本)的源码与测试撰写,v6.2.0 时代的旧设置项名称在后续演进中已发生变化,文中会逐一指出两者的对应关系,帮助读者在旧版本与新版本之间建立准确的对照。

一、变更日志原文与核心语义

原文档(frappe/change_log/v6/v6_2_0.md)完整内容如下:

Permissions:

  • If User Permissions are missing for a DocType, don't show non-matching records.
  • IfIgnore User Permissions If Missingis checked in System Settings, show records even if User Permissions are not defined.

拆解这两条行为规则:

  1. 默认行为(收紧):当某个 DocType 配置了 User Permission(即存在针对特定用户/角色的记录过滤规则),而当前用户的记录不满足这些规则时,系统不再显示不匹配的记录。在 v6.2.0 之前,这类"规则缺失或记录不匹配"的情况往往被宽松对待,v6.2.0 将其收紧为"宁可少显示,也不越权显示"。
  2. 显式放行开关:在 System Settings 中勾选Ignore User Permissions If Missing后,即使 User Permissions 未定义(或记录不匹配),也照常显示这些记录,把"是否遵守缺失规则"的决策权交给系统管理员。

简言之:v6.2.0 让 User Permission 的过滤语义从"宽松"走向"严格默认、显式放行"。

二、当前仓库中的对应实现:从开关到开关语义的演进

2.1 设置项名称的演进:从 Ignore 到 Apply Strict

需要特别说明的是:v6.2.0 日志中提到的Ignore User Permissions If Missing设置项,在当前仓库中已演化为方向相反的语义:

  • 在 frappe/core/doctype/system_settings/system_settings.json 中,字段名为apply_strict_user_permissions,标签为Apply Strict User Permissions,默认值为"0"(不勾选);
  • 字段描述给出了精确语义:"If Apply Strict User Permission is checked and User Permission is defined for a DocType for a User, then all the documents where value of the link is blank, will not be shown to that User"(当勾选该选项且用户对某 DocType 定义了 User Permission 时,链接字段为空的文档将不会展示给该用户);
  • 对应的类型声明位于 frappe/core/doctype/system_settings/system_settings.py:apply_strict_user_permissions: DF.Check

也就是说,v6.2.0 时代的"忽略缺失的用户权限(Ignore)"在语义上等价于当前仓库中"不启用严格用户权限(Apply Strict = 不勾选)";而"严格模式"正是 v6.2.0 之后默认收紧的过滤行为。理解这个"开关取反"的演进,是读懂新旧版本行为的关键。

2.2 单例 DocType 的读取与缓存

System Settings 是典型的单例(Single)DocType。仓库提供了便捷读取接口get_system_settings(frappe/core/doctype/system_settings/system_settings.py),它优先从frappe.local.system_settings获取,未命中时通过frappe.client_cache.get_doc("System Settings")加载并缓存;保存设置后clear_system_settings_cache(同文件 L276-L279)会清除相关缓存键,保证开关变更立即生效。

三、权限判定源码:has_user_permission的两步检查

User Permission 的最终裁决入口是frappe/permissions.py中的has_user_permission(frappe/permissions.py)。它采用"两步检查 + 严格模式开关"的结构:

前置判断(L362-L386):

  • get_user_permissions(user)返回空(用户完全不受任何 User Permission 影响),直接返回True——这与日志第一条"缺失即不过滤"的默认宽松语义呼应;
  • apply_strict_user_permissions = strict and (False if doc.meta.issingle else frappe.get_system_settings("apply_strict_user_permissions")):单例 DocType 因为含空链接字段,永远不启用严格模式
  • 对于__islocal的未保存文档(ptype为 read/write 且数据库中不存在该记录),严格模式会被跳过,避免在新建过程中误判。

STEP 1:检查文档自身(L388-L418)

  • doctype in user_permissions且存在允许的文档列表allowed_docs时,若docname不在允许列表内,则拒绝访问。这对应"对 DocType 本身做记录级过滤"。

STEP 2:检查所有 Link 字段(L420-L485)

  • 遍历父表与所有子表记录的 Link 字段(check_user_permission_on_link_fields,L423-L476):
    • 字段设置了ignore_user_permissions则跳过;
    • 关键分支if not d.get(field.fieldname) and not apply_strict_user_permissions: continue——当链接值为空时,非严格模式直接放行;严格模式下空值也会被检查并拒绝;
    • 当该 Link 目标 DocType 在user_permissions中且存在允许列表时,若当前值不在允许列表内,则拒绝,并给出精确的错误消息(子表行会附带row {idx}, field {label}定位信息)。

这也印证了日志中"不显示不匹配记录"的落点:在 v6.2.0 收紧后,空链接值/不匹配链接值在默认情况下不再被展示。

四、列表查询层的过滤:db_query.py的 SQL 级实现

记录级访问控制同样作用于列表查询。在 frappe/model/db_query.py 的add_user_permissions中:

  • 遍历当前 DocType 的所有 Link 字段(并追加name字段作为自身过滤入口);
  • 对每个存在 User Permission 的字段构造过滤条件:
    • 严格模式开启时condition = ""不附加空值豁免,空链接值的行也进入过滤);
    • 非严格模式时condition = "ifnull(...)='' or "空值行豁免,直接放行)。

这是对has_user_permission语义在 SQL 层的复刻:同一开关同时决定"单文档级"与"列表级"的行为一致性。此外,frappe/model/mapper.py(L70、L99、L179)在文档映射(copy/map)场景中也读取同一设置,说明该开关对跨 DocType 的复制操作同样生效。

五、测试验证:三条测试用例锁定的行为契约

仓库中的 frappe/tests/test_permissions.py 用测试用例固化了这一语义,可将其作为行为契约的权威参考:

  1. test_ignore_user_permissions_if_missing(L455-L477)

    • 先为用户test2@example.com添加Test Blog Category的 User Permission,使用另一个分类(_Test Blog Category 2)创建文档时has_permission("write")False(记录不匹配 → 拒绝);
    • 移除该 User Permission 后,同一文档has_permission("write")变为True——"权限缺失即按角色放行",正是 v6.2.0 第一条语义的正面写照。
  2. test_strict_user_permissions(L479-L519)

    • 通过self.set_strict_user_permissions(0/1)切换 System Settings 中的apply_strict_user_permissions
    • 关闭严格模式时,未匹配的other_contact也可读,frappe.get_list("Contact")返回 2 条(空值豁免生效);
    • 开启严格模式后,other_contact不可读,列表仅返回 1 条(空值不再豁免)。
  3. 更早的test_user_permissions_in_doc(L420 前段)验证了"未配置 User Permission 时插入被拒、配置后放行"的完整闭环,以及权限检查对 read/write/create 的区分。

六、实战配置建议与行为对照表

6.1 在 System Settings 中配置

  1. 以 System Manager 角色登录,打开System Settings(单例 DocType,定义于 frappe/core/doctype/system_settings/system_settings.json);
  2. Permissions区块找到Apply Strict User Permissions复选框;
  3. 勾选后保存,clear_system_settings_cache会自动清除缓存,新行为即刻生效(frappe/core/doctype/system_settings/system_settings.py);
  4. 之后在User PermissionDocType 中为用户添加具体的记录级权限规则。

6.2 新旧语义对照表

v6.2.0 日志语义当前仓库等价语义源码落点
不勾选 Ignore User Permissions If Missing → 不显示不匹配记录勾选 Apply Strict User Permissions(默认关闭)→ 空值/不匹配记录被过滤frappe/permissions.py、frappe/model/db_query.py
勾选 Ignore User Permissions If Missing → 即使未定义也显示记录不勾选 Apply Strict User Permissions → 空值豁免、按角色放行frappe/permissions.py
单例 DocType 永不启用严格模式frappe/permissions.py
字段级ignore_user_permissions可单独豁免某个 Link 字段frappe/permissions.py

6.3 选择建议

  • 安全敏感场景(财务、人事、多租户数据隔离):保持严格模式开启,确保空链接字段的记录也绝不越权可见;
  • 日常业务流畅性优先:关闭严格模式,允许空链接值记录正常展示,仅对已定义规则且明确不匹配的记录进行过滤;
  • 对树形 DocType 的 create 操作、__islocal未保存文档,框架已内置豁免逻辑,无需额外配置。

七、总结

v6.2.0 的权限变更确立了 Frappe 用户权限体系的基线语义:默认按"存在规则即过滤、不匹配即隐藏"执行,同时提供全局开关允许管理员显式放宽。这一语义在 frappe/permissions.py(单文档裁决)、frappe/model/db_query.py(列表 SQL 过滤)、frappe/model/mapper.py(文档映射)三层实现中保持一致,并由 frappe/tests/test_permissions.py 中的test_ignore_user_permissions_if_missingtest_strict_user_permissions固化验证。理解并正确配置Apply Strict User Permissions开关,是任何 Frappe 应用在数据隔离与业务体验之间取得平衡的第一步。

【免费下载链接】frappeLow code web framework for real world applications, in Python and Javascript项目地址: https://gitcode.com/GitHub_Trending/fr/frappe

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/15 22:28:59

Open Agents 会话管理指南:如何创建、恢复与归档编码任务

Open Agents 会话管理指南:如何创建、恢复与归档编码任务 【免费下载链接】open-agents An open source template for building cloud agents. 项目地址: https://gitcode.com/GitHub_Trending/op/open-agents Open Agents 是一个开源的云编码智能体&#xf…

作者头像 李华
网站建设 2026/9/15 22:28:18

大模型Prompt注入攻击防御与测试实践

1. Prompt注入攻击的本质与危害在大模型应用开发中,Prompt注入攻击已成为最隐蔽且破坏性最强的安全威胁之一。这种攻击通过精心构造的输入文本,诱导模型执行非预期操作或泄露敏感信息。我曾在金融领域的大模型项目中,亲眼见证过攻击者仅用三行…

作者头像 李华
网站建设 2026/9/15 22:27:27

软考软件设计师安全与加密认证技术核心考点解析

1. 软考软件设计师安全与加密认证技术全景解析作为软考软件设计师考试的核心模块,计算机安全与加密认证技术占据着举足轻重的地位。根据近5年真题统计,该模块平均占比达18-22分,涉及知识点多达37个,是考生普遍反映的难点集中区。我…

作者头像 李华
网站建设 2026/9/15 22:25:14

R-EAM与SOA单片集成:实现10.7 Gb/s无色ONU的关键技术

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华