diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-10-02 11:54:56 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-10-02 11:54:56 +0200 |
| commit | d7b7f1049d95e45e6316ac419cb434088c15bd5e (patch) | |
| tree | 77da46e2fe3cb70af5fb2eebcbb1d69dad410b88 /packages/meshbay-node/tests | |
| parent | 56a8cf9167e8c7b0f2df15afed88031608adf782 (diff) | |
| parent | 754387590fa1754436b4648f969915888c6f6c9e (diff) | |
| download | meshbay-d7b7f1049d95e45e6316ac419cb434088c15bd5e.tar.gz | |
Diffstat (limited to 'packages/meshbay-node/tests')
| -rw-r--r-- | packages/meshbay-node/tests/golden/dispatch.json | 4652 | ||||
| -rw-r--r-- | packages/meshbay-node/tests/test_admin_challenge_bounds.py | 45 | ||||
| -rw-r--r-- | packages/meshbay-node/tests/test_admin_ops_mnp.py | 174 | ||||
| -rw-r--r-- | packages/meshbay-node/tests/test_node_status.py | 288 | ||||
| -rw-r--r-- | packages/meshbay-node/tests/test_root_writable_policy.py | 38 | ||||
| -rw-r--r-- | packages/meshbay-node/tests/test_security_regressions.py | 97 | ||||
| -rw-r--r-- | packages/meshbay-node/tests/test_sharing_is_local_only.py | 109 |
7 files changed, 257 insertions, 5146 deletions
diff --git a/packages/meshbay-node/tests/golden/dispatch.json b/packages/meshbay-node/tests/golden/dispatch.json index a7bb543..61bbc45 100644 --- a/packages/meshbay-node/tests/golden/dispatch.json +++ b/packages/meshbay-node/tests/golden/dispatch.json @@ -76,30 +76,6 @@ "_admin_exec_file_delete" ] }, - "gek_rotate": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_admin_exec_gek_rotate" - ] - }, - "group_attach": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_admin_exec_group_attach" - ] - }, - "group_detach": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_admin_exec_group_detach" - ] - }, "invite_cancel": { "audit": [], "log": [], @@ -132,14 +108,6 @@ "_admin_exec_member_revoke" ] }, - "member_unpin": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_admin_exec_member_unpin" - ] - }, "musicbrainz_enabled": { "audit": [], "log": [], @@ -160,14 +128,6 @@ ], "spawned": [] }, - "root_add": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_admin_exec_root_add" - ] - }, "root_eject": { "audit": [], "log": [], @@ -192,14 +152,6 @@ "_admin_exec_root_remove" ] }, - "root_update": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_admin_exec_root_update" - ] - }, "search_listed": { "audit": [], "log": [], @@ -247,14 +199,6 @@ "spawned": [ "_admin_exec_tmdb_rematch" ] - }, - "transfer_limits": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_admin_exec_transfer_limits" - ] } }, "dispatch": { @@ -2068,7 +2012,7 @@ "subject": "x", "ts": "<volatile>", "type": "admin_challenge", - "v": "5.0" + "v": "6.0" } ], "spawned": [] @@ -2391,7 +2335,7 @@ "subject": "gggggggggggggggggggggggggggggggg", "ts": "<volatile>", "type": "admin_challenge", - "v": "5.0" + "v": "6.0" } ], "spawned": [] @@ -2410,7 +2354,7 @@ "subject": "['x']", "ts": "<volatile>", "type": "admin_challenge", - "v": "5.0" + "v": "6.0" } ], "spawned": [] @@ -2429,7 +2373,7 @@ "subject": "7", "ts": "<volatile>", "type": "admin_challenge", - "v": "5.0" + "v": "6.0" } ], "spawned": [] @@ -2448,7 +2392,7 @@ "subject": "x", "ts": "<volatile>", "type": "admin_challenge", - "v": "5.0" + "v": "6.0" } ], "spawned": [] @@ -2718,7 +2662,7 @@ "messages": [], "req_id": 4242, "type": "chat_hist_resp", - "v": "5.0" + "v": "6.0" } ], "spawned": [] @@ -2732,7 +2676,7 @@ "messages": [], "req_id": 4242, "type": "chat_hist_resp", - "v": "5.0" + "v": "6.0" } ], "spawned": [] @@ -2746,7 +2690,7 @@ "messages": [], "req_id": 4242, "type": "chat_hist_resp", - "v": "5.0" + "v": "6.0" } ], "spawned": [] @@ -2760,7 +2704,7 @@ "messages": [], "req_id": 4242, "type": "chat_hist_resp", - "v": "5.0" + "v": "6.0" } ], "spawned": [] @@ -2774,7 +2718,7 @@ "messages": [], "req_id": 4242, "type": "chat_hist_resp", - "v": "5.0" + "v": "6.0" } ], "spawned": [] @@ -2788,7 +2732,7 @@ "messages": [], "req_id": 4242, "type": "chat_hist_resp", - "v": "5.0" + "v": "6.0" } ], "spawned": [] @@ -2802,7 +2746,7 @@ "messages": [], "req_id": 4242, "type": "chat_hist_resp", - "v": "5.0" + "v": "6.0" } ], "spawned": [] @@ -2816,7 +2760,7 @@ "messages": [], "req_id": 4242, "type": "chat_hist_resp", - "v": "5.0" + "v": "6.0" } ], "spawned": [] @@ -4029,646 +3973,6 @@ "sent": [], "spawned": [] }, - "denylist_clear | challenged | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "denylist_clear | challenged | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "denylist_clear | challenged | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "denylist_clear | challenged | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "denylist_clear | fresh | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "denylist_clear | fresh | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "denylist_clear | fresh | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "denylist_clear | fresh | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "denylist_clear | member | bare": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_denylist_clear" - ] - }, - "denylist_clear | member | lists": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_denylist_clear" - ] - }, - "denylist_clear | member | numbers": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_denylist_clear" - ] - }, - "denylist_clear | member | strings": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_denylist_clear" - ] - }, - "denylist_clear | operator | bare": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_denylist_clear" - ] - }, - "denylist_clear | operator | lists": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_denylist_clear" - ] - }, - "denylist_clear | operator | numbers": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_denylist_clear" - ] - }, - "denylist_clear | operator | strings": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_denylist_clear" - ] - }, - "denylist_clear_ack | challenged | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "denylist_clear_ack | challenged | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "denylist_clear_ack | challenged | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "denylist_clear_ack | challenged | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "denylist_clear_ack | fresh | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "denylist_clear_ack | fresh | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "denylist_clear_ack | fresh | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "denylist_clear_ack | fresh | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "denylist_clear_ack | member | bare": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "denylist_clear_ack | member | lists": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "denylist_clear_ack | member | numbers": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "denylist_clear_ack | member | strings": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "denylist_clear_ack | operator | bare": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "denylist_clear_ack | operator | lists": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "denylist_clear_ack | operator | numbers": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "denylist_clear_ack | operator | strings": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "denylist_read | challenged | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "denylist_read | challenged | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "denylist_read | challenged | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "denylist_read | challenged | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "denylist_read | fresh | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "denylist_read | fresh | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "denylist_read | fresh | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "denylist_read | fresh | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "denylist_read | member | bare": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_denylist_read" - ] - }, - "denylist_read | member | lists": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_denylist_read" - ] - }, - "denylist_read | member | numbers": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_denylist_read" - ] - }, - "denylist_read | member | strings": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_denylist_read" - ] - }, - "denylist_read | operator | bare": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_denylist_read" - ] - }, - "denylist_read | operator | lists": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_denylist_read" - ] - }, - "denylist_read | operator | numbers": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_denylist_read" - ] - }, - "denylist_read | operator | strings": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_denylist_read" - ] - }, - "denylist_read_ack | challenged | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "denylist_read_ack | challenged | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "denylist_read_ack | challenged | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "denylist_read_ack | challenged | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "denylist_read_ack | fresh | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "denylist_read_ack | fresh | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "denylist_read_ack | fresh | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "denylist_read_ack | fresh | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "denylist_read_ack | member | bare": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "denylist_read_ack | member | lists": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "denylist_read_ack | member | numbers": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "denylist_read_ack | member | strings": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "denylist_read_ack | operator | bare": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "denylist_read_ack | operator | lists": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "denylist_read_ack | operator | numbers": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "denylist_read_ack | operator | strings": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, "device_add | challenged | bare": { "audit": [], "log": [], @@ -8377,1132 +7681,6 @@ "sent": [], "spawned": [] }, - "gek_rotate | challenged | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "gek_rotate | challenged | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "gek_rotate | challenged | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "gek_rotate | challenged | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "gek_rotate | fresh | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "gek_rotate | fresh | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "gek_rotate | fresh | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "gek_rotate | fresh | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "gek_rotate | member | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "No authorized key for this", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "gek_rotate | member | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "No authorized key for this", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "gek_rotate | member | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "No authorized key for this", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "gek_rotate | member | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "No authorized key for this", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "gek_rotate | operator | bare": { - "audit": [], - "log": [], - "sent": [ - { - "group_id": "gggggggggggggggggggggggggggggggg", - "node_pk": "iojj3XQJ8ZX9UtstPLpdcspnCb8dlBIb83SIAbQPb1w=", - "nonce": "<volatile>", - "op": "gek_rotate", - "op_id": "<volatile>", - "req_id": 4242, - "subject": "gggggggggggggggggggggggggggggggg", - "ts": "<volatile>", - "type": "admin_challenge", - "v": "5.0" - } - ], - "spawned": [] - }, - "gek_rotate | operator | lists": { - "audit": [], - "log": [], - "sent": [ - { - "group_id": "['x']", - "node_pk": "iojj3XQJ8ZX9UtstPLpdcspnCb8dlBIb83SIAbQPb1w=", - "nonce": "<volatile>", - "op": "gek_rotate", - "op_id": "<volatile>", - "req_id": 4242, - "subject": "['x']", - "ts": "<volatile>", - "type": "admin_challenge", - "v": "5.0" - } - ], - "spawned": [] - }, - "gek_rotate | operator | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "group_id": "7", - "node_pk": "iojj3XQJ8ZX9UtstPLpdcspnCb8dlBIb83SIAbQPb1w=", - "nonce": "<volatile>", - "op": "gek_rotate", - "op_id": "<volatile>", - "req_id": 4242, - "subject": "7", - "ts": "<volatile>", - "type": "admin_challenge", - "v": "5.0" - } - ], - "spawned": [] - }, - "gek_rotate | operator | strings": { - "audit": [], - "log": [], - "sent": [ - { - "group_id": "x", - "node_pk": "iojj3XQJ8ZX9UtstPLpdcspnCb8dlBIb83SIAbQPb1w=", - "nonce": "<volatile>", - "op": "gek_rotate", - "op_id": "<volatile>", - "req_id": 4242, - "subject": "x", - "ts": "<volatile>", - "type": "admin_challenge", - "v": "5.0" - } - ], - "spawned": [] - }, - "gek_rotate_ack | challenged | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "gek_rotate_ack | challenged | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "gek_rotate_ack | challenged | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "gek_rotate_ack | challenged | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "gek_rotate_ack | fresh | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "gek_rotate_ack | fresh | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "gek_rotate_ack | fresh | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "gek_rotate_ack | fresh | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "gek_rotate_ack | member | bare": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "gek_rotate_ack | member | lists": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "gek_rotate_ack | member | numbers": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "gek_rotate_ack | member | strings": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "gek_rotate_ack | operator | bare": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "gek_rotate_ack | operator | lists": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "gek_rotate_ack | operator | numbers": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "gek_rotate_ack | operator | strings": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "group_attach | challenged | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_attach | challenged | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_attach | challenged | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_attach | challenged | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_attach | fresh | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_attach | fresh | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_attach | fresh | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_attach | fresh | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_attach | member | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Missing name or shared_dir", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_attach | member | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "No authorized key for this", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_attach | member | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "No authorized key for this", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_attach | member | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "No authorized key for this", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_attach | operator | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Missing name or shared_dir", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_attach | operator | lists": { - "audit": [], - "log": [], - "sent": [ - { - "group_id": "", - "node_pk": "iojj3XQJ8ZX9UtstPLpdcspnCb8dlBIb83SIAbQPb1w=", - "nonce": "<volatile>", - "op": "group_attach", - "op_id": "<volatile>", - "req_id": 4242, - "subject": "{\"name\":\"['x']\",\"shared_dir\":\"['x']\",\"writable\":true}", - "ts": "<volatile>", - "type": "admin_challenge", - "v": "5.0" - } - ], - "spawned": [] - }, - "group_attach | operator | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "group_id": "", - "node_pk": "iojj3XQJ8ZX9UtstPLpdcspnCb8dlBIb83SIAbQPb1w=", - "nonce": "<volatile>", - "op": "group_attach", - "op_id": "<volatile>", - "req_id": 4242, - "subject": "{\"name\":\"7\",\"shared_dir\":\"7\",\"writable\":true}", - "ts": "<volatile>", - "type": "admin_challenge", - "v": "5.0" - } - ], - "spawned": [] - }, - "group_attach | operator | strings": { - "audit": [], - "log": [], - "sent": [ - { - "group_id": "", - "node_pk": "iojj3XQJ8ZX9UtstPLpdcspnCb8dlBIb83SIAbQPb1w=", - "nonce": "<volatile>", - "op": "group_attach", - "op_id": "<volatile>", - "req_id": 4242, - "subject": "{\"name\":\"x\",\"shared_dir\":\"x\",\"writable\":true}", - "ts": "<volatile>", - "type": "admin_challenge", - "v": "5.0" - } - ], - "spawned": [] - }, - "group_attach_ack | challenged | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_attach_ack | challenged | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_attach_ack | challenged | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_attach_ack | challenged | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_attach_ack | fresh | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_attach_ack | fresh | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_attach_ack | fresh | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_attach_ack | fresh | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_attach_ack | member | bare": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "group_attach_ack | member | lists": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "group_attach_ack | member | numbers": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "group_attach_ack | member | strings": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "group_attach_ack | operator | bare": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "group_attach_ack | operator | lists": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "group_attach_ack | operator | numbers": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "group_attach_ack | operator | strings": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "group_detach | challenged | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_detach | challenged | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_detach | challenged | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_detach | challenged | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_detach | fresh | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_detach | fresh | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_detach | fresh | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_detach | fresh | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_detach | member | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Missing group name or id", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_detach | member | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "No authorized key for this", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_detach | member | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "No authorized key for this", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_detach | member | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "No authorized key for this", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_detach | operator | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Missing group name or id", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_detach | operator | lists": { - "audit": [], - "log": [], - "sent": [ - { - "group_id": "", - "node_pk": "iojj3XQJ8ZX9UtstPLpdcspnCb8dlBIb83SIAbQPb1w=", - "nonce": "<volatile>", - "op": "group_detach", - "op_id": "<volatile>", - "req_id": 4242, - "subject": "['x']", - "ts": "<volatile>", - "type": "admin_challenge", - "v": "5.0" - } - ], - "spawned": [] - }, - "group_detach | operator | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "group_id": "", - "node_pk": "iojj3XQJ8ZX9UtstPLpdcspnCb8dlBIb83SIAbQPb1w=", - "nonce": "<volatile>", - "op": "group_detach", - "op_id": "<volatile>", - "req_id": 4242, - "subject": "7", - "ts": "<volatile>", - "type": "admin_challenge", - "v": "5.0" - } - ], - "spawned": [] - }, - "group_detach | operator | strings": { - "audit": [], - "log": [], - "sent": [ - { - "group_id": "", - "node_pk": "iojj3XQJ8ZX9UtstPLpdcspnCb8dlBIb83SIAbQPb1w=", - "nonce": "<volatile>", - "op": "group_detach", - "op_id": "<volatile>", - "req_id": 4242, - "subject": "x", - "ts": "<volatile>", - "type": "admin_challenge", - "v": "5.0" - } - ], - "spawned": [] - }, - "group_detach_ack | challenged | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_detach_ack | challenged | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_detach_ack | challenged | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_detach_ack | challenged | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_detach_ack | fresh | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_detach_ack | fresh | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_detach_ack | fresh | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_detach_ack | fresh | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "group_detach_ack | member | bare": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "group_detach_ack | member | lists": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "group_detach_ack | member | numbers": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "group_detach_ack | member | strings": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "group_detach_ack | operator | bare": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "group_detach_ack | operator | lists": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "group_detach_ack | operator | numbers": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "group_detach_ack | operator | strings": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, "group_roster_req | challenged | bare": { "audit": [], "log": [], @@ -11641,7 +9819,7 @@ "subject": "link:gggggggggggggggggggggggggggggggg", "ts": "<volatile>", "type": "admin_challenge", - "v": "5.0" + "v": "6.0" } ], "spawned": [] @@ -13740,7 +11918,7 @@ "subject": "['x']", "ts": "<volatile>", "type": "admin_challenge", - "v": "5.0" + "v": "6.0" } ], "spawned": [] @@ -13759,7 +11937,7 @@ "subject": "7", "ts": "<volatile>", "type": "admin_challenge", - "v": "5.0" + "v": "6.0" } ], "spawned": [] @@ -13778,7 +11956,7 @@ "subject": "x", "ts": "<volatile>", "type": "admin_challenge", - "v": "5.0" + "v": "6.0" } ], "spawned": [] @@ -13943,379 +12121,6 @@ "sent": [], "spawned": [] }, - "member_unpin | challenged | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "member_unpin | challenged | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "member_unpin | challenged | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "member_unpin | challenged | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "member_unpin | fresh | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "member_unpin | fresh | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "member_unpin | fresh | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "member_unpin | fresh | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "member_unpin | member | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Missing user_id", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "member_unpin | member | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "No authorized key for this", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "member_unpin | member | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "No authorized key for this", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "member_unpin | member | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "No authorized key for this", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "member_unpin | operator | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Missing user_id", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "member_unpin | operator | lists": { - "audit": [], - "log": [], - "sent": [ - { - "group_id": "gggggggggggggggggggggggggggggggg", - "node_pk": "iojj3XQJ8ZX9UtstPLpdcspnCb8dlBIb83SIAbQPb1w=", - "nonce": "<volatile>", - "op": "member_unpin", - "op_id": "<volatile>", - "req_id": 4242, - "subject": "['x']", - "ts": "<volatile>", - "type": "admin_challenge", - "v": "5.0" - } - ], - "spawned": [] - }, - "member_unpin | operator | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "group_id": "gggggggggggggggggggggggggggggggg", - "node_pk": "iojj3XQJ8ZX9UtstPLpdcspnCb8dlBIb83SIAbQPb1w=", - "nonce": "<volatile>", - "op": "member_unpin", - "op_id": "<volatile>", - "req_id": 4242, - "subject": "7", - "ts": "<volatile>", - "type": "admin_challenge", - "v": "5.0" - } - ], - "spawned": [] - }, - "member_unpin | operator | strings": { - "audit": [], - "log": [], - "sent": [ - { - "group_id": "gggggggggggggggggggggggggggggggg", - "node_pk": "iojj3XQJ8ZX9UtstPLpdcspnCb8dlBIb83SIAbQPb1w=", - "nonce": "<volatile>", - "op": "member_unpin", - "op_id": "<volatile>", - "req_id": 4242, - "subject": "x", - "ts": "<volatile>", - "type": "admin_challenge", - "v": "5.0" - } - ], - "spawned": [] - }, - "member_unpin_ack | challenged | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "member_unpin_ack | challenged | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "member_unpin_ack | challenged | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "member_unpin_ack | challenged | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "member_unpin_ack | fresh | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "member_unpin_ack | fresh | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "member_unpin_ack | fresh | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "member_unpin_ack | fresh | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "member_unpin_ack | member | bare": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "member_unpin_ack | member | lists": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "member_unpin_ack | member | numbers": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "member_unpin_ack | member | strings": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "member_unpin_ack | operator | bare": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "member_unpin_ack | operator | lists": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "member_unpin_ack | operator | numbers": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "member_unpin_ack | operator | strings": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, "music_meta_req | challenged | bare": { "audit": [], "log": [], @@ -15148,966 +12953,6 @@ "sent": [], "spawned": [] }, - "node_reload | challenged | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_reload | challenged | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_reload | challenged | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_reload | challenged | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_reload | fresh | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_reload | fresh | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_reload | fresh | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_reload | fresh | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_reload | member | bare": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_node_reload" - ] - }, - "node_reload | member | lists": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_node_reload" - ] - }, - "node_reload | member | numbers": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_node_reload" - ] - }, - "node_reload | member | strings": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_node_reload" - ] - }, - "node_reload | operator | bare": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_node_reload" - ] - }, - "node_reload | operator | lists": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_node_reload" - ] - }, - "node_reload | operator | numbers": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_node_reload" - ] - }, - "node_reload | operator | strings": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_node_reload" - ] - }, - "node_reload_ack | challenged | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_reload_ack | challenged | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_reload_ack | challenged | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_reload_ack | challenged | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_reload_ack | fresh | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_reload_ack | fresh | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_reload_ack | fresh | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_reload_ack | fresh | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_reload_ack | member | bare": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "node_reload_ack | member | lists": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "node_reload_ack | member | numbers": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "node_reload_ack | member | strings": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "node_reload_ack | operator | bare": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "node_reload_ack | operator | lists": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "node_reload_ack | operator | numbers": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "node_reload_ack | operator | strings": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "node_settings_set | challenged | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_settings_set | challenged | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_settings_set | challenged | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_settings_set | challenged | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_settings_set | fresh | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_settings_set | fresh | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_settings_set | fresh | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_settings_set | fresh | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_settings_set | member | bare": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_node_settings_set" - ] - }, - "node_settings_set | member | lists": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_node_settings_set" - ] - }, - "node_settings_set | member | numbers": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_node_settings_set" - ] - }, - "node_settings_set | member | strings": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_node_settings_set" - ] - }, - "node_settings_set | operator | bare": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_node_settings_set" - ] - }, - "node_settings_set | operator | lists": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_node_settings_set" - ] - }, - "node_settings_set | operator | numbers": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_node_settings_set" - ] - }, - "node_settings_set | operator | strings": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_node_settings_set" - ] - }, - "node_settings_set_ack | challenged | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_settings_set_ack | challenged | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_settings_set_ack | challenged | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_settings_set_ack | challenged | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_settings_set_ack | fresh | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_settings_set_ack | fresh | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_settings_set_ack | fresh | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_settings_set_ack | fresh | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_settings_set_ack | member | bare": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "node_settings_set_ack | member | lists": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "node_settings_set_ack | member | numbers": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "node_settings_set_ack | member | strings": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "node_settings_set_ack | operator | bare": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "node_settings_set_ack | operator | lists": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "node_settings_set_ack | operator | numbers": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "node_settings_set_ack | operator | strings": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "node_status | challenged | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_status | challenged | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_status | challenged | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_status | challenged | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_status | fresh | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_status | fresh | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_status | fresh | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_status | fresh | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_status | member | bare": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_node_status" - ] - }, - "node_status | member | lists": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_node_status" - ] - }, - "node_status | member | numbers": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_node_status" - ] - }, - "node_status | member | strings": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_node_status" - ] - }, - "node_status | operator | bare": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_node_status" - ] - }, - "node_status | operator | lists": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_node_status" - ] - }, - "node_status | operator | numbers": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_node_status" - ] - }, - "node_status | operator | strings": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_node_status" - ] - }, - "node_status_ack | challenged | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_status_ack | challenged | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_status_ack | challenged | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_status_ack | challenged | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_status_ack | fresh | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_status_ack | fresh | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_status_ack | fresh | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_status_ack | fresh | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "node_status_ack | member | bare": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "node_status_ack | member | lists": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "node_status_ack | member | numbers": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "node_status_ack | member | strings": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "node_status_ack | operator | bare": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "node_status_ack | operator | lists": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "node_status_ack | operator | numbers": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "node_status_ack | operator | strings": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, "ping | challenged | bare": { "audit": [], "log": [], @@ -16212,7 +13057,7 @@ "req_id": 4242, "token": null, "type": "pong", - "v": "5.0" + "v": "6.0" } ], "spawned": [] @@ -16227,7 +13072,7 @@ "x" ], "type": "pong", - "v": "5.0" + "v": "6.0" } ], "spawned": [] @@ -16240,7 +13085,7 @@ "req_id": 4242, "token": 7, "type": "pong", - "v": "5.0" + "v": "6.0" } ], "spawned": [] @@ -16253,7 +13098,7 @@ "req_id": 4242, "token": "x", "type": "pong", - "v": "5.0" + "v": "6.0" } ], "spawned": [] @@ -16266,7 +13111,7 @@ "req_id": 4242, "token": null, "type": "pong", - "v": "5.0" + "v": "6.0" } ], "spawned": [] @@ -16281,7 +13126,7 @@ "x" ], "type": "pong", - "v": "5.0" + "v": "6.0" } ], "spawned": [] @@ -16294,7 +13139,7 @@ "req_id": 4242, "token": 7, "type": "pong", - "v": "5.0" + "v": "6.0" } ], "spawned": [] @@ -16307,7 +13152,7 @@ "req_id": 4242, "token": "x", "type": "pong", - "v": "5.0" + "v": "6.0" } ], "spawned": [] @@ -16472,379 +13317,6 @@ "sent": [], "spawned": [] }, - "root_add | challenged | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_add | challenged | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_add | challenged | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_add | challenged | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_add | fresh | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_add | fresh | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_add | fresh | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_add | fresh | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_add | member | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Missing group_id or path", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_add | member | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "No authorized key for this", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_add | member | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "No authorized key for this", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_add | member | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "No authorized key for this", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_add | operator | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Missing group_id or path", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_add | operator | lists": { - "audit": [], - "log": [], - "sent": [ - { - "group_id": "['x']", - "node_pk": "iojj3XQJ8ZX9UtstPLpdcspnCb8dlBIb83SIAbQPb1w=", - "nonce": "<volatile>", - "op": "root_add", - "op_id": "<volatile>", - "req_id": 4242, - "subject": "{\"kind\":\"['x']\",\"name\":\"['x']\",\"path\":\"['x']\",\"removable\":true,\"writable\":true}", - "ts": "<volatile>", - "type": "admin_challenge", - "v": "5.0" - } - ], - "spawned": [] - }, - "root_add | operator | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "group_id": "7", - "node_pk": "iojj3XQJ8ZX9UtstPLpdcspnCb8dlBIb83SIAbQPb1w=", - "nonce": "<volatile>", - "op": "root_add", - "op_id": "<volatile>", - "req_id": 4242, - "subject": "{\"kind\":\"7\",\"name\":\"7\",\"path\":\"7\",\"removable\":true,\"writable\":true}", - "ts": "<volatile>", - "type": "admin_challenge", - "v": "5.0" - } - ], - "spawned": [] - }, - "root_add | operator | strings": { - "audit": [], - "log": [], - "sent": [ - { - "group_id": "x", - "node_pk": "iojj3XQJ8ZX9UtstPLpdcspnCb8dlBIb83SIAbQPb1w=", - "nonce": "<volatile>", - "op": "root_add", - "op_id": "<volatile>", - "req_id": 4242, - "subject": "{\"kind\":\"x\",\"name\":\"x\",\"path\":\"x\",\"removable\":true,\"writable\":true}", - "ts": "<volatile>", - "type": "admin_challenge", - "v": "5.0" - } - ], - "spawned": [] - }, - "root_add_ack | challenged | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_add_ack | challenged | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_add_ack | challenged | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_add_ack | challenged | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_add_ack | fresh | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_add_ack | fresh | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_add_ack | fresh | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_add_ack | fresh | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_add_ack | member | bare": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "root_add_ack | member | lists": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "root_add_ack | member | numbers": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "root_add_ack | member | strings": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "root_add_ack | operator | bare": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "root_add_ack | operator | lists": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "root_add_ack | operator | numbers": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "root_add_ack | operator | strings": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, "root_eject | challenged | bare": { "audit": [], "log": [], @@ -17015,7 +13487,7 @@ "subject": "['x']", "ts": "<volatile>", "type": "admin_challenge", - "v": "5.0" + "v": "6.0" } ], "spawned": [] @@ -17034,7 +13506,7 @@ "subject": "7", "ts": "<volatile>", "type": "admin_challenge", - "v": "5.0" + "v": "6.0" } ], "spawned": [] @@ -17053,7 +13525,7 @@ "subject": "x", "ts": "<volatile>", "type": "admin_challenge", - "v": "5.0" + "v": "6.0" } ], "spawned": [] @@ -17388,7 +13860,7 @@ "subject": "['x']", "ts": "<volatile>", "type": "admin_challenge", - "v": "5.0" + "v": "6.0" } ], "spawned": [] @@ -17407,7 +13879,7 @@ "subject": "7", "ts": "<volatile>", "type": "admin_challenge", - "v": "5.0" + "v": "6.0" } ], "spawned": [] @@ -17426,7 +13898,7 @@ "subject": "x", "ts": "<volatile>", "type": "admin_challenge", - "v": "5.0" + "v": "6.0" } ], "spawned": [] @@ -17761,7 +14233,7 @@ "subject": "['x']", "ts": "<volatile>", "type": "admin_challenge", - "v": "5.0" + "v": "6.0" } ], "spawned": [] @@ -17780,7 +14252,7 @@ "subject": "7", "ts": "<volatile>", "type": "admin_challenge", - "v": "5.0" + "v": "6.0" } ], "spawned": [] @@ -17799,7 +14271,7 @@ "subject": "x", "ts": "<volatile>", "type": "admin_challenge", - "v": "5.0" + "v": "6.0" } ], "spawned": [] @@ -17964,699 +14436,6 @@ "sent": [], "spawned": [] }, - "root_update | challenged | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_update | challenged | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_update | challenged | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_update | challenged | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_update | fresh | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_update | fresh | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_update | fresh | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_update | fresh | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_update | member | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Missing group_id or root_name", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_update | member | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "No authorized key for this", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_update | member | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "No authorized key for this", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_update | member | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "No authorized key for this", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_update | operator | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Missing group_id or root_name", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_update | operator | lists": { - "audit": [], - "log": [], - "sent": [ - { - "group_id": "['x']", - "node_pk": "iojj3XQJ8ZX9UtstPLpdcspnCb8dlBIb83SIAbQPb1w=", - "nonce": "<volatile>", - "op": "root_update", - "op_id": "<volatile>", - "req_id": 4242, - "subject": "['x']:rw=on,rem=on", - "ts": "<volatile>", - "type": "admin_challenge", - "v": "5.0" - } - ], - "spawned": [] - }, - "root_update | operator | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "group_id": "7", - "node_pk": "iojj3XQJ8ZX9UtstPLpdcspnCb8dlBIb83SIAbQPb1w=", - "nonce": "<volatile>", - "op": "root_update", - "op_id": "<volatile>", - "req_id": 4242, - "subject": "7:rw=on,rem=on", - "ts": "<volatile>", - "type": "admin_challenge", - "v": "5.0" - } - ], - "spawned": [] - }, - "root_update | operator | strings": { - "audit": [], - "log": [], - "sent": [ - { - "group_id": "x", - "node_pk": "iojj3XQJ8ZX9UtstPLpdcspnCb8dlBIb83SIAbQPb1w=", - "nonce": "<volatile>", - "op": "root_update", - "op_id": "<volatile>", - "req_id": 4242, - "subject": "x:rw=on,rem=on", - "ts": "<volatile>", - "type": "admin_challenge", - "v": "5.0" - } - ], - "spawned": [] - }, - "root_update_ack | challenged | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_update_ack | challenged | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_update_ack | challenged | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_update_ack | challenged | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_update_ack | fresh | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_update_ack | fresh | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_update_ack | fresh | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_update_ack | fresh | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "root_update_ack | member | bare": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "root_update_ack | member | lists": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "root_update_ack | member | numbers": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "root_update_ack | member | strings": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "root_update_ack | operator | bare": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "root_update_ack | operator | lists": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "root_update_ack | operator | numbers": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "root_update_ack | operator | strings": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "roster_read | challenged | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "roster_read | challenged | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "roster_read | challenged | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "roster_read | challenged | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "roster_read | fresh | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "roster_read | fresh | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "roster_read | fresh | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "roster_read | fresh | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "roster_read | member | bare": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_roster_read" - ] - }, - "roster_read | member | lists": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_roster_read" - ] - }, - "roster_read | member | numbers": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_roster_read" - ] - }, - "roster_read | member | strings": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_roster_read" - ] - }, - "roster_read | operator | bare": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_roster_read" - ] - }, - "roster_read | operator | lists": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_roster_read" - ] - }, - "roster_read | operator | numbers": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_roster_read" - ] - }, - "roster_read | operator | strings": { - "audit": [], - "log": [], - "sent": [], - "spawned": [ - "_do_roster_read" - ] - }, - "roster_read_ack | challenged | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "roster_read_ack | challenged | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "roster_read_ack | challenged | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "roster_read_ack | challenged | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "roster_read_ack | fresh | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "roster_read_ack | fresh | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "roster_read_ack | fresh | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "roster_read_ack | fresh | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "roster_read_ack | member | bare": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "roster_read_ack | member | lists": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "roster_read_ack | member | numbers": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "roster_read_ack | member | strings": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "roster_read_ack | operator | bare": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "roster_read_ack | operator | lists": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "roster_read_ack | operator | numbers": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "roster_read_ack | operator | strings": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, "search_listed | challenged | bare": { "audit": [], "log": [], @@ -21119,7 +16898,7 @@ "subject": "{\"language\":null,\"token\":null}", "ts": "<volatile>", "type": "admin_challenge", - "v": "5.0" + "v": "6.0" } ], "spawned": [] @@ -21162,7 +16941,7 @@ "subject": "{\"language\":\"x\",\"token\":\"sha256:2d711642b726b04401627ca9fbac32f5c8530fb1903cc4db02258717921a4881\"}", "ts": "<volatile>", "type": "admin_challenge", - "v": "5.0" + "v": "6.0" } ], "spawned": [] @@ -22867,365 +18646,6 @@ "sent": [], "spawned": [] }, - "transfer_limits | challenged | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "transfer_limits | challenged | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "transfer_limits | challenged | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "transfer_limits | challenged | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "transfer_limits | fresh | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "transfer_limits | fresh | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "transfer_limits | fresh | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "transfer_limits | fresh | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "transfer_limits | member | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Invalid transfer limits", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "transfer_limits | member | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Invalid transfer limits", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "transfer_limits | member | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "No authorized key for this", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "transfer_limits | member | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Invalid transfer limits", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "transfer_limits | operator | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Invalid transfer limits", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "transfer_limits | operator | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Invalid transfer limits", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "transfer_limits | operator | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "group_id": "gggggggggggggggggggggggggggggggg", - "node_pk": "iojj3XQJ8ZX9UtstPLpdcspnCb8dlBIb83SIAbQPb1w=", - "nonce": "<volatile>", - "op": "transfer_limits", - "op_id": "<volatile>", - "req_id": 4242, - "subject": "d=7,u=7", - "ts": "<volatile>", - "type": "admin_challenge", - "v": "5.0" - } - ], - "spawned": [] - }, - "transfer_limits | operator | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Invalid transfer limits", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "transfer_limits_ack | challenged | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "transfer_limits_ack | challenged | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "transfer_limits_ack | challenged | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "transfer_limits_ack | challenged | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "transfer_limits_ack | fresh | bare": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "transfer_limits_ack | fresh | lists": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "transfer_limits_ack | fresh | numbers": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "transfer_limits_ack | fresh | strings": { - "audit": [], - "log": [], - "sent": [ - { - "detail": "Handshake required", - "req_id": 4242, - "type": "error" - } - ], - "spawned": [] - }, - "transfer_limits_ack | member | bare": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "transfer_limits_ack | member | lists": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "transfer_limits_ack | member | numbers": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "transfer_limits_ack | member | strings": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "transfer_limits_ack | operator | bare": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "transfer_limits_ack | operator | lists": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "transfer_limits_ack | operator | numbers": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, - "transfer_limits_ack | operator | strings": { - "audit": [], - "log": [ - "WARNING Unknown MNP message type on DataChannel: %s" - ], - "sent": [], - "spawned": [] - }, "transfer_open | challenged | bare": { "audit": [], "log": [], diff --git a/packages/meshbay-node/tests/test_admin_challenge_bounds.py b/packages/meshbay-node/tests/test_admin_challenge_bounds.py index fd3b2f1..9dcb750 100644 --- a/packages/meshbay-node/tests/test_admin_challenge_bounds.py +++ b/packages/meshbay-node/tests/test_admin_challenge_bounds.py @@ -3,8 +3,9 @@ What a connection may leave waiting for a signature (docs/MESHBAY_DESIGN.md §13 Anyone authenticated can ask for an admin challenge — the signature is checked later — so a member who never answers must not make the node keep every request. -Measured before the bound: 200 `root_add` of 1 MiB each from a plain member held -200 pending operations and ~400 MiB for the life of the connection. +Measured before the bound: 200 `root_add` (an op since removed) of 1 MiB each +from a plain member held 200 pending operations and ~400 MiB for the life of +the connection. """ import struct @@ -48,23 +49,24 @@ def _member_session(): return s -def _root_add(s, path: str) -> dict: - s._dispatch_message({"type": "root_add", "group_id": GROUP, "path": path}) +def _ask(s, path: str) -> dict: + """A signed op whose subject is whatever the caller sends.""" + s._dispatch_message({"type": "chat_directory", "path": path}) return s._channel.sent[-1] def test_a_member_cannot_pile_up_challenges(): s = _member_session() for i in range(MAX_PENDING_ADMIN_OPS): - assert _root_add(s, f"/srv/{i}")["type"] == "admin_challenge" - refused = _root_add(s, "/srv/one-too-many") + assert _ask(s, f"/srv/{i}")["type"] == "admin_challenge" + refused = _ask(s, "/srv/one-too-many") assert refused["type"] == "error" and refused["code"] == "too_many_pending" assert len(s._admin_ops) == MAX_PENDING_ADMIN_OPS def test_an_oversized_request_is_not_kept(): s = _member_session() - refused = _root_add(s, "x" * (MAX_ADMIN_OP_BYTES + 1)) + refused = _ask(s, "x" * (MAX_ADMIN_OP_BYTES + 1)) assert refused["type"] == "error" and refused["code"] == "too_large" assert s._admin_ops == {} @@ -72,21 +74,21 @@ def test_an_oversized_request_is_not_kept(): def test_an_expired_challenge_frees_its_place(): s = _member_session() for i in range(MAX_PENDING_ADMIN_OPS): - _root_add(s, f"/srv/{i}") + _ask(s, f"/srv/{i}") for pending in s._admin_ops.values(): pending["ts"] -= 10_000 - assert _root_add(s, "/srv/after-expiry")["type"] == "admin_challenge" + assert _ask(s, "/srv/after-expiry")["type"] == "admin_challenge" assert len(s._admin_ops) == 1 def test_answering_a_challenge_frees_its_place(): s = _member_session() for i in range(MAX_PENDING_ADMIN_OPS): - _root_add(s, f"/srv/{i}") + _ask(s, f"/srv/{i}") op_id = next(iter(s._admin_ops)) s._dispatch_message({"type": "admin_response", "op_id": op_id, "signature": "!!"}) assert len(s._admin_ops) == MAX_PENDING_ADMIN_OPS - 1 - assert _root_add(s, "/srv/next")["type"] == "admin_challenge" + assert _ask(s, "/srv/next")["type"] == "admin_challenge" assert all(time.time() - p["ts"] < 5 for p in s._admin_ops.values()) @@ -95,27 +97,6 @@ def test_answering_a_challenge_frees_its_place(): # The signature covers the subject and nothing else of a request, so every value # the executor acts on has to be in it. -def test_root_add_signs_whether_members_may_write(): - from meshbay_common.adminop import root_add_subject - s = _member_session() - s._dispatch_message({"type": "root_add", "group_id": GROUP, "path": "/srv/drop", - "name": "Drop", "writable": True, "removable": False}) - challenge = s._channel.sent[-1] - assert challenge["subject"] == root_add_subject("/srv/drop", "Drop", "generic", - True, False) - assert challenge["subject"] != root_add_subject("/srv/drop", "Drop", "generic", - False, False) - - -def test_group_attach_signs_the_directory_it_exposes(): - from meshbay_common.adminop import group_attach_subject - s = _member_session() - s._dispatch_message({"type": "group_attach", "name": "photos", - "shared_dir": "/home/me/Photos"}) - assert s._channel.sent[-1]["subject"] == group_attach_subject( - "photos", "/home/me/Photos", True) - - def test_invite_create_signs_the_name_it_records(): from meshbay_common.adminop import invite_create_subject s = _member_session() diff --git a/packages/meshbay-node/tests/test_admin_ops_mnp.py b/packages/meshbay-node/tests/test_admin_ops_mnp.py index 7fd1c2b..898228e 100644 --- a/packages/meshbay-node/tests/test_admin_ops_mnp.py +++ b/packages/meshbay-node/tests/test_admin_ops_mnp.py @@ -1,17 +1,14 @@ """ -`gek_rotate` and `member_unpin` over MNP. +Rotating the group key and forgetting a pinned identity — `ops.set_gek` and +`ops.unpin_member`, which the Node page and the CLI reach over loopback — and +the H5 rule every signed MNP operation lives under. -Both are destructive and both are new, so the tests are negative assertions: -nobody without the operator's pinned key can reach them, a signature over the -wrong transcript does not count, and the operation cannot be triggered by the -request message alone. - -The rule these live under is worth restating, because it is easy to read -draft-v5 §5.1 as forbidding them: **"nothing arriving over MNP can activate a -GEK" is about key material arriving from outside** (C5b — a member handing the -node a key of their choosing). An operator-signed instruction where the node -generates the key with its own CSPRNG is a different shape, and it is the only -thing that finishes a revocation: the ex-member still holds the current key. +`gek_rotate` and `member_unpin` were MNP messages until 6.0. No client sent +them, so they went; what they did is still tested here, at the door that is +used. **"Nothing arriving over MNP can activate a GEK" is about key material +arriving from outside** (C5b): the node generates the new key with its own +CSPRNG, which is the only thing that finishes a revocation — the ex-member +still holds the current key. """ import base64 @@ -19,14 +16,10 @@ from pathlib import Path import pytest from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey -from meshbay_common.adminop import ( - OP_GEK_ROTATE, - OP_MEMBER_UNPIN, - admin_transcript, -) +from meshbay_common.adminop import OP_CHAT_EPOCH, admin_transcript from meshbay_common.crypto import pk_to_b64 from meshbay_common.join import ROLE_MEMBER, ROLE_OPERATOR -from meshbay_common.protocol import MNP +from meshbay_node import ops from meshbay_node.indexer.group_index import GroupIndex from meshbay_node.roster import open_roster from meshbay_node.transport.webrtc_server import WebRTCPeerSession @@ -127,58 +120,7 @@ async def _drain(session): session.spawned.clear() -async def _sign_and_exec(session, op: str, subject: str, sk, exec_fn): - challenge = _last(session) - assert challenge["type"] == "admin_challenge", challenge - transcript = admin_transcript( - op=op, node_pk_b64=session._node_pk_b64(), group_id=GROUP, - subject=subject, nonce=base64.b64decode(challenge["nonce"]), - ts=challenge["ts"]) - pending = session._admin_ops.get(challenge["op_id"]) or { - "op": op, "subject": subject} - await exec_fn(pending, transcript, sk.sign(transcript)) - - -# ── gek_rotate ─────────────────────────────────────────────────────────────── - -async def test_rotation_needs_an_operator(tmp_path, roster): - """Without a paired operator there is nobody who could sign, so the node - fails closed and says why rather than issuing a challenge nobody can meet.""" - session = await _session(tmp_path, roster, operator=False) - - session._do_gek_rotate({}) - - assert _last(session)["type"] == "error" - assert "authorized key" in _last(session)["detail"] - assert not session._admin_ops - - -async def test_the_request_alone_rotates_nothing(tmp_path, roster): - """The message asks; only a signature acts. A node that rotated here would - let any member lock the group out.""" - session = await _session(tmp_path, roster, operator=True) - before = session._ctx["groups"][GROUP]["gek"] - - session._do_gek_rotate({}) - - assert _last(session)["type"] == "admin_challenge" - assert session._ctx["groups"][GROUP]["gek"] == before - - -async def test_a_members_signature_does_not_rotate(tmp_path, roster): - session = await _session(tmp_path, roster, operator=True) - sk_mallory, pk_mallory = _keypair() - await roster.pin_identity("mallory", "mallory", pk_mallory, pk_mallory, "code") - await roster.set_member(GROUP, "mallory", ROLE_MEMBER, "active", "grenet") - before = session._ctx["groups"][GROUP]["gek"] - - session._do_gek_rotate({}) - await _sign_and_exec(session, OP_GEK_ROTATE, GROUP, sk_mallory, - session._admin_exec_gek_rotate) - - assert _last(session)["type"] == "error" - assert session._ctx["groups"][GROUP]["gek"] == before - +# ── H5: a signature is for one operation ───────────────────────────────────── async def test_a_signature_over_another_operation_does_not_count(tmp_path, roster): """ @@ -191,15 +133,18 @@ async def test_a_signature_over_another_operation_does_not_count(tmp_path, roste control, and the test would pass while proving nothing. """ session = await _session(tmp_path, roster, operator=True) - before = session._ctx["groups"][GROUP]["gek"] + _, pk_bob = _keypair() + await roster.pin_identity("bob", "bob", pk_bob, pk_bob, "code") + await roster.set_member(GROUP, "bob", ROLE_MEMBER, "active", "code") - session._do_gek_rotate({}) + session._do_member_revoke({"user_id": "bob"}) challenge = _last(session) + assert challenge["type"] == "admin_challenge", challenge - # Signed over member_unpin, presented against the pending gek_rotate. + # Signed over chat_epoch, presented against the pending member_revoke. wrong = admin_transcript( - op=OP_MEMBER_UNPIN, node_pk_b64=session._node_pk_b64(), group_id=GROUP, - subject=GROUP, nonce=base64.b64decode(challenge["nonce"]), + op=OP_CHAT_EPOCH, node_pk_b64=session._node_pk_b64(), group_id=GROUP, + subject="bob", nonce=base64.b64decode(challenge["nonce"]), ts=challenge["ts"]) session._do_admin_response({ "op_id": challenge["op_id"], @@ -208,19 +153,18 @@ async def test_a_signature_over_another_operation_does_not_count(tmp_path, roste await _drain(session) assert _last(session)["type"] == "error" - assert session.state["groups_ctx"][GROUP]["gek"] == before + assert (await roster.get_member(GROUP, "bob"))["status"] == "active" -async def test_the_operator_rotates_and_the_node_makes_the_key(tmp_path, roster): +# ── Rotating the group key ─────────────────────────────────────────────────── + +async def test_rotating_makes_a_new_key_on_the_node(tmp_path, roster): session = await _session(tmp_path, roster, operator=True) - before = session._ctx["groups"][GROUP]["gek"] + before = session.state["groups_ctx"][GROUP]["gek"] - session._do_gek_rotate({}) - await _sign_and_exec(session, OP_GEK_ROTATE, GROUP, session.sk_op, - session._admin_exec_gek_rotate) + result = await ops.set_gek(session.state, GROUP, rotate=True) - ack = _last(session) - assert ack["type"] == MNP.GEK_ROTATE_ACK, ack + assert result["rotated"] is True after = session.state["groups_ctx"][GROUP]["gek"] assert after != before, "the key did not change" assert len(after) == 32 @@ -234,54 +178,21 @@ async def test_rotation_reaches_the_index(tmp_path, roster): serve members a listing they cannot open.""" session = await _session(tmp_path, roster, operator=True) - session._do_gek_rotate({}) - await _sign_and_exec(session, OP_GEK_ROTATE, GROUP, session.sk_op, - session._admin_exec_gek_rotate) + await ops.set_gek(session.state, GROUP, rotate=True) assert session.state["indexes"][GROUP].gek == \ session.state["groups_ctx"][GROUP]["gek"] -# ── member_unpin ───────────────────────────────────────────────────────────── - -async def test_unpinning_needs_an_operator(tmp_path, roster): - session = await _session(tmp_path, roster, operator=False) - session._do_member_unpin({"user_id": "bob"}) - assert _last(session)["type"] == "error" - - -async def test_unpinning_yourself_is_refused(tmp_path, roster): - """It would end the authority of the connection performing the operation, - halfway through it.""" - session = await _session(tmp_path, roster, operator=True) - session._do_member_unpin({"user_id": "grenet"}) - assert _last(session)["detail"] == "Cannot unpin yourself" - - -async def test_a_members_signature_does_not_unpin(tmp_path, roster): - session = await _session(tmp_path, roster, operator=True) - sk_bob, pk_bob = _keypair() - await roster.pin_identity("bob", "bob", pk_bob, pk_bob, "code") - - session._do_member_unpin({"user_id": "bob"}) - await _sign_and_exec(session, OP_MEMBER_UNPIN, "bob", sk_bob, - session._admin_exec_member_unpin) - - assert _last(session)["type"] == "error" - assert await roster.get_identity("bob") is not None, ( - "a member removed their own pin — only the operator may") - +# ── Forgetting a pinned identity ───────────────────────────────────────────── -async def test_the_operator_unpins(tmp_path, roster): +async def test_unpinning_forgets_the_identity_and_its_bundle(tmp_path, roster): session = await _session(tmp_path, roster, operator=True) _, pk_bob = _keypair() await roster.pin_identity("bob", "bob", pk_bob, pk_bob, "code") - session._do_member_unpin({"user_id": "bob"}) - await _sign_and_exec(session, OP_MEMBER_UNPIN, "bob", session.sk_op, - session._admin_exec_member_unpin) + await ops.unpin_member(session.state, "bob") - assert _last(session)["type"] == MNP.MEMBER_UNPIN_ACK assert await roster.get_identity("bob") is None # The stored keypair bundle goes too — left behind it blocks the re-join # the unpin exists to enable. @@ -290,8 +201,21 @@ async def test_the_operator_unpins(tmp_path, roster): async def test_unpinning_someone_unknown_says_so(tmp_path, roster): session = await _session(tmp_path, roster, operator=True) - session._do_member_unpin({"user_id": "nobody"}) - await _sign_and_exec(session, OP_MEMBER_UNPIN, "nobody", session.sk_op, - session._admin_exec_member_unpin) - assert _last(session)["type"] == "error" - assert "No such pinned identity" in _last(session)["detail"] + with pytest.raises(ops.OpError, match="No such pinned identity"): + await ops.unpin_member(session.state, "nobody") + + +# ── What MNP no longer carries ─────────────────────────────────────────────── + +@pytest.mark.parametrize("op", ["gek_rotate", "member_unpin", "transfer_limits", + "group_detach"]) +def test_operations_no_client_sent_are_not_signed_ops_any_more(op): + """Gone with MNP 6.0: a door nobody uses is an untested way in. The Node + page and the CLI do the same work over loopback.""" + from meshbay_common import adminop + from meshbay_node.transport.webrtc.admin import _ADMIN_EXECUTORS + from meshbay_node.transport.webrtc.dispatch import _HANDLERS + + assert op not in _HANDLERS + assert op not in _ADMIN_EXECUTORS + assert op not in vars(adminop).values() diff --git a/packages/meshbay-node/tests/test_node_status.py b/packages/meshbay-node/tests/test_node_status.py index 91c07b6..45a9710 100644 --- a/packages/meshbay-node/tests/test_node_status.py +++ b/packages/meshbay-node/tests/test_node_status.py @@ -1,24 +1,19 @@ """ -node_status, root_add, root_remove over MNP. +The node management panel's server-side behaviour. -These test the D5 node management panel's server-side behaviour: the admin -identity check on node_status, the list_groups operation, and the root -add/remove flows through the MNP handlers. +The `_is_node_admin` hint, root removal over MNP, and the operations the Node +page and the CLI reach over loopback: listing groups, adding and updating +roots, the roster, the denylist and unpinning. Their own MNP messages +(`node_status`, `root_add`, `roster_read`, …) are gone since MNP 6.0. """ -import base64 from dataclasses import asdict from pathlib import Path import pytest from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey -from meshbay_common.adminop import ( - OP_MEMBER_UNPIN, - admin_transcript, -) from meshbay_common.crypto import pk_to_b64 from meshbay_common.join import ROLE_OPERATOR -from meshbay_common.protocol import MNP from meshbay_node import ops from meshbay_node.indexer.group_index import GroupIndex from meshbay_node.roots import RootSet @@ -133,19 +128,6 @@ async def _session( return session -async def _sign_and_exec(session, op: str, subject: str, sk, exec_fn, - group_id: str = GROUP): - challenge = _last(session) - assert challenge["type"] == "admin_challenge", challenge - transcript = admin_transcript( - op=op, node_pk_b64=session._node_pk_b64(), group_id=group_id, - subject=subject, nonce=base64.b64decode(challenge["nonce"]), - ts=challenge["ts"]) - pending = session._admin_ops.get(challenge["op_id"]) or { - "op": op, "subject": subject} - await exec_fn(pending, transcript, sk.sign(transcript)) - - # ── _is_node_admin ────────────────────────────────────────────────────────── async def test_is_node_admin_matches_user_id(tmp_path, roster): @@ -167,62 +149,6 @@ async def test_is_node_admin_rejects_missing_node_user_id(tmp_path, roster): assert not session._is_node_admin() -# ── node_status ───────────────────────────────────────────────────────────── - -async def test_node_status_returns_groups_for_admin(tmp_path, roster): - session = await _session(tmp_path, roster, operator=True, - node_user_id="grenet") - session._spawn(session._do_node_status({})) - await _drain(session) - msg = _last(session) - assert msg["type"] == MNP.NODE_STATUS_ACK - assert len(msg["groups"]) == 1 - assert msg["groups"][0]["id"] == GROUP - - -async def test_node_status_refused_for_non_admin(tmp_path, roster): - session = await _session(tmp_path, roster, operator=False, - node_user_id="grenet") - session._spawn(session._do_node_status({})) - await _drain(session) - msg = _last(session) - assert msg["type"] == "error" - assert "operator" in msg["detail"].lower() - - -async def test_node_status_refused_when_user_is_operator_but_ids_mismatch( - tmp_path, roster, -): - """A paired operator who is not the node owner cannot see node_status.""" - session = await _session(tmp_path, roster, operator=True, - node_user_id="someone-else") - session._spawn(session._do_node_status({})) - await _drain(session) - msg = _last(session) - assert msg["type"] == "error" - - -async def test_node_status_catches_send_failure(tmp_path, roster): - """If _send itself throws (e.g. msgpack encoding fails), the error must - not silently vanish — it used to, because _send was outside the try block.""" - session = await _session(tmp_path, roster, operator=True, - node_user_id="grenet") - sent = [] - call_count = [0] - - def _exploding_send(msg): - call_count[0] += 1 - if msg.get("type") == "node_status_ack": - raise TypeError("msgpack cannot encode this") - sent.append(msg) - - session._send = _exploding_send - session._spawn(session._do_node_status({})) - await _drain(session) - # The try/except around _send should catch the error and send an error reply - assert any(m.get("type") == "error" for m in sent) - - # ── ops.list_groups ───────────────────────────────────────────────────────── async def test_list_groups_returns_group_metadata(tmp_path): @@ -479,32 +405,6 @@ async def test_remove_root_succeeds_with_two_roots(tmp_path): assert cfg.roots[0].name == "dir1" -# ── root_add MNP handler ─────────────────────────────────────────────────── - -async def test_root_add_issues_challenge(tmp_path, roster): - session = await _session(tmp_path, roster, operator=True, - node_user_id="grenet") - session._do_root_add({"group_id": GROUP, "path": "/tmp/test"}) - msg = _last(session) - assert msg["type"] == "admin_challenge" - - -async def test_root_add_refuses_without_authority(tmp_path, roster): - session = await _session(tmp_path, roster, operator=False) - session._do_root_add({"group_id": GROUP, "path": "/tmp/test"}) - msg = _last(session) - assert msg["type"] == "error" - assert "authorized" in msg["detail"].lower() - - -async def test_root_add_refuses_missing_fields(tmp_path, roster): - session = await _session(tmp_path, roster, operator=True, - node_user_id="grenet") - session._do_root_add({"group_id": GROUP}) - assert _last(session)["type"] == "error" - assert "Missing" in _last(session)["detail"] - - # ── root_remove MNP handler ──────────────────────────────────────────────── async def test_root_remove_issues_challenge(tmp_path, roster): @@ -530,52 +430,32 @@ async def test_root_remove_refuses_missing_fields(tmp_path, roster): assert "Missing" in _last(session)["detail"] -# ── roster_read MNP handler ────────────────────────────────────────────── +# ── The roster, the denylist and unpinning (loopback, CLI) ────────────────── +# +# Their MNP messages are gone (MNP 6.0, no client sent them); the operations are +# what the Node page and the CLI call. -async def test_roster_read_returns_members_for_admin(tmp_path, roster): - session = await _session(tmp_path, roster, operator=True, - node_user_id="grenet") - session._spawn(session._do_roster_read({"group_id": GROUP})) - await _drain(session) - msg = _last(session) - assert msg["type"] == "roster_read_ack" - assert "members" in msg - assert "identities" in msg - - -async def test_roster_read_refused_for_non_admin(tmp_path, roster): - session = await _session(tmp_path, roster, operator=False, - node_user_id="grenet") - session._spawn(session._do_roster_read({"group_id": GROUP})) - await _drain(session) - msg = _last(session) - assert msg["type"] == "error" - - -async def test_roster_read_filters_ghost_members(tmp_path, roster): +async def test_read_roster_filters_ghost_members(tmp_path, roster): """Members whose identity was deleted (revoked then unpinned) are filtered out by read_roster — the LEFT JOIN returns them with pk_ed25519 = NULL but they should never reach the UI.""" session = await _session(tmp_path, roster, operator=True, node_user_id="grenet") - sk2, pk2 = _keypair() + _, pk2 = _keypair() await roster.pin_identity("ghost", "ghost", pk2, pk2, "code") await roster.set_member(GROUP, "ghost", "member", "revoked", "local-cli") await roster._db.execute("DELETE FROM identities WHERE user_id = 'ghost'") await roster._db.commit() # Also add a real member so the roster isn't empty - sk3, pk3 = _keypair() + _, pk3 = _keypair() await roster.pin_identity("real", "real", pk3, pk3, "code") await roster.set_member(GROUP, "real", "member", "active", "local-cli") - session._spawn(session._do_roster_read({"group_id": GROUP})) - await _drain(session) - msg = _last(session) - assert msg["type"] == "roster_read_ack" - ghost = [m for m in msg["members"] if m["user_id"] == "ghost"] - assert len(ghost) == 0, "ghost members must be filtered out" - real = [m for m in msg["members"] if m["user_id"] == "real"] - assert len(real) == 1 + result = await ops.read_roster(session.state, GROUP) + assert "identities" in result + assert not [m for m in result["members"] if m["user_id"] == "ghost"], ( + "ghost members must be filtered out") + assert len([m for m in result["members"] if m["user_id"] == "real"]) == 1 async def test_unpin_fails_for_ghost_member(tmp_path, roster): @@ -583,145 +463,35 @@ async def test_unpin_fails_for_ghost_member(tmp_path, roster): session = await _session(tmp_path, roster, operator=True, node_user_id="grenet") await roster.set_member(GROUP, "ghost", "member", "revoked", "local-cli") - # ghost has no identity row - session._do_member_unpin({"user_id": "ghost"}) - challenge = _last(session) - assert challenge["type"] == "admin_challenge" + with pytest.raises(ops.OpError, match="No such pinned identity"): + await ops.unpin_member(session.state, "ghost") - await _sign_and_exec(session, OP_MEMBER_UNPIN, "ghost", - session.sk_op, session._admin_exec_member_unpin) - msg = _last(session) - assert msg["type"] == "error" - assert "No such pinned identity" in msg["detail"] - - -async def test_unpin_succeeds_for_real_identity(tmp_path, roster): - """Full unpin flow: challenge → sign → exec → identity deleted.""" - session = await _session(tmp_path, roster, operator=True, - node_user_id="grenet") - sk2, pk2 = _keypair() - await roster.pin_identity("target", "target", pk2, pk2, "code") - await roster.set_member(GROUP, "target", "member", "active", "local-cli") - - session._do_member_unpin({"user_id": "target"}) - challenge = _last(session) - assert challenge["type"] == "admin_challenge" - - await _sign_and_exec(session, OP_MEMBER_UNPIN, "target", - session.sk_op, session._admin_exec_member_unpin) - msg = _last(session) - assert msg["type"] == "member_unpin_ack" - assert msg["user_id"] == "target" - - idents = await roster.list_identities() - assert not any(i["user_id"] == "target" for i in idents) - - -# ── denylist_read MNP handler ──────────────────────────────────────────── -async def test_denylist_read_returns_entries_for_admin(tmp_path, roster): +async def test_read_denylist_lists_entries(tmp_path, roster): session = await _session(tmp_path, roster, operator=True, node_user_id="grenet") session.denylist.deny_user("bad-user") - session._spawn(session._do_denylist_read({})) - await _drain(session) - msg = _last(session) - assert msg["type"] == "denylist_read_ack" - assert msg["count"] == 1 - assert "bad-user" in msg["users"] + result = await ops.read_denylist(session.state) + assert result["count"] == 1 + assert "bad-user" in result["users"] -async def test_denylist_read_refused_for_non_admin(tmp_path, roster): - session = await _session(tmp_path, roster, operator=False, - node_user_id="grenet") - session._spawn(session._do_denylist_read({})) - await _drain(session) - msg = _last(session) - assert msg["type"] == "error" - - -# ── denylist_clear MNP handler ─────────────────────────────────────────── - -async def test_denylist_clear_removes_entry_for_admin(tmp_path, roster): +async def test_clear_denylist_removes_one_entry(tmp_path, roster): session = await _session(tmp_path, roster, operator=True, node_user_id="grenet") session.denylist.deny_user("bad-user") session.denylist.deny_user("other-user") - session._spawn(session._do_denylist_clear({"subject": "bad-user"})) - await _drain(session) - msg = _last(session) - assert msg["type"] == "denylist_clear_ack" - assert msg["removed"] == 1 + result = await ops.clear_denylist(session.state, subject="bad-user") + assert result["removed"] == 1 assert "bad-user" not in session.denylist.entries()["users"] assert "other-user" in session.denylist.entries()["users"] -async def test_denylist_clear_all_for_admin(tmp_path, roster): +async def test_clear_denylist_all(tmp_path, roster): session = await _session(tmp_path, roster, operator=True, node_user_id="grenet") session.denylist.deny_user("a") session.denylist.deny_user("b") session.denylist.deny_jti("j") - session._spawn(session._do_denylist_clear({"subject": ""})) - await _drain(session) - msg = _last(session) - assert msg["type"] == "denylist_clear_ack" - assert msg["removed"] == 3 - - -async def test_denylist_clear_refused_for_non_admin(tmp_path, roster): - session = await _session(tmp_path, roster, operator=False, - node_user_id="grenet") - session._spawn(session._do_denylist_clear({"subject": "bad-user"})) - await _drain(session) - msg = _last(session) - assert msg["type"] == "error" - - -# ── group_attach MNP handler ──────────────────────────────────────────── - -async def test_group_attach_issues_challenge(tmp_path, roster): - session = await _session(tmp_path, roster, operator=True, - node_user_id="grenet") - session._do_group_attach({"name": "test-group", "shared_dir": "/tmp/share"}) - msg = _last(session) - assert msg["type"] == "admin_challenge" - - -async def test_group_attach_refused_without_authority(tmp_path, roster): - session = await _session(tmp_path, roster, operator=False) - session._do_group_attach({"name": "test-group", "shared_dir": "/tmp/share"}) - msg = _last(session) - assert msg["type"] == "error" - assert "authorized" in msg["detail"].lower() - - -async def test_group_attach_refuses_missing_fields(tmp_path, roster): - session = await _session(tmp_path, roster, operator=True, - node_user_id="grenet") - session._do_group_attach({"name": "test-group"}) - msg = _last(session) - assert msg["type"] == "error" - assert "Missing" in msg["detail"] - - -# ── node_reload MNP handler ───────────────────────────────────────────── - -async def test_node_reload_runs_for_admin(tmp_path, roster): - session = await _session(tmp_path, roster, operator=True, - node_user_id="grenet") - session._spawn(session._do_node_reload({})) - await _drain(session) - msg = _last(session) - assert msg["type"] == "node_reload_ack" - assert msg["status"] == "reloaded" - assert len(session.reload_called) == 1 - - -async def test_node_reload_refused_for_non_admin(tmp_path, roster): - session = await _session(tmp_path, roster, operator=False, - node_user_id="grenet") - session._spawn(session._do_node_reload({})) - await _drain(session) - msg = _last(session) - assert msg["type"] == "error" + result = await ops.clear_denylist(session.state, subject="") + assert result["removed"] == 3 diff --git a/packages/meshbay-node/tests/test_root_writable_policy.py b/packages/meshbay-node/tests/test_root_writable_policy.py index 0cd9af8..0dc5d6d 100644 --- a/packages/meshbay-node/tests/test_root_writable_policy.py +++ b/packages/meshbay-node/tests/test_root_writable_policy.py @@ -12,8 +12,9 @@ The properties this holds: A member with an old tab open, or one speaking MNP directly, gets the same answer. That half is pinned in `test_security_regressions.py`, next to the overwrite properties it belongs with; -* the setting is changed by a **signed** operator instruction, or it is a - suggestion any member can undo; +* the setting is changed **on the node's own machine** — the desktop + application over loopback, or the CLI — and never over MNP, where a signature + proves only that the operator's key signed (`test_sharing_is_local_only.py`); * it is stored on the **node**, never the hub. A hub that could decide who writes to the operator's disk would have authority over the node. @@ -26,7 +27,7 @@ from pathlib import Path import pytest from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey -from meshbay_common.adminop import OP_ROOT_EJECT, OP_ROOT_PLUG, OP_ROOT_UPDATE +from meshbay_common.adminop import OP_ROOT_EJECT, OP_ROOT_PLUG from meshbay_common.crypto import generate_gek from meshbay_common.protocol import MNP from meshbay_node.indexer.group_index import GroupIndex @@ -163,34 +164,6 @@ def _capture_challenges(session) -> list[tuple[str, str]]: return issued -async def test_changing_a_roots_flags_needs_a_signature(tmp_path): - """The flags are not applied by the request — only by the signed response.""" - session = _session(tmp_path, "the-operator", operator="the-operator") - issued = _capture_challenges(session) - - session._do_root_update({"group_id": "g" * 32, "root_name": "shared", - "writable": False}) - - assert [op for op, _ in issued] == [OP_ROOT_UPDATE] - assert session._ctx["roots"].roots[0].writable is True, ( - "applied before it was signed") - - -async def test_the_subject_names_the_outcome_not_the_operation(tmp_path): - """ - The operator is shown the subject before signing, so it has to say what will - be true afterwards. "shared" alone would have them authorize a change they - cannot see the direction of. - """ - session = _session(tmp_path, "op", operator="op") - issued = _capture_challenges(session) - - session._do_root_update({"group_id": "g" * 32, "root_name": "shared", - "writable": True, "removable": True}) - - assert issued == [(OP_ROOT_UPDATE, "shared:rw=on,rem=on")] - - async def test_eject_and_plug_are_signed_too(tmp_path): """ Hiding a group's whole library from every member is not a lesser act than @@ -214,8 +187,7 @@ async def test_a_request_with_nobody_to_authorize_it_is_refused(tmp_path): issued = _capture_challenges(session) session._has_admin_authority = lambda: False - session._do_root_update({"group_id": "g" * 32, "root_name": "shared", - "writable": True}) + session._do_root_eject({"group_id": "g" * 32, "root_name": "shared"}) assert issued == [] assert [m for m in session.sent if m.get("type") == "error"] diff --git a/packages/meshbay-node/tests/test_security_regressions.py b/packages/meshbay-node/tests/test_security_regressions.py index 43e88c2..26a3b1d 100644 --- a/packages/meshbay-node/tests/test_security_regressions.py +++ b/packages/meshbay-node/tests/test_security_regressions.py @@ -842,14 +842,11 @@ def test_node_control_api_serves_no_html(): # ── NS4 / M3: the node's own controls take no authority from the hub ───────── -async def _owner_session(tmp_path, roster, *, device: str = "", - confirmed: bool = False): +async def _owner_session(tmp_path, roster): """A session whose token says it is the account this node belongs to. Which is all a hub can decide: `_user_id` is the `sub` of a JWT it issued, - so this is what an active hub forging a token arrives holding. Whether the - *device* on the connection is one the node pinned as an operator is the - other half, and no token can assert it. + so this is what an active hub forging a token arrives holding. """ from meshbay_node.indexer.group_index import GroupIndex @@ -865,9 +862,6 @@ async def _owner_session(tmp_path, roster, *, device: str = "", } session._group_id = "g" * 32 session._user_id = "the-owner" - session._username = "the-owner" - session._pinned_pk = device - session._device_confirmed = confirmed session._pk_user = "" session.sent = [] session._send = session.sent.append @@ -876,18 +870,18 @@ async def _owner_session(tmp_path, roster, *, device: str = "", @pytest.mark.asyncio -async def test_a_token_naming_the_owner_is_not_node_authority(tmp_path): +@pytest.mark.parametrize("mtype", ["node_status", "node_settings_set", "roster_read", + "denylist_read", "denylist_clear", "node_reload"]) +async def test_a_token_naming_the_owner_reaches_no_node_control(tmp_path, mtype): """ - The hub holds no user keys, so it cannot countersign a device — but it does - choose what a token says. Six node-wide controls used to be gated on the - account id alone, which is the hub's to decide: `node_status` (every group - on the machine, with the operator's absolute paths), `node_settings_set`, - `roster_read`, `denylist_read`, `denylist_clear` (the persisted revocation - H4 exists to keep) and `node_reload`. - - An active hub reaches a completed handshake wherever it can also obtain the - group key, which §3.5 concedes it can in an open-join group. From there, - "the hub says you are the owner" was the whole of the check. + The hub holds no user keys, but it does choose what a token says. Six + node-wide controls were once gated on the account id alone: `node_status` + (every group on the machine, with the operator's absolute paths), + `node_settings_set`, `roster_read`, `denylist_read`, `denylist_clear` (the + persisted revocation H4 exists to keep) and `node_reload`. A device proof + closed that; MNP 6.0 removed the messages, since no client sent them. They + are the loopback API's and the CLI's — on the operator's own machine — and a + peer naming one over MNP is answered by nobody. """ from meshbay_node.roster import Roster @@ -895,67 +889,8 @@ async def test_a_token_naming_the_owner_is_not_node_authority(tmp_path): await roster.open() try: forged = await _owner_session(tmp_path, roster) - await forged._do_node_status({}) - assert forged.sent[-1]["type"] == "error" - assert forged.sent[-1]["code"] == "not_operator" - - forged.sent.clear() - await forged._do_denylist_read({}) - assert forged.sent[-1]["type"] == "error" - - forged.sent.clear() - await forged._do_denylist_clear({"subject": ""}) - assert forged.sent[-1]["type"] == "error", ( - "clearing the denylist undoes a revocation every node enforces") - finally: - await roster.close() - - -@pytest.mark.asyncio -async def test_an_identified_device_that_is_not_an_operator_is_refused(tmp_path): - """Being a pinned member of the group is not being the node's operator. - - The device proof is real here; what it proves is an ordinary member's key, - and `operator_pks()` is rebuilt from the roster on every call so a revoked - one stops working at once. - """ - from meshbay_common.crypto import pk_to_b64 - from meshbay_node.roster import Roster - - roster = Roster(db_path=tmp_path / "roster.db") - await roster.open() - try: - sk = Ed25519PrivateKey.generate() - member_pk = pk_to_b64(sk.public_key()) - await roster.pin_identity("the-owner", "the-owner", member_pk, - member_pk, "code") - session = await _owner_session(tmp_path, roster, device=member_pk, - confirmed=True) - await session._do_node_status({}) - assert session.sent[-1]["type"] == "error" - finally: - await roster.close() - - -@pytest.mark.asyncio -async def test_a_paired_operator_device_is_what_opens_it(tmp_path): - """The positive case, so the test above is about authority and not about - everything being refused.""" - from meshbay_common.crypto import pk_to_b64 - from meshbay_common.join import ROLE_OPERATOR - from meshbay_node.roster import Roster - - roster = Roster(db_path=tmp_path / "roster.db") - await roster.open() - try: - sk = Ed25519PrivateKey.generate() - pk = pk_to_b64(sk.public_key()) - await roster.pin_identity("the-owner", "the-owner", pk, pk, "code") - await roster.set_member("", "the-owner", ROLE_OPERATOR, "active", - "local-cli") - session = await _owner_session(tmp_path, roster, device=pk, - confirmed=True) - await session._do_denylist_read({}) - assert session.sent[-1]["type"] != "error", session.sent[-1] + forged._dispatch_message({"type": mtype, "subject": "", "group_id": "g" * 32, + "settings": {"max_peers": 1}}) + assert forged.sent == [], f"{mtype} answered over MNP: {forged.sent}" finally: await roster.close() diff --git a/packages/meshbay-node/tests/test_sharing_is_local_only.py b/packages/meshbay-node/tests/test_sharing_is_local_only.py new file mode 100644 index 0000000..ac8bebb --- /dev/null +++ b/packages/meshbay-node/tests/test_sharing_is_local_only.py @@ -0,0 +1,109 @@ +""" +What of the operator's disk is shared, and who may write there, is decided on +the node's own machine — never over MNP (MNP 6.0). + +A signed operation proves that the operator's key signed, not that the operator +meant it: in a browser the key is driven by code the hub serves, and in the +desktop application by a renderer that parses content from nodes. `root_add`, +`root_update` and `group_attach` let either of them share any folder on the +machine, or open one to writes, from anywhere. They are gone; the loopback API +(the desktop application) and the CLI remain. + +And the consequence that has to hold for the operator's list to stay true: a +flag changed through the loopback API reaches every connected page, which the +MNP ack used to do. +""" + +from dataclasses import asdict +from pathlib import Path +from types import SimpleNamespace + +import pytest +from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey +from meshbay_common import adminop +from meshbay_common.protocol import MNP +from meshbay_node import ops +from meshbay_node.config import GroupConfig, RootSpec +from meshbay_node.indexer.indexer import DirectoryIndexer +from meshbay_node.roots import RootSet +from meshbay_node.transport.webrtc.admin import _ADMIN_EXECUTORS +from meshbay_node.transport.webrtc.dispatch import _HANDLERS +from meshbay_node.transport.webrtc_server import WebRTCPeerSession +from test_admin_challenge_bounds import _PC, _Channel + +GROUP = "g" * 32 +GONE = ("root_add", "root_update", "group_attach") + + +@pytest.mark.parametrize("mtype", GONE) +def test_no_message_widens_what_the_node_shares(mtype): + assert mtype not in _HANDLERS, f"{mtype} is dispatched again" + assert mtype not in _ADMIN_EXECUTORS, f"{mtype} can be executed again" + assert mtype not in vars(MNP).values(), f"{mtype} is back in the protocol" + assert mtype not in vars(adminop).values(), f"{mtype} is a signed op again" + + +@pytest.mark.parametrize("mtype", GONE) +def test_an_older_client_asking_is_issued_nothing_to_sign(mtype): + """A 5.x client still sends these. Nothing it sends may come back as a + challenge — a challenge is what a compromised page needs signed.""" + ctx = {"sk_node": Ed25519PrivateKey.from_private_bytes(b"\x01" * 32), + "groups": {GROUP: {}}, "has_admin_authority": True} + s = WebRTCPeerSession(_PC(), ctx, peer_id="peer") + s._channel = _Channel() + s._audit = lambda *a, **k: None + s._user_id, s._group_id = "operator", GROUP + + s._dispatch_message({"type": mtype, "group_id": GROUP, "path": "/home/someone", + "shared_dir": "/home/someone", "name": "x", + "root_name": "x", "writable": True}) + + assert s._admin_ops == {} + assert not [m for m in s._channel.sent if m.get("type") == "admin_challenge"] + + +def _state(tmp_path: Path, indexer_roots: RootSet | None = None): + (tmp_path / "media").mkdir() + cfg = GroupConfig(id=GROUP, name="plop", + roots=[RootSpec(path=str(tmp_path / "media"), name="media")]) + conf = tmp_path / "node.toml" + conf.write_text( + f'[[groups]]\nid = "{GROUP}"\nname = "plop"\n\n' + f' [[groups.roots]]\n path = "{(tmp_path / "media").as_posix()}"\n' + f' name = "media"\n', encoding="utf-8") + live = RootSet.build([asdict(r) for r in cfg.roots]) + pushed: list[list[dict]] = [] + + async def on_change(indexer): + pushed.append(indexer.index.roots) + + indexer = DirectoryIndexer(indexer_roots or live, GROUP, + Ed25519PrivateKey.generate(), None, + on_change=on_change) + state = {"config": SimpleNamespace(groups=[cfg]), "config_path": str(conf), + "groups_ctx": {GROUP: {"roots": live}}, + "indexers": {GROUP: indexer}} + return state, pushed + + +async def test_a_flag_changed_on_the_node_reaches_every_open_page(tmp_path): + state, pushed = _state(tmp_path) + + await ops.update_root(state, GROUP, "media", writable=True) + + assert pushed, "nothing was pushed — open pages keep the old flag" + assert pushed[-1][0]["writable"] is True + + +async def test_the_pushed_table_is_right_when_the_indexer_holds_its_own_set(tmp_path): + """The indexer and the group context normally share one RootSet; when they + do not, the table peers receive is the indexer's, and must carry the flag.""" + (tmp_path / "media").mkdir() + own = RootSet.build([{"path": str(tmp_path / "media"), "name": "media"}]) + (tmp_path / "media").rmdir() + state, pushed = _state(tmp_path, indexer_roots=own) + + await ops.update_root(state, GROUP, "media", removable=True) + + assert pushed[-1][0]["removable"] is True + assert state["groups_ctx"][GROUP]["roots"].by_name("media").removable is True |