summaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node/tests/test_roster_pairing.py
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-node/tests/test_roster_pairing.py')
-rw-r--r--packages/meshbay-node/tests/test_roster_pairing.py49
1 files changed, 49 insertions, 0 deletions
diff --git a/packages/meshbay-node/tests/test_roster_pairing.py b/packages/meshbay-node/tests/test_roster_pairing.py
index a2f7cd1..a5a48e4 100644
--- a/packages/meshbay-node/tests/test_roster_pairing.py
+++ b/packages/meshbay-node/tests/test_roster_pairing.py
@@ -756,3 +756,52 @@ def test_admin_authority_is_never_fetched_from_the_hub():
assert "admin_pk_ed25519" not in daemon, (
"the node.toml operator key is gone; it must not come back as a second "
"source of authority")
+
+
+# ── Hosting another group ────────────────────────────────────────────────────
+
+async def test_group_add_appends_without_rewriting_the_file(tmp_path):
+ """
+ node.toml is hand-written and full of comments explaining decisions. The
+ block is appended as text for that reason: a round trip through a TOML
+ writer would silently throw all of it away.
+ """
+ from meshbay_node.config import load_config
+
+ conf = tmp_path / "node.toml"
+ conf.write_text(
+ '# keep me\n[hub]\nurl = "https://meshbay.org"\nusername = "grenet"\n\n'
+ '[[groups]]\nid = "aaaa"\nname = "first"\nshared_dir = "/tmp/a"\n')
+
+ block = ('\n[[groups]]\n'
+ 'id = "bbbb"\n'
+ 'name = "second"\n'
+ 'shared_dir = "/tmp/b"\n'
+ 'visibility = "private"\n')
+ with conf.open("a") as f:
+ f.write(block)
+
+ assert "# keep me" in conf.read_text(), "comments must survive"
+ cfg = load_config(conf)
+ assert [g.name for g in cfg.groups] == ["first", "second"]
+ assert [g.shared_dir for g in cfg.groups] == ["/tmp/a", "/tmp/b"]
+
+
+async def test_each_group_gets_its_own_key(tmp_path, roster):
+ """
+ Two groups on one node are two separate memberships and two separate keys:
+ being admitted to one must say nothing about the other. This is the property
+ that makes hosting a second group meaningful rather than cosmetic.
+ """
+ from meshbay_common.crypto import generate_gek
+
+ gek_a, gek_b = generate_gek(), generate_gek()
+ assert gek_a != gek_b
+
+ sk_ed, pk_ed_b64, pk_x_b64 = _keypair()
+ await roster.pin_identity("member", "member", pk_ed_b64, pk_x_b64, "code")
+ await roster.set_member("group-a", "member", ROLE_MEMBER, "active", "op")
+
+ assert await roster.is_authorized("group-a", "member") is True
+ assert await roster.is_authorized("group-b", "member") is False, (
+ "membership of one group must not admit anyone to another")