def test_handle_response_raises_for_no_content_in_response(): responses.add(responses.GET, 'http://127.0.0.1:4003/spongebob', status=404) connection = Connection('http://127.0.0.1:4003') response = requests.get('http://127.0.0.1:4003/spongebob') with pytest.raises(ArkHTTPException) as exception: connection._handle_response(response) assert str(exception.value) == 'No content in response' assert exception.value.response == response
def listen_for_messages(): """ Function responsible for receiving messages """ listening_socket = Connection.start_client_connection( hostname=Client.get_hostname(), port=Client.get_port()) Connection.accept_connections(listening_socket, Client, Functionalities.receive_messages) listening_socket.close()
def test_handle_response_retuns_body_from_request(): responses.add(responses.GET, 'http://127.0.0.1:4003/spongebob', json={'success': True}, status=200) connection = Connection('http://127.0.0.1:4003') response = requests.get('http://127.0.0.1:4003/spongebob') body = connection._handle_response(response) assert body == {'success': True}
def shutdown(server): """ Method to shutdown the client app :param server: Server socket whose connection will be closed """ Connection.RUNNING = False Connection.close(server) quit(0)
def test_connection_raises_for_request_retry_failure(): responses.add(responses.GET, 'http://127.0.0.1:4003/spongebob', body=requests.exceptions.RequestException()) connection = Connection('http://127.0.0.1:4003') with pytest.raises(ArkHTTPException) as exception: connection.get('spongebob') assert len(responses.calls) == 3
def test_handle_response_raises_for_success_false_in_response(): responses.add( responses.GET, 'http://127.0.0.1:4003/spongebob', json={'success': False, 'error': 'Best error ever'}, status=404 ) connection = Connection('http://127.0.0.1:4003') response = requests.get('http://127.0.0.1:4003/spongebob') with pytest.raises(PhantomHTTPException) as exception: connection._handle_response(response) assert str(exception.value) == 'GET 404 http://127.0.0.1:4003/spongebob - Best error ever' assert exception.value.response == response
def loginButtonClicked(self): loginBoxValue = self.loginTextBox.text() passwordBoxValue = self.passwordTextBox.text() if (not loginBoxValue) or (not passwordBoxValue): FunnyClassForErrorMsg().showMsg(self, "Type Login and Password") else: self.username = self.loginTextBox.text() self.passwd = self.passwordTextBox.text() s = Connection().getSocket() req = request.AuthRequest(user=self.username, passwd=self.passwd) transfer.send(s, req) resp = response.AuthResponse.fromJSON(transfer.recieve(s)) if resp.type == MessageType.ERR: FunnyClassForErrorMsg().showMsg(self, resp.description) else: if self.operatingWindow is None: self.operatingWindow = OperatingWindow(self.username) self.operatingWindow.set_connection(s) self.operatingWindow.refreshFileList() self.operatingWindow.show() self.hide() else: self.operatingWindow.close() self.operatingWindow = None
def list_users(client, server): """ Method that accepts list requests :param client: Client instance, whose properties can be fetched :param server: Server connection """ signed_username = base64.b64encode( Cryptography.sign(Connection.get_key(), client.get_username())).decode() server.send(f'LIST:{client.get_username()}:{signed_username}'.encode()) response = server.recv(100000000) if response[0] != 0x80: if response.decode() == 'UNAUTHORIZED': print("You don't have permissions to perform this operation!") return None user_list = pickle.loads(response) if len(user_list) > 0: print('Online users are:') for user in user_list: print('> ' + user['username']) client.add_user(user['username'], user['hostname'], user['port'], user['cert']) else: print('No users online!')
def perform_root(client, server, number, n): """ Method to ask the server to calculate a root of a number :param client: Client instance, whose properties can be fetched :param server: Server connection that will be used to ask for the operation :param number: Server number on which the root will be calculated :param n: N of the root that needs to be computed :return: Result of the number's N root """ signed_username = base64.b64encode( Cryptography.sign(Connection.get_key(), client.get_username())).decode() server.send( f'OP:{client.get_username()}:{signed_username}:{n}:{number}'. encode()) response = server.recv(100000).decode() if response == 'UNAUTHORIZED': print("You don't have permissions to perform this operation!") return None if response == 'INVALID': print("The values you inserted are not valid!") return None return float(response)
def register_client(client, server): """ Method to login a user in the server :param client: Client instance, whose properties can be fetched :param server: Server connection """ username = input('Please insert the username:\n> ') one_time_id = input('Please insert the One Time ID:\n> ') signed_one_time_id = base64.b64encode( Cryptography.sign(Connection.get_key(), one_time_id)).decode() server.send( f'LOGIN:{username}:{one_time_id}:{signed_one_time_id}:{client.get_hostname()}' f':{str(client.get_port())}:{Connection.get_cert()}'.encode()) response = server.recv(100000).decode() if response == 'OK': pin = input('Please insert your PIN:\n> ') client.save_pin(username, pin) client.set_username(username) print('Login successful and PIN set') return True else: print('Login was not successful, failed on the server') return False
def __init__(self, hostname): """ :param string hostname: Node hostname. Examples: `http://127.0.0.1:4002` or `http://my.domain.io/api/`. This is to allow people to server the api on whatever url they want. """ self.connection = Connection(hostname) self._import_api()
def test_request_get_calls_connection_get_with_correct_params(mocker): get_mock = mocker.patch.object(Connection, 'get') connection = Connection('http://127.0.0.1:4003') resource = Resource(connection) resource.request_get('spongebob', params={'foo': 'bar'}) get_mock.assert_called_once_with('spongebob', params={'foo': 'bar'})
def test_request_delete_calls_connection_delete_with_correct_params(mocker): delete_mock = mocker.patch.object(Connection, 'delete') connection = Connection('http://127.0.0.1:4003', '2') resource = Resource(connection) resource.request_delete('spongebob', params={'foo': 'bar'}) delete_mock.assert_called_once_with('spongebob', params={'foo': 'bar'})
def test_connection_request_retry_successful(): responses.add(responses.GET, 'http://127.0.0.1:4003/spongebob', body=requests.exceptions.RequestException()) responses.add(responses.GET, 'http://127.0.0.1:4003/spongebob', body=requests.exceptions.RequestException()) responses.add(responses.GET, 'http://127.0.0.1:4003/spongebob', json={'success': True}, status=200) connection = Connection('http://127.0.0.1:4003') data = connection.get('spongebob') assert data == {'success': True} assert len(responses.calls) == 3 assert responses.calls[0].request.url == 'http://127.0.0.1:4003/spongebob'
def start_client(): """ Function responsible for running the connections and client bootstrap """ # Creates a connection with the server server_connection = Connection.start_server_connection() # Listens to the port waiting for clients, for each client, setups a new thread for interaction Functionalities.server_functionalities(Client, server_connection)
def test_request_post_calls_connection_post_with_correct_params(mocker): post_mock = mocker.patch.object(Connection, 'post') connection = Connection('http://127.0.0.1:4003') resource = Resource(connection) resource.request_post('spongebob', data={'one': 'two'}, params={'foo': 'bar'}) post_mock.assert_called_once_with('spongebob', data={'one': 'two'}, params={'foo': 'bar'})
def test_http_methods_call_correct_url_and_return_correct_response( method, func_name): responses.add(method, 'http://127.0.0.1:4003/spongebob', json={'success': True}, status=200) connection = Connection('http://127.0.0.1:4003') data = getattr(connection, func_name)('spongebob') assert data == {'success': True} assert len(responses.calls) == 1 assert responses.calls[0].request.url == 'http://127.0.0.1:4003/spongebob'
def __init__(self, hostname, api_version='v2'): """ :param string hostname: Node hostname. Examples: `http://127.0.0.1:4002` or `http://my.domain.io/api/`. NOTE: For v1 of the client, hostname needs to include url to the API, meaning that because v1 API is accessible on `/api/` url, hostname needs to be `http://127.0.0.1:4002/api/`. This is to allow people to server the api on whatever url they want. :param string api_version: Version of the API you want to use. Defaults to v2. """ if api_version not in ['v1', 'v2']: raise ArkParameterException( 'Only versions "v1" and "v2" are supported') self.api_version = api_version self.connection = Connection(hostname, api_version.replace('v', '')) self._import_api()
def send_message(local_client, target_client): """ Method to send a message to a given user :param local_client: Client instance, whose properties can be fetched :param target_client: Socket to where the message will be sent """ target_connection = Connection.start_target_connection( target_client['hostname'], target_client['port']) continue_messages = True while continue_messages: message = input('\n\nWrite your message: ') data = f'{local_client.get_username()}|{datetime.now()}|{message}' target_connection.send(data.encode()) local_client.save_message(data) answer = input('\n\nDo you want to quit now? (Y/N)\n > ') if answer.lower() == 'y': continue_messages = False
def main(hostname='127.0.0.1', port=8081, database_location='/data', client_cert='/client.crt', client_key='/client.key', ca_file='/server.crt'): """ Main thread """ Client.set_hostname(hostname) Client.set_port(port) Client.set_local_file(database_location) Connection.set_ca_file(ca_file) Connection.set_cert_file(client_cert) Connection.set_key_file(client_key) logging.basicConfig(filename='logs.log', level=logging.INFO, filemode='a') _thread.start_new_thread(Client.listen_for_messages, ()) Client.start_client()
def test_connection_creation_sets_default_session_headers_and_variables(): connection = Connection('http://127.0.0.1:4003') assert connection.hostname == 'http://127.0.0.1:4003' assert isinstance(connection.session, requests.Session) assert connection.session.headers['Content-Type'] == 'application/json' assert connection.session.headers['API-Version'] == '2'
def test_connection_creation_sets_default_session_headers_and_variables(): connection = Connection('http://127.0.0.1:4003', '2') assert connection.hostname == 'http://127.0.0.1:4003' assert isinstance(connection.session, requests.Session) assert connection.session.headers['port'] == '1' assert connection.session.headers['API-Version'] == '2'
def test_connection_creation_raises_with_wrong_api_version_number( version_number): with pytest.raises(Exception) as error: Connection('http://127.0.0.1:4003', version_number) assert 'Only versions "1" and "2" are supported' in str(error.value)
def test_build_url_correctly_builds_url(): connection = Connection('http://127.0.0.1:4003', '2') url = connection._build_url('spongebob') assert url == 'http://127.0.0.1:4003/spongebob'