def check_objects_exist(self, compare_id): if compare_id == normalize_compare_id(';'.join( [TEST_FW_2.uid, TEST_FW.uid])): return None if compare_id == normalize_compare_id(';'.join( [TEST_TEXT_FILE.uid, TEST_FW.uid])): return None raise FactCompareException('bla')
def get_compare_result(self, compare_id): if compare_id == normalize_compare_id(';'.join([TEST_FW.uid, TEST_FW_2.uid])): return { 'this_is': 'a_compare_result', 'general': {'hid': {TEST_FW.uid: 'foo', TEST_TEXT_FILE.uid: 'bar'}}, 'plugins': {'File_Coverage': {'some_feature': {TEST_FW.uid: [TEST_TEXT_FILE.uid]}}} } if compare_id == normalize_compare_id(';'.join([TEST_FW.uid, TEST_TEXT_FILE.uid])): return {'this_is': 'a_compare_result'} return 'generic error'
def test_unpack_analyse_and_compare(self): test_fw_1 = Firmware( file_path='{}/container/test.zip'.format(get_test_data_dir())) test_fw_1.release_date = '2017-01-01' test_fw_2 = Firmware( file_path='{}/regression_one'.format(get_test_data_dir())) test_fw_2.release_date = '2017-01-01' self._unpack_scheduler.add_task(test_fw_1) self._unpack_scheduler.add_task(test_fw_2) self.analysis_finished_event.wait(timeout=20) compare_id = normalize_compare_id(';'.join( [fw.uid for fw in [test_fw_1, test_fw_2]])) self.assertIsNone( self._compare_scheduler.add_task((compare_id, False)), 'adding compare task creates error') self.compare_finished_event.wait(timeout=10) with ConnectTo(CompareDbInterface, self._config) as sc: result = sc.get_compare_result(compare_id) self.assertEqual(result['plugins']['Software'], self._expected_result()['Software']) self.assertCountEqual( result['plugins']['File_Coverage']['files_in_common'], self._expected_result()['File_Coverage']['files_in_common'])
def get(self, compare_id=None): ''' The request data should have the form {"uid_list": uid_list, "<optional>redo": True} return value: the result dict from the compare ''' try: compare_id = normalize_compare_id(compare_id) except (AttributeError, TypeError): return error_message( 'Compare ID must be of the form uid1;uid2(;uid3..)', self.URL, request_data={'compare_id': compare_id}) with ConnectTo(CompareDbInterface, self.config) as db_compare_service: result = None with suppress(FactCompareException): if db_compare_service.compare_result_is_in_db(compare_id): result = db_compare_service.get_compare_result(compare_id) if result: return success_message(result, self.URL, request_data={'compare_id': compare_id}, return_code=202) return error_message( 'Compare not found in database. Please use /rest/start_compare to start the compare.', self.URL, request_data={'compare_id': compare_id}, return_code=404)
def put(self): ''' The request data should have the form {"uid_list": uid_list, "<optional>redo": True} return value: the result dict from the compare ''' try: data = convert_rest_request(request.data) except TypeError as type_error: return error_message(str(type_error), self.URL, request_data=request.data) try: uid_string = ';'.join(data['uid_list']) compare_id = normalize_compare_id(uid_string) redo = data.get('redo', False) except (AttributeError, TypeError, KeyError): return error_message( 'Request should be of the form {"uid_list": uid_list, "redo": boolean}', self.URL, request_data=data) with ConnectTo(CompareDbInterface, self.config) as db_compare_service: if not db_compare_service.compare_result_is_in_db( compare_id) or redo: return self.start_compare(db_compare_service, compare_id, data, redo) return error_message( 'Compare already exists. Use "redo" to force re-compare.', self.URL, request_data=data, return_code=200)
def get_compare_result(self, compare_id): if compare_id == normalize_compare_id(';'.join( [TEST_FW.uid, TEST_FW_2.uid])): return { 'this_is': 'a_compare_result', 'general': { 'hid': { TEST_FW.uid: 'foo', TEST_TEXT_FILE.uid: 'bar' } } } elif compare_id == normalize_compare_id(';'.join( [TEST_FW.uid, TEST_TEXT_FILE.uid])): return {'this_is': 'a_compare_result'} else: return 'generic error'
def delete_old_compare_result(self, compare_id): try: self.compare_results.remove( {'_id': normalize_compare_id(compare_id)}) logging.debug('old compare result deleted: {}'.format(compare_id)) except Exception as exception: logging.warning( 'Could not delete old compare result: {} {}'.format( type(exception).__name__, exception))
def get_compare_result(self, compare_id: str) -> Optional[dict]: compare_id = normalize_compare_id(compare_id) self.check_objects_exist(compare_id) compare_result = self.compare_results.find_one(compare_id) if compare_result: logging.debug('got compare result from db: {}'.format(compare_id)) return compare_result logging.debug('compare result not found in db: {}'.format(compare_id)) return None
def put(self): ''' The request data should have the form {"uid_list": uid_list, "<optional>redo": True} return value: the result dict from the compare ''' try: data = convert_rest_request(request.data) except TypeError as type_error: return error_message(str(type_error), self.URL, request_data=request.data) try: uid_string = ';'.join(data['uid_list']) compare_id = normalize_compare_id(uid_string) redo = data.get('redo', False) except (AttributeError, TypeError, KeyError): return error_message( 'Request should be of the form {"uid_list": uid_list, "redo": boolean}', self.URL, request_data=data) with ConnectTo(CompareDbInterface, self.config) as db_compare_service: if not db_compare_service.compare_result_is_in_db( compare_id) or redo: try: db_compare_service.check_objects_exist(compare_id) except FactCompareException as exception: return error_message(exception.get_message(), self.URL, request_data=data, return_code=404) with ConnectTo(InterComFrontEndBinding, self.config) as intercom: intercom.add_compare_task(compare_id, force=redo) return success_message( { 'message': 'Compare started. Please use GET to get the results.' }, self.URL, request_data=data, return_code=202) return error_message( 'Compare already exists. Use "redo" to force re-compare.', self.URL, request_data=data, return_code=200)
def _app_show_compare_result(self, compare_id): compare_id = normalize_compare_id(compare_id) try: with ConnectTo(CompareDbInterface, self._config) as sc: result = sc.get_compare_result(compare_id) except FactCompareException as exception: return render_template('compare/error.html', error=exception.get_message()) if not result: return render_template('compare/wait.html', compare_id=compare_id) download_link = self._create_ida_download_if_existing(result, compare_id) uid_list = convert_compare_id_to_list(compare_id) plugin_views, plugins_without_view = self._get_compare_plugin_views(result) compare_view = self._get_compare_view(plugin_views) self._fill_in_empty_fields(result, compare_id) return render_template_string( compare_view, result=result, uid_list=uid_list, download_link=download_link, plugins_without_view=plugins_without_view )
def compare_result_is_in_db(self, compare_id): compare_result = self.compare_results.find_one( normalize_compare_id(compare_id)) return True if compare_result else False
def compare_result_is_in_db(self, uid_list): return uid_list == normalize_compare_id(';'.join( [TEST_FW.uid, TEST_TEXT_FILE.uid]))
def test_normalize_compare_id(): ids_a = 'a;b' ids_b = 'b;a' assert normalize_compare_id(ids_a) == 'a;b', 'compare id not correct' assert normalize_compare_id(ids_a) == normalize_compare_id( ids_b), 'compare ids not the same'
def compare_result_is_in_db(self, compare_id): compare_result = self.compare_results.find_one( normalize_compare_id(compare_id)) return bool(compare_result)