def tearDown(self): XpresserUnittest.tearDown(self) # Just in case... we don't want to break other tests startup_cfg = StartUpConfig() startup_cfg.last_upd = datetime.date.today() startup_cfg.save()
def test_get_prompt(self): # We want to get the prompt, not a disclaimer message startup_cfg = StartUpConfig() startup_cfg.accepted_disclaimer = True startup_cfg.save() # The easy way to do this was to simply pass 'python' to Popen # but now that we want to run the tests in virtualenv, we need to # find the "correct" / "virtual" python executable using which and # then pass that one to Popen python_executable = which('python')[0] p = subprocess.Popen([python_executable, 'w3af_console', '-n'], stdout=subprocess.PIPE, stdin=subprocess.PIPE) # Wait for the subprocess to start and the prompt to appear time.sleep(15) expected_prompt = 'w3af>>>' prompt = non_block_read(p.stdout) msg = 'Failed to find "%s" in "%s" using "%s" as python executable.' msg = msg % (expected_prompt, prompt, python_executable) self.assertTrue(prompt.startswith(expected_prompt), msg) p.kill()
def tearDown(self): XpresserUnittest.tearDown(self) # Just in case... we don't want to break other tests startup_cfg = StartUpConfig() startup_cfg.accepted_disclaimer = True startup_cfg.save()
def accept_disclaimer(self): ''' :return: True/False depending on the user's answer to our disclaimer. Please note that in w3af_console we'll stop if the user does not accept the disclaimer. ''' startup_cfg = StartUpConfig() if startup_cfg.accepted_disclaimer: return True QUESTION = 'Do you accept the terms and conditions? [N|y] ' msg = DISCLAIMER + '\n\n' + QUESTION try: user_response = raw_input(msg) except (KeyboardInterrupt, EOFError): print '' user_response = '' user_response = user_response.lower() if user_response == 'y' or user_response == 'yes': startup_cfg.accepted_disclaimer = True startup_cfg.save() return True return False
def test_disclaimer_shown_accept(self): startup_cfg = StartUpConfig() startup_cfg.last_upd = - datetime.timedelta(days=3) startup_cfg.save() self.find('update_window') self.click('update') self.find('owasp_top_10_profile')
def test_disclaimer_shown_not_accept(self): startup_cfg = StartUpConfig() startup_cfg.accepted_disclaimer = False startup_cfg.save() self.find('accept_terms_conditions') self.click('simple_no') self.not_find('owasp_top_10_profile')
def test_disclaimer_shown_accept(self): startup_cfg = StartUpConfig() startup_cfg.last_upd = datetime.date.today() - datetime.timedelta( days=3) startup_cfg.save() self.find('update_window') self.click('update') self.find('owasp_top_10_profile')
def test_update_not_required_not_forced(self): ''' Test that we don't perform any extra steps if the local installation was already updated today. ''' self.vmgr._start_cfg = start_cfg = StartUpConfig() start_cfg._autoupd = True start_cfg._freq = StartUpConfig.FREQ_DAILY last_upd = datetime.date.today() - datetime.timedelta(days=0) start_cfg._lastupd = last_upd on_update_check_mock = MagicMock() on_already_latest_mock = MagicMock() on_update_mock = MagicMock() self.vmgr.register(VersionMgr.ON_UPDATE_CHECK, on_update_check_mock, None) self.vmgr.register(VersionMgr.ON_ALREADY_LATEST, on_already_latest_mock, None) self.vmgr.register(VersionMgr.ON_UPDATE, on_update_mock, None) self.vmgr.update() self.assertEqual(on_update_check_mock.call_count, 0) self.assertEqual(on_already_latest_mock.call_count, 0) self.assertEqual(on_update_mock.call_count, 0)
def test_no_need_update(self): vmgr = self.vmgr vmgr._start_cfg = StartUpConfig() vmgr._start_cfg._autoupd = False # Test no auto-update self.assertFalse(vmgr._has_to_update())
def test_update_required_not_forced(self): ''' Test that we check if we're on the latest version if the latest local installation update was 3 days ago and the frequency is set to daily. The local repository is in the latest version (git pull is run before) ''' git_client = GitClient('.') git_client.pull() self.vmgr._start_cfg = start_cfg = StartUpConfig() start_cfg._autoupd = True start_cfg._freq = StartUpConfig.FREQ_DAILY last_upd = datetime.date.today() - datetime.timedelta(days=3) start_cfg._lastupd = last_upd on_update_check_mock = MagicMock() on_already_latest_mock = MagicMock() on_update_mock = MagicMock() self.vmgr.register(VersionMgr.ON_UPDATE_CHECK, on_update_check_mock, None) self.vmgr.register(VersionMgr.ON_ALREADY_LATEST, on_already_latest_mock, None) self.vmgr.register(VersionMgr.ON_UPDATE, on_update_mock, None) self.vmgr.update() self.assertEqual(on_update_check_mock.call_count, 1) self.assertEqual(on_already_latest_mock.call_count, 1) self.assertEqual(on_update_mock.call_count, 0)
def test_save(self): scfg = StartUpConfig(self.CFG_FILE) scfg.last_upd = date.today() scfg.accepted_disclaimer = True scfg.last_commit_id = '3f4808082c1943f964669af1a1c94245bab09c61' scfg.save()
def __init__(self, localpath=W3AF_LOCAL_PATH, log=None): ''' w3af version manager class. Handles the logic concerning the automatic update/commit process of the code. :param localpath: Working directory :param log: Default output function ''' self._localpath = localpath self._client = GitClient(localpath) self._client.add_observer(self._client_progress) log = log if log is not None else om.out.console self._log = log # Set default events self.register_default_events(log) # Startup configuration self._start_cfg = StartUpConfig()
def test_load_not_exist(self): ''' This is a test to verify that the defaults are loaded when the file does not exist. ''' scfg = StartUpConfig('foo.conf') self.assertEqual(scfg.last_upd, date.today() - timedelta(days=31)) self.assertEqual(scfg.accepted_disclaimer, False) self.assertEqual(scfg.last_commit_id, '') self.assertEqual(scfg.freq, 'D')
def accept_disclaimer(self): ''' :return: True/False depending on the user's answer to our disclaimer. Please note that in w3af_gui we'll stop if the user does not accept the disclaimer. ''' startup_cfg = StartUpConfig() if startup_cfg.accepted_disclaimer: return True QUESTION = 'Do you accept the terms and conditions?' msg = DISCLAIMER + '\n\n' + QUESTION user_response = ask(msg) if user_response: startup_cfg.accepted_disclaimer = True startup_cfg.save() return True return False
def test_load_file_exists(self): '''This is a test to verify that the things we saved were persited in the actual file. ''' # Save scfg = StartUpConfig(self.CFG_FILE) scfg.last_upd = date.today() scfg.accepted_disclaimer = True scfg.last_commit_id = '3f4808082c1943f964669af1a1c94245bab09c61' scfg.save() # Load scfg = StartUpConfig(self.CFG_FILE) self.assertEqual(scfg.last_upd, date.today()) self.assertEqual(scfg.accepted_disclaimer, True) self.assertEqual(scfg.last_commit_id, '3f4808082c1943f964669af1a1c94245bab09c61') self.assertEqual(scfg.freq, 'D')
def test_update_required_outdated_not_forced(self): ''' Test that we check if we're on the latest version if the latest local installation update was 3 days ago and the frequency is set to daily. The local repository is NOT in the latest version. A 'git reset --hard' is run at the beginning of this test to reset the repo to a revision before the latest one. ''' try: git_client = GitClient('.') head_id = git_client.get_local_head_id() one_before_head = git_client.get_parent_for_revision(head_id) git_client.reset_to_previous_state(one_before_head) self.vmgr._start_cfg = start_cfg = StartUpConfig() start_cfg._autoupd = True start_cfg._freq = StartUpConfig.FREQ_DAILY last_upd = datetime.date.today() - datetime.timedelta(days=3) start_cfg._lastupd = last_upd on_update_check_mock = MagicMock() on_already_latest_mock = MagicMock() on_update_mock = MagicMock() self.vmgr.register(VersionMgr.ON_UPDATE_CHECK, on_update_check_mock, None) self.vmgr.register(VersionMgr.ON_ALREADY_LATEST, on_already_latest_mock, None) self.vmgr.register(VersionMgr.ON_UPDATE, on_update_mock, None) self.vmgr.callback_onupdate_confirm = MagicMock(side_effect=[ True, ]) self.vmgr.update() self.assertEqual(on_update_check_mock.call_count, 1) self.assertEqual(on_already_latest_mock.call_count, 0) self.assertEqual(on_update_mock.call_count, 1) finally: git_client.pull()
def test_has_to_update(self): ''' Test [D]aily, [W]eekly and [M]onthly auto-update ''' SC = StartUpConfig vmgr = self.vmgr for freq, diffdays in ((SC.FREQ_DAILY, 1), (SC.FREQ_WEEKLY, 8), (SC.FREQ_MONTHLY, 34)): vmgr._start_cfg = start_cfg = StartUpConfig() start_cfg._autoupd = True start_cfg._freq = freq last_upd = datetime.date.today() - datetime.timedelta( days=diffdays) start_cfg._lastupd = last_upd self.assertTrue(vmgr._has_to_update())
class VersionMgr(object): ''' Perform SVN w3af code update and commit. When an instance is created loads data from a .conf file that will be used when actions are executed. Also provides some callbacks as well as events to register to. Callbacks on: UPDATE: * callback_onupdate_confirm(msg) Return True/False * callback_onupdate_show_log(msg, log_func) Displays 'msg' to the user and depending on user's answer call 'log_func()' which returns a string with the summary of the commit logs from the from local revision to repo's. * callback_onupdate_error If an SVNError occurs this callback is called in order to the client class handles the error. Probably notify the user. COMMIT: {implementation pending} Events: ON_UPDATE ON_UPDATE_ADDED_DEP ON_UPDATE_CHECK ON_ACTION_ERROR ''' # Events constants ON_UPDATE = 1 ON_UPDATE_ADDED_DEP = 2 ON_UPDATE_CHECK = 3 ON_ALREADY_LATEST = 4 ON_ACTION_ERROR = 5 ON_COMMIT = 6 ON_PROGRESS = 7 # Callbacks callback_onupdate_confirm = None callback_onupdate_show_log = None callback_onupdate_error = None # Revision constants HEAD = 'HEAD' BACK = 'BACK' def __init__(self, localpath=W3AF_LOCAL_PATH, log=None): ''' w3af version manager class. Handles the logic concerning the automatic update/commit process of the code. :param localpath: Working directory :param log: Default output function ''' self._localpath = localpath self._client = GitClient(localpath) self._client.add_observer(self._client_progress) log = log if log is not None else om.out.console self._log = log # Set default events self.register_default_events(log) # Startup configuration self._start_cfg = StartUpConfig() def _client_progress(self, op_code, cur_count, max_count, message): ''' The GitClient will call this method when it has progress to show for fetch() and pull(). Please note that because I don't need it at this moment, I'm simply ignoring all parameters and just letting the observers know that this event was triggered. ''' self._notify(VersionMgr.ON_PROGRESS) def register_default_events(self, log): ''' Default events registration :param log: Log function to call for events :return: None, all saved in self._reg_funcs ''' # Registered functions self._reg_funcs = {} msg = ('Checking if a new version is available in our git repository.' ' Please wait...') self.register(VersionMgr.ON_UPDATE_CHECK, log, msg) msg = ('Your installation is already on the latest available version.') self.register(VersionMgr.ON_ALREADY_LATEST, log, msg) msg = 'w3af is updating from github.com ...' self.register(VersionMgr.ON_UPDATE, log, msg) msg = ('The third-party dependencies for w3af have changed, please' ' exit the framework and run it again to load all changes' ' and install any missing modules.') self.register(VersionMgr.ON_UPDATE_ADDED_DEP, log, msg) def update(self, force=False): ''' Perform code update if necessary. Return three elems tuple with the ChangeLog of the changed files, the local and the final commit id. :param force: Force update ignoring the startup config. :return: (changelog: A ChangeLog instance, local_head_id: The local id before the update, commit_id: The commit id after the update) ''' if not force and not self._has_to_update(): # No need to update based on user preferences return # Save the latest update date, always, even when the update had errors # or there was no update available self._start_cfg.last_upd = date.today() self._start_cfg.save() local_head_id = self._client.get_local_head_id() short_local_head_id = to_short_id(local_head_id) # Lets update! self._notify(VersionMgr.ON_UPDATE_CHECK) # This performs a fetch() which takes time remote_head_id = self._client.get_remote_head_id() short_remote_head_id = to_short_id(remote_head_id) if local_head_id == remote_head_id: # If local and repo's rev are the same => Nothing to do. self._notify(VersionMgr.ON_ALREADY_LATEST) return if self._user_confirmed_update(short_local_head_id, local_head_id, short_remote_head_id, remote_head_id): return self.__update_impl() def _user_confirmed_update(self, short_local_head_id, local_head_id, short_remote_head_id, remote_head_id): ''' Ask the user if he wants to update or not. :return: True if the user wants to update. ''' # Call callback function if self.callback_onupdate_confirm is not None: callback = self.callback_onupdate_confirm # pylint: disable=E1102 # pylint: disable=E1103 msg = 'Your current w3af installation is %s (%s). Do you want '\ 'to update to %s (%s)?' proceed_upd = callback(msg % (short_local_head_id, get_commit_id_date(local_head_id), short_remote_head_id, get_commit_id_date(remote_head_id))) return proceed_upd def __update_impl(self): ''' Finally call the Git client's pull! :return: (changelog, local_head_id, target_commit) ''' self._notify(VersionMgr.ON_UPDATE) try: changelog = self._client.pull() except GitClientError, exc: msg = '%s' % exc self._notify(VersionMgr.ON_ACTION_ERROR, msg) return else:
def test_disclaimer_not_shown(self): startup_cfg = StartUpConfig() startup_cfg.accepted_disclaimer = True startup_cfg.save() self.not_find('accept_terms_conditions')
class VersionMgr(object): ''' Perform SVN w3af code update and commit. When an instance is created loads data from a .conf file that will be used when actions are executed. Also provides some callbacks as well as events to register to. Callbacks on: UPDATE: * callback_onupdate_confirm(msg) Return True/False * callback_onupdate_show_log(msg, log_func) Displays 'msg' to the user and depending on user's answer call 'log_func()' which returns a string with the summary of the commit logs from the from local revision to repo's. * callback_onupdate_error If an SVNError occurs this callback is called in order to the client class handles the error. Probably notify the user. COMMIT: {implementation pending} Events: ON_UPDATE ON_UPDATE_ADDED_DEP ON_UPDATE_CHECK ON_ACTION_ERROR ''' # Events constants ON_UPDATE = 1 ON_UPDATE_ADDED_DEP = 2 ON_UPDATE_CHECK = 3 ON_ALREADY_LATEST = 4 ON_ACTION_ERROR = 5 ON_COMMIT = 6 ON_PROGRESS = 7 # Callbacks callback_onupdate_confirm = None callback_onupdate_show_log = None callback_onupdate_error = None # Revision constants HEAD = 'HEAD' BACK = 'BACK' def __init__(self, localpath=W3AF_LOCAL_PATH, log=None): ''' w3af version manager class. Handles the logic concerning the automatic update/commit process of the code. :param localpath: Working directory :param log: Default output function ''' self._localpath = localpath self._client = GitClient(localpath) self._client.add_observer(self._client_progress) log = log if log is not None else om.out.console self._log = log # Set default events self.register_default_events(log) # Startup configuration self._start_cfg = StartUpConfig() def _client_progress(self, op_code, cur_count, max_count, message): ''' The GitClient will call this method when it has progress to show for fetch() and pull(). Please note that because I don't need it at this moment, I'm simply ignoring all parameters and just letting the observers know that this event was triggered. ''' self._notify(VersionMgr.ON_PROGRESS) def register_default_events(self, log): ''' Default events registration :param log: Log function to call for events :return: None, all saved in self._reg_funcs ''' # Registered functions self._reg_funcs = {} msg = ('Checking if a new version is available in our git repository.' ' Please wait...') self.register(VersionMgr.ON_UPDATE_CHECK, log, msg) msg = ('Your installation is already on the latest available version.') self.register(VersionMgr.ON_ALREADY_LATEST, log, msg) msg = 'w3af is updating from github.com ...' self.register(VersionMgr.ON_UPDATE, log, msg) msg = ('The third-party dependencies for w3af have changed, please' ' exit the framework and run it again to load all changes' ' and install any missing modules.') self.register(VersionMgr.ON_UPDATE_ADDED_DEP, log, msg) def update(self, force=False): ''' Perform code update if necessary. Return three elems tuple with the ChangeLog of the changed files, the local and the final commit id. :param force: Force update ignoring the startup config. :return: (changelog: A ChangeLog instance, local_head_id: The local id before the update, commit_id: The commit id after the update) ''' if not force and not self._has_to_update(): # No need to update based on user preferences return # Save the latest update date, always, even when the update had errors # or there was no update available self._start_cfg.last_upd = date.today() self._start_cfg.save() local_head_id = self._client.get_local_head_id() short_local_head_id = to_short_id(local_head_id) # Lets update! self._notify(VersionMgr.ON_UPDATE_CHECK) # This performs a fetch() which takes time remote_head_id = self._client.get_remote_head_id() short_remote_head_id = to_short_id(remote_head_id) if local_head_id == remote_head_id: # If local and repo's rev are the same => Nothing to do. self._notify(VersionMgr.ON_ALREADY_LATEST) return if self._user_confirmed_update(short_local_head_id, local_head_id, short_remote_head_id, remote_head_id): return self.__update_impl() def _user_confirmed_update(self, short_local_head_id, local_head_id, short_remote_head_id, remote_head_id): ''' Ask the user if he wants to update or not. :return: True if the user wants to update. ''' # Call callback function if self.callback_onupdate_confirm is not None: callback = self.callback_onupdate_confirm # pylint: disable=E1102 # pylint: disable=E1103 msg = 'Your current w3af installation is %s (%s). Do you want '\ 'to update to %s (%s)?' proceed_upd = callback( msg % (short_local_head_id, get_commit_id_date(local_head_id), short_remote_head_id, get_commit_id_date(remote_head_id))) return proceed_upd def __update_impl(self): ''' Finally call the Git client's pull! :return: (changelog, local_head_id, target_commit) ''' self._notify(VersionMgr.ON_UPDATE) try: changelog = self._client.pull() except GitClientError, exc: msg = '%s' % exc self._notify(VersionMgr.ON_ACTION_ERROR, msg) return else: