1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
"""
A revocation the hub signed closes what it revokes, not only what comes next.
The denylist refuses the next connection. A revoked account's live sessions
were left open — streaming, downloading, chatting — until they happened to end;
only a group's revocation closed its sessions.
"""
import asyncio
import pytest
from meshbay_node.daemon import NodeDaemon
from meshbay_node.transport.quic_server import Denylist
class _Session:
def __init__(self, user_id, group_id):
self._user_id = user_id
self._group_id = group_id
self.closed = False
async def close(self):
self.closed = True
def _daemon(sessions):
d = NodeDaemon.__new__(NodeDaemon)
d._webrtc = type("T", (), {"_sessions": sessions})()
return d
@pytest.mark.asyncio
async def test_a_revoked_account_is_disconnected(tmp_path):
mallory, alice = _Session("mallory", "g1"), _Session("alice", "g1")
phone = _Session("mallory", "g2")
d = _daemon({"a": mallory, "b": alice, "c": phone})
deny = Denylist(path=tmp_path / "deny.json")
d._apply_revocation(deny, "user", "mallory")
await asyncio.sleep(0.05)
assert mallory.closed and phone.closed, "every session of the account ends"
assert not alice.closed
assert deny.is_denied("mallory", "")
@pytest.mark.asyncio
async def test_a_revoked_group_is_still_disconnected(tmp_path):
a, b = _Session("alice", "g1"), _Session("alice", "g2")
d = _daemon({"a": a, "b": b})
d._apply_revocation(Denylist(path=tmp_path / "deny.json"), "group", "g1")
await asyncio.sleep(0.05)
assert a.closed and not b.closed
|