Merge pull request 'Let in-proc plugins register the EXT-8 resource authorizer (fix rdm.* unknown-command)' (#124) from feature/ext8-inproc-authorizer into main
ci / vet-and-test (push) Successful in 41s
ci / vet-and-test (push) Successful in 41s
This commit was merged in pull request #124.
This commit is contained in:
@@ -86,6 +86,19 @@ func (r compiledRegistry) RegisterResourceAuthorizer(extension.ResourceAuthorize
|
||||
return errors.New("extension: declarative plugins cannot register resource authorizers")
|
||||
}
|
||||
|
||||
// RegisterResourceAuthorizer 进程内扩展(EXT-1):填充 EXT-8 适配器槽
|
||||
// (hostcaps.authz 共享指针;首个注册者生效,组合根已装配进 Server/runmgr)。
|
||||
// 此前 pluginRegistry 未覆盖该方法——进程内插件注册适配器会命中声明式分支的
|
||||
// 拒绝,register() 整体中止,插件命令全部未注册(RDM 二进制 rdm.* 全部
|
||||
// 「unknown command」;MS1 重验收烟测实测发现)。
|
||||
func (r pluginRegistry) RegisterResourceAuthorizer(fn extension.ResourceAuthorizer) error {
|
||||
if fn == nil {
|
||||
return errors.New("extension: " + r.pluginID + ": nil resource authorizer")
|
||||
}
|
||||
r.caps.authz.set(r.pluginID, fn)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r compiledRegistry) Note(kind, name string, payload json.RawMessage) error {
|
||||
log.Printf("extension: note %s %s (%d bytes)", kind, name, len(payload))
|
||||
return nil
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
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 应被拒绝")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user