コード例 #1
0
    def _show_message_cleartext(self, message_id: str, ciphertext: str, address_id: str) -> None:
        key_id, private_key = self._db.get_own_address_nacl_key(address_id)
        cleartext = self._crypto_provider.decrypt(ciphertext, private_key)

        # Cleartext is supposed to be a MIME formatted message
        msg = BytesParser(policy=policy.default).parsebytes(cleartext)

        ## DEBUG
        self._logger.debug("Message id: {0} - Content: {1}".format(message_id, msg.as_string()))

        content = []
        address_pad = None
        address_pad_req = None

        for part in msg.walk():
            # Account for stuff we know will turn up - Specifically wrappers and protocol
            # control messages
            if part.get_content_type() == 'application/json':
                if part['Content-Description'] == NodeIntercom.address_pad_request_description:
                    address_pad_req = NodeIntercom.AddressPadRequest.deserialize(part.get_content())
                if part['Content-Description'] == NodeIntercom.address_pad_description:
                    address_pad = NodeIntercom.AddressPad.deserialize(part.get_content())
            elif part.get_content_maintype() == 'multipart' or \
              part.get_content_maintype() == 'application':
                continue
            else:
                content.append(part.get_content())

        msg_string = "From: {0}\nTo: {1}\n\n{2}".format(msg['from'], msg['to'], "\n".join(content))

        def _delete_message(message_id):
            self._logger.debug("Attempting to clean out message: {0}".format(message_id))
            self._db.clean_out_received_message(message_id)
            self.received_messages()  # Reload the messages menu
            return True

        def _no_action():
            return True

        # If the mail contained a address pad request or a message pad, show the alternatives
        if address_pad:
            import_prompt = "This message includes a block of addresses to {0}. " \
            "Import these?".format(address_pad.from_alias)
            should_import = self._show_confirmation_dialog(import_prompt)
            self._redraw()

            if should_import:
                self._import_address_pad(address_pad, msg['to'])

        if address_pad_req:
            request_prompt = "This message includes a request by {0} to send {1} additional " \
              "addresses. Enqueue addresses to {0}?".format(msg['from'], address_pad_req.pad_size)
            should_respond = self._show_confirmation_dialog(request_prompt)
            self._redraw()

            if should_respond:
                # Takes the "from" field and finds a contact from it, which is not ideal -
                # A "real" version of this would offer some kind of contact selection interaction
                # instead of trusting the from-header.
                destination = self._db.read_contact_from_nickname(msg['from'])
                # If the destination is not a known nickname, we'll just drop it - Again not ideal.
                if not destination:
                    return
                address_data = self._db.get_address_pad_nacl(destination.contact_id)[0]
                return_msg = self._generate_own_address_pad_mime_message(destination, 10)
                self._enqueue_generic_message(address_data, return_msg)


        # With the system messages done and dusted, let's show the defaul choices
        menu_items = []
        menu_items.append(_MenuItem("q", "Return", lambda: _no_action))
        menu_items.append(_MenuItem("d", "Delete", lambda: _delete_message(message_id)))
        action_menu = _Menu("Choice", menu_items)

        self._show_selection_dialog(action_menu, vertical=False, text=msg_string)