mirror of
https://github.com/9001/copyparty.git
synced 2025-09-28 12:42:26 -06:00
rbac disk-info and --ver (closes #726);
options --du-who and --ver-who specifies who can see the disk-info (disk-usage, disk-free) and server-version based on user permissions
This commit is contained in:
parent
09f22993be
commit
19a4c45389
|
@ -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("--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 <title>")
|
ap2.add_argument("-nth", action="store_true", help="no title hostname; don't show \033[33m--name\033[0m in <title>")
|
||||||
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. 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("-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("--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)")
|
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("--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("--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("--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("--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("--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")
|
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")
|
||||||
|
|
|
@ -1014,7 +1014,10 @@ class AuthSrv(object):
|
||||||
yield prev, True
|
yield prev, True
|
||||||
|
|
||||||
def vf0(self):
|
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(
|
def idp_checkin(
|
||||||
self, broker: Optional["BrokerCli"], uname: str, gname: str
|
self, broker: Optional["BrokerCli"], uname: str, gname: str
|
||||||
|
@ -1759,8 +1762,7 @@ class AuthSrv(object):
|
||||||
if hits:
|
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"
|
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)
|
self.log(t % (E.cfg, ehint, ", ".join(hits)), 3)
|
||||||
zvf = {"tcolor": self.args.tcolor}
|
vfs = VFS(self.log_func, absreal("."), "", "", axs, self.vf0b())
|
||||||
vfs = VFS(self.log_func, absreal("."), "", "", axs, zvf)
|
|
||||||
if not axs.uread:
|
if not axs.uread:
|
||||||
self.badcfg1 = True
|
self.badcfg1 = True
|
||||||
elif "" not in mount:
|
elif "" not in mount:
|
||||||
|
@ -2294,6 +2296,8 @@ class AuthSrv(object):
|
||||||
vol.lim.uid = vol.flags["uid"]
|
vol.lim.uid = vol.flags["uid"]
|
||||||
vol.lim.gid = vol.flags["gid"]
|
vol.lim.gid = vol.flags["gid"]
|
||||||
|
|
||||||
|
vol.flags["du_iwho"] = n_du_who(vol.flags["du_who"])
|
||||||
|
|
||||||
if vol.flags.get("og"):
|
if vol.flags.get("og"):
|
||||||
self.args.uqe = True
|
self.args.uqe = True
|
||||||
|
|
||||||
|
@ -3474,6 +3478,30 @@ class AuthSrv(object):
|
||||||
self.log("generated config:\n\n" + "\n".join(ret))
|
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]:
|
def split_cfg_ln(ln: str) -> dict[str, Any]:
|
||||||
# "a, b, c: 3" => {a:true, b:true, c:3}
|
# "a, b, c: 3" => {a:true, b:true, c:3}
|
||||||
ret = {}
|
ret = {}
|
||||||
|
|
|
@ -84,6 +84,7 @@ def vf_vmap() -> dict[str, str]:
|
||||||
"chmod_d",
|
"chmod_d",
|
||||||
"chmod_f",
|
"chmod_f",
|
||||||
"dbd",
|
"dbd",
|
||||||
|
"du_who",
|
||||||
"forget_ip",
|
"forget_ip",
|
||||||
"hsortn",
|
"hsortn",
|
||||||
"html_head",
|
"html_head",
|
||||||
|
@ -296,6 +297,7 @@ flagcats = {
|
||||||
"html_head=TXT": "includes TXT in the <head>, or @PATH for file at PATH",
|
"html_head=TXT": "includes TXT in the <head>, or @PATH for file at PATH",
|
||||||
"tcolor=#fc0": "theme color (a hint for webbrowsers, discord, etc.)",
|
"tcolor=#fc0": "theme color (a hint for webbrowsers, discord, etc.)",
|
||||||
"nodirsz": "don't show total folder size",
|
"nodirsz": "don't show total folder size",
|
||||||
|
"du_who=all": "show disk-usage info to everyone",
|
||||||
"robots": "allows indexing by search engines (default)",
|
"robots": "allows indexing by search engines (default)",
|
||||||
"norobots": "kindly asks search engines to leave",
|
"norobots": "kindly asks search engines to leave",
|
||||||
"unlistcr": "don't list read-access in controlpanel",
|
"unlistcr": "don't list read-access in controlpanel",
|
||||||
|
|
|
@ -1632,7 +1632,14 @@ class HttpCli(object):
|
||||||
self.log("inaccessible: %r" % ("/" + self.vpath,))
|
self.log("inaccessible: %r" % ("/" + self.vpath,))
|
||||||
raise Pebkac(401, "authenticate")
|
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)
|
bfree, btot, _ = get_df(vn.realpath, False)
|
||||||
if btot:
|
if btot:
|
||||||
df = {
|
df = {
|
||||||
|
@ -5159,6 +5166,11 @@ class HttpCli(object):
|
||||||
elif nre:
|
elif nre:
|
||||||
re_btn = "&re=%s" % (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(
|
html = self.j2s(
|
||||||
"splash",
|
"splash",
|
||||||
this=self,
|
this=self,
|
||||||
|
@ -5181,7 +5193,7 @@ class HttpCli(object):
|
||||||
no304=self.no304(),
|
no304=self.no304(),
|
||||||
k304vis=self.args.k304 > 0,
|
k304vis=self.args.k304 > 0,
|
||||||
no304vis=self.args.no304 > 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 != "*",
|
chpw=self.args.chpw and self.uname != "*",
|
||||||
ahttps="" if self.is_https else "https://" + self.host + self.req,
|
ahttps="" if self.is_https else "https://" + self.host + self.req,
|
||||||
)
|
)
|
||||||
|
@ -6360,7 +6372,14 @@ class HttpCli(object):
|
||||||
except:
|
except:
|
||||||
self.log("#wow #whoa")
|
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)
|
free, total, zs = get_df(abspath, False)
|
||||||
if total:
|
if total:
|
||||||
h1 = humansize(free or 0)
|
h1 = humansize(free or 0)
|
||||||
|
|
|
@ -27,7 +27,7 @@ if True: # pylint: disable=using-constant-test
|
||||||
from typing import Any, Optional, Union
|
from typing import Any, Optional, Union
|
||||||
|
|
||||||
from .__init__ import ANYWIN, EXE, MACOS, PY2, TYPE_CHECKING, E, EnvParams, unicode
|
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 .bos import bos
|
||||||
from .cert import ensure_cert
|
from .cert import ensure_cert
|
||||||
from .mtag import HAVE_FFMPEG, HAVE_FFPROBE, HAVE_MUTAGEN
|
from .mtag import HAVE_FFMPEG, HAVE_FFPROBE, HAVE_MUTAGEN
|
||||||
|
@ -289,6 +289,14 @@ class SvcHub(object):
|
||||||
ch = "abcdefghijklmnopqrstuvwx"[int(args.theme / 2)]
|
ch = "abcdefghijklmnopqrstuvwx"[int(args.theme / 2)]
|
||||||
args.theme = "{0}{1} {0} {1}".format(ch, bri)
|
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:
|
if args.nih:
|
||||||
args.vname = ""
|
args.vname = ""
|
||||||
args.doctitle = args.doctitle.replace(" @ --name", "")
|
args.doctitle = args.doctitle.replace(" @ --name", "")
|
||||||
|
|
|
@ -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"
|
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()})
|
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()})
|
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"
|
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_cmax=8192,
|
||||||
cookie_nmax=50,
|
cookie_nmax=50,
|
||||||
dbd="wal",
|
dbd="wal",
|
||||||
|
du_who="all",
|
||||||
dk_salt="b" * 16,
|
dk_salt="b" * 16,
|
||||||
fk_salt="a" * 16,
|
fk_salt="a" * 16,
|
||||||
grp_all="acct",
|
grp_all="acct",
|
||||||
|
@ -220,6 +221,7 @@ class Cfg(Namespace):
|
||||||
u2sort="s",
|
u2sort="s",
|
||||||
u2ts="c",
|
u2ts="c",
|
||||||
unpost=600,
|
unpost=600,
|
||||||
|
ver_who="all",
|
||||||
warksalt="hunter2",
|
warksalt="hunter2",
|
||||||
**ka
|
**ka
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue