new permission G returns filekey on write-only uploads

This commit is contained in:
ed 2022-10-08 01:17:41 +02:00
parent b8a93e74bf
commit d8bddede6a
5 changed files with 48 additions and 20 deletions

View file

@ -879,7 +879,7 @@ def main(argv: Optional[list[str]] = None) -> None:
if re.match("c[^,]", opt):
mod = True
na.append("c," + opt[1:])
elif re.sub("^[rwmdg]*", "", opt) and "," not in opt:
elif re.sub("^[rwmdgG]*", "", opt) and "," not in opt:
mod = True
perm = opt[0]
if perm == "a":

View file

@ -58,18 +58,20 @@ class AXS(object):
umove: Optional[Union[list[str], set[str]]] = None,
udel: Optional[Union[list[str], set[str]]] = None,
uget: Optional[Union[list[str], set[str]]] = None,
upget: Optional[Union[list[str], set[str]]] = None,
) -> None:
self.uread: set[str] = set(uread or [])
self.uwrite: set[str] = set(uwrite or [])
self.umove: set[str] = set(umove or [])
self.udel: set[str] = set(udel or [])
self.uget: set[str] = set(uget or [])
self.upget: set[str] = set(upget or [])
def __repr__(self) -> str:
return "AXS({})".format(
", ".join(
"{}={!r}".format(k, self.__dict__[k])
for k in "uread uwrite umove udel uget".split()
for k in "uread uwrite umove udel uget upget".split()
)
)
@ -293,6 +295,7 @@ class VFS(object):
self.amove: dict[str, list[str]] = {}
self.adel: dict[str, list[str]] = {}
self.aget: dict[str, list[str]] = {}
self.apget: dict[str, list[str]] = {}
if realpath:
self.histpath = os.path.join(realpath, ".hist") # db / thumbcache
@ -384,8 +387,10 @@ class VFS(object):
return self, vpath
def can_access(self, vpath: str, uname: str) -> tuple[bool, bool, bool, bool, bool]:
"""can Read,Write,Move,Delete,Get"""
def can_access(
self, vpath: str, uname: str
) -> tuple[bool, bool, bool, bool, bool, bool]:
"""can Read,Write,Move,Delete,Get,Upget"""
vn, _ = self._find(vpath)
c = vn.axs
return (
@ -394,6 +399,7 @@ class VFS(object):
uname in c.umove or "*" in c.umove,
uname in c.udel or "*" in c.udel,
uname in c.uget or "*" in c.uget,
uname in c.upget or "*" in c.upget,
)
def get(
@ -728,7 +734,7 @@ class AuthSrv(object):
def _read_vol_str(
self, lvl: str, uname: str, axs: AXS, flags: dict[str, Any]
) -> None:
if lvl.strip("crwmdg"):
if lvl.strip("crwmdgG"):
raise Exception("invalid volflag: {},{}".format(lvl, uname))
if lvl == "c":
@ -758,7 +764,9 @@ class AuthSrv(object):
("m", axs.umove),
("d", axs.udel),
("g", axs.uget),
]:
("G", axs.uget),
("G", axs.upget),
]: # b bb bbb
if ch in lvl:
al.add(un)
@ -808,7 +816,7 @@ class AuthSrv(object):
if self.args.v:
# list of src:dst:permset:permset:...
# permset is <rwmdg>[,username][,username] or <c>,<flag>[=args]
# permset is <rwmdgG>[,username][,username] or <c>,<flag>[=args]
for v_str in self.args.v:
m = re_vol.match(v_str)
if not m:
@ -873,7 +881,7 @@ class AuthSrv(object):
vfs.all_vols = {}
vfs.get_all_vols(vfs.all_vols)
for perm in "read write move del get".split():
for perm in "read write move del get pget".split():
axs_key = "u" + perm
unames = ["*"] + list(acct.keys())
umap: dict[str, list[str]] = {x: [] for x in unames}
@ -888,7 +896,7 @@ class AuthSrv(object):
all_users = {}
missing_users = {}
for axs in daxs.values():
for d in [axs.uread, axs.uwrite, axs.umove, axs.udel, axs.uget]:
for d in [axs.uread, axs.uwrite, axs.umove, axs.udel, axs.uget, axs.upget]:
for usr in d:
all_users[usr] = 1
if usr != "*" and usr not in acct:
@ -1193,6 +1201,7 @@ class AuthSrv(object):
[" move", "umove"],
["delete", "udel"],
[" get", "uget"],
[" upget", "upget"],
]:
u = list(sorted(getattr(zv.axs, attr)))
u = ", ".join("\033[35meverybody\033[0m" if x == "*" else x for x in u)
@ -1288,10 +1297,11 @@ class AuthSrv(object):
raise Exception("volume not found: " + zs)
self.log(str({"users": users, "vols": vols, "flags": flags}))
t = "/{}: read({}) write({}) move({}) del({}) get({})"
t = "/{}: read({}) write({}) move({}) del({}) get({}) upget({})"
for k, zv in self.vfs.all_vols.items():
vc = zv.axs
self.log(t.format(k, vc.uread, vc.uwrite, vc.umove, vc.udel, vc.uget))
vs = [k, vc.uread, vc.uwrite, vc.umove, vc.udel, vc.uget, vc.upget]
self.log(t.format(*vs))
flag_v = "v" in flags
flag_ln = "ln" in flags

View file

@ -94,6 +94,9 @@ class FtpFs(AbstractedFS):
self.cwd = "/" # pyftpdlib convention of leading slash
self.root = "/var/lib/empty"
self.can_read = self.can_write = self.can_move = False
self.can_delete = self.can_get = self.can_upget = False
self.listdirinfo = self.listdir
self.chdir(".")
@ -153,8 +156,14 @@ class FtpFs(AbstractedFS):
def chdir(self, path: str) -> None:
self.cwd = join(self.cwd, path)
x = self.hub.asrv.vfs.can_access(self.cwd.lstrip("/"), self.h.username)
self.can_read, self.can_write, self.can_move, self.can_delete, self.can_get = x
(
self.can_read,
self.can_write,
self.can_move,
self.can_delete,
self.can_get,
self.can_upget,
) = self.hub.asrv.vfs.can_access(self.cwd.lstrip("/"), self.h.username)
def mkdir(self, path: str) -> None:
ap = self.rv2a(path, w=True)

View file

@ -147,6 +147,7 @@ class HttpCli(object):
self.can_move = False
self.can_delete = False
self.can_get = False
self.can_upget = False
# post
self.parser: Optional[MultipartParser] = None
# end placeholders
@ -363,6 +364,7 @@ class HttpCli(object):
self.mvol = self.asrv.vfs.amove[self.uname]
self.dvol = self.asrv.vfs.adel[self.uname]
self.gvol = self.asrv.vfs.aget[self.uname]
self.upvol = self.asrv.vfs.apget[self.uname]
if pwd:
self.out_headerlist.append(("Set-Cookie", self.get_pwd_cookie(pwd)[0]))
@ -376,8 +378,14 @@ class HttpCli(object):
ptn: Optional[Pattern[str]] = self.conn.lf_url # mypy404
self.do_log = not ptn or not ptn.search(self.req)
x = self.asrv.vfs.can_access(self.vpath, self.uname)
self.can_read, self.can_write, self.can_move, self.can_delete, self.can_get = x
(
self.can_read,
self.can_write,
self.can_move,
self.can_delete,
self.can_get,
self.can_upget,
) = self.asrv.vfs.can_access(self.vpath, self.uname)
try:
if self.mode in ["GET", "HEAD"]:
@ -885,7 +893,7 @@ class HttpCli(object):
)
vsuf = ""
if self.can_read and "fk" in vfs.flags:
if (self.can_read or self.can_upget) and "fk" in vfs.flags:
vsuf = "?k=" + self.gen_fk(
self.args.fk_salt,
path,
@ -1544,7 +1552,7 @@ class HttpCli(object):
for sz, sha_hex, sha_b64, ofn, lfn, ap in files:
vsuf = ""
if self.can_read and "fk" in vfs.flags:
if (self.can_read or self.can_upget) and "fk" in vfs.flags:
vsuf = "?k=" + self.gen_fk(
self.args.fk_salt,
ap,
@ -2494,9 +2502,8 @@ class HttpCli(object):
if not is_dir and (self.can_read or self.can_get):
if not self.can_read and "fk" in vn.flags:
vabs = vjoin(vn.realpath, rem)
correct = self.gen_fk(
self.args.fk_salt, vabs, st.st_size, 0 if ANYWIN else st.st_ino
self.args.fk_salt, abspath, st.st_size, 0 if ANYWIN else st.st_ino
)[: vn.flags["fk"]]
got = self.uparam.get("k")
if got != correct:
@ -2541,6 +2548,8 @@ class HttpCli(object):
perms.append("delete")
if self.can_get:
perms.append("get")
if self.can_upget:
perms.append("upget")
url_suf = self.urlq({}, ["k"])
is_ls = "ls" in self.uparam

View file

@ -422,7 +422,7 @@ class SvcHub(object):
with self.log_mutex:
ts = datetime.utcnow().strftime("%Y-%m%d-%H%M%S.%f")[:-3]
self.logf.write("@{} [{}] {}\n".format(ts, src, msg))
self.logf.write("@{} [{}\033[0m] {}\n".format(ts, src, msg))
now = time.time()
if now >= self.next_day: