config: fix config_template_file and config_template being ignored via config/create - fixes #9572
When creating or updating a remote through the rc api (config/create, config/update), parameters whose name starts with the ephemeral prefix "config_" (for example config_template_file and config_template used to customise the OAuth success page) were silently ignored. updateRemote sets each supplied parameter into the config mapper, but skips the "config_" prefixed keys so they are never written to the config file. That guard is correct, because the mapper's setter writes to the config file and these values are ephemeral. However backends read these values back from the mapper (oauthutil reads config_template_file and config_template via m.Get), so dropping them entirely meant the values could never reach the backend and the default template was always used. Collect the ephemeral parameters into a separate map and add it to the mapper as a getter overlay at PriorityNormal after the loop. The values are now readable through m.Get without being written to the config file, which is the same approach rclone authorize already uses to expose a template supplied on the command line. Fixes #9572 Co-authored-by: Hakanbaban53 <93117749+Hakanbaban53@users.noreply.github.com> Co-authored-by: maximilize <3752128+maximilize@users.noreply.github.com>
This commit is contained in:
committed by
Nick Craig-Wood
co-authored by
Hakanbaban53
maximilize
parent
75429ca647
commit
859439c1e0
@@ -565,6 +565,7 @@ func updateRemote(ctx context.Context, name string, keyValues rc.Params, opt Upd
|
|||||||
}
|
}
|
||||||
|
|
||||||
choices := configmap.Simple{}
|
choices := configmap.Simple{}
|
||||||
|
ephemeral := configmap.Simple{}
|
||||||
m := fs.ConfigMap(ri.Prefix, ri.Options, name, nil)
|
m := fs.ConfigMap(ri.Prefix, ri.Options, name, nil)
|
||||||
|
|
||||||
// Set the config
|
// Set the config
|
||||||
@@ -588,8 +589,14 @@ func updateRemote(ctx context.Context, name string, keyValues rc.Params, opt Upd
|
|||||||
choices.Set(k, vStr)
|
choices.Set(k, vStr)
|
||||||
if !strings.HasPrefix(k, fs.ConfigKeyEphemeralPrefix) {
|
if !strings.HasPrefix(k, fs.ConfigKeyEphemeralPrefix) {
|
||||||
m.Set(k, vStr)
|
m.Set(k, vStr)
|
||||||
|
} else {
|
||||||
|
ephemeral.Set(k, vStr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Add a getter to make sure ephemeral config is still visible
|
||||||
|
if len(ephemeral) > 0 {
|
||||||
|
m.AddGetter(ephemeral, configmap.PriorityNormal)
|
||||||
|
}
|
||||||
if opt.Edit {
|
if opt.Edit {
|
||||||
choices[fs.ConfigEdit] = "true"
|
choices[fs.ConfigEdit] = "true"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,11 +3,16 @@
|
|||||||
package config_test
|
package config_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/rclone/rclone/fs"
|
||||||
"github.com/rclone/rclone/fs/config"
|
"github.com/rclone/rclone/fs/config"
|
||||||
"github.com/rclone/rclone/fs/config/configfile"
|
"github.com/rclone/rclone/fs/config/configfile"
|
||||||
|
"github.com/rclone/rclone/fs/config/configmap"
|
||||||
|
"github.com/rclone/rclone/fs/rc"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@@ -29,3 +34,38 @@ func TestConfigLoad(t *testing.T) {
|
|||||||
expect = []string{"type", "nounc"}
|
expect = []string{"type", "nounc"}
|
||||||
assert.Equal(t, expect, keys)
|
assert.Equal(t, expect, keys)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestCreateRemoteEphemeralConfigKeysReachBackend checks that config_* parameters
|
||||||
|
// (#9572) are readable by the backend via the mapper but not saved to the config file.
|
||||||
|
func TestCreateRemoteEphemeralConfigKeysReachBackend(t *testing.T) {
|
||||||
|
defer testConfigFile(t, simpleOptions, "ephemeral.conf")()
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
var seenTemplateFile, seenTemplate string
|
||||||
|
backendName := "config_template_test_remote"
|
||||||
|
if regInfo, _ := fs.Find(backendName); regInfo == nil {
|
||||||
|
fs.Register(&fs.RegInfo{
|
||||||
|
Name: backendName,
|
||||||
|
Config: func(_ context.Context, _ string, m configmap.Mapper, _ fs.ConfigIn) (*fs.ConfigOut, error) {
|
||||||
|
seenTemplateFile, _ = m.Get("config_template_file")
|
||||||
|
seenTemplate, _ = m.Get("config_template")
|
||||||
|
return nil, nil
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := config.CreateRemote(ctx, "eph", backendName, rc.Params{
|
||||||
|
"config_template_file": "/path/to/template.html",
|
||||||
|
"config_template": "<html>ok</html>",
|
||||||
|
}, config.UpdateRemoteOpt{NonInteractive: true})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// The backend must be able to read the ephemeral config_* parameters
|
||||||
|
// through the mapper (before the fix these came back empty).
|
||||||
|
assert.Equal(t, "/path/to/template.html", seenTemplateFile)
|
||||||
|
assert.Equal(t, "<html>ok</html>", seenTemplate)
|
||||||
|
|
||||||
|
// ...but they must not be persisted to the config file.
|
||||||
|
assert.Equal(t, "", config.GetValue("eph", "config_template_file"))
|
||||||
|
assert.Equal(t, "", config.GetValue("eph", "config_template"))
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user