diff --git a/backend/cache/cache.go b/backend/cache/cache.go index 469cc9f73..000c4bc2f 100644 --- a/backend/cache/cache.go +++ b/backend/cache/cache.go @@ -1864,6 +1864,24 @@ func cleanPath(p string) string { return p } +// UserInfo returns info about the connected user +func (f *Fs) UserInfo(ctx context.Context) (map[string]string, error) { + do := f.Fs.Features().UserInfo + if do == nil { + return nil, fs.ErrorNotImplemented + } + return do(ctx) +} + +// Disconnect the current user +func (f *Fs) Disconnect(ctx context.Context) error { + do := f.Fs.Features().Disconnect + if do == nil { + return fs.ErrorNotImplemented + } + return do(ctx) +} + // Check the interfaces are satisfied var ( _ fs.Fs = (*Fs)(nil) @@ -1879,4 +1897,6 @@ var ( _ fs.ListRer = (*Fs)(nil) _ fs.ChangeNotifier = (*Fs)(nil) _ fs.Abouter = (*Fs)(nil) + _ fs.UserInfoer = (*Fs)(nil) + _ fs.Disconnecter = (*Fs)(nil) ) diff --git a/backend/crypt/crypt.go b/backend/crypt/crypt.go index c03392a1d..ae92e22ed 100644 --- a/backend/crypt/crypt.go +++ b/backend/crypt/crypt.go @@ -802,6 +802,24 @@ func (f *Fs) newDir(ctx context.Context, dir fs.Directory) fs.Directory { return newDir } +// UserInfo returns info about the connected user +func (f *Fs) UserInfo(ctx context.Context) (map[string]string, error) { + do := f.Fs.Features().UserInfo + if do == nil { + return nil, fs.ErrorNotImplemented + } + return do(ctx) +} + +// Disconnect the current user +func (f *Fs) Disconnect(ctx context.Context) error { + do := f.Fs.Features().Disconnect + if do == nil { + return fs.ErrorNotImplemented + } + return do(ctx) +} + // ObjectInfo describes a wrapped fs.ObjectInfo for being the source // // This encrypts the remote name and adjusts the size @@ -888,6 +906,8 @@ var ( _ fs.DirCacheFlusher = (*Fs)(nil) _ fs.ChangeNotifier = (*Fs)(nil) _ fs.PublicLinker = (*Fs)(nil) + _ fs.UserInfoer = (*Fs)(nil) + _ fs.Disconnecter = (*Fs)(nil) _ fs.ObjectInfo = (*ObjectInfo)(nil) _ fs.Object = (*Object)(nil) _ fs.ObjectUnWrapper = (*Object)(nil) diff --git a/fs/fs.go b/fs/fs.go index c6febd29f..f2f0d3f86 100644 --- a/fs/fs.go +++ b/fs/fs.go @@ -69,6 +69,7 @@ var ( ErrorImmutableModified = errors.New("immutable file modified") ErrorPermissionDenied = errors.New("permission denied") ErrorCantShareDirectories = errors.New("this backend can't share directories with link") + ErrorNotImplemented = errors.New("optional feature not implemented") ) // RegInfo provides information about a filesystem @@ -588,6 +589,12 @@ type Features struct { // // It truncates any existing object OpenWriterAt func(ctx context.Context, remote string, size int64) (WriterAtCloser, error) + + // UserInfo returns info about the connected user + UserInfo func(ctx context.Context) (map[string]string, error) + + // Disconnect the current user + Disconnect func(ctx context.Context) error } // Disable nil's out the named feature. If it isn't found then it @@ -703,6 +710,12 @@ func (ft *Features) Fill(f Fs) *Features { if do, ok := f.(OpenWriterAter); ok { ft.OpenWriterAt = do.OpenWriterAt } + if do, ok := f.(UserInfoer); ok { + ft.UserInfo = do.UserInfo + } + if do, ok := f.(Disconnecter); ok { + ft.Disconnect = do.Disconnect + } return ft.DisableList(Config.DisableFeatures) } @@ -771,6 +784,12 @@ func (ft *Features) Mask(f Fs) *Features { if mask.OpenWriterAt == nil { ft.OpenWriterAt = nil } + if mask.UserInfo == nil { + ft.UserInfo = nil + } + if mask.Disconnect == nil { + ft.Disconnect = nil + } return ft.DisableList(Config.DisableFeatures) } @@ -980,6 +999,18 @@ type OpenWriterAter interface { OpenWriterAt(ctx context.Context, remote string, size int64) (WriterAtCloser, error) } +// UserInfoer is an optional interface for Fs +type UserInfoer interface { + // UserInfo returns info about the connected user + UserInfo(ctx context.Context) (map[string]string, error) +} + +// Disconnecter is an optional interface for Fs +type Disconnecter interface { + // Disconnect the current user + Disconnect(ctx context.Context) error +} + // ObjectsChan is a channel of Objects type ObjectsChan chan Object