Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Rclone patch for supporting 21Vianet version of OneDrive
diff --git a/backend/onedrive/onedrive.go b/backend/onedrive/onedrive.go
index b64d68263..1d73d8231 100644
--- a/backend/onedrive/onedrive.go
+++ b/backend/onedrive/onedrive.go
@@ -43,7 +43,10 @@ const (
minSleep = 10 * time.Millisecond
maxSleep = 2 * time.Second
decayConstant = 2 // bigger for slower decay, exponential
- graphURL = "https://graph.microsoft.com/v1.0"
+ graphAPIEndpoint = "https://graph.microsoft.com"
+ authEndpoint = "https://login.microsoftonline.com"
+ graphAPIEndpoint21V = "https://microsoftgraph.chinacloudapi.cn"
+ authEndpoint21V = "https://login.chinacloudapi.cn"
configDriveID = "drive_id"
configDriveType = "drive_type"
driveTypePersonal = "personal"
@@ -56,11 +59,15 @@ const (
// Globals
var (
// Description of how to auth for this app for a business account
+ oauthEndpoint = &oauth2.Endpoint{
+ AuthURL: authEndpoint + "/common/oauth2/v2.0/authorize",
+ TokenURL: authEndpoint + "/common/oauth2/v2.0/token",
+ }
+ oauthEndpointV21 = &oauth2.Endpoint{
+ AuthURL: authEndpoint21V + "/common/oauth2/v2.0/authorize",
+ TokenURL: authEndpoint21V + "/common/oauth2/v2.0/token",
+ }
oauthConfig = &oauth2.Config{
- Endpoint: oauth2.Endpoint{
- AuthURL: "https://login.microsoftonline.com/common/oauth2/v2.0/authorize",
- TokenURL: "https://login.microsoftonline.com/common/oauth2/v2.0/token",
- },
Scopes: []string{"Files.Read", "Files.ReadWrite", "Files.Read.All", "Files.ReadWrite.All", "offline_access"},
ClientID: rcloneClientID,
ClientSecret: obscure.MustReveal(rcloneEncryptedClientSecret),
@@ -79,8 +86,22 @@ func init() {
Description: "Microsoft OneDrive",
NewFs: NewFs,
Config: func(name string, m configmap.Mapper) {
+ opt := new(Options)
+ err := configstruct.Set(m, opt)
+ if err != nil {
+ fs.Errorf(nil, "Couldn't parse config into struct: %v", err)
+ return
+ }
+
+ graphURL := graphAPIEndpoint + "/v1.0"
+ oauthConfig.Endpoint = *oauthEndpoint
+ if opt.Is21Vianet {
+ graphURL = graphAPIEndpoint21V + "/v1.0"
+ oauthConfig.Endpoint = *oauthEndpointV21
+ }
+
ctx := context.TODO()
- err := oauthutil.Config("onedrive", name, m, oauthConfig)
+ err = oauthutil.Config("onedrive", name, m, oauthConfig)
if err != nil {
log.Fatalf("Failed to configure token: %v", err)
return
@@ -223,6 +244,10 @@ func init() {
}, {
Name: config.ConfigClientSecret,
Help: "Microsoft App Client Secret\nLeave blank normally.",
+ }, {
+ Name: "is_21vianet_version",
+ Default: false,
+ Help: "OneDrive operated by 21Vianet (世纪互联).",
}, {
Name: "chunk_size",
Help: `Chunk size to upload files with - must be multiple of 320k (327,680 bytes).
@@ -258,6 +283,7 @@ listing, set this option.`,
// Options defines the configuration for this backend
type Options struct {
+ Is21Vianet bool `config:"is_21vianet_version"`
ChunkSize fs.SizeSuffix `config:"chunk_size"`
DriveID string `config:"drive_id"`
DriveType string `config:"drive_type"`
@@ -494,6 +520,13 @@ func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
return nil, errors.New("unable to get drive_id and drive_type - if you are upgrading from older versions of rclone, please run `rclone config` and re-configure this backend")
}
+ rootURL := graphAPIEndpoint + "/v1.0" + "/drives/" + opt.DriveID
+ oauthConfig.Endpoint = *oauthEndpoint
+ if opt.Is21Vianet {
+ rootURL = graphAPIEndpoint21V + "/v1.0" + "/me/drive"
+ oauthConfig.Endpoint = *oauthEndpointV21
+ }
+
root = parsePath(root)
oAuthClient, ts, err := oauthutil.NewClient(name, m, oauthConfig)
if err != nil {
@@ -506,7 +539,7 @@ func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
opt: *opt,
driveID: opt.DriveID,
driveType: opt.DriveType,
- srv: rest.NewClient(oAuthClient).SetRoot(graphURL + "/drives/" + opt.DriveID),
+ srv: rest.NewClient(oAuthClient).SetRoot(rootURL),
pacer: fs.NewPacer(pacer.NewDefault(pacer.MinSleep(minSleep), pacer.MaxSleep(maxSleep), pacer.DecayConstant(decayConstant))),
}
f.features = (&fs.Features{
@@ -1705,7 +1738,8 @@ func newOptsCall(normalizedID string, method string, route string) (opts rest.Op
func parseNormalizedID(ID string) (string, string, string) {
if strings.Index(ID, "#") >= 0 {
s := strings.Split(ID, "#")
- return s[1], s[0], graphURL + "/drives"
+ // return s[1], s[0], graphURL + "/drives"
+ return s[1], "", ""
}
return ID, "", ""
}
@xytoki

This comment has been minimized.

Copy link

xytoki commented Feb 7, 2020

could this be merged into official rclone?it would be great.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.