refactor(api): extract method configMuxBuilder.postAdjustGui and add test coverage (#9979)

This is extracted from PR #9175. This deduplicates `SetPassword` calls
and makes `postAdjustGui` a single place where PR #9175 can add
another adjustment step for sanitizing changes to WebAuthn
credentials.

This also adds tests to validate that the refactored logic was not
broken.
This commit is contained in:
Emil Lundberg
2025-03-09 21:31:06 +01:00
committed by GitHub
parent 435f2d2178
commit 893071d2ba
2 changed files with 141 additions and 15 deletions
+123
View File
@@ -751,6 +751,129 @@ func TestHTTPLogin(t *testing.T) {
testWith(false, http.StatusOK, http.StatusOK, "/")
testWith(false, http.StatusOK, http.StatusForbidden, "/meta.js")
testWith(false, http.StatusNotFound, http.StatusForbidden, "/any-path/that/does/nooooooot/match-any/noauth-pattern")
t.Run("Password change invalidates old and enables new password", func(t *testing.T) {
t.Parallel()
// This test needs a longer-than-default shutdown timeout to finish saving
// config changes when running on GitHub Actions
shutdownTimeout := time.Second
initConfig := func(password string, t *testing.T) config.Wrapper {
gui := config.GUIConfiguration{
RawAddress: "127.0.0.1:0",
APIKey: testAPIKey,
User: "user",
}
if err := gui.SetPassword(password); err != nil {
t.Fatal(err, "Failed to set initial password")
}
cfg := config.Configuration{
GUI: gui,
}
tmpFile, err := os.CreateTemp("", "syncthing-testConfig-Password-*")
if err != nil {
t.Fatal(err, "Failed to create tmpfile for test")
}
w := config.Wrap(tmpFile.Name(), cfg, protocol.LocalDeviceID, events.NoopLogger)
tmpFile.Close()
cfgCtx, cfgCancel := context.WithCancel(context.Background())
go w.Serve(cfgCtx)
t.Cleanup(func() {
os.Remove(tmpFile.Name())
cfgCancel()
})
return w
}
initialPassword := "Asdf123!"
newPassword := "123!asdF"
t.Run("when done via /rest/config", func(t *testing.T) {
t.Parallel()
w := initConfig(initialPassword, t)
{
baseURL, cancel, err := startHTTPWithShutdownTimeout(w, shutdownTimeout)
cfgPath := baseURL + "/rest/config"
path := baseURL + "/meta.js"
t.Cleanup(cancel)
if err != nil {
t.Fatal(err)
}
resp := httpGetBasicAuth(path, "user", initialPassword)
if resp.StatusCode != http.StatusOK {
t.Fatalf("Unexpected non-200 return code %d for auth with initial password", resp.StatusCode)
}
cfg := w.RawCopy()
cfg.GUI.Password = newPassword
httpRequest(http.MethodPut, cfgPath, cfg, "", "", testAPIKey, "", "", "", nil, t)
}
{
baseURL, cancel, err := startHTTP(w)
path := baseURL + "/meta.js"
t.Cleanup(cancel)
if err != nil {
t.Fatal(err)
}
resp := httpGetBasicAuth(path, "user", initialPassword)
if resp.StatusCode != http.StatusForbidden {
t.Errorf("Unexpected non-403 return code %d for request authed with old password", resp.StatusCode)
}
resp2 := httpGetBasicAuth(path, "user", newPassword)
if resp2.StatusCode != http.StatusOK {
t.Errorf("Unexpected non-200 return code %d for request authed with new password", resp2.StatusCode)
}
}
})
t.Run("when done via /rest/config/gui", func(t *testing.T) {
t.Parallel()
w := initConfig(initialPassword, t)
{
baseURL, cancel, err := startHTTPWithShutdownTimeout(w, shutdownTimeout)
cfgPath := baseURL + "/rest/config/gui"
path := baseURL + "/meta.js"
t.Cleanup(cancel)
if err != nil {
t.Fatal(err)
}
resp := httpGetBasicAuth(path, "user", initialPassword)
if resp.StatusCode != http.StatusOK {
t.Fatalf("Unexpected non-200 return code %d for auth with initial password", resp.StatusCode)
}
cfg := w.RawCopy()
cfg.GUI.Password = newPassword
httpRequest(http.MethodPut, cfgPath, cfg.GUI, "", "", testAPIKey, "", "", "", nil, t)
}
{
baseURL, cancel, err := startHTTP(w)
path := baseURL + "/meta.js"
t.Cleanup(cancel)
if err != nil {
t.Fatal(err)
}
resp := httpGetBasicAuth(path, "user", initialPassword)
if resp.StatusCode != http.StatusForbidden {
t.Errorf("Unexpected non-403 return code %d for request authed with old password", resp.StatusCode)
}
resp2 := httpGetBasicAuth(path, "user", newPassword)
if resp2.StatusCode != http.StatusOK {
t.Errorf("Unexpected non-200 return code %d for request authed with new password", resp2.StatusCode)
}
}
})
})
}
func TestHtmlFormLogin(t *testing.T) {