diff --git a/backend/drive/drive.go b/backend/drive/drive.go index ca04837fa..40a770b7c 100644 --- a/backend/drive/drive.go +++ b/backend/drive/drive.go @@ -1303,6 +1303,7 @@ func createOAuthClient(ctx context.Context, opt *Options, name string, m configm return nil, fmt.Errorf("failed to create client from environment: %w", err) } } else { + oauthutil.SharedClientIDWarning(name, "Google Drive", "https://rclone.org/drive/#making-your-own-client-id", m) oAuthClient, _, err = oauthutil.NewClientWithBaseClient(ctx, name, m, driveConfig, getClient(ctx, opt)) if err != nil { return nil, fmt.Errorf("failed to create oauth client: %w", err) diff --git a/backend/googlephotos/googlephotos.go b/backend/googlephotos/googlephotos.go index bbe7d84b1..6ecb4ce38 100644 --- a/backend/googlephotos/googlephotos.go +++ b/backend/googlephotos/googlephotos.go @@ -349,6 +349,8 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e return nil, err } + oauthutil.SharedClientIDWarning(name, "Google Photos", "https://rclone.org/googlephotos/#making-your-own-client-id", m) + baseClient := fshttp.NewClient(ctx) oAuthClient, ts, err := oauthutil.NewClientWithBaseClient(ctx, name, m, oauthConfig, baseClient) if err != nil { diff --git a/lib/oauthutil/oauthutil.go b/lib/oauthutil/oauthutil.go index 856c881eb..fb713ba88 100644 --- a/lib/oauthutil/oauthutil.go +++ b/lib/oauthutil/oauthutil.go @@ -484,6 +484,24 @@ func OverrideCredentials(name string, m configmap.Mapper, origConfig *Config) (n return newConfig, changed } +// SharedClientIDWarning warns the user that this remote is relying on +// rclone's built-in shared OAuth client_id. +// +// It only warns when the user has not configured their own client_id +// (config.ConfigClientID is blank in the config), so it must only be +// called from the code path that actually uses the shared client_id - +// not for service account, environment or anonymous auth which don't. +// +// name is the remote's name, service is the human readable name of the +// service (eg "Google Drive") and helpURL points at the docs describing +// how to make your own client_id. +func SharedClientIDWarning(name, service, helpURL string, m configmap.Mapper) { + if clientID, _ := m.Get(config.ConfigClientID); clientID != "" { + return + } + fs.Logf(name, "This remote uses rclone's shared %s client_id, which is being retired and will stop working during 2026. Create your own client_id to avoid interruption: %s", service, helpURL) +} + // NewClientWithBaseClient gets a token from the config file and // configures a Client with it. It returns the client and a // TokenSource which Invalidate may need to be called on. It uses the