Example #1
0
    async def _api_device_claim(self, client_ctx, msg):
        replied_ok = False

        # Must start listening events before calling `claim_device_invitation`
        # given this function will send the `device.claimed` event the creator
        # is waiting for.

        send_channel, recv_channel = trio.open_memory_channel(1000)

        def _on_organization_events(event,
                                    organization_id,
                                    device_id,
                                    device_certificate=None,
                                    encrypted_answer=None):
            if organization_id == client_ctx.organization_id:
                send_channel.send_nowait(
                    (event, device_id, device_certificate, encrypted_answer))

        with self._event_bus.connect_in_context(
            (BackendEvent.DEVICE_CREATED, _on_organization_events),
            (BackendEvent.DEVICE_INVITATION_CANCELLED,
             _on_organization_events),
        ):
            try:
                invitation = await self.claim_device_invitation(
                    client_ctx.organization_id, msg["invited_device_id"],
                    msg["encrypted_claim"])
                if not invitation.is_valid():
                    return {"status": "not_found"}

            except UserAlreadyExistsError:
                return {"status": "not_found"}

            except UserNotFoundError:
                return {"status": "not_found"}

            # Wait for creator device to accept (or refuse) our claim
            async for event, device_id, device_certificate, encrypted_answer in recv_channel:
                if device_id == invitation.device_id:
                    replied_ok = event == BackendEvent.DEVICE_CREATED
                    break

        if not replied_ok:
            return {
                "status": "denied",
                "reason": ("Invitation creator rejected us.")
            }

        else:
            return apiv1_device_claim_serializer.rep_dump({
                "status":
                "ok",
                "device_certificate":
                device_certificate,
                "encrypted_answer":
                encrypted_answer,
            })
Example #2
0
    async def api_device_claim(self, client_ctx, msg):
        msg = apiv1_device_claim_serializer.req_load(msg)

        # Setting the cancel scope here instead of just were we are waiting
        # for the event make testing easier.
        with trio.move_on_after(PEER_EVENT_MAX_WAIT) as cancel_scope:
            rep = await self._api_device_claim(client_ctx, msg)

        if cancel_scope.cancelled_caught:
            rep = {
                "status": "timeout",
                "reason": "Timeout while waiting for invitation creator to answer.",
            }

        return apiv1_device_claim_serializer.rep_dump(rep)