Erst die Sitzung, dann der Schluessel
Der Schluessel kennt keinen Nutzer und landete beim Standardnutzer — auch dann, wenn die App unter derselben Site liegt und der Browser das HoneyOS-Cookie laengst mitschickt (cloud.honeyos.… und honeyos.… sind dieselbe Site, duckdns.org steht auf der Public-Suffix-Liste). Damit trug die HoneyBar in Aether die Farben eines fremden Nutzers. Jetzt sieht /api/apps erst nach der Sitzung, und nur bei eigener Anmeldung: Im offenen Betrieb und hinter einem Anmelde-Proxy gilt jede Anfrage als angemeldet, dort bleibt der Schluessel das letzte Wort. Test dazu, mit zwei Nutzern, damit der Rueckfall auf den einzigen Nutzer das Ergebnis nicht zufaellig richtig aussehen laesst.
This commit is contained in:
1 parent
ffaba616ce
commit
cc7a50c621
4 files changed
+111
-14
No files matched your search
@@ -483,6 +483,69 @@ func TestAppListeBrauchtDenSchlüssel(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Liegt die App unter derselben Site, kommt die Sitzung mit — dann muss die
|
||||
// HoneyBar die Einstellungen des Angemeldeten bekommen und nicht die des
|
||||
// Standardnutzers. Der Schlüssel darf dabei ruhig mitgeschickt werden: Er ist
|
||||
// die Krücke für den fremden Fall und darf die Sitzung nicht überstimmen.
|
||||
func TestSitzungSchlaegtSchluessel(t *testing.T) {
|
||||
idp := newFakeIdP(t, "honeyos")
|
||||
s := newTestServer(t, idp.URL)
|
||||
s.cfg.AppsKey = "geheim123"
|
||||
s.auth = auth.New(s.cfg)
|
||||
h := s.routes()
|
||||
|
||||
sess, csrf := signIn(t, h)
|
||||
|
||||
// Der Angemeldete stellt seine Röhre auf grün.
|
||||
req := httptest.NewRequest("PUT", "/api/settings", strings.NewReader(`{"phosphor":"green"}`))
|
||||
req.Header.Set("X-CSRF-Token", csrf.Value)
|
||||
req.AddCookie(sess)
|
||||
req.AddCookie(csrf)
|
||||
rec := httptest.NewRecorder()
|
||||
h.ServeHTTP(rec, req)
|
||||
if rec.Code != http.StatusNoContent {
|
||||
t.Fatalf("Einstellungen speichern: %d", rec.Code)
|
||||
}
|
||||
|
||||
// Ein zweiter Nutzer mit anderer Röhre — sonst könnte der Rückfall auf den
|
||||
// „einzigen Nutzer" das Ergebnis zufällig richtig aussehen lassen.
|
||||
if err := s.store.SetSettings("jemand-anders", map[string]string{"phosphor": "ice"}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
hole := func(mod func(*http.Request)) map[string]any {
|
||||
req := httptest.NewRequest("GET", "/api/apps", nil)
|
||||
mod(req)
|
||||
rec := httptest.NewRecorder()
|
||||
h.ServeHTTP(rec, req)
|
||||
if rec.Code != 200 {
|
||||
t.Fatalf("/api/apps: %d", rec.Code)
|
||||
}
|
||||
var out map[string]any
|
||||
if err := json.Unmarshal(rec.Body.Bytes(), &out); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
mitBeidem := hole(func(r *http.Request) {
|
||||
r.AddCookie(sess)
|
||||
r.Header.Set("X-HoneyOS-Key", "geheim123")
|
||||
})
|
||||
if got := mitBeidem["settings"].(map[string]any)["phosphor"]; got != "green" {
|
||||
t.Errorf("mit Sitzung und Schlüssel: %v, erwartet green (die des Angemeldeten)", got)
|
||||
}
|
||||
|
||||
// Ohne Sitzung bleibt der Schlüssel der Weg — und landet beim
|
||||
// Standardnutzer. Bei zwei Nutzern heißt das: kein Rateweg, leere Menge.
|
||||
nurSchluessel := hole(func(r *http.Request) {
|
||||
r.Header.Set("X-HoneyOS-Key", "geheim123")
|
||||
})
|
||||
if got := nurSchluessel["settings"].(map[string]any)["phosphor"]; got == "green" {
|
||||
t.Errorf("nur mit Schlüssel: %v — der Schlüssel kennt keinen Nutzer und darf keinen raten", got)
|
||||
}
|
||||
}
|
||||
|
||||
// Der Schlüssel öffnet nur das Lesen der Liste, nicht das Schreiben.
|
||||
func TestSchlüsselDarfNichtSchreiben(t *testing.T) {
|
||||
idp := newFakeIdP(t, "honeyos")
|
||||
|
||||
Reference in new issue
Block a user