diff --git a/amazonclouddrive/amazonclouddrive.go b/amazonclouddrive/amazonclouddrive.go
index 00ed959e8..b440179af 100644
--- a/amazonclouddrive/amazonclouddrive.go
+++ b/amazonclouddrive/amazonclouddrive.go
@@ -31,8 +31,6 @@ import (
const (
rcloneClientID = "amzn1.application-oa2-client.6bf18d2d1f5b485c94c8988bb03ad0e7"
rcloneClientSecret = "k8/NyszKm5vEkZXAwsbGkd6C3NrbjIqMg4qEhIeF14Szub2wur+/teS3ubXgsLe9//+tr/qoqK+lq6mg8vWkoA=="
- bindAddress = "127.0.0.1:53682"
- redirectURL = "http://" + bindAddress + "/"
folderKind = "FOLDER"
fileKind = "FILE"
assetKind = "ASSET"
@@ -54,7 +52,7 @@ var (
},
ClientID: rcloneClientID,
ClientSecret: fs.Reveal(rcloneClientSecret),
- RedirectURL: redirectURL,
+ RedirectURL: oauthutil.RedirectURL,
}
)
@@ -64,7 +62,7 @@ func init() {
Name: "amazon cloud drive",
NewFs: NewFs,
Config: func(name string) {
- err := oauthutil.ConfigWithWebserver(name, acdConfig, bindAddress)
+ err := oauthutil.Config(name, acdConfig)
if err != nil {
log.Fatalf("Failed to configure token: %v", err)
}
diff --git a/docs/content/drive.md b/docs/content/drive.md
index 7e16414d2..f65e10923 100644
--- a/docs/content/drive.md
+++ b/docs/content/drive.md
@@ -1,7 +1,7 @@
---
title: "Google drive"
description: "Rclone docs for Google drive"
-date: "2015-05-10"
+date: "2015-09-12"
---
Google Drive
@@ -39,10 +39,16 @@ client_id>
Google Application Client Secret - leave blank to use rclone's.
client_secret>
Remote config
-Go to the following link in your browser
-https://accounts.google.com/o/oauth2/auth?access_type=&approval_prompt=&client_id=XXXXXXXXXXXX.apps.googleusercontent.com&redirect_uri=urn%3XXXXX%3Awg%3Aoauth%3XX.0%3Aoob&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive&state=state
-Log in, then type paste the token that is returned in the browser here
-Enter verification code> X/XXXXXXXXXXXXXXXXXX-XXXXXXXXX.XXXXXXXXX-XXXXX_XXXXXXX_XXXXXXX
+Use auto config?
+ * Say Y if not sure
+ * Say N if you are working on a remote or headless machine
+y) Yes
+n) No
+y/n> y
+If your browser doesn't open automatically go to the following link: http://127.0.0.1:53682/auth
+Log in and authorize rclone for access
+Waiting for code...
+Got code
--------------------
[remote]
client_id =
@@ -55,6 +61,13 @@ d) Delete this remote
y/e/d> y
```
+Note that rclone runs a webserver on your local machine to collect the
+token as returned from Google if you use auto config mode. This only
+runs from the moment it opens your browser to the moment you get back
+the verification code. This is on `http://127.0.0.1:53682/` and this
+it may require you to unblock it temporarily if you are running a host
+firewall, or use manual mode.
+
You can then use it like this,
List directories in top level of your drive
diff --git a/docs/content/googlecloudstorage.md b/docs/content/googlecloudstorage.md
index 6f15fe8d6..5de71ffbb 100644
--- a/docs/content/googlecloudstorage.md
+++ b/docs/content/googlecloudstorage.md
@@ -1,7 +1,7 @@
---
title: "Google Cloud Storage"
description: "Rclone docs for Google Cloud Storage"
-date: "2014-07-17"
+date: "2015-09-12"
---
Google Cloud Storage
@@ -70,10 +70,17 @@ Choose a number from below, or type in your own value
5) publicReadWrite
bucket_acl> 2
Remote config
-Go to the following link in your browser
-https://accounts.google.com/o/oauth2/auth?access_type=&approval_prompt=&client_id=XXXXXXXXXXXX.apps.googleusercontent.com&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdevstorage.full_control&state=state
-Log in, then type paste the token that is returned in the browser here
-Enter verification code> x/xxxxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxx_xxxxxxxx
+Remote config
+Use auto config?
+ * Say Y if not sure
+ * Say N if you are working on a remote or headless machine
+y) Yes
+n) No
+y/n> y
+If your browser doesn't open automatically go to the following link: http://127.0.0.1:53682/auth
+Log in and authorize rclone for access
+Waiting for code...
+Got code
--------------------
[remote]
type = google cloud storage
@@ -90,6 +97,13 @@ d) Delete this remote
y/e/d> y
```
+Note that rclone runs a webserver on your local machine to collect the
+token as returned from Google if you use auto config mode. This only
+runs from the moment it opens your browser to the moment you get back
+the verification code. This is on `http://127.0.0.1:53682/` and this
+it may require you to unblock it temporarily if you are running a host
+firewall, or use manual mode.
+
This remote is called `remote` and can now be used like this
See all the buckets in your project
diff --git a/oauthutil/oauthutil.go b/oauthutil/oauthutil.go
index 3fb851b1a..696a683b1 100644
--- a/oauthutil/oauthutil.go
+++ b/oauthutil/oauthutil.go
@@ -15,13 +15,21 @@ import (
"golang.org/x/oauth2"
)
-// configKey is the key used to store the token under
-const configKey = "token"
+const (
+ // configKey is the key used to store the token under
+ configKey = "token"
-// TitleBarRedirectURL is the OAuth2 redirect URL to use when the authorization
-// code should be returned in the title bar of the browser, with the page text
-// prompting the user to copy the code and paste it in the application.
-const TitleBarRedirectURL = "urn:ietf:wg:oauth:2.0:oob"
+ // TitleBarRedirectURL is the OAuth2 redirect URL to use when the authorization
+ // code should be returned in the title bar of the browser, with the page text
+ // prompting the user to copy the code and paste it in the application.
+ TitleBarRedirectURL = "urn:ietf:wg:oauth:2.0:oob"
+
+ // BindAddress is binding for local webserver when active
+ bindAddress = "127.0.0.1:53682"
+
+ // RedirectURL is redirect to local webserver when active
+ RedirectURL = "http://" + bindAddress + "/"
+)
// oldToken contains an end-user's tokens.
// This is the data you must store to persist authentication.
@@ -144,8 +152,8 @@ func NewClient(name string, config *oauth2.Config) (*http.Client, error) {
// Config does the initial creation of the token
//
-// It runs an internal webserver to receive the results
-func ConfigWithWebserver(name string, config *oauth2.Config, bindAddress string) error {
+// It may run an internal webserver to receive the results
+func Config(name string, config *oauth2.Config) error {
// See if already have a token
tokenString := fs.ConfigFile.MustValue(name, "token")
if tokenString != "" {
@@ -155,6 +163,22 @@ func ConfigWithWebserver(name string, config *oauth2.Config, bindAddress string)
}
}
+ // Detect whether we should use internal web server
+ useWebServer := false
+ switch config.RedirectURL {
+ case RedirectURL:
+ useWebServer = true
+ case TitleBarRedirectURL:
+ fmt.Printf("Use auto config?\n")
+ fmt.Printf(" * Say Y if not sure\n")
+ fmt.Printf(" * Say N if you are working on a remote or headless machine\n")
+ useWebServer = fs.Confirm()
+ // copy the config and set to use the internal webserver
+ configCopy := *config
+ config = &configCopy
+ config.RedirectURL = RedirectURL
+ }
+
// Make random state
stateBytes := make([]byte, 16)
_, err := rand.Read(stateBytes)
@@ -170,7 +194,7 @@ func ConfigWithWebserver(name string, config *oauth2.Config, bindAddress string)
bindAddress: bindAddress,
authUrl: authUrl,
}
- if bindAddress != "" {
+ if useWebServer {
server.code = make(chan string, 1)
go server.Start()
defer server.Stop()
@@ -183,7 +207,7 @@ func ConfigWithWebserver(name string, config *oauth2.Config, bindAddress string)
fmt.Printf("Log in and authorize rclone for access\n")
var authCode string
- if bindAddress != "" {
+ if useWebServer {
// Read the code, and exchange it for a token.
fmt.Printf("Waiting for code...\n")
authCode = <-server.code
@@ -204,11 +228,6 @@ func ConfigWithWebserver(name string, config *oauth2.Config, bindAddress string)
return putToken(name, token)
}
-// Config does the initial creation of the token
-func Config(name string, config *oauth2.Config) error {
- return ConfigWithWebserver(name, config, "")
-}
-
// Local web server for collecting auth
type authServer struct {
state string