mirror of
https://github.com/9001/copyparty.git
synced 2025-08-17 09:02:15 -06:00
new permission G returns filekey on write-only uploads
This commit is contained in:
parent
b8a93e74bf
commit
d8bddede6a
|
@ -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":
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue