def test_func__user_create_command__ok__nominal_case(self) -> None: """ Test User creation """ api = UserApi( current_user=None, session=self.session, config=self.app_config, ) with pytest.raises(UserDoesNotExist): api.get_one_by_email('command_test@user') self.disconnect_database() app = TracimCLI() result = app.run([ 'user', 'create', '-c', 'tests_configs.ini#command_test', '-l', 'command_test@user', '-p', 'new_password', '--debug', ]) assert result == 0 self.connect_database() api = UserApi( current_user=None, session=self.session, config=self.app_config, ) new_user = api.get_one_by_email('command_test@user') assert new_user.email == 'command_test@user' assert new_user.validate_password('new_password') assert new_user.profile.name == 'users'
def test_func__user_create_command__ok__in_admin_group(self) -> None: """ Test User creation with admin as group """ api = UserApi(current_user=None, session=self.session, config=self.app_config) with pytest.raises(UserDoesNotExist): api.get_one_by_email("command_test@user") self.disconnect_database() app = TracimCLI() result = app.run([ "user", "create", "-c", "{}#command_test".format(TEST_CONFIG_FILE_PATH), "-l", "command_test@user", "-p", "new_password", "-g", "administrators", "--debug", ]) assert result == 0 self.connect_database() api = UserApi(current_user=None, session=self.session, config=self.app_config) new_user = api.get_one_by_email("command_test@user") assert new_user.email == "command_test@user" assert new_user.validate_password("new_password") assert new_user.profile.name == "administrators"
def test_func__user_update_command__ok__nominal_case(self) -> None: """ Test user password update """ api = UserApi( current_user=None, session=self.session, config=self.app_config, ) user = api.get_one_by_email('*****@*****.**') assert user.email == '*****@*****.**' assert user.validate_password('*****@*****.**') assert not user.validate_password('new_password') self.disconnect_database() app = TracimCLI() result = app.run([ 'user', 'update', '-c', 'tests_configs.ini#command_test', '-l', '*****@*****.**', '-p', 'new_password', '--debug', ]) assert result == 0 self.connect_database() api = UserApi( current_user=None, session=self.session, config=self.app_config, ) new_user = api.get_one_by_email('*****@*****.**') assert new_user.email == '*****@*****.**' assert new_user.validate_password('new_password') assert not new_user.validate_password('*****@*****.**')
def test_func__create_new_content_with_notification__ok__nominal_case(self): uapi = UserApi(current_user=None, session=self.session, config=self.app_config) current_user = uapi.get_one_by_email("*****@*****.**") # Create new user with notification enabled on w1 workspace wapi = WorkspaceApi(current_user=current_user, session=self.session, config=self.app_config) workspace = wapi.get_one_by_label("Recipes") user = uapi.get_one_by_email("*****@*****.**") wapi.enable_notifications(user, workspace) api = ContentApi(current_user=user, session=self.session, config=self.app_config) item = api.create( content_type_list.Folder.slug, workspace, None, "parent", do_save=True, do_notify=False ) api.create( content_type_list.File.slug, workspace, item, "file1", do_save=True, do_notify=True ) # Send mail async from redis queue with daemon daemon = MailSenderDaemon(self.app_config, burst=True) daemon.run() # check mail received response = self.get_mailhog_mails() headers = response[0]["Content"]["Headers"] assert headers["From"][0] == '"Bob i. via Tracim" <test_user_from+3@localhost>' assert headers["To"][0] == "Global manager <*****@*****.**>" assert headers["Subject"][0] == "[TRACIM] [Recipes] file1 (Open)" assert headers["References"][0] == "test_user_refs+22@localhost" assert ( headers["Reply-to"][0] == '"Bob i. & all members of Recipes" <test_user_reply+22@localhost>' )
def test_func__user_create_command__ok__nominal_case(self) -> None: """ Test User creation """ api = UserApi(current_user=None, session=self.session, config=self.app_config) with pytest.raises(UserDoesNotExist): api.get_one_by_email("command_test@user") self.disconnect_database() app = TracimCLI() result = app.run( [ "user", "create", "-c", "tests_configs.ini#command_test", "-l", "command_test@user", "-p", "new_password", "--debug", ] ) assert result == 0 self.connect_database() api = UserApi(current_user=None, session=self.session, config=self.app_config) new_user = api.get_one_by_email("command_test@user") assert new_user.email == "command_test@user" assert new_user.validate_password("new_password") assert new_user.profile.name == "users"
def test_func__user_update_command__ok__nominal_case(self) -> None: """ Test user password update """ api = UserApi(current_user=None, session=self.session, config=self.app_config) user = api.get_one_by_email("*****@*****.**") assert user.email == "*****@*****.**" assert user.validate_password("*****@*****.**") assert not user.validate_password("new_password") self.disconnect_database() app = TracimCLI() result = app.run([ "user", "update", "-c", "{}#command_test".format(TEST_CONFIG_FILE_PATH), "-l", "*****@*****.**", "-p", "new_password", "--debug", ]) assert result == 0 self.connect_database() api = UserApi(current_user=None, session=self.session, config=self.app_config) new_user = api.get_one_by_email("*****@*****.**") assert new_user.email == "*****@*****.**" assert new_user.validate_password("new_password") assert not new_user.validate_password("*****@*****.**")
def test_func__user_update_command__ok__remove_group(self) -> None: """ Test user password update """ api = UserApi(current_user=None, session=self.session, config=self.app_config) user = api.get_one_by_email("*****@*****.**") assert user.email == "*****@*****.**" assert user.validate_password("*****@*****.**") assert not user.validate_password("new_password") assert user.profile.name == "administrators" self.disconnect_database() app = TracimCLI() result = app.run( [ "user", "update", "-c", "tests_configs.ini#command_test", "-l", "*****@*****.**", "-p", "new_password", "-rmg", "administrators", "--debug", ] ) assert result == 0 self.connect_database() api = UserApi(current_user=None, session=self.session, config=self.app_config) new_user = api.get_one_by_email("*****@*****.**") assert new_user.email == "*****@*****.**" assert new_user.validate_password("new_password") assert not new_user.validate_password("*****@*****.**") assert new_user.profile.name == "trusted-users"
def test_unit__get_one_by_email__err__user_does_not_exist(self): api = UserApi( current_user=None, session=self.session, config=self.app_config, ) with pytest.raises(UserDoesNotExist): api.get_one_by_email('unknown')
def test_func__create_new_content_with_notification__ok__nominal_case( self): uapi = UserApi( current_user=None, session=self.session, config=self.app_config, ) current_user = uapi.get_one_by_email('*****@*****.**') # Create new user with notification enabled on w1 workspace wapi = WorkspaceApi( current_user=current_user, session=self.session, config=self.app_config, ) workspace = wapi.get_one_by_label('Recipes') user = uapi.get_one_by_email('*****@*****.**') wapi.enable_notifications(user, workspace) api = ContentApi( current_user=user, session=self.session, config=self.app_config, ) item = api.create( content_type_list.Folder.slug, workspace, None, 'parent', do_save=True, do_notify=False, ) item2 = api.create( content_type_list.File.slug, workspace, item, 'file1', do_save=True, do_notify=True, ) # Send mail async from redis queue redis = get_redis_connection(self.app_config) queue = get_rq_queue( redis, 'mail_sender', ) worker = SimpleWorker([queue], connection=queue.connection) worker.work(burst=True) # check mail received response = requests.get('http://127.0.0.1:8025/api/v1/messages') response = response.json() headers = response[0]['Content']['Headers'] assert headers['From'][ 0] == '"Bob i. via Tracim" <test_user_from+3@localhost>' # nopep8 assert headers['To'][0] == 'Global manager <*****@*****.**>' assert headers['Subject'][0] == '[TRACIM] [Recipes] file1 (Open)' assert headers['References'][0] == 'test_user_refs+22@localhost' assert headers['Reply-to'][ 0] == '"Bob i. & all members of Recipes" <test_user_reply+22@localhost>' # nopep8
def test_func__create_comment_with_notification__ok__nominal_case(self): uapi = UserApi( current_user=None, session=self.session, config=self.app_config, ) current_user = uapi.get_one_by_email('*****@*****.**') # set admin as french, useful to verify if i18n work properly current_user.lang = 'fr' # Create new user with notification enabled on w1 workspace wapi = WorkspaceApi( current_user=current_user, session=self.session, config=self.app_config, ) workspace = wapi.get_one_by_label('Recipes') user = uapi.get_one_by_email('*****@*****.**') wapi.enable_notifications(user, workspace) api = ContentApi( current_user=user, session=self.session, config=self.app_config, ) item = api.create( content_type_list.Folder.slug, workspace, None, 'parent', do_save=True, do_notify=False, ) item2 = api.create( content_type_list.File.slug, workspace, item, 'file1', do_save=True, do_notify=False, ) api.create_comment(parent=item2, content='My super comment', do_save=True, do_notify=True) transaction.commit() # check mail received response = requests.get('http://127.0.0.1:8025/api/v1/messages') response = response.json() headers = response[0]['Content']['Headers'] assert headers['From'][ 0] == '"Bob i. via Tracim" <test_user_from+3@localhost>' # nopep8 assert headers['To'][0] == 'Global manager <*****@*****.**>' assert headers['Subject'][0] == '[TRACIM] [Recipes] file1 (Open)' assert headers['References'][0] == 'test_user_refs+22@localhost' assert headers['Reply-to'][ 0] == '"Bob i. & all members of Recipes" <test_user_reply+22@localhost>' # nopep8
def test_func__create_new_content_with_notification__ok__nominal_case(self): uapi = UserApi( current_user=None, session=self.session, config=self.app_config, ) current_user = uapi.get_one_by_email('*****@*****.**') # Create new user with notification enabled on w1 workspace wapi = WorkspaceApi( current_user=current_user, session=self.session, config=self.app_config, ) workspace = wapi.get_one_by_label('Recipes') user = uapi.get_one_by_email('*****@*****.**') wapi.enable_notifications(user, workspace) api = ContentApi( current_user=user, session=self.session, config=self.app_config, ) item = api.create( content_type_list.Folder.slug, workspace, None, 'parent', do_save=True, do_notify=False, ) item2 = api.create( content_type_list.File.slug, workspace, item, 'file1', do_save=True, do_notify=True, ) # Send mail async from redis queue redis = get_redis_connection( self.app_config ) queue = get_rq_queue( redis, 'mail_sender', ) worker = SimpleWorker([queue], connection=queue.connection) worker.work(burst=True) # check mail received response = self.get_mailhog_mails() headers = response[0]['Content']['Headers'] assert headers['From'][0] == '"Bob i. via Tracim" <test_user_from+3@localhost>' # nopep8 assert headers['To'][0] == 'Global manager <*****@*****.**>' assert headers['Subject'][0] == '[TRACIM] [Recipes] file1 (Open)' assert headers['References'][0] == 'test_user_refs+22@localhost' assert headers['Reply-to'][0] == '"Bob i. & all members of Recipes" <test_user_reply+22@localhost>' # nopep8
def isRealmUser(self, realmname, username, environ): """ Called to check if for a given root, the username exists (though here we don't make difference between root as we're always starting at tracim's root """ api = UserApi(None, environ['tracim_dbsession'], self.app_config) try: api.get_one_by_email(username) return True except: return False
def isRealmUser(self, realmname: str, username: str, environ: typing.Dict[str, typing.Any]) -> bool: """ Called to check if for a given root, the username exists (though here we don't make difference between root as we're always starting at tracim's root """ session = environ['tracim_dbsession'] # type: Session api = UserApi(None, session, self.app_config) try: api.get_one_by_email(username) return True except: return False
def test_func__create_new_content_with_notification__ok__nominal_case( self): uapi = UserApi( current_user=None, session=self.session, config=self.app_config, ) current_user = uapi.get_one_by_email('*****@*****.**') # Create new user with notification enabled on w1 workspace wapi = WorkspaceApi( current_user=current_user, session=self.session, config=self.app_config, ) workspace = wapi.get_one_by_label('Recipes') user = uapi.get_one_by_email('*****@*****.**') wapi.enable_notifications(user, workspace) api = ContentApi( current_user=user, session=self.session, config=self.app_config, ) item = api.create( content_type_list.Folder.slug, workspace, None, 'parent', do_save=True, do_notify=False, ) item2 = api.create( content_type_list.File.slug, workspace, item, 'file1', do_save=True, do_notify=True, ) # Send mail async from redis queue with daemon daemon = MailSenderDaemon(self.app_config, burst=True) daemon.run() # check mail received response = self.get_mailhog_mails() headers = response[0]['Content']['Headers'] assert headers['From'][ 0] == '"Bob i. via Tracim" <test_user_from+3@localhost>' # nopep8 assert headers['To'][0] == 'Global manager <*****@*****.**>' assert headers['Subject'][0] == '[TRACIM] [Recipes] file1 (Open)' assert headers['References'][0] == 'test_user_refs+22@localhost' assert headers['Reply-to'][ 0] == '"Bob i. & all members of Recipes" <test_user_reply+22@localhost>' # nopep8
def test_func__create_comment_with_notification__ok__nominal_case(self): uapi = UserApi( current_user=None, session=self.session, config=self.app_config, ) current_user = uapi.get_one_by_email('*****@*****.**') # set admin as french, useful to verify if i18n work properly current_user.lang = 'fr' # Create new user with notification enabled on w1 workspace wapi = WorkspaceApi( current_user=current_user, session=self.session, config=self.app_config, ) workspace = wapi.get_one_by_label('Recipes') user = uapi.get_one_by_email('*****@*****.**') wapi.enable_notifications(user, workspace) api = ContentApi( current_user=user, session=self.session, config=self.app_config, ) item = api.create( content_type_list.Folder.slug, workspace, None, 'parent', do_save=True, do_notify=False, ) item2 = api.create( content_type_list.File.slug, workspace, item, 'file1', do_save=True, do_notify=False, ) api.create_comment(parent=item2, content='My super comment', do_save=True, do_notify=True) transaction.commit() # check mail received response = self.get_mailhog_mails() headers = response[0]['Content']['Headers'] assert headers['From'][0] == '"Bob i. via Tracim" <test_user_from+3@localhost>' # nopep8 assert headers['To'][0] == 'Global manager <*****@*****.**>' assert headers['Subject'][0] == '[TRACIM] [Recipes] file1 (Open)' assert headers['References'][0] == 'test_user_refs+22@localhost' assert headers['Reply-to'][0] == '"Bob i. & all members of Recipes" <test_user_reply+22@localhost>' # nopep8
def test_func__user_update_command__err_password_modification_failed__external_auth(self) -> None: """ Test user password update """ api = UserApi( current_user=None, session=self.session, config=self.app_config, ) user = api.get_one_by_email('*****@*****.**') assert user.email == '*****@*****.**' assert user.validate_password('*****@*****.**') assert not user.validate_password('new_password') user.auth_type = AuthType.LDAP assert user.auth_type == AuthType.LDAP self.session.add(user) self.session.flush() transaction.commit() self.disconnect_database() app = TracimCLI() with pytest.raises(ExternalAuthUserPasswordModificationDisallowed): result = app.run([ 'user', 'update', '-c', 'tests_configs.ini#command_test', '-l', '*****@*****.**', '-p', 'new_ldap_password', '--debug', ])
def test__init__db__ok_nominal_case(self): """ Test database initialisation """ api = UserApi(current_user=None, session=self.session, config=self.app_config) user = api.get_one_by_email("*****@*****.**") assert user.email == "*****@*****.**" assert user.validate_password("*****@*****.**") assert not user.validate_password("new_password") self.disconnect_database() app = TracimCLI() # delete config to be sure command will work app.run([ "db", "delete", "--force", "-c", "{}#command_test".format(TEST_CONFIG_FILE_PATH), "--debug", ]) result = app.run([ "db", "init", "-c", "{}#command_test".format(TEST_CONFIG_FILE_PATH), "--debug" ]) assert result == 0
def test_func__user_update_command__err_password_modification_failed__external_auth( self) -> None: """ Test user password update """ api = UserApi(current_user=None, session=self.session, config=self.app_config) user = api.get_one_by_email("*****@*****.**") assert user.email == "*****@*****.**" assert user.validate_password("*****@*****.**") assert not user.validate_password("new_password") user.auth_type = AuthType.LDAP assert user.auth_type == AuthType.LDAP self.session.add(user) self.session.flush() transaction.commit() self.disconnect_database() app = TracimCLI() with pytest.raises(ExternalAuthUserPasswordModificationDisallowed): app.run([ "user", "update", "-c", "{}#command_test".format(TEST_CONFIG_FILE_PATH), "-l", "*****@*****.**", "-p", "new_ldap_password", "--debug", ])
def test_func__reset_password__ok__nominal_case(self): uapi = UserApi( current_user=None, session=self.session, config=self.app_config, ) current_user = uapi.get_one_by_email('*****@*****.**') uapi.reset_password_notification(current_user, do_save=True) transaction.commit() # Send mail async from redis queue redis = get_redis_connection( self.app_config ) queue = get_rq_queue( redis, 'mail_sender', ) worker = SimpleWorker([queue], connection=queue.connection) worker.work(burst=True) # check mail received response = self.get_mailhog_mails() headers = response[0]['Content']['Headers'] assert headers['From'][0] == 'Tracim Notifications <test_user_from+0@localhost>' # nopep8 assert headers['To'][0] == 'Global manager <*****@*****.**>' assert headers['Subject'][0] == '[TRACIM] A password reset has been requested'
def test_func__reset_password__ok__nominal_case(self): uapi = UserApi( current_user=None, session=self.session, config=self.app_config, ) current_user = uapi.get_one_by_email('*****@*****.**') uapi.reset_password_notification(current_user, do_save=True) transaction.commit() # Send mail async from redis queue redis = get_redis_connection(self.app_config) queue = get_rq_queue( redis, 'mail_sender', ) worker = SimpleWorker([queue], connection=queue.connection) worker.work(burst=True) # check mail received response = requests.get('http://127.0.0.1:8025/api/v1/messages') response = response.json() headers = response[0]['Content']['Headers'] assert headers['From'][ 0] == 'Tracim Notifications <test_user_from+0@localhost>' # nopep8 assert headers['To'][0] == 'Global manager <*****@*****.**>' assert headers['Subject'][0] == '[TRACIM] Reset Password Request'
def _get_user(self, user_email: typing.Callable): user_email = user_email() uapi = UserApi(None, show_deleted=True, session=self.dbsession, config=self.app_config) return uapi.get_one_by_email(user_email)
def test__init__db__ok_nominal_case(self): """ Test database initialisation """ api = UserApi( current_user=None, session=self.session, config=self.app_config, ) user = api.get_one_by_email('*****@*****.**') assert user.email == '*****@*****.**' assert user.validate_password('*****@*****.**') assert not user.validate_password('new_password') self.disconnect_database() app = TracimCLI() # delete config to be sure command will work app.run([ 'db', 'delete', '--force', '-c', 'tests_configs.ini#command_test', '--debug', ]) result = app.run([ 'db', 'init', '-c', 'tests_configs.ini#command_test', '--debug', ]) assert result == 0
def test__delete__db__err_no_config_file(self): """ Test database deletion """ api = UserApi( current_user=None, session=self.session, config=self.app_config, ) user = api.get_one_by_email('*****@*****.**') assert user.email == '*****@*****.**' assert user.validate_password('*****@*****.**') assert not user.validate_password('new_password') self.disconnect_database() app = TracimCLI() with pytest.raises(FileNotFoundError): app.run([ 'db', 'delete', '-c', 'donotexit.ini#command_test', '--debug', ]) result = app.run([ 'db', 'delete', '-c', 'donotexist.ini#command_test', ]) assert result == 1
def test__delete__db__err_no_sqlalchemy_url(self): """ Test database deletion """ api = UserApi( current_user=None, session=self.session, config=self.app_config, ) user = api.get_one_by_email('*****@*****.**') assert user.email == '*****@*****.**' assert user.validate_password('*****@*****.**') assert not user.validate_password('new_password') self.disconnect_database() app = TracimCLI() with pytest.raises(InvalidSettingFile): app.run([ 'db', 'delete', '-c', 'tests_configs.ini#command_test_no_sqlalchemy_url', '--debug', ]) result = app.run([ 'db', 'delete', '-c', 'tests_configs.ini#command_test_no_sqlalchemy_url', ]) assert result == 1
def isRealmUser( self, realmname: str, username: str, environ: typing.Dict[str, typing.Any] ) -> bool: """ Called to check if for a given root, the username exists (though here we don't make difference between root as we're always starting at tracim's root """ session = environ["tracim_dbsession"] # type: Session api = UserApi(None, session, self.app_config) try: api.get_one_by_email(username) return True # TODO - G.M - 2019-04-25 - do better exception handling here, # see https://github.com/tracim/tracim/issues/1636 except Exception: return False
def authDomainUser(self, realmname, username, password, environ): """ If you ever feel the need to send a request al-mano with a curl, this is the function that'll be called by http_authenticator to validate the password sent """ api = UserApi(None, environ['tracim_dbsession'], self.app_config) return self.isRealmUser(realmname, username, environ) and \ api.get_one_by_email(username).validate_password(password)
def test_unit__create_minimal_user_and_update__ok__nominal_case(self): api = UserApi(current_user=None, session=self.session, config=self.app_config) u = api.create_minimal_user("bob@bob") api.update(u, "bob", "bob@bob", "password", do_save=True) nu = api.get_one_by_email("bob@bob") assert nu is not None assert nu.email == "bob@bob" assert nu.display_name == "bob" assert nu.validate_password("password")
def test_get_one_by_email(self): api = UserApi(current_user=None, session=self.session, config=self.app_config) u = api.create_minimal_user("bibi@bibi") self.session.flush() api.update(u, "bibi", "bibi@bibi", "password", do_save=True) uid = u.user_id transaction.commit() eq_(uid, api.get_one_by_email("bibi@bibi").user_id)
def _get_user(self, user_email: typing.Callable): user_email = user_email() uapi = UserApi( None, show_deleted=True, session=self.dbsession, config=self.app_config ) return uapi.get_one_by_email(user_email)
def test_unit__create_minimal_user_and_update__ok__nominal_case(self): api = UserApi( current_user=None, session=self.session, config=self.config, ) u = api.create_minimal_user('bob@bob') api.update(u, 'bob', 'bob@bob', 'pass', do_save=True) nu = api.get_one_by_email('bob@bob') assert nu is not None assert nu.email == 'bob@bob' assert nu.display_name == 'bob' assert nu.validate_password('pass')
def test_get_one_by_email(self): api = UserApi( current_user=None, session=self.session, config=self.config, ) u = api.create_minimal_user('bibi@bibi') self.session.flush() api.update(u, 'bibi', 'bibi@bibi', 'pass', do_save=True) uid = u.user_id transaction.commit() eq_(uid, api.get_one_by_email('bibi@bibi').user_id)
def reset_password_request(self, context, request: TracimRequest, hapic_data=None): """ Send a request to reset password. This will result in a new email sent to the user with a token to be used for password reset operation. """ app_config = request.registry.settings["CFG"] # type: CFG uapi = UserApi(None, session=request.dbsession, config=app_config) user = uapi.get_one_by_email(hapic_data.body.email) uapi.reset_password_notification(user, do_save=True) return
def test_unit__create_minimal_user_and_update__ok__nominal_case(self): api = UserApi( current_user=None, session=self.session, config=self.app_config, ) u = api.create_minimal_user('bob@bob') api.update(u, 'bob', 'bob@bob', 'password', do_save=True) nu = api.get_one_by_email('bob@bob') assert nu is not None assert nu.email == 'bob@bob' assert nu.display_name == 'bob' assert nu.validate_password('password')
def test__init__db__ok_db_already_exist(self): """ Test database initialisation """ api = UserApi(current_user=None, session=self.session, config=self.app_config) user = api.get_one_by_email("*****@*****.**") assert user.email == "*****@*****.**" assert user.validate_password("*****@*****.**") assert not user.validate_password("new_password") self.disconnect_database() app = TracimCLI() with pytest.raises(DatabaseInitializationFailed): app.run(["db", "init", "-c", "tests_configs.ini#command_test", "--debug"])
def test_get_one_by_email(self): api = UserApi( current_user=None, session=self.session, config=self.app_config, ) u = api.create_minimal_user('bibi@bibi') self.session.flush() api.update(u, 'bibi', 'bibi@bibi', 'password', do_save=True) uid = u.user_id transaction.commit() eq_(uid, api.get_one_by_email('bibi@bibi').user_id)
def test_api__reset_password_check_token__ok_204__unknown_auth(self): # create new user without auth (default is unknown) self.testapp.authorization = ( 'Basic', ( '*****@*****.**', '*****@*****.**' ) ) params = { 'email': '*****@*****.**', 'password': '******', 'profile': 'users', 'timezone': 'Europe/Paris', 'lang': 'fr', 'public_name': 'test user', 'email_notification': False, } res = self.testapp.post_json( '/api/v2/users', status=200, params=params, ) res = res.json_body assert res['user_id'] user_id = res['user_id'] # make a check of token self.testapp.authorization = None dbsession = get_tm_session(self.session_factory, transaction.manager) admin = dbsession.query(User) \ .filter(User.email == '*****@*****.**') \ .one() uapi = UserApi( current_user=admin, session=dbsession, config=self.app_config, ) user = uapi.get_one_by_email('*****@*****.**') reset_password_token = uapi.reset_password_notification(user, do_save=True) # nopep8 transaction.commit() params = { 'email': '*****@*****.**', 'reset_password_token': reset_password_token } self.testapp.post_json( '/api/v2/auth/password/reset/token/check', status=204, params=params, )
def reset_password_check_token(self, context, request: TracimRequest, hapic_data=None): # nopep8 """ Check reset_password token. The token sent by email has a limited life duration, this API allow to check that the token is existing and still valid. """ app_config = request.registry.settings['CFG'] uapi = UserApi( None, session=request.dbsession, config=app_config, ) user = uapi.get_one_by_email(hapic_data.body.email) uapi.validate_reset_password_token(user, hapic_data.body.reset_password_token) # nopep8 return
def reset_password_request(self, context, request: TracimRequest, hapic_data=None): # nopep8 """ Send a request to reset password. This will result in a new email sent to the user with a token to be used for password reset operation. """ app_config = request.registry.settings['CFG'] uapi = UserApi( None, session=request.dbsession, config=app_config, ) user = uapi.get_one_by_email(hapic_data.body.email) uapi.reset_password_notification(user, do_save=True) return
def test_func__reset_password__ok__nominal_case(self): uapi = UserApi( current_user=None, session=self.session, config=self.app_config, ) current_user = uapi.get_one_by_email('*****@*****.**') uapi.reset_password_notification(current_user, do_save=True) transaction.commit() # check mail received response = self.get_mailhog_mails() headers = response[0]['Content']['Headers'] assert headers['From'][0] == 'Tracim Notifications <test_user_from+0@localhost>' # nopep8 assert headers['To'][0] == 'Global manager <*****@*****.**>' assert headers['Subject'][0] == '[TRACIM] A password reset has been requested'
def reset_password_modify(self, context, request: TracimRequest, hapic_data=None): # nopep8 """ Do change the password. This requires the token received by email. After this request returns a 200, the user password is effectively changed """ app_config = request.registry.settings['CFG'] uapi = UserApi( None, session=request.dbsession, config=app_config, ) user = uapi.get_one_by_email(hapic_data.body.email) uapi.set_password_reset_token( new_password=hapic_data.body.new_password, new_password2=hapic_data.body.new_password2, reset_token=hapic_data.body.reset_password_token, user=user, do_save=True ) return
class UserCommand(AppContextCommand): ACTION_CREATE = 'create' ACTION_UPDATE = 'update' action = NotImplemented def get_description(self) -> str: return '''Create or update user.''' def get_parser(self, prog_name: str) -> argparse.ArgumentParser: parser = super().get_parser(prog_name) parser.add_argument( "-l", "--login", help='User login (email)', dest='login', required=True ) parser.add_argument( "-p", "--password", help='User password', dest='password', required=False, default=None ) parser.add_argument( "-g", "--add-to-group", help='Add user to group', dest='add_to_group', nargs='*', action=Extender, default=[], ) parser.add_argument( "-rmg", "--remove-from-group", help='Remove user from group', dest='remove_from_group', nargs='*', action=Extender, default=[], ) parser.add_argument( "--send-email", help='Send mail to user', dest='send_email', required=False, action='store_true', default=False, ) return parser def _user_exist(self, login: str) -> User: return self._user_api.user_with_email_exists(login) def _get_group(self, name: str) -> Group: groups_availables = [group.group_name for group in self._group_api.get_all()] if name not in groups_availables: msg = "Group '{}' does not exist, choose a group name in : ".format(name) # nopep8 for group in groups_availables: msg+= "'{}',".format(group) self._session.rollback() raise GroupDoesNotExist(msg) return self._group_api.get_one_with_name(name) def _add_user_to_named_group( self, user: str, group_name: str ) -> None: group = self._get_group(group_name) if user not in group.users: group.users.append(user) self._session.flush() def _remove_user_from_named_group( self, user: User, group_name: str ) -> None: group = self._get_group(group_name) if user in group.users: group.users.remove(user) self._session.flush() def _create_user( self, login: str, password: str, do_notify: bool, **kwargs ) -> User: if not password: if self._password_required(): raise BadCommandError( "You must provide -p/--password parameter" ) password = '' if self._user_api.check_email_already_in_db(login): raise UserAlreadyExistError() try: user = self._user_api.create_user( email=login, password=password, do_save=True, do_notify=do_notify, ) # TODO - G.M - 04-04-2018 - [Caldav] Check this code # # We need to enable radicale if it not already done # daemons = DaemonsManager() # daemons.run('radicale', RadicaleDaemon) self._user_api.execute_created_user_actions(user) except IntegrityError as exception: self._session.rollback() raise UserAlreadyExistError() from exception except (NotificationSendingFailed, NotificationDisabledCantCreateUserWithInvitation) as exception: self._session.rollback() raise exception from exception return user def _update_password_for_login(self, login: str, password: str) -> None: user = self._user_api.get_one_by_email(login) self._user_api._check_password_modification_allowed(user) user.password = password self._session.flush() transaction.commit() def take_app_action( self, parsed_args: argparse.Namespace, app_context: AppEnvironment ) -> None: # TODO - G.M - 05-04-2018 -Refactor this in order # to not setup object var outside of __init__ . self._session = app_context['request'].dbsession self._app_config = app_context['registry'].settings['CFG'] self._user_api = UserApi( current_user=None, session=self._session, config=self._app_config, ) self._group_api = GroupApi( current_user=None, session=self._session, config=self._app_config, ) user = self._proceed_user(parsed_args) self._proceed_groups(user, parsed_args) print("User created/updated") def _proceed_user(self, parsed_args: argparse.Namespace) -> User: self._check_context(parsed_args) if self.action == self.ACTION_CREATE: try: user = self._create_user( login=parsed_args.login, password=parsed_args.password, do_notify=parsed_args.send_email, ) except UserAlreadyExistError as exc: raise UserAlreadyExistError("Error: User already exist (use `user update` command instead)") from exc # nopep8 except NotificationSendingFailed as exc: raise NotificationSendingFailed("Error: Cannot send email notification due to error, user not created.") from exc # nopep8 except NotificationDisabledCantCreateUserWithInvitation as exc: raise NotificationDisabledCantCreateUserWithInvitation("Error: Email notification disabled but notification required, user not created.") from exc # nopep8 else: if parsed_args.password: self._update_password_for_login( login=parsed_args.login, password=parsed_args.password ) user = self._user_api.get_one_by_email(parsed_args.login) return user def _proceed_groups( self, user: User, parsed_args: argparse.Namespace ) -> None: # User always in "users" group self._add_user_to_named_group(user, 'users') for group_name in parsed_args.add_to_group: self._add_user_to_named_group(user, group_name) for group_name in parsed_args.remove_from_group: self._remove_user_from_named_group(user, group_name) def _password_required(self) -> bool: # TODO - G.M - 04-04-2018 - [LDAP] Check this code # if config.get('auth_type') == LDAPAuth.name: # return False return True def _check_context(self, parsed_args: argparse.Namespace) -> None: # TODO - G.M - 04-04-2018 - [LDAP] Check this code # if config.get('auth_type') == LDAPAuth.name: # auth_instance = config.get('auth_instance') # if not auth_instance.ldap_auth.user_exist(parsed_args.login): # raise LDAPUserUnknown( # "LDAP is enabled and user with login/email \"%s\" not found in LDAP" % parsed_args.login # ) pass