49 lines
1.5 KiB
Go
49 lines
1.5 KiB
Go
package stdio
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
// Callers is a module's trusted list of who may call a verb of its (novox/hq ADR 0459 §2, ADR 0563 §8), as the mesh
|
|
// writes a list setting into a file the module reads: `{"callers": [...]}`. An entry is a module's name (that module on
|
|
// any machine), exactly <machine>.<module>, or exactly person.<name>. Each caller is the runtime's proof (CallerOf), never
|
|
// an argument; nobody beyond the list is granted, a wildcard is no entry, and an unproven caller never matches.
|
|
type Callers []string
|
|
|
|
// ParseCallers reads a callers file: the list under `callers`, and nothing else.
|
|
func ParseCallers(raw []byte) (Callers, error) {
|
|
var f struct {
|
|
Callers Callers `json:"callers"`
|
|
}
|
|
dec := json.NewDecoder(bytes.NewReader(raw))
|
|
dec.DisallowUnknownFields()
|
|
if err := dec.Decode(&f); err != nil {
|
|
return nil, fmt.Errorf("the callers setting is not a list of callers: %v", err)
|
|
}
|
|
return f.Callers, nil
|
|
}
|
|
|
|
// Allows says whether caller, as the runtime proved it, is one the list names.
|
|
func (c Callers) Allows(caller string) bool {
|
|
if caller == "" || caller == Unproven {
|
|
return false
|
|
}
|
|
for _, entry := range c {
|
|
if entry == "" || strings.ContainsAny(entry, "*> ") {
|
|
continue
|
|
}
|
|
if entry == caller {
|
|
return true
|
|
}
|
|
if !strings.Contains(entry, ".") {
|
|
if _, module, ok := strings.Cut(caller, "."); ok && module == entry && !strings.HasPrefix(caller, "person.") {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
return false
|
|
}
|