From 9c2c423761dd13651c24386c4874d80ed7462ba4 Mon Sep 17 00:00:00 2001 From: ed Date: Sun, 16 Mar 2025 19:28:23 +0000 Subject: [PATCH] IdP: extend ${u} with syntax to exclude by group just like before, if vpath contains ${u} then the IdP-volume is created unconditionally but this is new: ${u%+foo} creates the vol only if user is member of group foo ${u%-foo} creates the vol if user is NOT member of group foo --- copyparty/authsrv.py | 18 ++++++++++++++++-- docs/examples/docker/idp/copyparty.conf | 18 ++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/copyparty/authsrv.py b/copyparty/authsrv.py index ed728eee..256b0003 100644 --- a/copyparty/authsrv.py +++ b/copyparty/authsrv.py @@ -72,6 +72,8 @@ SSEELOG = " ({})".format(SEE_LOG) BAD_CFG = "invalid config; {}".format(SEE_LOG) SBADCFG = " ({})".format(BAD_CFG) +PTN_U_GRP = re.compile(r"\$\{u%([+-])([^}]+)\}") + class CfgEx(Exception): pass @@ -953,12 +955,24 @@ class AuthSrv(object): un_gn = [("", "")] for un, gn in un_gn: + m = PTN_U_GRP.search(dst0) + if m: + req, gnc = m.groups() + hit = gnc in (un_gns.get(un) or []) + if req == "+": + if not hit: + continue + elif hit: + continue + # if ap/vp has a user/group placeholder, make sure to keep # track so the same user/group is mapped when setting perms; # otherwise clear un/gn to indicate it's a regular volume src1 = src0.replace("${u}", un or "\n") dst1 = dst0.replace("${u}", un or "\n") + src1 = PTN_U_GRP.sub(un or "\n", src1) + dst1 = PTN_U_GRP.sub(un or "\n", dst1) if src0 == src1 and dst0 == dst1: un = "" @@ -2312,7 +2326,7 @@ class AuthSrv(object): idp_vn, _ = vfs.get(idp_vp, "*", False, False) idp_vp0 = idp_vn.vpath0 - sigils = set(re.findall(r"(\${[ug]})", idp_vp0)) + sigils = set(re.findall(r"(\${[ug][}%])", idp_vp0)) if len(sigils) > 1: t = '\nWARNING: IdP-volume "/%s" created by "/%s" has multiple IdP placeholders: %s' self.idp_warn.append(t % (idp_vp, idp_vp0, list(sigils))) @@ -2344,7 +2358,7 @@ class AuthSrv(object): elif oth_write: taxs = "WRITABLE BY %r" % (oth_write,) else: - continue + break # no sigil; not idp; safe to stop t = '\nWARNING: IdP-volume "/%s" created by "/%s" has parent/grandparent "/%s" and would be %s' self.idp_err.append(t % (idp_vp, idp_vp0, par_vn.vpath, taxs)) diff --git a/docs/examples/docker/idp/copyparty.conf b/docs/examples/docker/idp/copyparty.conf index 35dd809d..d14dd7b1 100644 --- a/docs/examples/docker/idp/copyparty.conf +++ b/docs/examples/docker/idp/copyparty.conf @@ -13,6 +13,8 @@ # because that is the data-volume in the docker containers, # because a deployment like this (with an IdP) is more commonly # seen in containerized environments -- but this is not required +# +# the example group "su" (super-user) is the admins group [global] @@ -78,6 +80,18 @@ rwmda: @${g}, @su # read-write-move-delete-admin for that group + the "su" group +[/sus/${u%+su}] # users which ARE members of group "su" gets /sus/username + /w/tank1/${u} # which will be "tank1/username" in the docker data volume + accs: + rwmda: ${u} # read-write-move-delete-admin for that username + + +[/m8s/${u%-su}] # users which are NOT members of group "su" gets /m8s/username + /w/tank2/${u} # which will be "tank2/username" in the docker data volume + accs: + rwmda: ${u} # read-write-move-delete-admin for that username + + # and create some strategic volumes to prevent anyone from gaining # unintended access to priv folders if the users/groups db is lost [/u] @@ -88,3 +102,7 @@ /w/lounge accs: rwmda: @su +[/sus] + /w/tank1 +[/m8s] + /w/tank2