Files
CHFS-NG/chfs-ng/internal/api/webdav_permission_matrix_test.go
T

116 lines
3.4 KiB
Go

package api
import (
"bytes"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"testing"
"chfs-ng/internal/auth"
"chfs-ng/internal/storage"
)
func webDAVMatrixServer(t *testing.T, mask auth.PermMask) (*Server, string) {
t.Helper()
root := t.TempDir()
for _, name := range []string{"src-copy.txt", "src-move.txt", "src-delete.txt"} {
if err := os.WriteFile(filepath.Join(root, name), []byte("src"), 0o644); err != nil {
t.Fatal(err)
}
}
return &Server{
Store: storage.Local{Root: root},
Auth: &auth.Manager{
Accounts: map[string]*auth.Account{},
Guest: &auth.Account{Mask: mask},
},
RemoveMode: 3,
WebDAVRoot: root,
}, root
}
func webDAVRequest(h http.Handler, method, target string, body []byte, headers map[string]string) int {
req := httptest.NewRequest(method, target, bytes.NewReader(body))
for k, v := range headers {
req.Header.Set(k, v)
}
rr := httptest.NewRecorder()
h.ServeHTTP(rr, req)
return rr.Code
}
func TestWebDAVPermissionMatrix(t *testing.T) {
cases := []struct {
name string
mask auth.PermMask
read int
write int
del int
copy int
move int
}{
{"none", auth.None, http.StatusForbidden, http.StatusForbidden, http.StatusForbidden, http.StatusForbidden, http.StatusForbidden},
{"read", auth.Read, http.StatusMultiStatus, http.StatusForbidden, http.StatusForbidden, http.StatusForbidden, http.StatusForbidden},
{"read-write", auth.Read | auth.Write, http.StatusMultiStatus, http.StatusCreated, http.StatusForbidden, http.StatusCreated, http.StatusCreated},
{"read-write-delete", auth.Read | auth.Write | auth.Delete, http.StatusMultiStatus, http.StatusCreated, http.StatusNoContent, http.StatusCreated, http.StatusCreated},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
s, root := webDAVMatrixServer(t, tc.mask)
h := s.Handler()
propf := webDAVRequest(h, "PROPFIND", "/webdav/", nil, map[string]string{"Depth": "1"})
if propf != tc.read {
t.Errorf("PROPFIND: got %d want %d", propf, tc.read)
}
get := webDAVRequest(h, http.MethodGet, "/webdav/src-copy.txt", nil, nil)
if get != func() int {
if tc.mask.HasRead() {
return http.StatusOK
}
return http.StatusForbidden
}() {
want := http.StatusForbidden
if tc.mask.HasRead() {
want = http.StatusOK
}
t.Errorf("GET: got %d want %d", get, want)
}
put := webDAVRequest(h, http.MethodPut, "/webdav/new.txt", []byte("new"), nil)
if put != tc.write {
t.Errorf("PUT: got %d want %d", put, tc.write)
}
mkcol := webDAVRequest(h, "MKCOL", "/webdav/newdir", nil, nil)
if mkcol != tc.write {
t.Errorf("MKCOL: got %d want %d", mkcol, tc.write)
}
del := webDAVRequest(h, http.MethodDelete, "/webdav/src-delete.txt", nil, nil)
if del != tc.del {
t.Errorf("DELETE: got %d want %d", del, tc.del)
}
copy := webDAVRequest(h, "COPY", "/webdav/src-copy.txt", nil, map[string]string{"Destination": "/webdav/copied.txt"})
if copy != tc.copy {
t.Errorf("COPY: got %d want %d", copy, tc.copy)
}
move := webDAVRequest(h, "MOVE", "/webdav/src-move.txt", nil, map[string]string{"Destination": "/webdav/moved.txt"})
if move != tc.move {
t.Errorf("MOVE: got %d want %d", move, tc.move)
}
if tc.write == http.StatusCreated {
if _, err := os.Stat(filepath.Join(root, "new.txt")); tc.name != "none" && err != nil {
t.Errorf("PUT file missing: %v", err)
}
}
})
}
}