From cdf12b1fc8b6890a018b43f27fecf8ac20078e87 Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Wed, 20 Mar 2019 11:33:25 +0000 Subject: [PATCH] crypt: Fix wrapping of ChangeNotify to decrypt directories properly Also change the way it is added to make the FsCheckWrap test pass --- backend/crypt/crypt.go | 47 ++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/backend/crypt/crypt.go b/backend/crypt/crypt.go index 4a798e6ec..609d41692 100644 --- a/backend/crypt/crypt.go +++ b/backend/crypt/crypt.go @@ -171,21 +171,6 @@ func NewFs(name, rpath string, m configmap.Mapper) (fs.Fs, error) { CanHaveEmptyDirectories: true, }).Fill(f).Mask(wrappedFs).WrapsFs(f, wrappedFs) - doChangeNotify := wrappedFs.Features().ChangeNotify - if doChangeNotify != nil { - f.features.ChangeNotify = func(notifyFunc func(string, fs.EntryType), pollInterval <-chan time.Duration) { - wrappedNotifyFunc := func(path string, entryType fs.EntryType) { - decrypted, err := f.DecryptFileName(path) - if err != nil { - fs.Logf(f, "ChangeNotify was unable to decrypt %q: %s", path, err) - return - } - notifyFunc(decrypted, entryType) - } - doChangeNotify(wrappedNotifyFunc, pollInterval) - } - } - return f, err } @@ -650,6 +635,38 @@ func (f *Fs) DirCacheFlush() { } } +// ChangeNotify calls the passed function with a path +// that has had changes. If the implementation +// uses polling, it should adhere to the given interval. +func (f *Fs) ChangeNotify(notifyFunc func(string, fs.EntryType), pollIntervalChan <-chan time.Duration) { + do := f.Fs.Features().ChangeNotify + if do == nil { + return + } + wrappedNotifyFunc := func(path string, entryType fs.EntryType) { + fs.Logf(f, "path %q entryType %d", path, entryType) + var ( + err error + decrypted string + ) + switch entryType { + case fs.EntryDirectory: + decrypted, err = f.cipher.DecryptDirName(path) + case fs.EntryObject: + decrypted, err = f.cipher.DecryptFileName(path) + default: + fs.Errorf(path, "crypt ChangeNotify: ignoring unknown EntryType %d", entryType) + return + } + if err != nil { + fs.Logf(f, "ChangeNotify was unable to decrypt %q: %s", path, err) + return + } + notifyFunc(decrypted, entryType) + } + do(wrappedNotifyFunc, pollIntervalChan) +} + // Object describes a wrapped for being read from the Fs // // This decrypts the remote name and decrypts the data