From 859439c1e0643b7767a830748fbdc62310e06264 Mon Sep 17 00:00:00 2001 From: hexbinoct Date: Mon, 6 Jul 2026 11:49:39 +0500 Subject: [PATCH] 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> --- fs/config/config.go | 7 +++++++ fs/config/config_test.go | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/fs/config/config.go b/fs/config/config.go index d01306534..57d3d1746 100644 --- a/fs/config/config.go +++ b/fs/config/config.go @@ -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" } diff --git a/fs/config/config_test.go b/fs/config/config_test.go index 7c4a503bf..d430444b6 100644 --- a/fs/config/config_test.go +++ b/fs/config/config_test.go @@ -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": "ok", + }, 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, "ok", 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")) +}