Ejemplo n.º 1
0
    def index(self, context, request: TracimRequest):
        app_config = request.registry.settings["CFG"]  # type: CFG
        # TODO - G.M - 2018-08-07 - Refactor autogen valid app list for frontend
        frontend_apps = []
        app_api = ApplicationApi(app_list=app_list)
        applications = [
            app_api.get_application_in_context(app, app_config)
            for app in app_api.get_all()
        ]
        for app in applications:
            app_frontend_path = APP_FRONTEND_PATH.replace(
                "{minislug}", app.minislug)
            app_path = os.path.join(self.dist_folder_path, app_frontend_path)
            if os.path.exists(app_path):
                frontend_apps.append(app)

        return render_to_response(
            self._get_index_file_path(),
            {
                "colors": {
                    "primary": ExtendedColor(app_config.APPS_COLORS["primary"])
                },
                "applications": frontend_apps,
                "website_title": app_config.WEBSITE__TITLE,
                "custom_toolbox_files": self.custom_toolbox_files,
                "cache_token": self.cache_token,
                "excluded_notifications":
                app_config.WEB__NOTIFICATIONS__EXCLUDED,
            },
        )
Ejemplo n.º 2
0
    def index(self, context, request: TracimRequest):
        app_config = request.registry.settings['CFG']
        # TODO - G.M - 2018-08-07 - Refactor autogen valid app list for frontend
        frontend_apps = []
        app_api = ApplicationApi(
            app_list=app_list,
        )
        applications = app_api.get_all()
        for app in applications:
            app_frontend_path = APP_FRONTEND_PATH.replace('{minislug}',
                                                          app.minislug)  # nopep8
            app_path = os.path.join(self.dist_folder_path,
                                    app_frontend_path)  # nopep8
            if os.path.exists(app_path):
                frontend_apps.append(app)

        return render_to_response(
            self._get_index_file_path(),
            {
                'colors': {
                    'primary': ExtendedColor(app_config.APPS_COLORS['primary']),
                },
                'applications': frontend_apps,
            }
        )
Ejemplo n.º 3
0
 def applications(self, context, request: TracimRequest, hapic_data=None):
     """
     Get list of alls applications installed in this tracim instance.
     """
     app_config = request.registry.settings['CFG']
     app_api = ApplicationApi(app_list=app_list, )
     return app_api.get_all()
Ejemplo n.º 4
0
 def test_api__get_applications__ok_200__nominal_case(self):
     """
     Get applications list with a registered user.
     """
     self.testapp.authorization = (
         'Basic',
         (
             '*****@*****.**',
             '*****@*****.**'
         )
     )
     res = self.testapp.get('/api/v2/system/applications', status=200)
     res = res.json_body
     dbsession = get_tm_session(self.session_factory, transaction.manager)
     app_api = ApplicationApi(
         app_list=app_list,
     )
     applications = app_api.get_all()
     assert len(res) == len(applications)
     for counter, application in enumerate(applications):
         assert res[counter]['label'] == application.label
         assert res[counter]['slug'] == application.slug
         assert res[counter]['fa_icon'] == application.fa_icon
         assert res[counter]['hexcolor'] == application.hexcolor
         assert res[counter]['is_active'] == application.is_active
         assert res[counter]['config'] == application.config
Ejemplo n.º 5
0
    def __init__(self, settings: typing.Dict[str, typing.Any]):
        # INFO - G.M - 2019-12-02 - Store own settings original dict, with copy
        # to avoid issue when serializing CFG object. settings dict is completed
        # with object in some context
        self.settings = settings.copy()
        self.config_info = []  # type: typing.List[ConfigParam]
        logger.debug(self, "CONFIG_PROCESS:1: load enabled apps")
        self.load_enabled_apps()
        logger.debug(self, "CONFIG_PROCESS:3: load config from settings")
        self.load_config()
        logger.debug(self, "CONFIG_PROCESS:4: check validity of config given")
        self._check_consistency()
        self.check_config_validity()
        logger.debug(self, "CONFIG_PROCESS:5: End of config process")

        app_lib = ApplicationApi(app_list=app_list, show_inactive=True)
        for app in app_lib.get_all():
            logger.info(
                self,
                "LOADED_APP:{state}:{slug}:{label}".format(
                    state="ENABLED" if app.is_active else "DISABLED",
                    slug=app.slug,
                    label=app.label,
                ),
            )
Ejemplo n.º 6
0
    def index(self, context, request: TracimRequest):
        app_config = request.registry.settings["CFG"]  # type: CFG
        # TODO - G.M - 2018-08-07 - Refactor autogen valid app list for frontend
        frontend_apps = []
        app_api = ApplicationApi(app_list=app_list)
        applications = [
            app_api.get_application_in_context(app, app_config)
            for app in app_api.get_all()
        ]
        for app in applications:
            app_frontend_path = APP_FRONTEND_PATH.replace(
                "{minislug}", app.minislug)
            app_path = os.path.join(self.dist_folder_path, app_frontend_path)
            if os.path.exists(app_path):
                frontend_apps.append(app)

        base_response = None
        csp_nonce = ""
        if app_config.CONTENT_SECURITY_POLICY__ENABLED:
            csp_nonce = os.urandom(CSP_NONCE_SIZE).hex()
            csp_headers = []
            csp_header_key = ("Content-Security-Policy-Report-Only" if
                              app_config.CONTENT_SECURITY_POLICY__REPORT_ONLY
                              else "Content-Security-Policy")
            csp = "; ".join("{} {}".format(k, v)
                            for k, v in BASE_CSP_DIRECTIVES)
            csp = "{}; {}".format(
                csp, app_config.CONTENT_SECURITY_POLICY__ADDITIONAL_DIRECTIVES)
            csp_header_value = csp.format(nonce=csp_nonce)
            if app_config.CONTENT_SECURITY_POLICY__REPORT_URI:
                csp_headers.append(
                    ("Report-To",
                     app_config.CONTENT_SECURITY_POLICY__REPORT_URI))
                csp_header_value = "{}; report-uri {}".format(
                    csp_header_value,
                    app_config.CONTENT_SECURITY_POLICY__REPORT_URI)
            csp_headers.append((csp_header_key, csp_header_value))
            base_response = Response(
                headerlist=[("Content-Type", "text/html")] + csp_headers)
        return render_to_response(
            self._get_index_file_path(),
            {
                "colors": {
                    "primary": ExtendedColor(app_config.APPS_COLORS["primary"])
                },
                "applications": frontend_apps,
                "website_title": app_config.WEBSITE__TITLE,
                "custom_toolbox_files": self.custom_toolbox_files,
                "cache_token": self.cache_token,
                "excluded_notifications":
                app_config.WEB__NOTIFICATIONS__EXCLUDED,
                "csp_nonce": csp_nonce,
                "glob": self.glob,
            },
            request=request,
            response=base_response,
        )
Ejemplo n.º 7
0
 def applications(self, context, request: TracimRequest, hapic_data=None):
     """
     Get list of alls applications installed in this tracim instance.
     """
     app_config = request.registry.settings['CFG']
     app_api = ApplicationApi(
         app_list=app_list,
     )
     return app_api.get_all()
Ejemplo n.º 8
0
 def applications(self, context, request: TracimRequest, hapic_data=None):
     """
     Get list of alls applications installed in this tracim instance.
     """
     app_config = request.registry.settings["CFG"]  # type: CFG
     app_api = ApplicationApi(app_list=app_list)
     applications_in_context = [
         app_api.get_application_in_context(app, app_config) for app in app_api.get_all()
     ]
     return applications_in_context
Ejemplo n.º 9
0
    def check_config_validity(self) -> None:
        """
        Check if config setted is correct
        """
        self._check_global_config_validity()
        self._check_email_config_validity()
        self._check_ldap_config_validity()
        self._check_search_config_validity()

        app_lib = ApplicationApi(app_list=app_list)
        for app in app_lib.get_all():
            app.check_config(self)
Ejemplo n.º 10
0
 def test_api__get_applications__ok_200__nominal_case(self):
     """
     Get applications list with a registered user.
     """
     self.testapp.authorization = ("Basic", ("*****@*****.**",
                                             "*****@*****.**"))
     res = self.testapp.get("/api/v2/system/applications", status=200)
     res = res.json_body
     app_api = ApplicationApi(app_list=app_list)
     applications = app_api.get_all()
     assert len(res) == len(applications)
     for counter, application in enumerate(applications):
         assert res[counter]["label"] == application.label
         assert res[counter]["slug"] == application.slug
         assert res[counter]["fa_icon"] == application.fa_icon
         assert res[counter]["hexcolor"] == application.hexcolor
         assert res[counter]["is_active"] == application.is_active
         assert res[counter]["config"] == application.config
Ejemplo n.º 11
0
 def test_api__get_applications__ok_200__nominal_case(self):
     """
     Get applications list with a registered user.
     """
     self.testapp.authorization = ('Basic', ('*****@*****.**',
                                             '*****@*****.**'))
     res = self.testapp.get('/api/v2/system/applications', status=200)
     res = res.json_body
     dbsession = get_tm_session(self.session_factory, transaction.manager)
     app_api = ApplicationApi(app_list=app_list, )
     applications = app_api.get_all()
     assert len(res) == len(applications)
     for counter, application in enumerate(applications):
         assert res[counter]['label'] == application.label
         assert res[counter]['slug'] == application.slug
         assert res[counter]['fa_icon'] == application.fa_icon
         assert res[counter]['hexcolor'] == application.hexcolor
         assert res[counter]['is_active'] == application.is_active
         assert res[counter]['config'] == application.config
Ejemplo n.º 12
0
    def load_config(self) -> None:
        """Parse configuration file and env variables"""
        self.log_config_header("Global config parameters:")
        self._load_global_config()
        self.log_config_header("Limitation config parameters:")
        self._load_limitation_config()
        self.log_config_header("Email config parameters:")
        self._load_email_config()
        self.log_config_header("LDAP config parameters:")
        self._load_ldap_config()
        self.log_config_header("Webdav config parameters:")
        self._load_webdav_config()
        self.log_config_header("Search config parameters:")
        self._load_search_config()

        app_lib = ApplicationApi(app_list=app_list)
        for app in app_lib.get_all():
            self.log_config_header(
                '"{label}" app config parameters:'.format(label=app.label))
            app.load_config(self)
Ejemplo n.º 13
0
def web(global_config: OrderedDict, **local_settings) -> Router:
    """ This function returns a Pyramid WSGI application.
    """
    settings = deepcopy(global_config)
    settings.update(local_settings)
    # set CFG object
    app_config = CFG(settings)
    app_config.configure_filedepot()
    settings["CFG"] = app_config

    # Init plugin manager
    plugin_manager = init_plugin_manager(app_config)
    settings["plugin_manager"] = plugin_manager

    configurator = Configurator(settings=settings, autocommit=True)
    # Add beaker session cookie
    tracim_setting_for_beaker = sliced_dict(settings, beginning_key_string="session.")
    tracim_setting_for_beaker["session.data_dir"] = app_config.SESSION__DATA_DIR
    tracim_setting_for_beaker["session.lock_dir"] = app_config.SESSION__LOCK_DIR
    tracim_setting_for_beaker["session.httponly"] = app_config.SESSION__HTTPONLY
    tracim_setting_for_beaker["session.secure"] = app_config.SESSION__SECURE
    session_factory = pyramid_beaker.session_factory_from_settings(tracim_setting_for_beaker)
    configurator.set_session_factory(session_factory)
    pyramid_beaker.set_cache_regions_from_settings(tracim_setting_for_beaker)
    # Add AuthPolicy
    configurator.include("pyramid_multiauth")
    policies = []
    if app_config.REMOTE_USER_HEADER:
        policies.append(
            RemoteAuthentificationPolicy(remote_user_login_header=app_config.REMOTE_USER_HEADER)
        )
    policies.append(CookieSessionAuthentificationPolicy())
    policies.append(QueryTokenAuthentificationPolicy())
    if app_config.API__KEY:
        policies.append(
            ApiTokenAuthentificationPolicy(
                api_key_header=TRACIM_API_KEY_HEADER,
                api_user_login_header=TRACIM_API_USER_LOGIN_HEADER,
            )
        )
    policies.append(TracimBasicAuthAuthenticationPolicy(realm=BASIC_AUTH_WEBUI_REALM))
    # Hack for ldap
    if AuthType.LDAP in app_config.AUTH_TYPES:
        import ldap3

        configurator.include("pyramid_ldap3")
        configurator.ldap_setup(
            app_config.LDAP_URL,
            bind=app_config.LDAP_BIND_DN,
            passwd=app_config.LDAP_BIND_PASS,
            use_tls=app_config.LDAP_TLS,
            use_pool=app_config.LDAP_USE_POOL,
            pool_size=app_config.LDAP_POOL_SIZE,
            pool_lifetime=app_config.LDAP_POOL_LIFETIME,
            get_info=app_config.LDAP_GET_INFO,
        )
        configurator.ldap_set_login_query(
            base_dn=app_config.LDAP_USER_BASE_DN,
            filter_tmpl=app_config.LDAP_USER_FILTER,
            scope=ldap3.LEVEL,
            attributes=ldap3.ALL_ATTRIBUTES,
        )

    configurator.include(add_cors_support)
    # make sure to add this before other routes to intercept OPTIONS
    configurator.add_cors_preflight_handler()
    # Default authorization : Accept anything.
    configurator.set_authorization_policy(AcceptAllAuthorizationPolicy())
    authn_policy = MultiAuthenticationPolicy(policies)
    configurator.set_authentication_policy(authn_policy)
    # INFO - GM - 11-04-2018 - set default perm
    # setting default perm is needed to force authentification
    # mechanism in all views.
    configurator.set_default_permission(TRACIM_DEFAULT_PERM)
    # Override default request
    configurator.set_request_factory(TracimRequest)
    # Pyramids "plugin" include.
    # Add SqlAlchemy DB
    init_models(configurator, app_config)
    # set Hapic
    context = TracimPyramidContext(
        configurator=configurator, default_error_builder=ErrorSchema(), debug=app_config.DEBUG
    )
    hapic.set_context(context)
    # INFO - G.M - 2018-07-04 - global-context exceptions
    # Not found
    context.handle_exception(PageNotFound, HTTPStatus.NOT_FOUND)
    # Bad request
    context.handle_exception(WorkspaceNotFoundInTracimRequest, HTTPStatus.BAD_REQUEST)
    context.handle_exception(UserNotFoundInTracimRequest, HTTPStatus.BAD_REQUEST)
    context.handle_exception(ContentNotFoundInTracimRequest, HTTPStatus.BAD_REQUEST)
    context.handle_exception(WorkspaceNotFound, HTTPStatus.BAD_REQUEST)
    context.handle_exception(UserDoesNotExist, HTTPStatus.BAD_REQUEST)
    context.handle_exception(ContentNotFound, HTTPStatus.BAD_REQUEST)
    context.handle_exception(ContentTypeNotExist, HTTPStatus.BAD_REQUEST)
    context.handle_exception(ContentInNotEditableState, HTTPStatus.BAD_REQUEST)
    context.handle_exception(ContentTypeNotAllowed, HTTPStatus.BAD_REQUEST)
    context.handle_exception(InvalidId, HTTPStatus.BAD_REQUEST)
    context.handle_exception(SameValueError, HTTPStatus.BAD_REQUEST)
    # Auth exception
    context.handle_exception(NotAuthenticated, HTTPStatus.UNAUTHORIZED)
    context.handle_exception(UserGivenIsNotTheSameAsAuthenticated, HTTPStatus.FORBIDDEN)
    context.handle_exception(UserAuthenticatedIsNotActive, HTTPStatus.FORBIDDEN)
    context.handle_exception(AuthenticationFailed, HTTPStatus.FORBIDDEN)
    context.handle_exception(InsufficientUserRoleInWorkspace, HTTPStatus.FORBIDDEN)
    context.handle_exception(InsufficientUserProfile, HTTPStatus.FORBIDDEN)
    # Internal server error
    context.handle_exception(OperationalError, HTTPStatus.INTERNAL_SERVER_ERROR)
    context.handle_exception(Exception, HTTPStatus.INTERNAL_SERVER_ERROR)

    # Add controllers
    session_controller = SessionController()
    system_controller = SystemController()
    user_controller = UserController()
    account_controller = AccountController()
    reset_password_controller = ResetPasswordController()
    workspace_controller = WorkspaceController()
    comment_controller = CommentController()
    configurator.include(session_controller.bind, route_prefix=BASE_API)
    configurator.include(system_controller.bind, route_prefix=BASE_API)
    configurator.include(user_controller.bind, route_prefix=BASE_API)
    configurator.include(account_controller.bind, route_prefix=BASE_API)
    configurator.include(reset_password_controller.bind, route_prefix=BASE_API)
    configurator.include(workspace_controller.bind, route_prefix=BASE_API)
    configurator.include(comment_controller.bind, route_prefix=BASE_API)

    app_lib = ApplicationApi(app_list=app_list)
    for app in app_lib.get_all():
        app.load_controllers(
            app_config=app_config, configurator=configurator, route_prefix=BASE_API, context=context
        )

    configurator.scan("tracim_backend.lib.utils.authentification")

    # TODO - G.M - 2019-05-17 - check if possible to avoid this import here,
    # import is here because import SearchController without adding it to
    # pyramid make trouble in hapic which try to get view related
    # to controller but failed.
    from tracim_backend.lib.search.search_factory import SearchFactory

    search_controller = SearchFactory.get_search_controller(app_config)

    configurator.include(search_controller.bind, route_prefix=BASE_API)
    if app_config.FRONTEND__SERVE:
        configurator.include("pyramid_mako")
        frontend_controller = FrontendController(
            dist_folder_path=app_config.FRONTEND__DIST_FOLDER_PATH,
            custom_toolbox_folder_path=app_config.FRONTEND__CUSTOM_TOOLBOX_FOLDER_PATH,
            cache_token=app_config.FRONTEND__CACHE_TOKEN,
        )
        configurator.include(frontend_controller.bind)

    # INFO - G.M - 2019-11-27 - Include plugin custom web code
    plugin_manager.hook.web_include(configurator=configurator, app_config=app_config)

    hapic.add_documentation_view("/api/doc", "Tracim API", "API of Tracim")
    return configurator.make_wsgi_app()
Ejemplo n.º 14
0
 def applications(self, context, request: TracimRequest, hapic_data=None):
     """
     Get list of alls applications installed in this tracim instance.
     """
     app_api = ApplicationApi(app_list=app_list)
     return app_api.get_all()