Compare commits

...
Author SHA1 Message Date
Henrique Dias 9bc219271c fix: additive permissions 2025-10-17 17:10:24 +02:00
2 changed files with 49 additions and 2 deletions
+46 -1
View File
@@ -217,7 +217,7 @@ users:
})
}
func TestServerRules(t *testing.T) {
func TestServerRulesRestrictive(t *testing.T) {
t.Parallel()
dir := makeTestDirectory(t, map[string][]byte{
@@ -292,6 +292,51 @@ users:
require.ErrorContains(t, err, "403")
}
func TestServerRulesAdditive(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"),
})
srv := makeTestServer(t, fmt.Sprintf(`
directory: %s
permissions: none
users:
- username: basic
password: basic
rules:
- regex: "^.+.js$"
permissions: R
- path: "/a/foo.txt"
permissions: CRU
- path: "/b/"
permissions: D
`, dir))
client := gowebdav.NewClient(srv.URL, "basic", "basic")
_, err := client.ReadDir("/")
require.ErrorContains(t, err, "403")
err = client.Write("/foo.txt", []byte("new"), 0666)
require.ErrorContains(t, err, "403")
err = client.Write("/new.txt", []byte("new"), 0666)
require.ErrorContains(t, err, "403")
err = client.Copy("/bar.js", "/a/foo.txt", true)
require.NoError(t, err)
err = client.Remove("/b/foo.txt")
require.NoError(t, err)
}
func TestServerRulesPrefix(t *testing.T) {
t.Parallel()
+3 -1
View File
@@ -56,9 +56,11 @@ func (p UserPermissions) Allowed(r *request, fileExists func(string) bool) bool
// we fail immediately. If no rule matches, we check the global permissions.
if r.method == "COPY" || r.method == "MOVE" {
dst := r.destination
ruleMatched := false
for i := len(p.Rules) - 1; i >= 0; i-- {
if p.Rules[i].Matches(dst) {
ruleMatched = true
if !p.Rules[i].Permissions.AllowedDestination(r, fileExists) {
return false
}
@@ -68,7 +70,7 @@ func (p UserPermissions) Allowed(r *request, fileExists func(string) bool) bool
}
}
if !p.Permissions.AllowedDestination(r, fileExists) {
if !ruleMatched && !p.Permissions.AllowedDestination(r, fileExists) {
return false
}
}