批准被更正为 Declined:如何测试权限撤销

先在免费沙盒中跑通流程,再准备生产接入。

统计选择在本站复用,可随时关闭;账号关联另行同意。

批准被更正为 Declined:如何测试权限撤销

你的 fixture 会话收到 Approved,并授予了一项本地权限。随后又到达一个 Declined 事件。你需要决定该事件是否撤销访问,以及如何区分真正的更正与重放或过时的回调。本文在合成 fixture 中测试这一决策,并区分 fixture 已实现的行为与应用需自行设计的部分。

curl https://gridzen.ai/console/api/quickstart/trial \
  -H 'Content-Type: application/json' \
  -d '{"task": "identity_onboarding", "scenario": "success"}'

接入指南

问题:不再成立的批准

某卖家通过了验证,处理程序记录了 Approved,显式策略允许授予本地权限。之后,同一会话收到新的 Declined 事件。如果代码把所有终态视为最终结果,就会忽略这次更正,访问仍然开放。如果把每个传入事件都视为新事件,重放的回调可能让状态来回翻转。目标很明确:在 Approved 之后到达的新 Declined 更正,必须把 permission_granted 从 true 改为 false;grant_count 必须保持为 1,因为授予的历史不会消失。重复事件和过时事件不应改变任何内容。真实提供方是否会发送此类更正、其含义是什么,取决于该提供方的实际合同。fixture 只用于演练这种结构。

fixture 实际实现了什么

可下载的身份示例把会话和已处理的事件 ID 存在 SQLite 中。其 event 方法只接受 mode 为 synthetic_fixture、source 为 fixture_callback 的输入,且事件 ID 必须以 fixture- 开头。它没有生产签名验证器。它先检查 tenant 与 subject 绑定,再按会话与事件 ID 组合去重。更正由一条规则处理:若存储状态为 approved 且传入状态为 Declined,fixture 会记录该事件,把 status 设为 declined、granted 设为 0,grants 计数保持不变。针对 approved、declined 或 expired 会话的其他任何事件,都会原样返回当前状态,且不会记录该事件。这项更正检查在截止时间检查之前执行,因此即使 Declined 更正在截止时间之后到达,也会被应用。live_permission_changed 始终为 false,不存在任何真实权限。

假设场景与预期输出

以下是假设演练:会话为 fixture-session,绑定 fixture-tenant 和 fixture-user,deadline 为 60。 第 1 步:发送事件 fixture-approved,status 为 Approved,policy 为 true。预期 status 为 approved,deadline 为 60,permission_granted 为 true,grant_count 为 1,live_permission_changed 为 false。 第 2 步:重放 fixture-approved。预期返回完全相同的对象,重复事件不产生任何效果。 第 3 步:发送新的事件 ID,例如 fixture-correction,status 为 Declined。预期 status 为 declined,deadline 为 60,permission_granted 为 false,grant_count 为 1,live_permission_changed 为 false。 已测试的 expired 输出属于另一条路径:会话从未获得批准。其 status 为 expired,permission_granted 为 false,grant_count 为 0,next 为 review_or_authorized_provider_refresh,provider_polled 为 false。不要把它当作撤销的证据。

新的更正、重复事件,还是过时的待定事件

有三类输入看起来相似,必须加以区分。 新的更正:事件 ID 未出现过,针对 approved 会话,status 为 Declined。它会撤销权限。 重复事件:复用已处理的事件 ID。即使其 status 字段已变化,也只返回已存储的状态。 过时的待定事件:例如在 Approved 之后到达的 In Progress 或 In Review。它不得降级或重新授予任何内容。fixture 返回当前状态,且不记录该事件。 另有两种情况遵循同一规则:Declined 更正之后迟到的 Approved 同样被忽略,权限不会被悄悄重新开放;declined 之后的第二个 Declined 也不改变任何内容。 每种情况都应使用不同的事件 ID 测试,并同时断言 permission_granted 和 grant_count。

提议设计:由调用方持有的撤销回执

以下是提议设计,不是 fixture 的行为。fixture 只翻转一个标志;真实的撤销会涉及你自己系统中的上架、付款或会话。由调用方持有的撤销回执可以记录: - 会话 - 触发更正的事件 ID - 先前状态和新状态 - 撤销时的授予计数 - 时间戳 - 请求了哪些下游操作、哪些已确认完成 在清除权限的同一事务中写入该回执,并让下游撤销步骤基于该回执保持幂等。在信任一次更正之前,应通过已授权的提供方通道重新获取权威决定。合成的 Declined 不能证明真实拒绝,合成 fixture 权限也不等于真实的业务权限。

失败处理

以下几类失败需要明确的处理方式。 若更正未通过绑定检查,fixture 会抛出 BINDING_MISMATCH。应将其视为告警,而不是撤销。 非合成来源会抛出 PRODUCTION_SIGNATURE_VERIFIER_NOT_IMPLEMENTED;不以 fixture- 开头的事件 ID 会抛出 SYNTHETIC_EVENT_REQUIRED;向不存在的会话提交事件会抛出 BINDING_MISMATCH;使用 read 读取不存在的会话会抛出 SESSION_NOT_FOUND。 recover 方法只会在本地把 pending、review 或 unknown 会话置为过期。它从不轮询提供方,也从不撤回批准,因此不能依赖它来发现遗漏的更正。 若下游撤销部分失败,应保持权限已清除,并把回执标记为未完成以待审核,不要恢复访问。

验收清单

- Approved 且 policy 为 true 时,permission_granted 为 true,grant_count 为 1。 - 重放批准事件 ID 后,两个字段均不变。 - 新的 Declined 事件得到 status declined、permission_granted false、grant_count 1。 - Approved 之后过时的 In Progress 或 In Review 不改变任何内容。 - 更正之后迟到的 Approved 不会恢复权限。 - tenant 或 subject 错误的更正被拒绝。 - live_permission_changed 始终为 false。 - 你自己的回执和下游撤销步骤需单独测试。 - 在任何真实使用之前,已对照真实提供方合同确认更正语义。

运行已检查的模拟示例

下载并解压 https://gridzen.ai/downloads/verification-delivery.zip,进入 verification_delivery,用 Python 3.10+ 运行。此本地示例不联网;独立身份实验请使用新的数据库。

python3 delivery.py identity --db /tmp/gridzen-article-fixture.sqlite

来源与范围

https://gridzen.ai/guides/approved-seller-permissions/ https://gridzen.ai/guides/current-capabilities/ 依据已检查的来源快照与本地模拟;建议的业务规则属于设计建议,不代表已证明的生产行为。内容使用 AI 辅助写作,并经过独立审稿。

另行体验三种沙盒结果 创建账号,继续项目接入

下载不等于运行成功;本地示例与在线沙盒分别测试。

接入你的应用

运行三种模拟结果 · 需要接入帮助

连接免费沙盒账号

号码基础有效性不证明持有权或送达,不提供短信验证码。业务放行由你的系统判断。