Pulse/internal/config/api_tokens_test.go
rcourtman 5c54685f04 Add API token scopes and standalone host agent
Introduces granular permission scopes for API tokens (docker:report, docker:manage, host-agent:report, monitoring:read/write, settings:read/write) allowing tokens to be restricted to minimum required access. Legacy tokens default to full access until scopes are explicitly configured.

Adds standalone host agent for monitoring Linux, macOS, and Windows servers outside Proxmox/Docker estates. New Servers workspace in UI displays uptime, OS metadata, and capacity metrics from enrolled agents.

Includes comprehensive token management UI overhaul with scope presets, inline editing, and visual scope indicators.
2025-10-23 11:40:31 +00:00

58 lines
1.6 KiB
Go

package config
import (
"os"
"path/filepath"
"testing"
)
func TestAPITokenRecordHasScope(t *testing.T) {
record := APITokenRecord{Scopes: []string{ScopeMonitoringRead}}
if !record.HasScope(ScopeMonitoringRead) {
t.Fatalf("expected scope %q to be granted", ScopeMonitoringRead)
}
if record.HasScope(ScopeSettingsWrite) {
t.Fatalf("did not expect scope %q to be granted", ScopeSettingsWrite)
}
record.Scopes = nil // legacy tokens with no scopes should default to wildcard
if !record.HasScope(ScopeSettingsWrite) {
t.Fatalf("expected wildcard to grant %q", ScopeSettingsWrite)
}
if !IsKnownScope(ScopeMonitoringRead) {
t.Fatalf("expected %q to be known scope", ScopeMonitoringRead)
}
if IsKnownScope("unknown:scope") {
t.Fatalf("unexpected scope recognised")
}
}
func TestLoadAPITokensAppliesLegacyScopes(t *testing.T) {
if len(AllKnownScopes) == 0 {
t.Fatal("expected known scopes to be defined")
}
dir := t.TempDir()
persistence := NewConfigPersistence(dir)
if err := persistence.EnsureConfigDir(); err != nil {
t.Fatalf("EnsureConfigDir: %v", err)
}
payload := `[{"id":"legacy","name":"legacy","hash":"abc","createdAt":"2024-01-01T00:00:00Z"}]`
if err := os.WriteFile(filepath.Join(dir, "api_tokens.json"), []byte(payload), 0600); err != nil {
t.Fatalf("write api_tokens.json: %v", err)
}
tokens, err := persistence.LoadAPITokens()
if err != nil {
t.Fatalf("LoadAPITokens: %v", err)
}
if len(tokens) != 1 {
t.Fatalf("expected 1 token, got %d", len(tokens))
}
if len(tokens[0].Scopes) != 1 || tokens[0].Scopes[0] != ScopeWildcard {
t.Fatalf("expected legacy token to default to wildcard scope, got %#v", tokens[0].Scopes)
}
}