mirror of
https://github.com/rclone/rclone.git
synced 2026-07-13 01:02:15 -04:00
A connection string can carry global.* options which change rclone's process-wide configuration (e.g. global.http_proxy). This is undesirable for the rc interface which was designed to have multiple users or connections at once. The rc interface has the `_config` mechanism for setting request scoped global config. This blocks global.* options on all rc paths by marking the context as a remote control request at the rc boundaries. fs.NewFs then skips applying global.* to the process-wide config for a marked context. The marker is reapplied in fs.CopyConfig, which is the call rclone uses to detach context but keep config. global.* options still apply to the individual backend they are set on, exactly like override.* options; they just no longer leak into the rest of the process. Remotes created directly on the command line are unaffected as are remotes defined in the config file. See: GHSA-qw24-gh76-8rvv
78 lines
2.3 KiB
Go
78 lines
2.3 KiB
Go
package fs
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/rclone/rclone/fs/config/configmap"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// When no override/global keys exist, ctx must be returned unchanged.
|
|
func TestAddConfigToContext_NoChanges(t *testing.T) {
|
|
ctx := context.Background()
|
|
newCtx, err := addConfigToContext(ctx, "unit-test", configmap.Simple{})
|
|
require.NoError(t, err)
|
|
assert.Equal(t, newCtx, ctx)
|
|
}
|
|
|
|
// A single override.key must create a new ctx, but leave the
|
|
// background ctx untouched.
|
|
func TestAddConfigToContext_OverrideOnly(t *testing.T) {
|
|
override := configmap.Simple{
|
|
"override.user_agent": "potato",
|
|
}
|
|
ctx := context.Background()
|
|
globalCI := GetConfig(ctx)
|
|
original := globalCI.UserAgent
|
|
newCtx, err := addConfigToContext(ctx, "unit-test", override)
|
|
require.NoError(t, err)
|
|
assert.NotEqual(t, newCtx, ctx)
|
|
assert.Equal(t, original, globalCI.UserAgent)
|
|
ci := GetConfig(newCtx)
|
|
assert.Equal(t, "potato", ci.UserAgent)
|
|
}
|
|
|
|
// A single global.key must create a new ctx and update the
|
|
// background/global config.
|
|
func TestAddConfigToContext_GlobalOnly(t *testing.T) {
|
|
global := configmap.Simple{
|
|
"global.user_agent": "potato2",
|
|
}
|
|
ctx := context.Background()
|
|
globalCI := GetConfig(ctx)
|
|
original := globalCI.UserAgent
|
|
defer func() {
|
|
globalCI.UserAgent = original
|
|
}()
|
|
newCtx, err := addConfigToContext(ctx, "unit-test", global)
|
|
require.NoError(t, err)
|
|
assert.NotEqual(t, newCtx, ctx)
|
|
assert.Equal(t, "potato2", globalCI.UserAgent)
|
|
ci := GetConfig(newCtx)
|
|
assert.Equal(t, "potato2", ci.UserAgent)
|
|
}
|
|
|
|
// When the ctx is marked as a remote control (rc) request, a global.key must
|
|
// apply to the backend's own ctx but must NOT change the process-wide config.
|
|
func TestAddConfigToContext_GlobalFromRC(t *testing.T) {
|
|
global := configmap.Simple{
|
|
"global.user_agent": "potato3",
|
|
}
|
|
ctx := WithRCRequest(context.Background())
|
|
globalCI := GetConfig(ctx)
|
|
original := globalCI.UserAgent
|
|
defer func() {
|
|
globalCI.UserAgent = original
|
|
}()
|
|
newCtx, err := addConfigToContext(ctx, "unit-test", global)
|
|
require.NoError(t, err)
|
|
assert.NotEqual(t, newCtx, ctx)
|
|
// The process-wide config must be untouched
|
|
assert.Equal(t, original, globalCI.UserAgent)
|
|
// but the backend's own ctx still gets the value
|
|
ci := GetConfig(newCtx)
|
|
assert.Equal(t, "potato3", ci.UserAgent)
|
|
}
|