From 5226853fcafd38975c453c69246743664dc530b1 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Sat, 17 May 2025 10:53:07 +0200 Subject: [PATCH] fix: lock files across different users Fixes #66. --- lib/handler.go | 12 ++++++++++-- lib/locksystem.go | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 lib/locksystem.go diff --git a/lib/handler.go b/lib/handler.go index 7096518..70ce5f2 100644 --- a/lib/handler.go +++ b/lib/handler.go @@ -23,6 +23,8 @@ type Handler struct { } func NewHandler(c *Config) (http.Handler, error) { + ls := webdav.NewMemLS() + h := &Handler{ noPassword: c.NoPassword, behindProxy: c.BehindProxy, @@ -36,7 +38,10 @@ func NewHandler(c *Config) (http.Handler, error) { Dir: webdav.Dir(c.Directory), noSniff: c.NoSniff, }, - LockSystem: webdav.NewMemLS(), + LockSystem: &lockSystem{ + LockSystem: ls, + directory: c.Directory, + }, }, }, users: map[string]*handlerUser{}, @@ -51,7 +56,10 @@ func NewHandler(c *Config) (http.Handler, error) { Dir: webdav.Dir(u.Directory), noSniff: c.NoSniff, }, - LockSystem: webdav.NewMemLS(), + LockSystem: &lockSystem{ + LockSystem: ls, + directory: u.Directory, + }, }, } } diff --git a/lib/locksystem.go b/lib/locksystem.go new file mode 100644 index 0000000..ba41ac2 --- /dev/null +++ b/lib/locksystem.go @@ -0,0 +1,35 @@ +package lib + +import ( + "path/filepath" + "time" + + "golang.org/x/net/webdav" +) + +var _ webdav.LockSystem = &lockSystem{} + +// LockSystem wraps a [webdav.LockSystem] with a root directory, allowing +// to reuse the same [webdav.LockSystem] for multiple users with different base +// directories, meaning we can correctly lock the files across different users. +type lockSystem struct { + webdav.LockSystem + directory string +} + +func (l *lockSystem) Confirm(now time.Time, name0, name1 string, conditions ...webdav.Condition) (release func(), err error) { + if name0 != "" { + name0 = filepath.Join(l.directory, name0) + } + + if name1 != "" { + name1 = filepath.Join(l.directory, name1) + } + + return l.LockSystem.Confirm(now, name0, name1, conditions...) +} + +func (l *lockSystem) Create(now time.Time, details webdav.LockDetails) (token string, err error) { + details.Root = filepath.Join(l.directory, details.Root) + return l.LockSystem.Create(now, details) +}