diff --git a/copyparty/__main__.py b/copyparty/__main__.py index 86a2fdbe..6645e0cb 100644 --- a/copyparty/__main__.py +++ b/copyparty/__main__.py @@ -1485,7 +1485,7 @@ def add_optouts(ap): ap2.add_argument("--no-fs-abrt", action="store_true", help="disable ability to abort ongoing copy/move") ap2.add_argument("-nth", action="store_true", help="no title hostname; don't show \033[33m--name\033[0m in ") 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. This is the same as --du-who no") ap2.add_argument("-nb", action="store_true", help="no powered-by-copyparty branding in UI") ap2.add_argument("--zipmaxn", metavar="N", type=u, default="0", help="reject download-as-zip if more than \033[33mN\033[0m files in total; optionally takes a unit suffix: [\033[32m256\033[0m], [\033[32m9K\033[0m], [\033[32m4G\033[0m] (volflag=zipmaxn)") ap2.add_argument("--zipmaxs", metavar="SZ", type=u, default="0", help="reject download-as-zip if total download size exceeds \033[33mSZ\033[0m bytes; optionally takes a unit suffix: [\033[32m256M\033[0m], [\033[32m4G\033[0m], [\033[32m2T\033[0m] (volflag=zipmaxs)") @@ -1763,7 +1763,11 @@ def add_ui(ap, retry): ap2.add_argument("--doctitle", metavar="TXT", type=u, default="copyparty @ --name", help="title / service-name to show in html documents") ap2.add_argument("--bname", metavar="TXT", type=u, default="--name", help="server name (displayed in filebrowser document title)") ap2.add_argument("--pb-url", metavar="URL", type=u, default=URL_PRJ, help="powered-by link; disable with \033[33m-nb\033[0m") - ap2.add_argument("--ver", action="store_true", help="show version on the control panel (incompatible with \033[33m-nb\033[0m)") + ap2.add_argument("--ver", action="store_true", help="show version on the control panel (incompatible with \033[33m-nb\033[0m). This is the same as --ver-who all") + ap2.add_argument("--ver-who", metavar="TXT", type=u, default="no", help="only show version for: [\033[32ma\033[0m]=admin-permission-anywhere, [\033[32mauth\033[0m]=authenticated, [\033[32mall\033[0m]=anyone") + ap2.add_argument("--du-who", metavar="TXT", type=u, default="all", help="only show disk usage for: [\033[32mno\033[0m]=nobody, [\033[32ma\033[0m]=admin-permission, [\033[32mrw\033[0m]=read-write, [\033[32mw\033[0m]=write, [\033[32mauth\033[0m]=authenticated, [\033[32mall\033[0m]=anyone (volflag=du_who)") + ap2.add_argument("--ver-iwho", type=int, default=0, help=argparse.SUPPRESS) + ap2.add_argument("--du-iwho", type=int, default=0, help=argparse.SUPPRESS) ap2.add_argument("--k304", metavar="NUM", type=int, default=0, help="configure the option to enable/disable k304 on the controlpanel (workaround for buggy reverse-proxies); [\033[32m0\033[0m] = hidden and default-off, [\033[32m1\033[0m] = visible and default-off, [\033[32m2\033[0m] = visible and default-on") ap2.add_argument("--no304", metavar="NUM", type=int, default=0, help="configure the option to enable/disable no304 on the controlpanel (workaround for buggy caching in browsers); [\033[32m0\033[0m] = hidden and default-off, [\033[32m1\033[0m] = visible and default-off, [\033[32m2\033[0m] = visible and default-on") ap2.add_argument("--ctl-re", metavar="SEC", type=int, default=1, help="the controlpanel Refresh-button will autorefresh every SEC; [\033[32m0\033[0m] = just once") diff --git a/copyparty/authsrv.py b/copyparty/authsrv.py index 34a3fe46..f68a9f7b 100644 --- a/copyparty/authsrv.py +++ b/copyparty/authsrv.py @@ -1014,7 +1014,10 @@ class AuthSrv(object): yield prev, True def vf0(self): - return {"d2d": True, "tcolor": self.args.tcolor} + return {"d2d": True, "tcolor": self.args.tcolor, "du_iwho": self.args.du_iwho} + + def vf0b(self): + return {"tcolor": self.args.tcolor, "du_iwho": self.args.du_iwho} def idp_checkin( self, broker: Optional["BrokerCli"], uname: str, gname: str @@ -1759,8 +1762,7 @@ class AuthSrv(object): if hits: t = "Hint: Found some config files in [%s], but these were not automatically loaded because they are in the wrong place%s %s\n" self.log(t % (E.cfg, ehint, ", ".join(hits)), 3) - zvf = {"tcolor": self.args.tcolor} - vfs = VFS(self.log_func, absreal("."), "", "", axs, zvf) + vfs = VFS(self.log_func, absreal("."), "", "", axs, self.vf0b()) if not axs.uread: self.badcfg1 = True elif "" not in mount: @@ -2294,6 +2296,8 @@ class AuthSrv(object): vol.lim.uid = vol.flags["uid"] vol.lim.gid = vol.flags["gid"] + vol.flags["du_iwho"] = n_du_who(vol.flags["du_who"]) + if vol.flags.get("og"): self.args.uqe = True @@ -3474,6 +3478,30 @@ class AuthSrv(object): self.log("generated config:\n\n" + "\n".join(ret)) +def n_du_who(s: str) -> int: + if s == "all": + return 9 + if s == "auth": + return 7 + if s == "w": + return 5 + if s == "rw": + return 4 + if s == "a": + return 3 + return 0 + + +def n_ver_who(s: str) -> int: + if s == "all": + return 9 + if s == "auth": + return 6 + if s == "a": + return 3 + return 0 + + def split_cfg_ln(ln: str) -> dict[str, Any]: # "a, b, c: 3" => {a:true, b:true, c:3} ret = {} diff --git a/copyparty/cfg.py b/copyparty/cfg.py index 51c47853..549ffa10 100644 --- a/copyparty/cfg.py +++ b/copyparty/cfg.py @@ -84,6 +84,7 @@ def vf_vmap() -> dict[str, str]: "chmod_d", "chmod_f", "dbd", + "du_who", "forget_ip", "hsortn", "html_head", @@ -296,6 +297,7 @@ flagcats = { "html_head=TXT": "includes TXT in the <head>, or @PATH for file at PATH", "tcolor=#fc0": "theme color (a hint for webbrowsers, discord, etc.)", "nodirsz": "don't show total folder size", + "du_who=all": "show disk-usage info to everyone", "robots": "allows indexing by search engines (default)", "norobots": "kindly asks search engines to leave", "unlistcr": "don't list read-access in controlpanel", diff --git a/copyparty/httpcli.py b/copyparty/httpcli.py index 8e111386..dc72bf7d 100644 --- a/copyparty/httpcli.py +++ b/copyparty/httpcli.py @@ -1632,7 +1632,14 @@ class HttpCli(object): self.log("inaccessible: %r" % ("/" + self.vpath,)) raise Pebkac(401, "authenticate") - if "quota-available-bytes" in props and not self.args.nid: + zi = vn.flags["du_iwho"] if "quota-available-bytes" in props else 0 + if zi and ( + zi == 9 + or (zi == 7 and self.uname != "*") + or (zi == 5 and self.can_write) + or (zi == 4 and self.can_write and self.can_read) + or (zi == 3 and self.can_admin) + ): bfree, btot, _ = get_df(vn.realpath, False) if btot: df = { @@ -5159,6 +5166,11 @@ class HttpCli(object): elif nre: re_btn = "&re=%s" % (nre,) + zi = self.args.ver_iwho + show_ver = zi and ( + zi == 9 or (zi == 6 and self.uname != "*") or (zi == 3 and avol) + ) + html = self.j2s( "splash", this=self, @@ -5181,7 +5193,7 @@ class HttpCli(object): no304=self.no304(), k304vis=self.args.k304 > 0, no304vis=self.args.no304 > 0, - ver=S_VERSION if self.args.ver else "", + ver=S_VERSION if show_ver else "", chpw=self.args.chpw and self.uname != "*", ahttps="" if self.is_https else "https://" + self.host + self.req, ) @@ -6360,7 +6372,14 @@ class HttpCli(object): except: self.log("#wow #whoa") - if not self.args.nid: + zi = vn.flags["du_iwho"] + if zi and ( + zi == 9 + or (zi == 7 and self.uname != "*") + or (zi == 5 and self.can_write) + or (zi == 4 and self.can_write and self.can_read) + or (zi == 3 and self.can_admin) + ): free, total, zs = get_df(abspath, False) if total: h1 = humansize(free or 0) diff --git a/copyparty/svchub.py b/copyparty/svchub.py index eca7f8e0..75a269ad 100644 --- a/copyparty/svchub.py +++ b/copyparty/svchub.py @@ -27,7 +27,7 @@ if True: # pylint: disable=using-constant-test from typing import Any, Optional, Union from .__init__ import ANYWIN, EXE, MACOS, PY2, TYPE_CHECKING, E, EnvParams, unicode -from .authsrv import BAD_CFG, AuthSrv +from .authsrv import BAD_CFG, AuthSrv, n_du_who, n_ver_who from .bos import bos from .cert import ensure_cert from .mtag import HAVE_FFMPEG, HAVE_FFPROBE, HAVE_MUTAGEN @@ -289,6 +289,14 @@ class SvcHub(object): ch = "abcdefghijklmnopqrstuvwx"[int(args.theme / 2)] args.theme = "{0}{1} {0} {1}".format(ch, bri) + if args.nid: + args.du_who = "no" + args.du_iwho = n_du_who(args.du_who) + + if args.ver and args.ver_who == "no": + args.ver_who = "all" + args.ver_iwho = n_ver_who(args.ver_who) + if args.nih: args.vname = "" args.doctitle = args.doctitle.replace(" @ --name", "") diff --git a/tests/util.py b/tests/util.py index e4804b38..6acc4a42 100644 --- a/tests/util.py +++ b/tests/util.py @@ -158,7 +158,7 @@ class Cfg(Namespace): ex = "hash_mt hsortn qdel safe_dedup srch_time tail_fd tail_rate th_spec_p u2abort u2j u2sz unp_who" ka.update(**{k: 1 for k in ex.split()}) - ex = "ac_convt au_vol dl_list mtab_age reg_cap s_thead s_tbody tail_tmax tail_who th_convt ups_who zip_who" + ex = "ac_convt au_vol dl_list du_iwho mtab_age reg_cap s_thead s_tbody tail_tmax tail_who th_convt ups_who ver_iwho zip_who" ka.update(**{k: 9 for k in ex.split()}) ex = "ctl_re db_act forget_ip idp_cookie idp_store k304 loris no304 nosubtle qr_pin qr_wait re_maxage rproxy rsp_jtr rsp_slp s_wr_slp snap_wri theme themes turbo u2ow zipmaxn zipmaxs" @@ -189,6 +189,7 @@ class Cfg(Namespace): cookie_cmax=8192, cookie_nmax=50, dbd="wal", + du_who="all", dk_salt="b" * 16, fk_salt="a" * 16, grp_all="acct", @@ -220,6 +221,7 @@ class Cfg(Namespace): u2sort="s", u2ts="c", unpost=600, + ver_who="all", warksalt="hunter2", **ka )