Skip to content

filterAppForUser 只走 app 顶层 navigation —— areas[] 里的 nav 项权限过滤仅客户端生效(#4651 移除假闸门后剩下的真缺口) #4722

Description

@os-zhuang

从 #4651 / #4718 分出的独立记录。未指派 —— 只是记录。

现象

服务端权威可见性闸门 filterAppForUser(packages/rest/src/rest-server.ts)只过滤 app 的顶层 navigation 树:

:1814  检 app 级 requiredPermissions —— 不满足 return null
:1823  const nav = Array.isArray(item.navigation) ? item.navigation : null;
       if (!nav) return item;                       ← 没有 navigation 就直接原样返回
:1826  filterNav 递归检 nav 项级 requiredPermissions / requiresService

item.areas 从头到尾没有被读到。所以一个写在 area 内部的 nav 项上的 requiredPermissions / requiresService:

  • 服务端不剥离 —— 该条目连同它的 objectName / pageName / componentRef 等指向,照常出现在 /meta 响应里;
  • 只有客户端 NavigationRenderer.tsx:894 的 checkPerm 会把它藏起来。

也就是说,对 areas 型 app 而言,导航项级权限目前是渲染层的礼貌,不是服务端强制。改一次前端状态、或者直接读 /meta 的 JSON,就能看到本该被 gate 掉的条目。

与 #4651 的关系(这是剩下的那一半)

#4651 处理的是 area 级的两个键 areas[].visible / areas[].requiredPermissions——它们任何一层都没有消费者,是纯粹 fail-open 的假闸门,已按维护者裁决在 17.0.0 走路线 B 移除(#4718)。

本单是另一件事:area 里面的 nav 项闸门是真的被消费的,只是只被客户端消费。#4651 的处方对此没有回避,明写了限定并落进了三处:

  • 退役处方本身(ui/app.zod.ts 的 AREA_REQUIRED_PERMISSIONS_RETIRED:「Items nested under areas[] are gated in the shell only — the server does not walk areas」);
  • 活性账本 packages/spec/liveness/app.json 的 areas.navigation 条目 note;
  • 一条 characterisation pin(packages/rest/src/rest.test.ts,filterAppForUser — the enforced permission layers (#4651) 里的最后一条),它故意把当前行为钉住,并在注释里写明:谁让它开始走 areas,就应该看到这条断言红掉、然后连同账本 note 一起有意识地改写。

所以现状是「已知、已记录、已钉住」,但没有 open issue 跟踪——#4651 已随 #4718 关闭。本单补上这个跟踪位。

需要决定(与 #4651 的路线 A 是同一组语义问题)

要让服务端也过滤 areas,先得回答:

  1. 一个 area 里的项被过滤光之后,这个 area 本身还返不返回?(返回一个空 area,客户端切过去是一片空白)
  2. 顶层 navigation 与 areas[].navigation 同时存在时(schema 允许,AppSchema with areas 的 backward-compat 用例就是这个形状),两棵树的过滤要不要一致?
  3. 是否顺带补服务端的 visible CEL 求值?目前 visible 任何层级都只在客户端求值(AppSidebar.tsx:236 经 ExpressionProvider),服务端从不绑定 user 上下文——所以「服务端强制」在 requiredPermissions / requiresService 上成立,在 visible 上不成立,这个不对称本身也值得写进文档而不是让人自己发现。

影响面

关联

#4651(area 级假闸门,已移除)、#4718(实现 PR,含上述三处记录与 pin)、ADR-0045(hidden app 可见性)、ADR-0057 D10(requiresService 能力闸门)、ADR-0049(enforce-or-remove)、ADR-0078(false compliance)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions