xbu/xau with custom message

This commit is contained in:
ed 2025-09-26 23:49:32 +00:00
parent 397ed5653b
commit df0fa9d1b7
6 changed files with 224 additions and 95 deletions

View file

@ -0,0 +1,61 @@
#!/usr/bin/env python3
import json
import os
import re
import sys
_ = r"""
reject file upload (with a nice explanation why)
example usage as global config:
--xbu j,c1,bin/hooks/reject-and-explain.py
example usage as a volflag (per-volume config):
-v srv/inc:inc:r:rw,ed:c,xbu=j,c1,bin/hooks/reject-and-explain.py
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
(share filesystem-path srv/inc as volume /inc,
readable by everyone, read-write for user 'ed',
running this plugin on all uploads with the params listed below)
example usage as a volflag in a copyparty config file:
[/inc]
srv/inc
accs:
r: *
rw: ed
flags:
xbu: j,c1,bin/hooks/reject-and-explain.py
parameters explained,
xbu = execute-before-upload (can also be xau, execute-after-upload)
j = this hook needs upload information as json (not just the filename)
c1 = this hook returns json on stdout, so tell copyparty to read that
"""
def main():
inf = json.loads(sys.argv[1])
vdir, fn = os.path.split(inf["vp"])
print("inf[vp] = %r" % (inf["vp"],), file=sys.stderr)
# reject upload if the following regex-pattern does not match:
ok = re.search(r"(^|/)day[0-9]+$", vdir, re.IGNORECASE)
if ok:
# allow the upload
print("{}")
return
# the upload was rejected; display the following errortext
# (NOTE: you can optionally mention {0!r} anywhere in the message (zero or more times), and it will be replaced with the file's URL)
errmsg = "Files can only be uploaded into a folder named 'DayN' where N is a number, for example 'Day573'. This file was REJECTED: "
errmsg += inf["vp"] # mention the file's url at the end of the message
print(json.dumps({"rejectmsg": errmsg}))
if __name__ == "__main__":
main()

View file

@ -493,24 +493,30 @@ class FtpHandler(FTPHandler):
return
self.vfs_map[ap] = vp
xbu = vfs.flags.get("xbu")
if xbu and not runhook(
None,
None,
self.hub.up2k,
"xbu.ftpd",
xbu,
ap,
vp,
"",
self.uname,
self.hub.asrv.vfs.get_perms(vp, self.uname),
0,
0,
self.cli_ip,
time.time(),
"",
):
raise FSE("Upload blocked by xbu server config")
if xbu:
hr = runhook(
None,
None,
self.hub.up2k,
"xbu.ftpd",
xbu,
ap,
vp,
"",
self.uname,
self.hub.asrv.vfs.get_perms(vp, self.uname),
0,
0,
self.cli_ip,
time.time(),
"",
)
t = hr.get("rejectmsg") or ""
if t or not hr:
if not t:
t = "Upload blocked by xbu server config: %r" % (vp,)
self.respond("550 %s" % (t,), logging.info)
return
# print("ftp_STOR: {} {} => {}".format(vp, mode, ap))
ret = FTPHandler.ftp_STOR(self, file, mode)

View file

@ -2268,8 +2268,10 @@ class HttpCli(object):
at,
"",
)
if not hr:
t = "upload blocked by xbu server config"
t = hr.get("rejectmsg") or ""
if t or not hr:
if not t:
t = "upload blocked by xbu server config: %r" % (vp,)
self.log(t, 1)
raise Pebkac(403, t)
if hr.get("reloc"):
@ -2401,8 +2403,10 @@ class HttpCli(object):
at,
"",
)
if not hr:
t = "upload blocked by xau server config"
t = hr.get("rejectmsg") or ""
if t or not hr:
if not t:
t = "upload blocked by xau server config: %r" % (vp,)
self.log(t, 1)
wunlink(self.log, path, vfs.flags)
raise Pebkac(403, t)
@ -3214,11 +3218,38 @@ class HttpCli(object):
new_file += ".md"
sanitized = sanitize_fn(new_file, "")
fdir = vfs.canonical(rem)
fn = os.path.join(fdir, sanitized)
for hn in ("xbu", "xau"):
xxu = vfs.flags.get(hn)
if xxu:
hr = runhook(
self.log,
self.conn.hsrv.broker,
None,
"%s.http.new-md" % (hn,),
xxu,
fn,
vjoin(self.vpath, sanitized),
self.host,
self.uname,
self.asrv.vfs.get_perms(self.vpath, self.uname),
time.time(),
0,
self.ip,
time.time(),
"",
)
t = hr.get("rejectmsg") or ""
if t or not hr:
if not t:
t = "new-md blocked by " + hn + " server config: %r"
t = t % (vjoin(vfs.vpath, rem),)
self.log(t, 1)
raise Pebkac(403, t)
if not nullwrite:
fdir = vfs.canonical(rem)
fn = os.path.join(fdir, sanitized)
if bos.path.exists(fn):
raise Pebkac(500, "that file exists already")
@ -3382,8 +3413,11 @@ class HttpCli(object):
at,
"",
)
if not hr:
t = "upload blocked by xbu server config"
t = hr.get("rejectmsg") or ""
if t or not hr:
if not t:
t = "upload blocked by xbu server config: %r"
t = t % (vjoin(upload_vpath, fname),)
self.log(t, 1)
raise Pebkac(403, t)
if hr.get("reloc"):
@ -3486,8 +3520,11 @@ class HttpCli(object):
at,
"",
)
if not hr:
t = "upload blocked by xau server config"
t = hr.get("rejectmsg") or ""
if t or not hr:
if not t:
t = "upload blocked by xau server config: %r"
t = t % (vjoin(upload_vpath, fname),)
self.log(t, 1)
wunlink(self.log, abspath, vfs.flags)
raise Pebkac(403, t)
@ -3779,7 +3816,7 @@ class HttpCli(object):
xbu = vfs.flags.get("xbu")
if xbu:
if not runhook(
hr = runhook(
self.log,
self.conn.hsrv.broker,
None,
@ -3795,8 +3832,11 @@ class HttpCli(object):
self.ip,
time.time(),
"",
):
t = "save blocked by xbu server config"
)
t = hr.get("rejectmsg") or ""
if t or not hr:
if not t:
t = "save blocked by xbu server config"
self.log(t, 1)
raise Pebkac(403, t)
@ -3823,27 +3863,31 @@ class HttpCli(object):
sha512 = sha512[:56]
xau = vfs.flags.get("xau")
if xau and not runhook(
self.log,
self.conn.hsrv.broker,
None,
"xau.http.txt",
xau,
fp,
self.vpath,
self.host,
self.uname,
self.asrv.vfs.get_perms(self.vpath, self.uname),
new_lastmod,
sz,
self.ip,
new_lastmod,
"",
):
t = "save blocked by xau server config"
self.log(t, 1)
wunlink(self.log, fp, vfs.flags)
raise Pebkac(403, t)
if xau:
hr = runhook(
self.log,
self.conn.hsrv.broker,
None,
"xau.http.txt",
xau,
fp,
self.vpath,
self.host,
self.uname,
self.asrv.vfs.get_perms(self.vpath, self.uname),
new_lastmod,
sz,
self.ip,
new_lastmod,
"",
)
t = hr.get("rejectmsg") or ""
if t or not hr:
if not t:
t = "save blocked by xau server config"
self.log(t, 1)
wunlink(self.log, fp, vfs.flags)
raise Pebkac(403, t)
self.conn.hsrv.broker.say(
"up2k.hash_file",

View file

@ -246,24 +246,29 @@ class SMB(object):
ap = absreal(ap)
xbu = vfs.flags.get("xbu")
if xbu and not runhook(
self.nlog,
None,
self.hub.up2k,
"xbu.smb",
xbu,
ap,
vpath,
"",
"",
"",
0,
0,
"1.7.6.2",
time.time(),
"",
):
yeet("blocked by xbu server config: %r" % (vpath,))
if xbu:
hr = runhook(
self.nlog,
None,
self.hub.up2k,
"xbu.smb",
xbu,
ap,
vpath,
"",
"",
"",
0,
0,
"1.7.6.2",
time.time(),
"",
)
t = hr.get("rejectmsg") or ""
if t or not hr:
if not t:
t = "blocked by xbu server config: %r" % (vpath,)
yeet(t)
ret = bos.open(ap, flags, *a, mode=chmod, **ka)
if wr:

View file

@ -363,24 +363,29 @@ class Tftpd(object):
yeet("blocked write; folder not world-deletable: /%s" % (vpath,))
xbu = vfs.flags.get("xbu")
if xbu and not runhook(
self.nlog,
None,
self.hub.up2k,
"xbu.tftpd",
xbu,
ap,
vpath,
"",
"",
"",
0,
0,
"8.3.8.7",
time.time(),
"",
):
yeet("blocked by xbu server config: %r" % (vpath,))
if xbu:
hr = runhook(
self.nlog,
None,
self.hub.up2k,
"xbu.tftpd",
xbu,
ap,
vpath,
"",
"",
"",
0,
0,
"8.3.8.7",
time.time(),
"",
)
t = hr.get("rejectmsg") or ""
if t or not hr:
if not t:
t = "upload blocked by xbu server config: %r" % (vpath,)
yeet(t)
if not self.args.tftp_nols and bos.path.isdir(ap):
return self._ls(vpath, "", 0, True)

View file

@ -3300,8 +3300,11 @@ class Up2k(object):
job["at"],
"",
)
if not hr:
t = "upload blocked by xbu server config: %r" % (dst,)
t = hr.get("rejectmsg") or ""
if t or not hr:
if not t:
t = "upload blocked by xbu server config: %r"
t = t % (vp,)
self.log(t, 1)
raise Pebkac(403, t)
if hr.get("reloc"):
@ -3981,8 +3984,11 @@ class Up2k(object):
at or time.time(),
"",
)
if not hr:
t = "upload blocked by xau server config"
t = hr.get("rejectmsg") or ""
if t or not hr:
if not t:
t = "upload blocked by xau server config: %r"
t = t % (djoin(vtop, rd, fn),)
self.log(t, 1)
wunlink(self.log, dst, vflags)
self.registry[ptop].pop(wark, None)
@ -5132,8 +5138,10 @@ class Up2k(object):
job["t0"],
"",
)
if not hr:
t = "upload blocked by xbu server config: %r" % (vp_chk,)
t = hr.get("rejectmsg") or ""
if t or not hr:
if not t:
t = "upload blocked by xbu server config: %r" % (vp_chk,)
self.log(t, 1)
raise Pebkac(403, t)
if hr.get("reloc"):