diff --git a/server/tests/api_v4/authenticated/test_certificate_get.py b/server/tests/api_v4/authenticated/test_certificate_get.py index d6695096cce..4131c3aa066 100644 --- a/server/tests/api_v4/authenticated/test_certificate_get.py +++ b/server/tests/api_v4/authenticated/test_certificate_get.py @@ -29,6 +29,7 @@ authenticated_cmds, ) from tests.common import AsyncClient, AuthenticatedRpcClient, Backend, CoolorgRpcClients +from tests.common.client import setup_shamir_for_coolorg @pytest.mark.parametrize("redacted", (False, True)) @@ -41,7 +42,7 @@ async def test_authenticated_certificate_get_ok_common_certificates( org_id = OrganizationID("Org") root_key = SigningKey.generate() - t0 = DateTime(1999, 12, 31) # Oldest time: nothing occured at this point + t0 = DateTime(1999, 12, 31) # Oldest time: nothing occurred at this point t1 = DateTime( 2000, 1, 1 ) # Orga is bootstrapped, Alice is created (used as client when not redacted) @@ -350,7 +351,7 @@ async def test_authenticated_certificate_get_ok_common_certificates( async def test_authenticated_certificate_get_ok_realm_certificates( backend: Backend, coolorg: CoolorgRpcClients ) -> None: - t0 = DateTime(2000, 12, 31) # Oldest time: nothing occured at this point + t0 = DateTime(2000, 12, 31) # Oldest time: nothing occurred at this point t1 = DateTime(2001, 1, 1) t2 = DateTime(2001, 1, 2) t3 = DateTime(2001, 1, 3) @@ -740,3 +741,79 @@ async def test_authenticated_certificate_get_ok_realm_certificates_no_longer_sha ) assert isinstance(rep, authenticated_cmds.v4.certificate_get.RepOk) assert rep.realm_certificates[coolorg.wksp1_id] == wksp1_certificates + + +async def test_authenticated_certificate_get_ok_shamir( + backend: Backend, coolorg: CoolorgRpcClients +) -> None: + a_long_time_ago = DateTime.now() + + # no shamir certificate at first + rep = await coolorg.alice.certificate_get( + common_after=None, + sequester_after=None, + shamir_recovery_after=None, + realm_after={}, + ) + assert isinstance(rep, authenticated_cmds.v4.certificate_get.RepOk) + assert rep.shamir_recovery_certificates == [] + + # setup usual shamir + (brief, share) = await setup_shamir_for_coolorg(coolorg) + + # checks from alice's (=author) point of view + rep1 = await coolorg.alice.certificate_get( + common_after=None, + sequester_after=None, + shamir_recovery_after=None, + realm_after={}, + ) + + rep2 = await coolorg.alice.certificate_get( + common_after=None, + sequester_after=None, + shamir_recovery_after=a_long_time_ago, + realm_after={}, + ) + + assert rep1 == rep2 + assert isinstance(rep1, authenticated_cmds.v4.certificate_get.RepOk) + assert rep1.shamir_recovery_certificates == [brief] + + # no new shamir + rep = await coolorg.alice.certificate_get( + common_after=None, + sequester_after=None, + shamir_recovery_after=DateTime.now(), + realm_after={}, + ) + assert isinstance(rep, authenticated_cmds.v4.certificate_get.RepOk) + assert rep.shamir_recovery_certificates == [] + + # from mallory's (=share recipient) point of view + + rep = await coolorg.mallory.certificate_get( + common_after=None, + sequester_after=None, + shamir_recovery_after=a_long_time_ago, + realm_after={}, + ) + + assert isinstance(rep, authenticated_cmds.v4.certificate_get.RepOk) + assert set(rep.shamir_recovery_certificates) == set( + [brief, share] + ) # these have the same timestamp, so order does not matter + + # from bob's (=not involved) point of view + + rep = await coolorg.bob.certificate_get( + common_after=None, + sequester_after=None, + shamir_recovery_after=a_long_time_ago, + realm_after={}, + ) + + assert isinstance(rep, authenticated_cmds.v4.certificate_get.RepOk) + assert rep.shamir_recovery_certificates == [] + + # TODO check coherence after deletion diff --git a/server/tests/common/client.py b/server/tests/common/client.py index 2959f4b0387..6df432ea666 100644 --- a/server/tests/common/client.py +++ b/server/tests/common/client.py @@ -382,7 +382,11 @@ async def coolorg(app: AsgiApp, testbed: TestbedBackend) -> AsyncGenerator[Coolo async def setup_shamir_for_coolorg( coolorg: CoolorgRpcClients, -): +) -> tuple[bytes, bytes]: + """ + setup a shamir for alice, with mallory as a share recipient + returns the associated brief and share as bytes + """ dt = DateTime.now() share = ShamirRecoveryShareCertificate( author=coolorg.alice.device_id, @@ -399,14 +403,18 @@ async def setup_shamir_for_coolorg( per_recipient_shares={coolorg.mallory.user_id: 2}, ) + raw_brief = brief.dump_and_sign(coolorg.alice.signing_key) + raw_share = share.dump_and_sign(coolorg.alice.signing_key) + setup = authenticated_cmds.v4.shamir_recovery_setup.ShamirRecoverySetup( b"abc", ShamirRevealToken.new(), - brief.dump_and_sign(coolorg.alice.signing_key), - [share.dump_and_sign(coolorg.alice.signing_key)], + raw_brief, + [raw_share], ) rep = await coolorg.alice.shamir_recovery_setup(setup) assert rep == authenticated_cmds.v4.shamir_recovery_setup.RepOk() + return (raw_brief, raw_share) @dataclass(slots=True)