Use a dedicated path for the shares

This commit is contained in:
Andreas Schneider 2019-08-03 18:51:26 +02:00
parent 56caf8d499
commit 17f9ed2cbd
2 changed files with 27 additions and 5 deletions

View File

@ -42,6 +42,11 @@ import (
"strings"
)
type DirectoryMapping struct {
VirtualName string
RealName string
}
// slashClean is equivalent to but slightly more efficient than
// path.Clean("/" + name).
func slashClean(name string) string {
@ -54,18 +59,24 @@ func slashClean(name string) string {
type BaseDir string
func (d BaseDir) resolve(ctx context.Context, name string) string {
subDir := ctx.Value("dir").(string)
directoryMapping := ctx.Value("mapping").(*DirectoryMapping)
prefix := directoryMapping.VirtualName + "/"
if !strings.HasPrefix(name, prefix) {
// something does not add up
return ""
}
nameWithoutPrefix := strings.TrimPrefix(name, prefix)
// This implementation is based on Dir.Open's code in the standard net/http package.
if filepath.Separator != '/' && strings.IndexRune(name, filepath.Separator) >= 0 ||
strings.Contains(name, "\x00") {
strings.Contains(nameWithoutPrefix, "\x00") {
return ""
}
dir := string(d)
if dir == "" {
dir = "."
}
return filepath.Join(dir, subDir, filepath.FromSlash(slashClean(name)))
return filepath.Join(dir, directoryMapping.RealName, filepath.FromSlash(slashClean(nameWithoutPrefix)))
}
func (d BaseDir) Mkdir(ctx context.Context, name string, perm os.FileMode) error {

15
main.go
View File

@ -29,6 +29,7 @@ import (
"context"
"flag"
"fmt"
"github.com/go-chi/chi"
pwgen "github.com/sethvargo/go-password/password"
"golang.org/x/crypto/bcrypt"
"golang.org/x/net/webdav"
@ -73,6 +74,7 @@ func main() {
c := LoadConfig(*configFile)
h := &webdav.Handler{}
h.Prefix = "/share/"
h.LockSystem = webdav.NewMemLS()
h.FileSystem = BaseDir(c.BaseDirectory)
@ -88,11 +90,20 @@ func main() {
return
}
shareName := chi.URLParam(r, "share")
directoryMapping := DirectoryMapping{
VirtualName: shareName,
RealName: directory,
}
// Use the WebDAV handler to actually serve the request. Also enhance the context
// to contain the subdirectory (of the base directory) which contains the data for
// the authenticated user.
h.ServeHTTP(w, r.WithContext(context.WithValue(r.Context(), "dir", directory)))
h.ServeHTTP(w, r.WithContext(context.WithValue(r.Context(), "mapping", &directoryMapping)))
})
http.ListenAndServe(c.ListenAddress, authenticatedWebdavHandler)
r := chi.NewRouter()
r.Handle("/share/{share}/*", authenticatedWebdavHandler)
http.ListenAndServe(c.ListenAddress, r)
}