Files
wehub-resource-sync bf9395e022
CI / results (push) Blocked by required conditions
CI / license-header (push) Has been skipped
CI / e2e-dry-run (push) Has been skipped
CI / e2e-live (push) Waiting to run
CI / fast-gate (push) Failing after 0s
Test PR Label Logic / test-pr-labels (push) Failing after 1s
Skill Format Check / check-format (push) Failing after 2s
CI / security (push) Failing after 5s
CI / unit-test (push) Has been skipped
CI / lint (push) Has been skipped
CI / script-test (push) Has been skipped
CI / deterministic-gate (push) Has been skipped
CI / coverage (push) Has been skipped
CI / deadcode (push) Waiting to run
chore: import upstream snapshot with attribution
2026-07-13 12:22:54 +08:00

434 lines
16 KiB
Go

// Copyright (c) 2026 Lark Technologies Pte. Ltd.
// SPDX-License-Identifier: MIT
package internalplatform_test
import (
"bytes"
"context"
"errors"
"strings"
"testing"
"github.com/larksuite/cli/extension/platform"
internalplatform "github.com/larksuite/cli/internal/platform"
)
// happyPlugin is a textbook plugin: declares Capabilities, calls a few
// Registrar methods, returns nil. The install pipeline must accept it.
type happyPlugin struct{ name string }
func (p happyPlugin) Name() string { return p.name }
func (p happyPlugin) Version() string { return "1.0.0" }
func (p happyPlugin) Capabilities() platform.Capabilities {
return platform.Capabilities{
FailurePolicy: platform.FailOpen,
}
}
func (p happyPlugin) Install(r platform.Registrar) error {
r.Observe(platform.Before, "audit-pre", platform.All(),
func(context.Context, platform.Invocation) {})
r.Wrap("policy", platform.All(),
func(next platform.Handler) platform.Handler {
return func(ctx context.Context, inv platform.Invocation) error {
return next(ctx, inv)
}
})
r.On(platform.Shutdown, "flush",
func(context.Context, *platform.LifecycleContext) error { return nil })
return nil
}
func TestInstallAll_happyPlugin(t *testing.T) {
result, err := internalplatform.InstallAll([]platform.Plugin{happyPlugin{name: "audit"}}, nil)
if err != nil {
t.Fatalf("InstallAll: %v", err)
}
if result.Registry == nil {
t.Fatalf("registry should be populated")
}
if len(result.PluginRules) != 0 {
t.Errorf("happy plugin did not call Restrict; rules should be empty")
}
// Cross-check: observers, wrappers, lifecycles got staged through to the live Registry.
if len(result.Registry.MatchingObservers(fakeView{}, platform.Before)) != 1 {
t.Errorf("Before observer not committed")
}
if len(result.Registry.MatchingWrappers(fakeView{})) != 1 {
t.Errorf("Wrapper not committed")
}
if len(result.Registry.LifecycleHandlers(platform.Shutdown)) != 1 {
t.Errorf("Shutdown lifecycle not committed")
}
}
// fakeView satisfies platform.CommandView for selector lookups in the
// platformhost tests; All() matches everything so the type can stay
// trivial.
type fakeView struct{}
func (fakeView) Path() string { return "" }
func (fakeView) Domain() string { return "" }
func (fakeView) Risk() (platform.Risk, bool) { return "", false }
func (fakeView) Identities() []platform.Identity { return nil }
func (fakeView) Annotation(string) (string, bool) { return "", false }
// A FailClosed plugin whose Install returns an error must abort
// InstallAll. Design hard-constraint #6.
type failClosedPlugin struct{}
func (failClosedPlugin) Name() string { return "secaudit" }
func (failClosedPlugin) Version() string { return "1.0.0" }
func (failClosedPlugin) Capabilities() platform.Capabilities {
return platform.Capabilities{
FailurePolicy: platform.FailClosed,
}
}
func (failClosedPlugin) Install(platform.Registrar) error {
return errors.New("upstream unreachable")
}
func TestInstallAll_failClosedAborts(t *testing.T) {
_, err := internalplatform.InstallAll([]platform.Plugin{failClosedPlugin{}}, nil)
if err == nil {
t.Fatalf("FailClosed install error should abort")
}
var pi *internalplatform.PluginInstallError
if !errors.As(err, &pi) {
t.Fatalf("error must be *PluginInstallError, got %T", err)
}
if pi.ReasonCode != internalplatform.ReasonInstallFailed {
t.Errorf("ReasonCode = %q, want install_failed", pi.ReasonCode)
}
}
// FailOpen install failure logs a warning and skips this plugin; other
// plugins still get installed.
type failOpenPlugin struct{}
func (failOpenPlugin) Name() string { return "audit-broken" }
func (failOpenPlugin) Version() string { return "1.0.0" }
func (failOpenPlugin) Capabilities() platform.Capabilities {
return platform.Capabilities{FailurePolicy: platform.FailOpen}
}
func (failOpenPlugin) Install(platform.Registrar) error {
return errors.New("could not connect")
}
func TestInstallAll_failOpenSkips(t *testing.T) {
var buf bytes.Buffer
plugins := []platform.Plugin{
failOpenPlugin{},
happyPlugin{name: "audit"},
}
result, err := internalplatform.InstallAll(plugins, &buf)
if err != nil {
t.Fatalf("FailOpen failure must not abort, got %v", err)
}
if !strings.Contains(buf.String(), "audit-broken") {
t.Errorf("FailOpen warning should mention plugin name, got %q", buf.String())
}
// Second plugin's observer should be present.
if len(result.Registry.MatchingObservers(fakeView{}, platform.Before)) != 1 {
t.Errorf("happy plugin's observer should still be installed after first plugin skipped")
}
}
// Restricts=true with FailOpen is a configuration error: a policy
// plugin that silently disappears under FailOpen would erase the
// security boundary. The host must reject this combo BEFORE Install
// runs.
type misconfiguredRestrictPlugin struct{}
func (misconfiguredRestrictPlugin) Name() string { return "secaudit" }
func (misconfiguredRestrictPlugin) Version() string { return "1.0.0" }
func (misconfiguredRestrictPlugin) Capabilities() platform.Capabilities {
return platform.Capabilities{
Restricts: true, // policy plugin
FailurePolicy: platform.FailOpen, // contradicts safety contract
}
}
func (misconfiguredRestrictPlugin) Install(platform.Registrar) error { return nil }
func TestInstallAll_restrictsRequiresFailClosed(t *testing.T) {
_, err := internalplatform.InstallAll([]platform.Plugin{misconfiguredRestrictPlugin{}}, nil)
if err == nil {
t.Fatalf("Restricts+FailOpen must abort")
}
var pi *internalplatform.PluginInstallError
if !errors.As(err, &pi) || pi.ReasonCode != internalplatform.ReasonRestrictsMismatch {
t.Fatalf("ReasonCode = %v, want restricts_mismatch", pi)
}
}
// Restricts=true but Install didn't call r.Restrict -> mismatch.
type lyingRestrictPlugin struct{}
func (lyingRestrictPlugin) Name() string { return "p" }
func (lyingRestrictPlugin) Version() string { return "1.0.0" }
func (lyingRestrictPlugin) Capabilities() platform.Capabilities {
return platform.Capabilities{
Restricts: true,
FailurePolicy: platform.FailClosed,
}
}
func (lyingRestrictPlugin) Install(platform.Registrar) error {
// Forgot to call r.Restrict.
return nil
}
func TestInstallAll_restrictsDeclaredButNotCalled(t *testing.T) {
_, err := internalplatform.InstallAll([]platform.Plugin{lyingRestrictPlugin{}}, nil)
if err == nil {
t.Fatalf("missing Restrict call when declared must fail")
}
var pi *internalplatform.PluginInstallError
if !errors.As(err, &pi) || pi.ReasonCode != internalplatform.ReasonRestrictsMismatch {
t.Fatalf("ReasonCode = %v, want restricts_mismatch", pi)
}
}
// Plugin that panics inside Install must NOT crash the binary -- the
// host recovers and converts the panic into a typed install_panic.
type panicInstallPlugin struct{}
func (panicInstallPlugin) Name() string { return "panicker" }
func (panicInstallPlugin) Version() string { return "1.0.0" }
func (panicInstallPlugin) Capabilities() platform.Capabilities {
return platform.Capabilities{FailurePolicy: platform.FailClosed}
}
func (panicInstallPlugin) Install(platform.Registrar) error {
panic("boom")
}
func TestInstallAll_installPanicRecovered(t *testing.T) {
_, err := internalplatform.InstallAll([]platform.Plugin{panicInstallPlugin{}}, nil)
if err == nil {
t.Fatalf("Install panic should surface as error")
}
var pi *internalplatform.PluginInstallError
if !errors.As(err, &pi) || pi.ReasonCode != internalplatform.ReasonInstallPanic {
t.Fatalf("ReasonCode = %v, want install_panic", pi)
}
}
// Two plugins with the same Name must abort before any Install runs.
func TestInstallAll_duplicatePluginName(t *testing.T) {
_, err := internalplatform.InstallAll([]platform.Plugin{
happyPlugin{name: "audit"},
happyPlugin{name: "audit"},
}, nil)
if err == nil {
t.Fatalf("duplicate Plugin.Name must abort")
}
var pi *internalplatform.PluginInstallError
if !errors.As(err, &pi) || pi.ReasonCode != internalplatform.ReasonDuplicatePluginName {
t.Fatalf("ReasonCode = %v, want duplicate_plugin_name", pi)
}
}
// Plugin with an invalid Name (contains "." or starts with a hyphen)
// must abort with invalid_plugin_name. The dot ban is critical -- the
// "{plugin}.{hook}" namespace join would become ambiguous if dots were
// allowed inside Plugin.Name().
type badNamePlugin struct{ n string }
func (p badNamePlugin) Name() string { return p.n }
func (p badNamePlugin) Version() string { return "1.0.0" }
func (p badNamePlugin) Capabilities() platform.Capabilities {
return platform.Capabilities{FailurePolicy: platform.FailClosed}
}
func (p badNamePlugin) Install(platform.Registrar) error { return nil }
func TestInstallAll_invalidPluginName(t *testing.T) {
cases := []string{"with.dot", "", "-leading-hyphen", "UPPER"}
for _, name := range cases {
t.Run(name, func(t *testing.T) {
_, err := internalplatform.InstallAll([]platform.Plugin{badNamePlugin{n: name}}, nil)
if err == nil {
t.Fatalf("invalid name %q should abort", name)
}
var pi *internalplatform.PluginInstallError
if !errors.As(err, &pi) || pi.ReasonCode != internalplatform.ReasonInvalidPluginName {
t.Fatalf("ReasonCode = %v, want invalid_plugin_name", pi)
}
})
}
}
// Plugin's Install registers two hooks with the same name -- the
// staging Registrar rejects the second one with duplicate_hook_name.
type duplicateHookPlugin struct{}
func (duplicateHookPlugin) Name() string { return "dup" }
func (duplicateHookPlugin) Version() string { return "1.0.0" }
func (duplicateHookPlugin) Capabilities() platform.Capabilities {
return platform.Capabilities{FailurePolicy: platform.FailClosed}
}
func (duplicateHookPlugin) Install(r platform.Registrar) error {
r.Observe(platform.Before, "x", platform.All(), func(context.Context, platform.Invocation) {})
r.Observe(platform.After, "x", platform.All(), func(context.Context, platform.Invocation) {})
return nil
}
func TestInstallAll_duplicateHookName(t *testing.T) {
_, err := internalplatform.InstallAll([]platform.Plugin{duplicateHookPlugin{}}, nil)
if err == nil {
t.Fatalf("duplicate hookName within same plugin must abort")
}
var pi *internalplatform.PluginInstallError
if !errors.As(err, &pi) || pi.ReasonCode != internalplatform.ReasonDuplicateHookName {
t.Fatalf("ReasonCode = %v, want duplicate_hook_name", pi)
}
}
// Restrict contributes a rule to result.PluginRules so the pruning
// resolver can pick it up. Exercise the full path.
type restrictPlugin struct{ rule *platform.Rule }
func (p restrictPlugin) Name() string { return "secaudit" }
func (p restrictPlugin) Version() string { return "1.0.0" }
func (p restrictPlugin) Capabilities() platform.Capabilities {
return platform.Capabilities{
Restricts: true,
FailurePolicy: platform.FailClosed,
}
}
func (p restrictPlugin) Install(r platform.Registrar) error {
r.Restrict(p.rule)
return nil
}
func TestInstallAll_restrictPropagatesRule(t *testing.T) {
rule := &platform.Rule{
Name: "secaudit-policy",
MaxRisk: "read",
Allow: []string{"docs/**"},
Deny: []string{"docs/+delete-doc"},
Identities: []platform.Identity{"bot"},
}
result, err := internalplatform.InstallAll([]platform.Plugin{restrictPlugin{rule: rule}}, nil)
if err != nil {
t.Fatalf("InstallAll: %v", err)
}
if len(result.PluginRules) != 1 {
t.Fatalf("expected 1 plugin rule, got %d", len(result.PluginRules))
}
stored := result.PluginRules[0].Rule
if stored == nil {
t.Fatalf("stored rule is nil")
}
// stagingRegistrar.Restrict defensively clones the plugin-supplied
// rule so a misbehaving plugin can't mutate it after Install
// returns. The clone must carry identical contents but live on a
// distinct pointer.
if stored == rule {
t.Errorf("stored rule should be a clone, got identical pointer")
}
if stored.Name != rule.Name || stored.MaxRisk != rule.MaxRisk {
t.Errorf("stored rule lost data: %+v", stored)
}
if got, want := len(stored.Allow), len(rule.Allow); got != want {
t.Errorf("stored Allow len = %d, want %d", got, want)
}
// Verify the clone is actually isolated: mutating the plugin's
// rule after install must not change the stored one.
rule.Allow[0] = "evil/**"
rule.Deny = append(rule.Deny, "extra/**")
if stored.Allow[0] == "evil/**" {
t.Errorf("Allow slice aliased plugin storage")
}
if len(stored.Deny) != 1 {
t.Errorf("Deny slice aliased plugin storage: %v", stored.Deny)
}
if result.PluginRules[0].PluginName != "secaudit" {
t.Errorf("PluginName = %q", result.PluginRules[0].PluginName)
}
}
// Atomic install: a plugin whose validation fails AFTER it registered
// some hooks must NOT leak those hooks into the live registry. The
// staging buffer is the atomicity boundary.
type partiallyRegisterThenFailPlugin struct{}
func (partiallyRegisterThenFailPlugin) Name() string { return "partial" }
func (partiallyRegisterThenFailPlugin) Version() string { return "1.0.0" }
func (partiallyRegisterThenFailPlugin) Capabilities() platform.Capabilities {
return platform.Capabilities{
Restricts: true, // declares Restrict but won't call it
FailurePolicy: platform.FailClosed,
}
}
func (partiallyRegisterThenFailPlugin) Install(r platform.Registrar) error {
r.Observe(platform.Before, "would-leak", platform.All(),
func(context.Context, platform.Invocation) {})
// validateSelf will fail because Restricts=true but Restrict
// was not called -- this is the atomic-rollback case.
return nil
}
func TestInstallAll_atomicRollback(t *testing.T) {
_, err := internalplatform.InstallAll(
[]platform.Plugin{partiallyRegisterThenFailPlugin{}, happyPlugin{name: "audit"}},
nil,
)
if err == nil {
t.Fatalf("partial plugin should abort (FailClosed)")
}
// We cannot check Registry contents here because InstallAll
// returns nil on failure; the rollback invariant is "nothing the
// failing plugin staged ever reached a live Registry", which is
// proven by the fact that we got nil back. A weaker but useful
// check: even if we passed a happy second plugin, the loop must
// have stopped at the first FailClosed failure.
var pi *internalplatform.PluginInstallError
if !errors.As(err, &pi) {
t.Fatalf("error must be *PluginInstallError, got %T", err)
}
}
// multiRestrictPlugin calls r.Restrict twice -- the multi-rule case. A
// single plugin may declare several scoped grants; both must be collected
// into PluginRules under the same plugin name, in registration order.
type multiRestrictPlugin struct{}
func (multiRestrictPlugin) Name() string { return "secaudit" }
func (multiRestrictPlugin) Version() string { return "1.0.0" }
func (multiRestrictPlugin) Capabilities() platform.Capabilities {
return platform.Capabilities{
Restricts: true,
FailurePolicy: platform.FailClosed,
}
}
func (multiRestrictPlugin) Install(r platform.Registrar) error {
r.Restrict(&platform.Rule{Name: "docs-ro", Allow: []string{"docs/**"}, MaxRisk: platform.RiskRead})
r.Restrict(&platform.Rule{Name: "im-rw", Allow: []string{"im/**"}, MaxRisk: platform.RiskWrite})
return nil
}
// A single plugin calling Restrict more than once is valid (multi-rule
// support): both rules are collected, in order, under the one plugin name.
// This pins the behaviour change from the old "Restrict at most once"
// double_restrict error.
func TestInstallAll_multipleRestrictPerPlugin(t *testing.T) {
result, err := internalplatform.InstallAll([]platform.Plugin{multiRestrictPlugin{}}, nil)
if err != nil {
t.Fatalf("multiple Restrict per plugin must succeed, got %v", err)
}
if len(result.PluginRules) != 2 {
t.Fatalf("PluginRules = %d, want 2", len(result.PluginRules))
}
for _, pr := range result.PluginRules {
if pr.PluginName != "secaudit" {
t.Errorf("PluginName = %q, want secaudit", pr.PluginName)
}
}
if result.PluginRules[0].Rule.Name != "docs-ro" || result.PluginRules[1].Rule.Name != "im-rw" {
t.Errorf("rules out of order: %q, %q",
result.PluginRules[0].Rule.Name, result.PluginRules[1].Rule.Name)
}
}