show h vols in ls and tree,

and compensate with some optimizations
This commit is contained in:
ed 2025-10-23 21:44:28 +00:00
parent 7f5810f1a7
commit fff7291dcf
4 changed files with 69 additions and 45 deletions

View file

@ -393,11 +393,15 @@ class VFS(object):
axs: AXS,
flags: dict[str, Any],
) -> None:
nss: set[str] = set()
self.log = log
self.realpath = realpath # absolute path on host filesystem
self.vpath = vpath # absolute path in the virtual filesystem
self.vpath0 = vpath0 # original vpath (before idp expansion)
self.axs = axs
self.uaxs: dict[
str, tuple[bool, bool, bool, bool, bool, bool, bool, bool, bool]
] = {}
self.flags = flags # config options
self.root = self
self.dev = 0 # st_dev
@ -555,29 +559,19 @@ class VFS(object):
def can_access(
self, vpath: str, uname: str
) -> tuple[bool, bool, bool, bool, bool, bool, bool, bool]:
"""can Read,Write,Move,Delete,Get,Upget,Admin,Dot"""
) -> tuple[bool, bool, bool, bool, bool, bool, bool, bool, bool]:
"""can Read,Write,Move,Delete,Get,Upget,Html,Admin,Dot"""
# NOTE: only used by get_perms, which is only used by hooks; the lowest of fruits
if vpath:
vn, _ = self._find(undot(vpath))
else:
vn = self
c = vn.axs
return (
uname in c.uread,
uname in c.uwrite,
uname in c.umove,
uname in c.udel,
uname in c.uget,
uname in c.upget,
uname in c.uadmin,
uname in c.udot,
)
# skip uhtml because it's rarely needed
return vn.uaxs[uname]
def get_perms(self, vpath: str, uname: str) -> str:
zbl = self.can_access(vpath, uname)
ret = "".join(ch for ch, ok in zip("rwmdgGa.", zbl) if ok)
ret = "".join(ch for ch, ok in zip("rwmdgGha.", zbl) if ok)
if "rwmd" in ret and "a." in ret:
ret += "A"
return ret
@ -772,20 +766,17 @@ class VFS(object):
virt_vis[name] = vn2
continue
ok = False
zx = vn2.axs
axs = [zx.uread, zx.uwrite, zx.umove, zx.udel, zx.uget]
u_has = vn2.uaxs.get(uname) or [False] * 9
for pset in permsets:
ok = True
for req, lst in zip(pset, axs):
if req and uname not in lst:
for req, zb in zip(pset, u_has):
if req and not zb:
ok = False
break
if ok:
virt_vis[name] = vn2
break
if ok:
virt_vis[name] = vn2
if ".hist" in abspath:
p = abspath.replace("\\", "/") if WINDOWS else abspath
if p.endswith("/.hist"):
@ -1995,6 +1986,23 @@ class AuthSrv(object):
umap[usr].sort()
setattr(vfs, "a" + perm, umap)
for vol in vfs.all_nodes.values():
za = vol.axs
vol.uaxs = {
un: (
un in za.uread,
un in za.uwrite,
un in za.umove,
un in za.udel,
un in za.uget,
un in za.upget,
un in za.uhtml,
un in za.uadmin,
un in za.udot,
)
for un in unames
}
all_users = {}
missing_users = {}
associated_users = {}
@ -3436,7 +3444,7 @@ class AuthSrv(object):
raise Exception("volume not found: " + zs)
self.log(str({"users": users, "vols": vols, "flags": flags}))
t = "/{}: read({}) write({}) move({}) del({}) dots({}) get({}) upGet({}) uadmin({})"
t = "/{}: read({}) write({}) move({}) del({}) dots({}) get({}) upGet({}) html({}) uadmin({})"
for k, zv in self.vfs.all_vols.items():
vc = zv.axs
vs = [

View file

@ -198,7 +198,7 @@ class FtpFs(AbstractedFS):
if not avfs:
raise FSE(t.format(vpath), 1)
cr, cw, cm, cd, _, _, _, _ = avfs.can_access("", self.h.uname)
cr, cw, cm, cd, _, _, _, _, _ = avfs.uaxs[self.h.uname]
if r and not cr or w and not cw or m and not cm or d and not cd:
raise FSE(t.format(vpath), 1)
@ -250,6 +250,7 @@ class FtpFs(AbstractedFS):
td = 0
if w and need_unlink:
assert td # type: ignore # !rm
if td >= -1 and td <= self.args.ftp_wt:
# within permitted timeframe; allow overwrite or resume
do_it = True

View file

@ -165,6 +165,12 @@ RE_MDV = re.compile(r"(.*)\.([0-9]+\.[0-9]{3})(\.[Mm][Dd])$")
UPARAM_CC_OK = set("doc move tree".split())
PERMS_rwh = [
[True, False],
[False, True],
[False, False, False, False, False, False, True],
]
class HttpCli(object):
"""
@ -229,6 +235,7 @@ class HttpCli(object):
self.can_delete = False
self.can_get = False
self.can_upget = False
self.can_html = False
self.can_admin = False
self.can_dot = False
self.out_headerlist: list[tuple[str, str]] = []
@ -737,18 +744,21 @@ class HttpCli(object):
if "bcasechk" in vn.flags and not vn.casechk(rem, True):
return self.tx_404() and False
(
self.can_read,
self.can_write,
self.can_move,
self.can_delete,
self.can_get,
self.can_upget,
self.can_admin,
self.can_dot,
) = (
avn.can_access("", self.uname) if avn else [False] * 8
)
try:
(
self.can_read,
self.can_write,
self.can_move,
self.can_delete,
self.can_get,
self.can_upget,
self.can_html,
self.can_admin,
self.can_dot,
) = avn.uaxs[self.uname]
except:
pass # default is all-false
self.avn = avn
self.vn = vn # note: do not dbv due to walk/zipgen
self.rem = rem
@ -5560,7 +5570,7 @@ class HttpCli(object):
rem,
self.uname,
not self.args.no_scandir,
[[True, False], [False, True]],
PERMS_rwh,
)
dots = self.uname in vn.axs.udot
dk_sz = vn.flags.get("dk")
@ -5592,7 +5602,13 @@ class HttpCli(object):
for x in vfs_virt:
if x != excl:
try:
dvn, drem = vfs.get(vjoin(top, x), self.uname, True, False)
dvn, drem = vfs.get(vjoin(top, x), self.uname, False, False)
if (
self.uname not in dvn.axs.uread
and self.uname not in dvn.axs.uwrite
and self.uname not in dvn.axs.uhtml
):
raise Exception()
bos.stat(dvn.canonical(drem, False))
except:
x += "\n"
@ -6518,8 +6534,7 @@ class HttpCli(object):
return self.tx_svg("upload\nonly")
if not self.can_read and self.can_get and self.avn:
axs = self.avn.axs
if self.uname not in axs.uhtml:
if not self.can_html:
pass
elif is_dir:
for fn in ("index.htm", "index.html"):
@ -6734,7 +6749,7 @@ class HttpCli(object):
rem,
self.uname,
not self.args.no_scandir,
[[True, False], [False, True]],
PERMS_rwh,
lstat="lt" in self.uparam,
throw=True,
)

View file

@ -187,9 +187,9 @@ class TestVFS(unittest.TestCase):
self.assertEqual(n.realpath, os.path.join(td, "a"))
self.assertAxs(n.axs.uread, ["*", "k"])
self.assertAxs(n.axs.uwrite, [])
perm_na = (False, False, False, False, False, False, False, False)
perm_rw = (True, True, False, False, False, False, False, False)
perm_ro = (True, False, False, False, False, False, False, False)
perm_na = (False, False, False, False, False, False, False, False, False)
perm_rw = (True, True, False, False, False, False, False, False, False)
perm_ro = (True, False, False, False, False, False, False, False, False)
self.assertEqual(vfs.can_access("/", "*"), perm_na)
self.assertEqual(vfs.can_access("/", "k"), perm_rw)
self.assertEqual(vfs.can_access("/a", "*"), perm_ro)