mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-27 05:57:27 +00:00
39f988b220
AI Discovery ran a separate model-backed service scanner beside Patrol and the Assistant: its own store, scheduler, model route, API, tool and drawer UI. No telemetry counter ever measured its use (the telemetry discovery_enabled flag OR'd it with network subnet discovery), the maintainer judged it a flop, and the context it produced is already available to the models through pulse_query, pulse_read and the unified-resource context sections. This deletes internal/servicediscovery, internal/ai/infradiscovery, the pulse_discovery tool, the /api/discovery routes, the mock Discovery fixtures, the Discovery tabs in the resource, guest, node and Docker host drawers, the identified-service cards, readiness badges, provenance markers, suggested web-interface URLs, the Workloads AI Context column, the chat "Discovery is off" hint and the AI Service Context settings page. The old settings route redirects to Assistant settings. The model-bound sanitizer allow-list existed only to pass Discovery context through, so it goes too, along with the CopyableCodeRow primitive that only the Discovery tab used. Network subnet discovery (/api/discover, the Infrastructure discovery settings) and the discoveryTarget agent coordinates are separate features and stay. Stored discovery_enabled, discovery_interval_hours and discovery_model AI settings are ignored on load; the settings API decoder is lenient, so older frontends saving those fields still succeed.
58 lines
1.9 KiB
Go
58 lines
1.9 KiB
Go
package api
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/rcourtman/pulse-go-rewrite/internal/config"
|
|
internalauth "github.com/rcourtman/pulse-go-rewrite/pkg/auth"
|
|
)
|
|
|
|
func TestQuickSecuritySetupForcePreservesSystemSettings(t *testing.T) {
|
|
t.Setenv("PULSE_TRUSTED_PROXY_CIDRS", "")
|
|
t.Setenv("PULSE_DOCKER", "true")
|
|
resetTrustedProxyConfig()
|
|
dir := t.TempDir()
|
|
InitPersistentAuthStores(dir)
|
|
hash, err := internalauth.HashPassword("ExistingPassword!1")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
token := strings.Repeat("ab", 32)
|
|
record, err := config.NewAPITokenRecord(token, "synthetic", []string{config.ScopeWildcard})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
cfg := &config.Config{AuthUser: "admin", AuthPass: hash, DataPath: dir, ConfigPath: dir, APITokens: []config.APITokenRecord{*record}}
|
|
cfg.SortAPITokens()
|
|
persistence := config.NewConfigPersistence(dir)
|
|
before := config.DefaultSystemSettings()
|
|
before.FullWidthMode = true
|
|
before.ConnectionTimeout = 23
|
|
if err := persistence.SaveSystemSettings(*before); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
router := &Router{config: cfg, persistence: persistence}
|
|
authLimiter.Reset("203.0.113.10")
|
|
req := httptest.NewRequest(http.MethodPost, "/api/security/quick-setup", strings.NewReader(`{"username":"rotated","password":"RotatedPassword!1","apiToken":"`+token+`","force":true}`))
|
|
req.RemoteAddr = "203.0.113.10:1234"
|
|
req.Header.Set("X-API-Token", token)
|
|
response := httptest.NewRecorder()
|
|
handleQuickSecuritySetupFixed(router)(response, req)
|
|
if response.Code != http.StatusOK {
|
|
t.Fatalf("setup returned %d", response.Code)
|
|
}
|
|
after, err := persistence.LoadSystemSettings()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if after == nil {
|
|
t.Fatal("settings missing")
|
|
}
|
|
if !after.FullWidthMode || after.ConnectionTimeout != 23 {
|
|
t.Fatalf("non-auth settings overwritten: fullWidthMode=%v connectionTimeout=%v", after.FullWidthMode, after.ConnectionTimeout)
|
|
}
|
|
}
|