Files
mesh-catalog/modules/mesh-mail-reader/cmd/mesh-mail-reader/callers.go
T

85 lines
3.2 KiB
Go

package main
// Callers is the trusted setting `callers` (lead-m2@g14's decision at this milestone's prepare step, said to
// the operator; novox/hq ADR 0459 §2: "each answers only a caller the operator grants it"): who may call one
// of mail-reading's six verbs. An entry is a bare module name (granted wherever it runs, on any machine),
// exactly <machine>.<module>, or exactly person.<name> — the same shapes mesh-mail's own trusted setting
// `grants` matches (modules/mesh-mail/cmd/mesh-mail/config.go, Grants.Allows), copied here in miniature (one
// flat list, not one per account) so mesh-mail-reader never imports mesh-mail. Nobody beyond the list is
// granted, a wildcard in the list is no entry, and an unproven caller never matches. The setting's default is
// ["mesh-mail-web"].
import (
"encoding/json"
"errors"
"fmt"
"os"
"strings"
)
// Unproven is the caller the runtime proved nobody to be (stdio.Unproven; copied so this file reads alone).
const Unproven = "unproven"
// Callers is the setting's shape once read: a flat list of entries.
type Callers []string
// callersFile is the shape of the setting as the mesh writes it.
type callersFile struct {
Callers Callers `json:"callers"`
}
// ReadCallers reads the callers setting. A setting that cannot be read allows nobody, and says why: a caller
// refused for a reason it can read is better than one let through because the setting was unreadable.
func ReadCallers(path string) (Callers, error) {
if path == "" {
return nil, errors.New("the module was started without its callers setting (MESH_MAIL_READER_CALLERS)")
}
raw, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("the callers setting cannot be read: %w", err)
}
return ParseCallers(raw)
}
// ParseCallers reads the callers setting's content.
func ParseCallers(raw []byte) (Callers, error) {
var f callersFile
dec := json.NewDecoder(strings.NewReader(string(raw)))
dec.DisallowUnknownFields()
if err := dec.Decode(&f); err != nil {
return nil, fmt.Errorf("the callers setting is not the module's: %v", err)
}
return f.Callers, nil
}
// Allows says whether the caller may call a mail-reading verb: a bare module name (on any machine, as long as
// the caller is not person.<name>), exactly <machine>.<module>, or exactly person.<name>. Nobody is granted by
// default, an unproven caller never, and a wildcard entry is no entry (mesh-mail's own Grants.Allows mirrored).
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
}
// refuseCaller says why the caller is refused a mail-reading verb: the setting unread, or simply not named in it.
func refuseCaller(readErr error, caller string) error {
if readErr != nil {
return fmt.Errorf("refused: the setting callers cannot be read, so it allows nobody: %w", readErr)
}
return fmt.Errorf("refused: %s is not named in the setting callers; the operator grants it there", caller)
}