Files
sanspie a6822156cd
ci-platforms / windows amd64 smoke (push) Skipped
ci / release (push) Successful in 8m58s
ci-platforms / darwin amd64 smoke (push) Skipped
ci-platforms / darwin arm64 smoke (push) Skipped
ci / checks (push) Successful in 4m46s
ci / build (amd64, linux, ubuntu-24.04) (push) Successful in 13m28s
Finish Stage 12 editor fixes and refreshed platformer
2026-11-05 17:36:42 +03:00

97 lines
2.1 KiB
Go

package agentui
import (
"crypto/sha256"
"encoding/json"
"errors"
"fmt"
"os"
"path/filepath"
)
// PlaytestTrust is a user-local permission for one project and playtest kind.
type PlaytestTrust struct {
dir, project, kind string
}
func NewPlaytestTrust(dir, project string, native bool) *PlaytestTrust {
if dir == "" || project == "" {
return nil
}
root, err := filepath.Abs(project)
if err != nil {
return nil
}
root, err = filepath.EvalSymlinks(root)
if err != nil {
return nil
}
kind := "scripts"
if native {
kind = "native"
}
return &PlaytestTrust{dir: filepath.Join(dir, "agent-playtests"), project: filepath.Clean(root), kind: kind}
}
func (t *PlaytestTrust) path() string {
sum := sha256.Sum256([]byte(t.project + "\x00" + t.kind))
return filepath.Join(t.dir, fmt.Sprintf("%x.json", sum))
}
type playtestPermission struct {
Version int `json:"version"`
Project string `json:"project"`
Kind string `json:"kind"`
}
func (t *PlaytestTrust) Allowed() bool {
if t == nil {
return false
}
info, err := os.Lstat(t.path())
if err != nil || !info.Mode().IsRegular() || info.Size() > 16<<10 {
return false
}
data, err := os.ReadFile(t.path())
var p playtestPermission
return err == nil && json.Unmarshal(data, &p) == nil && p.Version == 1 && p.Project == t.project && p.Kind == t.kind
}
func (t *PlaytestTrust) Allow() error {
if t == nil {
return errors.New("cannot save the playtest permission without a user configuration directory")
}
if err := os.MkdirAll(t.dir, 0o700); err != nil {
return err
}
data, err := json.Marshal(playtestPermission{Version: 1, Project: t.project, Kind: t.kind})
if err != nil {
return err
}
f, err := os.CreateTemp(t.dir, ".permission-*")
if err != nil {
return err
}
name := f.Name()
defer os.Remove(name)
if _, err = f.Write(data); err != nil {
f.Close()
return err
}
if err = f.Close(); err != nil {
return err
}
return os.Rename(name, t.path())
}
func (t *PlaytestTrust) Revoke() error {
if t == nil {
return nil
}
err := os.Remove(t.path())
if errors.Is(err, os.ErrNotExist) {
return nil
}
return err
}