From b8280521a5cc4bce22442b3b17f67ec9980eb3c9 Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Sat, 5 Jan 2019 20:53:42 +0000 Subject: [PATCH] drive: supply correct scopes to when using --drive-impersonate This fixes using --drive-impersonate and appfolders. --- backend/drive/drive.go | 42 ++++++++++++++++++++-------- backend/drive/drive_internal_test.go | 25 +++++++++++++++++ 2 files changed, 56 insertions(+), 11 deletions(-) diff --git a/backend/drive/drive.go b/backend/drive/drive.go index 46cfd3625..a8c2cea53 100644 --- a/backend/drive/drive.go +++ b/backend/drive/drive.go @@ -125,6 +125,29 @@ var ( _linkTemplates map[string]*template.Template // available link types ) +// Parse the scopes option returning a slice of scopes +func driveScopes(scopesString string) (scopes []string) { + if scopesString == "" { + scopesString = defaultScope + } + for _, scope := range strings.Split(scopesString, ",") { + scope = strings.TrimSpace(scope) + scopes = append(scopes, scopePrefix+scope) + } + return scopes +} + +// Returns true if one of the scopes was "drive.appfolder" +func driveScopesContainsAppFolder(scopes []string) bool { + for _, scope := range scopes { + if scope == scopePrefix+"drive.appfolder" { + return true + } + + } + return false +} + // Register with Fs func init() { fs.Register(&fs.RegInfo{ @@ -139,18 +162,14 @@ func init() { fs.Errorf(nil, "Couldn't parse config into struct: %v", err) return } + // Fill in the scopes - if opt.Scope == "" { - opt.Scope = defaultScope - } - driveConfig.Scopes = nil - for _, scope := range strings.Split(opt.Scope, ",") { - driveConfig.Scopes = append(driveConfig.Scopes, scopePrefix+strings.TrimSpace(scope)) - // Set the root_folder_id if using drive.appfolder - if scope == "drive.appfolder" { - m.Set("root_folder_id", "appDataFolder") - } + driveConfig.Scopes = driveScopes(opt.Scope) + // Set the root_folder_id if using drive.appfolder + if driveScopesContainsAppFolder(driveConfig.Scopes) { + m.Set("root_folder_id", "appDataFolder") } + if opt.ServiceAccountFile == "" { err = oauthutil.Config("drive", name, m, driveConfig) if err != nil { @@ -756,7 +775,8 @@ func newPacer() *pacer.Pacer { } func getServiceAccountClient(opt *Options, credentialsData []byte) (*http.Client, error) { - conf, err := google.JWTConfigFromJSON(credentialsData, driveConfig.Scopes...) + scopes := driveScopes(opt.Scope) + conf, err := google.JWTConfigFromJSON(credentialsData, scopes...) if err != nil { return nil, errors.Wrap(err, "error processing credentials") } diff --git a/backend/drive/drive_internal_test.go b/backend/drive/drive_internal_test.go index e894f9a3f..c1b9108f8 100644 --- a/backend/drive/drive_internal_test.go +++ b/backend/drive/drive_internal_test.go @@ -22,6 +22,31 @@ import ( "google.golang.org/api/drive/v3" ) +func TestDriveScopes(t *testing.T) { + for _, test := range []struct { + in string + want []string + wantFlag bool + }{ + {"", []string{ + "https://www.googleapis.com/auth/drive", + }, false}, + {" drive.file , drive.readonly", []string{ + "https://www.googleapis.com/auth/drive.file", + "https://www.googleapis.com/auth/drive.readonly", + }, false}, + {" drive.file , drive.appfolder", []string{ + "https://www.googleapis.com/auth/drive.file", + "https://www.googleapis.com/auth/drive.appfolder", + }, true}, + } { + got := driveScopes(test.in) + assert.Equal(t, test.want, got, test.in) + gotFlag := driveScopesContainsAppFolder(got) + assert.Equal(t, test.wantFlag, gotFlag, test.in) + } +} + /* var additionalMimeTypes = map[string]string{ "application/vnd.ms-excel.sheet.macroenabled.12": ".xlsm",