mirror of
https://github.com/rclone/rclone
synced 2024-11-25 02:47:14 +01:00
fs: add names to each config parameter so we can override them #3455
This commit is contained in:
parent
94dbfa4ea6
commit
f122808d86
@ -208,9 +208,9 @@ func init() {
|
||||
return fs.ConfigGoto("teamdrive")
|
||||
case "teamdrive":
|
||||
if opt.TeamDriveID == "" {
|
||||
return fs.ConfigConfirm("teamdrive_ok", false, "Configure this as a Shared Drive (Team Drive)?\n")
|
||||
return fs.ConfigConfirm("teamdrive_ok", false, "config_change_team_drive", "Configure this as a Shared Drive (Team Drive)?\n")
|
||||
}
|
||||
return fs.ConfigConfirm("teamdrive_ok", false, fmt.Sprintf("Change current Shared Drive (Team Drive) ID %q?\n", opt.TeamDriveID))
|
||||
return fs.ConfigConfirm("teamdrive_ok", false, "config_change_team_drive", fmt.Sprintf("Change current Shared Drive (Team Drive) ID %q?\n", opt.TeamDriveID))
|
||||
case "teamdrive_ok":
|
||||
if config.Result == "false" {
|
||||
m.Set("team_drive", "")
|
||||
@ -227,7 +227,7 @@ func init() {
|
||||
if len(teamDrives) == 0 {
|
||||
return fs.ConfigError("", "No Shared Drives found in your account")
|
||||
}
|
||||
return fs.ConfigChoose("teamdrive_final", "Shared Drive", len(teamDrives), func(i int) (string, string) {
|
||||
return fs.ConfigChoose("teamdrive_final", "config_team_drive", "Shared Drive", len(teamDrives), func(i int) (string, string) {
|
||||
teamDrive := teamDrives[i]
|
||||
return teamDrive.Id, teamDrive.Name
|
||||
})
|
||||
|
@ -98,7 +98,7 @@ func init() {
|
||||
})
|
||||
case "warning":
|
||||
// Warn the user as required by google photos integration
|
||||
return fs.ConfigConfirm("warning_done", true, `Warning
|
||||
return fs.ConfigConfirm("warning_done", true, "config_warning", `Warning
|
||||
|
||||
IMPORTANT: All media items uploaded to Google Photos with rclone
|
||||
are stored in full resolution at original quality. These uploads
|
||||
|
@ -126,7 +126,7 @@ func init() {
|
||||
func Config(ctx context.Context, name string, m configmap.Mapper, config fs.ConfigIn) (*fs.ConfigOut, error) {
|
||||
switch config.State {
|
||||
case "":
|
||||
return fs.ConfigChooseFixed("auth_type_done", `Authentication type`, []fs.OptionExample{{
|
||||
return fs.ConfigChooseFixed("auth_type_done", "config_type", `Authentication type`, []fs.OptionExample{{
|
||||
Value: "standard",
|
||||
Help: "Standard authentication - use this if you're a normal Jottacloud user.",
|
||||
}, {
|
||||
@ -141,7 +141,7 @@ func Config(ctx context.Context, name string, m configmap.Mapper, config fs.Conf
|
||||
return fs.ConfigGoto(config.Result)
|
||||
case "standard": // configure a jottacloud backend using the modern JottaCli token based authentication
|
||||
m.Set("configVersion", fmt.Sprint(configVersion))
|
||||
return fs.ConfigInput("standard_token", "Personal login token.\n\nGenerate here: https://www.jottacloud.com/web/secure")
|
||||
return fs.ConfigInput("standard_token", "config_login_token", "Personal login token.\n\nGenerate here: https://www.jottacloud.com/web/secure")
|
||||
case "standard_token":
|
||||
loginToken := config.Result
|
||||
m.Set(configClientID, "jottacli")
|
||||
@ -159,7 +159,7 @@ func Config(ctx context.Context, name string, m configmap.Mapper, config fs.Conf
|
||||
return fs.ConfigGoto("choose_device")
|
||||
case "legacy": // configure a jottacloud backend using legacy authentication
|
||||
m.Set("configVersion", fmt.Sprint(v1configVersion))
|
||||
return fs.ConfigConfirm("legacy_api", false, `Do you want to create a machine specific API key?
|
||||
return fs.ConfigConfirm("legacy_api", false, "config_machine_specific", `Do you want to create a machine specific API key?
|
||||
|
||||
Rclone has it's own Jottacloud API KEY which works fine as long as one
|
||||
only uses rclone on a single machine. When you want to use rclone with
|
||||
@ -177,10 +177,10 @@ machines.`)
|
||||
m.Set(configClientSecret, obscure.MustObscure(deviceRegistration.ClientSecret))
|
||||
fs.Debugf(nil, "Got clientID %q and clientSecret %q", deviceRegistration.ClientID, deviceRegistration.ClientSecret)
|
||||
}
|
||||
return fs.ConfigInput("legacy_user", "Username")
|
||||
return fs.ConfigInput("legacy_user", "config_user", "Username")
|
||||
case "legacy_username":
|
||||
m.Set(configUsername, config.Result)
|
||||
return fs.ConfigPassword("legacy_password", "Jottacloud password\n\n(this is only required during setup and will not be stored).")
|
||||
return fs.ConfigPassword("legacy_password", "config_password", "Jottacloud password\n\n(this is only required during setup and will not be stored).")
|
||||
case "legacy_password":
|
||||
m.Set("password", config.Result)
|
||||
m.Set("auth_code", "")
|
||||
@ -213,7 +213,7 @@ machines.`)
|
||||
|
||||
token, err := doAuthV1(ctx, srv, username, password, authCode)
|
||||
if err == errAuthCodeRequired {
|
||||
return fs.ConfigInput("legacy_auth_code", "Verification Code\nThis account uses 2 factor authentication you will receive a verification code via SMS.")
|
||||
return fs.ConfigInput("legacy_auth_code", "config_auth_code", "Verification Code\nThis account uses 2 factor authentication you will receive a verification code via SMS.")
|
||||
}
|
||||
m.Set("password", "")
|
||||
m.Set("auth_code", "")
|
||||
@ -241,7 +241,7 @@ machines.`)
|
||||
},
|
||||
})
|
||||
case "choose_device":
|
||||
return fs.ConfigConfirm("choose_device_query", false, "Use a non standard device/mountpoint e.g. for accessing files uploaded using the official Jottacloud client?")
|
||||
return fs.ConfigConfirm("choose_device_query", false, "config_non_standard", "Use a non standard device/mountpoint e.g. for accessing files uploaded using the official Jottacloud client?")
|
||||
case "choose_device_query":
|
||||
if config.Result != "true" {
|
||||
m.Set(configDevice, "")
|
||||
@ -265,7 +265,7 @@ machines.`)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return fs.ConfigChoose("choose_device_result", `Please select the device to use. Normally this will be Jotta`, len(acc.Devices), func(i int) (string, string) {
|
||||
return fs.ConfigChoose("choose_device_result", "config_device", `Please select the device to use. Normally this will be Jotta`, len(acc.Devices), func(i int) (string, string) {
|
||||
return acc.Devices[i].Name, ""
|
||||
})
|
||||
case "choose_device_result":
|
||||
@ -283,7 +283,7 @@ machines.`)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return fs.ConfigChoose("choose_device_mountpoint", `Please select the mountpoint to use. Normally this will be Archive.`, len(dev.MountPoints), func(i int) (string, string) {
|
||||
return fs.ConfigChoose("choose_device_mountpoint", "config_mountpoint", `Please select the mountpoint to use. Normally this will be Archive.`, len(dev.MountPoints), func(i int) (string, string) {
|
||||
return dev.MountPoints[i].Name, ""
|
||||
})
|
||||
case "choose_device_mountpoint":
|
||||
|
@ -363,7 +363,7 @@ func chooseDrive(ctx context.Context, name string, m configmap.Mapper, srv *rest
|
||||
if len(drives.Drives) == 0 {
|
||||
return fs.ConfigError("choose_type", "No drives found")
|
||||
}
|
||||
return fs.ConfigChoose("driveid_final", "Select drive you want to use", len(drives.Drives), func(i int) (string, string) {
|
||||
return fs.ConfigChoose("driveid_final", "config_driveid", "Select drive you want to use", len(drives.Drives), func(i int) (string, string) {
|
||||
drive := drives.Drives[i]
|
||||
return drive.DriveID, fmt.Sprintf("%s (%s)", drive.DriveName, drive.DriveType)
|
||||
})
|
||||
@ -388,7 +388,7 @@ func Config(ctx context.Context, name string, m configmap.Mapper, config fs.Conf
|
||||
OAuth2Config: oauthConfig,
|
||||
})
|
||||
case "choose_type":
|
||||
return fs.ConfigChooseFixed("choose_type_done", "Type of connection", []fs.OptionExample{{
|
||||
return fs.ConfigChooseFixed("choose_type_done", "config_type", "Type of connection", []fs.OptionExample{{
|
||||
Value: "onedrive",
|
||||
Help: "OneDrive Personal or Business",
|
||||
}, {
|
||||
@ -430,19 +430,19 @@ func Config(ctx context.Context, name string, m configmap.Mapper, config fs.Conf
|
||||
},
|
||||
})
|
||||
case "driveid":
|
||||
return fs.ConfigInput("driveid_end", "Drive ID")
|
||||
return fs.ConfigInput("driveid_end", "config_driveid_fixed", "Drive ID")
|
||||
case "driveid_end":
|
||||
return chooseDrive(ctx, name, m, srv, chooseDriveOpt{
|
||||
finalDriveID: config.Result,
|
||||
})
|
||||
case "siteid":
|
||||
return fs.ConfigInput("siteid_end", "Site ID")
|
||||
return fs.ConfigInput("siteid_end", "config_siteid", "Site ID")
|
||||
case "siteid_end":
|
||||
return chooseDrive(ctx, name, m, srv, chooseDriveOpt{
|
||||
siteID: config.Result,
|
||||
})
|
||||
case "url":
|
||||
return fs.ConfigInput("url_end", `Site URL
|
||||
return fs.ConfigInput("url_end", "config_site_url", `Site URL
|
||||
|
||||
Example: "https://contoso.sharepoint.com/sites/mysite" or "mysite"
|
||||
`)
|
||||
@ -459,13 +459,13 @@ Example: "https://contoso.sharepoint.com/sites/mysite" or "mysite"
|
||||
relativePath: "/sites/" + siteURL,
|
||||
})
|
||||
case "path":
|
||||
return fs.ConfigInput("path_end", `Server-relative URL`)
|
||||
return fs.ConfigInput("path_end", "config_sharepoint_url", `Server-relative URL`)
|
||||
case "path_end":
|
||||
return chooseDrive(ctx, name, m, srv, chooseDriveOpt{
|
||||
relativePath: config.Result,
|
||||
})
|
||||
case "search":
|
||||
return fs.ConfigInput("search_end", `Search term`)
|
||||
return fs.ConfigInput("search_end", "config_search_term", `Search term`)
|
||||
case "search_end":
|
||||
searchTerm := config.Result
|
||||
opts := rest.Opts{
|
||||
@ -483,7 +483,7 @@ Example: "https://contoso.sharepoint.com/sites/mysite" or "mysite"
|
||||
if len(sites.Sites) == 0 {
|
||||
return fs.ConfigError("choose_type", fmt.Sprintf("search for %q returned no results", searchTerm))
|
||||
}
|
||||
return fs.ConfigChoose("search_sites", `Select the Site you want to use`, len(sites.Sites), func(i int) (string, string) {
|
||||
return fs.ConfigChoose("search_sites", "config_site", `Select the Site you want to use`, len(sites.Sites), func(i int) (string, string) {
|
||||
site := sites.Sites[i]
|
||||
return site.SiteID, fmt.Sprintf("%s (%s)", site.SiteName, site.SiteURL)
|
||||
})
|
||||
@ -508,7 +508,7 @@ Example: "https://contoso.sharepoint.com/sites/mysite" or "mysite"
|
||||
m.Set(configDriveID, finalDriveID)
|
||||
m.Set(configDriveType, rootItem.ParentReference.DriveType)
|
||||
|
||||
return fs.ConfigConfirm("driveid_final_end", true, fmt.Sprintf("Drive OK?\n\nFound drive %q of type %q\nURL: %s\n", rootItem.Name, rootItem.ParentReference.DriveType, rootItem.WebURL))
|
||||
return fs.ConfigConfirm("driveid_final_end", true, "config_drive_ok", fmt.Sprintf("Drive OK?\n\nFound drive %q of type %q\nURL: %s\n", rootItem.Name, rootItem.ParentReference.DriveType, rootItem.WebURL))
|
||||
case "driveid_final_end":
|
||||
if config.Result == "true" {
|
||||
return nil, nil
|
||||
|
@ -327,7 +327,7 @@ func Config(ctx context.Context, name string, m configmap.Mapper, config fs.Conf
|
||||
case "":
|
||||
// Just make sure we do have a password
|
||||
if password == "" {
|
||||
return fs.ConfigPassword("", "Two-factor authentication: please enter your password (it won't be saved in the configuration)")
|
||||
return fs.ConfigPassword("", "config_password", "Two-factor authentication: please enter your password (it won't be saved in the configuration)")
|
||||
}
|
||||
return fs.ConfigGoto("password")
|
||||
case "password":
|
||||
@ -338,7 +338,7 @@ func Config(ctx context.Context, name string, m configmap.Mapper, config fs.Conf
|
||||
m.Set(configPassword, obscure.MustObscure(config.Result))
|
||||
return fs.ConfigGoto("2fa")
|
||||
case "2fa":
|
||||
return fs.ConfigInput("2fa_do", "Two-factor authentication: please enter your 2FA code")
|
||||
return fs.ConfigInput("2fa_do", "config_2fa", "Two-factor authentication: please enter your 2FA code")
|
||||
case "2fa_do":
|
||||
code := config.Result
|
||||
if code == "" {
|
||||
@ -358,10 +358,10 @@ func Config(ctx context.Context, name string, m configmap.Mapper, config fs.Conf
|
||||
|
||||
token, err := getAuthorizationToken(ctx, srv, username, password, code)
|
||||
if err != nil {
|
||||
return fs.ConfigConfirm("2fa_error", true, fmt.Sprintf("Authentication failed: %v\n\nTry Again?", err))
|
||||
return fs.ConfigConfirm("2fa_error", true, "config_retry", fmt.Sprintf("Authentication failed: %v\n\nTry Again?", err))
|
||||
}
|
||||
if token == "" {
|
||||
return fs.ConfigConfirm("2fa_error", true, "Authentication failed - no token returned.\n\nTry Again?")
|
||||
return fs.ConfigConfirm("2fa_error", true, "config_retry", "Authentication failed - no token returned.\n\nTry Again?")
|
||||
}
|
||||
// Let's save the token into the configuration
|
||||
m.Set(configAuthToken, token)
|
||||
|
@ -87,17 +87,17 @@ func init() {
|
||||
if opt.RefreshToken == "" {
|
||||
return fs.ConfigGoto("username")
|
||||
}
|
||||
return fs.ConfigConfirm("refresh", true, "Already have a token - refresh?")
|
||||
return fs.ConfigConfirm("refresh", true, "config_refresh", "Already have a token - refresh?")
|
||||
case "refresh":
|
||||
if config.Result == "false" {
|
||||
return nil, nil
|
||||
}
|
||||
return fs.ConfigGoto("username")
|
||||
case "username":
|
||||
return fs.ConfigInput("password", "username (email address)")
|
||||
return fs.ConfigInput("password", "config_username", "username (email address)")
|
||||
case "password":
|
||||
m.Set("username", config.Result)
|
||||
return fs.ConfigPassword("auth", "Your Sugarsync password.\n\nOnly required during setup and will not be stored.")
|
||||
return fs.ConfigPassword("auth", "config_password", "Your Sugarsync password.\n\nOnly required during setup and will not be stored.")
|
||||
case "auth":
|
||||
username, _ := m.Get("username")
|
||||
m.Set("username", "")
|
||||
|
@ -131,7 +131,7 @@ func init() {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return fs.ConfigChoose("workspace", "Team Drive ID", len(teams), func(i int) (string, string) {
|
||||
return fs.ConfigChoose("workspace", "config_team_drive_id", "Team Drive ID", len(teams), func(i int) (string, string) {
|
||||
team := teams[i]
|
||||
return team.ID, team.Attributes.Name
|
||||
})
|
||||
@ -145,7 +145,7 @@ func init() {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return fs.ConfigChoose("workspace_end", "Workspace ID", len(workspaces), func(i int) (string, string) {
|
||||
return fs.ConfigChoose("workspace_end", "config_workspace", "Workspace ID", len(workspaces), func(i int) (string, string) {
|
||||
workspace := workspaces[i]
|
||||
return workspace.ID, workspace.Attributes.Name
|
||||
})
|
||||
|
@ -25,7 +25,9 @@ var ConfigOAuth func(ctx context.Context, name string, m configmap.Mapper, ri *R
|
||||
|
||||
// ConfigIn is passed to the Config function for an Fs
|
||||
//
|
||||
// The interactive config system for backends is state based. This is so that different frontends to the config can be attached, eg over the API or web page.
|
||||
// The interactive config system for backends is state based. This is
|
||||
// so that different frontends to the config can be attached, eg over
|
||||
// the API or web page.
|
||||
//
|
||||
// Each call to the config system supplies ConfigIn which tells the
|
||||
// system what to do. Each will return a ConfigOut which gives a
|
||||
@ -47,6 +49,10 @@ var ConfigOAuth func(ctx context.Context, name string, m configmap.Mapper, ri *R
|
||||
//
|
||||
// The utilities here are convenience methods for different kinds of
|
||||
// questions and responses.
|
||||
//
|
||||
// Where the questions ask for a name then this should start with
|
||||
// "config_" to show it is an ephemeral config input rather than the
|
||||
// actual value stored in the config file.
|
||||
type ConfigIn struct {
|
||||
State string // State to run
|
||||
Result string // Result from previous Option
|
||||
@ -66,33 +72,42 @@ type ConfigOut struct {
|
||||
Result string // if Option/OAuth not set then this is passed to the next state
|
||||
}
|
||||
|
||||
// ConfigInput asks the user for a string
|
||||
// ConfigInputOptional asks the user for a string which may be empty
|
||||
//
|
||||
// state should be the next state required
|
||||
// name is the config name for this item
|
||||
// help should be the help shown to the user
|
||||
func ConfigInput(state string, help string) (*ConfigOut, error) {
|
||||
func ConfigInputOptional(state string, name string, help string) (*ConfigOut, error) {
|
||||
return &ConfigOut{
|
||||
State: state,
|
||||
Option: &Option{
|
||||
Name: name,
|
||||
Help: help,
|
||||
Default: "",
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ConfigInput asks the user for a non-empty string
|
||||
//
|
||||
// state should be the next state required
|
||||
// name is the config name for this item
|
||||
// help should be the help shown to the user
|
||||
func ConfigInput(state string, name string, help string) (*ConfigOut, error) {
|
||||
out, _ := ConfigInputOptional(state, name, help)
|
||||
out.Option.Required = true
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// ConfigPassword asks the user for a password
|
||||
//
|
||||
// state should be the next state required
|
||||
// name is the config name for this item
|
||||
// help should be the help shown to the user
|
||||
func ConfigPassword(state string, help string) (*ConfigOut, error) {
|
||||
return &ConfigOut{
|
||||
State: state,
|
||||
Option: &Option{
|
||||
Help: help,
|
||||
Default: "",
|
||||
IsPassword: true,
|
||||
},
|
||||
}, nil
|
||||
func ConfigPassword(state string, name string, help string) (*ConfigOut, error) {
|
||||
out, _ := ConfigInputOptional(state, name, help)
|
||||
out.Option.IsPassword = true
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// ConfigGoto goes to the next state with empty Result
|
||||
@ -130,11 +145,13 @@ func ConfigError(state string, Error string) (*ConfigOut, error) {
|
||||
//
|
||||
// state should be the next state required
|
||||
// Default should be the default state
|
||||
// name is the config name for this item
|
||||
// help should be the help shown to the user
|
||||
func ConfigConfirm(state string, Default bool, help string) (*ConfigOut, error) {
|
||||
func ConfigConfirm(state string, Default bool, name string, help string) (*ConfigOut, error) {
|
||||
return &ConfigOut{
|
||||
State: state,
|
||||
Option: &Option{
|
||||
Name: name,
|
||||
Help: help,
|
||||
Default: Default,
|
||||
Examples: []OptionExample{{
|
||||
@ -151,19 +168,21 @@ func ConfigConfirm(state string, Default bool, help string) (*ConfigOut, error)
|
||||
// ConfigChooseFixed returns a ConfigOut structure which has a list of items to choose from.
|
||||
//
|
||||
// state should be the next state required
|
||||
// name is the config name for this item
|
||||
// help should be the help shown to the user
|
||||
// items should be the items in the list
|
||||
//
|
||||
// It chooses the first item to be the default.
|
||||
// If there are no items then it will return an error.
|
||||
// If there is only one item it will short cut to the next state
|
||||
func ConfigChooseFixed(state string, help string, items []OptionExample) (*ConfigOut, error) {
|
||||
func ConfigChooseFixed(state string, name string, help string, items []OptionExample) (*ConfigOut, error) {
|
||||
if len(items) == 0 {
|
||||
return nil, errors.Errorf("no items found in: %s", help)
|
||||
}
|
||||
choose := &ConfigOut{
|
||||
State: state,
|
||||
Option: &Option{
|
||||
Name: name,
|
||||
Help: help,
|
||||
Examples: items,
|
||||
},
|
||||
@ -180,6 +199,7 @@ func ConfigChooseFixed(state string, help string, items []OptionExample) (*Confi
|
||||
// ConfigChoose returns a ConfigOut structure which has a list of items to choose from.
|
||||
//
|
||||
// state should be the next state required
|
||||
// name is the config name for this item
|
||||
// help should be the help shown to the user
|
||||
// n should be the number of items in the list
|
||||
// getItem should return the items (value, help)
|
||||
@ -187,12 +207,12 @@ func ConfigChooseFixed(state string, help string, items []OptionExample) (*Confi
|
||||
// It chooses the first item to be the default.
|
||||
// If there are no items then it will return an error.
|
||||
// If there is only one item it will short cut to the next state
|
||||
func ConfigChoose(state string, help string, n int, getItem func(i int) (itemValue string, itemHelp string)) (*ConfigOut, error) {
|
||||
func ConfigChoose(state string, name string, help string, n int, getItem func(i int) (itemValue string, itemHelp string)) (*ConfigOut, error) {
|
||||
items := make(OptionExamples, n)
|
||||
for i := range items {
|
||||
items[i].Value, items[i].Help = getItem(i)
|
||||
}
|
||||
return ConfigChooseFixed(state, help, items)
|
||||
return ConfigChooseFixed(state, name, help, items)
|
||||
}
|
||||
|
||||
// StatePush pushes a new values onto the front of the config string
|
||||
@ -237,21 +257,21 @@ func StatePop(state string) (newState string, value string) {
|
||||
// BackendConfig calls the config for the backend in ri
|
||||
//
|
||||
// It wraps any OAuth transactions as necessary so only straight forward config questions are emitted
|
||||
func BackendConfig(ctx context.Context, name string, m configmap.Mapper, ri *RegInfo, in ConfigIn) (*ConfigOut, error) {
|
||||
func BackendConfig(ctx context.Context, name string, m configmap.Mapper, ri *RegInfo, in ConfigIn) (out *ConfigOut, err error) {
|
||||
ci := GetConfig(ctx)
|
||||
if ri.Config == nil {
|
||||
return nil, nil
|
||||
}
|
||||
// Do internal states here
|
||||
if strings.HasPrefix(in.State, "*") {
|
||||
switch {
|
||||
case strings.HasPrefix(in.State, "*oauth"):
|
||||
return ConfigOAuth(ctx, name, m, ri, in)
|
||||
default:
|
||||
return nil, errors.Errorf("unknown internal state %q", in.State)
|
||||
}
|
||||
switch {
|
||||
case strings.HasPrefix(in.State, "*oauth"):
|
||||
// Do internal oauth states
|
||||
out, err = ConfigOAuth(ctx, name, m, ri, in)
|
||||
case strings.HasPrefix(in.State, "*"):
|
||||
err = errors.Errorf("unknown internal state %q", in.State)
|
||||
default:
|
||||
// Otherwise pass to backend
|
||||
out, err = ri.Config(ctx, name, m, in)
|
||||
}
|
||||
out, err := ri.Config(ctx, name, m, in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -267,11 +287,21 @@ func BackendConfig(ctx context.Context, name string, m configmap.Mapper, ri *Reg
|
||||
}
|
||||
// Run internal state, saving the input so we can recall the state
|
||||
return ConfigGoto(StatePush("", "*oauth", returnState, in.State, in.Result))
|
||||
case out.Option != nil && ci.AutoConfirm:
|
||||
case out.Option != nil:
|
||||
if out.Option.Name == "" {
|
||||
return nil, errors.New("internal error: no name set in Option")
|
||||
}
|
||||
// If override value is set in the config then use that
|
||||
if result, ok := m.Get(out.Option.Name); ok {
|
||||
Debugf(nil, "Override value found, choosing value %q for state %q", result, out.State)
|
||||
return ConfigResult(out.State, result)
|
||||
}
|
||||
// If AutoConfirm is set, choose the default value
|
||||
result := fmt.Sprint(out.Option.Default)
|
||||
Debugf(nil, "Auto confirm is set, choosing default %q for state %q", result, out.State)
|
||||
return ConfigResult(out.State, result)
|
||||
if ci.AutoConfirm {
|
||||
result := fmt.Sprint(out.Option.Default)
|
||||
Debugf(nil, "Auto confirm is set, choosing default %q for state %q", result, out.State)
|
||||
return ConfigResult(out.State, result)
|
||||
}
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
@ -245,7 +245,6 @@ func OkRemote(name string) bool {
|
||||
//
|
||||
// The is the user interface loop that drives the post configuration backend config.
|
||||
func PostConfig(ctx context.Context, name string, m configmap.Mapper, ri *fs.RegInfo) error {
|
||||
// FIXME if doing authorize, stop when we've got to the OAuth
|
||||
if ri.Config == nil {
|
||||
return errors.New("backend doesn't support reconnect or authorize")
|
||||
}
|
||||
@ -267,6 +266,7 @@ func PostConfig(ctx context.Context, name string, m configmap.Mapper, ri *fs.Reg
|
||||
in.State = out.State
|
||||
in.Result = out.Result
|
||||
if out.Option != nil {
|
||||
fs.Debugf(name, "config: reading config item named %q", out.Option.Name)
|
||||
if out.Option.Default == nil {
|
||||
out.Option.Default = ""
|
||||
}
|
||||
|
@ -455,14 +455,14 @@ func ConfigOAuth(ctx context.Context, name string, m configmap.Mapper, ri *fs.Re
|
||||
// See if already have a token
|
||||
tokenString, ok := m.Get("token")
|
||||
if ok && tokenString != "" {
|
||||
return fs.ConfigConfirm(newState("*oauth-confirm"), true, "Already have a token - refresh?")
|
||||
return fs.ConfigConfirm(newState("*oauth-confirm"), true, "config_refresh_token", "Already have a token - refresh?")
|
||||
}
|
||||
return fs.ConfigGoto(newState("*oauth-confirm"))
|
||||
case "*oauth-confirm":
|
||||
if in.Result == "false" {
|
||||
return fs.ConfigGoto(newState("*oauth-done"))
|
||||
}
|
||||
return fs.ConfigConfirm(newState("*oauth-islocal"), true, "Use auto config?\n * Say Y if not sure\n * Say N if you are working on a remote or headless machine\n")
|
||||
return fs.ConfigConfirm(newState("*oauth-islocal"), true, "config_is_local", "Use auto config?\n * Say Y if not sure\n * Say N if you are working on a remote or headless machine\n")
|
||||
case "*oauth-islocal":
|
||||
if in.Result == "true" {
|
||||
return fs.ConfigGoto(newState("*oauth-do"))
|
||||
@ -478,7 +478,7 @@ func ConfigOAuth(ctx context.Context, name string, m configmap.Mapper, ri *fs.Re
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return fs.ConfigInput(newState("*oauth-do"), fmt.Sprintf("Verification code\n\nGo to this URL, authenticate then paste the code here.\n\n%s\n", authURL))
|
||||
return fs.ConfigInput(newState("*oauth-do"), "config_verification_code", fmt.Sprintf("Verification code\n\nGo to this URL, authenticate then paste the code here.\n\n%s\n", authURL))
|
||||
}
|
||||
var out strings.Builder
|
||||
fmt.Fprintf(&out, `For this to work, you will need rclone available on a machine that has
|
||||
@ -508,7 +508,7 @@ version recommended):
|
||||
fmt.Fprintf(&out, "\trclone authorize %q\n", ri.Name)
|
||||
}
|
||||
fmt.Fprintln(&out, "\nThen paste the result.")
|
||||
return fs.ConfigInput(newState("*oauth-authorize"), out.String())
|
||||
return fs.ConfigInput(newState("*oauth-authorize"), "config_token", out.String())
|
||||
case "*oauth-authorize":
|
||||
// Read the updates to the config
|
||||
outM := configmap.Simple{}
|
||||
|
Loading…
Reference in New Issue
Block a user