Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support GCD impersonation via modified service account file #612

Merged
merged 1 commit into from Mar 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
29 changes: 25 additions & 4 deletions src/duplicacy_gcdstorage.go
Expand Up @@ -41,6 +41,7 @@ type GCDStorage struct {
backoffs []int // desired backoff time in seconds for each thread
attempts []int // number of failed attempts since last success for each thread
driveID string // the ID of the shared drive or 'root' (GCDUserDrive) if the user's drive
spaces string // 'appDataFolder' if scope is drive.appdata; 'drive' otherwise

createDirectoryLock sync.Mutex
isConnected bool
Expand Down Expand Up @@ -199,7 +200,7 @@ func (storage *GCDStorage) listFiles(threadIndex int, parentID string, listFiles
var err error

for {
q := storage.service.Files.List().Q(query).Fields("nextPageToken", "files(name, mimeType, id, size)").PageToken(startToken).PageSize(maxCount)
q := storage.service.Files.List().Q(query).Fields("nextPageToken", "files(name, mimeType, id, size)").PageToken(startToken).PageSize(maxCount).Spaces(storage.spaces)
if storage.driveID != GCDUserDrive {
q = q.DriveId(storage.driveID).IncludeItemsFromAllDrives(true).Corpora("drive").SupportsAllDrives(true)
}
Expand Down Expand Up @@ -231,7 +232,7 @@ func (storage *GCDStorage) listByName(threadIndex int, parentID string, name str

for {
query := "name = '" + name + "' and '" + parentID + "' in parents and trashed = false "
q := storage.service.Files.List().Q(query).Fields("files(name, mimeType, id, size)")
q := storage.service.Files.List().Q(query).Fields("files(name, mimeType, id, size)").Spaces(storage.spaces)
if storage.driveID != GCDUserDrive {
q = q.DriveId(storage.driveID).IncludeItemsFromAllDrives(true).Corpora("drive").SupportsAllDrives(true)
}
Expand Down Expand Up @@ -344,11 +345,23 @@ func CreateGCDStorage(tokenFile string, driveID string, storagePath string, thre

var tokenSource oauth2.TokenSource

scope := drive.DriveScope

if isServiceAccount {
config, err := google.JWTConfigFromJSON(description, drive.DriveScope)

if newScope, ok := object["scope"]; ok {
scope = newScope.(string)
}

config, err := google.JWTConfigFromJSON(description, scope)
if err != nil {
return nil, err
}

if subject, ok := object["subject"]; ok {
config.Subject = subject.(string)
}

tokenSource = config.TokenSource(ctx)
} else {
gcdConfig := &GCDConfig{}
Expand Down Expand Up @@ -398,14 +411,22 @@ func CreateGCDStorage(tokenFile string, driveID string, storagePath string, thre
backoffs: make([]int, threads),
attempts: make([]int, threads),
driveID: driveID,
spaces: "drive",
}

for i := range storage.backoffs {
storage.backoffs[i] = 1
storage.attempts[i] = 0
}

storage.savePathID("", driveID)

if scope == drive.DriveAppdataScope {
storage.spaces = "appDataFolder"
storage.savePathID("", "appDataFolder")
} else {
storage.savePathID("", driveID)
}

storagePathID, err := storage.getIDFromPath(0, storagePath, true)
if err != nil {
return nil, err
Expand Down
4 changes: 4 additions & 0 deletions src/duplicacy_storage_test.go
Expand Up @@ -142,6 +142,10 @@ func loadStorage(localStoragePath string, threads int) (Storage, error) {
storage, err := CreateGCDStorage(config["token_file"], config["drive"], config["storage_path"], threads)
storage.SetDefaultNestingLevels([]int{2, 3}, 2)
return storage, err
} else if testStorageName == "gcd-impersonate" {
storage, err := CreateGCDStorage(config["token_file"], config["drive"], config["storage_path"], threads)
storage.SetDefaultNestingLevels([]int{2, 3}, 2)
return storage, err
} else if testStorageName == "one" {
storage, err := CreateOneDriveStorage(config["token_file"], false, config["storage_path"], threads)
storage.SetDefaultNestingLevels([]int{2, 3}, 2)
Expand Down