6d90374f63
gates / gates (push) Successful in 45s
internal/privpolicy checks the RENDERED compose (privileged, cap_add, devices, host namespaces, security_opt,
sysctls, volumes_from, build/include/extends, env_file/config files outside the stack dir, aliasing named volumes,
binds outside the box's data roots, the Docker socket, propagation, ${VAR} in a privileged key) against an
allow-list compiled into the controller (one entry: homepage's read-only socket). Asked before every compose
write: the 15-minute sync, the guarded update/ladder step, the install, both settings changes, both restores
(before the stop). A refusal writes nothing, keeps the app on its last good compose, raises the operator-only
event app_definition_refused once per definition and puts one line on the app page. The sync never copies a
template named like a controller infra stack. Structural guard TestAllowList_IsWiredIntoEveryComposeWriter.
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
36 lines
1.5 KiB
Go
36 lines
1.5 KiB
Go
package web
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"gitea.dooplex.hu/admin/felhom-controller/internal/stacks"
|
|
)
|
|
|
|
// R-971 (v0.328.0) — the box refused the catalog's newer definition of an installed app: the app page says so in the
|
|
// reader's language, and says nothing when there is no refusal. A render test PER BRANCH of the gate (seam-wiring).
|
|
// COMPANION RED-PROOF (controller REPORT.md): drop the `{{if .Stack.DefinitionRefused}}` block — the refused branch
|
|
// fails in both languages.
|
|
func TestR971_AppPage_SaysTheDefinitionWasRefused(t *testing.T) {
|
|
for _, refused := range []bool{true, false} {
|
|
st := ubStack(nil, map[string]string{"homepage": "ghcr.io/gethomepage/homepage:v1.13.2"}, "2026-07-18")
|
|
st.State = stacks.StateRunning
|
|
if refused {
|
|
st.DefinitionRefused = "the catalog definition of homepage asks for container rights the box does not allow: homepage: privileged true"
|
|
}
|
|
for lang, want := range map[string]string{"hu": "nem fogadta el", "en": "did not accept"} {
|
|
h := renderBackupPageLang(t, lang, "app_settings", appInfoData(st))
|
|
has := strings.Contains(h, `data-definition-refused="true"`)
|
|
if refused && (!has || !strings.Contains(h, want)) {
|
|
t.Errorf("[%s] a refused definition is not on the page (marker %v, sentence %q)", lang, has, want)
|
|
}
|
|
if !refused && has {
|
|
t.Errorf("[%s] positive control: no refusal, yet the line is shown", lang)
|
|
}
|
|
if strings.Contains(h, "privileged true") {
|
|
t.Errorf("[%s] the household page shows the operator detail", lang)
|
|
}
|
|
}
|
|
}
|
|
}
|