Ejemplo n.º 1
0
    def test_api___simple_search_ok__no_search_string(self) -> 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)
        gapi = GroupApi(current_user=admin, session=dbsession, config=self.app_config)
        groups = [gapi.get_one_with_name("trusted-users")]
        user = uapi.create_user(
            "*****@*****.**",
            password="******",
            do_save=True,
            do_notify=False,
            groups=groups,
        )
        workspace_api = WorkspaceApi(
            current_user=admin, session=dbsession, config=self.app_config, show_deleted=True
        )
        workspace = workspace_api.create_workspace("test", save_now=True)
        rapi = RoleApi(current_user=admin, session=dbsession, config=self.app_config)
        rapi.create_one(user, workspace, UserRoleInWorkspace.WORKSPACE_MANAGER, False)
        api = ContentApi(session=dbsession, current_user=user, config=self.app_config)
        api.create(
            content_type_slug="html-document", workspace=workspace, label="test", do_save=True
        )
        transaction.commit()

        self.testapp.authorization = ("Basic", ("*****@*****.**", "*****@*****.**"))
        res = self.testapp.get("/api/v2/search/content".format(), status=200)
        search_result = res.json_body
        assert search_result
        assert search_result["total_hits"] == 0
        assert search_result["is_total_hits_accurate"] is True
        assert len(search_result["contents"]) == 0
Ejemplo n.º 2
0
    def _create_content_event(self, operation: OperationType, content: Content,
                              context: TracimContext) -> None:
        current_user = context.safe_current_user()
        content_api = ContentApi(context.dbsession, current_user, self._config)
        content_in_context = content_api.get_content_in_context(content)
        content_schema = EventApi.get_content_schema_for_type(content.type)
        content_dict = content_schema.dump(content_in_context).data

        workspace_api = WorkspaceApi(context.dbsession,
                                     current_user,
                                     self._config,
                                     show_deleted=True)
        workspace_in_context = workspace_api.get_workspace_with_context(
            workspace_api.get_one(content_in_context.workspace.workspace_id))
        fields = {
            Event.CONTENT_FIELD:
            content_dict,
            Event.WORKSPACE_FIELD:
            EventApi.workspace_schema.dump(workspace_in_context).data,
        }
        event_api = EventApi(current_user, context.dbsession, self._config)
        event_api.create_event(
            entity_type=EntityType.CONTENT,
            operation=operation,
            additional_fields=fields,
            entity_subtype=content.type,
            context=context,
        )
Ejemplo n.º 3
0
 def test_proxy_workspace_agenda__err__other_workspace_agenda(self) -> 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)
     gapi = GroupApi(current_user=admin,
                     session=dbsession,
                     config=self.app_config)
     groups = [gapi.get_one_with_name("users")]
     uapi.create_user(
         "*****@*****.**",
         password="******",
         do_save=True,
         do_notify=False,
         groups=groups,
     )
     workspace_api = WorkspaceApi(current_user=admin,
                                  session=dbsession,
                                  config=self.app_config,
                                  show_deleted=True)
     workspace = workspace_api.create_workspace("test", save_now=True)
     transaction.commit()
     self.testapp.authorization = ("Basic", ("*****@*****.**",
                                             "*****@*****.**"))
     result = self.testapp.get("/agenda/workspace/{}/".format(
         workspace.workspace_id),
                               status=403)
     assert result.json_body["code"] == 5001
Ejemplo n.º 4
0
 def account_contents_read_status(self,
                                  context,
                                  request: TracimRequest,
                                  hapic_data=None):
     """
     get user_read status of contents
     """
     app_config = request.registry.settings["CFG"]  # type: CFG
     api = ContentApi(
         current_user=request.current_user,
         session=request.dbsession,
         config=app_config  # User
     )
     wapi = WorkspaceApi(
         current_user=request.current_user,
         session=request.dbsession,
         config=app_config  # User
     )
     workspace = None
     if hapic_data.path.workspace_id:
         workspace = wapi.get_one(hapic_data.path.workspace_id)
     last_actives = api.get_last_active(
         workspace=workspace,
         limit=None,
         before_content=None,
         content_ids=hapic_data.query.content_ids or None,
     )
     return [
         api.get_content_in_context(content) for content in last_actives
     ]
Ejemplo n.º 5
0
 def __init__(
     self,
     path: str,
     environ: dict,
     label: str,
     workspace: typing.Optional[Workspace],
     provider: "TracimDavProvider",
     tracim_context: "WebdavTracimContext",
     list_orphan_workspaces: bool = False,
 ) -> None:
     """
     Some rules:
     - if workspace given is None, return workspaces with no parent
     - if workspace given is correct, return children workspaces of this workspace
     - if list_orphan_workspaces is True, it
      adds user-known workspaces without any user-known parent to the list.
      - in case of workspace collision, only the first named workspace (sorted by workspace_id
      from lower to higher) will be returned
     """
     self.path = path
     self.environ = environ
     self.workspace = workspace
     self.tracim_context = tracim_context
     self.user = tracim_context.current_user
     self.session = tracim_context.dbsession
     self.label = label
     self.provider = provider
     self.workspace_api = WorkspaceApi(
         current_user=self.user,
         session=self.session,
         force_role=True,
         config=tracim_context.app_config,
     )
     self.list_orphan_workspaces = list_orphan_workspaces
Ejemplo n.º 6
0
    def should_anonymize(self,
                         user: User,
                         owned_workspace_will_be_deleted: bool = False
                         ) -> UserNeedAnonymization:
        wapi = WorkspaceApi(config=self.app_config,
                            session=self.session,
                            current_user=user,
                            show_deleted=True)
        user_owned_workspaces_to_filter = wapi.get_all_for_user(
            user, include_owned=True, include_with_role=False)

        query = self.session.query(ContentRevisionRO)
        if owned_workspace_will_be_deleted:
            query = query.filter(~ContentRevisionRO.workspace_id.in_([
                workspace.workspace_id
                for workspace in user_owned_workspaces_to_filter
            ]))
            user_blocking_workspaces = []
        else:
            user_blocking_workspaces = user_owned_workspaces_to_filter

        query = query.filter(ContentRevisionRO.owner_id == user.user_id)
        user_blocking_revisions = query.all()
        return UserNeedAnonymization(
            blocking_workspaces=user_blocking_workspaces,
            blocking_revisions=user_blocking_revisions)
Ejemplo n.º 7
0
    def test_children(self, admin_user, session, app_config,
                      content_api_factory, content_type_list):
        workspace = WorkspaceApi(current_user=admin_user,
                                 session=session,
                                 config=app_config).create_workspace(
                                     "workspace_1", save_now=True)
        folder = Content(type=content_type_list.Folder.slug, owner=admin_user)
        folder.label = "folder_1"
        folder.workspace = workspace
        session.add(folder)
        session.flush()

        thread = Content(type=content_type_list.Thread.slug,
                         owner=admin_user,
                         parent=folder)
        thread.label = "thread_1"
        thread.workspace = workspace
        session.add(folder)
        session.flush()
        workspace = session.query(Workspace).filter(
            Workspace.label == "workspace_1").one()
        content_api = content_api_factory.get()
        folder = content_api.get_canonical_query().filter(
            Content.label == "folder_1").one()
        assert [folder] == list(workspace.get_valid_children())
Ejemplo n.º 8
0
 def test_unit__get_known__user__distinct_workspaces_users_by_name__exclude_workspace(self):
     admin = self.session.query(User) \
         .filter(User.email == '*****@*****.**') \
         .one()
     api = UserApi(
         current_user=None,
         session=self.session,
         config=self.app_config,
     )
     u1 = api.create_user(
         email='email@email',
         name='name',
         do_notify=False,
         do_save=True,
     )
     u2 = api.create_user(
         email='email2@email2',
         name='name2',
         do_notify=False,
         do_save=True,
     )
     u3 = api.create_user(
         email='notfound@notfound',
         name='notfound',
         do_notify=False,
         do_save=True,
     )
     wapi = WorkspaceApi(
         current_user=admin,
         session=self.session,
         config=self.app_config,
     )
     workspace = wapi.create_workspace(
         'test workspace n°1',
         save_now=True)
     wapi = WorkspaceApi(
         current_user=admin,
         session=self.session,
         config=self.app_config,
     )
     workspace_2 = wapi.create_workspace(
         'test workspace n°2',
         save_now=True)
     role_api = RoleApi(
         current_user=admin,
         session=self.session,
         config=self.app_config,
     )
     role_api.create_one(u1, workspace, UserRoleInWorkspace.READER, False)
     role_api.create_one(u2, workspace_2, UserRoleInWorkspace.READER, False)
     role_api.create_one(u3, workspace, UserRoleInWorkspace.READER, False)
     role_api.create_one(u3, workspace_2, UserRoleInWorkspace.READER, False)
     api2 = UserApi(
         current_user=u3,
         session=self.session,
         config=self.app_config,
     )
     users = api2.get_known_user('name', exclude_workspace_ids=[workspace.workspace_id])
     assert len(users) == 1
     assert users[0] == u2
Ejemplo n.º 9
0
 def account_last_active_content(self, context, request: TracimRequest, hapic_data=None):  # nopep8
     """
     Get last_active_content for user
     """
     app_config = request.registry.settings['CFG']
     content_filter = hapic_data.query
     api = ContentApi(
         current_user=request.current_user,  # User
         session=request.dbsession,
         config=app_config,
     )
     wapi = WorkspaceApi(
         current_user=request.current_user,  # User
         session=request.dbsession,
         config=app_config,
     )
     workspace = None
     if hapic_data.path.workspace_id:
         workspace = wapi.get_one(hapic_data.path.workspace_id)
     before_content = None
     if content_filter.before_content_id:
         before_content = api.get_one(
             content_id=content_filter.before_content_id,
             workspace=workspace,
             content_type=content_type_list.Any_SLUG
         )
     last_actives = api.get_last_active(
         workspace=workspace,
         limit=content_filter.limit or None,
         before_content=before_content,
     )
     return [
         api.get_content_in_context(content)
         for content in last_actives
     ]
Ejemplo n.º 10
0
    def _get_content(self, content_path_fetcher):
        path = content_path_fetcher()
        content_path = self.reduce_path(path)
        splited_local_path = content_path.strip('/').split('/')
        workspace_name = webdav_convert_file_name_to_bdd(splited_local_path[0])
        wapi = WorkspaceApi(
            current_user=self.current_user,
            session=self.dbsession,
            config=self.app_config,
        )
        workspace = wapi.get_one_by_label(workspace_name)
        parents = []
        if len(splited_local_path) > 2:
            parent_string = splited_local_path[1:-1]
            parents = [webdav_convert_file_name_to_bdd(x) for x in parent_string]

        content_api = ContentApi(
            config=self.app_config,
            current_user=self.current_user,
            session=self.dbsession
        )
        return content_api.get_one_by_filename_and_parent_labels(
            content_label=webdav_convert_file_name_to_bdd(basename(path)),
            content_parent_labels=parents,
            workspace=workspace,
        )
Ejemplo n.º 11
0
 def delete_comment(self, context, request: TracimRequest, hapic_data=None):
     """
     Delete comment
     """
     app_config = request.registry.settings['CFG']
     api = ContentApi(
         show_archived=True,
         show_deleted=True,
         current_user=request.current_user,
         session=request.dbsession,
         config=app_config,
     )
     wapi = WorkspaceApi(
         current_user=request.current_user,
         session=request.dbsession,
         config=app_config,
     )
     workspace = wapi.get_one(hapic_data.path.workspace_id)
     parent = api.get_one(hapic_data.path.content_id,
                          content_type=content_type_list.Any_SLUG,
                          workspace=workspace)
     comment = api.get_one(
         hapic_data.path.comment_id,
         content_type=content_type_list.Comment.slug,
         workspace=workspace,
         parent=parent,
     )
     with new_revision(session=request.dbsession,
                       tm=transaction.manager,
                       content=comment):
         api.delete(comment)
     return
Ejemplo n.º 12
0
 def account_contents_read_status(self, context, request: TracimRequest, hapic_data=None):  # nopep8
     """
     get user_read status of contents
     """
     app_config = request.registry.settings['CFG']
     content_filter = hapic_data.query
     api = ContentApi(
         current_user=request.current_user,  # User
         session=request.dbsession,
         config=app_config,
     )
     wapi = WorkspaceApi(
         current_user=request.current_user,  # User
         session=request.dbsession,
         config=app_config,
     )
     workspace = None
     if hapic_data.path.workspace_id:
         workspace = wapi.get_one(hapic_data.path.workspace_id)
     last_actives = api.get_last_active(
         workspace=workspace,
         limit=None,
         before_content=None,
         content_ids=hapic_data.query.content_ids or None
     )
     return [
         api.get_content_in_context(content)
         for content in last_actives
     ]
Ejemplo n.º 13
0
 def contents_read_status(self,
                          context,
                          request: TracimRequest,
                          hapic_data=None):  # nopep8
     """
     get user_read status of contents
     """
     app_config = request.registry.settings['CFG']
     content_filter = hapic_data.query
     api = ContentApi(
         current_user=request.candidate_user,  # User
         session=request.dbsession,
         config=app_config,
     )
     wapi = WorkspaceApi(
         current_user=request.candidate_user,  # User
         session=request.dbsession,
         config=app_config,
     )
     workspace = None
     if hapic_data.path.workspace_id:
         workspace = wapi.get_one(hapic_data.path.workspace_id)
     last_actives = api.get_last_active(
         workspace=workspace,
         limit=None,
         before_content=None,
         content_ids=hapic_data.query.contents_ids or None)
     return [
         api.get_content_in_context(content) for content in last_actives
     ]
Ejemplo n.º 14
0
    def test_unit__get_all_manageable(
        self, admin_user, session, app_config, user_api_factory, role_api_factory
    ):

        uapi = user_api_factory.get()
        # Checks a case without workspaces.
        wapi = WorkspaceApi(session=session, current_user=admin_user, config=app_config)
        assert [] == wapi.get_all_manageable()
        # Checks an admin_user gets all workspaces.
        w4 = wapi.create_workspace(label="w4")
        w3 = wapi.create_workspace(label="w3")
        w2 = wapi.create_workspace(label="w2")
        w1 = wapi.create_workspace(label="w1")
        assert [w1, w2, w3, w4] == wapi.get_all_manageable()
        # Checks a regular user gets none workspace.

        u = uapi.create_minimal_user("[email protected]", profile=Profile.USER, save_now=True)
        wapi = WorkspaceApi(session=session, current_user=u, config=app_config)
        rapi = role_api_factory.get()
        rapi.create_one(u, w4, UserRoleInWorkspace.READER, False)
        rapi.create_one(u, w3, UserRoleInWorkspace.CONTRIBUTOR, False)
        rapi.create_one(u, w2, UserRoleInWorkspace.CONTENT_MANAGER, False)
        rapi.create_one(u, w1, UserRoleInWorkspace.WORKSPACE_MANAGER, False)
        assert [] == wapi.get_all_manageable()
        # Checks a manager gets only its own workspaces.
        u.profile = Profile.TRUSTED_USER
        rapi.delete_one(u.user_id, w2.workspace_id)
        rapi.create_one(u, w2, UserRoleInWorkspace.WORKSPACE_MANAGER, False)
        assert [w1, w2] == wapi.get_all_manageable()
Ejemplo n.º 15
0
    def test_unit__create_workspace_same__ok__same_workspace_name_allowed(
        self, admin_user, session, app_config
    ):

        wapi = WorkspaceApi(session=session, current_user=admin_user, config=app_config)
        wapi.create_workspace(label="business", save_now=True)
        wapi.create_workspace(label="business", save_now=True)
Ejemplo n.º 16
0
 def _get_current_workspace(
         self,
         user: User,
         request: 'TracimRequest'
 ) -> Workspace:
     """
     Get current workspace from request
     :param user: User who want to check the workspace
     :param request: pyramid request
     :return: current workspace
     """
     workspace_id = ''
     try:
         if 'workspace_id' in request.matchdict:
             workspace_id_str = request.matchdict['workspace_id']
             if not isinstance(workspace_id_str, str) or not workspace_id_str.isdecimal():  # nopep8
                 raise InvalidWorkspaceId('workspace_id is not a correct integer')  # nopep8
             workspace_id = int(request.matchdict['workspace_id'])
         if not workspace_id:
             raise WorkspaceNotFoundInTracimRequest('No workspace_id property found in request')  # nopep8
         wapi = WorkspaceApi(
             current_user=user,
             session=request.dbsession,
             config=request.registry.settings['CFG'],
             show_deleted=True,
         )
         workspace = wapi.get_one(workspace_id)
     except NoResultFound as exc:
         raise WorkspaceNotFound(
             'Workspace {} does not exist '
             'or is not visible for this user'.format(workspace_id)
         ) from exc
     return workspace
Ejemplo n.º 17
0
    def guest_download_check(self,
                             context,
                             request: TracimRequest,
                             hapic_data=None) -> None:
        """
        Check if share token is correct and password given valid
        """
        app_config = request.registry.settings["CFG"]  # type: CFG
        api = ShareLib(current_user=None,
                       session=request.dbsession,
                       config=app_config)
        content_share = api.get_content_share_by_token(
            share_token=hapic_data.path.share_token)  # type: ContentShare

        # TODO - G.M - 2019-08-01 - verify in access to content share can be granted
        # we should considered do these check at decorator level
        api.check_password(content_share, password=hapic_data.body.password)
        content = ContentApi(current_user=None,
                             session=request.dbsession,
                             config=app_config).get_one(
                                 content_share.content_id,
                                 content_type=content_type_list.Any_SLUG)
        workspace_api = WorkspaceApi(current_user=None,
                                     session=request.dbsession,
                                     config=app_config)
        workspace = workspace_api.get_one(content.workspace_id)
        workspace_api.check_public_download_enabled(workspace)
        if content.type not in shareables_content_type:
            raise ContentTypeNotAllowed()
Ejemplo n.º 18
0
    def _get_content(self, content_path_fetcher):
        path = content_path_fetcher()
        content_path = self.reduce_path(path)
        splited_local_path = content_path.strip('/').split('/')
        workspace_name = webdav_convert_file_name_to_bdd(splited_local_path[0])
        wapi = WorkspaceApi(
            current_user=self.current_user,
            session=self.dbsession,
            config=self.app_config,
        )
        workspace = wapi.get_one_by_label(workspace_name)
        parents = []
        if len(splited_local_path) > 2:
            parent_string = splited_local_path[1:-1]
            parents = [
                webdav_convert_file_name_to_bdd(x) for x in parent_string
            ]

        content_api = ContentApi(config=self.app_config,
                                 current_user=self.current_user,
                                 session=self.dbsession)
        return content_api.get_one_by_filename_and_parent_labels(
            content_label=webdav_convert_file_name_to_bdd(basename(path)),
            content_parent_labels=parents,
            workspace=workspace,
        )
Ejemplo n.º 19
0
 def last_active_content(self,
                         context,
                         request: TracimRequest,
                         hapic_data=None):
     """
     Get last_active_content for user
     """
     app_config = request.registry.settings["CFG"]  # type: CFG
     content_filter = hapic_data.query
     api = ContentApi(
         current_user=request.candidate_user,  # User
         session=request.dbsession,
         config=app_config,
     )
     wapi = WorkspaceApi(
         current_user=request.candidate_user,  # User
         session=request.dbsession,
         config=app_config,
     )
     workspace = None
     if hapic_data.path.workspace_id:
         workspace = wapi.get_one(hapic_data.path.workspace_id)
     before_content = None
     if content_filter.before_content_id:
         before_content = api.get_one(
             content_id=content_filter.before_content_id,
             workspace=workspace,
             content_type=content_type_list.Any_SLUG,
         )
     last_actives = api.get_last_active(workspace=workspace,
                                        limit=content_filter.limit or None,
                                        before_content=before_content)
     return [
         api.get_content_in_context(content) for content in last_actives
     ]
Ejemplo n.º 20
0
    def used_space(self) -> int:
        from tracim_backend.lib.core.workspace import WorkspaceApi

        wapi = WorkspaceApi(current_user=None,
                            session=self.dbsession,
                            config=self.config)
        return wapi.get_user_used_space(self.user)
Ejemplo n.º 21
0
 def _create_subscription_event(self, operation: OperationType,
                                subscription: WorkspaceSubscription,
                                context: TracimContext) -> None:
     current_user = context.safe_current_user()
     workspace_api = WorkspaceApi(
         session=context.dbsession,
         config=self._config,
         current_user=None,
     )
     workspace_in_context = workspace_api.get_workspace_with_context(
         workspace_api.get_one(subscription.workspace_id))
     user_api = UserApi(current_user,
                        context.dbsession,
                        self._config,
                        show_deleted=True)
     subscription_author_in_context = user_api.get_user_with_context(
         subscription.author)
     fields = {
         Event.WORKSPACE_FIELD:
         EventApi.workspace_schema.dump(workspace_in_context).data,
         Event.SUBSCRIPTION_FIELD:
         EventApi.workspace_subscription_schema.dump(subscription).data,
         Event.USER_FIELD:
         EventApi.user_schema.dump(subscription_author_in_context).data,
     }
     event_api = EventApi(current_user, context.dbsession, self._config)
     event_api.create_event(
         entity_type=EntityType.WORKSPACE_SUBSCRIPTION,
         operation=operation,
         additional_fields=fields,
         context=context,
     )
Ejemplo n.º 22
0
    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>'
        )
Ejemplo n.º 23
0
 def test_proxy_user_agenda__ok__workspace_filter(self) -> 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)
     gapi = GroupApi(current_user=admin,
                     session=dbsession,
                     config=self.app_config)
     groups = [gapi.get_one_with_name("users")]
     user = uapi.create_user(
         "*****@*****.**",
         password="******",
         do_save=True,
         do_notify=False,
         groups=groups,
     )
     workspace_api = WorkspaceApi(current_user=admin,
                                  session=dbsession,
                                  config=self.app_config,
                                  show_deleted=True)
     workspace = workspace_api.create_workspace("wp1", save_now=True)
     workspace.agenda_enabled = True
     workspace2 = workspace_api.create_workspace("wp2", save_now=True)
     workspace2.agenda_enabled = True
     workspace3 = workspace_api.create_workspace("wp3", save_now=True)
     workspace3.agenda_enabled = True
     rapi = RoleApi(current_user=admin,
                    session=dbsession,
                    config=self.app_config)
     rapi.create_one(user, workspace, UserRoleInWorkspace.CONTRIBUTOR,
                     False)
     rapi.create_one(user, workspace2, UserRoleInWorkspace.READER, False)
     rapi.create_one(user, workspace3, UserRoleInWorkspace.READER, False)
     transaction.commit()
     self.testapp.authorization = ("Basic", ("*****@*****.**",
                                             "*****@*****.**"))
     params = {
         "workspace_ids":
         "{},{}".format(workspace.workspace_id, workspace3.workspace_id),
         "agenda_types":
         "workspace",
     }
     result = self.testapp.get("/api/v2/users/{}/agenda".format(
         user.user_id),
                               params=params,
                               status=200)
     assert len(result.json_body) == 2
     agenda = result.json_body[0]
     assert agenda[
         "agenda_url"] == "http://localhost:6543/agenda/workspace/{}/".format(
             workspace.workspace_id)
     assert agenda["with_credentials"] is True
     agenda = result.json_body[1]
     assert agenda[
         "agenda_url"] == "http://localhost:6543/agenda/workspace/{}/".format(
             workspace3.workspace_id)
     assert agenda["with_credentials"] is True
Ejemplo n.º 24
0
    def test_api___simple_search_ok__by_comment_content(
        self,
        created_content_name,
        search_string,
        nb_content_result,
        first_search_result_content_name,
        first_created_comment_content,
        second_created_comment_content,
    ) -> 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)
        gapi = GroupApi(current_user=admin, session=dbsession, config=self.app_config)
        groups = [gapi.get_one_with_name("trusted-users")]
        user = uapi.create_user(
            "*****@*****.**",
            password="******",
            do_save=True,
            do_notify=False,
            groups=groups,
        )
        workspace_api = WorkspaceApi(
            current_user=admin, session=dbsession, config=self.app_config, show_deleted=True
        )
        workspace = workspace_api.create_workspace("test", save_now=True)
        rapi = RoleApi(current_user=admin, session=dbsession, config=self.app_config)
        rapi.create_one(user, workspace, UserRoleInWorkspace.WORKSPACE_MANAGER, False)
        api = ContentApi(session=dbsession, current_user=user, config=self.app_config)
        content = api.create(
            content_type_slug="html-document",
            workspace=workspace,
            label=created_content_name,
            do_save=True,
        )
        api.create_comment(
            workspace=workspace, parent=content, content=first_created_comment_content, do_save=True
        )
        api.create_comment(
            workspace=workspace,
            parent=content,
            content=second_created_comment_content,
            do_save=True,
        )
        api.create(
            content_type_slug="html-document", workspace=workspace, label="report", do_save=True
        )
        api.create(
            content_type_slug="thread", workspace=workspace, label="discussion", do_save=True
        )
        transaction.commit()

        self.testapp.authorization = ("Basic", ("*****@*****.**", "*****@*****.**"))
        params = {"search_string": search_string}
        res = self.testapp.get("/api/v2/search/content".format(), status=200, params=params)
        search_result = res.json_body
        assert search_result
        assert search_result["total_hits"] == nb_content_result
        assert search_result["is_total_hits_accurate"] is False
        assert search_result["contents"][0]["label"] == first_search_result_content_name
Ejemplo n.º 25
0
 def on_user_role_in_workspace_deleted(self, role: UserRoleInWorkspace,
                                       context: TracimContext) -> None:
     wapi = WorkspaceApi(context.dbsession, None, context.app_config)
     rapi = RoleApi(context.dbsession, None, context.app_config)
     for workspace in wapi.get_all_for_user(role.user):
         rapi.delete_one(role.user.user_id,
                         workspace.workspace_id,
                         flush=False)
Ejemplo n.º 26
0
    def test_api__elasticsearch_search__ok__in_file_ingest_search(self):
        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)
        gapi = GroupApi(current_user=admin,
                        session=dbsession,
                        config=self.app_config)
        groups = [gapi.get_one_with_name("trusted-users")]
        user = uapi.create_user(
            "*****@*****.**",
            password="******",
            do_save=True,
            do_notify=False,
            groups=groups,
        )
        workspace_api = WorkspaceApi(current_user=admin,
                                     session=dbsession,
                                     config=self.app_config,
                                     show_deleted=True)
        workspace = workspace_api.create_workspace("test", save_now=True)
        rapi = RoleApi(current_user=admin,
                       session=dbsession,
                       config=self.app_config)
        rapi.create_one(user, workspace, UserRoleInWorkspace.WORKSPACE_MANAGER,
                        False)
        api = ContentApi(session=dbsession,
                         current_user=user,
                         config=self.app_config)
        with self.session.no_autoflush:
            text_file = api.create(
                content_type_slug=content_type_list.File.slug,
                workspace=workspace,
                label="important",
                do_save=False,
            )
            api.update_file_data(text_file, "test_file", "text/plain",
                                 b"we need to find stringtosearch here !")
            api.save(text_file)
            api.execute_created_content_actions(text_file)
        content_id = text_file.content_id
        transaction.commit()
        self.refresh_elasticsearch()

        params = {"search_string": "stringtosearch"}
        self.testapp.authorization = ("Basic", ("*****@*****.**",
                                                "*****@*****.**"))
        res = self.testapp.get("/api/v2/search/content".format(),
                               status=200,
                               params=params)
        search_result = res.json_body
        assert search_result
        assert search_result["total_hits"] == 1
        assert search_result["is_total_hits_accurate"] is True
        assert len(search_result["contents"]) == 1
        assert search_result["contents"][0]["content_id"] == content_id
Ejemplo n.º 27
0
    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
Ejemplo n.º 28
0
    def test_unit__rename_workspace_same_workspace_same_name__ok__nominal_case(
        self, admin_user, session, app_config
    ):

        wapi = WorkspaceApi(session=session, current_user=admin_user, config=app_config)
        workspace1 = wapi.create_workspace(label="business", save_now=True)
        modified_datetime = workspace1.updated
        wapi.update_workspace(workspace=workspace1, label="business", description="")
        assert workspace1.updated != modified_datetime
Ejemplo n.º 29
0
    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
Ejemplo n.º 30
0
 def _get_workspace(self, workspace_id_fetcher):
     workspace_id = workspace_id_fetcher()
     wapi = WorkspaceApi(
         current_user=self.current_user,
         session=self.dbsession,
         config=self.app_config,
         show_deleted=True,
     )
     return wapi.get_one_by_label(workspace_id)
Ejemplo n.º 31
0
 def _get_workspace(self, workspace_id_fetcher):
     workspace_id = workspace_id_fetcher()
     wapi = WorkspaceApi(
         current_user=self.current_user,
         session=self.dbsession,
         config=self.app_config,
         show_deleted=True,
     )
     return wapi.get_one_by_label(workspace_id)
Ejemplo n.º 32
0
    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
Ejemplo n.º 33
0
 def _get_workspace(
         self, workspace_id_fetcher: typing.Callable[[], int]) -> Workspace:
     workspace_id = workspace_id_fetcher()
     wapi = WorkspaceApi(
         current_user=self.current_user,
         session=self.dbsession,
         config=self.app_config,
         show_deleted=True,
     )
     return wapi.get_one(workspace_id)
Ejemplo n.º 34
0
 def workspace(self, context, request: TracimRequest, hapic_data=None):
     """
     Get workspace informations
     """
     app_config = request.registry.settings['CFG']
     wapi = WorkspaceApi(
         current_user=request.current_user,  # User
         session=request.dbsession,
         config=app_config,
     )
     return wapi.get_workspace_with_context(request.current_workspace)
Ejemplo n.º 35
0
    def test__unit__workspace_deletion__ok__nominal_case(
        self, session, admin_user, app_config
    ) -> None:

        wapi = WorkspaceApi(session=session, current_user=admin_user, config=app_config)
        business_workspace = wapi.create_workspace(label="business")
        assert business_workspace.label == "business"
        wapi.delete(business_workspace)
        assert business_workspace.is_deleted is True
        assert business_workspace.label != "business"
        assert business_workspace.label.startswith("business-deleted-")
Ejemplo n.º 36
0
    def guest_download_file(self,
                            context,
                            request: TracimRequest,
                            hapic_data=None) -> HapicFile:
        app_config = request.registry.settings["CFG"]  # type: CFG
        api = ShareLib(current_user=None,
                       session=request.dbsession,
                       config=app_config)
        content_share = api.get_content_share_by_token(
            share_token=hapic_data.path.share_token)  # type: ContentShare

        # TODO - G.M - 2019-08-01 - verify in access to content share can be granted
        # we should considered do these check at decorator level
        if hapic_data.forms:
            password = hapic_data.forms.password
        else:
            password = None
        api.check_password(content_share, password=password)
        content = ContentApi(current_user=None,
                             session=request.dbsession,
                             config=app_config).get_one(
                                 content_share.content_id,
                                 content_type=content_type_list.Any_SLUG)
        workspace_api = WorkspaceApi(current_user=None,
                                     session=request.dbsession,
                                     config=app_config)
        workspace = workspace_api.get_one(content.workspace_id)
        workspace_api.check_public_download_enabled(workspace)
        if content.type not in shareables_content_type:
            raise ContentTypeNotAllowed()

        try:
            file = DepotManager.get(
                app_config.UPLOADED_FILES__STORAGE__STORAGE_NAME).get(
                    content.depot_file)
        except IOError as exc:
            raise TracimFileNotFound(
                "file related to revision {} of content {} not found in depot."
                .format(content.cached_revision_id,
                        content.content_id)) from exc
        filename = hapic_data.path.filename

        # INFO - G.M - 2019-08-08 - use given filename in all case but none or
        # "raw", when filename returned will be original file one.
        if not filename or filename == "raw":
            filename = content.file_name
        return HapicFile(
            file_object=file,
            mimetype=file.content_type,
            filename=filename,
            as_attachment=True,
            content_length=file.content_length,
            last_modified=content.updated,
        )
Ejemplo n.º 37
0
 def workspace(self, context, request: TracimRequest, hapic_data=None):
     """
     Get workspace informations
     """
     app_config = request.registry.settings['CFG']
     wapi = WorkspaceApi(
         current_user=request.current_user,  # User
         session=request.dbsession,
         config=app_config,
     )
     return wapi.get_workspace_with_context(request.current_workspace)
Ejemplo n.º 38
0
 def delete_workspace(self, context, request: TracimRequest, hapic_data=None):  # nopep8
     """
     Delete a workspace. This route is for trusted users and administrators.
     Note : a trusted user can only delete spaces on which he/she is space manager
     """
     app_config = request.registry.settings['CFG']
     wapi = WorkspaceApi(
         current_user=request.current_user,  # User
         session=request.dbsession,
         config=app_config,
     )
     wapi.delete(request.current_workspace, flush=True)
     return
Ejemplo n.º 39
0
    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
Ejemplo n.º 40
0
 def undelete_workspace(self, context, request: TracimRequest, hapic_data=None):  # nopep8
     """
     Restore a deleted space.
     Note : a trusted user can only restore spaces on which he/she is space manager
     """
     app_config = request.registry.settings['CFG']
     wapi = WorkspaceApi(
         current_user=request.current_user,  # User
         session=request.dbsession,
         config=app_config,
         show_deleted=True,
     )
     wapi.undelete(request.current_workspace, flush=True)
     return
Ejemplo n.º 41
0
 def create_workspace(self, context, request: TracimRequest, hapic_data=None):  # nopep8
     """
     Create a workspace. This route is for trusted users and administrators.
     """
     app_config = request.registry.settings['CFG']
     wapi = WorkspaceApi(
         current_user=request.current_user,  # User
         session=request.dbsession,
         config=app_config,
     )
     workspace = wapi.create_workspace(
         label=hapic_data.body.label,
         description=hapic_data.body.description,
         save_now=True,
     )
     return wapi.get_workspace_with_context(workspace)
Ejemplo n.º 42
0
    def account_workspace(self, context, request: TracimRequest, hapic_data=None):
        """
        Get list of auth user workspaces
        """
        app_config = request.registry.settings['CFG']
        wapi = WorkspaceApi(
            current_user=request.current_user,  # User
            session=request.dbsession,
            config=app_config,
        )

        workspaces = wapi.get_all_for_user(request.current_user)
        return [
            wapi.get_workspace_with_context(workspace)
            for workspace in workspaces
        ]
Ejemplo n.º 43
0
    def workspaces(self, context, request: TracimRequest, hapic_data=None):
        """
        Returns the list of all workspaces. This route is for admin only.
        Standard users must use their own route: /api/v2/users/me/workspaces
        """
        app_config = request.registry.settings['CFG']
        wapi = WorkspaceApi(
            current_user=request.current_user,  # User
            session=request.dbsession,
            config=app_config,
        )

        workspaces = wapi.get_all()
        return [
            wapi.get_workspace_with_context(workspace)
            for workspace in workspaces
        ]
Ejemplo n.º 44
0
 def test__unit__get_notifiable_roles__ok__nominal_case(self):
     admin = self.session.query(User) \
         .filter(User.email == '*****@*****.**').one()
     wapi = WorkspaceApi(
         session=self.session,
         config=self.app_config,
         current_user=admin,
     )
     workspace = wapi.create_workspace(label='workspace w', save_now=True)
     uapi = UserApi(
         session=self.session,
         current_user=admin,
         config=self.app_config
     )
     user_1 = uapi.create_user(
         email='[email protected]',
         auth_type=AuthType.INTERNAL,
         do_save=True,
         do_notify=False
     )
     user_2 = uapi.create_user(
         email='[email protected]',
         auth_type=AuthType.INTERNAL,
         do_save=True,
         do_notify = False
     )
     assert wapi.get_notifiable_roles(workspace=workspace) == []
     rapi = RoleApi(
         session=self.session,
         current_user=admin,
         config=self.app_config,
     )
     role_1 = rapi.create_one(
         user_1,
         workspace,
         UserRoleInWorkspace.READER,
         with_notif=True
     )
     role_2 = rapi.create_one(
         user_2,
         workspace,
         UserRoleInWorkspace.READER,
         with_notif=False
     )
     assert role_1 in wapi.get_notifiable_roles(workspace=workspace)
     assert not role_2 in wapi.get_notifiable_roles(workspace=workspace)
Ejemplo n.º 45
0
 def update_workspace(self, context, request: TracimRequest, hapic_data=None):  # nopep8
     """
     Update a workspace. This route is for trusted users and administrators.
     Note : a trusted user can only update spaces on which he/she is space manager
     """
     app_config = request.registry.settings['CFG']
     wapi = WorkspaceApi(
         current_user=request.current_user,  # User
         session=request.dbsession,
         config=app_config,
     )
     wapi.update_workspace(
         request.current_workspace,
         label=hapic_data.body.label,
         description=hapic_data.body.description,
         save_now=True,
     )
     return wapi.get_workspace_with_context(request.current_workspace)
Ejemplo n.º 46
0
 def enable_account_workspace_notification(self, context, request: TracimRequest, hapic_data=None):  # nopep8
     """
     enable workspace notification
     """
     app_config = request.registry.settings['CFG']
     api = ContentApi(
         current_user=request.current_user,  # User
         session=request.dbsession,
         config=app_config,
     )
     wapi = WorkspaceApi(
         current_user=request.current_user,  # User
         session=request.dbsession,
         config=app_config,
     )
     workspace = wapi.get_one(hapic_data.path.workspace_id)
     wapi.enable_notifications(request.current_user, workspace)
     rapi = RoleApi(
         current_user=request.current_user,  # User
         session=request.dbsession,
         config=app_config,
     )
     role = rapi.get_one(request.current_user.user_id, workspace.workspace_id)  # nopep8
     wapi.save(workspace)
     return
Ejemplo n.º 47
0
 def test_unit__get_all_manageable(self):
     admin = self.session.query(User) \
         .filter(User.email == '*****@*****.**').one()
     uapi = UserApi(
         session=self.session,
         current_user=admin,
         config=self.app_config,
     )
     # Checks a case without workspaces.
     wapi = WorkspaceApi(
         session=self.session,
         current_user=admin,
         config=self.app_config,
     )
     eq_([], wapi.get_all_manageable())
     # Checks an admin gets all workspaces.
     w4 = wapi.create_workspace(label='w4')
     w3 = wapi.create_workspace(label='w3')
     w2 = wapi.create_workspace(label='w2')
     w1 = wapi.create_workspace(label='w1')
     eq_([w1, w2, w3, w4], wapi.get_all_manageable())
     # Checks a regular user gets none workspace.
     gapi = GroupApi(
         session=self.session,
         current_user=None,
         config=self.app_config,
     )
     u = uapi.create_minimal_user('[email protected]', [gapi.get_one(Group.TIM_USER)], True)
     wapi = WorkspaceApi(
         session=self.session,
         current_user=u,
         config=self.app_config,
     )
     rapi = RoleApi(
         session=self.session,
         current_user=None,
         config=self.app_config,
     )
     rapi.create_one(u, w4, UserRoleInWorkspace.READER, False)
     rapi.create_one(u, w3, UserRoleInWorkspace.CONTRIBUTOR, False)
     rapi.create_one(u, w2, UserRoleInWorkspace.CONTENT_MANAGER, False)
     rapi.create_one(u, w1, UserRoleInWorkspace.WORKSPACE_MANAGER, False)
     eq_([], wapi.get_all_manageable())
     # Checks a manager gets only its own workspaces.
     u.groups.append(gapi.get_one(Group.TIM_MANAGER))
     rapi.delete_one(u.user_id, w2.workspace_id)
     rapi.create_one(u, w2, UserRoleInWorkspace.WORKSPACE_MANAGER, False)
     eq_([w1, w2], wapi.get_all_manageable())
Ejemplo n.º 48
0
 def __init__(self, path: str, environ: dict, tracim_context: 'WebdavTracimContext'):
     super(RootResource, self).__init__(path, environ)
     self.tracim_context = tracim_context
     self.user = tracim_context.current_user
     self.session = tracim_context.dbsession
     # TODO BS 20170221: Web interface should list all workspace to. We
     # disable it here for moment. When web interface will be updated to
     # list all workspace, change this here to.
     self.workspace_api = WorkspaceApi(
         current_user=self.user,
         session=self.session,
         force_role=True,
         config=tracim_context.app_config
     )
Ejemplo n.º 49
0
 def delete_comment(self, context, request: TracimRequest, hapic_data=None):
     """
     Delete comment
     """
     app_config = request.registry.settings['CFG']
     api = ContentApi(
         show_archived=True,
         show_deleted=True,
         current_user=request.current_user,
         session=request.dbsession,
         config=app_config,
     )
     wapi = WorkspaceApi(
         current_user=request.current_user,
         session=request.dbsession,
         config=app_config,
     )
     workspace = wapi.get_one(hapic_data.path.workspace_id)
     parent = api.get_one(
         hapic_data.path.content_id,
         content_type=content_type_list.Any_SLUG,
         workspace=workspace
     )
     comment = api.get_one(
         hapic_data.path.comment_id,
         content_type=content_type_list.Comment.slug,
         workspace=workspace,
         parent=parent,
     )
     with new_revision(
             session=request.dbsession,
             tm=transaction.manager,
             content=comment
     ):
         api.delete(comment)
     return
Ejemplo n.º 50
0
 def disable_workspace_notification(self, context, request: TracimRequest, hapic_data=None):  # nopep8
     """
     disable workspace notification
     """
     app_config = request.registry.settings['CFG']
     api = ContentApi(
         current_user=request.candidate_user,  # User
         session=request.dbsession,
         config=app_config,
     )
     wapi = WorkspaceApi(
         current_user=request.candidate_user,  # User
         session=request.dbsession,
         config=app_config,
     )
     workspace = wapi.get_one(hapic_data.path.workspace_id)
     wapi.disable_notifications(request.candidate_user, workspace)
     wapi.save(workspace)
     return
Ejemplo n.º 51
0
 def test_api__post_content_comment__err_400__content_not_editable(self) -> None:
     """
     Get alls comments of a content
     """
     dbsession = get_tm_session(self.session_factory, transaction.manager)
     admin = dbsession.query(User) \
         .filter(User.email == '*****@*****.**') \
         .one() # type: User
     workspace_api = WorkspaceApi(
         current_user=admin,
         session=dbsession,
         config=self.app_config
     )
     business_workspace = workspace_api.get_one(1)
     content_api = ContentApi(
         current_user=admin,
         session=dbsession,
         config=self.app_config
     )
     tool_folder = content_api.get_one(1, content_type=content_type_list.Any_SLUG)
     test_thread = content_api.create(
         content_type_slug=content_type_list.Thread.slug,
         workspace=business_workspace,
         parent=tool_folder,
         label='Test Thread',
         do_save=True,
         do_notify=False,
     )
     with new_revision(
        session=dbsession,
        tm=transaction.manager,
        content=test_thread,
     ):
         content_api.update_content(
             test_thread,
             new_label='test_thread_updated',
             new_content='Just a test'
         )
     content_api.set_status(test_thread, 'closed-deprecated')
     transaction.commit()
     self.testapp.authorization = (
         'Basic',
         (
             '*****@*****.**',
             '*****@*****.**'
         )
     )
     params = {
         'raw_content': 'I strongly disagree, Tiramisu win!'
     }
     res = self.testapp.post_json(
         '/api/v2/workspaces/{}/contents/{}/comments'.format(
             business_workspace.workspace_id,
             test_thread.content_id
         ),
         params=params,
         status=400
     )
     assert res.json_body
     assert 'code' in res.json_body
     assert res.json_body['code'] == error.CONTENT_IN_NOT_EDITABLE_STATE
Ejemplo n.º 52
0
 def test_api__post_content_comment__ok_200__nominal_case(self) -> None:
     """
     Get alls comments of a content
     """
     dbsession = get_tm_session(self.session_factory, transaction.manager)
     admin = dbsession.query(User) \
         .filter(User.email == '*****@*****.**') \
         .one() # type: User
     workspace_api = WorkspaceApi(
         current_user=admin,
         session=dbsession,
         config=self.app_config
     )
     business_workspace = workspace_api.get_one(1)
     content_api = ContentApi(
         current_user=admin,
         session=dbsession,
         config=self.app_config
     )
     tool_folder = content_api.get_one(1, content_type=content_type_list.Any_SLUG)
     test_thread = content_api.create(
         content_type_slug=content_type_list.Thread.slug,
         workspace=business_workspace,
         parent=tool_folder,
         label='Test Thread',
         do_save=True,
         do_notify=False,
     )
     with new_revision(
        session=dbsession,
        tm=transaction.manager,
        content=test_thread,
     ):
         content_api.update_content(
             test_thread,
             new_label='test_thread_updated',
             new_content='Just a test'
         )
     transaction.commit()
     self.testapp.authorization = (
         'Basic',
         (
             '*****@*****.**',
             '*****@*****.**'
         )
     )
     params = {
         'raw_content': 'I strongly disagree, Tiramisu win!'
     }
     res = self.testapp.post_json(
         '/api/v2/workspaces/{}/contents/{}/comments'.format(
             business_workspace.workspace_id,
             test_thread.content_id
         ),
         params=params,
         status=200
     )
     comment = res.json_body
     assert comment['content_id']
     assert comment['parent_id'] == test_thread.content_id
     assert comment['raw_content'] == 'I strongly disagree, Tiramisu win!'
     assert comment['author']
     assert comment['author']['user_id'] == admin.user_id
     # TODO - G.M - 2018-06-172 - [avatar] setup avatar url
     assert comment['author']['avatar_url'] is None
     assert comment['author']['public_name'] == admin.display_name
     # TODO - G.M - 2018-06-179 - better check for datetime
     assert comment['created']
Ejemplo n.º 53
0
    def insert(self):
        admin = self._session.query(User) \
            .filter(User.email == '*****@*****.**') \
            .one()
        bob = self._session.query(User) \
            .filter(User.email == '*****@*****.**') \
            .one()
        john_the_reader = self._session.query(User) \
            .filter(User.email == '*****@*****.**') \
            .one()

        admin_workspace_api = WorkspaceApi(
            current_user=admin,
            session=self._session,
            config=self._config,
        )
        bob_workspace_api = WorkspaceApi(
            current_user=bob,
            session=self._session,
            config=self._config
        )
        content_api = ContentApi(
            current_user=admin,
            session=self._session,
            config=self._config
        )
        bob_content_api = ContentApi(
            current_user=bob,
            session=self._session,
            config=self._config
        )
        reader_content_api = ContentApi(
            current_user=john_the_reader,
            session=self._session,
            config=self._config
        )
        role_api = RoleApi(
            current_user=admin,
            session=self._session,
            config=self._config,
        )

        # Workspaces
        business_workspace = admin_workspace_api.create_workspace(
            'Business',
            description='All importants documents',
            save_now=True,
        )
        recipe_workspace = admin_workspace_api.create_workspace(
            'Recipes',
            description='Our best recipes',
            save_now=True,
        )
        other_workspace = bob_workspace_api.create_workspace(
            'Others',
            description='Other Workspace',
            save_now=True,
        )

        # Workspaces roles
        role_api.create_one(
            user=bob,
            workspace=recipe_workspace,
            role_level=UserRoleInWorkspace.CONTENT_MANAGER,
            with_notif=False,
        )
        role_api.create_one(
            user=john_the_reader,
            workspace=recipe_workspace,
            role_level=UserRoleInWorkspace.READER,
            with_notif=False,
        )
        # Folders

        tool_workspace = content_api.create(
            content_type_slug=content_type_list.Folder.slug,
            workspace=business_workspace,
            label='Tools',
            do_save=True,
            do_notify=False,
        )
        menu_workspace = content_api.create(
            content_type_slug=content_type_list.Folder.slug,
            workspace=business_workspace,
            label='Menus',
            do_save=True,
            do_notify=False,
        )

        dessert_folder = content_api.create(
            content_type_slug=content_type_list.Folder.slug,
            workspace=recipe_workspace,
            label='Desserts',
            do_save=True,
            do_notify=False,
        )
        salads_folder = content_api.create(
            content_type_slug=content_type_list.Folder.slug,
            workspace=recipe_workspace,
            label='Salads',
            do_save=True,
            do_notify=False,
        )
        other_folder = content_api.create(
            content_type_slug=content_type_list.Folder.slug,
            workspace=other_workspace,
            label='Infos',
            do_save=True,
            do_notify=False,
        )

        # Pages, threads, ..
        tiramisu_page = content_api.create(
            content_type_slug=content_type_list.Page.slug,
            workspace=recipe_workspace,
            parent=dessert_folder,
            label='Tiramisu Recipes!!!',
            do_save=True,
            do_notify=False,
        )
        with new_revision(
                session=self._session,
                tm=transaction.manager,
                content=tiramisu_page,
        ):
            content_api.update_content(
                item=tiramisu_page,
                new_content='<p>To cook a greet Tiramisu, you need many ingredients.</p>',  # nopep8
                new_label='Tiramisu Recipes!!!',
            )
            content_api.save(tiramisu_page)

        best_cake_thread = content_api.create(
            content_type_slug=content_type_list.Thread.slug,
            workspace=recipe_workspace,
            parent=dessert_folder,
            label='Best Cake',
            do_save=False,
            do_notify=False,
        )
        best_cake_thread.description = 'Which is the best cake?'
        self._session.add(best_cake_thread)
        apple_pie_recipe = content_api.create(
            content_type_slug=content_type_list.File.slug,
            workspace=recipe_workspace,
            parent=dessert_folder,
            label='Apple_Pie',
            do_save=False,
            do_notify=False,
        )
        apple_pie_recipe.file_extension = '.txt'
        apple_pie_recipe.depot_file = FileIntent(
            b'Apple pie Recipe',
            'apple_Pie.txt',
            'text/plain',
        )
        self._session.add(apple_pie_recipe)
        Brownie_recipe = content_api.create(
            content_type_slug=content_type_list.File.slug,
            workspace=recipe_workspace,
            parent=dessert_folder,
            label='Brownie Recipe',
            do_save=False,
            do_notify=False,
        )
        Brownie_recipe.file_extension = '.html'
        Brownie_recipe.depot_file = FileIntent(
            b'<p>Brownie Recipe</p>',
            'brownie_recipe.html',
            'text/html',
        )
        self._session.add(Brownie_recipe)
        fruits_desserts_folder = content_api.create(
            content_type_slug=content_type_list.Folder.slug,
            workspace=recipe_workspace,
            label='Fruits Desserts',
            parent=dessert_folder,
            do_save=True,
        )

        menu_page = content_api.create(
            content_type_slug=content_type_list.Page.slug,
            workspace=business_workspace,
            parent=menu_workspace,
            label='Current Menu',
            do_save=True,
        )

        new_fruit_salad = content_api.create(
            content_type_slug=content_type_list.Page.slug,
            workspace=recipe_workspace,
            parent=fruits_desserts_folder,
            label='New Fruit Salad',
            do_save=True,
        )
        old_fruit_salad = content_api.create(
            content_type_slug=content_type_list.Page.slug,
            workspace=recipe_workspace,
            parent=fruits_desserts_folder,
            label='Fruit Salad',
            do_save=True,
            do_notify=False,
        )
        with new_revision(
                session=self._session,
                tm=transaction.manager,
                content=old_fruit_salad,
        ):
            content_api.archive(old_fruit_salad)
        content_api.save(old_fruit_salad)

        bad_fruit_salad = content_api.create(
            content_type_slug=content_type_list.Page.slug,
            workspace=recipe_workspace,
            parent=fruits_desserts_folder,
            label='Bad Fruit Salad',
            do_save=True,
            do_notify=False,
        )
        with new_revision(
                session=self._session,
                tm=transaction.manager,
                content=bad_fruit_salad,
        ):
            content_api.delete(bad_fruit_salad)
        content_api.save(bad_fruit_salad)

        # File at the root for test
        new_fruit_salad = content_api.create(
            content_type_slug=content_type_list.Page.slug,
            workspace=other_workspace,
            label='New Fruit Salad',
            do_save=True,
        )
        old_fruit_salad = content_api.create(
            content_type_slug=content_type_list.Page.slug,
            workspace=other_workspace,
            label='Fruit Salad',
            do_save=True,
        )
        with new_revision(
                session=self._session,
                tm=transaction.manager,
                content=old_fruit_salad,
        ):
            content_api.archive(old_fruit_salad)
        content_api.save(old_fruit_salad)

        bad_fruit_salad = content_api.create(
            content_type_slug=content_type_list.Page.slug,
            workspace=other_workspace,
            label='Bad Fruit Salad',
            do_save=True,
        )
        with new_revision(
                session=self._session,
                tm=transaction.manager,
                content=bad_fruit_salad,
        ):
            content_api.delete(bad_fruit_salad)
        content_api.save(bad_fruit_salad)

        content_api.create_comment(
            parent=best_cake_thread,
            content='<p>What is for you the best cake ever? </br> I personnally vote for Chocolate cupcake!</p>',  # nopep8
            do_save=True,
        )
        bob_content_api.create_comment(
            parent=best_cake_thread,
            content='<p>What about Apple Pie? There are Awesome!</p>',
            do_save=True,
        )
        reader_content_api.create_comment(
            parent=best_cake_thread,
            content='<p>You are right, but Kouign-amann are clearly better.</p>',
            do_save=True,
        )
        with new_revision(
                session=self._session,
                tm=transaction.manager,
                content=best_cake_thread,
        ):
            bob_content_api.update_content(
                item=best_cake_thread,
                new_content='What is the best cake?',
                new_label='Best Cakes?',
            )
            bob_content_api.save(best_cake_thread)

        with new_revision(
                session=self._session,
                tm=transaction.manager,
                content=tiramisu_page,
        ):
            bob_content_api.update_content(
                item=tiramisu_page,
                new_content='<p>To cook a great Tiramisu, you need many ingredients.</p>',  # nopep8
                new_label='Tiramisu Recipe',
            )
            bob_content_api.save(tiramisu_page)
        self._session.flush()
Ejemplo n.º 54
0
class RootResource(DAVCollection):
    """
    RootResource ressource that represents tracim's home, which contains all workspaces
    """

    def __init__(self, path: str, environ: dict, tracim_context: 'WebdavTracimContext'):
        super(RootResource, self).__init__(path, environ)
        self.tracim_context = tracim_context
        self.user = tracim_context.current_user
        self.session = tracim_context.dbsession
        # TODO BS 20170221: Web interface should list all workspace to. We
        # disable it here for moment. When web interface will be updated to
        # list all workspace, change this here to.
        self.workspace_api = WorkspaceApi(
            current_user=self.user,
            session=self.session,
            force_role=True,
            config=tracim_context.app_config
        )

    def __repr__(self) -> str:
        return '<DAVCollection: RootResource>'

    @webdav_check_right(is_user)
    def getMemberNames(self) -> [str]:
        """
        This method returns the names (here workspace's labels) of all its children

        Though for perfomance issue, we're not using this function anymore
        """
        return [
            webdav_convert_file_name_to_display(workspace.label)
            for workspace in self.workspace_api.get_all()
        ]

    @webdav_check_right(is_user)
    def getMember(self, label: str) -> DAVCollection:
        """
        This method returns the child Workspace that corresponds to a given name

        Though for perfomance issue, we're not using this function anymore
        """
        try:
            workspace = self.workspace_api.get_one_by_label(label)
            # fix path
            workspace_path = '%s%s%s' % (self.path, '' if self.path == '/' else '/', webdav_convert_file_name_to_display(workspace.label))
            # return item
            return WorkspaceResource(
                workspace_path,
                self.environ,
                workspace,
                tracim_context=self.tracim_context
            )
        except AttributeError:
            return None

    @webdav_check_right(is_trusted_user)
    def createEmptyResource(self, name: str):
        """
        This method is called whenever the user wants to create a DAVNonCollection resource (files in our case).

        There we don't allow to create files at the root;
        only workspaces (thus collection) can be created.
        """
        raise DAVError(HTTP_FORBIDDEN)

    @webdav_check_right(is_trusted_user)
    def createCollection(self, name: str):
        """
        This method is called whenever the user wants to create a DAVCollection resource as a child (in our case,
        we create workspaces as this is the root).

        [For now] we don't allow to create new workspaces through
        webdav client. Though if we come to allow it, deleting the error's raise will
        make it possible.
        """
        # TODO : remove comment here
        # raise DAVError(HTTP_FORBIDDEN)
        workspace_name = webdav_convert_file_name_to_bdd(name)
        new_workspace = self.workspace_api.create_workspace(workspace_name)
        self.workspace_api.save(new_workspace)
        transaction.commit()
        # fix path
        workspace_path = '%s%s%s' % (
            self.path, '' if self.path == '/' else '/', webdav_convert_file_name_to_display(new_workspace.label)
        )

        # create item
        return WorkspaceResource(
            workspace_path,
            self.environ,
            new_workspace,
            tracim_context=self.tracim_context
        )

    @webdav_check_right(is_user)
    def getMemberList(self):
        """
        This method is called by wsgidav when requesting with a depth > 0, it will return a list of _DAVResource
        of all its direct children
        """

        members = []
        for workspace in self.workspace_api.get_all():
            # fix path
            workspace_label = webdav_convert_file_name_to_display(workspace.label)
            path = add_trailing_slash(self.path)
            # return item
            workspace_path = '{}{}'.format(path, workspace_label)
            members.append(
                WorkspaceResource(
                    path=workspace_path,
                    environ=self.environ,
                    workspace=workspace,
                    tracim_context=self.tracim_context
                )
            )

        return members