def test_scan_ports_with_invalid_target_host(self, invalid_target_name, docker_server_ids, metasploit_api): """ Tests scenarios where the port scanning invalid host names should return an error response body and a bad request. """ for docker_server_id in docker_server_ids: logger.info( f"Scan ports, instance: {docker_server_id}, target: {invalid_target_name}" ) response_body, actual_status_code = metasploit_api.scan_ports( instance_id=docker_server_id, target_host=invalid_target_name) logger.info( f"Verify scan ports of {invalid_target_name} on instance {docker_server_id} failed" ) assert is_error_response_valid( error_response=response_body, code=HttpCodes.BAD_REQUEST ), (f"Failed to verify that response {response_body} is an ERROR") logger.info(f"Verify the status code is {HttpCodes.BAD_REQUEST}") assert is_expected_code( actual_code=actual_status_code, expected_code=HttpCodes.BAD_REQUEST ), (f"actual {actual_status_code}, expected: {HttpCodes.BAD_REQUEST}" )
def test_update_user_succeed(self, email, password, update_user_body_request, expected_params, user_api): """ Tests scenarios where updating a user should succeed. """ user_body_response, actual_status_code = user_api.put( email=email, request_body=update_user_body_request) logger.info(f"Verify that the PUT body response is an empty string") assert user_body_response == '', f"Failed to update user with username {email} password {password}" logger.info( f"Verify that the PUT response status code is {HttpCodes.NO_CONTENT}" ) assert is_expected_code( actual_code=actual_status_code, expected_code=HttpCodes.NO_CONTENT ), (f"actual {actual_status_code}, expected {HttpCodes.NO_CONTENT}") user_body_response_post_update, status_code = user_api.get_one( email=email, password=password) assert status_code != HttpCodes.UNAUTHORIZED, f"Failed to update password {password}" for key, val in expected_params.items(): logger.info(f"Verify that update {key} to {val} was successful") assert user_body_response_post_update[key] == val, ( f"Failed to update {key} to {val}, actual: {user_body_response_post_update[key]}" )
def test_delete_non_existing_container_fails(self, docker_server_ids, container_api): """ Tests that in case there isn't a container with the requested ID, the server returns ERROR response body and 404. """ for docker_server_id in docker_server_ids: logger.info(f"delete container {config.INVALID_CONTAINER_ID} from instance {docker_server_id}") body_response, actual_status_code = container_api.delete( instance_id=docker_server_id, container_id=config.INVALID_CONTAINER_ID ) if isinstance(body_response, str): body_response = load_json(string=body_response) logger.info(f"Verify that DELETE body response {body_response} is an ERROR") assert is_error_response_valid( error_response=body_response, code=HttpCodes.NOT_FOUND, message=config.CONTAINER_NOT_FOUND_MSG.format(invalid_container_id=config.INVALID_CONTAINER_ID) ), ( f"Response body {body_response} is not as expected" ) logger.info(f"Verify that the DELETE response status code is {HttpCodes.NOT_FOUND}") assert is_expected_code(actual_code=actual_status_code, expected_code=HttpCodes.NOT_FOUND), ( f"actual {actual_status_code}, expected {HttpCodes.NOT_FOUND}" )
def test_get_all_containers_succeed(self, docker_server_ids, container_api): """ Tests that given new containers in a docker servers, GET all containers returns all of them. """ for docker_server_id in docker_server_ids: all_containers_response, actual_status_code = container_api.get_many(instance_id=docker_server_id) assert isinstance(all_containers_response, list), f"{all_containers_response} is not a list" assert len(all_containers_response) == self.num_of_containers_to_create, ( f"actual number of containers {len(all_containers_response)}, " f"expected number of containers {self.num_of_containers_to_create}" ) for single_container_response in all_containers_response: container_id = get_container_id_from_container_response( container_body_response=single_container_response ) assert container_id, f"Failed to get container ID from {single_container_response}" assert isinstance(single_container_response, dict), ( f"response {single_container_response} is not a dict!" ) logger.info(f"Verify that {single_container_response} is a valid response") assert is_container_response_valid( container_response_body=single_container_response, **get_container_expected_response(instance_id=docker_server_id, container_id=container_id) ) logger.info(f"Verify the status code is {actual_status_code}") assert is_expected_code(actual_code=actual_status_code, expected_code=HttpCodes.OK)
def test_update_user_with_unexpected_parameters(self, email, password, update_user_body_request, user_api, find_user_response): """ Tests scenarios where updating fields of a user that cannot be updated do nothing. """ body_response_before_update = find_user_response user_body_response, actual_status_code = user_api.put( email=email, request_body=update_user_body_request) logger.info(f"Verify that the PUT body response is an empty string") assert user_body_response == '', f"Failed to update user with username {email} password {password}" logger.info( f"Verify that the PUT response status code is {HttpCodes.NO_CONTENT}" ) assert is_expected_code( actual_code=actual_status_code, expected_code=HttpCodes.NO_CONTENT ), (f"actual {actual_status_code}, expected {HttpCodes.NO_CONTENT}") user_body_response_post_update, _ = user_api.get_one(email=email, password=password) assert body_response_before_update == user_body_response_post_update
def test_delete_docker_server_fails(self, docker_server_api): """ Tests that given an invalid docker server, DELETE operation fails. """ docker_server_body_response, actual_status_code = docker_server_api.delete( instance_id=config.INVALID_INSTANCE_ID) if isinstance(docker_server_body_response, str): docker_server_body_response = load_json( string=docker_server_body_response) logger.info( f"Verify that DELETE body response {docker_server_body_response} is an ERROR" ) assert is_error_response_valid( error_response=docker_server_body_response, code=HttpCodes.NOT_FOUND, message=config.INSTANCE_NOT_FOUND_MSG.format( invalid_instance_id=config.INVALID_INSTANCE_ID) ), f"Response body {docker_server_body_response} is not as expected" logger.info( f"Verify that the DELETE response status code is {HttpCodes.NOT_FOUND}" ) assert is_expected_code( actual_code=actual_status_code, expected_code=HttpCodes.NOT_FOUND), ( f"actual {actual_status_code}, expected {HttpCodes.NOT_FOUND}")
def test_get_invalid_exploit_name(self, invalid_exploit_name, docker_server_ids, metasploit_api): """ Tests scenarios where trying to get invalid exploit names should fail. """ for docker_server_id in docker_server_ids: logger.info( f"Get exploit {invalid_exploit_name} in instance {docker_server_id}" ) response_body, actual_status_code = metasploit_api.get_exploit( instance_id=docker_server_id, exploit_name=invalid_exploit_name) logger.info( f"Verify get exploit of {invalid_exploit_name} on instance {docker_server_id} failed" ) assert is_error_response_valid( error_response=response_body, code=HttpCodes.BAD_REQUEST), ( f"Failed to verify that {response_body} is an ERROR") logger.info(f"Verify the status code is {HttpCodes.BAD_REQUEST}") assert is_expected_code( actual_code=actual_status_code, expected_code=HttpCodes.BAD_REQUEST ), (f"actual {actual_status_code}, expected {HttpCodes.BAD_REQUEST}" )
def test_get_docker_servers_without_instances(self, docker_server_api): """ Tests that given an empty DB without docker servers, GET all dockers servers brings back [] """ docker_servers, actual_status_code = docker_server_api.get_many() logger.info(f"Verify that response {docker_servers} == []") assert docker_servers == [], f"Failed to verify that docker servers is empty" logger.info(f"Verify that the status code is {HttpCodes.OK}") assert is_expected_code(actual_code=actual_status_code), ( f"actual: {actual_status_code}, expected: {HttpCodes.OK}")
def test_get_all_containers_empty(self, docker_server_ids, container_api): """ Tests that given a docker server without containers, GET all containers returns [] """ for docker_server_id in docker_server_ids: response_body, actual_status_code = container_api.get_many(instance_id=docker_server_id) logger.info(f"Verify response body {response_body} == []") assert response_body == [], f"Failed to validate containers are empty" logger.info(f"Verify the status code is {HttpCodes.OK}") assert is_expected_code(actual_code=actual_status_code, expected_code=HttpCodes.OK)
def test_create_metasploit_container_fails(self, container_api): """ Tests that given an invalid docker server ID, creating a metasploit container should fail. """ body_response, actual_status_code = container_api.post(instance_id=docker_server_config.INVALID_INSTANCE_ID) logger.info(f"Verify that {body_response} is an ERROR") assert is_error_response_valid(error_response=body_response, code=HttpCodes.NOT_FOUND), ( f"Response {body_response} is not an ERROR" ) logger.info(f"Verify that status code is {HttpCodes.NOT_FOUND}") assert is_expected_code(actual_code=actual_status_code, expected_code=HttpCodes.NOT_FOUND)
def test_get_all_users_without_users(self, user_api): """ Tests that getting all users with empty DB returns empty list. """ user_response_body, actual_status_code = user_api.get_many() logger.info( f"Verify that the user body {user_response_body} response is an empty list" ) assert user_response_body == [], f"actual: {user_response_body}, expected: []" logger.info(f"Verify that status code is {HttpCodes.OK}") assert is_expected_code(actual_code=actual_status_code), ( f"actual {actual_status_code}, expected {HttpCodes.OK}")
def test_create_user_success(self, create_users): """ Tests scenarios in which the creating a user is expected to be successful. """ for new_user_body_response, actual_status_code in create_users: logger.info( f"Verify that the user body response {new_user_body_response} is valid" ) assert is_user_response_body_valid( user_response_body=new_user_body_response, data={}) logger.info(f"Verify that status code is {HttpCodes.OK}") assert is_expected_code(actual_code=actual_status_code), ( f"actual {actual_status_code}, expected {HttpCodes.OK}")
def test_get_user_succeed(self, email, password, user_api): """ Tests scenarios in which trying to get a user with a valid credentials should succeed. """ user_response_body, actual_status_code = user_api.get_one( email=email, password=password) logger.info( f"Verify that the user body response {user_response_body} is valid" ) assert is_user_response_body_valid( user_response_body=user_response_body) logger.info(f"Verify that status code is {HttpCodes.OK}") assert is_expected_code(actual_code=actual_status_code), ( f"actual {actual_status_code}, expected {HttpCodes.OK}")
def test_get_all_users_succeed(self, user_api): """ Tests that get all the users succeed. """ users_body_responses, actual_status_code = user_api.get_many() for user_body_response in users_body_responses: logger.info( f"Verify that the user body response {user_body_response} is valid" ) assert is_user_response_body_valid( user_response_body=user_body_response) logger.info(f"Verify that status code is {HttpCodes.OK}") assert is_expected_code(actual_code=actual_status_code), ( f"actual {actual_status_code}, expected {HttpCodes.OK}")
def test_delete_user_succeed(self, valid_email, user_api): """ Tests scenarios where trying to delete a valid user fails. """ user_body_response, actual_status_code = user_api.delete( email=valid_email) logger.info(f"Verify that the DELETE body response is an empty string") assert user_body_response == '', f"Failed to delete user with username {valid_email}" logger.info( f"Verify that the DELETE response status code is {HttpCodes.NO_CONTENT}" ) assert is_expected_code( actual_code=actual_status_code, expected_code=HttpCodes.NO_CONTENT ), (f"actual {actual_status_code}, expected {HttpCodes.NO_CONTENT}")
def test_docker_daemon_start(self, docker_server_ids, container_api): """ Tests that given the docker daemon is down, if the server is able to recover it and create a container. """ for docker_server_id in docker_server_ids: body_response, actual_status_code = container_api.post(instance_id=docker_server_id) logger.info(f"Verify that container body response {body_response} is valid") assert is_container_response_valid( container_response_body=body_response, **config.EXPECTED_NEW_CONTAINER_RESPONSE ) logger.info(f"Verify the status code is {HttpCodes.OK}") assert is_expected_code(actual_code=actual_status_code), ( f"actual: {actual_status_code}, expected: {HttpCodes.OK}" )
def test_create_existing_user_fails(self, user_body_request, user_api): """ Tests scenarios in which trying to creating an existing user fails. """ user_response_body, actual_status_code = user_api.post( create_user_body_request=user_body_request) logger.info( f"Verify that the user body response {user_response_body} is an ERROR" ) assert is_error_response_valid(error_response=user_response_body, code=HttpCodes.DUPLICATE) logger.info(f"Verify that status code is {HttpCodes.DUPLICATE}") assert is_expected_code( actual_code=actual_status_code, expected_code=HttpCodes.DUPLICATE), ( f"actual {actual_status_code}, expected {HttpCodes.DUPLICATE}")
def test_get_user_fails(self, email, password, user_api): """ Tests scenarios in which trying to get a user with invalid credentials should fail. """ user_response_body, actual_status_code = user_api.get_one( email=email, password=password) logger.info( f"Verify that the user body response {user_response_body} is an ERROR" ) assert is_error_response_valid(error_response=user_response_body, code=HttpCodes.UNAUTHORIZED) logger.info(f"Verify that status code is {HttpCodes.UNAUTHORIZED}") assert is_expected_code( actual_code=actual_status_code, expected_code=HttpCodes.UNAUTHORIZED ), (f"actual {actual_status_code}, expected {HttpCodes.UNAUTHORIZED}")
def test_create_invalid_user_fails(self, invalid_user_request, user_api): """ Tests scenarios where creating a user should fail. """ user_response_body, actual_status_code = user_api.post( create_user_body_request=invalid_user_request) logger.info( f"Verify that the user body response {user_response_body} is an ERROR" ) assert is_error_response_valid(error_response=user_response_body, code=HttpCodes.BAD_REQUEST) logger.info(f"Verify that status code is {HttpCodes.BAD_REQUEST}") assert is_expected_code( actual_code=actual_status_code, expected_code=HttpCodes.BAD_REQUEST), ( f"actual {actual_status_code}, expected {HttpCodes.OK}")
def test_get_single_docker_server_fails_without_instances( self, docker_server_api): """ Tests that given an empty DB without docker servers, single GET response returns an error. """ docker_server_body_response, actual_status_code = docker_server_api.get_one( instance_id=config.INVALID_INSTANCE_ID) assert is_error_response_valid( error_response=docker_server_body_response, code=HttpCodes.NOT_FOUND, message=config.INSTANCE_NOT_FOUND_MSG.format( invalid_instance_id=config.INVALID_INSTANCE_ID) ), f"Response body {docker_server_body_response} is not as expected" logger.info(f"Verify that the status code is {HttpCodes.NOT_FOUND}") assert is_expected_code( actual_code=actual_status_code, expected_code=HttpCodes.NOT_FOUND ), (f"actual: {actual_status_code}, expected: {HttpCodes.NOT_FOUND}")
def test_get_container_fails(self, docker_server_ids, container_api): """ Tests that given an invalid container ID, the server returns Error response body and 404. """ for docker_server_id in docker_server_ids: response_body, actual_status_code = container_api.get_one( instance_id=docker_server_id, container_id=config.INVALID_CONTAINER_ID ) logger.info(f"Verify that response body {response_body} is an ERROR") assert is_error_response_valid( error_response=response_body, code=HttpCodes.NOT_FOUND, message=config.CONTAINER_NOT_FOUND_MSG.format(invalid_container_id=config.INVALID_CONTAINER_ID) ), f"Failed to validate that {response_body} is an ERROR" logger.info(f"Verify the status code is {HttpCodes.NOT_FOUND}") assert is_expected_code(actual_code=actual_status_code, expected_code=HttpCodes.NOT_FOUND), ( f"actual code: {actual_status_code}, expected code: {HttpCodes.NOT_FOUND}" )
def test_create_docker_server_success(self, create_docker_servers): """ Tests that creating a new docker server succeed with the correct response body and code. """ created_instances = create_docker_servers for docker_server_body_response, actual_status_code in created_instances: is_response_valid = is_docker_server_response_body_valid( docker_server_data_response=docker_server_body_response, **config.EXPECTED_RESPONSE_FOR_NEW_DOCKER_SERVER) logger.info( f"Verify that the docker response {docker_server_body_response} is expected" ) assert is_response_valid, f"{docker_server_body_response} is not as expected" logger.info(f"Verify that status code is {HttpCodes.OK}") assert is_expected_code(actual_code=actual_status_code), ( f"actual {actual_status_code}, expected {HttpCodes.OK}")
def test_create_metasploit_container_succeed(self, docker_server_ids, container_api): """ Tests that creating a new metasploit container succeed with the correct response body and code. """ for docker_server_id in docker_server_ids: body_response, actual_status_code = container_api.post(instance_id=docker_server_id) container_id = get_container_id_from_container_response(container_body_response=body_response) assert container_id, f"Failed to get container ID from {body_response}" logger.info(f"Verify that container body response {body_response} is valid") assert is_container_response_valid( container_response_body=body_response, **get_container_expected_response(instance_id=docker_server_id, container_id=container_id) ) logger.info(f"Verify the status code is {HttpCodes.OK}") assert is_expected_code(actual_code=actual_status_code), ( f"actual: {actual_status_code}, expected: {HttpCodes.OK}" )
def test_delete_user_fails(self, invalid_email, user_api): """ Tests scenarios where trying to delete a user that does not exist fails. """ user_body_response, actual_status_code = user_api.delete( email=invalid_email, expected_to_fail=True) logger.info( f"Verify that DELETE body response {user_body_response} is an ERROR" ) assert is_error_response_valid( error_response=user_body_response, code=HttpCodes.NOT_FOUND), ( f"Response body {user_body_response} is not as expected") logger.info( f"Verify that the DELETE response status code is {HttpCodes.NOT_FOUND}" ) assert is_expected_code( actual_code=actual_status_code, expected_code=HttpCodes.NOT_FOUND), ( f"actual {actual_status_code}, expected {HttpCodes.NOT_FOUND}")
def test_get_many_new_docker_servers_succeed(self, docker_server_api): """ Tests that given many new docker servers that were just created, a GET response is valid. """ docker_servers, actual_status_code = docker_server_api.get_many() for docker_server_body_response in docker_servers: is_response_valid = is_docker_server_response_body_valid( docker_server_data_response=docker_server_body_response, **config.EXPECTED_RESPONSE_FOR_NEW_DOCKER_SERVER) logger.info( f"Verify that the docker response {docker_server_body_response} is expected" ) assert is_response_valid, f"{docker_server_body_response} is not as expected" logger.info(f"Verify that status code is {HttpCodes.OK}") assert is_expected_code( actual_code=actual_status_code ), f"actual {actual_status_code}, expected {HttpCodes.OK}"
def test_get_payload_name_success(self, payload_name, docker_server_ids, metasploit_api): """ Tests scenarios where trying to get a valid payload names should succeed. """ for docker_server_id in docker_server_ids: logger.info( f"Get payload {payload_name} in instance {docker_server_id}") response_body, actual_status_code = metasploit_api.get_payload( instance_id=docker_server_id, payload_name=payload_name) logger.info( f"Verify get payload of {payload_name} on instance {docker_server_id} succeeded" ) assert is_payload_name_response_valid( payload_details_response_body=response_body), ( f"Payload details response {response_body} is not valid") logger.info(f"Verify the status code is {HttpCodes.OK}") assert is_expected_code(actual_code=actual_status_code), ( f"actual {actual_status_code}, expected {HttpCodes.OK}")
def test_get_single_new_docker_server_succeed(self, docker_server_ids, docker_server_api): """ Tests that given a new docker server that was just created, a GET response is valid. """ for docker_server_id in docker_server_ids: docker_server_body_response, actual_status_code = docker_server_api.get_one( instance_id=docker_server_id) is_response_valid = is_docker_server_response_body_valid( docker_server_data_response=docker_server_body_response, **config.EXPECTED_RESPONSE_FOR_NEW_DOCKER_SERVER) logger.info( f"Verify that the docker response {docker_server_body_response} is expected" ) assert is_response_valid, f"{docker_server_body_response} is not as expected" logger.info(f"Verify that status code is {HttpCodes.OK}") assert is_expected_code(actual_code=actual_status_code), ( f"actual {actual_status_code}, expected {HttpCodes.OK}")
def test_execute_exploit_succeed(self, exploit_body_request, fill_exploit_body_request, create_metasploitable_server, metasploit_api): """ Tests scenarios where executing an exploit on metasploitable is expected to succeed and get details from it. """ docker_server_id, metasploitable_ip = create_metasploitable_server response_body, actual_status_code = metasploit_api.run_exploit( instance_id=docker_server_id, target=metasploitable_ip, execute_exploit_body_request=fill_exploit_body_request) logger.info(f"Verify that {response_body} is valid") assert is_execute_exploit_response_valid( execute_exploit_body_response=response_body), ( f"execute exploit response {response_body} is not valid") logger.info(f"Verify the status code is {HttpCodes.OK}") assert is_expected_code(actual_code=actual_status_code), ( f"actual {actual_status_code}, expected {HttpCodes.OK}")
def test_get_container_succeed(self, docker_server_ids_and_container_ids, container_api): """ Tests that given a docker server with containers, GET of a single container gives a valid container response. """ for docker_server_id, container_ids in docker_server_ids_and_container_ids.items(): for container_id in container_ids: body_response, actual_status_code = container_api.get_one( instance_id=docker_server_id, container_id=container_id ) assert isinstance(body_response, dict), f"response {body_response} is not a dict!" logger.info(f"Verify that container body response {body_response} is valid") assert is_container_response_valid( container_response_body=body_response, **get_container_expected_response(instance_id=docker_server_id, container_id=container_id) ) logger.info(f"Verify the status code is {HttpCodes.OK}") assert is_expected_code(actual_code=actual_status_code), ( f"actual: {actual_status_code}, expected: {HttpCodes.OK}" )
def test_scan_ports_success(self, target_host, docker_server_ids, metasploit_api): """ Tests scenarios where the port scanning of valid target host should be success. """ for docker_server_id in docker_server_ids: logger.info( f"Scan ports, instance: {docker_server_id}, target: {target_host}" ) response_body, actual_status_code = metasploit_api.scan_ports( instance_id=docker_server_id, target_host=target_host) logger.info(f"Verify that response body {response_body} is a list") assert isinstance( response_body, list), f"response body {response_body} is not a list." logger.info( f"Verify that response body {response_body} is not empty") assert response_body != [], f"Failed to verify that {response_body} is not empty" target_ip = socket.gethostbyname(target_host) logger.info( f"Verify that response body {response_body} contains IP {target_ip} with a valid port" ) actual_response = re.findall(pattern=f"{target_ip}:[0-9]+", string=" ".join(response_body)) assert len(actual_response) == len( response_body ), f"actual {actual_response}, expected {response_body}" logger.info(f"Verify the status code is {HttpCodes.OK}") assert is_expected_code(actual_code=actual_status_code), ( f"actual {actual_status_code}, expected {HttpCodes.OK}")