Ejemplo n.º 1
0
    async def _run_claimer():
        async with backend_invited_cmds_factory(addr=invitation_addr) as cmds:
            initial_ctx = await claimer_retrieve_info(cmds)
            assert isinstance(initial_ctx, UserClaimInitialCtx)
            assert initial_ctx.claimer_email == claimer_email
            assert initial_ctx.greeter_user_id == alice.user_id
            assert initial_ctx.greeter_human_handle == alice.human_handle

            in_progress_ctx = await initial_ctx.do_wait_peer()

            choices = in_progress_ctx.generate_greeter_sas_choices(size=4)
            assert len(choices) == 4
            assert in_progress_ctx.greeter_sas in choices

            greeter_sas = await oob_recv.receive()
            assert greeter_sas == in_progress_ctx.greeter_sas

            in_progress_ctx = await in_progress_ctx.do_signify_trust()
            await oob_send.send(in_progress_ctx.claimer_sas)

            in_progress_ctx = await in_progress_ctx.do_wait_peer_trust()

            nonlocal new_device
            new_device = await in_progress_ctx.do_claim_user(
                requested_device_label=requested_device_label,
                requested_human_handle=requested_human_handle,
            )
            assert isinstance(new_device, LocalDevice)
            # User storage should be populated with non-speculative user manifest
            # before save the device
            await user_storage_non_speculative_init(
                data_base_dir=data_base_dir, device=new_device)
Ejemplo n.º 2
0
    async def _run_claimer():
        nonlocal greeter_sas
        nonlocal claimer_sas

        async with backend_invited_cmds_factory(
                addr=gdi_w.invite_addr) as cmds:
            await start_claimer.wait()

            initial_ctx = await claimer_retrieve_info(cmds)
            in_progress_ctx = await initial_ctx.do_wait_peer()
            greeter_sas = in_progress_ctx.greeter_sas
            greeter_sas_available.set()

            await start_claimer_trust.wait()

            in_progress_ctx = await in_progress_ctx.do_signify_trust()
            claimer_sas = in_progress_ctx.claimer_sas
            claimer_sas_available.set()
            in_progress_ctx = await in_progress_ctx.do_wait_peer_trust()

            await start_claimer_claim_user.wait()

            await in_progress_ctx.do_claim_device(
                requested_device_label=requested_device_label)
            claimer_done.set()
Ejemplo n.º 3
0
 async def _reset_claimer(self):
     async with backend_invited_cmds_factory(addr=self.invitation_addr) as cmds:
         claimer_initial_ctx = await claimer_retrieve_info(cmds)
         async with trio.open_nursery() as nursery:
             nursery.start_soon(claimer_initial_ctx.do_wait_peer)
             yield
             nursery.cancel_scope.cancel()
Ejemplo n.º 4
0
    async def _run_claimer():
        async with backend_invited_cmds_factory(addr=invitation_addr) as cmds:
            initial_ctx = await claimer_retrieve_info(cmds)
            assert isinstance(initial_ctx, DeviceClaimInitialCtx)
            assert initial_ctx.greeter_user_id == alice.user_id
            assert initial_ctx.greeter_human_handle == alice.human_handle

            in_progress_ctx = await initial_ctx.do_wait_peer()

            choices = in_progress_ctx.generate_greeter_sas_choices(size=4)
            assert len(choices) == 4
            assert in_progress_ctx.greeter_sas in choices

            greeter_sas = await oob_recv.receive()
            assert greeter_sas == in_progress_ctx.greeter_sas

            in_progress_ctx = await in_progress_ctx.do_signify_trust()
            await oob_send.send(in_progress_ctx.claimer_sas)

            in_progress_ctx = await in_progress_ctx.do_wait_peer_trust()

            nonlocal new_device
            new_device = await in_progress_ctx.do_claim_device(
                requested_device_label=requested_device_label)
            assert isinstance(new_device, LocalDevice)
Ejemplo n.º 5
0
async def _claim_invitation(config, addr, password):
    async with backend_invited_cmds_factory(addr=addr) as cmds:
        try:
            async with spinner("Retrieving invitation info"):
                initial_ctx = await claimer_retrieve_info(cmds)
        except BackendConnectionRefused:
            raise RuntimeError("Invitation not found")

        if initial_ctx.greeter_human_handle:
            display_greeter = click.style(initial_ctx.greeter_human_handle,
                                          fg="yellow")
        else:
            display_greeter = click.style(initial_ctx.greeter_user_id,
                                          fg="yellow")
        click.echo(f"Invitation greeter: {display_greeter}")
        while True:
            try:
                if isinstance(initial_ctx, DeviceClaimInitialCtx):
                    new_device = await _do_claim_device(initial_ctx)
                else:
                    assert isinstance(initial_ctx, UserClaimInitialCtx)
                    new_device = await _do_claim_user(initial_ctx)
                if new_device:
                    break
            except InviteError as exc:
                click.secho(str(exc), fg="red")
            click.secho("Restarting the invitation process", fg="red")

        device_display = click.style(new_device.slughash, fg="yellow")
        with operation(f"Saving device {device_display}"):
            save_device_with_password(config.config_dir, new_device, password)
Ejemplo n.º 6
0
    async def _run_claimer():
        async with backend_invited_cmds_factory(addr=invitation_addr) as cmds:
            initial_ctx = await claimer_retrieve_info(cmds)
            in_progress_ctx = await initial_ctx.do_wait_peer()
            in_progress_ctx = await in_progress_ctx.do_signify_trust()
            in_progress_ctx = await in_progress_ctx.do_wait_peer_trust()

            await in_progress_ctx.do_claim_user(requested_device_label=None,
                                                requested_human_handle=None)
Ejemplo n.º 7
0
async def test_handshake_unknown_organization(running_backend, coolorg):
    invitation_addr = BackendInvitationAddr.build(
        backend_addr=running_backend.addr,
        organization_id=coolorg.organization_id,
        invitation_type=InvitationType.DEVICE,
        token=uuid4(),
    )
    with pytest.raises(BackendInvitationNotFound) as exc:
        async with backend_invited_cmds_factory(invitation_addr) as cmds:
            await cmds.ping()
    assert str(exc.value) == "Invalid handshake: Invitation not found"
Ejemplo n.º 8
0
async def test_handshake_already_used_invitation(running_backend, coolorg, invitation_addr, alice):
    await running_backend.backend.invite.delete(
        organization_id=alice.organization_id,
        greeter=alice.user_id,
        token=invitation_addr.token,
        on=pendulum_now(),
        reason=InvitationDeletedReason.CANCELLED,
    )

    with pytest.raises(BackendInvitationAlreadyUsed) as exc:
        async with backend_invited_cmds_factory(invitation_addr) as cmds:
            await cmds.ping()
    assert str(exc.value) == "Invalid handshake: Invitation already deleted"
Ejemplo n.º 9
0
 async def run(self):
     await self.bootstrap()
     async with trio.open_nursery() as self.nursery:
         async with backend_invited_cmds_factory(addr=self.invitation_addr) as self.cmds:
             next_step = "step_1_start_greet"
             while True:
                 current_step = next_step
                 next_step = await getattr(self, current_step)()
                 self.steps_done.append(current_step)
                 if next_step is None:
                     break
             if self.claimer_claim_task:
                 await self.claimer_claim_task.cancel_and_join()
Ejemplo n.º 10
0
 async def run(self):
     await self.bootstrap()
     async with backend_invited_cmds_factory(
             addr=self.invitation_addr) as self.cmds:
         # Nursery used to run the claimer, should be closed before tearing down
         # invited cmds otherwise deadlock may occur
         async with trio.open_nursery() as self.nursery:
             next_step = "step_1_start_greet"
             while True:
                 current_step = next_step
                 next_step = await getattr(self, current_step)()
                 self.steps_done.append(current_step)
                 if next_step is None:
                     break
             if self.claimer_claim_task:
                 await self.claimer_claim_task.cancel_and_join()
Ejemplo n.º 11
0
async def test_handshake_organization_expired(running_backend, expiredorg,
                                              expiredorgalice):
    invitation = await running_backend.backend.invite.new_for_device(
        organization_id=expiredorgalice.organization_id,
        greeter_user_id=expiredorgalice.user_id)
    invitation_addr = BackendInvitationAddr.build(
        backend_addr=running_backend.addr,
        organization_id=expiredorgalice.organization_id,
        invitation_type=InvitationType.DEVICE,
        token=invitation.token,
    )

    with pytest.raises(BackendConnectionRefused) as exc:
        async with backend_invited_cmds_factory(invitation_addr) as cmds:
            await cmds.ping()
    assert str(exc.value) == "Trial organization has expired"
Ejemplo n.º 12
0
async def _claim_invitation(
    config: CoreConfig, addr: BackendInvitationAddr, save_device_with_selected_auth: Callable
) -> None:
    async with backend_invited_cmds_factory(
        addr=addr, keepalive=config.backend_connection_keepalive
    ) as cmds:
        try:
            async with spinner("Retrieving invitation info"):
                initial_ctx = await claimer_retrieve_info(cmds)
        except BackendConnectionRefused:
            raise RuntimeError("Invitation not found")

        if initial_ctx.greeter_human_handle:
            display_greeter = click.style(str(initial_ctx.greeter_human_handle), fg="yellow")
        else:
            display_greeter = click.style(initial_ctx.greeter_user_id, fg="yellow")
        click.echo(f"Invitation greeter: {display_greeter}")
        while True:
            try:
                if isinstance(initial_ctx, DeviceClaimInitialCtx):
                    new_device = await _do_claim_device(initial_ctx)
                else:
                    assert isinstance(initial_ctx, UserClaimInitialCtx)
                    new_device = await _do_claim_user(initial_ctx)
                if new_device:
                    break
            except InviteError as exc:
                click.secho(str(exc), fg="red")
            click.secho("Restarting the invitation process", fg="red")

        # Claiming a user means we are it first device, hence we know there
        # is no existing user manifest (hence our placeholder is non-speculative)
        if addr.invitation_type == InvitationType.USER:
            await user_storage_non_speculative_init(
                data_base_dir=config.data_base_dir, device=new_device
            )
        await save_device_with_selected_auth(config_dir=config.config_dir, device=new_device)
Ejemplo n.º 13
0
async def test_backend_switch_offline(running_backend, invitation_addr):
    async with backend_invited_cmds_factory(invitation_addr) as cmds:
        await cmds.ping()
        with running_backend.offline():
            with pytest.raises(BackendNotAvailable):
                await cmds.ping()
Ejemplo n.º 14
0
    async def run(self, addr, config):
        try:
            async with backend_invited_cmds_factory(
                    addr=addr,
                    keepalive=config.backend_connection_keepalive) as cmds:
                # Trigger handshake
                await cmds.ping()
                r = await self.main_oob_recv.receive()

                assert r == self.Step.RetrieveInfo
                try:
                    initial_ctx = await claimer_retrieve_info(cmds)
                    await self.job_oob_send.send(
                        (True, None, initial_ctx.claimer_email))
                except Exception as exc:
                    await self.job_oob_send.send((False, exc, None))

                r = await self.main_oob_recv.receive()

                assert r == self.Step.WaitPeer
                try:
                    in_progress_ctx = await initial_ctx.do_wait_peer()
                    await self.job_oob_send.send((True, None))
                except Exception as exc:
                    await self.job_oob_send.send((False, exc))

                r = await self.main_oob_recv.receive()

                assert r == self.Step.GetGreeterSas
                try:
                    choices = in_progress_ctx.generate_greeter_sas_choices(
                        size=4)
                    await self.job_oob_send.send(
                        (True, None, in_progress_ctx.greeter_sas, choices))
                except Exception as exc:
                    await self.job_oob_send.send((False, exc, None, None))

                r = await self.main_oob_recv.receive()

                assert r == self.Step.SignifyTrust
                try:
                    in_progress_ctx = await in_progress_ctx.do_signify_trust()
                    await self.job_oob_send.send((True, None))
                except Exception as exc:
                    await self.job_oob_send.send((False, exc))

                r = await self.main_oob_recv.receive()

                assert r == self.Step.GetClaimerSas
                await self.job_oob_send.send(in_progress_ctx.claimer_sas)

                r = await self.main_oob_recv.receive()

                assert r == self.Step.WaitPeerTrust
                try:
                    in_progress_ctx = await in_progress_ctx.do_wait_peer_trust(
                    )
                    await self.job_oob_send.send((True, None))
                except Exception as exc:
                    await self.job_oob_send.send((False, exc))

                r = await self.main_oob_recv.receive()
                assert r == self.Step.ClaimUser

                try:
                    device_label, human_handle = await self.main_oob_recv.receive(
                    )

                    new_device = await in_progress_ctx.do_claim_user(
                        requested_device_label=device_label,
                        requested_human_handle=human_handle)
                    # Claiming a user means we are it first device, hence we know there
                    # is no existing user manifest (hence our placeholder is non-speculative)
                    await user_storage_non_speculative_init(
                        data_base_dir=config.data_base_dir, device=new_device)
                    await self.job_oob_send.send((True, None, new_device))
                except Exception as exc:
                    await self.job_oob_send.send((False, exc, None))
        except BackendNotAvailable as exc:
            raise JobResultError(status="backend-not-available", origin=exc)
        except BackendInvitationAlreadyUsed as exc:
            raise JobResultError(status="invitation-already-used", origin=exc)
        except BackendConnectionRefused as exc:
            raise JobResultError(status="invitation-not-found", origin=exc)
        except BackendOutOfBallparkError as exc:
            raise JobResultError(status="out-of-ballpark", origin=exc)
Ejemplo n.º 15
0
    async def run(self, addr, config):
        try:
            async with backend_invited_cmds_factory(
                    addr=addr,
                    keepalive=config.backend_connection_keepalive) as cmds:
                # Trigger handshake
                await cmds.ping()
                r = await self.main_oob_recv.receive()

                assert r == self.Step.RetrieveInfo
                try:
                    initial_ctx = await claimer_retrieve_info(cmds)
                    await self.job_oob_send.send(
                        (True, None, initial_ctx.claimer_email))
                except Exception as exc:
                    await self.job_oob_send.send((False, exc, None))

                r = await self.main_oob_recv.receive()

                assert r == self.Step.WaitPeer
                try:
                    in_progress_ctx = await initial_ctx.do_wait_peer()
                    await self.job_oob_send.send((True, None))
                except Exception as exc:
                    await self.job_oob_send.send((False, exc))

                r = await self.main_oob_recv.receive()

                assert r == self.Step.GetGreeterSas
                try:
                    choices = in_progress_ctx.generate_greeter_sas_choices(
                        size=4)
                    await self.job_oob_send.send(
                        (True, None, in_progress_ctx.greeter_sas, choices))
                except Exception as exc:
                    await self.job_oob_send.send((False, exc, None, None))

                r = await self.main_oob_recv.receive()

                assert r == self.Step.SignifyTrust
                try:
                    in_progress_ctx = await in_progress_ctx.do_signify_trust()
                    await self.job_oob_send.send((True, None))
                except Exception as exc:
                    await self.job_oob_send.send((False, exc))

                r = await self.main_oob_recv.receive()

                assert r == self.Step.GetClaimerSas
                await self.job_oob_send.send(in_progress_ctx.claimer_sas)

                r = await self.main_oob_recv.receive()

                assert r == self.Step.WaitPeerTrust
                try:
                    in_progress_ctx = await in_progress_ctx.do_wait_peer_trust(
                    )
                    await self.job_oob_send.send((True, None))
                except Exception as exc:
                    await self.job_oob_send.send((False, exc))

                r = await self.main_oob_recv.receive()
                assert r == self.Step.ClaimUser

                try:
                    device_label, human_handle = await self.main_oob_recv.receive(
                    )

                    new_device = await in_progress_ctx.do_claim_user(
                        requested_device_label=device_label,
                        requested_human_handle=human_handle)
                    await self.job_oob_send.send((True, None, new_device))
                except Exception as exc:
                    await self.job_oob_send.send((False, exc, None))
        except BackendNotAvailable as exc:
            raise JobResultError(status="backend-not-available", origin=exc)
        except BackendInvitationAlreadyUsed as exc:
            raise JobResultError(status="invitation-already-used", origin=exc)
        except BackendConnectionRefused as exc:
            raise JobResultError(status="invitation-not-found", origin=exc)
Ejemplo n.º 16
0
 def _cmds_factory(keepalive):
     return backend_invited_cmds_factory(invitation_addr,
                                         keepalive=keepalive)
Ejemplo n.º 17
0
async def test_ping(running_backend, invitation_addr):
    async with backend_invited_cmds_factory(invitation_addr) as cmds:
        rep = await cmds.ping("Hello World !")
        assert rep == {"status": "ok", "pong": "Hello World !"}
Ejemplo n.º 18
0
async def test_claimer_handle_reset(backend, running_backend, alice,
                                    alice_backend_cmds):
    invitation = await backend.invite.new_for_device(
        organization_id=alice.organization_id, greeter_user_id=alice.user_id)
    invitation_addr = BackendInvitationAddr.build(
        backend_addr=alice.organization_addr.get_backend_addr(),
        organization_id=alice.organization_id,
        invitation_type=InvitationType.DEVICE,
        token=invitation.token,
    )

    async with backend_invited_cmds_factory(
            addr=invitation_addr) as claimer_cmds:
        greeter_initial_ctx = UserGreetInitialCtx(cmds=alice_backend_cmds,
                                                  token=invitation_addr.token)
        claimer_initial_ctx = await claimer_retrieve_info(claimer_cmds)

        claimer_in_progress_ctx = None
        greeter_in_progress_ctx = None

        # Step 1
        async with real_clock_timeout():
            async with trio.open_nursery() as nursery:

                async def _do_claimer():
                    nonlocal claimer_in_progress_ctx
                    claimer_in_progress_ctx = await claimer_initial_ctx.do_wait_peer(
                    )

                async def _do_greeter():
                    nonlocal greeter_in_progress_ctx
                    greeter_in_progress_ctx = await greeter_initial_ctx.do_wait_peer(
                    )

                nursery.start_soon(_do_claimer)
                nursery.start_soon(_do_greeter)

        # Claimer restart the conduit while greeter try to do step 2
        async with real_clock_timeout():
            async with trio.open_nursery() as nursery:

                async def _do_claimer():
                    nonlocal claimer_in_progress_ctx
                    claimer_in_progress_ctx = await claimer_initial_ctx.do_wait_peer(
                    )

                nursery.start_soon(_do_claimer)
                with pytest.raises(InvitePeerResetError):
                    await greeter_in_progress_ctx.do_wait_peer_trust()

                # Greeter redo step 1
                greeter_in_progress_ctx = await greeter_initial_ctx.do_wait_peer(
                )

        # Now do the other way around: greeter restart conduit while claimer try step 2
        async with real_clock_timeout():
            async with trio.open_nursery() as nursery:

                async def _do_greeter():
                    nonlocal greeter_in_progress_ctx
                    greeter_in_progress_ctx = await greeter_initial_ctx.do_wait_peer(
                    )

                nursery.start_soon(_do_greeter)
                with pytest.raises(InvitePeerResetError):
                    await claimer_in_progress_ctx.do_signify_trust()

                # Claimer redo step 1
                claimer_in_progress_ctx = await claimer_initial_ctx.do_wait_peer(
                )
Ejemplo n.º 19
0
async def test_backend_closed_cmds(running_backend, invitation_addr):
    async with backend_invited_cmds_factory(invitation_addr) as cmds:
        pass
    with pytest.raises(trio.ClosedResourceError):
        await cmds.ping()
Ejemplo n.º 20
0
async def initialize_test_organization(
    config_dir: Path,
    backend_address: BackendAddr,
    password: str,
    administration_token: str,
    force: bool,
) -> Tuple[LocalDevice, LocalDevice, LocalDevice]:

    configure_logging("WARNING")

    organization_id = OrganizationID("Org")

    # Create organization

    async with apiv1_backend_administration_cmds_factory(
        backend_address, administration_token
    ) as administration_cmds:

        rep = await administration_cmds.organization_create(organization_id)
        assert rep["status"] == "ok"
        bootstrap_token = rep["bootstrap_token"]

        organization_bootstrap_addr = BackendOrganizationBootstrapAddr.build(
            backend_address, organization_id, bootstrap_token
        )

    # Bootstrap organization and Alice user

    async with apiv1_backend_anonymous_cmds_factory(organization_bootstrap_addr) as anonymous_cmds:
        alice_device = await bootstrap_organization(
            cmds=anonymous_cmds,
            human_handle=HumanHandle(label="Alice", email="*****@*****.**"),
            device_label="laptop",
        )
        save_device_with_password(config_dir, alice_device, password, force=force)

    # Create a workspace for Alice

    config = load_config(config_dir, debug="DEBUG" in os.environ)
    async with logged_core_factory(config, alice_device) as core:
        alice_ws_id = await core.user_fs.workspace_create("alice_workspace")
        await core.user_fs.sync()

    # Register a new device for Alice

    other_alice_device = None
    async with backend_authenticated_cmds_factory(
        addr=alice_device.organization_addr,
        device_id=alice_device.device_id,
        signing_key=alice_device.signing_key,
    ) as alice_cmds:
        rep = await alice_cmds.invite_new(type=InvitationType.DEVICE)
        assert rep["status"] == "ok"
        invitation_addr = BackendInvitationAddr.build(
            backend_addr=alice_device.organization_addr,
            organization_id=alice_device.organization_id,
            invitation_type=InvitationType.DEVICE,
            token=rep["token"],
        )

        async with backend_invited_cmds_factory(addr=invitation_addr) as invited_cmds:

            async def invite_task():
                initial_ctx = DeviceGreetInitialCtx(cmds=alice_cmds, token=invitation_addr.token)
                in_progress_ctx = await initial_ctx.do_wait_peer()
                in_progress_ctx = await in_progress_ctx.do_wait_peer_trust()
                in_progress_ctx = await in_progress_ctx.do_signify_trust()
                in_progress_ctx = await in_progress_ctx.do_get_claim_requests()
                await in_progress_ctx.do_create_new_device(
                    author=alice_device, device_label=in_progress_ctx.requested_device_label
                )

            async def claim_task():
                nonlocal other_alice_device
                initial_ctx = await claimer_retrieve_info(cmds=invited_cmds)
                in_progress_ctx = await initial_ctx.do_wait_peer()
                in_progress_ctx = await in_progress_ctx.do_signify_trust()
                in_progress_ctx = await in_progress_ctx.do_wait_peer_trust()
                other_alice_device = await in_progress_ctx.do_claim_device(
                    requested_device_label="pc"
                )

            async with trio.open_service_nursery() as nursery:
                nursery.start_soon(invite_task)
                nursery.start_soon(claim_task)

            save_device_with_password(config_dir, other_alice_device, password, force=force)

        # Invite Bob in

        bob_device = None
        rep = await alice_cmds.invite_new(type=InvitationType.USER, claimer_email="*****@*****.**")
        assert rep["status"] == "ok"
        invitation_addr = BackendInvitationAddr.build(
            backend_addr=alice_device.organization_addr,
            organization_id=alice_device.organization_id,
            invitation_type=InvitationType.USER,
            token=rep["token"],
        )

        async with backend_invited_cmds_factory(addr=invitation_addr) as invited_cmds:

            async def invite_task():
                initial_ctx = UserGreetInitialCtx(cmds=alice_cmds, token=invitation_addr.token)
                in_progress_ctx = await initial_ctx.do_wait_peer()
                in_progress_ctx = await in_progress_ctx.do_wait_peer_trust()
                in_progress_ctx = await in_progress_ctx.do_signify_trust()
                in_progress_ctx = await in_progress_ctx.do_get_claim_requests()
                await in_progress_ctx.do_create_new_user(
                    author=alice_device,
                    human_handle=in_progress_ctx.requested_human_handle,
                    device_label=in_progress_ctx.requested_device_label,
                    profile=UserProfile.STANDARD,
                )

            async def claim_task():
                nonlocal bob_device
                initial_ctx = await claimer_retrieve_info(cmds=invited_cmds)
                in_progress_ctx = await initial_ctx.do_wait_peer()
                in_progress_ctx = await in_progress_ctx.do_signify_trust()
                in_progress_ctx = await in_progress_ctx.do_wait_peer_trust()
                bob_device = await in_progress_ctx.do_claim_user(
                    requested_human_handle=HumanHandle(label="Bob", email="*****@*****.**"),
                    requested_device_label="laptop",
                )

            async with trio.open_service_nursery() as nursery:
                nursery.start_soon(invite_task)
                nursery.start_soon(claim_task)

            save_device_with_password(config_dir, bob_device, password, force=force)

    # Create bob workspace and share with Alice

    async with logged_core_factory(config, bob_device) as core:
        bob_ws_id = await core.user_fs.workspace_create("bob_workspace")
        await core.user_fs.workspace_share(bob_ws_id, alice_device.user_id, WorkspaceRole.MANAGER)

    # Share Alice workspace with bob

    async with logged_core_factory(config, alice_device) as core:
        await core.user_fs.workspace_share(alice_ws_id, bob_device.user_id, WorkspaceRole.MANAGER)

    # Synchronize every device
    for device in (alice_device, other_alice_device, bob_device):
        async with logged_core_factory(config, device) as core:
            await core.user_fs.process_last_messages()
            await core.user_fs.sync()

    return (alice_device, other_alice_device, bob_device)
Ejemplo n.º 21
0
async def test_invited_cmds_has_right_methods(running_backend, coolorg):
    async with backend_invited_cmds_factory(coolorg.addr) as cmds:
        for method_name in INVITED_CMDS:
            assert hasattr(cmds, method_name)
        for method_name in ALL_CMDS - INVITED_CMDS:
            assert not hasattr(cmds, method_name)
Ejemplo n.º 22
0
async def test_claimer_handle_cancel_event(backend, running_backend, alice,
                                           alice_backend_cmds, fail_on_step):
    invitation = await backend.invite.new_for_device(
        organization_id=alice.organization_id, greeter_user_id=alice.user_id)
    invitation_addr = BackendInvitationAddr.build(
        backend_addr=alice.organization_addr.get_backend_addr(),
        organization_id=alice.organization_id,
        invitation_type=InvitationType.DEVICE,
        token=invitation.token,
    )

    async def _cancel_invitation():
        await backend.invite.delete(
            organization_id=alice.organization_id,
            greeter=alice.user_id,
            token=invitation_addr.token,
            on=pendulum_now(),
            reason=InvitationDeletedReason.CANCELLED,
        )

    async with backend_invited_cmds_factory(
            addr=invitation_addr) as claimer_cmds:
        greeter_initial_ctx = UserGreetInitialCtx(cmds=alice_backend_cmds,
                                                  token=invitation_addr.token)
        claimer_initial_ctx = await claimer_retrieve_info(claimer_cmds)

        claimer_in_progress_ctx = None
        greeter_in_progress_ctx = None

        async def _do_claimer():
            nonlocal claimer_in_progress_ctx
            if fail_on_step == "wait_peer":
                return
            claimer_in_progress_ctx = await claimer_initial_ctx.do_wait_peer()
            if fail_on_step == "signify_trust":
                return
            claimer_in_progress_ctx = await claimer_in_progress_ctx.do_signify_trust(
            )
            if fail_on_step == "wait_peer_trust":
                return
            claimer_in_progress_ctx = await claimer_in_progress_ctx.do_wait_peer_trust(
            )

        async def _do_greeter():
            nonlocal greeter_in_progress_ctx
            if fail_on_step == "wait_peer":
                return
            greeter_in_progress_ctx = await greeter_initial_ctx.do_wait_peer()
            if fail_on_step == "signify_trust":
                return
            greeter_in_progress_ctx = await greeter_in_progress_ctx.do_wait_peer_trust(
            )
            if fail_on_step == "wait_peer_trust":
                return
            greeter_in_progress_ctx = await greeter_in_progress_ctx.do_signify_trust(
            )

        async with real_clock_timeout():
            async with trio.open_nursery() as nursery:

                nursery.start_soon(_do_claimer)
                nursery.start_soon(_do_greeter)

        async with real_clock_timeout():

            async with trio.open_nursery() as nursery:

                async def _do_claimer_wait_peer():
                    with pytest.raises(
                            BackendInvitationAlreadyUsed) as exc_info:
                        await claimer_initial_ctx.do_wait_peer()
                    assert str(
                        exc_info.value
                    ) == "Invalid handshake: Invitation already deleted"

                async def _do_claimer_signify_trust():
                    with pytest.raises(
                            BackendInvitationAlreadyUsed) as exc_info:
                        await claimer_in_progress_ctx.do_signify_trust()
                    assert str(
                        exc_info.value
                    ) == "Invalid handshake: Invitation already deleted"

                async def _do_claimer_wait_peer_trust():
                    with pytest.raises(
                            BackendInvitationAlreadyUsed) as exc_info:
                        await claimer_in_progress_ctx.do_wait_peer_trust()
                    assert str(
                        exc_info.value
                    ) == "Invalid handshake: Invitation already deleted"

                async def _do_claimer_claim_device():
                    with pytest.raises(
                            BackendInvitationAlreadyUsed) as exc_info:
                        await claimer_in_progress_ctx.do_claim_device(
                            requested_device_label=DeviceLabel(
                                "TheSecretDevice"))
                    assert str(
                        exc_info.value
                    ) == "Invalid handshake: Invitation already deleted"

                steps = {
                    "wait_peer": _do_claimer_wait_peer,
                    "signify_trust": _do_claimer_signify_trust,
                    "wait_peer_trust": _do_claimer_wait_peer_trust,
                    "claim_device": _do_claimer_claim_device,
                }
                _do_claimer = steps[fail_on_step]

                with backend.event_bus.listen() as spy:
                    nursery.start_soon(_do_claimer)
                    # Be sure that _do_claimer got valid invitations before cancelation
                    await spy.wait_with_timeout(
                        BackendEvent.INVITE_CONDUIT_UPDATED)
                    await _cancel_invitation()
                    await spy.wait_with_timeout(
                        BackendEvent.INVITE_STATUS_CHANGED)
Ejemplo n.º 23
0
async def test_claimer_handle_command_failure(backend, running_backend, alice,
                                              alice_backend_cmds, monkeypatch,
                                              fail_on_step):
    invitation = await backend.invite.new_for_device(
        organization_id=alice.organization_id, greeter_user_id=alice.user_id)
    invitation_addr = BackendInvitationAddr.build(
        backend_addr=alice.organization_addr.get_backend_addr(),
        organization_id=alice.organization_id,
        invitation_type=InvitationType.DEVICE,
        token=invitation.token,
    )

    async def _cancel_invitation():
        await backend.invite.delete(
            organization_id=alice.organization_id,
            greeter=alice.user_id,
            token=invitation_addr.token,
            on=pendulum_now(),
            reason=InvitationDeletedReason.CANCELLED,
        )

    async with backend_invited_cmds_factory(
            addr=invitation_addr) as claimer_cmds:
        greeter_initial_ctx = UserGreetInitialCtx(cmds=alice_backend_cmds,
                                                  token=invitation_addr.token)
        claimer_initial_ctx = await claimer_retrieve_info(claimer_cmds)

        claimer_in_progress_ctx = None
        greeter_in_progress_ctx = None

        async def _do_claimer():
            nonlocal claimer_in_progress_ctx
            if fail_on_step == "wait_peer":
                return
            claimer_in_progress_ctx = await claimer_initial_ctx.do_wait_peer()
            if fail_on_step == "signify_trust":
                return
            claimer_in_progress_ctx = await claimer_in_progress_ctx.do_signify_trust(
            )
            if fail_on_step == "wait_peer_trust":
                return
            claimer_in_progress_ctx = await claimer_in_progress_ctx.do_wait_peer_trust(
            )

        async def _do_greeter():
            nonlocal greeter_in_progress_ctx
            if fail_on_step == "wait_peer":
                return
            greeter_in_progress_ctx = await greeter_initial_ctx.do_wait_peer()
            if fail_on_step == "signify_trust":
                return
            greeter_in_progress_ctx = await greeter_in_progress_ctx.do_wait_peer_trust(
            )
            if fail_on_step == "wait_peer_trust":
                return
            greeter_in_progress_ctx = await greeter_in_progress_ctx.do_signify_trust(
            )

        async with real_clock_timeout():

            async with trio.open_nursery() as nursery:
                nursery.start_soon(_do_claimer)
                nursery.start_soon(_do_greeter)

        deleted_event = trio.Event()

        async def _send_event(*args, **kwargs):
            if BackendEvent.INVITE_STATUS_CHANGED in args and (
                    kwargs.get("status") == InvitationStatus.DELETED):
                deleted_event.set()
            await trio.sleep(0)

        backend.invite._send_event = _send_event
        monkeypatch.setattr("parsec.backend.postgresql.invite.send_signal",
                            _send_event)

        async with real_clock_timeout():
            await _cancel_invitation()
            await deleted_event.wait()
            with pytest.raises(BackendInvitationAlreadyUsed) as exc_info:
                if fail_on_step == "wait_peer":
                    await claimer_initial_ctx.do_wait_peer()
                elif fail_on_step == "signify_trust":
                    await claimer_in_progress_ctx.do_signify_trust()
                elif fail_on_step == "wait_peer_trust":
                    await claimer_in_progress_ctx.do_wait_peer_trust()
                elif fail_on_step == "claim_device":
                    await claimer_in_progress_ctx.do_claim_device(
                        requested_device_label=DeviceLabel("TheSecretDevice"))
                else:
                    raise AssertionError(f"Unknown step {fail_on_step}")
            assert str(exc_info.value
                       ) == "Invalid handshake: Invitation already deleted"