diff --git a/cli/storage_webdav.go b/cli/storage_webdav.go index de335912b..8433e6f4a 100644 --- a/cli/storage_webdav.go +++ b/cli/storage_webdav.go @@ -21,11 +21,13 @@ func init() { func(cmd *kingpin.CmdClause) { cmd.Flag("url", "URL of WebDAV server").Required().StringVar(&options.URL) cmd.Flag("flat", "Use flat directory structure").BoolVar(&connectFlat) + cmd.Flag("webdav-username", "WebDAV username").Envar("KOPIA_WEBDAV_USERNAME").StringVar(&options.Username) + cmd.Flag("webdav-password", "WebDAV password").Envar("KOPIA_WEBDAV_PASSWORD").StringVar(&options.Password) }, func(ctx context.Context, isNew bool) (blob.Storage, error) { wo := options - if wo.Username != "" { + if wo.Username != "" && wo.Password == "" { pass, err := askPass("Enter WebDAV password: ") if err != nil { return nil, err diff --git a/repo/blob/webdav/webdav_storage_test.go b/repo/blob/webdav/webdav_storage_test.go index 73cc87e26..837280892 100644 --- a/repo/blob/webdav/webdav_storage_test.go +++ b/repo/blob/webdav/webdav_storage_test.go @@ -14,6 +14,23 @@ "github.com/kopia/kopia/internal/blobtesting" ) +func basicAuth(h http.Handler) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + if user, passwd, ok := r.BasicAuth(); ok { + if user == "user" && passwd == "password" { + h.ServeHTTP(w, r) + return + } + + http.Error(w, "not authorized", http.StatusForbidden) + } else { + w.Header().Set("WWW-Authenticate", `Basic realm="testing"`) + w.WriteHeader(401) + w.Write([]byte("Unauthorized.\n")) //nolint:errcheck + } + } +} + func TestWebDAVStorage(t *testing.T) { tmpDir, _ := ioutil.TempDir("", "webdav") defer os.RemoveAll(tmpDir) @@ -21,10 +38,10 @@ func TestWebDAVStorage(t *testing.T) { t.Logf("tmpDir: %v", tmpDir) mux := http.NewServeMux() - mux.Handle("/", &webdav.Handler{ + mux.HandleFunc("/", basicAuth(&webdav.Handler{ FileSystem: webdav.Dir(tmpDir), LockSystem: webdav.NewMemLS(), - }) + })) server := httptest.NewServer(mux) defer server.Close() @@ -50,6 +67,8 @@ func TestWebDAVStorage(t *testing.T) { r, err := New(context.Background(), &Options{ URL: server.URL, DirectoryShards: shardSpec, + Username: "user", + Password: "password", }) if r == nil || err != nil {