diff --git a/copyparty/__main__.py b/copyparty/__main__.py index a8aefeec..c02308bb 100755 --- a/copyparty/__main__.py +++ b/copyparty/__main__.py @@ -785,6 +785,7 @@ def add_webdav(ap): ap2.add_argument("--dav-inf", action="store_true", help="allow depth:infinite requests (recursive file listing); extremely server-heavy but required for spec compliance -- luckily few clients rely on this") ap2.add_argument("--dav-mac", action="store_true", help="disable apple-garbage filter -- allow macos to create junk files (._* and .DS_Store, .Spotlight-*, .fseventsd, .Trashes, .AppleDouble, __MACOS)") ap2.add_argument("--dav-rt", action="store_true", help="show symlink-destination's lastmodified instead of the link itself; always enabled for recursive listings (volflag=davrt)") + ap2.add_argument("--dav-auth", action="store_true", help="force auth for all folders (required by davfs2 when only some folders are world-readable) (volflag=davauth)") def add_smb(ap): diff --git a/copyparty/cfg.py b/copyparty/cfg.py index cb65c14e..bf128544 100644 --- a/copyparty/cfg.py +++ b/copyparty/cfg.py @@ -13,6 +13,7 @@ def vf_bmap() -> dict[str, str]: "no_dedup": "copydupes", "no_dupe": "nodupe", "no_forget": "noforget", + "dav_auth": "davauth", "dav_rt": "davrt", } for k in ( @@ -144,6 +145,7 @@ flagcats = { }, "others": { "fk=8": 'generates per-file accesskeys,\nwhich will then be required at the "g" permission', + "davauth": "ask webdav clients to login for all folders", "davrt": "show lastmod time of symlink destination, not the link itself\n(note: this option is always enabled for recursive listings)", }, } diff --git a/copyparty/httpcli.py b/copyparty/httpcli.py index cb470d96..0406e9bd 100644 --- a/copyparty/httpcli.py +++ b/copyparty/httpcli.py @@ -830,12 +830,15 @@ class HttpCli(object): if self.args.no_dav: raise Pebkac(405, "WebDAV is disabled in server config") - if not self.can_read and not self.can_write and not self.can_get: - if self.vpath: - self.log("inaccessible: [{}]".format(self.vpath)) - raise Pebkac(401, "authenticate") + vn, rem = self.asrv.vfs.get(self.vpath, self.uname, False, False, err=401) + tap = vn.canonical(rem) - self.uparam["h"] = "" + if "davauth" in vn.flags and self.uname == "*": + self.can_read = self.can_write = self.can_get = False + + if not self.can_read and not self.can_write and not self.can_get: + self.log("inaccessible: [{}]".format(self.vpath)) + raise Pebkac(401, "authenticate") from .dxml import parse_xml @@ -879,8 +882,6 @@ class HttpCli(object): ] props = set(props_lst) - vn, rem = self.asrv.vfs.get(self.vpath, self.uname, True, False, err=401) - tap = vn.canonical(rem) depth = self.headers.get("depth", "infinity").lower() try: @@ -890,7 +891,7 @@ class HttpCli(object): raise raise Pebkac(404) - if not stat.S_ISDIR(topdir["st"].st_mode): + if depth == "0" or not self.can_read or not stat.S_ISDIR(topdir["st"].st_mode): fgen = [] elif depth == "infinity": @@ -932,9 +933,6 @@ class HttpCli(object): ls += [{"vp": v, "st": zsr} for v in vfs_virt] fgen = ls # type: ignore - elif depth == "0": - fgen = [] # type: ignore - else: t = "invalid depth value '{}' (must be either '0' or '1'{})" t2 = " or 'infinity'" if self.args.dav_inf else ""