82 lines
2.8 KiB
Go
82 lines
2.8 KiB
Go
// Package permissions provides a registry for plugin permissions.
|
|
package permissions
|
|
|
|
import (
|
|
"sort"
|
|
"sync"
|
|
)
|
|
|
|
// Entry describes a known permission.
|
|
type Entry struct {
|
|
Name string `json:"name"`
|
|
Description string `json:"description"`
|
|
Dangerous bool `json:"dangerous"`
|
|
}
|
|
|
|
// Registry tracks known permissions and their safety levels.
|
|
type Registry struct {
|
|
mu sync.RWMutex
|
|
permissions map[string]Entry
|
|
}
|
|
|
|
// NewRegistry creates a new permissions registry.
|
|
func NewRegistry() *Registry {
|
|
r := &Registry{
|
|
permissions: make(map[string]Entry),
|
|
}
|
|
r.registerDefaults()
|
|
return r
|
|
}
|
|
|
|
func (r *Registry) registerDefaults() {
|
|
defaults := []Entry{
|
|
{Name: "vault.read", Description: "Read vault files and metadata", Dangerous: false},
|
|
{Name: "vault.write", Description: "Write vault files and metadata", Dangerous: true},
|
|
{Name: "vault.watch", Description: "Watch vault file changes", Dangerous: false},
|
|
{Name: "storage.namespace", Description: "Read/write plugin's own storage namespace", Dangerous: false},
|
|
{Name: "storage.migrations", Description: "Run database migrations in plugin namespace", Dangerous: false},
|
|
{Name: "events.publish", Description: "Publish events to the event bus", Dangerous: false},
|
|
{Name: "events.subscribe", Description: "Subscribe to events on the event bus", Dangerous: false},
|
|
{Name: "ui.register", Description: "Register UI components and contributions", Dangerous: false},
|
|
{Name: "commands.register", Description: "Register command palette commands", Dangerous: false},
|
|
{Name: "network.local", Description: "Connect to localhost network services", Dangerous: false},
|
|
{Name: "network.remote", Description: "Connect to remote network services", Dangerous: true},
|
|
{Name: "process.spawn", Description: "Spawn external processes", Dangerous: true},
|
|
{Name: "secrets.read", Description: "Read secrets from the secret store", Dangerous: true},
|
|
{Name: "secrets.write", Description: "Write secrets to the secret store", Dangerous: true},
|
|
{Name: "sync.participate", Description: "Participate in vault sync", Dangerous: true},
|
|
}
|
|
for _, e := range defaults {
|
|
r.permissions[e.Name] = e
|
|
}
|
|
}
|
|
|
|
// Get returns permission info by name.
|
|
func (r *Registry) Get(name string) (Entry, bool) {
|
|
r.mu.RLock()
|
|
defer r.mu.RUnlock()
|
|
e, ok := r.permissions[name]
|
|
return e, ok
|
|
}
|
|
|
|
// IsDangerous checks if a permission is marked dangerous.
|
|
func (r *Registry) IsDangerous(name string) bool {
|
|
e, ok := r.Get(name)
|
|
return ok && e.Dangerous
|
|
}
|
|
|
|
// List returns all known permissions, sorted by name.
|
|
func (r *Registry) List() []Entry {
|
|
r.mu.RLock()
|
|
defer r.mu.RUnlock()
|
|
|
|
entries := make([]Entry, 0, len(r.permissions))
|
|
for _, e := range r.permissions {
|
|
entries = append(entries, e)
|
|
}
|
|
sort.Slice(entries, func(i, j int) bool {
|
|
return entries[i].Name < entries[j].Name
|
|
})
|
|
return entries
|
|
}
|