mirror of
https://github.com/CyberMind-FR/secubox-deb.git
synced 2026-07-29 17:37:13 +00:00
fix(assist): join link defaults to the public hub URL, not hostname.local
The joinlink base_url defaulted to https://assist.local (LAN-only), so a shared assistance join link was unreachable over the internet. Derive the public hub from [api].sso_cookie_domain in secubox.conf (.gk2.secubox.in -> https://admin.gk2.secubox.in); ASSIST_BASE_URL/--base-url still override; falls back to assist.local only when no domain is configured. Same public-base-URL pattern as the Nextcloud _public_base_url fix. Co-Authored-By: Gerald KERMA <devel@cybermind.fr>
This commit is contained in:
parent
aec4353657
commit
9776112de1
|
|
@ -8,8 +8,14 @@ secubox-assist (0.2.1-1~bookworm1) bookworm; urgency=medium
|
|||
running as `secubox` via the API, can reach the node signing key to sign
|
||||
journal ops (offer/request/session) — the shared parent's root:secubox-toolbox
|
||||
0750 blocked it. Never chowns/tightens the parent; subdirs keep 0700.
|
||||
* joinlink: the shared join URL now defaults to the PUBLIC hub
|
||||
(https://admin.<domain>, derived from [api].sso_cookie_domain in
|
||||
secubox.conf) instead of the LAN-only https://assist.local, so an
|
||||
assistance join link is reachable over the internet. ASSIST_BASE_URL /
|
||||
--base-url still override; falls back to assist.local only when no domain
|
||||
is configured.
|
||||
|
||||
-- Gerald KERMA <devel@cybermind.fr> Sat, 26 Jul 2026 06:00:00 +0200
|
||||
-- Gerald KERMA <devel@cybermind.fr> Sun, 26 Jul 2026 10:10:00 +0200
|
||||
|
||||
secubox-assist (0.2.0-1~bookworm1) bookworm; urgency=medium
|
||||
|
||||
|
|
|
|||
|
|
@ -79,9 +79,11 @@ Env (override; keys are NEVER generated here):
|
|||
DRYRUN=1 print {"dryrun": true, "would": ...}; write nothing —
|
||||
no journal append, nothing minted, `list` afterwards
|
||||
is unchanged.
|
||||
ASSIST_BASE_URL default https://assist.local — base url `joinlink`
|
||||
prefixes the single-use token with (override with
|
||||
--base-url).
|
||||
ASSIST_BASE_URL public base url `joinlink` prefixes the single-use token
|
||||
with (override with --base-url). Default: derived from
|
||||
[api].sso_cookie_domain in secubox.conf -> the public hub
|
||||
https://admin.<domain>; falls back to https://assist.local
|
||||
only when no domain is configured.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
|
|
@ -156,6 +158,33 @@ def _dryrun_report(would: str, **fields) -> None:
|
|||
print(json.dumps({"dryrun": True, "would": would, **fields}))
|
||||
|
||||
|
||||
CONF_PATH = os.environ.get("SECUBOX_CONF", "/etc/secubox/secubox.conf")
|
||||
|
||||
|
||||
def _default_base_url() -> str:
|
||||
"""Public base URL that fronts /assist/join/<tok> — the canonical admin/hub
|
||||
vhost, so a shared join link is reachable over the internet, not just the
|
||||
LAN. A hostname.local link only works on the local segment.
|
||||
|
||||
Precedence: an explicit ASSIST_BASE_URL env wins; else derive the hub from
|
||||
[api].sso_cookie_domain in secubox.conf (".gk2.secubox.in" -> the hub is
|
||||
admin.gk2.secubox.in); else fall back to the LAN-only https://assist.local.
|
||||
"""
|
||||
env = os.environ.get("ASSIST_BASE_URL")
|
||||
if env:
|
||||
return env
|
||||
try:
|
||||
import tomllib
|
||||
with open(CONF_PATH, "rb") as fh:
|
||||
conf = tomllib.load(fh)
|
||||
base = str((conf.get("api", {}) or {}).get("sso_cookie_domain", "")).lstrip(".").strip()
|
||||
if base and "." in base:
|
||||
return f"https://admin.{base}"
|
||||
except Exception:
|
||||
pass
|
||||
return "https://assist.local"
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# commands
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
|
@ -509,8 +538,7 @@ def main(argv=None) -> int:
|
|||
jl = sub.add_parser("joinlink", help="mint a single-use, time-boxed join link")
|
||||
jl.add_argument("--for", dest="for_", required=True, help="opaque reference (e.g. match_id)")
|
||||
jl.add_argument("--ttl", type=int, required=True)
|
||||
jl.add_argument("--base-url", dest="base_url",
|
||||
default=os.environ.get("ASSIST_BASE_URL", "https://assist.local"))
|
||||
jl.add_argument("--base-url", dest="base_url", default=_default_base_url())
|
||||
jl.set_defaults(fn=cmd_joinlink)
|
||||
|
||||
jo = sub.add_parser("join", help="redeem a join link (plans escalate argv, does not exec)")
|
||||
|
|
|
|||
|
|
@ -67,3 +67,35 @@ def test_join_does_not_leak_private_key(tmp_path):
|
|||
assert not (len(stripped) == 64 and all(c in "0123456789abcdef"
|
||||
for c in stripped.lower())), (
|
||||
f"raw 64-hex secret leaked in join output: {stripped!r}")
|
||||
|
||||
|
||||
def _joinlink_base_url(tmp_path, conf_body=None, extra_env=None):
|
||||
env = _env(tmp_path); env["DRYRUN"] = "1"
|
||||
if conf_body is not None:
|
||||
conf = tmp_path / "secubox.conf"; conf.write_text(conf_body)
|
||||
env["SECUBOX_CONF"] = str(conf)
|
||||
else:
|
||||
env["SECUBOX_CONF"] = str(tmp_path / "does-not-exist.conf")
|
||||
env.pop("ASSIST_BASE_URL", None)
|
||||
if extra_env:
|
||||
env.update(extra_env)
|
||||
r = subprocess.run([sys.executable, CTL, "joinlink", "--for", "m1", "--ttl", "600"],
|
||||
env=env, capture_output=True, text=True)
|
||||
assert r.returncode == 0, r.stderr
|
||||
return json.loads(r.stdout)["base_url"]
|
||||
|
||||
|
||||
def test_joinlink_base_url_derived_from_sso_cookie_domain(tmp_path):
|
||||
# a hostname.local link only works on the LAN; derive the public hub instead
|
||||
url = _joinlink_base_url(tmp_path, '[api]\nsso_cookie_domain = ".gk2.secubox.in"\n')
|
||||
assert url == "https://admin.gk2.secubox.in"
|
||||
|
||||
|
||||
def test_joinlink_base_url_falls_back_to_local_without_domain(tmp_path):
|
||||
assert _joinlink_base_url(tmp_path, conf_body=None) == "https://assist.local"
|
||||
|
||||
|
||||
def test_joinlink_base_url_env_override_wins(tmp_path):
|
||||
url = _joinlink_base_url(tmp_path, '[api]\nsso_cookie_domain = ".gk2.secubox.in"\n',
|
||||
extra_env={"ASSIST_BASE_URL": "https://custom.example.org"})
|
||||
assert url == "https://custom.example.org"
|
||||
|
|
|
|||
|
|
@ -69,6 +69,6 @@ def test_postinst_ephemeral_block_only_touches_its_own_subdirectory():
|
|||
assert "chmod -R /etc/secubox" not in post
|
||||
|
||||
|
||||
def test_changelog_bumped_to_0_2_0():
|
||||
def test_changelog_bumped_to_0_2_1():
|
||||
changelog = (ROOT / "debian" / "changelog").read_text()
|
||||
assert changelog.startswith("secubox-assist (0.2.0-1~bookworm1)")
|
||||
assert changelog.startswith("secubox-assist (0.2.1-1~bookworm1)")
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user