Beispiel #1
0
def input_loop(queues: Dict[bytes, 'Queue[bytes]'], settings: 'Settings',
               gateway: 'Gateway', contact_list: 'ContactList',
               group_list: 'GroupList', master_key: 'MasterKey',
               onion_service: 'OnionService', stdin_fd: int) -> NoReturn:
    """Get input from user and process it accordingly.

    Running this loop as a process allows handling different functions
    including inputs, key exchanges, file loading and assembly packet
    generation, separate from assembly packet output.
    """
    sys.stdin = os.fdopen(stdin_fd)
    window = TxWindow(contact_list, group_list)

    while True:
        with ignored(EOFError, FunctionReturn, KeyboardInterrupt):
            readline.set_completer(
                get_tab_completer(contact_list, group_list, settings, gateway))
            readline.parse_and_bind('tab: complete')

            window.update_window(group_list)

            while not onion_service.is_delivered:
                export_onion_service_data(contact_list, settings,
                                          onion_service, gateway)

            while not contact_list.has_local_contact():
                new_local_key(contact_list, settings, queues)

            while not contact_list.has_contacts():
                add_new_contact(contact_list, group_list, settings, queues,
                                onion_service)

            while not window.is_selected():
                window.select_tx_window(settings, queues, onion_service,
                                        gateway)

            user_input = get_input(window, settings)

            if user_input.type == MESSAGE:
                queue_message(user_input, window, settings, queues)

            elif user_input.type == FILE:
                queue_file(window, settings, queues)

            elif user_input.type == COMMAND:
                process_command(user_input, window, contact_list, group_list,
                                settings, queues, master_key, onion_service,
                                gateway)
Beispiel #2
0
 def test_standard_nick_psk_kex(self, *_: Any) -> None:
     self.onion_service.account = nick_to_onion_address('Bob').encode()
     self.assertIsNone(add_new_contact(*self.args))
     contact = self.contact_list.get_contact_by_pub_key(
         nick_to_pub_key("Alice"))
     self.assertEqual(contact.nick, 'Alice_')
     self.assertEqual(contact.tx_fingerprint, bytes(FINGERPRINT_LENGTH))
Beispiel #3
0
    def window_selection_command(self, selection: str, settings: 'Settings',
                                 queues: 'QueueDict',
                                 onion_service: 'OnionService',
                                 gateway: 'Gateway') -> None:
        """Commands for adding and removing contacts from contact selection menu.

        In situations where only pending contacts are available and
        those contacts are not online, these commands prevent the user
        from not being able to add new contacts.
        """
        if selection == '/add':
            add_new_contact(self.contact_list, self.group_list, settings,
                            queues, onion_service)
            raise FunctionReturn("New contact added.", output=False)

        elif selection == '/connect':
            export_onion_service_data(self.contact_list, settings,
                                      onion_service, gateway)

        elif selection.startswith('/rm'):
            try:
                selection = selection.split()[1]
            except IndexError:
                raise FunctionReturn("Error: No account specified.", delay=1)

            if not yes(f"Remove contact '{selection}'?", abort=False, head=1):
                raise FunctionReturn("Removal of contact aborted.",
                                     head=0,
                                     delay=1)

            if selection in self.contact_list.contact_selectors():
                onion_pub_key = self.contact_list.get_contact_by_address_or_nick(
                    selection).onion_pub_key
                self.contact_list.remove_contact_by_pub_key(onion_pub_key)
                self.contact_list.store_contacts()
                raise FunctionReturn(f"Removed contact '{selection}'.",
                                     delay=1)
            else:
                raise FunctionReturn(f"Error: Unknown contact '{selection}'.",
                                     delay=1)

        else:
            raise FunctionReturn("Error: Invalid command.", delay=1)
Beispiel #4
0
 def test_default_nick_ecdhe(self, *_: Any) -> None:
     self.assertIsNone(add_new_contact(*self.args))
     contact = self.contact_list.get_contact_by_address_or_nick("Bob")
     self.assertEqual(contact.nick, 'Bob')
     self.assertNotEqual(contact.tx_fingerprint, bytes(FINGERPRINT_LENGTH))