add a File interface so we can avoid to use os.File directly
This commit is contained in:
parent
969b38586e
commit
ca0ff0d630
17 changed files with 63 additions and 47 deletions
|
@ -260,7 +260,7 @@ func (c *BaseConnection) RemoveFile(fsPath, virtualPath string, info os.FileInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.CommandLog(removeLogSender, fsPath, "", c.User.Username, "", c.ID, c.protocol, -1, -1, "", "", "", -1)
|
logger.CommandLog(removeLogSender, fsPath, "", c.User.Username, "", c.ID, c.protocol, -1, -1, "", "", "", -1)
|
||||||
if info.Mode()&os.ModeSymlink != os.ModeSymlink {
|
if info.Mode()&os.ModeSymlink == 0 {
|
||||||
vfolder, err := c.User.GetVirtualFolderForPath(path.Dir(virtualPath))
|
vfolder, err := c.User.GetVirtualFolderForPath(path.Dir(virtualPath))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
dataprovider.UpdateVirtualFolderQuota(vfolder.BaseVirtualFolder, -1, -size, false) //nolint:errcheck
|
dataprovider.UpdateVirtualFolderQuota(vfolder.BaseVirtualFolder, -1, -size, false) //nolint:errcheck
|
||||||
|
@ -318,7 +318,7 @@ func (c *BaseConnection) RemoveDir(fsPath, virtualPath string) error {
|
||||||
c.Log(logger.LevelWarn, "failed to remove a dir %#v: stat error: %+v", fsPath, err)
|
c.Log(logger.LevelWarn, "failed to remove a dir %#v: stat error: %+v", fsPath, err)
|
||||||
return c.GetFsError(err)
|
return c.GetFsError(err)
|
||||||
}
|
}
|
||||||
if !fi.IsDir() || fi.Mode()&os.ModeSymlink == os.ModeSymlink {
|
if !fi.IsDir() || fi.Mode()&os.ModeSymlink != 0 {
|
||||||
c.Log(logger.LevelDebug, "cannot remove %#v is not a directory", fsPath)
|
c.Log(logger.LevelDebug, "cannot remove %#v is not a directory", fsPath)
|
||||||
return c.GetGenericError(nil)
|
return c.GetGenericError(nil)
|
||||||
}
|
}
|
||||||
|
@ -638,7 +638,7 @@ func (c *BaseConnection) isRenamePermitted(fsSourcePath, virtualSourcePath, virt
|
||||||
if fi != nil {
|
if fi != nil {
|
||||||
if fi.IsDir() {
|
if fi.IsDir() {
|
||||||
return c.User.HasPerm(dataprovider.PermCreateDirs, path.Dir(virtualTargetPath))
|
return c.User.HasPerm(dataprovider.PermCreateDirs, path.Dir(virtualTargetPath))
|
||||||
} else if fi.Mode()&os.ModeSymlink == os.ModeSymlink {
|
} else if fi.Mode()&os.ModeSymlink != 0 {
|
||||||
return c.User.HasPerm(dataprovider.PermCreateSymlinks, path.Dir(virtualTargetPath))
|
return c.User.HasPerm(dataprovider.PermCreateSymlinks, path.Dir(virtualTargetPath))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -806,7 +806,7 @@ func TestRenamePermission(t *testing.T) {
|
||||||
}
|
}
|
||||||
info, err = os.Lstat(tmpDirLink)
|
info, err = os.Lstat(tmpDirLink)
|
||||||
if assert.NoError(t, err) {
|
if assert.NoError(t, err) {
|
||||||
assert.True(t, info.Mode()&os.ModeSymlink == os.ModeSymlink)
|
assert.True(t, info.Mode()&os.ModeSymlink != 0)
|
||||||
// the source is a symlink and the target has createDirs and upload perm
|
// the source is a symlink and the target has createDirs and upload perm
|
||||||
assert.False(t, conn.isRenamePermitted(tmpDir, request.Filepath, request.Target, info))
|
assert.False(t, conn.isRenamePermitted(tmpDir, request.Filepath, request.Target, info))
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ var (
|
||||||
type BaseTransfer struct { //nolint:maligned
|
type BaseTransfer struct { //nolint:maligned
|
||||||
ID uint64
|
ID uint64
|
||||||
Fs vfs.Fs
|
Fs vfs.Fs
|
||||||
File *os.File
|
File vfs.File
|
||||||
Connection *BaseConnection
|
Connection *BaseConnection
|
||||||
cancelFn func()
|
cancelFn func()
|
||||||
fsPath string
|
fsPath string
|
||||||
|
@ -42,7 +42,7 @@ type BaseTransfer struct { //nolint:maligned
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBaseTransfer returns a new BaseTransfer and adds it to the given connection
|
// NewBaseTransfer returns a new BaseTransfer and adds it to the given connection
|
||||||
func NewBaseTransfer(file *os.File, conn *BaseConnection, cancelFn func(), fsPath, requestPath string, transferType int,
|
func NewBaseTransfer(file vfs.File, conn *BaseConnection, cancelFn func(), fsPath, requestPath string, transferType int,
|
||||||
minWriteOffset, initialSize, maxWriteSize int64, isNewFile bool, fs vfs.Fs) *BaseTransfer {
|
minWriteOffset, initialSize, maxWriteSize int64, isNewFile bool, fs vfs.Fs) *BaseTransfer {
|
||||||
t := &BaseTransfer{
|
t := &BaseTransfer{
|
||||||
ID: conn.GetTransferID(),
|
ID: conn.GetTransferID(),
|
||||||
|
|
|
@ -99,7 +99,7 @@ func (c *Connection) Remove(name string) error {
|
||||||
return c.GetFsError(err)
|
return c.GetFsError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if fi.IsDir() && fi.Mode()&os.ModeSymlink != os.ModeSymlink {
|
if fi.IsDir() && fi.Mode()&os.ModeSymlink == 0 {
|
||||||
c.Log(logger.LevelDebug, "cannot remove %#v is not a file/symlink", p)
|
c.Log(logger.LevelDebug, "cannot remove %#v is not a file/symlink", p)
|
||||||
return c.GetGenericError(nil)
|
return c.GetGenericError(nil)
|
||||||
}
|
}
|
||||||
|
@ -307,7 +307,7 @@ func (c *Connection) uploadFile(fsPath, ftpPath string, flags int) (ftpserver.Fi
|
||||||
}
|
}
|
||||||
|
|
||||||
stat, statErr := c.Fs.Lstat(fsPath)
|
stat, statErr := c.Fs.Lstat(fsPath)
|
||||||
if (statErr == nil && stat.Mode()&os.ModeSymlink == os.ModeSymlink) || c.Fs.IsNotExist(statErr) {
|
if (statErr == nil && stat.Mode()&os.ModeSymlink != 0) || c.Fs.IsNotExist(statErr) {
|
||||||
if !c.User.HasPerm(dataprovider.PermUpload, path.Dir(ftpPath)) {
|
if !c.User.HasPerm(dataprovider.PermUpload, path.Dir(ftpPath)) {
|
||||||
return nil, c.GetPermissionDeniedError()
|
return nil, c.GetPermissionDeniedError()
|
||||||
}
|
}
|
||||||
|
|
14
go.mod
14
go.mod
|
@ -8,7 +8,7 @@ require (
|
||||||
github.com/Azure/azure-storage-blob-go v0.11.0
|
github.com/Azure/azure-storage-blob-go v0.11.0
|
||||||
github.com/GehirnInc/crypt v0.0.0-20200316065508-bb7000b8a962
|
github.com/GehirnInc/crypt v0.0.0-20200316065508-bb7000b8a962
|
||||||
github.com/alexedwards/argon2id v0.0.0-20200802152012-2464efd3196b
|
github.com/alexedwards/argon2id v0.0.0-20200802152012-2464efd3196b
|
||||||
github.com/aws/aws-sdk-go v1.35.28
|
github.com/aws/aws-sdk-go v1.35.29
|
||||||
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf // indirect
|
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf // indirect
|
||||||
github.com/eikenb/pipeat v0.0.0-20200430215831-470df5986b6d
|
github.com/eikenb/pipeat v0.0.0-20200430215831-470df5986b6d
|
||||||
github.com/fclairamb/ftpserverlib v0.9.1-0.20201105003045-1edd6bf7ae53
|
github.com/fclairamb/ftpserverlib v0.9.1-0.20201105003045-1edd6bf7ae53
|
||||||
|
@ -21,7 +21,7 @@ require (
|
||||||
github.com/jlaffaye/ftp v0.0.0-20201112195030-9aae4d151126
|
github.com/jlaffaye/ftp v0.0.0-20201112195030-9aae4d151126
|
||||||
github.com/lib/pq v1.8.0
|
github.com/lib/pq v1.8.0
|
||||||
github.com/magiconair/properties v1.8.4 // indirect
|
github.com/magiconair/properties v1.8.4 // indirect
|
||||||
github.com/mattn/go-sqlite3 v1.14.4
|
github.com/mattn/go-sqlite3 v1.14.5
|
||||||
github.com/miekg/dns v1.1.35 // indirect
|
github.com/miekg/dns v1.1.35 // indirect
|
||||||
github.com/mitchellh/mapstructure v1.3.3 // indirect
|
github.com/mitchellh/mapstructure v1.3.3 // indirect
|
||||||
github.com/otiai10/copy v1.2.0
|
github.com/otiai10/copy v1.2.0
|
||||||
|
@ -43,14 +43,14 @@ require (
|
||||||
github.com/studio-b12/gowebdav v0.0.0-20200929080739-bdacfab94796
|
github.com/studio-b12/gowebdav v0.0.0-20200929080739-bdacfab94796
|
||||||
go.etcd.io/bbolt v1.3.5
|
go.etcd.io/bbolt v1.3.5
|
||||||
go.uber.org/automaxprocs v1.3.0
|
go.uber.org/automaxprocs v1.3.0
|
||||||
golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9
|
golang.org/x/crypto v0.0.0-20201116153603-4be66e5b6582
|
||||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b
|
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b
|
||||||
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58 // indirect
|
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58 // indirect
|
||||||
golang.org/x/sys v0.0.0-20201113233024-12cec1faf1ba
|
golang.org/x/sys v0.0.0-20201116194326-cc9327a14d48
|
||||||
golang.org/x/tools v0.0.0-20201116002733-ac45abd4c88c // indirect
|
golang.org/x/tools v0.0.0-20201117021029-3c3a81204b10 // indirect
|
||||||
google.golang.org/api v0.35.0
|
google.golang.org/api v0.35.0
|
||||||
google.golang.org/appengine v1.6.7 // indirect
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
google.golang.org/genproto v0.0.0-20201113130914-ce600e9a6f9e // indirect
|
google.golang.org/genproto v0.0.0-20201117123952-62d171c70ae1 // indirect
|
||||||
gopkg.in/ini.v1 v1.62.0 // indirect
|
gopkg.in/ini.v1 v1.62.0 // indirect
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
||||||
)
|
)
|
||||||
|
@ -58,6 +58,6 @@ require (
|
||||||
replace (
|
replace (
|
||||||
github.com/jlaffaye/ftp => github.com/drakkan/ftp v0.0.0-20201114075148-9b9adce499a9
|
github.com/jlaffaye/ftp => github.com/drakkan/ftp v0.0.0-20201114075148-9b9adce499a9
|
||||||
github.com/pkg/sftp => github.com/drakkan/sftp v0.0.0-20201116163812-863783342b7c
|
github.com/pkg/sftp => github.com/drakkan/sftp v0.0.0-20201116163812-863783342b7c
|
||||||
golang.org/x/crypto => github.com/drakkan/crypto v0.0.0-20201114074711-d051624c4fd2
|
golang.org/x/crypto => github.com/drakkan/crypto v0.0.0-20201117140033-e88a43c86bda
|
||||||
golang.org/x/net => github.com/drakkan/net v0.0.0-20201114074615-8a2467084c77
|
golang.org/x/net => github.com/drakkan/net v0.0.0-20201114074615-8a2467084c77
|
||||||
)
|
)
|
||||||
|
|
24
go.sum
24
go.sum
|
@ -71,8 +71,8 @@ github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj
|
||||||
github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
|
github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
|
||||||
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
|
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
|
||||||
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||||
github.com/aws/aws-sdk-go v1.35.28 h1:S2LuRnfC8X05zgZLC8gy/Sb82TGv2Cpytzbzz7tkeHc=
|
github.com/aws/aws-sdk-go v1.35.29 h1:1kYnwrWTp2e+lI9yYFaDo7OFaLug8yXC6Qdj+u8451Q=
|
||||||
github.com/aws/aws-sdk-go v1.35.28/go.mod h1:tlPOdRjfxPBpNIwqDj61rmsnA85v9jc0Ps9+muhnW+k=
|
github.com/aws/aws-sdk-go v1.35.29/go.mod h1:tlPOdRjfxPBpNIwqDj61rmsnA85v9jc0Ps9+muhnW+k=
|
||||||
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
|
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
|
||||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||||
|
@ -115,8 +115,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||||
github.com/drakkan/crypto v0.0.0-20201114074711-d051624c4fd2 h1:1X+tt8X6lyGWn17TJaKOybGkRuGm1Rd0ErPhIY1Zy4A=
|
github.com/drakkan/crypto v0.0.0-20201117140033-e88a43c86bda h1:YiF1OveSSl1o5QTgz0Fj0UQvWS8TVO0kwSCPGDeqR1s=
|
||||||
github.com/drakkan/crypto v0.0.0-20201114074711-d051624c4fd2/go.mod h1:v3bhWOXGYda7H5d2s5t9XA6th3fxW3s0MQxU1R96G/w=
|
github.com/drakkan/crypto v0.0.0-20201117140033-e88a43c86bda/go.mod h1:Y+hk0JcLG7/moavCckN+J0fs8kd8mUEUPg5sSgBKDMQ=
|
||||||
github.com/drakkan/ftp v0.0.0-20201114075148-9b9adce499a9 h1:LPH1dEblAOO/LoG7yHPMtBLXhQmjaga91/DDjWk9jWA=
|
github.com/drakkan/ftp v0.0.0-20201114075148-9b9adce499a9 h1:LPH1dEblAOO/LoG7yHPMtBLXhQmjaga91/DDjWk9jWA=
|
||||||
github.com/drakkan/ftp v0.0.0-20201114075148-9b9adce499a9/go.mod h1:2lmrmq866uF2tnje75wQHzmPXhmSWUt7Gyx2vgK1RCU=
|
github.com/drakkan/ftp v0.0.0-20201114075148-9b9adce499a9/go.mod h1:2lmrmq866uF2tnje75wQHzmPXhmSWUt7Gyx2vgK1RCU=
|
||||||
github.com/drakkan/net v0.0.0-20201114074615-8a2467084c77 h1:keiJPG0lodjq5Ep9XuDKGRQRC52pp/8NB8/1xbqmw+Y=
|
github.com/drakkan/net v0.0.0-20201114074615-8a2467084c77 h1:keiJPG0lodjq5Ep9XuDKGRQRC52pp/8NB8/1xbqmw+Y=
|
||||||
|
@ -316,8 +316,8 @@ github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx
|
||||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||||
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
|
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
|
||||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||||
github.com/mattn/go-sqlite3 v1.14.4 h1:4rQjbDxdu9fSgI/r3KN72G3c2goxknAqHHgPWWs8UlI=
|
github.com/mattn/go-sqlite3 v1.14.5 h1:1IdxlwTNazvbKJQSxoJ5/9ECbEeaTTyeU7sEAZ5KKTQ=
|
||||||
github.com/mattn/go-sqlite3 v1.14.4/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI=
|
github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||||
|
@ -587,6 +587,7 @@ golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||||
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
@ -610,8 +611,9 @@ golang.org/x/sys v0.0.0-20200828194041-157a740278f4/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201113233024-12cec1faf1ba h1:xmhUJGQGbxlod18iJGqVEp9cHIPLl7QiX2aA3to708s=
|
golang.org/x/sys v0.0.0-20201116194326-cc9327a14d48 h1:AYCWBZhgIw6XobZ5CibNJr0Rc4ZofGGKvWa1vcx2IGk=
|
||||||
golang.org/x/sys v0.0.0-20201113233024-12cec1faf1ba/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201116194326-cc9327a14d48/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/term v0.0.0-20201113234701-d7a72108b828/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
@ -677,7 +679,7 @@ golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82u
|
||||||
golang.org/x/tools v0.0.0-20200915173823-2db8f0ff891c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
golang.org/x/tools v0.0.0-20200915173823-2db8f0ff891c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||||
golang.org/x/tools v0.0.0-20200918232735-d647fc253266/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
golang.org/x/tools v0.0.0-20200918232735-d647fc253266/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||||
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.0.0-20201116002733-ac45abd4c88c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20201117021029-3c3a81204b10/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
@ -746,8 +748,8 @@ google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6D
|
||||||
google.golang.org/genproto v0.0.0-20200914193844-75d14daec038/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20200914193844-75d14daec038/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20200921151605-7abf4a1a14d5/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20200921151605-7abf4a1a14d5/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20201113130914-ce600e9a6f9e h1:jRAe+6EDD0LNrVzmjx7FxBivivOZTKnXMbH5lvmxLP8=
|
google.golang.org/genproto v0.0.0-20201117123952-62d171c70ae1 h1:EVow1AaDgdoMjdO64/fntn4+RGTVor8YE/mkmIYsqFM=
|
||||||
google.golang.org/genproto v0.0.0-20201113130914-ce600e9a6f9e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20201117123952-62d171c70ae1/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
|
google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
|
||||||
|
|
|
@ -113,7 +113,7 @@ func (c *Connection) handleFilewrite(request *sftp.Request) (sftp.WriterAtReader
|
||||||
}
|
}
|
||||||
|
|
||||||
stat, statErr := c.Fs.Lstat(p)
|
stat, statErr := c.Fs.Lstat(p)
|
||||||
if (statErr == nil && stat.Mode()&os.ModeSymlink == os.ModeSymlink) || c.Fs.IsNotExist(statErr) {
|
if (statErr == nil && stat.Mode()&os.ModeSymlink != 0) || c.Fs.IsNotExist(statErr) {
|
||||||
if !c.User.HasPerm(dataprovider.PermUpload, path.Dir(request.Filepath)) {
|
if !c.User.HasPerm(dataprovider.PermUpload, path.Dir(request.Filepath)) {
|
||||||
return nil, sftp.ErrSSHFxPermissionDenied
|
return nil, sftp.ErrSSHFxPermissionDenied
|
||||||
}
|
}
|
||||||
|
@ -300,7 +300,7 @@ func (c *Connection) handleSFTPRemove(filePath string, request *sftp.Request) er
|
||||||
c.Log(logger.LevelWarn, "failed to remove a file %#v: stat error: %+v", filePath, err)
|
c.Log(logger.LevelWarn, "failed to remove a file %#v: stat error: %+v", filePath, err)
|
||||||
return c.GetFsError(err)
|
return c.GetFsError(err)
|
||||||
}
|
}
|
||||||
if fi.IsDir() && fi.Mode()&os.ModeSymlink != os.ModeSymlink {
|
if fi.IsDir() && fi.Mode()&os.ModeSymlink == 0 {
|
||||||
c.Log(logger.LevelDebug, "cannot remove %#v is not a file/symlink", filePath)
|
c.Log(logger.LevelDebug, "cannot remove %#v is not a file/symlink", filePath)
|
||||||
return sftp.ErrSSHFxFailure
|
return sftp.ErrSSHFxFailure
|
||||||
}
|
}
|
||||||
|
|
|
@ -260,7 +260,7 @@ func (c *scpCommand) handleUpload(uploadFilePath string, sizeToRead int64) error
|
||||||
filePath = c.connection.Fs.GetAtomicUploadPath(p)
|
filePath = c.connection.Fs.GetAtomicUploadPath(p)
|
||||||
}
|
}
|
||||||
stat, statErr := c.connection.Fs.Lstat(p)
|
stat, statErr := c.connection.Fs.Lstat(p)
|
||||||
if (statErr == nil && stat.Mode()&os.ModeSymlink == os.ModeSymlink) || c.connection.Fs.IsNotExist(statErr) {
|
if (statErr == nil && stat.Mode()&os.ModeSymlink != 0) || c.connection.Fs.IsNotExist(statErr) {
|
||||||
if !c.connection.User.HasPerm(dataprovider.PermUpload, path.Dir(uploadFilePath)) {
|
if !c.connection.User.HasPerm(dataprovider.PermUpload, path.Dir(uploadFilePath)) {
|
||||||
c.connection.Log(logger.LevelWarn, "cannot upload file: %#v, permission denied", uploadFilePath)
|
c.connection.Log(logger.LevelWarn, "cannot upload file: %#v, permission denied", uploadFilePath)
|
||||||
c.sendErrorMessage(common.ErrPermissionDenied)
|
c.sendErrorMessage(common.ErrPermissionDenied)
|
||||||
|
@ -352,7 +352,7 @@ func (c *scpCommand) handleRecursiveDownload(dirPath string, stat os.FileInfo) e
|
||||||
var dirs []string
|
var dirs []string
|
||||||
for _, file := range files {
|
for _, file := range files {
|
||||||
filePath := c.connection.Fs.GetRelativePath(c.connection.Fs.Join(dirPath, file.Name()))
|
filePath := c.connection.Fs.GetRelativePath(c.connection.Fs.Join(dirPath, file.Name()))
|
||||||
if file.Mode().IsRegular() || file.Mode()&os.ModeSymlink == os.ModeSymlink {
|
if file.Mode().IsRegular() || file.Mode()&os.ModeSymlink != 0 {
|
||||||
err = c.handleDownload(filePath)
|
err = c.handleDownload(filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
break
|
break
|
||||||
|
|
|
@ -753,11 +753,11 @@ func TestStat(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
info, err := client.Lstat(symlinkName)
|
info, err := client.Lstat(symlinkName)
|
||||||
if assert.NoError(t, err) {
|
if assert.NoError(t, err) {
|
||||||
assert.True(t, info.Mode()&os.ModeSymlink == os.ModeSymlink)
|
assert.True(t, info.Mode()&os.ModeSymlink != 0)
|
||||||
}
|
}
|
||||||
info, err = client.Stat(symlinkName)
|
info, err = client.Stat(symlinkName)
|
||||||
if assert.NoError(t, err) {
|
if assert.NoError(t, err) {
|
||||||
assert.False(t, info.Mode()&os.ModeSymlink == os.ModeSymlink)
|
assert.False(t, info.Mode()&os.ModeSymlink != 0)
|
||||||
}
|
}
|
||||||
linkName, err := client.ReadLink(symlinkName)
|
linkName, err := client.ReadLink(symlinkName)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
|
@ -552,7 +552,7 @@ func (c *sshCommand) hasCopyPermissions(sshSourcePath, sshDestPath string, srcIn
|
||||||
}
|
}
|
||||||
if srcInfo.IsDir() {
|
if srcInfo.IsDir() {
|
||||||
return c.connection.User.HasPerm(dataprovider.PermCreateDirs, path.Dir(sshDestPath))
|
return c.connection.User.HasPerm(dataprovider.PermCreateDirs, path.Dir(sshDestPath))
|
||||||
} else if srcInfo.Mode()&os.ModeSymlink == os.ModeSymlink {
|
} else if srcInfo.Mode()&os.ModeSymlink != 0 {
|
||||||
return c.connection.User.HasPerm(dataprovider.PermCreateSymlinks, path.Dir(sshDestPath))
|
return c.connection.User.HasPerm(dataprovider.PermCreateSymlinks, path.Dir(sshDestPath))
|
||||||
}
|
}
|
||||||
return c.connection.User.HasPerm(dataprovider.PermUpload, path.Dir(sshDestPath))
|
return c.connection.User.HasPerm(dataprovider.PermUpload, path.Dir(sshDestPath))
|
||||||
|
|
|
@ -189,7 +189,7 @@ func (fs *AzureBlobFs) Lstat(name string) (os.FileInfo, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open opens the named file for reading
|
// Open opens the named file for reading
|
||||||
func (fs *AzureBlobFs) Open(name string, offset int64) (*os.File, *pipeat.PipeReaderAt, func(), error) {
|
func (fs *AzureBlobFs) Open(name string, offset int64) (File, *pipeat.PipeReaderAt, func(), error) {
|
||||||
r, w, err := pipeat.PipeInDir(fs.localTempDir)
|
r, w, err := pipeat.PipeInDir(fs.localTempDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
|
@ -221,7 +221,7 @@ func (fs *AzureBlobFs) Open(name string, offset int64) (*os.File, *pipeat.PipeRe
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create creates or opens the named file for writing
|
// Create creates or opens the named file for writing
|
||||||
func (fs *AzureBlobFs) Create(name string, flag int) (*os.File, *PipeWriter, func(), error) {
|
func (fs *AzureBlobFs) Create(name string, flag int) (File, *PipeWriter, func(), error) {
|
||||||
r, w, err := pipeat.PipeInDir(fs.localTempDir)
|
r, w, err := pipeat.PipeInDir(fs.localTempDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
|
|
|
@ -163,7 +163,7 @@ func (fs *GCSFs) Lstat(name string) (os.FileInfo, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open opens the named file for reading
|
// Open opens the named file for reading
|
||||||
func (fs *GCSFs) Open(name string, offset int64) (*os.File, *pipeat.PipeReaderAt, func(), error) {
|
func (fs *GCSFs) Open(name string, offset int64) (File, *pipeat.PipeReaderAt, func(), error) {
|
||||||
r, w, err := pipeat.PipeInDir(fs.localTempDir)
|
r, w, err := pipeat.PipeInDir(fs.localTempDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
|
@ -194,7 +194,7 @@ func (fs *GCSFs) Open(name string, offset int64) (*os.File, *pipeat.PipeReaderAt
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create creates or opens the named file for writing
|
// Create creates or opens the named file for writing
|
||||||
func (fs *GCSFs) Create(name string, flag int) (*os.File, *PipeWriter, func(), error) {
|
func (fs *GCSFs) Create(name string, flag int) (File, *PipeWriter, func(), error) {
|
||||||
r, w, err := pipeat.PipeInDir(fs.localTempDir)
|
r, w, err := pipeat.PipeInDir(fs.localTempDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
|
|
|
@ -81,13 +81,13 @@ func (fs *OsFs) Lstat(name string) (os.FileInfo, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open opens the named file for reading
|
// Open opens the named file for reading
|
||||||
func (*OsFs) Open(name string, offset int64) (*os.File, *pipeat.PipeReaderAt, func(), error) {
|
func (*OsFs) Open(name string, offset int64) (File, *pipeat.PipeReaderAt, func(), error) {
|
||||||
f, err := os.Open(name)
|
f, err := os.Open(name)
|
||||||
return f, nil, nil, err
|
return f, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create creates or opens the named file for writing
|
// Create creates or opens the named file for writing
|
||||||
func (*OsFs) Create(name string, flag int) (*os.File, *PipeWriter, func(), error) {
|
func (*OsFs) Create(name string, flag int) (File, *PipeWriter, func(), error) {
|
||||||
var err error
|
var err error
|
||||||
var f *os.File
|
var f *os.File
|
||||||
if flag == 0 {
|
if flag == 0 {
|
||||||
|
|
|
@ -189,7 +189,7 @@ func (fs *S3Fs) Lstat(name string) (os.FileInfo, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open opens the named file for reading
|
// Open opens the named file for reading
|
||||||
func (fs *S3Fs) Open(name string, offset int64) (*os.File, *pipeat.PipeReaderAt, func(), error) {
|
func (fs *S3Fs) Open(name string, offset int64) (File, *pipeat.PipeReaderAt, func(), error) {
|
||||||
r, w, err := pipeat.PipeInDir(fs.localTempDir)
|
r, w, err := pipeat.PipeInDir(fs.localTempDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
|
@ -216,7 +216,7 @@ func (fs *S3Fs) Open(name string, offset int64) (*os.File, *pipeat.PipeReaderAt,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create creates or opens the named file for writing
|
// Create creates or opens the named file for writing
|
||||||
func (fs *S3Fs) Create(name string, flag int) (*os.File, *PipeWriter, func(), error) {
|
func (fs *S3Fs) Create(name string, flag int) (File, *PipeWriter, func(), error) {
|
||||||
r, w, err := pipeat.PipeInDir(fs.localTempDir)
|
r, w, err := pipeat.PipeInDir(fs.localTempDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
|
|
18
vfs/vfs.go
18
vfs/vfs.go
|
@ -4,6 +4,7 @@ package vfs
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
@ -28,8 +29,8 @@ type Fs interface {
|
||||||
ConnectionID() string
|
ConnectionID() string
|
||||||
Stat(name string) (os.FileInfo, error)
|
Stat(name string) (os.FileInfo, error)
|
||||||
Lstat(name string) (os.FileInfo, error)
|
Lstat(name string) (os.FileInfo, error)
|
||||||
Open(name string, offset int64) (*os.File, *pipeat.PipeReaderAt, func(), error)
|
Open(name string, offset int64) (File, *pipeat.PipeReaderAt, func(), error)
|
||||||
Create(name string, flag int) (*os.File, *PipeWriter, func(), error)
|
Create(name string, flag int) (File, *PipeWriter, func(), error)
|
||||||
Rename(source, target string) error
|
Rename(source, target string) error
|
||||||
Remove(name string, isDir bool) error
|
Remove(name string, isDir bool) error
|
||||||
Mkdir(name string) error
|
Mkdir(name string) error
|
||||||
|
@ -57,6 +58,19 @@ type Fs interface {
|
||||||
GetMimeType(name string) (string, error)
|
GetMimeType(name string) (string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// File defines an interface representing a SFTPGo file
|
||||||
|
type File interface {
|
||||||
|
io.Reader
|
||||||
|
io.Writer
|
||||||
|
io.Closer
|
||||||
|
io.ReaderAt
|
||||||
|
io.WriterAt
|
||||||
|
io.Seeker
|
||||||
|
Stat() (os.FileInfo, error)
|
||||||
|
Name() string
|
||||||
|
Truncate(size int64) error
|
||||||
|
}
|
||||||
|
|
||||||
// ErrVfsUnsupported defines the error for an unsupported VFS operation
|
// ErrVfsUnsupported defines the error for an unsupported VFS operation
|
||||||
var ErrVfsUnsupported = errors.New("Not supported")
|
var ErrVfsUnsupported = errors.New("Not supported")
|
||||||
|
|
||||||
|
|
|
@ -127,7 +127,7 @@ func (c *Connection) RemoveAll(ctx context.Context, name string) error {
|
||||||
return c.GetFsError(err)
|
return c.GetFsError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if fi.IsDir() && fi.Mode()&os.ModeSymlink != os.ModeSymlink {
|
if fi.IsDir() && fi.Mode()&os.ModeSymlink == 0 {
|
||||||
return c.removeDirTree(p, name)
|
return c.removeDirTree(p, name)
|
||||||
}
|
}
|
||||||
return c.RemoveFile(p, name, fi)
|
return c.RemoveFile(p, name, fi)
|
||||||
|
@ -152,7 +152,7 @@ func (c *Connection) OpenFile(ctx context.Context, name string, flag int, perm o
|
||||||
|
|
||||||
func (c *Connection) getFile(fsPath, virtualPath string) (webdav.File, error) {
|
func (c *Connection) getFile(fsPath, virtualPath string) (webdav.File, error) {
|
||||||
var err error
|
var err error
|
||||||
var file *os.File
|
var file vfs.File
|
||||||
var r *pipeat.PipeReaderAt
|
var r *pipeat.PipeReaderAt
|
||||||
var cancelFn func()
|
var cancelFn func()
|
||||||
|
|
||||||
|
@ -184,7 +184,7 @@ func (c *Connection) putFile(fsPath, virtualPath string) (webdav.File, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
stat, statErr := c.Fs.Lstat(fsPath)
|
stat, statErr := c.Fs.Lstat(fsPath)
|
||||||
if (statErr == nil && stat.Mode()&os.ModeSymlink == os.ModeSymlink) || c.Fs.IsNotExist(statErr) {
|
if (statErr == nil && stat.Mode()&os.ModeSymlink != 0) || c.Fs.IsNotExist(statErr) {
|
||||||
if !c.User.HasPerm(dataprovider.PermUpload, path.Dir(virtualPath)) {
|
if !c.User.HasPerm(dataprovider.PermUpload, path.Dir(virtualPath)) {
|
||||||
return nil, c.GetPermissionDeniedError()
|
return nil, c.GetPermissionDeniedError()
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ func (fs *MockOsFs) Name() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open returns nil
|
// Open returns nil
|
||||||
func (fs *MockOsFs) Open(name string, offset int64) (*os.File, *pipeat.PipeReaderAt, func(), error) {
|
func (fs *MockOsFs) Open(name string, offset int64) (vfs.File, *pipeat.PipeReaderAt, func(), error) {
|
||||||
return nil, fs.reader, nil, nil
|
return nil, fs.reader, nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue