From d69283809581cfb7eb188c57468656944a05e0df Mon Sep 17 00:00:00 2001 From: ed Date: Sun, 8 Feb 2026 00:43:21 +0000 Subject: [PATCH] rw_edit fixes --- copyparty/authsrv.py | 5 +++++ copyparty/httpcli.py | 22 +++++++++++++++------- copyparty/svchub.py | 2 +- copyparty/up2k.py | 2 +- copyparty/web/browser.js | 12 +++++++++--- 5 files changed, 31 insertions(+), 12 deletions(-) diff --git a/copyparty/authsrv.py b/copyparty/authsrv.py index 924fed38..e0b17c8e 100644 --- a/copyparty/authsrv.py +++ b/copyparty/authsrv.py @@ -2589,6 +2589,11 @@ class AuthSrv(object): t = "WARNING: volume [/%s]: invalid value specified for ext-th: %s" self.log(t % (vol.vpath, etv), 3) + zsl = [x.strip() for x in vol.flags["rw_edit"].split(",")] + zsl = [x for x in zsl if x] + vol.flags["rw_edit"] = ",".join(zsl) + vol.flags["rw_edit_set"] = set(x for x in zsl if x) + emb_all = vol.flags["emb_all"] = set() zsl1 = [x for x in vol.flags["preadmes"].split(",") if x] diff --git a/copyparty/httpcli.py b/copyparty/httpcli.py index 2e29d015..cb915bba 100644 --- a/copyparty/httpcli.py +++ b/copyparty/httpcli.py @@ -3534,10 +3534,10 @@ class HttpCli(object): if not self.can_delete and ( "." not in new_file - or new_file.rsplit(".", 1)[1].lower() not in self.args.rw_edit_set + or new_file.rsplit(".", 1)[1].lower() not in vfs.flags["rw_edit_set"] ): t = "you can only create %s files because you don't have the delete-permission" - raise Pebkac(400, t % (self.args.rw_edit.replace(",", "/"))) + raise Pebkac(400, t % (vfs.flags["rw_edit"].replace(",", "/"))) sanitized = sanitize_fn(new_file) fdir = vfs.canonical(rem) @@ -4055,10 +4055,11 @@ class HttpCli(object): dbv, vrem = vfs.get_dbv(rem) if not self.can_delete and ( - "." not in rem or rem.rsplit(".", 1)[1].lower() not in self.args.rw_edit_set + "." not in rem + or rem.rsplit(".", 1)[1].lower() not in vfs.flags["rw_edit_set"] ): t = "you can only edit %s files because you don't have the delete-permission" - raise Pebkac(400, t % (self.args.rw_edit.replace(",", "/"))) + raise Pebkac(400, t % (vfs.flags["rw_edit"].replace(",", "/"))) if nullwrite: response = json.dumps({"ok": True, "lastmod": 0}) @@ -6881,13 +6882,20 @@ class HttpCli(object): vpnodes.pop() if ( - (is_md or self.can_delete) - and "nohtml" not in vn.flags - and ( + ( (is_md and "v" in self.uparam) or "edit" in self.uparam or "edit2" in self.uparam ) + and "nohtml" not in vn.flags + and ( + is_md + or self.can_delete + or ( + "." in abspath + and abspath.rsplit(".", 1)[1].lower() in vn.flags["rw_edit_set"] + ) + ) ): return self.tx_md(vn, abspath) diff --git a/copyparty/svchub.py b/copyparty/svchub.py index 719d9db2..072f9928 100644 --- a/copyparty/svchub.py +++ b/copyparty/svchub.py @@ -1122,7 +1122,7 @@ class SvcHub(object): vs = os.path.expandvars(os.path.expanduser(vs)) setattr(al, k, vs) - for k in "idp_adm rw_edit stats_u".split(" "): + for k in "idp_adm stats_u".split(" "): vs = getattr(al, k) vsa = [x.strip() for x in vs.split(",")] vsa = [x.lower() for x in vsa if x] diff --git a/copyparty/up2k.py b/copyparty/up2k.py index b5356bfd..a3da35ab 100644 --- a/copyparty/up2k.py +++ b/copyparty/up2k.py @@ -1152,7 +1152,7 @@ class Up2k(object): ft = "\033[0;32m{}{:.0}" ff = "\033[0;35m{}{:.0}" fv = "\033[0;36m{}:\033[90m{}" - zs = "bcasechk du_iwho emb_all emb_lgs emb_mds ext_th_d html_head html_head_d html_head_s ls_q_m put_name2 mv_re_r mv_re_t rm_re_r rm_re_t srch_re_dots srch_re_nodot zipmax zipmaxn_v zipmaxs_v" + zs = "bcasechk du_iwho emb_all emb_lgs emb_mds ext_th_d html_head html_head_d html_head_s ls_q_m put_name2 mv_re_r mv_re_t rm_re_r rm_re_t rw_edit_set srch_re_dots srch_re_nodot zipmax zipmaxn_v zipmaxs_v" fx = set(zs.split()) fd = vf_bmap() fd.update(vf_cmap()) diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index 15d75169..10197b56 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -3818,6 +3818,12 @@ function fmt_ren(re, md, fmt) { } +function enre_rw_edit() { + window.re_rw_edit = new RegExp('\.(' + rw_edit.replace(/,/g, '|') + ')$', 'i'); +} +enre_rw_edit(); + + function fs_abrt() { toast.inf(30, L.fp_abrt); fileman.sn++; @@ -5161,7 +5167,7 @@ var showfile = (function () { ebi('files').style.display = ebi('gfiles').style.display = ebi('lazy').style.display = ebi('pro').style.display = ebi('epi').style.display = 'none'; ebi('dldoc').setAttribute('href', url); ebi('editdoc').setAttribute('href', addq(url, 'edit')); - ebi('editdoc').style.display = (has(perms, 'write') && (is_md || has(perms, 'delete'))) ? '' : 'none'; + ebi('editdoc').style.display = (has(perms, 'write') && (re_rw_edit.test(name) || has(perms, 'delete'))) ? '' : 'none'; var wr = ebi('bdoc'), nrend = r.nrend, @@ -7981,7 +7987,7 @@ function apply_perms(res) { if (res.cfg) rw_edit = res.rw_edit; - window.re_rw_edit = new RegExp('\.(' + rw_edit.replace(/,/g, '|') + ')$', 'i'); + enre_rw_edit(); ebi('new_mdi').innerHTML = has(perms, "delete") ? L.nmd_i1 : L.nmd_i2.format(rw_edit.replace(/,/g, '/')); widget.setvis(); @@ -8790,7 +8796,7 @@ var msel = (function () { form.onsubmit = function (e) { if (!has(perms, "delete") && !re_rw_edit.test(tb.value)) { ev(e); - toast.err(10, L.nmd_i2); + toast.err(10, L.nmd_i2.format(rw_edit.replace(/,/g, '/'))); return false; } if (tb.value) {