85 lines
3.2 KiB
Go
85 lines
3.2 KiB
Go
package davsync
|
|
|
|
import (
|
|
"context"
|
|
"io"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// A 403 is told apart: a folder in the address that isn't on the server, one
|
|
// the account may only read, and a server that won't say — not all of them a
|
|
// wrong password, as they read before.
|
|
func TestDAVForbidden(t *testing.T) {
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if u, p, ok := r.BasicAuth(); !ok || u != "me" || p != "pw" {
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
return
|
|
}
|
|
path := strings.TrimSuffix(r.URL.Path, "/")
|
|
switch {
|
|
case r.Method == "PROPFIND" && (path == "" || path == "/ro"):
|
|
w.WriteHeader(http.StatusMultiStatus)
|
|
case r.Method == "PROPFIND" && path == "/missing":
|
|
w.WriteHeader(http.StatusNotFound)
|
|
case r.Method == http.MethodGet && strings.HasPrefix(path, "/ro/"):
|
|
w.WriteHeader(http.StatusNotFound)
|
|
default: // a Synology: anything else, 403
|
|
w.WriteHeader(http.StatusForbidden)
|
|
}
|
|
}))
|
|
defer srv.Close()
|
|
ctx := context.Background()
|
|
for _, c := range []struct{ dir, pass, want string }{
|
|
{"/missing", "pw", "there is no folder /missing"},
|
|
{"/ro", "pw", "doesn't let this account write in /ro"},
|
|
{"/secret", "pw", "doesn't let this account use /secret"},
|
|
{"/missing", "bad", "user name or password"},
|
|
} {
|
|
d, err := newDAV(Config{URL: srv.URL + c.dir, User: "me", Password: c.pass})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
_, _, err = d.get(ctx)
|
|
if err == nil {
|
|
err = d.put(ctx, []byte("x"), "")
|
|
}
|
|
if err == nil || !strings.Contains(err.Error(), c.want) {
|
|
t.Errorf("%s: %v, want %q", c.dir, err, c.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
// OpenList's and Alist's /dav/ lists their storages: a folder can't be made
|
|
// there (MKCOL 405, as if it were) and a file can't be put (404). The error
|
|
// says to put a storage in the address, naming them.
|
|
func TestDAVStorageRoot(t *testing.T) {
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
switch {
|
|
case r.Method == "PROPFIND" && r.URL.Path == "/dav/" && r.Header.Get("Depth") == "1":
|
|
w.WriteHeader(http.StatusMultiStatus)
|
|
io.WriteString(w, `<?xml version="1.0" encoding="UTF-8"?><D:multistatus xmlns:D="DAV:">`+
|
|
`<D:response><D:href>/dav/</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype></D:prop></D:propstat></D:response>`+
|
|
`<D:response><D:href>/dav/local/</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype></D:prop></D:propstat></D:response>`+
|
|
`<D:response><D:href>/dav/aliyun/</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype></D:prop></D:propstat></D:response>`+
|
|
`<D:response><D:href>/dav/readme.txt</D:href><D:propstat><D:prop><D:resourcetype/></D:prop></D:propstat></D:response>`+
|
|
`</D:multistatus>`)
|
|
case r.Method == "MKCOL":
|
|
w.WriteHeader(http.StatusMethodNotAllowed)
|
|
default:
|
|
w.WriteHeader(http.StatusNotFound)
|
|
}
|
|
}))
|
|
defer srv.Close()
|
|
d, err := newDAV(Config{URL: srv.URL + "/dav/"})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
err = d.put(context.Background(), []byte("x"), "")
|
|
if err == nil || !strings.Contains(err.Error(), "(local, aliyun), like "+srv.URL+"/dav/local") {
|
|
t.Fatalf("%v", err)
|
|
}
|
|
}
|