More work on tentacles.
This commit is contained in:
1 parent
573d15d7b4
commit
4cf3335017
29 files changed
+1194
-66
No files matched your search
@@ -0,0 +1,92 @@
|
||||
// Copyright (c) 2026 Storm Dragon
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package tentacle
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"git.stormux.org/storm/cthulhu/internal/tentaclewire"
|
||||
)
|
||||
|
||||
func TestRemotePolicyRevokesPendingAndLiveSDKAccess(t *testing.T) {
|
||||
for _, language := range []string{"go", "python"} {
|
||||
t.Run(language, func(t *testing.T) {
|
||||
manager := test_manager(t, DefaultLimits(), nil)
|
||||
policy := NewRemotePolicy()
|
||||
if err := manager.UseRemotePolicy(policy); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
session := startSessionSDK(t, manager, language, "policy-probe")
|
||||
if _, err := session.AuthorizeRemote("controlled", []string{"output-observe"}); !errors.Is(err, ErrPermission) {
|
||||
t.Fatal("fixture authorizer bypassed policy", err)
|
||||
}
|
||||
stale, _ := session.BeginRemoteApproval("controlled", []string{"output-observe"})
|
||||
policy.SetAvailable(false)
|
||||
if _, err := session.BeginRemoteApproval("controlled", []string{"output-observe"}); !errors.Is(err, ErrPermission) {
|
||||
t.Fatal("unavailable policy issued ticket", err)
|
||||
}
|
||||
policy.SetAvailable(true)
|
||||
if _, err := session.AuthorizeRemoteWithApproval(stale, "controlled", []string{"output-observe"}); !errors.Is(err, ErrPermission) {
|
||||
t.Fatal("lock round trip revived ticket", err)
|
||||
}
|
||||
foreign := &RemoteApproval{policy: NewRemotePolicy()}
|
||||
if _, err := session.AuthorizeRemoteWithApproval(foreign, "controlled", []string{"output-observe"}); !errors.Is(err, ErrPermission) {
|
||||
t.Fatal("foreign ticket accepted", err)
|
||||
}
|
||||
for _, opened := range []bool{false, true} {
|
||||
approval, _ := session.BeginRemoteApproval("controlled", []string{"output-observe"})
|
||||
action, err := session.AuthorizeRemoteWithApproval(approval, "controlled", []string{"output-observe"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := session.AuthorizeRemoteWithApproval(approval, "controlled", []string{"output-observe"}); !errors.Is(err, ErrPermission) {
|
||||
t.Fatal("replayed approval", err)
|
||||
}
|
||||
invokeSessionSDK(t, session, "event", nil)
|
||||
var lease tentaclewire.RemoteLease
|
||||
request := tentaclewire.RemoteOpen{Action: action.Action, Epoch: action.Epoch, Role: action.Role, Grants: action.Grants}
|
||||
if opened {
|
||||
value, code := remoteCall(t, session, "remote.open", request)
|
||||
if code != 0 || json.Unmarshal(value, &lease) != nil {
|
||||
t.Fatal("open failed", code)
|
||||
}
|
||||
}
|
||||
// Hold the session lock so asynchronous event cleanup cannot run.
|
||||
// Policy cancellation must already invalidate every delivery context.
|
||||
session.mutex.Lock()
|
||||
access := session.remote
|
||||
policy.SetAvailable(false)
|
||||
cancelled := access.ctx.Err() != nil
|
||||
session.mutex.Unlock()
|
||||
if !cancelled {
|
||||
t.Fatal("revocation waited for session worker")
|
||||
}
|
||||
policy.SetAvailable(true)
|
||||
if _, code := remoteCall(t, session, "remote.open", request); code != -32001 {
|
||||
t.Fatal("stale open revived approval", code)
|
||||
}
|
||||
if opened {
|
||||
if _, err := session.RemoteContext(lease, "output-observe"); !errors.Is(err, ErrPermission) {
|
||||
t.Fatal("delivery survived policy", err)
|
||||
}
|
||||
if _, code := remoteCall(t, session, "remote.heartbeat", tentaclewire.RemoteOperation{Lease: lease.Lease, Epoch: lease.Epoch, Sequence: 1}); code != -32001 {
|
||||
t.Fatal("heartbeat revived lease", code)
|
||||
}
|
||||
var event tentaclewire.SessionEvent
|
||||
if json.Unmarshal(invokeSessionSDK(t, session, "event", nil), &event) != nil || event.Kind != "remote.revoked" || event.Lease != lease.Lease {
|
||||
t.Fatal("revocation event", event)
|
||||
}
|
||||
}
|
||||
}
|
||||
// A fresh approval can replace the cancelled epoch even if its
|
||||
// asynchronous policy callback has not acquired the session lock yet.
|
||||
fresh, _ := session.BeginRemoteApproval("controlled", []string{"output-observe"})
|
||||
if _, err := session.AuthorizeRemoteWithApproval(fresh, "controlled", []string{"output-observe"}); err != nil {
|
||||
t.Fatal("fresh approval failed", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user