From 4bafc95ee132e148f6ab7c51c38507a34dca1429 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gu=C3=A9na=C3=ABl=20Muller?= Date: Mon, 21 May 2018 12:13:04 +0200 Subject: [PATCH 01/12] better runner, use wsgidav.config_file param instead of env var --- tracim/command/webdav.py | 6 ++---- tracim/lib/webdav/__init__.py | 21 ++++++++------------- wsgi/__init__.py | 16 ++++++++++++++++ wsgi/web.py | 6 ++---- wsgi/webdav.py | 10 +++------- 5 files changed, 31 insertions(+), 28 deletions(-) create mode 100644 wsgi/__init__.py diff --git a/tracim/command/webdav.py b/tracim/command/webdav.py index b060158..9943373 100644 --- a/tracim/command/webdav.py +++ b/tracim/command/webdav.py @@ -6,6 +6,7 @@ from tracim.command import AppContextCommand from tracim.lib.webdav import WebdavAppFactory +from wsgi import webdav_app class WebdavRunnerCommand(AppContextCommand): @@ -22,8 +23,5 @@ def take_action(self, parsed_args: argparse.Namespace) -> None: super(WebdavRunnerCommand, self).take_action(parsed_args) tracim_config = parsed_args.config_file # TODO - G.M - 16-04-2018 - Allow specific webdav config file - app_factory = WebdavAppFactory( - tracim_config_file_path=tracim_config, - ) - app = app_factory.get_wsgi_app() + app = webdav_app(tracim_config) serve(app, port=app.config['port'], host=app.config['host']) diff --git a/tracim/lib/webdav/__init__.py b/tracim/lib/webdav/__init__.py index b467f6c..5fdc296 100644 --- a/tracim/lib/webdav/__init__.py +++ b/tracim/lib/webdav/__init__.py @@ -27,22 +27,17 @@ class WebdavAppFactory(object): def __init__(self, - webdav_config_file_path: str = None, tracim_config_file_path: str = None, ): self.config = self._initConfig( - webdav_config_file_path, tracim_config_file_path ) def _initConfig(self, - webdav_config_file_path: str = None, tracim_config_file_path: str = None ): """Setup configuration dictionary from default, command line and configuration file.""" - if not webdav_config_file_path: - webdav_config_file_path = DEFAULT_WEBDAV_CONFIG_FILE if not tracim_config_file_path: tracim_config_file_path = DEFAULT_TRACIM_CONFIG_FILE @@ -50,20 +45,20 @@ def _initConfig(self, config = DEFAULT_CONFIG.copy() temp_verbose = config["verbose"] - default_config_file = os.path.abspath(webdav_config_file_path) - webdav_config_file = self._readConfigFile( - webdav_config_file_path, - temp_verbose - ) - # Configuration file overrides defaults - config.update(webdav_config_file) - # Get pyramid Env tracim_config_file_path = os.path.abspath(tracim_config_file_path) config['tracim_config'] = tracim_config_file_path settings = get_appsettings(config['tracim_config']) app_config = CFG(settings) + default_config_file = os.path.abspath(settings['wsgidav.config_path']) + webdav_config_file = self._readConfigFile( + default_config_file, + temp_verbose + ) + # Configuration file overrides defaults + config.update(webdav_config_file) + if not useLxml and config["verbose"] >= 1: print( "WARNING: Could not import lxml: using xml instead (slower). " diff --git a/wsgi/__init__.py b/wsgi/__init__.py new file mode 100644 index 0000000..5ceafde --- /dev/null +++ b/wsgi/__init__.py @@ -0,0 +1,16 @@ +# coding=utf-8 +import pyramid.paster + +from tracim.lib.webdav import WebdavAppFactory + + +def web_app(config_uri): + pyramid.paster.setup_logging(config_uri) + return pyramid.paster.get_app(config_uri) + + +def webdav_app(config_uri): + app_factory = WebdavAppFactory( + tracim_config_file_path=config_uri, + ) + return app_factory.get_wsgi_app() diff --git a/wsgi/web.py b/wsgi/web.py index 34f45a6..5a5f01a 100644 --- a/wsgi/web.py +++ b/wsgi/web.py @@ -1,9 +1,7 @@ # coding=utf-8 # Runner for uwsgi import os -import pyramid.paster +from wsgi import web_app config_uri = os.environ['TRACIM_CONF_PATH'] - -pyramid.paster.setup_logging(config_uri) -application = pyramid.paster.get_app(config_uri) +application = web_app(config_uri) diff --git a/wsgi/webdav.py b/wsgi/webdav.py index 5dd2d1b..8345a3b 100644 --- a/wsgi/webdav.py +++ b/wsgi/webdav.py @@ -1,12 +1,8 @@ # coding=utf-8 # Runner for uwsgi -from tracim.lib.webdav import WebdavAppFactory import os +from wsgi import webdav_app + config_uri = os.environ['TRACIM_CONF_PATH'] -webdav_config_uri = os.environ['TRACIM_WEBDAV_CONF_PATH'] -app_factory = WebdavAppFactory( - tracim_config_file_path=config_uri, - webdav_config_file_path=webdav_config_uri, -) -application = app_factory.get_wsgi_app() +application = webdav_app(config_uri) From 40aa6035b127b82a5bf61704c73f0a4cc1c5dbd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gu=C3=A9na=C3=ABl=20Muller?= Date: Mon, 21 May 2018 15:40:31 +0200 Subject: [PATCH 02/12] convert webdav as plaster pastedeploy app --- development.ini.sample | 10 +++++++++- setup.py | 3 ++- tracim/__init__.py | 14 +++++++++++++- tracim/lib/webdav/__init__.py | 5 ++++- tracim/lib/webdav/middlewares.py | 5 ++++- wsgi/__init__.py | 9 +++++---- wsgi/webdav.py | 1 - 7 files changed, 37 insertions(+), 10 deletions(-) diff --git a/development.ini.sample b/development.ini.sample index 200eed0..539924f 100644 --- a/development.ini.sample +++ b/development.ini.sample @@ -2,7 +2,9 @@ # app configuration # https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html ### -[app:main] +[pipeline:main] +pipeline = tracim_web +[app:tracim_web] use = egg:tracim_backend pyramid.reload_templates = true @@ -13,6 +15,12 @@ pyramid.default_locale_name = en pyramid.includes = pyramid_debugtoolbar +[pipeline:webdav] +pipeline = tracim_webdav +[app:tracim_webdav] +use = egg:tracim_backend#webdav + +[DEFAULT] sqlalchemy.url = sqlite:///%(here)s/tracim.sqlite retry.attempts = 3 diff --git a/setup.py b/setup.py index 3f8df60..464f49c 100644 --- a/setup.py +++ b/setup.py @@ -89,7 +89,8 @@ install_requires=requires, entry_points={ 'paste.app_factory': [ - 'main = tracim:main', + 'main = tracim:web', + 'webdav = tracim:webdav' ], 'console_scripts': [ 'tracimcli = tracim.command:main', diff --git a/tracim/__init__.py b/tracim/__init__.py index 366c80e..cb2f3d2 100644 --- a/tracim/__init__.py +++ b/tracim/__init__.py @@ -13,15 +13,18 @@ from tracim.lib.utils.authentification import BASIC_AUTH_WEBUI_REALM from tracim.lib.utils.authorization import AcceptAllAuthorizationPolicy from tracim.lib.utils.authorization import TRACIM_DEFAULT_PERM +from tracim.lib.webdav import WebdavAppFactory from tracim.views import BASE_API_V2 from tracim.views.core_api.session_controller import SessionController from tracim.views.errors import ErrorSchema from tracim.lib.utils.cors import add_cors_support -def main(global_config, **settings): +def web(global_config, **local_settings): """ This function returns a Pyramid WSGI application. """ + settings = global_config + settings.update(local_settings) # set CFG object app_config = CFG(settings) app_config.configure_filedepot() @@ -64,3 +67,12 @@ def main(global_config, **settings): 'API of Tracim v2', ) return configurator.make_wsgi_app() + + +def webdav(global_config, **local_settings): + settings = global_config + settings.update(local_settings) + app_factory = WebdavAppFactory( + tracim_config_file_path=settings['__file__'], + ) + return app_factory.get_wsgi_app() diff --git a/tracim/lib/webdav/__init__.py b/tracim/lib/webdav/__init__.py index 5fdc296..8229eb8 100644 --- a/tracim/lib/webdav/__init__.py +++ b/tracim/lib/webdav/__init__.py @@ -48,7 +48,10 @@ def _initConfig(self, # Get pyramid Env tracim_config_file_path = os.path.abspath(tracim_config_file_path) config['tracim_config'] = tracim_config_file_path - settings = get_appsettings(config['tracim_config']) + global_conf = get_appsettings(config['tracim_config']).global_conf + local_conf = get_appsettings(config['tracim_config'], 'tracim_web') + settings = global_conf + settings.update(local_conf) app_config = CFG(settings) default_config_file = os.path.abspath(settings['wsgidav.config_path']) diff --git a/tracim/lib/webdav/middlewares.py b/tracim/lib/webdav/middlewares.py index 5e14289..bd6b60a 100644 --- a/tracim/lib/webdav/middlewares.py +++ b/tracim/lib/webdav/middlewares.py @@ -256,7 +256,10 @@ def __init__(self, application, config): super().__init__(application, config) self._application = application self._config = config - self.settings = get_appsettings(config['tracim_config']) + global_conf = get_appsettings(config['tracim_config']).global_conf + local_conf = get_appsettings(config['tracim_config'], 'tracim_web') + self.settings = global_conf + self.settings.update(local_conf) self.engine = get_engine(self.settings) self.session_factory = get_session_factory(self.engine) self.app_config = CFG(self.settings) diff --git a/wsgi/__init__.py b/wsgi/__init__.py index 5ceafde..03e4132 100644 --- a/wsgi/__init__.py +++ b/wsgi/__init__.py @@ -1,4 +1,5 @@ # coding=utf-8 +import plaster import pyramid.paster from tracim.lib.webdav import WebdavAppFactory @@ -10,7 +11,7 @@ def web_app(config_uri): def webdav_app(config_uri): - app_factory = WebdavAppFactory( - tracim_config_file_path=config_uri, - ) - return app_factory.get_wsgi_app() + config_uri = '{}#webdav'.format(config_uri) + plaster.setup_logging(config_uri) + loader = plaster.get_loader(config_uri, protocols=['wsgi']) + return loader.get_wsgi_app() diff --git a/wsgi/webdav.py b/wsgi/webdav.py index 8345a3b..f53e71a 100644 --- a/wsgi/webdav.py +++ b/wsgi/webdav.py @@ -1,7 +1,6 @@ # coding=utf-8 # Runner for uwsgi import os - from wsgi import webdav_app config_uri = os.environ['TRACIM_CONF_PATH'] From 6941b046575d60ab87a0e82c8b8239fbb5d705e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gu=C3=A9na=C3=ABl=20Muller?= Date: Thu, 24 May 2018 11:13:57 +0200 Subject: [PATCH 03/12] fix renaming of main function --- tracim/tests/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tracim/tests/__init__.py b/tracim/tests/__init__.py index c7d6d0a..dd597d7 100644 --- a/tracim/tests/__init__.py +++ b/tracim/tests/__init__.py @@ -17,7 +17,7 @@ from tracim.fixtures.users_and_groups import Base as BaseFixture from tracim.config import CFG from tracim.extensions import hapic -from tracim import main +from tracim import web from webtest import TestApp @@ -42,7 +42,7 @@ def setUp(self): } hapic.reset_context() - app = main({}, **settings) + app = web({}, **settings) self.init_database(settings) self.testapp = TestApp(app) From a701fd817d66895ed9ac00b69a2c687edae5eefa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gu=C3=A9na=C3=ABl=20Muller?= Date: Thu, 24 May 2018 12:14:32 +0200 Subject: [PATCH 04/12] add tests for user, permission and controller models --- tracim/tests/models/test_controller.py | 16 ++++ tracim/tests/models/test_permission.py | 51 ++++++++++++ tracim/tests/models/test_user.py | 103 ++++++++++++++++++++++--- 3 files changed, 159 insertions(+), 11 deletions(-) create mode 100644 tracim/tests/models/test_controller.py create mode 100644 tracim/tests/models/test_permission.py diff --git a/tracim/tests/models/test_controller.py b/tracim/tests/models/test_controller.py new file mode 100644 index 0000000..379ce09 --- /dev/null +++ b/tracim/tests/models/test_controller.py @@ -0,0 +1,16 @@ +# coding=utf-8 +import pytest +from pyramid.config import Configurator + +from tracim.views.controllers import Controller + + +class TestControllerModel(object): + """ + Test for Controller object + """ + def test_unit__bind__err__not_implemented(self): + controller = Controller() + configurator = Configurator() + with pytest.raises(NotImplementedError): + controller.bind(configurator) diff --git a/tracim/tests/models/test_permission.py b/tracim/tests/models/test_permission.py new file mode 100644 index 0000000..9af83ec --- /dev/null +++ b/tracim/tests/models/test_permission.py @@ -0,0 +1,51 @@ +# coding=utf-8 +import transaction +from tracim.tests import eq_ +from tracim.tests import BaseTest +from tracim.models.auth import Permission + + +class TestPermissionModel(BaseTest): + """ + Test for permission model + """ + def test_unit__create__ok__nominal_case(self): + self.session.flush() + transaction.commit() + + name = 'my_permission' + description = 'my_perm_description' + permission = Permission() + permission.permission_name = name + permission.description = description + + self.session.add(permission) + self.session.flush() + transaction.commit() + + new_permission = self.session.query(Permission).filter(permission.permission_name == name).one() # nopep8 + + assert new_permission.permission_name == name + assert new_permission.description == description + assert new_permission.permission_id + assert isinstance(new_permission.permission_id, int) + # TODO - G.M -24-05-2018 - Do test for groups + + def test_unit__repr__ok__nominal_case(self): + name = 'my_permission' + description = 'my_perm_description' + permission = Permission() + permission.permission_name = name + permission.description = description + + assert permission.__repr__() == "" + + def test_unit__unicode__ok__nominal_case(self): + name = 'my_permission' + description = 'my_perm_description' + permission = Permission() + permission.permission_name = name + permission.description = description + + assert permission.__unicode__() == name + diff --git a/tracim/tests/models/test_user.py b/tracim/tests/models/test_user.py index 203da70..1e9b080 100644 --- a/tracim/tests/models/test_user.py +++ b/tracim/tests/models/test_user.py @@ -1,15 +1,15 @@ # -*- coding: utf-8 -*- -import transaction -from tracim.tests import eq_ +import transaction from tracim.tests import BaseTest - from tracim.models.auth import User class TestUserModel(BaseTest): - - def test_create(self): + """ + Test for User model + """ + def test_unit__create__ok__nominal_case(self): self.session.flush() transaction.commit() name = 'Damien' @@ -23,13 +23,49 @@ def test_create(self): self.session.flush() transaction.commit() - new_user = self.session.query(User).filter(User.display_name==name).one() + new_user = self.session.query(User).filter(User.display_name == name).one() # nopep8 + + assert new_user.display_name == name + assert new_user.email == email + assert new_user.email_address == email + + def test_unit__password__ok__nominal_case(self): + """ + Check if password can be set and hashed password + can be retrieve. Verify if hashed password is not + same as password. + """ + name = 'Damien' + email = 'tracim@trac.im' + password = 'my_secure_password' + + user = User() + user.display_name = name + user.email = email + assert user._password is None + user.password = password + assert user._password is not None + assert user._password != password + assert user.password == user._password + + def test__unit__validate_password__ok__nominal_case(self): + """ + Check if validate_password can correctly check if password i the correct + one + """ - eq_(new_user.display_name, name) - eq_(new_user.email, email) - eq_(new_user.email_address, email) + name = 'Damien' + email = 'tracim@trac.im' + password = 'my_secure_password' + + user = User() + user.display_name = name + user.email = email + user.password = password + + assert user.validate_password(password) is True - def test_null_password(self): + def test_unit__validate_password__false__null_password(self): # Check bug #70 fixed # http://tracim.org/workspaces/4/folders/5/threads/70 @@ -40,4 +76,49 @@ def test_null_password(self): user.display_name = name user.email = email - eq_(False, user.validate_password(None)) + assert user.validate_password('') is False + + def test_unit__validate_password__false__bad_password(self): + """ + Check if validate_password can correctly check if password is + an uncorrect correct one + """ + name = 'Damien' + email = 'tracim@trac.im' + password = 'my_secure_password' + + user = User() + user.display_name = name + user.email = email + user.password = password + + assert user.validate_password('uncorrect_password') is False + + def test_unit__repr__ok__nominal_case(self): + name = 'Damien' + email = 'tracim@trac.im' + + user = User() + user.display_name = name + user.email = email + + assert user.__repr__() == "" # nopep8 + + def test_unit__unicode__ok__nominal_case(self): + name = 'Damien' + email = 'tracim@trac.im' + + user = User() + user.display_name = name + user.email = email + + assert user.__unicode__() == name + + def test__unit__unicode__ok__no_display_name(self): + + email = 'tracim@trac.im' + + user = User() + user.email = email + + assert user.__unicode__() == email \ No newline at end of file From f32874ffca5ede7a416ca1c0bfdc940d87f7ef15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gu=C3=A9na=C3=ABl=20Muller?= Date: Thu, 24 May 2018 16:52:25 +0200 Subject: [PATCH 05/12] add better test for commandes --- tests_configs.ini | 8 +++ tracim/tests/__init__.py | 22 +++++--- tracim/tests/commands/test_commands.py | 69 +++++++++++++++++++++++++- 3 files changed, 90 insertions(+), 9 deletions(-) diff --git a/tests_configs.ini b/tests_configs.ini index 4c2b2ce..41e1390 100644 --- a/tests_configs.ini +++ b/tests_configs.ini @@ -5,6 +5,14 @@ depot_storage_dir = /tmp/test/depot user.auth_token.validity = 604800 preview_cache_dir = /tmp/test/preview_cache +[app:command_test] +use = egg:tracim_backend +sqlalchemy.url = sqlite:///tracim_test.sqlite +depot_storage_name = test +depot_storage_dir = /tmp/test/depot +user.auth_token.validity = 604800 +preview_cache_dir = /tmp/test/preview_cache + [mail_test] sqlalchemy.url = sqlite:///:memory: depot_storage_name = test diff --git a/tracim/tests/__init__.py b/tracim/tests/__init__.py index 5694b52..678631d 100644 --- a/tracim/tests/__init__.py +++ b/tracim/tests/__init__.py @@ -36,7 +36,7 @@ class FunctionalTest(unittest.TestCase): def setUp(self): DepotManager._clear() - settings = { + self.settings = { 'sqlalchemy.url': self.sqlalchemy_url, 'user.auth_token.validity': '604800', 'depot_storage_dir': '/tmp/test/depot', @@ -45,19 +45,22 @@ def setUp(self): } hapic.reset_context() - app = main({}, **settings) - self.init_database(settings) + self.init_database(self.settings) + self.run_app() + + def run_app(self): + app = main({}, **self.settings) self.testapp = TestApp(app) def init_database(self, settings): self.engine = get_engine(settings) DeclarativeBase.metadata.create_all(self.engine) - session_factory = get_session_factory(self.engine) - app_config = CFG(settings) + self.session_factory = get_session_factory(self.engine) + self.app_config = CFG(settings) with transaction.manager: - dbsession = get_tm_session(session_factory, transaction.manager) + dbsession = get_tm_session(self.session_factory, transaction.manager) try: - fixtures_loader = FixturesLoader(dbsession, app_config) + fixtures_loader = FixturesLoader(dbsession, self.app_config) fixtures_loader.loads(self.fixtures) transaction.commit() print("Database initialized.") @@ -90,6 +93,11 @@ def init_database(self, settings): self.engine = get_engine(settings) +class CommandFunctionalTest(FunctionalTest): + + def run_app(self): + self.session = get_tm_session(self.session_factory, transaction.manager) + class BaseTest(unittest.TestCase): """ Pyramid default test. diff --git a/tracim/tests/commands/test_commands.py b/tracim/tests/commands/test_commands.py index e672746..0cb3e70 100644 --- a/tracim/tests/commands/test_commands.py +++ b/tracim/tests/commands/test_commands.py @@ -2,11 +2,27 @@ import os import subprocess +import pytest +import transaction +from pkg_resources import load_entry_point +from sqlalchemy.orm.exc import NoResultFound + import tracim +from tracim.command import TracimCLI +from tracim.command.user import UserCommand +from tracim.exceptions import UserNotExist +from tracim.lib.core.user import UserApi +from tracim.tests import CommandFunctionalTest + + +class TestCommands(CommandFunctionalTest): + """ + Test tracimcli command line ui. + """ + config_section = 'app:command_test' -class TestCommands(object): - def test_commands(self): + def test_func__check_commands_list__ok__nominal_case(self): """ Test listing of tracimcli command: Tracim commands must be listed :return: @@ -20,3 +36,52 @@ def test_commands(self): assert output.find('user update') > 0 assert output.find('db init') > 0 assert output.find('db delete') > 0 + assert output.find('webdav start') > 0 + + def test_func__user_create_command__ok__nominal_case(self): + """ + Test User creation + """ + api = UserApi( + current_user=None, + session=self.session, + config=self.app_config, + ) + with pytest.raises(NoResultFound): + api.get_one_by_email('command_test@user') + app = TracimCLI() + result = app.run([ + 'user', 'create', + '-c', 'tests_configs.ini#command_test', + '-l', 'command_test@user', + '-p', 'new_password' + ]) + new_user = api.get_one_by_email('command_test@user') + assert new_user.email == 'command_test@user' + assert new_user.validate_password('new_password') + + def test_func__user_update_command__ok__nominal_case(self): + """ + Test user password update + """ + api = UserApi( + current_user=None, + session=self.session, + config=self.app_config, + ) + user = api.get_one_by_email('admin@admin.admin') + assert user.email == 'admin@admin.admin' + assert user.validate_password('admin@admin.admin') + assert not user.validate_password('new_password') + + app = TracimCLI() + result = app.run([ + 'user', 'update', + '-c', 'tests_configs.ini#command_test', + '-l', 'admin@admin.admin', + '-p', 'new_password' + ]) + new_user = api.get_one_by_email('admin@admin.admin') + assert new_user.email == 'admin@admin.admin' + assert new_user.validate_password('new_password') + assert not new_user.validate_password('admin@admin.admin') From fdc6dd8b16d9e55d01bbca6b7933febc3fa3ad34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gu=C3=A9na=C3=ABl=20Muller?= Date: Fri, 25 May 2018 15:10:25 +0200 Subject: [PATCH 06/12] Refactor WebdavFactory + test config initialisation for wsgidav --- tracim/lib/webdav/__init__.py | 21 ++++++++---- tracim/tests/library/test_webdav.py | 51 ++++++++++++++++++++++++++++- 2 files changed, 65 insertions(+), 7 deletions(-) diff --git a/tracim/lib/webdav/__init__.py b/tracim/lib/webdav/__init__.py index 8229eb8..1ec2e76 100644 --- a/tracim/lib/webdav/__init__.py +++ b/tracim/lib/webdav/__init__.py @@ -44,14 +44,10 @@ def _initConfig(self, # Set config defaults config = DEFAULT_CONFIG.copy() temp_verbose = config["verbose"] - # Get pyramid Env tracim_config_file_path = os.path.abspath(tracim_config_file_path) config['tracim_config'] = tracim_config_file_path - global_conf = get_appsettings(config['tracim_config']).global_conf - local_conf = get_appsettings(config['tracim_config'], 'tracim_web') - settings = global_conf - settings.update(local_conf) + settings = self._get_tracim_settings(config) app_config = CFG(settings) default_config_file = os.path.abspath(settings['wsgidav.config_path']) @@ -91,10 +87,23 @@ def _initConfig(self, config['domaincontroller'] = TracimDomainController( presetdomain=None, presetserver=None, - app_config = app_config, + app_config=app_config, ) return config + def _get_tracim_settings( + self, + default_config, + ): + """ + Get tracim settings + """ + global_conf = get_appsettings(default_config['tracim_config']).global_conf + local_conf = get_appsettings(default_config['tracim_config'], 'tracim_web') # nopep8 + settings = global_conf + settings.update(local_conf) + return settings + # INFO - G.M - 13-04-2018 - Copy from # wsgidav.server.run_server._readConfigFile def _readConfigFile(self, config_file, verbose): diff --git a/tracim/tests/library/test_webdav.py b/tracim/tests/library/test_webdav.py index 30f3870..7ef400e 100644 --- a/tracim/tests/library/test_webdav.py +++ b/tracim/tests/library/test_webdav.py @@ -3,8 +3,10 @@ import pytest from sqlalchemy.exc import InvalidRequestError - +from wsgidav.wsgidav_app import DEFAULT_CONFIG +from tracim import WebdavAppFactory from tracim.lib.core.user import UserApi +from tracim.lib.webdav import TracimDomainController from tracim.tests import eq_ from tracim.lib.core.notifications import DummyNotifier from tracim.lib.webdav.dav_provider import Provider @@ -15,6 +17,53 @@ from tracim.fixtures.content import Content as ContentFixtures from tracim.fixtures.users_and_groups import Base as BaseFixture from wsgidav import util +from unittest.mock import MagicMock + + +class TestWebdavFactory(StandardTest): + + def test_unit__initConfig__ok__nominal_case(self): + """ + Check if config is correctly modify for wsgidav using mocked + wsgidav and tracim conf (as dict) + :return: + """ + tracim_settings = { + 'sqlalchemy.url': 'sqlite:///:memory:', + 'user.auth_token.validity': '604800', + 'depot_storage_dir': '/tmp/test/depot', + 'depot_storage_name': 'test', + 'preview_cache_dir': '/tmp/test/preview_cache', + 'wsgidav.config_path': 'development.ini' + + } + wsgidav_setting = DEFAULT_CONFIG.copy() + wsgidav_setting.update( + { + 'root_path': '', + 'acceptbasic': True, + 'acceptdigest': False, + 'defaultdigest': False, + } + ) + mock = MagicMock() + mock._initConfig = WebdavAppFactory._initConfig + mock._readConfigFile.return_value = wsgidav_setting + mock._get_tracim_settings.return_value = tracim_settings + config = mock._initConfig(mock) + assert config + assert config['acceptbasic'] is True + assert config['acceptdigest'] is False + assert config['defaultdigest'] is False + # TODO - G.M - 25-05-2018 - Better check for middleware stack config + assert 'middleware_stack' in config + assert len(config['middleware_stack']) == 7 + assert 'root_path' in config + assert 'provider_mapping' in config + assert config['root_path'] in config['provider_mapping'] + assert isinstance(config['provider_mapping'][config['root_path']], Provider) # nopep8 + assert 'domaincontroller' in config + assert isinstance(config['domaincontroller'], TracimDomainController) class TestWebDav(StandardTest): From de19c9e634ace1df571444f84241732a45602439 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gu=C3=A9na=C3=ABl=20Muller?= Date: Mon, 28 May 2018 10:47:58 +0200 Subject: [PATCH 07/12] better tests for user commands + tests for group_api + some fixe in group_api lib --- tracim/command/__init__.py | 3 +- tracim/command/user.py | 26 +++-- tracim/exceptions.py | 12 +-- tracim/lib/core/group.py | 19 +++- tracim/tests/commands/test_commands.py | 129 +++++++++++++++++++++++-- tracim/tests/library/test_group_api.py | 69 +++++++++++++ 6 files changed, 235 insertions(+), 23 deletions(-) create mode 100644 tracim/tests/library/test_group_api.py diff --git a/tracim/command/__init__.py b/tracim/command/__init__.py index 5ca17fc..8b850d2 100644 --- a/tracim/command/__init__.py +++ b/tracim/command/__init__.py @@ -9,7 +9,7 @@ from pyramid.paster import bootstrap from pyramid.scripting import AppEnvironment -from tracim.exceptions import CommandAbortedError +from tracim.exceptions import BadCommandError from tracim.lib.utils.utils import DEFAULT_TRACIM_CONFIG_FILE @@ -56,6 +56,7 @@ def take_action(self, parsed_args: argparse.Namespace) -> None: with app_context['request'].tm: self.take_app_action(parsed_args, app_context) + def get_parser(self, prog_name: str) -> argparse.ArgumentParser: parser = super(AppContextCommand, self).get_parser(prog_name) diff --git a/tracim/command/user.py b/tracim/command/user.py index 88bc6e2..9c3eb00 100644 --- a/tracim/command/user.py +++ b/tracim/command/user.py @@ -3,6 +3,7 @@ from pyramid.scripting import AppEnvironment import transaction from sqlalchemy.exc import IntegrityError +from sqlalchemy.orm.exc import NoResultFound from tracim import CFG from tracim.command import AppContextCommand @@ -11,9 +12,9 @@ #from tracim.lib.daemons import DaemonsManager #from tracim.lib.daemons import RadicaleDaemon #from tracim.lib.email import get_email_manager -from tracim.exceptions import AlreadyExistError +from tracim.exceptions import UserAlreadyExistError, GroupNotExist from tracim.exceptions import NotificationNotSend -from tracim.exceptions import CommandAbortedError +from tracim.exceptions import BadCommandError from tracim.lib.core.group import GroupApi from tracim.lib.core.user import UserApi from tracim.models import User @@ -85,6 +86,14 @@ 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 GroupNotExist(msg) return self._group_api.get_one_with_name(name) def _add_user_to_named_group( @@ -92,6 +101,7 @@ def _add_user_to_named_group( user: str, group_name: str ) -> None: + group = self._get_group(group_name) if user not in group.users: group.users.append(user) @@ -116,7 +126,7 @@ def _create_user( ) -> User: if not password: if self._password_required(): - raise CommandAbortedError( + raise BadCommandError( "You must provide -p/--password parameter" ) password = '' @@ -135,7 +145,7 @@ def _create_user( self._user_api.execute_created_user_actions(user) except IntegrityError: self._session.rollback() - raise AlreadyExistError() + raise UserAlreadyExistError() except NotificationNotSend as exception: self._session.rollback() raise exception @@ -181,10 +191,10 @@ def _proceed_user(self, parsed_args: argparse.Namespace) -> User: password=parsed_args.password, do_notify=parsed_args.send_email, ) - except AlreadyExistError: - raise CommandAbortedError("Error: User already exist (use `user update` command instead)") + except UserAlreadyExistError: + raise UserAlreadyExistError("Error: User already exist (use `user update` command instead)") except NotificationNotSend: - raise CommandAbortedError("Error: Cannot send email notification, user not created.") + raise NotificationNotSend("Error: Cannot send email notification, user not created.") # TODO - G.M - 04-04-2018 - [Email] Check this code # if parsed_args.send_email: # email_manager = get_email_manager() @@ -242,5 +252,5 @@ class UpdateUserCommand(UserCommand): action = UserCommand.ACTION_UPDATE -class LDAPUserUnknown(CommandAbortedError): +class LDAPUserUnknown(BadCommandError): pass diff --git a/tracim/exceptions.py b/tracim/exceptions.py index ae55eab..7e370f1 100644 --- a/tracim/exceptions.py +++ b/tracim/exceptions.py @@ -25,15 +25,11 @@ class ConfigurationError(TracimError): pass -class AlreadyExistError(TracimError): +class UserAlreadyExistError(TracimError): pass -class CommandError(TracimError): - pass - - -class CommandAbortedError(CommandError): +class BadCommandError(TracimError): pass @@ -99,3 +95,7 @@ class UserNotExist(TracimException): class NotificationNotSend(TracimException): pass + + +class GroupNotExist(TracimError): + pass \ No newline at end of file diff --git a/tracim/lib/core/group.py b/tracim/lib/core/group.py index e87dbd3..baed44d 100644 --- a/tracim/lib/core/group.py +++ b/tracim/lib/core/group.py @@ -1,6 +1,10 @@ # -*- coding: utf-8 -*- import typing +from sqlalchemy.orm.exc import NoResultFound + +from tracim.exceptions import GroupNotExist + __author__ = 'damien' from tracim.models.auth import Group, User @@ -22,7 +26,18 @@ def _base_query(self) -> Query: return self._session.query(Group) def get_one(self, group_id) -> Group: - return self._base_query().filter(Group.group_id == group_id).one() + try: + group = self._base_query().filter(Group.group_id == group_id).one() + return group + except NoResultFound: + raise GroupNotExist() def get_one_with_name(self, group_name) -> Group: - return self._base_query().filter(Group.group_name == group_name).one() + try: + group = self._base_query().filter(Group.group_name == group_name).one() + return group + except NoResultFound: + raise GroupNotExist() + + def get_all(self): + return self._base_query().order_by(Group.group_id).all() diff --git a/tracim/tests/commands/test_commands.py b/tracim/tests/commands/test_commands.py index 0cb3e70..cda7159 100644 --- a/tracim/tests/commands/test_commands.py +++ b/tracim/tests/commands/test_commands.py @@ -10,7 +10,8 @@ import tracim from tracim.command import TracimCLI from tracim.command.user import UserCommand -from tracim.exceptions import UserNotExist +from tracim.exceptions import UserAlreadyExistError, BadCommandError, \ + GroupNotExist from tracim.lib.core.user import UserApi from tracim.tests import CommandFunctionalTest @@ -22,7 +23,7 @@ class TestCommands(CommandFunctionalTest): config_section = 'app:command_test' - def test_func__check_commands_list__ok__nominal_case(self): + def test_func__check_commands_list__ok__nominal_case(self) -> None: """ Test listing of tracimcli command: Tracim commands must be listed :return: @@ -38,7 +39,7 @@ def test_func__check_commands_list__ok__nominal_case(self): assert output.find('db delete') > 0 assert output.find('webdav start') > 0 - def test_func__user_create_command__ok__nominal_case(self): + def test_func__user_create_command__ok__nominal_case(self) -> None: """ Test User creation """ @@ -54,13 +55,99 @@ def test_func__user_create_command__ok__nominal_case(self): 'user', 'create', '-c', 'tests_configs.ini#command_test', '-l', 'command_test@user', - '-p', 'new_password' + '-p', 'new_password', + '--debug', ]) 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): + 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(NoResultFound): + api.get_one_by_email('command_test@user') + app = TracimCLI() + result = app.run([ + 'user', 'create', + '-c', 'tests_configs.ini#command_test', + '-l', 'command_test@user', + '-p', 'new_password', + '-g', 'administrators', + '--debug', + ]) + 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_create_command__err__in_unknown_group(self) -> None: + """ + Test User creation with an unknown group + """ + api = UserApi( + current_user=None, + session=self.session, + config=self.app_config, + ) + app = TracimCLI() + with pytest.raises(GroupNotExist): + result = app.run([ + 'user', 'create', + '-c', 'tests_configs.ini#command_test', + '-l', 'command_test@user', + '-p', 'new_password', + '-g', 'unknown', + '--debug', + ]) + + def test_func__user_create_command__err_user_already_exist(self) -> None: + """ + Test User creation with existing user login + """ + api = UserApi( + current_user=None, + session=self.session, + config=self.app_config, + ) + app = TracimCLI() + with pytest.raises(UserAlreadyExistError): + result = app.run([ + '--debug', + 'user', 'create', + '-c', 'tests_configs.ini#command_test', + '-l', 'admin@admin.admin', + '-p', 'new_password', + '--debug', + ]) + + def test_func__user_create_command__err__password_required(self) -> None: + """ + Test User creation without filling password + """ + api = UserApi( + current_user=None, + session=self.session, + config=self.app_config, + ) + app = TracimCLI() + with pytest.raises(BadCommandError): + result = app.run([ + '--debug', + 'user', 'create', + '-c', 'tests_configs.ini#command_test', + '-l', 'admin@admin.admin', + '--debug', + ]) + + def test_func__user_update_command__ok__nominal_case(self) -> None: """ Test user password update """ @@ -79,9 +166,39 @@ def test_func__user_update_command__ok__nominal_case(self): 'user', 'update', '-c', 'tests_configs.ini#command_test', '-l', 'admin@admin.admin', - '-p', 'new_password' + '-p', 'new_password', + '--debug', + ]) + new_user = api.get_one_by_email('admin@admin.admin') + assert new_user.email == 'admin@admin.admin' + assert new_user.validate_password('new_password') + assert not new_user.validate_password('admin@admin.admin') + + 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('admin@admin.admin') + assert user.email == 'admin@admin.admin' + assert user.validate_password('admin@admin.admin') + assert not user.validate_password('new_password') + assert user.profile.name == 'administrators' + app = TracimCLI() + result = app.run([ + 'user', 'update', + '-c', 'tests_configs.ini#command_test', + '-l', 'admin@admin.admin', + '-p', 'new_password', + '-rmg', 'administrators', + '--debug', ]) new_user = api.get_one_by_email('admin@admin.admin') assert new_user.email == 'admin@admin.admin' assert new_user.validate_password('new_password') assert not new_user.validate_password('admin@admin.admin') + assert new_user.profile.name == 'managers' \ No newline at end of file diff --git a/tracim/tests/library/test_group_api.py b/tracim/tests/library/test_group_api.py new file mode 100644 index 0000000..3341c89 --- /dev/null +++ b/tracim/tests/library/test_group_api.py @@ -0,0 +1,69 @@ +# coding=utf-8 +import pytest + +from tracim.exceptions import GroupNotExist +from tracim.lib.core.group import GroupApi +from tracim.tests import DefaultTest +from tracim.fixtures.users_and_groups import Base as BaseFixture +from tracim.fixtures.content import Content as ContentFixture + + +class TestGroupApi(DefaultTest): + fixtures = [BaseFixture, ContentFixture] + + def test_unit__get_one__ok_nominal_case(self) -> None: + """ + Get one group by id + """ + api = GroupApi( + current_user=None, + session=self.session, + ) + group = api.get_one(1) + assert group.group_id == 1 + assert group.group_name == 'users' + + def test_unit__get_one__err__group_not_exist(self) -> None: + """ + Get one group who does not exist by id + """ + api = GroupApi( + current_user=None, + session=self.session, + ) + with pytest.raises(GroupNotExist): + group = api.get_one(10) + + def test_unit__get_one_group_with_name__nominal_case(self) -> None: + """ + get one group by name + """ + api = GroupApi( + current_user=None, + session=self.session, + ) + group = api.get_one_with_name('administrators') + assert group.group_id == 3 + assert group.group_name == 'administrators' + + def test_unit__get_one_with_name__err__group_not_exist(self) -> None: + """ + get one group by name who does not exist + """ + api = GroupApi( + current_user=None, + session=self.session, + ) + with pytest.raises(GroupNotExist): + group = api.get_one_with_name('unknown_group') + + def test_unit__get_all__ok__nominal_case(self): + """ + get all groups + """ + api = GroupApi( + current_user=None, + session=self.session, + ) + groups = api.get_all() + assert ['users', 'managers', 'administrators'] == [group.group_name for group in groups] # nopep8 From 9f40425d9c683fa622f29bace7bd045b82fe13ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gu=C3=A9na=C3=ABl=20Muller?= Date: Mon, 28 May 2018 14:57:55 +0200 Subject: [PATCH 08/12] force LEVEL warning for tests --- tests_configs.ini | 2 +- tracim/tests/__init__.py | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/tests_configs.ini b/tests_configs.ini index 41e1390..1367264 100644 --- a/tests_configs.ini +++ b/tests_configs.ini @@ -62,4 +62,4 @@ email.processing_mode = async email.notification.smtp.server = 127.0.0.1 email.notification.smtp.port = 1025 email.notification.smtp.user = test_user -email.notification.smtp.password = just_a_password \ No newline at end of file +email.notification.smtp.password = just_a_password diff --git a/tracim/tests/__init__.py b/tracim/tests/__init__.py index 1bee1be..c397487 100644 --- a/tracim/tests/__init__.py +++ b/tracim/tests/__init__.py @@ -35,6 +35,7 @@ class FunctionalTest(unittest.TestCase): sqlalchemy_url = 'sqlite:///tracim_test.sqlite' def setUp(self): + logger._logger.setLevel('WARNING') DepotManager._clear() self.settings = { 'sqlalchemy.url': self.sqlalchemy_url, @@ -100,6 +101,7 @@ class CommandFunctionalTest(FunctionalTest): def run_app(self): self.session = get_tm_session(self.session_factory, transaction.manager) + class BaseTest(unittest.TestCase): """ Pyramid default test. @@ -109,6 +111,7 @@ class BaseTest(unittest.TestCase): config_section = 'base_test' def setUp(self): + logger._logger.setLevel('WARNING') logger.debug(self, 'Setup Test...') self.settings = plaster.get_settings( self.config_uri, From 16284fd784b33d026b1f5ccc860a2f54741fe26a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gu=C3=A9na=C3=ABl=20Muller?= Date: Tue, 29 May 2018 11:23:12 +0200 Subject: [PATCH 09/12] remove uneeded id of profil/role + better schema with description/example --- tracim/tests/functional/test_session.py | 2 - tracim/tests/functional/test_workspaces.py | 1 - tracim/views/core_api/schemas.py | 149 ++++++++++++++++----- 3 files changed, 115 insertions(+), 37 deletions(-) diff --git a/tracim/tests/functional/test_session.py b/tracim/tests/functional/test_session.py index df5c55a..24109b5 100644 --- a/tracim/tests/functional/test_session.py +++ b/tracim/tests/functional/test_session.py @@ -52,7 +52,6 @@ def test_api__try_login_enpoint__ok_200__nominal_case(self): assert res.json_body['created'] assert res.json_body['is_active'] assert res.json_body['profile'] - assert isinstance(res.json_body['profile']['id'], int) assert res.json_body['profile']['slug'] == 'administrators' assert res.json_body['caldav_url'] is None assert res.json_body['avatar_url'] is None @@ -111,7 +110,6 @@ def test_api__try_whoami_enpoint__ok_200__nominal_case(self): assert res.json_body['created'] assert res.json_body['is_active'] assert res.json_body['profile'] - assert isinstance(res.json_body['profile']['id'], int) assert res.json_body['profile']['slug'] == 'administrators' assert res.json_body['caldav_url'] is None assert res.json_body['avatar_url'] is None diff --git a/tracim/tests/functional/test_workspaces.py b/tracim/tests/functional/test_workspaces.py index a2fc759..3c2e550 100644 --- a/tracim/tests/functional/test_workspaces.py +++ b/tracim/tests/functional/test_workspaces.py @@ -156,7 +156,6 @@ def test_api__get_workspace_members__ok_200__nominal_case(self): assert len(res) == 2 user_role = res[0] assert user_role['role_slug'] == 'workspace_manager' - assert user_role['role_id'] == 8 assert user_role['user_id'] == 1 assert user_role['workspace_id'] == 1 assert user_role['user']['display_name'] == 'Global manager' diff --git a/tracim/views/core_api/schemas.py b/tracim/views/core_api/schemas.py index b6d4b8c..6327e67 100644 --- a/tracim/views/core_api/schemas.py +++ b/tracim/views/core_api/schemas.py @@ -9,44 +9,84 @@ class ProfileSchema(marshmallow.Schema): - id = marshmallow.fields.Int(dump_only=True, validate=OneOf(Profile._IDS)) - slug = marshmallow.fields.String(attribute='name', validate=OneOf(Profile._NAME)) + slug = marshmallow.fields.String( + attribute='name', + validate=OneOf(Profile._NAME), + example='managers', + ) + + class Meta: + description = 'User Profile, give user right on whole Tracim instance.' class UserSchema(marshmallow.Schema): - user_id = marshmallow.fields.Int(dump_only=True) - email = marshmallow.fields.Email(required=True) - display_name = marshmallow.fields.String() - created = marshmallow.fields.DateTime(format='iso8601') - is_active = marshmallow.fields.Bool() + user_id = marshmallow.fields.Int(dump_only=True, example=3) + email = marshmallow.fields.Email( + required=True, + example='suri.cate@algoo.fr' + ) + display_name = marshmallow.fields.String( + example='Suri Cate', + ) + created = marshmallow.fields.DateTime( + format='iso8601', + description='User account creation date (iso8601 format).', + ) + is_active = marshmallow.fields.Bool( + example=True, + # TODO - G.M - Explains this value. + ) # TODO - G.M - 17-04-2018 - Restrict timezone values - timezone = marshmallow.fields.String() + timezone = marshmallow.fields.String( + example="Paris/Europe", + ) # TODO - G.M - 17-04-2018 - check this, relative url allowed ? caldav_url = marshmallow.fields.Url( allow_none=True, relative=True, - attribute='calendar_url' + attribute='calendar_url', + example="/api/v2/calendar/user/3.ics/", + description="The url for calendar CalDAV direct access", + ) + avatar_url = marshmallow.fields.Url( + allow_none=True, + example="/api/v2/assets/avatars/suri-cate.jpg", + description="avatar_url is the url to the image file. " + "If no avatar, then set it to null " + "(and frontend will interpret this with a default avatar)", ) - avatar_url = marshmallow.fields.Url(allow_none=True) profile = marshmallow.fields.Nested( ProfileSchema, many=False, ) + class Meta: + description = 'User account of Tracim' + class UserIdPathSchema(marshmallow.Schema): - user_id = marshmallow.fields.Int() + user_id = marshmallow.fields.Int(example=3) class WorkspaceIdPathSchema(marshmallow.Schema): - workspace_id = marshmallow.fields.Int() + workspace_id = marshmallow.fields.Int(example=4) class BasicAuthSchema(marshmallow.Schema): - email = marshmallow.fields.Email(required=True) - password = marshmallow.fields.String(required=True, load_only=True) + email = marshmallow.fields.Email( + example='suri.cate@algoo.fr', + required=True + ) + password = marshmallow.fields.String( + example='8QLa$ Date: Mon, 18 Jun 2018 10:49:47 +0200 Subject: [PATCH 10/12] repair test post-merge --- tracim/tests/functional/test_workspaces.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tracim/tests/functional/test_workspaces.py b/tracim/tests/functional/test_workspaces.py index 2f61a9e..06a42b9 100644 --- a/tracim/tests/functional/test_workspaces.py +++ b/tracim/tests/functional/test_workspaces.py @@ -156,7 +156,6 @@ def test_api__get_workspace_members__ok_200__nominal_case(self): assert len(res) == 2 user_role = res[0] assert user_role['role_slug'] == 'workspace-manager' - assert user_role['role_id'] == 8 assert user_role['user_id'] == 1 assert user_role['workspace_id'] == 1 assert user_role['user']['display_name'] == 'Global manager' From b5dedb48836930d82dcefaf249cb7e88c330e716 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gu=C3=A9na=C3=ABl=20Muller?= Date: Mon, 18 Jun 2018 10:53:37 +0200 Subject: [PATCH 11/12] remove temp file --- development.ini.old | 259 -------------------------------------- development.ini.oloool | 275 ----------------------------------------- 2 files changed, 534 deletions(-) delete mode 100644 development.ini.old delete mode 100644 development.ini.oloool diff --git a/development.ini.old b/development.ini.old deleted file mode 100644 index 554cdf6..0000000 --- a/development.ini.old +++ /dev/null @@ -1,259 +0,0 @@ -### -# app configuration -# https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html -### -[app:main] -use = egg:tracim_backend - -pyramid.reload_templates = true -pyramid.debug_authorization = false -pyramid.debug_notfound = false -pyramid.debug_routematch = false -pyramid.default_locale_name = en -pyramid.includes = - pyramid_debugtoolbar - -sqlalchemy.url = sqlite:///%(here)s/tracim.sqlite - -retry.attempts = 3 - -# By default, the toolbar only appears for clients from IP addresses -# '127.0.0.1' and '::1'. -# debugtoolbar.hosts = 127.0.0.1 ::1 - -### -# TRACIM SPECIFIC CONF -### - -### Global -debug = false -cache_dir = %(here)s/data -# preview generator cache directory -preview_cache_dir = /tmp/tracim/preview/ -# file depot storage -depot_storage_name = tracim -depot_storage_dir = %(here)s/depot/ - -# The following parameters allow to personalize the home page -# They are html ready (you can put html tags they will be interpreted) -website.title = TRACIM -website.title.color = #555 -website.home.subtitle = Default login: email: admin@admin.admin (password: admin@admin.admin) -website.home.tag_line =
Collaboration, versionning and traceability
-website.home.below_login_form = in case of problem, please contact the administrator. -# Values may be 'all' or 'folders' -website.treeview.content = all -# The following base_url is used for links and icons -# integrated in the email notifcations -website.base_url = http://127.0.0.1:8080 -# If config not provided, it will be extracted from website.base_url -website.server_name = 127.0.0.1 - -# Specifies if the update of comments and attached files is allowed (by the owner only). -# Examples: -# 600 means 10 minutes (ie 600 seconds) -# 3600 means 1 hour (60x60 seconds) -# -# Allowed values: -# -1 means that content update is allowed for ever -# 0 means that content update is not allowed -# x means that content update is allowed for x seconds (with x>0) -content.update.allowed.duration = 3600 - -# Auth type (internal or ldap) -auth_type = internal -# If auth_type is ldap, uncomment following ldap_* parameters -# LDAP server address -# ldap_url = ldap://localhost:389 -# Base dn to make queries -# ldap_base_dn = dc=directory,dc=fsf,dc=org -# Bind dn to identify the search -# ldap_bind_dn = cn=admin,dc=directory,dc=fsf,dc=org -# The bind password -# ldap_bind_pass = toor -# Attribute name of user record who contain user login (email) -# ldap_ldap_naming_attribute = uid -# Matching between ldap attribute and ldap user field (ldap_attr1=user_field1,ldap_attr2=user_field2,...) -# ldap_user_attributes = mail=email -# TLS usage to communicate with your LDAP server -# ldap_tls = False -# If True, LDAP own tracim group managment (not available for now!) -# ldap_group_enabled = False -# User auth token validity in seconds (used to interfaces like web calendars) -user.auth_token.validity = 604800 - -### Mail - -# Reset password through email related configuration. -# These emails will be sent through SMTP -# -resetpassword.email_sender = email@sender.com -resetpassword.smtp_host = smtp.sender -resetpassword.smtp_port = 25 -resetpassword.smtp_login = smtp.login -resetpassword.smtp_passwd = smtp.password - -email.notification.activated = False -# email.notification.log_file_path = /tmp/mail-notifications.log -# email notifications can be sent with the user_id added as an identifier -# this way email clients like Thunderbird will be able to distinguish -# notifications generated by a user or another one -email.notification.from.email = noreply+{user_id}@trac.im -email.notification.from.default_label = Tracim Notifications -email.notification.reply_to.email = reply+{content_id}@trac.im -email.notification.references.email = thread+{content_id}@trac.im -email.notification.content_update.template.html = %(here)s/tracim/templates/mail/content_update_body_html.mak -email.notification.content_update.template.text = %(here)s/tracim/templates/mail/content_update_body_text.mak -email.notification.created_account.template.html = %(here)s/tracim/templates/mail/created_account_body_html.mak -email.notification.created_account.template.text = %(here)s/tracim/templates/mail/created_account_body_text.mak -# Note: items between { and } are variable names. Do not remove / rename them -email.notification.content_update.subject = [{website_title}] [{workspace_label}] {content_label} ({content_status_label}) -email.notification.created_account.subject = [{website_title}] Created account -# processing_mode may be sync or async -email.notification.processing_mode = sync -email.notification.smtp.server = your_smtp_server -email.notification.smtp.port = 25 -email.notification.smtp.user = your_smtp_user -email.notification.smtp.password = your_smtp_password - -## Email sending configuration -# processing_mode may be sync or async, -# with async, please configure redis below -email.processing_mode = sync -# email.async.redis.host = localhost -# email.async.redis.port = 6379 -# email.async.redis.db = 0 - -# Email reply configuration -email.reply.activated = False -email.reply.imap.server = your_imap_server -email.reply.imap.port = 993 -email.reply.imap.user = your_imap_user -email.reply.imap.password = your_imap_password -email.reply.imap.folder = INBOX -email.reply.imap.use_ssl = true -email.reply.imap.use_idle = true -# Re-new connection each 10 minutes -email.reply.connection.max_lifetime = 600 -# Token for communication between mail fetcher and tracim controller -email.reply.token = mysecuretoken -# Delay in seconds between each check -email.reply.check.heartbeat = 60 -email.reply.use_html_parsing = true -email.reply.use_txt_parsing = true -# Lockfile path is required for email_reply feature, -# it's just an empty file use to prevent concurrent access to imap unseen mail -email.reply.lockfile_path = %(here)s/email_fetcher.lock - -### Radical (CalDav server) configuration - -# radicale.server.host = 0.0.0.0 -# radicale.server.port = 5232 -# radicale.server.ssl = false -radicale.server.filesystem.folder = %(here)s/radicale/collections/ -# radicale.server.allow_origin = * -# radicale.server.realm_message = Tracim Calendar - Password Required -## url can be extended like http://127.0.0.1:5232/calendar -## in this case, you have to create your own proxy behind this url. -## and update following parameters -# radicale.client.base_url.host = http://127.0.0.1:5232 -# radicale.client.base_url.prefix = / - -### WSGIDAV - -wsgidav.config_path = %(here)s/wsgidav.conf -## url can be extended like 127.0.0.1/webdav -## in this case, you have to create your own proxy behind this url. -## Do not set http:// prefix. -# wsgidav.client.base_url = 127.0.0.1: - -### -# wsgi server configuration -### - -[server:main] -use = egg:waitress#main -listen = localhost:6543 - -[alembic] -# path to migration scripts -script_location = tracim/migration - -# template used to generate migration files -# file_template = %%(rev)s_%%(slug)s - -# timezone to use when rendering the date -# within the migration file as well as the filename. -# string value is passed to dateutil.tz.gettz() -# leave blank for localtime -# timezone = - -# max length of characters to apply to the -# "slug" field -#truncate_slug_length = 40 - -# set to 'true' to run the environment during -# the 'revision' command, regardless of autogenerate -# revision_environment = false - -# set to 'true' to allow .pyc and .pyo files without -# a source .py file to be detected as revisions in the -# versions/ directory -# sourceless = false - -# version location specification; this defaults -# to migrate/versions. When using multiple version -# directories, initial revisions must be specified with --version-path -# version_locations = %(here)s/bar %(here)s/bat migrate/versions - -# the output encoding used when revision files -# are written from script.py.mako -# output_encoding = utf-8 - -sqlalchemy.url = sqlite:///%(here)s/tracim.sqlite - -### -# logging configuration -# https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html -### - -[loggers] -keys = root, tracim, sqlalchemy, alembic - -[handlers] -keys = console - -[formatters] -keys = generic - -[logger_root] -level = INFO -handlers = console - -[logger_tracim] -level = DEBUG -handlers = -qualname = tracim - -[logger_sqlalchemy] -level = INFO -handlers = -qualname = sqlalchemy.engine -# "level = INFO" logs SQL queries. -# "level = DEBUG" logs SQL queries and results. -# "level = WARN" logs neither. (Recommended for production systems.) - -[logger_alembic] -level = INFO -handlers = -qualname = alembic - -[handler_console] -class = StreamHandler -args = (sys.stderr,) -level = NOTSET -formatter = generic - -[formatter_generic] -format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s -datefmt = %H:%M:%S \ No newline at end of file diff --git a/development.ini.oloool b/development.ini.oloool deleted file mode 100644 index 6e95447..0000000 --- a/development.ini.oloool +++ /dev/null @@ -1,275 +0,0 @@ -### -# app configuration -# https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html -### -;[pipeline:main] -;pipeline = tracim_web - -[app:main] -use = egg:tracim_backend - -pyramid.reload_templates = true -pyramid.debug_authorization = false -pyramid.debug_notfound = false -pyramid.debug_routematch = false -pyramid.default_locale_name = en -;pyramid.includes = -; pyramid_debugtoolbar - -retry.attempts = 3 - -sqlalchemy.url = sqlite:///%(here)s/tracim.sqlite - -# By default, the toolbar only appears for clients from IP addresses -# '127.0.0.1' and '::1'. -# debugtoolbar.hosts = 127.0.0.1 ::1 - -### -# TRACIM SPECIFIC CONF -### - -### Global - -cache_dir = %(here)s/data -# preview generator cache directory -preview_cache_dir = /tmp/tracim/preview/ -# file depot storage -depot_storage_name = tracim -depot_storage_dir = %(here)s/depot/ - -# The following parameters allow to personalize the home page -# They are html ready (you can put html tags they will be interpreted) -website.title = TRACIM -website.title.color = #555 -website.home.subtitle = Default login: email: admin@admin.admin (password: admin@admin.admin) -website.home.tag_line =
Collaboration, versionning and traceability
-website.home.below_login_form = in case of problem, please contact the administrator. -# Values may be 'all' or 'folders' -website.treeview.content = all -# The following base_url is used for links and icons -# integrated in the email notifcations -website.base_url = http://127.0.0.1:8080 -# If config not provided, it will be extracted from website.base_url -website.server_name = 127.0.0.1 - -# Specifies if the update of comments and attached files is allowed (by the owner only). -# Examples: -# 600 means 10 minutes (ie 600 seconds) -# 3600 means 1 hour (60x60 seconds) -# -# Allowed values: -# -1 means that content update is allowed for ever -# 0 means that content update is not allowed -# x means that content update is allowed for x seconds (with x>0) -content.update.allowed.duration = 3600 - -# Auth type (internal or ldap) -auth_type = internal -# If auth_type is ldap, uncomment following ldap_* parameters -# LDAP server address -# ldap_url = ldap://localhost:389 -# Base dn to make queries -# ldap_base_dn = dc=directory,dc=fsf,dc=org -# Bind dn to identify the search -# ldap_bind_dn = cn=admin,dc=directory,dc=fsf,dc=org -# The bind password -# ldap_bind_pass = toor -# Attribute name of user record who contain user login (email) -# ldap_ldap_naming_attribute = uid -# Matching between ldap attribute and ldap user field (ldap_attr1=user_field1,ldap_attr2=user_field2,...) -# ldap_user_attributes = mail=email -# TLS usage to communicate with your LDAP server -# ldap_tls = False -# If True, LDAP own tracim group managment (not available for now!) -# ldap_group_enabled = False -# User auth token validity in seconds (used to interfaces like web calendars) -user.auth_token.validity = 604800 - -### Mail - -# Reset password through email related configuration. -# These emails will be sent through SMTP -# -resetpassword.email_sender = email@sender.com -resetpassword.smtp_host = smtp.sender -resetpassword.smtp_port = 25 -resetpassword.smtp_login = smtp.login -resetpassword.smtp_passwd = smtp.password - -email.notification.activated = false -# email.notification.log_file_path = /tmp/mail-notifications.log -# email notifications can be sent with the user_id added as an identifier -# this way email clients like Thunderbird will be able to distinguish -# notifications generated by a user or another one -email.notification.from.email = dev.tracim.maildaemon+{user_id}@algoo.fr -email.notification.from.default_label = Tracim Notifications -email.notification.reply_to.email = dev.tracim.maildaemon+{content_id}@algoo.fr -email.notification.references.email = dev.tracim.maildaemon+{content_id}@algoo.fr -email.notification.content_update.template.html = %(here)s/tracim/templates/mail/content_update_body_html.mak -email.notification.content_update.template.text = %(here)s/tracim/templates/mail/content_update_body_text.mak -email.notification.created_account.template.html = %(here)s/tracim/templates/mail/created_account_body_html.mak -email.notification.created_account.template.text = %(here)s/tracim/templates/mail/created_account_body_text.mak -# Note: items between { and } are variable names. Do not remove / rename them -email.notification.content_update.subject = [{website_title}] [{workspace_label}] {content_label} ({content_status_label}) -email.notification.created_account.subject = [{website_title}] Created account -# processing_mode may be sync or async -email.notification.processing_mode = async -email.notification.smtp.server = mail.gandi.net -email.notification.smtp.port = 25 -email.notification.smtp.user = dev.tracim.maildaemon@algoo.fr -email.notification.smtp.password = dev.tracim.maildaemon - -## Email sending configuration -# processing_mode may be sync or async, -# with async, please configure redis below -email.processing_mode = sync -# email.async.redis.host = localhost -# email.async.redis.port = 6379 -# email.async.redis.db = 0 - -# Email reply configuration -email.reply.activated = false -email.reply.imap.server = your_imap_server -email.reply.imap.port = 993 -email.reply.imap.user = your_imap_user -email.reply.imap.password = your_imap_password -email.reply.imap.folder = INBOX -email.reply.imap.use_ssl = true -email.reply.imap.use_idle = true -# Re-new connection each 10 minutes -email.reply.connection.max_lifetime = 600 -# Token for communication between mail fetcher and tracim controller -email.reply.token = mysecuretoken -# Delay in seconds between each check -email.reply.check.heartbeat = 60 -email.reply.use_html_parsing = true -email.reply.use_txt_parsing = true -# Lockfile path is required for email_reply feature, -# it's just an empty file use to prevent concurrent access to imap unseen mail -email.reply.lockfile_path = %(here)s/email_fetcher.lock - -### Radical (CalDav server) configuration - -# radicale.server.host = 0.0.0.0 -# radicale.server.port = 5232 -# radicale.server.ssl = false -radicale.server.filesystem.folder = %(here)s/radicale/collections/ -# radicale.server.allow_origin = * -# radicale.server.realm_message = Tracim Calendar - Password Required -## url can be extended like http://127.0.0.1:5232/calendar -## in this case, you have to create your own proxy behind this url. -## and update following parameters -# radicale.client.base_url.host = http://127.0.0.1:5232 -# radicale.client.base_url.prefix = / - -### WSGIDAV - -wsgidav.config_path = %(here)s/wsgidav.conf -## url can be extended like 127.0.0.1/webdav -## in this case, you have to create your own proxy behind this url. -## Do not set http:// prefix. -# wsgidav.client.base_url = 127.0.0.1: - -### -# wsgi server configuration -### -[uwsgi] -# Legacy server config (waitress) -[server:main] -use = egg:waitress#main -listen = localhost:6543 - -[alembic] -# path to migration scripts -script_location = tracim/migration - -# template used to generate migration files -# file_template = %%(rev)s_%%(slug)s - -# timezone to use when rendering the date -# within the migration file as well as the filename. -# string value is passed to dateutil.tz.gettz() -# leave blank for localtime -# timezone = - -# max length of characters to apply to the -# "slug" field -#truncate_slug_length = 40 - -# set to 'true' to run the environment during -# the 'revision' command, regardless of autogenerate -# revision_environment = false - -# set to 'true' to allow .pyc and .pyo files without -# a source .py file to be detected as revisions in the -# versions/ directory -# sourceless = false - -# version location specification; this defaults -# to migrate/versions. When using multiple version -# directories, initial revisions must be specified with --version-path -# version_locations = %(here)s/bar %(here)s/bat migrate/versions - -# the output encoding used when revision files -# are written from script.py.mako -# output_encoding = utf-8 - -sqlalchemy.url = sqlite:///%(here)s/tracim.sqlite - -### -# logging configuration -# https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html -### - -[loggers] -keys = root, tracim, sqlalchemy, alembic, sentry - -[handlers] -keys = console, sentry - -[formatters] -keys = generic - -[logger_root] -level = INFO -handlers = console, sentry - -[logger_sentry] -level = WARN -handlers = console -qualname = sentry.errors -propagate = 0 - -[logger_tracim] -level = DEBUG -handlers = -qualname = tracim - -[logger_sqlalchemy] -level = INFO -handlers = -qualname = sqlalchemy.engine -# "level = INFO" logs SQL queries. -# "level = DEBUG" logs SQL queries and results. -# "level = WARN" logs neither. (Recommended for production systems.) - -[logger_alembic] -level = INFO -handlers = -qualname = alembic - -[handler_console] -class = StreamHandler -args = (sys.stderr,) -level = NOTSET -formatter = generic - -[handler_sentry] -class = raven.handlers.logging.SentryHandler -args = ('http://1dbab0942cca4fbb97f3dae62cbc965d:4d1deecd8abc41e38c02b37ed4954f58@127.0.0.1:9000/4',) -level = WARNING -formatter = generic - -[formatter_generic] -format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s -datefmt = %H:%M:%S \ No newline at end of file From 302ad90c5d24047bfb234faacd575296981328fa Mon Sep 17 00:00:00 2001 From: Bastien Sevajol Date: Mon, 18 Jun 2018 11:20:23 +0200 Subject: [PATCH 12/12] code style --- tracim/command/user.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/tracim/command/user.py b/tracim/command/user.py index 9437870..902cfdc 100644 --- a/tracim/command/user.py +++ b/tracim/command/user.py @@ -8,11 +8,8 @@ from tracim import CFG from tracim.command import AppContextCommand from tracim.command import Extender -#from tracim.lib.auth.ldap import LDAPAuth -#from tracim.lib.daemons import DaemonsManager -#from tracim.lib.daemons import RadicaleDaemon -#from tracim.lib.email import get_email_manager -from tracim.exceptions import UserAlreadyExistError, GroupDoesNotExist +from tracim.exceptions import UserAlreadyExistError +from tracim.exceptions import GroupDoesNotExist from tracim.exceptions import NotificationNotSend from tracim.exceptions import BadCommandError from tracim.lib.core.group import GroupApi