Skip to content

Commit

Permalink
Revert "fix: rename/copy when using prefix"
Browse files Browse the repository at this point in the history
This reverts commit 617496c.
  • Loading branch information
hacdias committed Jan 15, 2025
1 parent 617496c commit 59c5f13
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 115 deletions.
48 changes: 9 additions & 39 deletions lib/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ type handlerUser struct {
type Handler struct {
noPassword bool
behindProxy bool
prefix string
user *handlerUser
users map[string]*handlerUser
}
Expand All @@ -28,12 +27,12 @@ func NewHandler(c *Config) (http.Handler, error) {
h := &Handler{
noPassword: c.NoPassword,
behindProxy: c.BehindProxy,
prefix: c.Prefix,
user: &handlerUser{
User: User{
UserPermissions: c.UserPermissions,
},
Handler: webdav.Handler{
Prefix: c.Prefix,
FileSystem: Dir{
Dir: webdav.Dir(c.Directory),
noSniff: c.NoSniff,
Expand All @@ -48,6 +47,7 @@ func NewHandler(c *Config) (http.Handler, error) {
h.users[u.Username] = &handlerUser{
User: u,
Handler: webdav.Handler{
Prefix: c.Prefix,
FileSystem: Dir{
Dir: webdav.Dir(u.Directory),
noSniff: c.NoSniff,
Expand Down Expand Up @@ -116,49 +116,19 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
zap.L().Info("user authorized", zap.String("username", username), zap.String("remote_address", remoteAddr))
}

// Validate and clean destination header if it exists, by stripping out the
// prefix and only keeping the actual destination path, always prefixed by
// a forward slash to ensure that the rules can successful match the path.
// Cleanup destination header if it's present by stripping out the prefix
// and only keeping the path.
if destination := r.Header.Get("Destination"); destination != "" {
u, err := url.Parse(destination)
if err != nil {
http.Error(w, "Invalid Destination header", http.StatusBadRequest)
return
}

if h.prefix != "" {
destination = strings.TrimPrefix(u.Path, h.prefix)
if len(destination) >= len(u.Path) {
http.Error(w, "Invalid URL prefix", http.StatusBadRequest)
return
if err == nil {
destination = strings.TrimPrefix(u.Path, user.Prefix)
if !strings.HasPrefix(destination, "/") {
destination = "/" + destination
}
}

if !strings.HasPrefix(destination, "/") {
destination = "/" + destination
}

r.Header.Set("Destination", destination)
}

// Clean up URL path by stripping out the prefix, and ensuring it always begins
// with a forward slash, so that it can match against the rules.
path := r.URL.Path

if h.prefix != "" {
path = strings.TrimPrefix(r.URL.Path, h.prefix)
if len(path) >= len(r.URL.Path) {
http.Error(w, "Invalid URL prefix", http.StatusBadRequest)
return
r.Header.Set("Destination", destination)
}
}

if !strings.HasPrefix(path, "/") {
path = "/" + path
}

r.URL.Path = path

// Checks for user permissions relatively to this PATH.
allowed := user.Allowed(r, func(filename string) bool {
_, err := user.FileSystem.Stat(r.Context(), filename)
Expand Down
76 changes: 0 additions & 76 deletions lib/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -292,82 +292,6 @@ users:
require.ErrorContains(t, err, "403")
}

func TestServerRulesPrefix(t *testing.T) {
t.Parallel()

dir := makeTestDirectory(t, map[string][]byte{
"foo.txt": []byte("foo"),
"bar.js": []byte("foo js"),
"a/foo.js": []byte("foo js"),
"a/foo.txt": []byte("foo txt"),
"b/foo.txt": []byte("foo b"),
"c/a.txt": []byte("b"),
"c/b.txt": []byte("b"),
"c/c.txt": []byte("b"),
})

srv := makeTestServer(t, fmt.Sprintf(`
directory: %s
permissions: CRUD
prefix: /prefix
users:
- username: basic
password: basic
rules:
- regex: "^.+.js$"
permissions: R
- path: "/b/"
permissions: R
- path: "/a/foo.txt"
permissions: none
- path: "/c/"
permissions: none
`, dir))

client := gowebdav.NewClient(srv.URL, "basic", "basic")

files, err := client.ReadDir("/prefix")
require.NoError(t, err)
require.Len(t, files, 5)

err = client.Write("/prefix/foo.txt", []byte("new"), 0666)
require.NoError(t, err)

err = client.Write("/prefix/new.txt", []byte("new"), 0666)
require.NoError(t, err)

err = client.Copy("/prefix/bar.js", "/prefix/b/bar.js", false)
require.ErrorContains(t, err, "403")

err = client.Copy("/prefix/bar.js", "/prefix/bar.jsx", false)
require.NoError(t, err)

err = client.Copy("/prefix/b/foo.txt", "/prefix/foo1.txt", false)
require.NoError(t, err)

err = client.Rename("/prefix/b/foo.txt", "/prefix/foo2.txt", false)
require.ErrorContains(t, err, "403")

_, err = client.Read("/prefix/a/foo.txt")
require.ErrorContains(t, err, "403")

err = client.Write("/prefix/a/foo.js", []byte("new"), 0666)
require.ErrorContains(t, err, "403")

err = client.Write("/prefix/b/foo.txt", []byte("new"), 0666)
require.ErrorContains(t, err, "403")

_, err = client.ReadDir("/prefix/c")
require.ErrorContains(t, err, "403")

_, err = client.Read("/prefix/c/a.txt")
require.ErrorContains(t, err, "403")

err = client.Write("/prefix/c/b.txt", []byte("new"), 0666)
require.ErrorContains(t, err, "403")
}

func TestServerPermissions(t *testing.T) {
t.Parallel()

Expand Down

0 comments on commit 59c5f13

Please sign in to comment.