mirror of
https://github.com/9001/copyparty.git
synced 2025-09-28 12:42:26 -06:00
add --auth-ord; closes #689
This commit is contained in:
parent
d30240b431
commit
543b7ea959
|
@ -676,6 +676,42 @@ def get_sects():
|
||||||
"""
|
"""
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
"auth-ord",
|
||||||
|
"authentication precedence",
|
||||||
|
dedent(
|
||||||
|
"""
|
||||||
|
\033[33m--auth-ord\033[0m is a comma-separated list of auth options
|
||||||
|
(one or more of the [\033[35moptions\033[0m] below); first one wins
|
||||||
|
|
||||||
|
[\033[35mpw\033[0m] is conventional login, for example the "\033[36mPW\033[0m" header,
|
||||||
|
or the \033[36m?pw=\033[0m[...] URL-suffix, or a valid session cookie
|
||||||
|
(see \033[33m--help-auth\033[0m)
|
||||||
|
|
||||||
|
[\033[35midp\033[0m] is a username provided in the http-request-header
|
||||||
|
defined by \033[33m--idp-h-usr\033[0m and/or \033[33m--idp-hm-usr\033[0m, which is
|
||||||
|
provided by an authentication middleware such as
|
||||||
|
authentik, authelia, tailscale, ... (see \033[33m--help-idp\033[0m)
|
||||||
|
|
||||||
|
[\033[35midp-h\033[0m] is specifically the \033[33m--idp-h-usr\033[0m header,
|
||||||
|
[\033[35midp-hm\033[0m] is specifically an \033[33m--idp-hm-usr\033[0m header;
|
||||||
|
[\033[35midp\033[0m] is the same as [\033[35midp-hm,idp-h\033[0m]
|
||||||
|
|
||||||
|
[\033[35mipu\033[0m] is a mapping from an IP-address to a username,
|
||||||
|
auto-authing that client-IP to that account
|
||||||
|
(see the description of \033[36m--ipu\033[0m in \033[33m--help\033[0m)
|
||||||
|
|
||||||
|
NOTE: even if an option (\033[35mpw\033[0m/\033[35mipu\033[0m/...) is not in the list,
|
||||||
|
it may still be enabled and can still take effect if
|
||||||
|
none of the other alternatives identify the user
|
||||||
|
|
||||||
|
NOTE: if [\033[35mipu\033[0m] is in the list, it must be FIRST or LAST
|
||||||
|
|
||||||
|
NOTE: if [\033[35mpw\033[0m] is not in the list, the logout-button
|
||||||
|
will be hidden when any idp feature is enabled
|
||||||
|
"""
|
||||||
|
),
|
||||||
|
],
|
||||||
[
|
[
|
||||||
"flags",
|
"flags",
|
||||||
"list of volflags",
|
"list of volflags",
|
||||||
|
@ -1254,6 +1290,7 @@ def add_auth(ap):
|
||||||
ap2.add_argument("--idp-store", metavar="N", type=int, default=1, help="how to use \033[33m--idp-db\033[0m; [\033[32m0\033[0m] = entirely disable, [\033[32m1\033[0m] = write-only (effectively disabled), [\033[32m2\033[0m] = remember users, [\033[32m3\033[0m] = remember users and groups.\nNOTE: Will remember and restore the IdP-volumes of all users for all eternity if set to 2 or 3, even when user is deleted from your IdP")
|
ap2.add_argument("--idp-store", metavar="N", type=int, default=1, help="how to use \033[33m--idp-db\033[0m; [\033[32m0\033[0m] = entirely disable, [\033[32m1\033[0m] = write-only (effectively disabled), [\033[32m2\033[0m] = remember users, [\033[32m3\033[0m] = remember users and groups.\nNOTE: Will remember and restore the IdP-volumes of all users for all eternity if set to 2 or 3, even when user is deleted from your IdP")
|
||||||
ap2.add_argument("--idp-adm", metavar="U,U", type=u, default="", help="comma-separated list of users allowed to use /?idp (the cache management UI)")
|
ap2.add_argument("--idp-adm", metavar="U,U", type=u, default="", help="comma-separated list of users allowed to use /?idp (the cache management UI)")
|
||||||
ap2.add_argument("--idp-cookie", metavar="S", type=int, default=0, help="generate a session-token for IdP users which is written to cookie \033[33mcppws\033[0m (or \033[33mcppwd\033[0m if plaintext), to reduce the load on the IdP server, lifetime \033[33mS\033[0m seconds.\n └─note: The expiration time is a client hint only; the actual lifetime of the session-token is infinite (until next restart with \033[33m--ses-db\033[0m wiped)")
|
ap2.add_argument("--idp-cookie", metavar="S", type=int, default=0, help="generate a session-token for IdP users which is written to cookie \033[33mcppws\033[0m (or \033[33mcppwd\033[0m if plaintext), to reduce the load on the IdP server, lifetime \033[33mS\033[0m seconds.\n └─note: The expiration time is a client hint only; the actual lifetime of the session-token is infinite (until next restart with \033[33m--ses-db\033[0m wiped)")
|
||||||
|
ap2.add_argument("--auth-ord", metavar="TXT", type=u, default="idp,ipu", help="controls auth precedence; examples: [\033[32mpw,idp,ipu\033[0m], [\033[32mipu,pw,idp\033[0m], see --help-auth-ord")
|
||||||
ap2.add_argument("--no-bauth", action="store_true", help="disable basic-authentication support; do not accept passwords from the 'Authenticate' header at all. NOTE: This breaks support for the android app")
|
ap2.add_argument("--no-bauth", action="store_true", help="disable basic-authentication support; do not accept passwords from the 'Authenticate' header at all. NOTE: This breaks support for the android app")
|
||||||
ap2.add_argument("--bauth-last", action="store_true", help="keeps basic-authentication enabled, but only as a last-resort; if a cookie is also provided then the cookie wins")
|
ap2.add_argument("--bauth-last", action="store_true", help="keeps basic-authentication enabled, but only as a last-resort; if a cookie is also provided then the cookie wins")
|
||||||
ap2.add_argument("--ses-db", metavar="PATH", type=u, default=ses_db, help="where to store the sessions database (if you run multiple copyparty instances, make sure they use different DBs)")
|
ap2.add_argument("--ses-db", metavar="PATH", type=u, default=ses_db, help="where to store the sessions database (if you run multiple copyparty instances, make sure they use different DBs)")
|
||||||
|
@ -1264,6 +1301,10 @@ def add_auth(ap):
|
||||||
ap2.add_argument("--ipr", metavar="CIDR=USR", type=u, action="append", help="\033[34mREPEATABLE:\033[0m username \033[33mUSR\033[0m can only connect from an IP matching one or more \033[33mCIDR\033[0m (comma-sep.); example: [\033[32m192.168.123.0/24,172.16.0.0/16=dave]")
|
ap2.add_argument("--ipr", metavar="CIDR=USR", type=u, action="append", help="\033[34mREPEATABLE:\033[0m username \033[33mUSR\033[0m can only connect from an IP matching one or more \033[33mCIDR\033[0m (comma-sep.); example: [\033[32m192.168.123.0/24,172.16.0.0/16=dave]")
|
||||||
ap2.add_argument("--have-idp-hdrs", type=u, default="", help=argparse.SUPPRESS)
|
ap2.add_argument("--have-idp-hdrs", type=u, default="", help=argparse.SUPPRESS)
|
||||||
ap2.add_argument("--have-ipu-or-ipr", type=u, default="", help=argparse.SUPPRESS)
|
ap2.add_argument("--have-ipu-or-ipr", type=u, default="", help=argparse.SUPPRESS)
|
||||||
|
ap2.add_argument("--ao-idp-before-pw", type=u, default="", help=argparse.SUPPRESS)
|
||||||
|
ap2.add_argument("--ao-h-before-hm", type=u, default="", help=argparse.SUPPRESS)
|
||||||
|
ap2.add_argument("--ao-ipu-wins", type=u, default="", help=argparse.SUPPRESS)
|
||||||
|
ap2.add_argument("--ao-has-pw", type=u, default="", help=argparse.SUPPRESS)
|
||||||
|
|
||||||
|
|
||||||
def add_chpw(ap):
|
def add_chpw(ap):
|
||||||
|
|
|
@ -1713,6 +1713,7 @@ class AuthSrv(object):
|
||||||
|
|
||||||
self.args.have_idp_hdrs = bool(self.args.idp_h_usr or self.args.idp_hm_usr)
|
self.args.have_idp_hdrs = bool(self.args.idp_h_usr or self.args.idp_hm_usr)
|
||||||
self.args.have_ipu_or_ipr = bool(self.args.ipu or self.args.ipr)
|
self.args.have_ipu_or_ipr = bool(self.args.ipu or self.args.ipr)
|
||||||
|
self.setup_auth_ord()
|
||||||
|
|
||||||
self.setup_pwhash(acct)
|
self.setup_pwhash(acct)
|
||||||
defpw = acct.copy()
|
defpw = acct.copy()
|
||||||
|
@ -2864,6 +2865,18 @@ class AuthSrv(object):
|
||||||
zs = str(vol.flags.get("tcolor") or self.args.tcolor)
|
zs = str(vol.flags.get("tcolor") or self.args.tcolor)
|
||||||
vol.flags["tcolor"] = zs.lstrip("#")
|
vol.flags["tcolor"] = zs.lstrip("#")
|
||||||
|
|
||||||
|
def setup_auth_ord(self) -> None:
|
||||||
|
ao = [x.strip() for x in self.args.auth_ord.split(",")]
|
||||||
|
if "idp" in ao:
|
||||||
|
zi = ao.index("idp")
|
||||||
|
ao = ao[:zi] + ["idp-hm", "idp-h"] + ao[zi:]
|
||||||
|
zsl = "pw idp-h idp-hm ipu".split()
|
||||||
|
pw, h, hm, ipu = [ao.index(x) if x in ao else 99 for x in zsl]
|
||||||
|
self.args.ao_idp_before_pw = min(h, hm) < pw
|
||||||
|
self.args.ao_h_before_hm = h < hm
|
||||||
|
self.args.ao_ipu_wins = ipu == 0
|
||||||
|
self.args.ao_have_pw = pw < 99
|
||||||
|
|
||||||
def load_idp_db(self, quiet=False) -> None:
|
def load_idp_db(self, quiet=False) -> None:
|
||||||
# mutex me
|
# mutex me
|
||||||
level = self.args.idp_store
|
level = self.args.idp_store
|
||||||
|
|
|
@ -624,7 +624,9 @@ class HttpCli(object):
|
||||||
or "*"
|
or "*"
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.args.have_idp_hdrs:
|
if self.args.have_idp_hdrs and (
|
||||||
|
self.uname == "*" or self.args.ao_idp_before_pw
|
||||||
|
):
|
||||||
idp_usr = ""
|
idp_usr = ""
|
||||||
if self.args.idp_hm_usr:
|
if self.args.idp_hm_usr:
|
||||||
for hn, hmv in self.args.idp_hm_usr_p.items():
|
for hn, hmv in self.args.idp_hm_usr_p.items():
|
||||||
|
@ -637,9 +639,9 @@ class HttpCli(object):
|
||||||
if idp_usr:
|
if idp_usr:
|
||||||
break
|
break
|
||||||
for hn in self.args.idp_h_usr:
|
for hn in self.args.idp_h_usr:
|
||||||
if idp_usr:
|
if idp_usr and not self.args.ao_h_before_hm:
|
||||||
break
|
break
|
||||||
idp_usr = self.headers.get(hn)
|
idp_usr = self.headers.get(hn) or idp_usr
|
||||||
if idp_usr:
|
if idp_usr:
|
||||||
idp_grp = (
|
idp_grp = (
|
||||||
self.headers.get(self.args.idp_h_grp) or ""
|
self.headers.get(self.args.idp_h_grp) or ""
|
||||||
|
@ -688,7 +690,10 @@ class HttpCli(object):
|
||||||
if idp_usr in self.asrv.vfs.aread:
|
if idp_usr in self.asrv.vfs.aread:
|
||||||
self.pw = ""
|
self.pw = ""
|
||||||
self.uname = idp_usr
|
self.uname = idp_usr
|
||||||
self.html_head += "<script>var is_idp=1</script>\n"
|
if self.args.ao_have_pw:
|
||||||
|
self.html_head += "<script>var is_idp=1</script>\n"
|
||||||
|
else:
|
||||||
|
self.html_head += "<script>var is_idp=2</script>\n"
|
||||||
zs = self.asrv.ases.get(idp_usr)
|
zs = self.asrv.ases.get(idp_usr)
|
||||||
if zs:
|
if zs:
|
||||||
self.set_idp_cookie(zs)
|
self.set_idp_cookie(zs)
|
||||||
|
@ -696,7 +701,7 @@ class HttpCli(object):
|
||||||
self.log("unknown username: %r" % (idp_usr,), 1)
|
self.log("unknown username: %r" % (idp_usr,), 1)
|
||||||
|
|
||||||
if self.args.have_ipu_or_ipr:
|
if self.args.have_ipu_or_ipr:
|
||||||
if self.args.ipu and self.uname == "*":
|
if self.args.ipu and (self.uname == "*" or self.args.ao_ipu_wins):
|
||||||
self.uname = self.conn.ipu_iu[self.conn.ipu_nm.map(self.ip)]
|
self.uname = self.conn.ipu_iu[self.conn.ipu_nm.map(self.ip)]
|
||||||
ipr = self.conn.hsrv.ipr
|
ipr = self.conn.hsrv.ipr
|
||||||
if ipr and self.uname in ipr:
|
if ipr and self.uname in ipr:
|
||||||
|
|
|
@ -834,7 +834,7 @@ if (o1 && o2 && d.lo3)
|
||||||
o1.setAttribute("value", d.lo3.format(o2.textContent));
|
o1.setAttribute("value", d.lo3.format(o2.textContent));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (is_idp) {
|
if (is_idp > 1) {
|
||||||
var z = ['#l+div', '#l', '#c'];
|
var z = ['#l+div', '#l', '#c'];
|
||||||
for (var a = 0; a < z.length; a++)
|
for (var a = 0; a < z.length; a++)
|
||||||
QS(z[a]).style.display = 'none';
|
QS(z[a]).style.display = 'none';
|
||||||
|
|
|
@ -183,6 +183,7 @@ class Cfg(Namespace):
|
||||||
v=v or [],
|
v=v or [],
|
||||||
c=c,
|
c=c,
|
||||||
E=E,
|
E=E,
|
||||||
|
auth_ord="idp,ipu",
|
||||||
bup_ck="sha512",
|
bup_ck="sha512",
|
||||||
chmod_d="755",
|
chmod_d="755",
|
||||||
cookie_cmax=8192,
|
cookie_cmax=8192,
|
||||||
|
|
Loading…
Reference in a new issue