give: take only a value a person holds, ask the desk by name, let the controller alone ask it, and announce every value given
The review of 2026-10-09 (M4): - give refuses broker (the bus account issue mints) and any own secret the mesh may make itself; - the desk's prompt is asked by module, secret and machine, never with words of the caller's, and the bus denies the prompt's subjects to every principal but the controller, however wide its grant, so the prompt's 'the controller asks' is the bus's word (Permissions.PublishDeny, broker.ControllerOnly); - secret accept with a value is refused through a verb: a value comes from the terminal or the desk; - every value given for an own secret, at the terminal or the desk, raises the urgent condition secret-given on every channel, until the operator silences it.
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
package inventory
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/novox/mesh-controller/internal/catalogue"
|
||||
)
|
||||
|
||||
// `give` takes only a value nobody but a person has (the review of 2026-10-09, M4): never the module's bus
|
||||
// account, which `issue` mints, nor a secret the mesh may make itself.
|
||||
func TestOnlyASecretThePersonHoldsIsGivenAtTheDesk(t *testing.T) {
|
||||
m := catalogue.Manifest{Module: "telegram", OwnSecrets: catalogue.OwnSecrets{
|
||||
"telegram-token": {Path: "/s/telegram-token"},
|
||||
"broker": {Path: "/s/broker"},
|
||||
"session": {Path: "/s/session", Taken: catalogue.TakenAtStart},
|
||||
}}
|
||||
if err := GivableAtDesk(m, "telegram-token"); err != nil {
|
||||
t.Errorf("the bot token was refused: %v", err)
|
||||
}
|
||||
for _, name := range []string{"broker", "session", "chat-id"} {
|
||||
if err := GivableAtDesk(m, name); err == nil {
|
||||
t.Errorf("%s was givable", name)
|
||||
} else if name != "chat-id" && !strings.Contains(err.Error(), "the mesh makes") {
|
||||
t.Errorf("%s: %v", name, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -561,8 +561,28 @@ func (i *Inventory) DeclaresOwnSecret(ctx context.Context, module, name string)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, ok := m.OwnSecrets[name]; !ok {
|
||||
return fmt.Errorf("%s does not declare %q as an own secret; %s", module, name, declaresOwn(m))
|
||||
return GivableAtDesk(m, name)
|
||||
}
|
||||
|
||||
// BrokerSecret is the own secret that is a module's bus account, which `issue` mints.
|
||||
const BrokerSecret = "broker"
|
||||
|
||||
// GivableAtDesk refuses, in words, an own secret a module does not declare, and one the mesh makes itself
|
||||
// (the review of 2026-10-09, M4): the module's bus account, which `issue` mints, and any the mesh may make
|
||||
// in place of a value given (catalogue.OwnSecret.MeshMayMake). The desk takes only what a person holds and
|
||||
// the mesh cannot make — a bot's token — so nobody is asked to type the mesh's own credential into a prompt.
|
||||
func GivableAtDesk(m catalogue.Manifest, name string) error {
|
||||
own, ok := m.OwnSecrets[name]
|
||||
if !ok {
|
||||
return fmt.Errorf("%s does not declare %q as an own secret; %s", m.Module, name, declaresOwn(m))
|
||||
}
|
||||
switch {
|
||||
case name == BrokerSecret:
|
||||
return fmt.Errorf("%q is %s's account on the bus, which the mesh makes (`issue`), never a value a person gives",
|
||||
name, m.Module)
|
||||
case own.MeshMayMake():
|
||||
return fmt.Errorf("%q of %s is a secret the mesh makes itself (it may replace a value given at the module's "+
|
||||
"start, ADR 0228); a person gives it only at the controller's terminal, with `secret accept`", name, m.Module)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user