ci / vet-and-test (pull_request) Successful in 42s
Why: pluginRegistry never overrode RegisterResourceAuthorizer, so
in-proc extensions hit the declarative-branch rejection; register()
aborted wholesale and every plugin command vanished from the bus. The
RDM binary ships the EXT-8 member adapter since step-4, meaning the
served RDM process answers 'unknown or disabled command' for every
rdm.* call — caught by the MS1 re-acceptance smoke replay (fb/report/
confirm/lifecycle smokes all failed on rdm.baseline).
Evidence: TestInprocPluginRegistersAuthorizerAndCommands — red on the
parent commit (registration aborts, dispatch rejected, nil-slot denies),
green with the fix (command committed; the shared authz slot answers
alice-allow/bob-deny through projectAuthz). Full go test ./... green;
RDM MS0 acceptance re-run follows on the pin bump.
Impact: pluginRegistry.RegisterResourceAuthorizer fills the shared
hostcaps.authz slot (first registrant wins, mirroring the composition
root); compiled/declarative branch unchanged.
Refs: RDM G1-8 MS1 re-acceptance; EXT-8 (d89e748 seam); RDM #113.
56 lines
1.9 KiB
Go
56 lines
1.9 KiB
Go
package app
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"agent-system-backend/internal/cmdbus"
|
|
"agent-system-backend/internal/store"
|
|
"agent-system-backend/pkg/extension"
|
|
core "agent-system-core"
|
|
)
|
|
|
|
// fakeExtAuthz 进程内扩展:注册 EXT-8 适配器+一条命令——修复前适配器注册被
|
|
// 声明式分支拒绝,register() 中止导致命令全部丢失。
|
|
type fakeExtAuthz struct{}
|
|
|
|
func (f *fakeExtAuthz) Register(reg extension.Registry) error {
|
|
if err := reg.RegisterResourceAuthorizer(func(owner string, projectID core.ID) (bool, error) {
|
|
return owner == "alice", nil
|
|
}); err != nil {
|
|
return err
|
|
}
|
|
return reg.AddCommandHandler([]byte(`{"id":"t.authz.ping","title":"t"}`),
|
|
func(ctx context.Context, h extension.Host, req extension.Request) (any, error) {
|
|
return map[string]any{"ok": true}, nil
|
|
})
|
|
}
|
|
|
|
func TestInprocPluginRegistersAuthorizerAndCommands(t *testing.T) {
|
|
extension.ResetCompiled()
|
|
extension.RegisterCompiled(extension.InProc{ID: "t", Register: (&fakeExtAuthz{}).Register})
|
|
defer extension.ResetCompiled()
|
|
st, err := store.OpenSQLite(t.TempDir() + "/t.db")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer st.Close()
|
|
bus := cmdbus.New(st, nil, func() time.Time { return time.Unix(1700000000, 0).UTC() })
|
|
caps := hostcaps{st: st, authz: &projectAuthz{}}
|
|
applyCompiled("", bus, caps)
|
|
// ① 命令已注册且可分发(修复前:适配器注册被拒 → register() 中止 →
|
|
// 命令全部丢失,rdm.* 全部 unknown command)。
|
|
if resp := bus.Dispatch(context.Background(), cmdbus.Request{
|
|
ID: "t.authz.ping", Entrance: "button", Owner: "alice"}); resp.Receipt.State != "committed" {
|
|
t.Fatalf("命令分发 = %+v(注册整体中止)", resp.Receipt)
|
|
}
|
|
// ② 适配器经共享槽生效:alice 放行、bob 拒绝。
|
|
if ok, _ := caps.authz.Authorize("alice", "p1"); !ok {
|
|
t.Fatal("alice 应放行")
|
|
}
|
|
if ok, _ := caps.authz.Authorize("bob", "p1"); ok {
|
|
t.Fatal("bob 应被拒绝")
|
|
}
|
|
}
|