def auth(self, response: Message): """Метод, отвечающий за авторизацию на сервере""" if response.action == REGISTER or response.action == AUTH: try: if response.action == REGISTER: data = { ACTION: REGISTER, FROM: self.user_name, TEXT: self.password } self.send(Message(**data)) response = receive(self.__sock, self.__logger)[0] # Получаем публичный ключ и декодируем его из байтов pubkey = self.keys.publickey().export_key().decode( 'ascii') if self.keys else None # Запускаем процедуру авторизации # Получаем хэш пароля passwd_bytes = self.password.encode('utf-8') salt = self.user_name.lower().encode('utf-8') passwd_hash = hashlib.pbkdf2_hmac('sha512', passwd_bytes, salt, 10000) passwd_hash_string = binascii.hexlify(passwd_hash) # Если сервер вернул ошибку, бросаем исключение. if response.response: if response.response == FORBIDDEN: raise ServerError(response.text) elif response.response == OK: # Если всё нормально, # то продолжаем процедуру авторизации. ans_data = response.text hash_str = hmac.new(passwd_hash_string, ans_data.encode('utf-8')) digest = hash_str.digest() request_data = { ACTION: AUTH, FROM: self.user_name, TEXT: binascii.b2a_base64(digest).decode('ascii'), USER: pubkey } self.send(Message(**request_data)) responses = receive(self.__sock, self.__logger) if responses and responses[0].response == OK: info_msg = f'Клиент запущен ({self.user_name}).' print(info_msg) self.__logger.info(info_msg) return True else: return False except OSError: raise ServerError('Сбой соединения в процессе авторизации.')
def load_contacts(self): """Метод загрузки списка контактов""" data = {ACTION: GET_CONTACTS, FROM: self.user_name} request = Message(data) self.send(request) time.sleep(1) messages = receive(self.__sock, self.__logger) return messages or False
def __check_presence(self): """Метод проверки соединения""" data = {ACTION: PRESENCE, FROM: self.__user_name} request = Message(data) self.send(request) messages = receive(self.__sock, self.__logger) return messages[0] if messages and messages[0].response == OK \ else False
def receive(self): """ Метод, принимающий сообщения от клиента :return: """ requests = receive(self.sock, self.__logger) if not requests: raise Exception self.__in.extend(requests)
def receiver(self, flag=1): try: while True: messages = [] try: messages = receive(self.__client.sock, self.__client.logger) except socket.timeout: pass while len(messages): message = messages.pop() checked_msg = self.__client.check_response(message) self.receive_callback(checked_msg) if flag != 1: break except KeyboardInterrupt: pass
def key_request(self, user_name): """ Метод, составляющий запрос на получение открытого ключа контакта. :param user_name: Имя контакта :return: """ data = { ACTION: PUBLIC_KEY_REQUEST, FROM: self.user_name, USER: user_name } with socket_lock: self.__client.send(Message(**data)) responses = receive(self.__client.sock, self.__client.logger) if responses: response = responses[0] if response.response and response.text: return response.text self.__client.logger.error( f'Не удалось получить ключ собеседника{user_name}.')
def key_request(self, user_name: str) -> str: """ Метод получающий открытый ключ контакта с сервера. :param user_name: Имя контакта :return: """ data = { ACTION: PUBLIC_KEY_REQUEST, FROM: self.__client.user_name, USER: user_name } with socket_lock: self.__client.send(Message(**data)) responses = receive(self.__client.sock, self.__client.logger) if responses: response = responses[0] if response.response and response.text: return response.text self.__client.logger.error( f'Не удалось получить ключ собеседника{user_name}.')
def run(self): """ Метод запускающий получение и обработку сообщений. Работает в отдельном потоке. :return: """ try: self.user_list_update() while True: messages = [] try: messages = receive(self.__client.sock, self.__client.logger) except socket.timeout: pass while len(messages): message = messages.pop() checked_msg = self.__client.check_response(message) self.receive_callback(checked_msg) except (ConnectionError, ConnectionAbortedError, ConnectionResetError): self.__listen_thread.is_alive = False self.connection_lost.emit()
def receiver(self, flag=1): """ Метод запускающий получение и обработку сообщений. Работает в отдельном потоке. :param flag: Если передана не 1, то выполнит только 1 цикл. :return: """ try: while True: messages = [] try: messages = receive(self.__client.sock, self.__client.logger) except socket.timeout: pass while len(messages): message = messages.pop() checked_msg = self.__client.check_response(message) self.receive_callback(checked_msg) if flag != 1: break except ConnectionResetError: self.__listen_thread.is_alive = False
def receive(self): requests = receive(self.sock, self.__logger) if not requests: raise Exception self.__in.extend(requests)
def __check_presence(self): data = {ACTION: PRESENCE, FROM: self.__user_name} request = Message(data) self.send(request) messages = receive(self.__sock, self.__logger) return messages[0].response == OK if messages else False