lib/api, lib/config: Apply defaults before deserializing json (#7690)

This commit is contained in:
Simon Frei
2021-06-03 15:09:35 +02:00
committed by GitHub
parent 855c53ad02
commit 52eb7392c4
3 changed files with 74 additions and 34 deletions

View File

@@ -2129,7 +2129,7 @@ angular.module('syncthing.core')
folderCfg.versioning.params.command = '' + folderCfg._guiVersioning.externalCommand;
break;
default:
delete folderCfg.versioning;
folderCfg.versioning = {type: ''};
}
delete folderCfg._guiVersioning;

View File

@@ -17,6 +17,7 @@ import (
"github.com/syncthing/syncthing/lib/config"
"github.com/syncthing/syncthing/lib/protocol"
"github.com/syncthing/syncthing/lib/util"
)
type configMuxBuilder struct {
@@ -63,10 +64,15 @@ func (c *configMuxBuilder) registerFolders(path string) {
})
c.HandlerFunc(http.MethodPut, path, func(w http.ResponseWriter, r *http.Request) {
var folders []config.FolderConfiguration
if err := unmarshalTo(r.Body, &folders); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
data, err := unmarshalToRawMessages(r.Body)
folders := make([]config.FolderConfiguration, len(data))
defaultFolder := c.cfg.DefaultFolder()
for i, bs := range data {
folders[i] = defaultFolder.Copy()
if err := json.Unmarshal(bs, &folders[i]); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
}
waiter, err := c.cfg.Modify(func(cfg *config.Configuration) {
cfg.SetFolders(folders)
@@ -79,7 +85,7 @@ func (c *configMuxBuilder) registerFolders(path string) {
})
c.HandlerFunc(http.MethodPost, path, func(w http.ResponseWriter, r *http.Request) {
c.adjustFolder(w, r, config.FolderConfiguration{}, false)
c.adjustFolder(w, r, c.cfg.DefaultFolder(), false)
})
}
@@ -89,10 +95,15 @@ func (c *configMuxBuilder) registerDevices(path string) {
})
c.HandlerFunc(http.MethodPut, path, func(w http.ResponseWriter, r *http.Request) {
var devices []config.DeviceConfiguration
if err := unmarshalTo(r.Body, &devices); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
data, err := unmarshalToRawMessages(r.Body)
devices := make([]config.DeviceConfiguration, len(data))
defaultDevice := c.cfg.DefaultDevice()
for i, bs := range data {
devices[i] = defaultDevice.Copy()
if err := json.Unmarshal(bs, &devices[i]); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
}
waiter, err := c.cfg.Modify(func(cfg *config.Configuration) {
cfg.SetDevices(devices)
@@ -105,19 +116,7 @@ func (c *configMuxBuilder) registerDevices(path string) {
})
c.HandlerFunc(http.MethodPost, path, func(w http.ResponseWriter, r *http.Request) {
var device config.DeviceConfiguration
if err := unmarshalTo(r.Body, &device); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
waiter, err := c.cfg.Modify(func(cfg *config.Configuration) {
cfg.SetDevice(device)
})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
c.finish(w, waiter)
c.adjustDevice(w, r, c.cfg.DefaultDevice(), false)
})
}
@@ -132,7 +131,7 @@ func (c *configMuxBuilder) registerFolder(path string) {
})
c.Handle(http.MethodPut, path, func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
c.adjustFolder(w, r, config.FolderConfiguration{}, false)
c.adjustFolder(w, r, c.cfg.DefaultFolder(), false)
})
c.Handle(http.MethodPatch, path, func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
@@ -176,7 +175,7 @@ func (c *configMuxBuilder) registerDevice(path string) {
})
c.Handle(http.MethodPut, path, func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
c.adjustDevice(w, r, config.DeviceConfiguration{}, false)
c.adjustDevice(w, r, c.cfg.DefaultDevice(), false)
})
c.Handle(http.MethodPatch, path, func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
@@ -206,7 +205,9 @@ func (c *configMuxBuilder) registerDefaultFolder(path string) {
})
c.HandlerFunc(http.MethodPut, path, func(w http.ResponseWriter, r *http.Request) {
c.adjustFolder(w, r, config.FolderConfiguration{}, true)
var cfg config.FolderConfiguration
util.SetDefaults(&cfg)
c.adjustFolder(w, r, cfg, true)
})
c.HandlerFunc(http.MethodPatch, path, func(w http.ResponseWriter, r *http.Request) {
@@ -220,7 +221,9 @@ func (c *configMuxBuilder) registerDefaultDevice(path string) {
})
c.HandlerFunc(http.MethodPut, path, func(w http.ResponseWriter, r *http.Request) {
c.adjustDevice(w, r, config.DeviceConfiguration{}, true)
var cfg config.DeviceConfiguration
util.SetDefaults(&cfg)
c.adjustDevice(w, r, cfg, true)
})
c.HandlerFunc(http.MethodPatch, path, func(w http.ResponseWriter, r *http.Request) {
@@ -234,7 +237,9 @@ func (c *configMuxBuilder) registerOptions(path string) {
})
c.HandlerFunc(http.MethodPut, path, func(w http.ResponseWriter, r *http.Request) {
c.adjustOptions(w, r, config.OptionsConfiguration{})
var cfg config.OptionsConfiguration
util.SetDefaults(&cfg)
c.adjustOptions(w, r, cfg)
})
c.HandlerFunc(http.MethodPatch, path, func(w http.ResponseWriter, r *http.Request) {
@@ -248,7 +253,9 @@ func (c *configMuxBuilder) registerLDAP(path string) {
})
c.HandlerFunc(http.MethodPut, path, func(w http.ResponseWriter, r *http.Request) {
c.adjustLDAP(w, r, config.LDAPConfiguration{})
var cfg config.LDAPConfiguration
util.SetDefaults(&cfg)
c.adjustLDAP(w, r, cfg)
})
c.HandlerFunc(http.MethodPatch, path, func(w http.ResponseWriter, r *http.Request) {
@@ -262,7 +269,9 @@ func (c *configMuxBuilder) registerGUI(path string) {
})
c.HandlerFunc(http.MethodPut, path, func(w http.ResponseWriter, r *http.Request) {
c.adjustGUI(w, r, config.GUIConfiguration{})
var cfg config.GUIConfiguration
util.SetDefaults(&cfg)
c.adjustGUI(w, r, cfg)
})
c.HandlerFunc(http.MethodPatch, path, func(w http.ResponseWriter, r *http.Request) {
@@ -403,6 +412,12 @@ func unmarshalTo(body io.ReadCloser, to interface{}) error {
return json.Unmarshal(bs, to)
}
func unmarshalToRawMessages(body io.ReadCloser) ([]json.RawMessage, error) {
var data []json.RawMessage
err := unmarshalTo(body, &data)
return data, err
}
func checkGUIPassword(oldPassword, newPassword string) (string, error) {
if newPassword == oldPassword {
return newPassword, nil

View File

@@ -163,19 +163,44 @@ func ReadXML(r io.Reader, myID protocol.DeviceID) (Configuration, int, error) {
}
func ReadJSON(r io.Reader, myID protocol.DeviceID) (Configuration, error) {
var cfg Configuration
util.SetDefaults(&cfg)
bs, err := ioutil.ReadAll(r)
if err != nil {
return Configuration{}, err
}
var cfg Configuration
util.SetDefaults(&cfg)
if err := json.Unmarshal(bs, &cfg); err != nil {
return Configuration{}, err
}
// Unmarshal list of devices and folders separately to set defaults
var rawFoldersDevices struct {
Folders []json.RawMessage
Devices []json.RawMessage
}
if err := json.Unmarshal(bs, &rawFoldersDevices); err != nil {
return Configuration{}, err
}
cfg.Folders = make([]FolderConfiguration, len(rawFoldersDevices.Folders))
for i, bs := range rawFoldersDevices.Folders {
cfg.Folders[i] = cfg.Defaults.Folder.Copy()
if err := json.Unmarshal(bs, &cfg.Folders[i]); err != nil {
return Configuration{}, err
}
}
cfg.Devices = make([]DeviceConfiguration, len(rawFoldersDevices.Devices))
for i, bs := range rawFoldersDevices.Devices {
cfg.Devices[i] = cfg.Defaults.Device.Copy()
if err := json.Unmarshal(bs, &cfg.Devices[i]); err != nil {
return Configuration{}, err
}
}
if err := cfg.prepare(myID); err != nil {
return Configuration{}, err
}