R-1281: FileBrowser is served on its own felhom-files network (traefik, and OnlyOffice while linked) and leaves traefik-public, so no app container reaches it. R-1126's check-then-publish gate unchanged. Red-proved. Commit only.
gates / gates (push) Successful in 1m29s
gates / gates (push) Successful in 1m29s
This commit is contained in:
@@ -279,20 +279,21 @@ func TestFileBrowserGate_PublishedOnlyAfterTheCheck(t *testing.T) {
|
||||
// A new run whose FileBrowser does not answer: nothing is published.
|
||||
down = true
|
||||
m.fileBrowserGateLocked()
|
||||
if nets["filebrowser@traefik-public"] {
|
||||
if nets["filebrowser@traefik-public"] || nets["filebrowser@felhom-files"] {
|
||||
t.Fatal("published while this run's default login was never checked")
|
||||
}
|
||||
// It answers, on its default: replaced first, published after.
|
||||
down = false
|
||||
m.fileBrowserGateLocked()
|
||||
want := []string{"connect felhom-controller felhom-filebrowser", "password replaced", "connect filebrowser traefik-public"}
|
||||
// R-1281: published on the files network (traefik joins it first), never on traefik-public.
|
||||
want := []string{"connect felhom-controller felhom-filebrowser", "password replaced", "connect traefik felhom-files", "connect filebrowser felhom-files"}
|
||||
if strings.Join(events, " | ") != strings.Join(want, " | ") {
|
||||
t.Fatalf("order:\n got %v\n want %v", events, want)
|
||||
}
|
||||
// A new run (a restart) on the box's own password: checked, nothing changes, nothing connected twice.
|
||||
run = "run-2"
|
||||
m.fileBrowserGateLocked()
|
||||
if len(events) != 3 {
|
||||
if len(events) != 4 {
|
||||
t.Fatalf("a checked restart did more: %v", events)
|
||||
}
|
||||
}
|
||||
@@ -313,7 +314,82 @@ func TestFileBrowserGate_ConnectsTheCheckedContainerById(t *testing.T) {
|
||||
return nil
|
||||
}
|
||||
m.fileBrowserGateLocked()
|
||||
if len(connected) != 2 || connected[1] != "3f2a9c@traefik-public" {
|
||||
if len(connected) != 3 || connected[2] != "3f2a9c@felhom-files" {
|
||||
t.Fatalf("the checked container must be published by its id, got %v", connected)
|
||||
}
|
||||
}
|
||||
|
||||
// R-1281 (D44 #23): every app container is on traefik-public, so FileBrowser on it could be reached directly — measured
|
||||
// 2026-10-18: from an app container, a forged sign-in header got the drive's listing. The checked FileBrowser is served
|
||||
// on the files network only, and one an earlier controller put on traefik-public leaves it.
|
||||
// RED-PROOF: skip the traefik-public disconnect → it stays on the app network; connect to traefik-public as before →
|
||||
// it is on it.
|
||||
func TestR1281_FileBrowserLeavesTheAppNetworkAndIsServedOnTheFilesNetwork(t *testing.T) {
|
||||
fb := &fakeFB{password: "admin"}
|
||||
srv := httptest.NewServer(fb.handler())
|
||||
defer srv.Close()
|
||||
m, _, _ := fbManager(t, srv.URL)
|
||||
m.fbStarted = func() string { return "3f2a9c 2026-10-25T20:00:00Z" }
|
||||
nets := map[string]bool{"3f2a9c@traefik-public": true} // as a 0.343.0 controller left it
|
||||
m.fbNetOnFn = func(c, n string) bool { return nets[c+"@"+n] }
|
||||
m.fbNetConnectFn = func(c, n string) error { nets[c+"@"+n] = true; return nil }
|
||||
m.fbNetDisconnectFn = func(c, n string) error { delete(nets, c+"@"+n); return nil }
|
||||
m.fbNetEnsureFn = func(string) error { return nil }
|
||||
m.fbOfficeLinkedFn = func() (bool, bool) { return false, false }
|
||||
m.fileBrowserGateLocked()
|
||||
if nets["3f2a9c@traefik-public"] {
|
||||
t.Fatal("FileBrowser is still on traefik-public — every app container reaches it")
|
||||
}
|
||||
if !nets["3f2a9c@felhom-files"] || !nets["traefik@felhom-files"] {
|
||||
t.Fatalf("FileBrowser and traefik must share the files network: %v", nets)
|
||||
}
|
||||
}
|
||||
|
||||
// The files network keeps R-1126's guarantee: an unchecked run joins nothing, so a re-created FileBrowser (default
|
||||
// password) is not reachable from outside.
|
||||
func TestR1281_AnUncheckedRunJoinsNothing(t *testing.T) {
|
||||
fb := &fakeFB{password: "admin"}
|
||||
srv := httptest.NewServer(fb.handler())
|
||||
defer srv.Close()
|
||||
m, _, _ := fbManager(t, srv.URL)
|
||||
m.fbStarted = func() string { return "" } // the run cannot be read
|
||||
var joined []string
|
||||
m.fbNetOnFn = func(string, string) bool { return false }
|
||||
m.fbNetConnectFn = func(c, n string) error { joined = append(joined, c+"@"+n); return nil }
|
||||
m.fbNetEnsureFn = func(string) error { return nil }
|
||||
m.fileBrowserGateLocked()
|
||||
for _, j := range joined {
|
||||
if strings.HasSuffix(j, "@felhom-files") || strings.HasSuffix(j, "@traefik-public") {
|
||||
t.Fatalf("an unchecked run joined %s", j)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// OnlyOffice shares the files network while — and only while — its FileBrowser link is on.
|
||||
// RED-PROOF: drop ensureOfficeOnFilesNetwork → the linked case never joins.
|
||||
func TestR1281_OnlyOfficeJoinsTheFilesNetworkOnlyWhileLinked(t *testing.T) {
|
||||
fb := &fakeFB{password: "admin"}
|
||||
srv := httptest.NewServer(fb.handler())
|
||||
defer srv.Close()
|
||||
m, _, _ := fbManager(t, srv.URL)
|
||||
m.fbStarted = func() string { return "3f2a9c 2026-10-25T20:00:00Z" }
|
||||
nets := map[string]bool{}
|
||||
m.fbNetOnFn = func(c, n string) bool { return nets[c+"@"+n] }
|
||||
m.fbNetConnectFn = func(c, n string) error { nets[c+"@"+n] = true; return nil }
|
||||
m.fbNetDisconnectFn = func(c, n string) error { delete(nets, c+"@"+n); return nil }
|
||||
m.fbNetEnsureFn = func(string) error { return nil }
|
||||
linked := true
|
||||
m.fbOfficeLinkedFn = func() (bool, bool) { return linked, true }
|
||||
m.fileBrowserGateLocked()
|
||||
if !nets["onlyoffice@felhom-files"] {
|
||||
t.Fatalf("a linked OnlyOffice must reach FileBrowser: %v", nets)
|
||||
}
|
||||
linked = false
|
||||
m.fileBrowserGateLocked()
|
||||
if nets["onlyoffice@felhom-files"] {
|
||||
t.Fatal("an unlinked OnlyOffice must leave the files network")
|
||||
}
|
||||
if nets["onlyoffice@traefik-public"] || nets["3f2a9c@traefik-public"] {
|
||||
t.Fatalf("nothing joins traefik-public here: %v", nets)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user