fix(commands): preserve owner allowlists for native auth · openclaw/openclaw@8af50b5
obviyus
·
2026-04-29
·
via Recent Commits to openclaw:main
| Original file line number | Diff line number | Diff line change |
|---|
@@ -99,6 +99,31 @@ describe("senderIsOwner only reflects explicit owner authorization", () => {
|
99 | 99 | expect(auth.senderIsOwner).toBe(false); |
100 | 100 | }); |
101 | 101 | |
| 102 | +it("does not let native command authorization bypass explicit owner allowlists", () => { |
| 103 | +const cfg = { |
| 104 | +channels: { telegram: {} }, |
| 105 | +commands: { ownerAllowFrom: ["456"] }, |
| 106 | +} as OpenClawConfig; |
| 107 | + |
| 108 | +const ctx = { |
| 109 | +Provider: "telegram", |
| 110 | +Surface: "telegram", |
| 111 | +ChatType: "group", |
| 112 | +From: "telegram:group:-100123", |
| 113 | +SenderId: "200482621", |
| 114 | +CommandSource: "native", |
| 115 | +} as MsgContext; |
| 116 | + |
| 117 | +const auth = resolveCommandAuthorization({ |
| 118 | + ctx, |
| 119 | + cfg, |
| 120 | +commandAuthorized: true, |
| 121 | +}); |
| 122 | + |
| 123 | +expect(auth.senderIsOwner).toBe(false); |
| 124 | +expect(auth.isAuthorizedSender).toBe(false); |
| 125 | +}); |
| 126 | + |
102 | 127 | it("senderIsOwner is true when ownerAllowFrom matches sender", () => { |
103 | 128 | const cfg = { |
104 | 129 | channels: { discord: {} }, |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -429,6 +429,7 @@ function resolveOwnerAuthorizationState(params: {
|
429 | 429 | |
430 | 430 | function resolveCommandSenderAuthorization(params: { |
431 | 431 | commandAuthorized: boolean; |
| 432 | +nativeCommandAuthorized: boolean; |
432 | 433 | isOwnerForCommands: boolean; |
433 | 434 | senderCandidates: string[]; |
434 | 435 | commandsAllowFromList: string[] | null; |
@@ -450,10 +451,7 @@ function resolveCommandSenderAuthorization(params: {
|
450 | 451 | !params.providerResolutionError && (commandsAllowAll || Boolean(matchedCommandsAllowFrom)) |
451 | 452 | ); |
452 | 453 | } |
453 | | -if (params.commandAuthorized) { |
454 | | -return true; |
455 | | -} |
456 | | -return params.isOwnerForCommands; |
| 454 | +return params.commandAuthorized && (params.isOwnerForCommands || params.nativeCommandAuthorized); |
457 | 455 | } |
458 | 456 | |
459 | 457 | function isConversationLikeIdentity(value: string): boolean { |
@@ -707,8 +705,11 @@ export function resolveCommandAuthorization(params: {
|
707 | 705 | : ownerAllowlistConfigured |
708 | 706 | ? senderIsOwner |
709 | 707 | : senderIsOwnerByScope || Boolean(matchedCommandOwner); |
| 708 | +const nativeCommandAuthorized = |
| 709 | +commandAuthorized && ctx.CommandSource === "native" && !ownerAllowlistConfigured; |
710 | 710 | const isAuthorizedSender = resolveCommandSenderAuthorization({ |
711 | 711 | commandAuthorized, |
| 712 | + nativeCommandAuthorized, |
712 | 713 | isOwnerForCommands, |
713 | 714 | senderCandidates, |
714 | 715 | commandsAllowFromList, |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -202,6 +202,49 @@ describe("resolveCommandAuthorization", () => {
|
202 | 202 | expect(auth.isAuthorizedSender).toBe(false); |
203 | 203 | }); |
204 | 204 | |
| 205 | +it("allows channel-validated native commands when plugin owner enforcement has no owner allowlist", () => { |
| 206 | +setActivePluginRegistry( |
| 207 | +createTestRegistry([ |
| 208 | +{ |
| 209 | +pluginId: "discord", |
| 210 | +plugin: { |
| 211 | + ...createOutboundTestPlugin({ |
| 212 | +id: "discord", |
| 213 | +outbound: { deliveryMode: "direct" }, |
| 214 | +}), |
| 215 | +commands: { enforceOwnerForCommands: true }, |
| 216 | +config: { |
| 217 | +listAccountIds: () => ["default"], |
| 218 | +resolveAccount: () => ({}), |
| 219 | +resolveAllowFrom: () => ["*"], |
| 220 | + formatAllowFrom, |
| 221 | +}, |
| 222 | +}, |
| 223 | +source: "test", |
| 224 | +}, |
| 225 | +]), |
| 226 | +); |
| 227 | +const cfg = { |
| 228 | +channels: { discord: { allowFrom: ["*"] } }, |
| 229 | +} as OpenClawConfig; |
| 230 | + |
| 231 | +const auth = resolveCommandAuthorization({ |
| 232 | +ctx: { |
| 233 | +Provider: "discord", |
| 234 | +Surface: "discord", |
| 235 | +ChatType: "direct", |
| 236 | +From: "discord:123", |
| 237 | +SenderId: "123", |
| 238 | +CommandSource: "native", |
| 239 | +} as MsgContext, |
| 240 | + cfg, |
| 241 | +commandAuthorized: true, |
| 242 | +}); |
| 243 | + |
| 244 | +expect(auth.senderIsOwner).toBe(false); |
| 245 | +expect(auth.isAuthorizedSender).toBe(true); |
| 246 | +}); |
| 247 | + |
205 | 248 | it("uses explicit owner allowlist when allowFrom is empty", () => { |
206 | 249 | const cfg = { |
207 | 250 | commands: { ownerAllowFrom: ["whatsapp:+15551234567"] }, |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。