mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-23 20:25:56 +00:00
Reject mixed bootstrap metadata and align credential-safe fixtures
The root parser's legacy no-token alias accepted a new private-file command beside a legacy download URL. Reject every mixed alias, as the existing coherent-transport contract requires. Preserve backup-permission URL bindings. Align older secret-in-command and shared type fixtures, and exercise the actual wrong server installer parser. Contract-Neutral: Enforce the already-declared coherent bootstrap transports and correct verification fixtures; no API, scope or documented behaviour delta. Change-source: pulse-maintainer
This commit is contained in:
@@ -149,6 +149,7 @@ describe('NodesAPI — branch coverage (downloadProxmoxSetupScript failure arms)
|
||||
});
|
||||
|
||||
const pveBootstrap = (): ProxmoxSetupCommandResponse => ({
|
||||
setupToken: 'synthetic-setup-token',
|
||||
type: 'pve',
|
||||
host: 'https://pve.example:8006',
|
||||
url: 'https://pulse.example/base/api/setup-script?type=pve',
|
||||
|
||||
@@ -407,7 +407,7 @@ describe('NodesAPI', () => {
|
||||
[field]: `unsafe-${secret}`,
|
||||
});
|
||||
await expect(
|
||||
NodesAPI.getProxmoxSetupCommand({ type: 'pve', host: 'pve.example' }),
|
||||
NodesAPI.getProxmoxSetupCommand({ type: 'pve', host: 'pve.example', backupPerms: false }),
|
||||
).rejects.toThrow('Setup credentials must be entered separately from commands and URLs');
|
||||
},
|
||||
);
|
||||
|
||||
@@ -48,12 +48,24 @@ describe('tokenRevealStore', () => {
|
||||
const state = tokenRevealStore.state();
|
||||
expect(state).not.toBeNull();
|
||||
expect(state!.token).toBe('secret-token');
|
||||
expect(state!.record.id).toBe('token-1');
|
||||
expect(state!.record!.id).toBe('token-1');
|
||||
expect(state!.source).toBe('settings');
|
||||
expect(state!.note).toBe('Test note');
|
||||
expect(state!.issuedAt).toBeDefined();
|
||||
});
|
||||
|
||||
it('reveals a temporary setup token without inventing an API token record', () => {
|
||||
showTokenReveal({
|
||||
token: 'synthetic-setup-token',
|
||||
source: 'pve',
|
||||
note: 'Private input only',
|
||||
});
|
||||
expect(tokenRevealStore.state()?.token).toBe('synthetic-setup-token');
|
||||
expect(tokenRevealStore.state()?.record).toBeUndefined();
|
||||
dismissTokenReveal();
|
||||
expect(tokenRevealStore.state()).toBeNull();
|
||||
});
|
||||
|
||||
it('sets issuedAt to current timestamp', () => {
|
||||
const before = Date.now();
|
||||
showTokenReveal({
|
||||
|
||||
+1
-1
@@ -2349,7 +2349,7 @@ for _field_name, _value, _requires_token in command_fields:
|
||||
if modern:
|
||||
valid = "PULSE_SETUP_TOKEN_FILE=" in _value and "PULSE_SETUP_TOKEN=" not in _value and setup_token not in _value
|
||||
else:
|
||||
valid = ("PULSE_SETUP_TOKEN=" in _value and setup_token in _value) if _requires_token else ("PULSE_SETUP_TOKEN=" not in _value and setup_token not in _value)
|
||||
valid = "PULSE_SETUP_TOKEN_FILE=" not in _value and (("PULSE_SETUP_TOKEN=" in _value and setup_token in _value) if _requires_token else ("PULSE_SETUP_TOKEN=" not in _value and setup_token not in _value))
|
||||
if not valid:
|
||||
if _field_name == "command":
|
||||
setup_command = ""
|
||||
|
||||
@@ -542,10 +542,10 @@ func TestHandleAgentInstallCommand(t *testing.T) {
|
||||
if resp.Token == "" || resp.Command == "" {
|
||||
t.Fatalf("expected token and command in response")
|
||||
}
|
||||
if !bytes.Contains([]byte(resp.Command), []byte(resp.Token)) {
|
||||
t.Fatalf("expected command to include token")
|
||||
if bytes.Contains([]byte(resp.Command), []byte(resp.Token)) || !strings.Contains(resp.Command, `--token-file "$token_file"`) {
|
||||
t.Fatal("credential must be entered privately, not included in copied command")
|
||||
}
|
||||
if !bytes.Contains([]byte(resp.Command), []byte("--proxmox-type "+posixShellQuote("pve"))) {
|
||||
if resp.Command != BuildProxmoxAgentInstallCommand(AgentInstallCommandOptions{BaseURL: "http://example.com:8080", Token: resp.Token, InstallType: "pve", IncludeInstallType: true, EnableCommands: true}) {
|
||||
t.Fatalf("expected command to include proxmox type")
|
||||
}
|
||||
if len(cfg.APITokens) != 1 {
|
||||
@@ -633,7 +633,7 @@ func TestHandleAgentInstallCommand_NormalizesType(t *testing.T) {
|
||||
if err := json.Unmarshal(rec.Body.Bytes(), &resp); err != nil {
|
||||
t.Fatalf("failed to decode response: %v", err)
|
||||
}
|
||||
if !bytes.Contains([]byte(resp.Command), []byte("--proxmox-type "+posixShellQuote("pbs"))) {
|
||||
if resp.Command != BuildProxmoxAgentInstallCommand(AgentInstallCommandOptions{BaseURL: "http://example.com:8080", Token: resp.Token, InstallType: "pbs", IncludeInstallType: true}) {
|
||||
t.Fatalf("expected normalized proxmox type in command, got: %s", resp.Command)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -435,7 +435,7 @@ func TestPVESetupScript_UsesFailFastRetryGuidance(t *testing.T) {
|
||||
}
|
||||
|
||||
script := rr.Body.String()
|
||||
if !containsString(script, `PULSE_BOOTSTRAP_COMMAND_WITH_ENV='curl -fsSL '"'"'http://sentinel-url:7656/api/setup-script?host=http%3A%2F%2Fsentinel-host%3A8006&pulse_url=http%3A%2F%2Fsentinel-url%3A7656&type=pve'"'"' | `) {
|
||||
if !containsString(script, `PULSE_BOOTSTRAP_COMMAND_WITH_ENV=`+posixShellQuote(BuildSetupScriptCommand("http://sentinel-url:7656/api/setup-script?host=http%3A%2F%2Fsentinel-host%3A8006&pulse_url=http%3A%2F%2Fsentinel-url%3A7656&type=pve", ""))) {
|
||||
t.Fatalf("expected canonical bootstrap command owner in setup script, got: %s", truncate(script, 700))
|
||||
}
|
||||
if !containsString(script, `echo " $PULSE_BOOTSTRAP_COMMAND_WITH_ENV"`) {
|
||||
@@ -952,7 +952,8 @@ func TestPVESetupScriptSmokeTestsCreatedTokenBeforeAutoRegistration(t *testing.T
|
||||
for _, needle := range []string{
|
||||
`smoke_test_pve_token() {`,
|
||||
`curl -kfsS --retry 2 --retry-delay 1`,
|
||||
`Authorization: PVEAPIToken=$PULSE_TOKEN_ID=$TOKEN_VALUE`,
|
||||
`printf 'Authorization: PVEAPIToken=%s=%s\n' "$PULSE_TOKEN_ID" "$TOKEN_VALUE" | curl`,
|
||||
`-H @-`,
|
||||
`${HOST_URL%/}/api2/json/nodes`,
|
||||
`TOKEN_READY=false`,
|
||||
`if smoke_test_pve_token; then`,
|
||||
|
||||
@@ -51,8 +51,12 @@ func TestHostedRuntimeMintsAgentInstallTokensWithoutLocalAuth(t *testing.T) {
|
||||
if len(cfg.APITokens) != 1 {
|
||||
t.Fatalf("persisted API tokens = %d, want 1", len(cfg.APITokens))
|
||||
}
|
||||
if resp.Command != "" && !strings.Contains(resp.Command, resp.Token) {
|
||||
t.Fatalf("install command does not carry the minted token: %s", resp.Command)
|
||||
if tc.name == "proxmox agent" {
|
||||
if strings.Contains(resp.Command, resp.Token) || !strings.Contains(resp.Command, `--token-file "$token_file"`) {
|
||||
t.Fatal("hosted Proxmox credential must use separate private input")
|
||||
}
|
||||
} else if resp.Command != "" && !strings.Contains(resp.Command, resp.Token) {
|
||||
t.Fatal("generic host command lost its existing credential transport")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -372,3 +372,25 @@ func TestPrivateBootstrapInteractiveHistoryContainsCommandButNotToken(t *testing
|
||||
t.Fatal("silent input entered shell history or terminal output")
|
||||
}
|
||||
}
|
||||
|
||||
// The public server installer is not the telemetry installer. If it is served
|
||||
// accidentally at the agent path, its real parser rejects --url before token
|
||||
// input or privileged installation; a complete but wrong fetch is not success.
|
||||
func TestPrivateAgentBootstrapRejectsActualServerInstaller(t *testing.T) {
|
||||
source, err := os.ReadFile(filepath.Join("..", "..", "..", "install.sh"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, env := bootstrapFixture(t, string(source))
|
||||
command := BuildProxmoxAgentInstallCommand(AgentInstallCommandOptions{BaseURL: "https://pulse.example", Token: "synthetic-token", InstallType: "pve", IncludeInstallType: true})
|
||||
out, err := runBootstrap(t, command, "", env, false)
|
||||
if err == nil || !strings.Contains(string(out), "Unknown option: --url") {
|
||||
t.Fatal("wrong installer was not rejected by its real parser")
|
||||
}
|
||||
dirs, _ := os.ReadFile(filepath.Join(root, "private-directories"))
|
||||
for _, path := range strings.Fields(string(dirs)) {
|
||||
if _, err := os.Stat(path); !os.IsNotExist(err) {
|
||||
t.Fatal("wrong-installer failure left a private directory")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -598,7 +598,7 @@ func TestRootInstallScriptAutoRegisterUsesSecureContractShape(t *testing.T) {
|
||||
`'if [ "$(id -u)" -eq 0 ]; then' not in _value`,
|
||||
`'elif command -v sudo >/dev/null 2>&1; then' not in _value`,
|
||||
`valid = "PULSE_SETUP_TOKEN_FILE=" in _value and "PULSE_SETUP_TOKEN=" not in _value and setup_token not in _value`,
|
||||
`valid = ("PULSE_SETUP_TOKEN=" in _value and setup_token in _value) if _requires_token else ("PULSE_SETUP_TOKEN=" not in _value and setup_token not in _value)`,
|
||||
`valid = "PULSE_SETUP_TOKEN_FILE=" not in _value and (("PULSE_SETUP_TOKEN=" in _value and setup_token in _value) if _requires_token else ("PULSE_SETUP_TOKEN=" not in _value and setup_token not in _value))`,
|
||||
`not token_hint or token_hint == setup_token`,
|
||||
`[[ "$setup_type" != "pve" ]]`,
|
||||
`[[ "$setup_host" != "$normalized_host_url" ]]`,
|
||||
|
||||
Reference in New Issue
Block a user