def test_change_password_happy_flow(self): """ Test method for the change password method. Happy flow. """ inserted_user = self._prepare_user_for_change_pwd() self.user_service.edit_user(inserted_user, hash_password("test_password")) changed_user = dao.get_user_by_name("test_user") assert changed_user.password == hash_password("new_test_password"), "The password did not change."
def _create_user(self, email_msg=None, validated=False, **data): """ Just create a user given the data input. Do form validation beforehand. """ form = RegisterForm() data = form.to_python(data) data[KEY_PASSWORD] = hash_password(data[KEY_PASSWORD]) data['password2'] = hash_password(data['password2']) return self.user_service.create_user(email_msg=email_msg, validated=validated, **data)
def test_change_password_wrong_old(self): """ Test method for the change password method. Old password is wrong, should return false. """ inserted_user = self._prepare_user_for_change_pwd() params = dict(edited_user=inserted_user, old_password=hash_password("wrong_old_pwd")) with pytest.raises(UsernameException): self.user_service.edit_user(**params) user = dao.get_user_by_name("test_user") assert user.password == hash_password("test_password"), "The password should have not been changed!"
def _prepare_user_for_change_pwd(self): """Private method to prepare password change operation""" data = dict(username="******", display_name="test_name", password=hash_password("test_password"), email="*****@*****.**", role="user", comment="") self.user_service.create_user(**data) self.user_service.validate_user("test_user") inserted_user = dao.get_user_by_name("test_user") assert inserted_user.password == hash_password("test_password"), "The password inserted is not correct." inserted_user.password = hash_password("new_test_password") return inserted_user
def test_reset_password_happy_flow(self): """ Test method for the reset password method. Happy flow. """ data = dict(username="******", display_name="test_name", password=hash_password("test_password"), email="*****@*****.**", role="user", comment="") self.user_service.create_user(**data) inserted_user = dao.get_user_by_name("test_user") assert inserted_user.password == hash_password("test_password"), "Incorrect password" reset_pass_data = dict(username="******", email="*****@*****.**") self.user_service.reset_password(**reset_pass_data) inserted_user = dao.get_user_by_name("test_user") assert inserted_user.password != hash_password("test_password"), "Password not reset for some reason!"
def test_reset_pass_wrong_email(self): """ Test method for the reset password method. Email is not valid, should raise exception """ data = dict(username="******", display_name="test_name", password=hash_password("test_password"), email="*****@*****.**", role="user", comment="") self.user_service.create_user(**data) inserted_user = dao.get_user_by_name("test_user") assert inserted_user.password == hash_password("test_password"), "Incorrect password" reset_pass_data = dict(username="******", email="*****@*****.**") with pytest.raises(UsernameException): self.user_service.reset_password(**reset_pass_data)
def test_edit_user_happy_flow(self): """ Test the method of editing a user. """ data = dict(username="******", display_name="test_name", password=hash_password("test_password"), email="*****@*****.**", role="user", comment="") self.user_service.create_user(**data) inserted_user = dao.get_user_by_name("test_user") assert inserted_user.password == hash_password("test_password"), "Incorrect password" inserted_user.role = "new_role" inserted_user.validated = 1 self.user_service.edit_user(inserted_user) changed_user = dao.get_user_by_name("test_user") assert changed_user.role == "new_role", "role unchanged" assert changed_user.validated == 1, "user not validated"
def test_create_user_happy_flow(self): """ Standard flow for creating a user. """ initial_user_count = dao.get_all_users() data = dict(username="******", display_name="test_name", password=hash_password("test_password"), email="*****@*****.**", role="user", comment="") self.user_service.create_user(**data) final_user_count = dao.get_all_users() assert len(initial_user_count) == len(final_user_count) - 1, "User count was not increased after create." inserted_user = dao.get_user_by_name("test_user") assert inserted_user.password == hash_password("test_password"), "Incorrect password" assert inserted_user.email == "*****@*****.**", "The email inserted is not correct." assert inserted_user.role == "user", "The role inserted is not correct." assert not inserted_user.validated, "User validation is not correct."
def reset_password(self, **data): """ Service Layer for resetting a password. """ if (KEY_EMAIL not in data) or len(data[KEY_EMAIL]) < 1: raise UsernameException("Empty Email!") old_pass, user = None, None try: email = data[KEY_EMAIL] name_hint = data[KEY_USERNAME] user = dao.get_user_by_email(email, name_hint) if user is None: raise UsernameException( "No singular user could be found for the given data!") old_pass = user.password new_pass = ''.join( chr(randint(48, 122)) for _ in range(DEFAULT_PASS_LENGTH)) user.password = hash_password(new_pass) self.edit_user(user, old_pass) self.logger.info("Resetting password for email : " + email) email_sender.send(FROM_ADDRESS, email, SUBJECT_RECOVERY, TEXT_RECOVERY % (user.username, new_pass)) return TEXT_DISPLAY except Exception as excep: if old_pass and len(old_pass) > 1 and user: user.password = old_pass dao.store_entity(user) self.logger.exception("Could not change user password!") raise UsernameException(excep)
def generate_users(nr_users, nr_projects): """ The generate_users method will create a clean state db with :param nr_users: number of users to be generated (with random roles between CLINICIAN and RESEARCHER and random validated state) :param nr_projects: maximum number of projects to be generated for each user """ users = [] for i in range(nr_users): coin_flip = random.randint(0, 1) role = 'CLINICIAN' if coin_flip == 1 else 'RESEARCHER' password = hash_password("test") new_user = User("gen" + str(i), "name" + str(i), password, "*****@*****.**", True, role) dao.store_entity(new_user) new_user = dao.get_user_by_name("gen" + str(i)) ExtremeTestFactory.VALIDATION_DICT[new_user.id] = 0 users.append(new_user) for i in range(nr_users): current_user = dao.get_user_by_name("gen" + str(i)) projects_for_user = random.randint(0, nr_projects) for j in range(projects_for_user): data = dict(name='GeneratedProject' + str(i) + '_' + str(j), description='test_desc', users=ExtremeTestFactory.get_users_ids( random.randint(0, nr_users - 3), nr_users, current_user.id, users)) ProjectService().store_project(current_user, True, None, **data) ExtremeTestFactory.VALIDATION_DICT[current_user.id] += 1
def profile(self, logout=False, save=False, **data): """ Display current user's profile page. On POST: logout, or save password/email. """ if cherrypy.request.method == 'POST' and logout: raise cherrypy.HTTPRedirect('/user/logout') template_specification = dict(mainContent="user/profile", title="User Profile") user = common.get_logged_user() if cherrypy.request.method == 'POST' and save: try: form = EditUserForm() data = form.to_python(data) if data.get(KEY_PASSWORD): user.password = hash_password(data[KEY_PASSWORD]) if data.get(KEY_EMAIL): user.email = data[KEY_EMAIL] old_password = None if data.get('old_password'): old_password = hash_password(data['old_password']) self.user_service.edit_user(user, old_password) if old_password: common.set_info_message("Changes Submitted!") else: common.set_info_message("Submitted! No password changed.") except formencode.Invalid as excep: template_specification[ common.KEY_ERRORS] = excep.unpack_errors() except UsernameException as excep: self.logger.exception(excep) user = common.get_logged_user() common.add2session(common.KEY_USER, self.user_service.get_user_by_id(user.id)) common.set_error_message( "Could not save changes. Probably wrong old password!!") else: # Update session user since disk size might have changed from last time to profile. user = self.user_service.get_user_by_id(user.id) common.add2session(common.KEY_USER, user) template_specification['user_used_disk_human'] = format_bytes_human( self.user_service.compute_user_generated_disk_size(user.id)) return self.fill_default_attributes(template_specification)
def test_index_valid_post(self): """ Tests for a valid redirect on user login """ user = User('valid_user', 'name', hash_password('valid_pass'), '*****@*****.**', True, 'CLINICIAN') dao.store_entity(user) login_data = {'username': '******', 'password': '******'} cherrypy.request.method = "POST" self._expect_redirect('/user/profile', self.user_c.index, **login_data)
def check_login(username, password): """ Service layer to check if given UserName and Password are according to DB. """ user = dao.get_user_by_name(username) if user is not None and user.password == hash_password(password) and user.validated: return user else: return None
def test_check_login_bad_user(self): """ Flow for entering a bad/invalid username. """ user = model_project.User("test_user", 'test_name', hash_password("test_pass"), "*****@*****.**", True, "user") dao.store_entity(user) available_users = dao.get_all_users() assert 2 == len(available_users) assert self.user_service.check_login("bad_user", "test_pass") is None, "Login succeeded with bad userName."
def test_check_login_happy_flow(self): """ Standard login flow with a valid username and password. """ user = model_project.User("test_user", 'test_name', hash_password("test_pass"), "*****@*****.**", True, "user") dao.store_entity(user) available_users = dao.get_all_users() assert 2 == len(available_users) assert self.user_service.check_login("test_user", "test_pass") is not None, "Login failed when it shouldn't."
def _create_external_service_user(self, user_data): gid = user_data['sub'] self.logger.info('Create a new external user for external id {}'.format(gid)) username, name, email, role = self._extract_user_info(user_data) if not self.is_username_valid(username): username = gid self.create_user(username, name, hash_password(''.join(random.sample(gid, len(gid)))), gid=gid, email=email, validated=True, skip_sending_email=True, role=role, skip_import=True) return self.get_user_by_gid(gid)
def create_external_service_user(self, user_data): external_id = user_data['sub'] email = user_data['email'] if 'email' in user_data else None self.create_user(external_id, hash_password(''.join( random.sample(external_id, len(external_id)))), external_id=external_id, email=email, validated=True, skip_sending_email=True) return self.get_user_by_external_id(external_id)
def test_with_valid_settings(self): # Ensure we submit acceptable values, depending on the current profile (set-up after fixtures execution) submit_data = copy.copy(self.VALID_SETTINGS) accepted_db_url = ('sqlite:///' + self.storage + os.path.sep + 'tvb-database.db' if TvbProfile.current.db.SELECTED_DB == 'sqlite' else TvbProfile.current.db.DB_URL) submit_data['SELECTED_DB'] = TvbProfile.current.db.SELECTED_DB submit_data['URL_VALUE'] = accepted_db_url self.settings_c._restart_services = self._fake_restart_services with pytest.raises(cherrypy.HTTPRedirect): self.settings_c.settings(save_settings=True, **self.VALID_SETTINGS) # wait until 'restart' is done sleep(1) assert self.was_reset assert len(TvbProfile.current.manager.stored_settings) == 21 assert submit_data['TVB_STORAGE'] == TvbProfile.current.TVB_STORAGE assert submit_data[ 'USR_DISK_SPACE'] * 2**10 == TvbProfile.current.MAX_DISK_SPACE assert submit_data[ 'MAXIMUM_NR_OF_THREADS'] == TvbProfile.current.MAX_THREADS_NUMBER assert submit_data[ 'MAXIMUM_NR_OF_OPS_IN_RANGE'] == TvbProfile.current.MAX_RANGE_NUMBER assert submit_data[ 'MAXIMUM_NR_OF_VERTICES_ON_SURFACE'] == TvbProfile.current.MAX_SURFACE_VERTICES_NUMBER assert submit_data['DEPLOY_CLUSTER'] == str( TvbProfile.current.cluster.IS_DEPLOY) assert submit_data['SELECTED_DB'] == TvbProfile.current.db.SELECTED_DB assert submit_data['URL_VALUE'] == TvbProfile.current.db.DB_URL assert submit_data[ 'WEB_SERVER_PORT'] == TvbProfile.current.web.SERVER_PORT assert submit_data[ 'ADMINISTRATOR_NAME'] == TvbProfile.current.web.admin.ADMINISTRATOR_NAME assert submit_data[ 'ADMINISTRATOR_EMAIL'] == TvbProfile.current.web.admin.ADMINISTRATOR_EMAIL assert hash_password( submit_data['ADMINISTRATOR_PASSWORD'] ) == TvbProfile.current.web.admin.ADMINISTRATOR_PASSWORD
def test_with_valid_settings(self): submit_data = copy.copy(self.VALID_SETTINGS) self.settings_c._restart_services = self._fake_restart_services with pytest.raises(cherrypy.HTTPRedirect): self.settings_c.settings(save_settings=True, **self.VALID_SETTINGS) # wait until 'restart' is done sleep(1) assert self.was_reset assert 17 == len(TvbProfile.current.manager.stored_settings) assert submit_data['TVB_STORAGE'] == TvbProfile.current.TVB_STORAGE assert submit_data[ 'USR_DISK_SPACE'] * 2**10 == TvbProfile.current.MAX_DISK_SPACE assert submit_data[ 'MAXIMUM_NR_OF_THREADS'] == TvbProfile.current.MAX_THREADS_NUMBER assert submit_data[ 'MAXIMUM_NR_OF_OPS_IN_RANGE'] == TvbProfile.current.MAX_RANGE_NUMBER assert submit_data[ 'MAXIMUM_NR_OF_VERTICES_ON_SURFACE'] == TvbProfile.current.MAX_SURFACE_VERTICES_NUMBER assert submit_data['DEPLOY_CLUSTER'] == str( TvbProfile.current.cluster.IS_DEPLOY) assert submit_data['SELECTED_DB'] == TvbProfile.current.db.SELECTED_DB assert submit_data['URL_VALUE'] == TvbProfile.current.db.DB_URL assert submit_data['URL_WEB'] == TvbProfile.current.web.BASE_URL assert submit_data[ 'WEB_SERVER_PORT'] == TvbProfile.current.web.SERVER_PORT assert submit_data[ 'ADMINISTRATOR_NAME'] == TvbProfile.current.web.admin.ADMINISTRATOR_NAME assert submit_data[ 'ADMINISTRATOR_EMAIL'] == TvbProfile.current.web.admin.ADMINISTRATOR_EMAIL assert hash_password( submit_data['ADMINISTRATOR_PASSWORD'] ) == TvbProfile.current.web.admin.ADMINISTRATOR_PASSWORD
def save_settings(self, **data): """ Check if new settings are correct. Make necessary changes, then save new data in configuration file. :returns: two boolean values -there were any changes to the configuration; -a reset should be performed on the TVB relaunch. """ new_storage = data[self.KEY_STORAGE] previous_storage = TvbProfile.current.TVB_STORAGE new_db = data[self.KEY_SELECTED_DB] previous_db = TvbProfile.current.db.SELECTED_DB db_changed = new_db != previous_db storage_changed = new_storage != previous_storage matlab_exec = data[self.KEY_MATLAB_EXECUTABLE] if matlab_exec == 'None': data[self.KEY_MATLAB_EXECUTABLE] = '' # Storage changed but DB didn't, just copy TVB storage to new one. if storage_changed and not db_changed: if os.path.exists(new_storage): if os.access(new_storage, os.W_OK): shutil.rmtree(new_storage) else: raise InvalidSettingsException( "No Write access on storage folder!!") shutil.copytree(previous_storage, new_storage) if not os.path.isdir(new_storage): os.makedirs(new_storage) max_space = data[self.KEY_MAX_DISK_SPACE_USR] available_mem_kb = SettingsService.get_disk_free_space(new_storage) kb_value = int(max_space) * 2**10 if not (0 < kb_value < available_mem_kb): raise InvalidSettingsException( "Not enough disk space. There is a maximum of %d MB available on this disk " "or partition. Wanted %d" % (available_mem_kb / (2**10), max_space)) data[self.KEY_MAX_DISK_SPACE_USR] = kb_value # Save data to file, all while checking if any data has changed first_run = TvbProfile.is_first_run() if first_run: data[ stored. KEY_LAST_CHECKED_FILE_VERSION] = TvbProfile.current.version.DATA_VERSION data[ stored. KEY_LAST_CHECKED_CODE_VERSION] = TvbProfile.current.version.SVN_VERSION file_data = data if self.KEY_ADMIN_PWD in data: data[self.KEY_ADMIN_PWD] = hash_password( data[self.KEY_ADMIN_PWD]) anything_changed = True else: file_data = TvbProfile.current.manager.stored_settings anything_changed = False for key in file_data: if key in data and str(data[key]) != str(file_data[key]): anything_changed = True file_data[key] = data[key] if db_changed: file_data[self.KEY_DB_URL] = TvbProfile.current.db.DB_URL for key in data: if key not in file_data: anything_changed = True file_data[key] = data[key] # Write in file new data if anything_changed: TvbProfile.current.manager.write_config_data(file_data) os.chmod(TvbProfile.current.TVB_CONFIG_FILE, 0o644) return anything_changed, first_run or db_changed