def send_response(self, msg_item: BaseRequest, timeout_seconds: float): log(f'response: {msg_item.response}') try: msg_item.socket.settimeout(timeout_seconds) msg_item.socket.send(msg_item.response.encode()) except ConnectionResetError as e: log_error(e, 'connection reset')
def check_if_friend_request_exists(self, sender_username: str, recipient_username: str) -> bool: """ Checks if the a friend request from a particular user to another exists. :param sender_username: The username of the user that sent the friend request. :param recipient_username: The username of the user receiving the friend request. :return: True if the request exists, else False. :raises UserNotFoundException If either user cannot be found in the database. """ user_id = self.db_fetch( self.query_builder.get_user_id(sender_username)) friends_id = self.db_fetch( self.query_builder.get_user_id(recipient_username)) if (user_id is False): raise UserNotFoundException(sender_username) if (friends_id is False): raise UserNotFoundException(recipient_username) user_id = user_id[0][0] friends_id = friends_id[0][0] result = self.db_fetch( self.query_builder.check_if_friend_request_exists( user_id, friends_id)) log(f'type of result from check_if_friend_request_exists: {type(result)}' ) int_result = result[0][0] return bool(int_result)
def signin(self, req_item: SigninRequest): username = req_item.username password = req_item.password data = self.get_account_info(req_item.parsed_data) if (self.validate_password(username, password)): if (self.token_up_to_date(username)): # Bundle the token into the response package signon_token = self.db.get_token(username) signon_token = signon_token[0][0] log(f'type of token from signin: {type(signon_token)}') if (signon_token is None): signon_token = self.token.get_token() self.db.signin(username, signon_token, self.token.get_token_creation_time()) req_item.set_response(token=signon_token, data=data) else: signon_token = self.token.get_token() self.db.signin(username, signon_token, self.token.get_token_creation_time()) req_item.set_response(token=signon_token, data=data) else: log(f"signin failed for user {username}") req_item.set_response(failure_reason='invalid password')
def create_request_processors(self): processes = [] for i in range(self.manifest.number_of_request_processors): log(f"creating request processor {str(i)}", level=INFO) # print('Creating processes %d' % i) processes.append(Process(target=self._create_request_processor)) for i in processes: i.start()
def create_socket(self): log('creating server socket listener', level=INFO) try: self.server_socket.bind((self.server_ip, self.port_number)) self.server_socket.listen(5) except OSError as error: log_error(error) log(f"server socket: {str(self.server_socket)}")
def token_up_to_date(self, username): token_expiration = self.db.get_token_creation_time(username) # if(token_expiration): # return False current_time = time.time() time_difference = current_time - token_expiration[0][0] if (time_difference > 86400): log(f"token expired for user {username}") return False log(f"token is valid for user {username}") return True
def set_ip(self): ip = None s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: # doesn't even have to be reachable s.connect(('10.255.255.255', 1)) ip = s.getsockname()[0] except socket.error: ip = '127.0.0.1' finally: s.close() self.server_ip = ip # self.server_ip = '18.191.38.171' log(f"server ip set to: {self.server_ip}", level=INFO)
def listen(self): connection_socket = None while True: self.req_count += 1 try: connection_socket, address = self.server_socket.accept() log(f"received message from {str(address)}") thread = Thread(target=self.process_request, args=(connection_socket, )) thread.start() except IOError as error: log_error(error) if connection_socket: connection_socket.close()
def process_request(self, connection_socket): full_msg = '' received_msg = '' buffer_exceeded = False while True: if buffer_exceeded: try: connection_socket.settimeout(3) received_msg = connection_socket.recv( self.buffer_size).decode('utf-8', 'replace') except socket.timeout: # Expecting a timeout break else: try: received_msg = connection_socket.recv( self.buffer_size).decode('utf-8', 'replace') except UnicodeDecodeError: self.send_bad_request(connection_socket) full_msg += received_msg if (len(received_msg) == 0): break elif len(received_msg) < self.buffer_size: break elif len(received_msg) == self.buffer_size: received_msg = '' buffer_exceeded = True try: if not (full_msg[0] == "{"): full_msg = full_msg[2::] except IndexError as error: log_error(error) return try: parsed_data = json.loads(full_msg) except (json.decoder.JSONDecodeError): log_error(f"unable to load message into json: {full_msg}") self.send_bad_request(connection_socket) return request = build_request(connection_socket, parsed_data) log(f"message item: {parsed_data}") self.request_queue.put(request)
def set_response(self, *, token: Optional[object] = None, data: Optional[list] = None, failure_reason: Optional[str] = None) -> None: """Sets the response for a signin request. Args: token: TODO describe the token. data: TODO What is expected? What is the structure required? failure_reason: A string representation of the reason for the failure. Returns: None """ user_dict = {} if not failure_reason: if token: if data and len(data) > 0 and len(data[0]) > 7: # noinspection SpellCheckingInspection user_dict = { 'token': token, 'avatar_style': data[0][0], 'chessboard_style': data[0][1], 'chesspiece_style': data[0][2], 'match_clock_choice': data[0][3], 'automatic_queening': data[0][4], 'disable_pausing': data[0][5], 'require_commit_press': data[0][6], 'level': data[0][7] } elif data: log(f'set_response was provided invalid data: {data}') failure_reason = 'Unexpected Error - Invalid user data received from database.' else: failure_reason = 'Unexpected Error - No user data received from database.' else: failure_reason = 'Unexpected Error - No token provided by server.' super().set_response(failure_reason=failure_reason, **user_dict)
def send_bad_request(self, connection_socket: socket): connection_socket.settimeout(self.timeout_seconds) log(f"bad request", level=VERBOSE) msg = "ERROR - BAD REQUEST" connection_socket.send(msg.encode('utf-8')) connection_socket.close()
def create_listener(self): log('creating request listener', level=INFO) self.listener.create_listener() thread = Thread(target=self.listener.listen) thread.start() thread.join()
# print('Creating processes %d' % i) processes.append(Process(target=self._create_request_processor)) for i in processes: i.start() def create_listener(self): log('creating request listener', level=INFO) self.listener.create_listener() thread = Thread(target=self.listener.listen) thread.start() thread.join() if __name__ == '__main__': args = sys.argv[1:] log(level=INFO) log('starting logon server', level=INFO) log(level=INFO) if args: # get database configuration info from arguments and password from input. from getpass import getpass db_implementation, host, username, db_name, *_ = args password = getpass(prompt='Enter database password: '******'./params.json', 'r') as f: data = json.loads(f.read()) db_implementation = 'mysql'