drive: make sure invalid auth for teamdrives always reports an error
For some reason Google doesn't return an error if you use a service account with the wrong permissions to list a team drive. This gives the user the false impression that the drive is empty. This change: - calls teamdrives get on rclone about - calls teamdrives get on a listing of the root which returned no entries These will both detect a team drive which has the incorrect auth and workaround the issue. Fixes: #3763 See: https://forum.rclone.org/t/rclone-missing-error-code-when-sas-have-no-permission/13086 See: https://forum.rclone.org/t/need-need-bug-verification-rclone-about-doesnt-work-on-teamdrives-empty-output/13105
This commit is contained in:
parent
33c80bbb96
commit
d3b0bed091
1 changed files with 46 additions and 1 deletions
|
@ -1480,6 +1480,14 @@ func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err e
|
||||||
if iErr != nil {
|
if iErr != nil {
|
||||||
return nil, iErr
|
return nil, iErr
|
||||||
}
|
}
|
||||||
|
// If listing the root of a teamdrive and got no entries,
|
||||||
|
// double check we have access
|
||||||
|
if f.isTeamDrive && len(entries) == 0 && f.root == "" && dir == "" {
|
||||||
|
err = f.teamDriveOK(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
return entries, nil
|
return entries, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1617,6 +1625,7 @@ func (f *Fs) ListR(ctx context.Context, dir string, callback fs.ListRCallback) (
|
||||||
out := make(chan error, fs.Config.Checkers)
|
out := make(chan error, fs.Config.Checkers)
|
||||||
list := walk.NewListRHelper(callback)
|
list := walk.NewListRHelper(callback)
|
||||||
overflow := []listREntry{}
|
overflow := []listREntry{}
|
||||||
|
listed := 0
|
||||||
|
|
||||||
cb := func(entry fs.DirEntry) error {
|
cb := func(entry fs.DirEntry) error {
|
||||||
mu.Lock()
|
mu.Lock()
|
||||||
|
@ -1629,6 +1638,7 @@ func (f *Fs) ListR(ctx context.Context, dir string, callback fs.ListRCallback) (
|
||||||
overflow = append(overflow, listREntry{d.ID(), d.Remote()})
|
overflow = append(overflow, listREntry{d.ID(), d.Remote()})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
listed++
|
||||||
return list.Add(entry)
|
return list.Add(entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1685,7 +1695,21 @@ func (f *Fs) ListR(ctx context.Context, dir string, callback fs.ListRCallback) (
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return list.Flush()
|
err = list.Flush()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// If listing the root of a teamdrive and got no entries,
|
||||||
|
// double check we have access
|
||||||
|
if f.isTeamDrive && listed == 0 && f.root == "" && dir == "" {
|
||||||
|
err = f.teamDriveOK(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// itemToDirEntry converts a drive.File to a fs.DirEntry.
|
// itemToDirEntry converts a drive.File to a fs.DirEntry.
|
||||||
|
@ -2058,9 +2082,30 @@ func (f *Fs) CleanUp(ctx context.Context) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// teamDriveOK checks to see if we can access the team drive
|
||||||
|
func (f *Fs) teamDriveOK(ctx context.Context) (err error) {
|
||||||
|
if !f.isTeamDrive {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
var td *drive.Drive
|
||||||
|
err = f.pacer.Call(func() (bool, error) {
|
||||||
|
td, err = f.svc.Drives.Get(f.opt.TeamDriveID).Fields("name,id,capabilities,createdTime,restrictions").Context(ctx).Do()
|
||||||
|
return shouldRetry(err)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "failed to get Team/Shared Drive info")
|
||||||
|
}
|
||||||
|
fs.Debugf(f, "read info from team drive %q", td.Name)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// About gets quota information
|
// About gets quota information
|
||||||
func (f *Fs) About(ctx context.Context) (*fs.Usage, error) {
|
func (f *Fs) About(ctx context.Context) (*fs.Usage, error) {
|
||||||
if f.isTeamDrive {
|
if f.isTeamDrive {
|
||||||
|
err := f.teamDriveOK(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
// Teamdrives don't appear to have a usage API so just return empty
|
// Teamdrives don't appear to have a usage API so just return empty
|
||||||
return &fs.Usage{}, nil
|
return &fs.Usage{}, nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue