forked from TrueCloudLab/rclone
onedrive: Removed second browser authentication and enabled headless mode #254
This commit is contained in:
parent
113f43ec42
commit
f91f89d409
2 changed files with 77 additions and 21 deletions
|
@ -114,7 +114,7 @@ To copy a local directory to an OneDrive directory called backup
|
||||||
|
|
||||||
### OneDrive for Business ###
|
### OneDrive for Business ###
|
||||||
|
|
||||||
There is experimental support for OneDrive for Business.
|
There is additional support for OneDrive for Business.
|
||||||
Select "b" when ask
|
Select "b" when ask
|
||||||
```
|
```
|
||||||
Choose OneDrive account type?
|
Choose OneDrive account type?
|
||||||
|
@ -124,10 +124,8 @@ b) Business
|
||||||
p) Personal
|
p) Personal
|
||||||
b/p>
|
b/p>
|
||||||
```
|
```
|
||||||
After that rclone requires two authentications. First to authenicate your account
|
After that rclone requires an authentication of your account. The application will first authenticate your account, then query the OneDrive resource URL
|
||||||
and second to get the final token to access your companies resources.
|
and do a second (silent) authentication for this resource URL.
|
||||||
|
|
||||||
Headless authentication is not working at the moment.
|
|
||||||
|
|
||||||
### Modified time and hashes ###
|
### Modified time and hashes ###
|
||||||
|
|
||||||
|
|
|
@ -91,9 +91,16 @@ func init() {
|
||||||
log.Fatalf("Failed to configure token: %v", err)
|
log.Fatalf("Failed to configure token: %v", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
err := oauthutil.Config("onedrivebusiness", name, oauthBusinessConfig, oauthBusinessResource)
|
err := oauthutil.Config("onedrive", name, oauthBusinessConfig, oauthBusinessResource)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to configure token: %v", err)
|
log.Fatalf("Failed to configure token: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Are we running headless?
|
||||||
|
if fs.ConfigFileGet(name, fs.ConfigAutomatic) != "" {
|
||||||
|
// Yes, okay we are done
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
type serviceResource struct {
|
type serviceResource struct {
|
||||||
|
@ -108,43 +115,94 @@ func init() {
|
||||||
oAuthClient, _, err := oauthutil.NewClient(name, oauthBusinessConfig)
|
oAuthClient, _, err := oauthutil.NewClient(name, oauthBusinessConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to configure OneDrive: %v", err)
|
log.Fatalf("Failed to configure OneDrive: %v", err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
srv := rest.NewClient(oAuthClient).SetRoot(discoveryServiceURL)
|
srv := rest.NewClient(oAuthClient)
|
||||||
|
|
||||||
opts := rest.Opts{
|
opts := rest.Opts{
|
||||||
Method: "GET",
|
Method: "GET",
|
||||||
Path: "/v2.0/me/services",
|
RootURL: discoveryServiceURL,
|
||||||
|
Path: "/v2.0/me/services",
|
||||||
}
|
}
|
||||||
services := serviceResponse{}
|
services := serviceResponse{}
|
||||||
resp, err := srv.CallJSON(&opts, nil, &services)
|
resp, err := srv.CallJSON(&opts, nil, &services)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to query available services: %v", err)
|
fs.Errorf(nil, "Failed to query available services: %v", err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
if resp.StatusCode != 200 {
|
if resp.StatusCode != 200 {
|
||||||
log.Fatalf("Failed to query available services: Got HTTP error code %d", resp.StatusCode)
|
fs.Errorf(nil, "Failed to query available services: Got HTTP error code %d", resp.StatusCode)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
foundService := false
|
foundService := ""
|
||||||
for _, service := range services.Services {
|
for _, service := range services.Services {
|
||||||
if service.ServiceAPIVersion == "v2.0" {
|
if service.ServiceAPIVersion == "v2.0" {
|
||||||
foundService = true
|
foundService = service.ServiceResourceID
|
||||||
fs.ConfigFileSet(name, configResourceURL, service.ServiceResourceID)
|
fs.ConfigFileSet(name, configResourceURL, foundService)
|
||||||
oauthBusinessResource = oauth2.SetAuthURLParam("resource", service.ServiceResourceID)
|
oauthBusinessResource = oauth2.SetAuthURLParam("resource", foundService)
|
||||||
|
|
||||||
fs.Logf(nil, "Found API %s endpoint %s", service.ServiceAPIVersion, service.ServiceEndpointURI)
|
fs.Logf(nil, "Found API %s endpoint %s", service.ServiceAPIVersion, service.ServiceEndpointURI)
|
||||||
|
break
|
||||||
}
|
}
|
||||||
// we only support 2.0 API
|
// we only support 2.0 API
|
||||||
fs.Logf(nil, "Skipping API %s endpoint %s", service.ServiceAPIVersion, service.ServiceEndpointURI)
|
fs.Infof(nil, "Skipping API %s endpoint %s", service.ServiceAPIVersion, service.ServiceEndpointURI)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !foundService {
|
if foundService == "" {
|
||||||
log.Fatalf("No Service found")
|
fs.Errorf(nil, "No Service found")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
fs.ConfigFileDeleteKey(name, fs.ConfigToken)
|
// get the token from the inital config
|
||||||
err = oauthutil.Config("onedrivebusiness", name, oauthBusinessConfig, oauthBusinessResource)
|
// we need to update the token with a resource
|
||||||
|
// specific token we will query now
|
||||||
|
token, err := oauthutil.GetToken(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to configure token: %v", err)
|
fs.Errorf(nil, "Error while getting token: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// values for the token query
|
||||||
|
values := url.Values{}
|
||||||
|
values.Set("refresh_token", token.RefreshToken)
|
||||||
|
values.Set("grant_type", "refresh_token")
|
||||||
|
values.Set("resource", foundService)
|
||||||
|
values.Set("client_id", oauthBusinessConfig.ClientID)
|
||||||
|
values.Set("client_secret", oauthBusinessConfig.ClientSecret)
|
||||||
|
opts = rest.Opts{
|
||||||
|
Method: "POST",
|
||||||
|
RootURL: oauthBusinessConfig.Endpoint.TokenURL,
|
||||||
|
ContentType: "application/x-www-form-urlencoded",
|
||||||
|
Body: strings.NewReader(values.Encode()),
|
||||||
|
}
|
||||||
|
|
||||||
|
// tokenJSON is the struct representing the HTTP response from OAuth2
|
||||||
|
// providers returning a token in JSON form.
|
||||||
|
// we are only interested in the new tokens, all other fields we don't care
|
||||||
|
type tokenJSON struct {
|
||||||
|
AccessToken string `json:"access_token"`
|
||||||
|
RefreshToken string `json:"refresh_token"`
|
||||||
|
}
|
||||||
|
jsonToken := tokenJSON{}
|
||||||
|
resp, err = srv.CallJSON(&opts, nil, &jsonToken)
|
||||||
|
if err != nil {
|
||||||
|
fs.Errorf(nil, "Failed to get resource token: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
fs.Errorf(nil, "Failed to get resource token: Got HTTP error code %d", resp.StatusCode)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// update the tokens
|
||||||
|
token.AccessToken = jsonToken.AccessToken
|
||||||
|
token.RefreshToken = jsonToken.RefreshToken
|
||||||
|
|
||||||
|
// finally save them in the config
|
||||||
|
err = oauthutil.PutToken(name, token, true)
|
||||||
|
if err != nil {
|
||||||
|
fs.Errorf(nil, "Error while setting token: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue