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:
hexbinoct
2026-07-09 15:44:49 +01:00
committed by Nick Craig-Wood
co-authored by Hakanbaban53 maximilize
parent 75429ca647
commit 859439c1e0
2 changed files with 47 additions and 0 deletions
+7
View File
@@ -565,6 +565,7 @@ func updateRemote(ctx context.Context, name string, keyValues rc.Params, opt Upd
}
choices := configmap.Simple{}
ephemeral := configmap.Simple{}
m := fs.ConfigMap(ri.Prefix, ri.Options, name, nil)
// Set the config
@@ -588,8 +589,14 @@ func updateRemote(ctx context.Context, name string, keyValues rc.Params, opt Upd
choices.Set(k, vStr)
if !strings.HasPrefix(k, fs.ConfigKeyEphemeralPrefix) {
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 {
choices[fs.ConfigEdit] = "true"
}
+40
View File
@@ -3,11 +3,16 @@
package config_test
import (
"context"
"testing"
"github.com/rclone/rclone/fs"
"github.com/rclone/rclone/fs/config"
"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/require"
)
func init() {
@@ -29,3 +34,38 @@ func TestConfigLoad(t *testing.T) {
expect = []string{"type", "nounc"}
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"))
}