aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node/tests/test_revocation_closes_sessions.py
blob: 7c8e79c110806fd2df8ec32468bfa66d0de7e0c5 (plain) (blame)
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