summaryrefslogtreecommitdiffstats
path: root/packages/meshbay-common/tests/test_handshake.py
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-common/tests/test_handshake.py')
-rw-r--r--packages/meshbay-common/tests/test_handshake.py34
1 files changed, 34 insertions, 0 deletions
diff --git a/packages/meshbay-common/tests/test_handshake.py b/packages/meshbay-common/tests/test_handshake.py
index 8981db8..d4f6d2b 100644
--- a/packages/meshbay-common/tests/test_handshake.py
+++ b/packages/meshbay-common/tests/test_handshake.py
@@ -223,3 +223,37 @@ def test_membership_refusal_carries_a_code_a_client_can_act_on():
with pytest.raises(HandshakeError) as excinfo:
authorize_token(token, pem_pub, group_id="g" * 32)
assert excinfo.value.code == "not_a_member"
+
+
+def test_a_group_this_node_does_not_host_is_refused_with_a_code():
+ """
+ A client is handed every node the hub registered for a group, and only some
+ of them may be able to serve it. Telling "try the next node" apart from
+ "you, here, must do something first" is what this code is for: without it
+ the client either stopped at the first refusal — which is how a group went
+ dark on 2026-09-11 with its real host online — or had to match on wording.
+ """
+ import jwt as _jwt
+ from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
+ from cryptography.hazmat.primitives import serialization
+
+ sk = Ed25519PrivateKey.generate()
+ pem_priv = sk.private_bytes(
+ serialization.Encoding.PEM, serialization.PrivateFormat.PKCS8,
+ serialization.NoEncryption())
+ pem_pub = sk.public_key().public_bytes(
+ serialization.Encoding.PEM, serialization.PublicFormat.SubjectPublicKeyInfo)
+
+ group = "g" * 32
+ token = _jwt.encode(
+ {"sub": "u1", "jti": "j1", "scope": "user", "groups": [group]},
+ pem_priv, algorithm="EdDSA")
+
+ # A member of the group, on a node that does not host it.
+ with pytest.raises(HandshakeError) as excinfo:
+ authorize_token(token, pem_pub, group_id=group, hosted_groups={"other"})
+ assert excinfo.value.code == "not_hosted"
+
+ # And the node that does host it still lets them in.
+ peer = authorize_token(token, pem_pub, group_id=group, hosted_groups={group})
+ assert peer.group_id == group