option to restrict download-as-zip/tar

new global-option / volflag `zip_who` specifies
who gets to use the download-as-zip/tar function;

* 0: nobody, same as --no-zip
* 1: admins
* 2: authorized users with read-access
* 3: anyone with read-access
This commit is contained in:
ed 2025-02-05 20:45:50 +00:00
parent 6c202effa4
commit c87af9e85c
5 changed files with 16 additions and 6 deletions

View file

@ -1263,7 +1263,8 @@ def add_optouts(ap):
ap2.add_argument("-nih", action="store_true", help="no info hostname -- don't show in UI") ap2.add_argument("-nih", action="store_true", help="no info hostname -- don't show in UI")
ap2.add_argument("-nid", action="store_true", help="no info disk-usage -- don't show in UI") ap2.add_argument("-nid", action="store_true", help="no info disk-usage -- don't show in UI")
ap2.add_argument("-nb", action="store_true", help="no powered-by-copyparty branding in UI") ap2.add_argument("-nb", action="store_true", help="no powered-by-copyparty branding in UI")
ap2.add_argument("--no-zip", action="store_true", help="disable download as zip/tar") ap2.add_argument("--zip-who", metavar="LVL", type=int, default=3, help="who can download as zip/tar? [\033[32m0\033[0m]=nobody, [\033[32m1\033[0m]=admins, [\033[32m2\033[0m]=authenticated-with-read-access, [\033[32m3\033[0m]=everyone-with-read-access (volflag=zip_who)\n\033[1;31mWARNING:\033[0m if a nested volume has a more restrictive value than a parent volume, then this will be \033[33mignored\033[0m if the download is initiated from the parent, more lenient volume")
ap2.add_argument("--no-zip", action="store_true", help="disable download as zip/tar; same as \033[33m--zip-who=0\033[0m")
ap2.add_argument("--no-tarcmp", action="store_true", help="disable download as compressed tar (?tar=gz, ?tar=bz2, ?tar=xz, ?tar=gz:9, ...)") ap2.add_argument("--no-tarcmp", action="store_true", help="disable download as compressed tar (?tar=gz, ?tar=bz2, ?tar=xz, ?tar=gz:9, ...)")
ap2.add_argument("--no-lifetime", action="store_true", help="do not allow clients (or server config) to schedule an upload to be deleted after a given time") ap2.add_argument("--no-lifetime", action="store_true", help="do not allow clients (or server config) to schedule an upload to be deleted after a given time")
ap2.add_argument("--no-pipe", action="store_true", help="disable race-the-beam (lockstep download of files which are currently being uploaded) (volflag=nopipe)") ap2.add_argument("--no-pipe", action="store_true", help="disable race-the-beam (lockstep download of files which are currently being uploaded) (volflag=nopipe)")

View file

@ -1914,7 +1914,7 @@ class AuthSrv(object):
if k not in vol.flags: if k not in vol.flags:
vol.flags[k] = getattr(self.args, k) vol.flags[k] = getattr(self.args, k)
for k in ("nrand", "u2abort"): for k in ("nrand", "u2abort", "ups_who", "zip_who"):
if k in vol.flags: if k in vol.flags:
vol.flags[k] = int(vol.flags[k]) vol.flags[k] = int(vol.flags[k])

View file

@ -94,6 +94,7 @@ def vf_vmap() -> dict[str, str]:
"u2abort", "u2abort",
"u2ts", "u2ts",
"ups_who", "ups_who",
"zip_who",
): ):
ret[k] = k ret[k] = k
return ret return ret
@ -252,6 +253,8 @@ flagcats = {
"dots": "allow all users with read-access to\nenable the option to show dotfiles in listings", "dots": "allow all users with read-access to\nenable the option to show dotfiles in listings",
"fk=8": 'generates per-file accesskeys,\nwhich are then required at the "g" permission;\nkeys are invalidated if filesize or inode changes', "fk=8": 'generates per-file accesskeys,\nwhich are then required at the "g" permission;\nkeys are invalidated if filesize or inode changes',
"fka=8": 'generates slightly weaker per-file accesskeys,\nwhich are then required at the "g" permission;\nnot affected by filesize or inode numbers', "fka=8": 'generates slightly weaker per-file accesskeys,\nwhich are then required at the "g" permission;\nnot affected by filesize or inode numbers',
"ups_who=2": "restrict viewing the list of recent uploads",
"zip_who=2": "restrict access to download-as-zip/tar",
"mv_retry": "ms-windows: timeout for renaming busy files", "mv_retry": "ms-windows: timeout for renaming busy files",
"rm_retry": "ms-windows: timeout for deleting busy files", "rm_retry": "ms-windows: timeout for deleting busy files",
"davauth": "ask webdav clients to login for all folders", "davauth": "ask webdav clients to login for all folders",

View file

@ -4283,8 +4283,14 @@ class HttpCli(object):
rem: str, rem: str,
items: list[str], items: list[str],
) -> bool: ) -> bool:
if self.args.no_zip: lvl = vn.flags["zip_who"]
raise Pebkac(400, "not enabled in server config") if self.args.no_zip or not lvl:
raise Pebkac(400, "download-as-zip/tar is disabled in server config")
elif lvl <= 1 and not self.can_admin:
raise Pebkac(400, "download-as-zip/tar is admin-only on this server")
elif lvl <= 2 and self.uname in ("", "*"):
t = "you must be authenticated to download-as-zip/tar on this server"
raise Pebkac(400, t)
logmsg = "{:4} {} ".format("", self.req) logmsg = "{:4} {} ".format("", self.req)
self.keepalive = False self.keepalive = False
@ -5152,7 +5158,7 @@ class HttpCli(object):
adm = "*" in vol.axs.uadmin or self.uname in vol.axs.uadmin adm = "*" in vol.axs.uadmin or self.uname in vol.axs.uadmin
dots = "*" in vol.axs.udot or self.uname in vol.axs.udot dots = "*" in vol.axs.udot or self.uname in vol.axs.udot
lvl = int(vol.flags["ups_who"]) lvl = vol.flags["ups_who"]
if not lvl: if not lvl:
continue continue
elif lvl == 1 and not adm: elif lvl == 1 and not adm:

View file

@ -141,7 +141,7 @@ class Cfg(Namespace):
ex = "hash_mt hsortn safe_dedup srch_time u2abort u2j u2sz" ex = "hash_mt hsortn safe_dedup srch_time u2abort u2j u2sz"
ka.update(**{k: 1 for k in ex.split()}) ka.update(**{k: 1 for k in ex.split()})
ex = "au_vol dl_list mtab_age reg_cap s_thead s_tbody th_convt ups_who" ex = "au_vol dl_list mtab_age reg_cap s_thead s_tbody th_convt ups_who zip_who"
ka.update(**{k: 9 for k in ex.split()}) ka.update(**{k: 9 for k in ex.split()})
ex = "db_act k304 loris no304 re_maxage rproxy rsp_jtr rsp_slp s_wr_slp snap_wri theme themes turbo" ex = "db_act k304 loris no304 re_maxage rproxy rsp_jtr rsp_slp s_wr_slp snap_wri theme themes turbo"