Exemplo n.º 1
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
Exemplo n.º 2
0
 def connect_database(self, create_tables: bool = False) -> None:
     self.engine = get_engine(self.app_config)
     if create_tables:
         DeclarativeBase.metadata.create_all(self.engine)
     self.session_factory = get_session_factory(self.engine)
     self.session = get_tm_session(self.session_factory,
                                   transaction.manager)
Exemplo n.º 3
0
 def test_functional__webdav_access_to_root__nominal_case(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)  # nopep8
     transaction.commit()
     self.testapp.authorization = (
         'Basic',
         (
             '*****@*****.**',
             '*****@*****.**'
         )
     )
     res = self.testapp.get('/', status=200)
     assert res
Exemplo n.º 4
0
 def test_api__reset_password_reset__ok_204__nominal_case(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,
     )
     reset_password_token = uapi.reset_password_notification(admin, do_save=True)  # nopep8
     transaction.commit()
     params = {
         'email': '*****@*****.**',
         'reset_password_token': reset_password_token,
         'new_password': '******',
         'new_password2': 'mynewpassword',
     }
     self.testapp.post_json(
         '/api/v2/auth/password/reset/modify',
         status=204,
         params=params,
     )
     # check if password is correctly setted
     self.testapp.authorization = (
         'Basic',
         (
             '*****@*****.**',
             'mynewpassword'
         )
     )
     self.testapp.get(
         '/api/v2/auth/whoami',
         status=200,
     )
Exemplo n.º 5
0
 def test_api__reset_password_reset__err_400__invalid_token(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,
     )
     reset_password_token = 'wrong_token'
     params = {
         'email': '*****@*****.**',
         'reset_password_token': reset_password_token,
         'new_password': '******',
         'new_password2': 'mynewpassword',
     }
     res = self.testapp.post_json(
         '/api/v2/auth/password/reset/modify',
         status=400,
         params=params,
     )
     assert isinstance(res.json, dict)
     assert 'code' in res.json.keys()
     assert res.json_body['code'] == error.INVALID_RESET_PASSWORD_TOKEN
Exemplo n.º 6
0
 def test_api__reset_password_reset__err_400__password_does_not_match(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,
     )
     reset_password_token = uapi.reset_password_notification(admin, do_save=True)  # nopep8
     transaction.commit()
     params = {
         'email': '*****@*****.**',
         'reset_password_token': reset_password_token,
         'new_password': '******',
         'new_password2': 'anotherpassword',
     }
     res = self.testapp.post_json(
         '/api/v2/auth/password/reset/modify',
         status=400,
         params=params,
     )
     assert isinstance(res.json, dict)
     assert 'code' in res.json.keys()
     assert res.json_body['code'] == error.PASSWORD_DO_NOT_MATCH
Exemplo n.º 7
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
Exemplo n.º 8
0
 def test_api__reset_password_reset__err_400__expired_token(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,
     )
     with freeze_time("1999-12-31 23:59:59"):
         reset_password_token = uapi.reset_password_notification(
             admin,
             do_save=True
         )
         params = {
             'email': '*****@*****.**',
             'reset_password_token': reset_password_token,
             'new_password': '******',
             'new_password2': 'mynewpassword',
         }
         transaction.commit()
     with freeze_time("2000-01-01 00:00:05"):
         res = self.testapp.post_json(
             '/api/v2/auth/password/reset/modify',
             status=400,
             params=params,
         )
         assert isinstance(res.json, dict)
         assert 'code' in res.json.keys()
         assert res.json_body['code'] == error.EXPIRED_RESET_PASSWORD_TOKEN  # nopep8
Exemplo n.º 9
0
 def test_api__reset_password_reset__err_400__expired_token(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)
     with freeze_time("1999-12-31 23:59:59"):
         reset_password_token = uapi.reset_password_notification(
             admin, do_save=True)
         params = {
             "email": "*****@*****.**",
             "reset_password_token": reset_password_token,
             "new_password": "******",
             "new_password2": "mynewpassword",
         }
         transaction.commit()
     with freeze_time("2000-01-01 00:00:05"):
         res = self.testapp.post_json("/api/v2/auth/password/reset/modify",
                                      status=400,
                                      params=params)
         assert isinstance(res.json, dict)
         assert "code" in res.json.keys()
         assert res.json_body[
             "code"] == ErrorCode.EXPIRED_RESET_PASSWORD_TOKEN
Exemplo n.º 10
0
 def _populate_database(
         cls,
         settings: plaster_pastedeploy.ConfigDict,
         add_test_data: bool
 ) -> None:
     engine = get_engine(settings)
     session_factory = get_session_factory(engine)
     app_config = CFG(settings)
     print("- Populate database with default data -")
     with transaction.manager:
         dbsession = get_tm_session(session_factory, transaction.manager)
         try:
             fixtures = [BaseFixture]
             fixtures_loader = FixturesLoader(dbsession, app_config)
             fixtures_loader.loads(fixtures)
             transaction.commit()
             if add_test_data:
                 app_config.configure_filedepot()
                 fixtures = [ContentFixture]
                 fixtures_loader.loads(fixtures)
             transaction.commit()
             print("Database initialized.")
         except IntegrityError as exc:
             transaction.abort()
             print('Database initialization failed')
             raise DatabaseInitializationFailed(
                 'Warning, there was a problem when adding default data'
                 ', it may have already been added.'
             ) from exc
Exemplo n.º 11
0
    def test_api__try_whoami_enpoint__err_401__user_is_not_active(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("users")]
        test_user = uapi.create_user(
            email="*****@*****.**",
            password="******",
            name="bob",
            groups=groups,
            timezone="Europe/Paris",
            lang="en",
            do_save=True,
            do_notify=False,
        )
        uapi.save(test_user)
        uapi.disable(test_user)
        transaction.commit()
        self.testapp.authorization = ("Basic", ("*****@*****.**", "password"))

        res = self.testapp.get("/api/v2/auth/whoami", status=401)
        assert isinstance(res.json, dict)
        assert "code" in res.json.keys()
        # INFO - G.M - 2018-09-10 - Handled by marshmallow_schema
        assert res.json_body["code"] is None
        assert "message" in res.json.keys()
        assert "details" in res.json.keys()
Exemplo n.º 12
0
 def test_functional__webdav_access_to_root__remote_auth(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=None,
         do_save=True,
         do_notify=False,
         groups=groups,
         auth_type=AuthType.REMOTE
     )
     uapi.save(user)
     transaction.commit()
     extra_environ = {
         'REMOTE_USER': '******',
     }
     res = self.testapp.get('/', status=200, extra_environ=extra_environ)
     assert res
Exemplo n.º 13
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
Exemplo n.º 14
0
 def test_proxy_user_agenda__ok__nominal_case(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,
     )
     transaction.commit()
     self.testapp.authorization = ("Basic", ("*****@*****.**",
                                             "*****@*****.**"))
     self.testapp.get("/agenda/user/{}/".format(user.user_id), status=404)
     event = VALID_CALDAV_BODY_PUT_EVENT
     self.testapp.put("/agenda/user/{}/".format(user.user_id),
                      event,
                      content_type="text/calendar",
                      status=201)
     self.testapp.get("/agenda/user/{}/".format(user.user_id), status=200)
     self.testapp.delete("/agenda/user/{}/".format(user.user_id),
                         status=200)
Exemplo n.º 15
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
Exemplo n.º 16
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
Exemplo n.º 17
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
Exemplo n.º 18
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']
Exemplo n.º 19
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"]
Exemplo n.º 20
0
    def test_api__reset_password_check_token__ok_204__unknown_auth(self):
        # create new user without auth (default is unknown)
        self.testapp.authorization = (
            'Basic',
            (
                '*****@*****.**',
                '*****@*****.**'
            )
        )
        params = {
            'email': '*****@*****.**',
            'password': '******',
            'profile': 'users',
            'timezone': 'Europe/Paris',
            'lang': 'fr',
            'public_name': 'test user',
            'email_notification': False,
        }
        res = self.testapp.post_json(
            '/api/v2/users',
            status=200,
            params=params,
        )
        res = res.json_body
        assert res['user_id']
        user_id = res['user_id']

        # make a check of token
        self.testapp.authorization = None
        dbsession = get_tm_session(self.session_factory, transaction.manager)
        admin = dbsession.query(User) \
            .filter(User.email == '*****@*****.**') \
            .one()
        uapi = UserApi(
            current_user=admin,
            session=dbsession,
            config=self.app_config,
        )
        user = uapi.get_one_by_email('*****@*****.**')
        reset_password_token = uapi.reset_password_notification(user, do_save=True) # nopep8
        transaction.commit()
        params = {
            'email': '*****@*****.**',
            'reset_password_token': reset_password_token
        }
        self.testapp.post_json(
            '/api/v2/auth/password/reset/token/check',
            status=204,
            params=params,
        )
Exemplo n.º 21
0
    def test_api__test_cookie_auth_token__ok__change_email_dont_break_cookie(self):
        """
        Test if email change doesn't break cookie auth
        :return:
        """
        dbsession = get_tm_session(self.session_factory, transaction.manager)
        admin = dbsession.query(User).filter(User.email == "*****@*****.**").one()
        with freeze_time("1999-12-31 23:59:58"):
            params = {"email": "*****@*****.**", "password": "******"}
            res = self.testapp.post_json("/api/v2/auth/login", params=params, status=200)
            assert "Set-Cookie" in res.headers
            assert "session_key" in self.testapp.cookies
            user_session_key_1 = self.testapp.cookies["session_key"]

        # change own email
        with freeze_time("1999-12-31 23:59:59"):
            params = {
                "email": "*****@*****.**",
                "loggedin_user_password": "******",
            }
            self.testapp.put_json(
                "/api/v2/users/{}/email".format(admin.user_id), params=params, status=200
            )
            assert "Set-Cookie" in res.headers
            assert "session_key" in self.testapp.cookies
            user_session_key_2 = self.testapp.cookies["session_key"]
            assert user_session_key_1 == user_session_key_2

        # session_id should not be return before x time
        with freeze_time("2000-01-01 00:00:00"):
            res = self.testapp.get("/api/v2/auth/whoami", status=200)
            assert "Set-Cookie" not in res.headers
            assert "session_key" in self.testapp.cookies
            user_session_key_3 = self.testapp.cookies["session_key"]
            assert user_session_key_3 == user_session_key_2

        # after x time session_id should be renew
        with freeze_time("2000-01-01 00:02:01"):
            res = self.testapp.get("/api/v2/auth/whoami", status=200)
            assert "Set-Cookie" in res.headers
            assert "session_key" in self.testapp.cookies
            user_session_key_4 = self.testapp.cookies["session_key"]
            assert user_session_key_4 != user_session_key_3

        # after too much time, session_id should be revoked
        with freeze_time("2000-01-01 00:12:02"):
            res = self.testapp.get("/api/v2/auth/whoami", params=params, status=401)
            assert "Set-Cookie" in res.headers
Exemplo n.º 22
0
 def test_proxy_workspace_agenda__ok__nominal_case(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("test", save_now=True)
     workspace.agenda_enabled = True
     rapi = RoleApi(current_user=admin,
                    session=dbsession,
                    config=self.app_config)
     rapi.create_one(user, workspace, UserRoleInWorkspace.CONTENT_MANAGER,
                     False)
     transaction.commit()
     self.testapp.authorization = ("Basic", ("*****@*****.**",
                                             "*****@*****.**"))
     self.testapp.get("/agenda/workspace/{}/".format(
         workspace.workspace_id),
                      status=404)
     event = VALID_CALDAV_BODY_PUT_EVENT
     self.testapp.put(
         "/agenda/workspace/{}/".format(workspace.workspace_id),
         event,
         content_type="text/agenda",
         status=201,
     )
     self.testapp.get("/agenda/workspace/{}/".format(
         workspace.workspace_id),
                      status=200)
     self.testapp.delete("/agenda/workspace/{}/".format(
         workspace.workspace_id),
                         status=200)
Exemplo n.º 23
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
Exemplo n.º 24
0
def set_html_document_slug_to_legacy(session_factory) -> None:
    """
    Simple function to help some functional test. This modify "html-documents"
    type content in database to legacy "page" slug.
    :param session_factory: session factory of the test
    :return: Nothing.
    """
    dbsession = get_tm_session(session_factory, transaction.manager)
    content_query = (dbsession.query(ContentRevisionRO).filter(
        ContentRevisionRO.type == "page").filter(
            ContentRevisionRO.content_id == 6))
    assert content_query.count() == 0
    html_documents_query = dbsession.query(ContentRevisionRO).filter(
        ContentRevisionRO.type == "html-document")
    html_documents_query.update({ContentRevisionRO.type: "page"})
    transaction.commit()
    assert content_query.count() > 0
Exemplo n.º 25
0
 def setUp(self):
     super().setUp()
     self.testapp.authorization = ("Basic", ("*****@*****.**",
                                             "*****@*****.**"))
     self.dbsession = get_tm_session(self.session_factory,
                                     transaction.manager)
     self.admin = self.dbsession.query(User).filter(
         User.email == "*****@*****.**").one()
     self.workspace_api = WorkspaceApi(current_user=self.admin,
                                       session=self.dbsession,
                                       config=self.app_config)
     self.content_api = ContentApi(current_user=self.admin,
                                   session=self.dbsession,
                                   config=self.app_config)
     self.workspace = self.workspace_api.create_workspace(label="test",
                                                          save_now=True)
     transaction.commit()
Exemplo n.º 26
0
 def test_api__reset_password_check_token__ok_204__nominal_case(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)
     reset_password_token = uapi.reset_password_notification(admin,
                                                             do_save=True)
     transaction.commit()
     params = {
         "email": "*****@*****.**",
         "reset_password_token": reset_password_token
     }
     self.testapp.post_json("/api/v2/auth/password/reset/token/check",
                            status=204,
                            params=params)
Exemplo n.º 27
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"] == ErrorCode.CONTENT_IN_NOT_EDITABLE_STATE
Exemplo n.º 28
0
    def test_api__try_whoami_enpoint__err_401__user_is_not_active(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('users')]
        test_user = uapi.create_user(
            email='*****@*****.**',
            password='******',
            name='bob',
            groups=groups,
            timezone='Europe/Paris',
            lang='en',
            do_save=True,
            do_notify=False,
        )
        uapi.save(test_user)
        uapi.disable(test_user)
        transaction.commit()
        self.testapp.authorization = (
            'Basic',
            (
                '*****@*****.**',
                'password'
            )
        )

        res = self.testapp.get('/api/v2/auth/whoami', status=401)
        assert isinstance(res.json, dict)
        assert 'code' in res.json.keys()
        # INFO - G.M - 2018-09-10 - Handled by marshmallow_schema
        assert res.json_body['code'] is None
        assert 'message' in res.json.keys()
        assert 'details' in res.json.keys()
Exemplo n.º 29
0
    def test_api__reset_password_reset__ok_204__unknown_auth(self):
        # create new user without auth (default is unknown)
        self.testapp.authorization = ("Basic", ("*****@*****.**",
                                                "*****@*****.**"))
        params = {
            "email": "*****@*****.**",
            "password": "******",
            "profile": "users",
            "timezone": "Europe/Paris",
            "lang": "fr",
            "public_name": "test user",
            "email_notification": False,
        }
        res = self.testapp.post_json("/api/v2/users",
                                     status=200,
                                     params=params)
        res = res.json_body
        assert res["user_id"]

        # make a check of token
        self.testapp.authorization = None
        dbsession = get_tm_session(self.session_factory, transaction.manager)
        admin = dbsession.query(User).filter(
            User.email == "*****@*****.**").one()
        uapi = UserApi(current_user=admin,
                       session=dbsession,
                       config=self.app_config)
        user = uapi.get_one_by_email("*****@*****.**")
        reset_password_token = uapi.reset_password_notification(user,
                                                                do_save=True)
        transaction.commit()
        params = {
            "email": "*****@*****.**",
            "reset_password_token": reset_password_token,
            "new_password": "******",
            "new_password2": "mynewpassword",
        }
        self.testapp.post_json("/api/v2/auth/password/reset/modify",
                               status=204,
                               params=params)
        # check if password is correctly setted
        self.testapp.authorization = ("Basic", ("*****@*****.**",
                                                "mynewpassword"))
        self.testapp.get("/api/v2/auth/whoami", status=200)
Exemplo n.º 30
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
Exemplo n.º 31
0
    def test_functional__webdav_access_to_workspace__nominal_case(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)  # nopep8
        workspace_api = WorkspaceApi(
            current_user=admin,
            session=dbsession,
            config=self.app_config,
            show_deleted=True,
        )
        workspace = workspace_api.create_workspace('test', save_now=True)  # nopep8
        rapi = RoleApi(
            current_user=admin,
            session=dbsession,
            config=self.app_config,
        )
        rapi.create_one(user, workspace, UserRoleInWorkspace.READER,
                        False)  # nopep8
        transaction.commit()

        self.testapp.authorization = (
            'Basic',
            (
                '*****@*****.**',
                '*****@*****.**'
            )
        )
        res = self.testapp.get('/test', status=200)
Exemplo n.º 32
0
 def init_database(self) -> None:
     session = get_tm_session(self.session_factory, transaction.manager)
     with transaction.manager:
         try:
             DeclarativeBase.metadata.drop_all(self.engine)
             DeclarativeBase.metadata.create_all(self.engine)
             fixtures_loader = FixturesLoader(session, self.app_config)
             fixtures_loader.loads(self.fixtures)
             transaction.commit()
             logger.info(self, "Database initialized.")
         except IntegrityError:
             logger.error(
                 self,
                 'Warning, there was a problem when adding default data'  # nopep8
                 ', it may have already been added:')
             import traceback
             logger.error(self, traceback.format_exc())
             transaction.abort()
             logger.error(self, 'Database initialization failed')
Exemplo n.º 33
0
    def test_api__try_login_enpoint__err_401__user_not_activated(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('users')]
        test_user = uapi.create_user(
            email='*****@*****.**',
            password='******',
            name='bob',
            groups=groups,
            timezone='Europe/Paris',
            do_save=True,
            do_notify=False,
        )
        uapi.save(test_user)
        uapi.disable(test_user)
        transaction.commit()

        params = {
            'email': '*****@*****.**',
            'password': '******',
        }
        res = self.testapp.post_json(
            '/api/v2/auth/login',
            params=params,
            status=403,
        )
        assert res.json_body
        assert 'code' in res.json_body
        assert res.json_body['code'] == error.AUTHENTICATION_FAILED
Exemplo n.º 34
0
 def __call__(self, environ, start_response):
     # TODO - G.M - 18-05-2018 - This code should not create trouble
     # with thread and database, this should be verify.
     # see https://github.com/tracim/tracim_backend/issues/62
     tm = transaction.manager
     session = get_tm_session(self.session_factory, tm)
     registry = get_current_registry()
     registry.ldap_connector = None
     if AuthType.LDAP in self.app_config.AUTH_TYPES:
         registry = self.setup_ldap(registry, self.app_config)
     environ['tracim_registry'] =  registry
     environ['tracim_context'] = WebdavTracimContext(environ, self.app_config, session)
     try:
         app = self._application(environ, start_response)
     except Exception as exc:
         transaction.rollback()
         raise exc
     finally:
         transaction.commit()
         session.close()
     return app
Exemplo n.º 35
0
 def test_api__reset_password_check_token__ok_204__nominal_case(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,
     )
     reset_password_token = uapi.reset_password_notification(admin, do_save=True) # nopep8
     transaction.commit()
     params = {
         'email': '*****@*****.**',
         'reset_password_token': reset_password_token
     }
     self.testapp.post_json(
         '/api/v2/auth/password/reset/token/check',
         status=204,
         params=params,
     )
Exemplo n.º 36
0
 def test_api__try_whoami_enpoint__err_401__user_is_not_active(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('users')]
     test_user = uapi.create_user(
         email='*****@*****.**',
         password='******',
         name='bob',
         groups=groups,
         timezone='Europe/Paris',
         do_save=True,
         do_notify=False,
     )
     uapi.save(test_user)
     uapi.disable(test_user)
     transaction.commit()
     headers_auth = {
             'Tracim-Api-Key': 'mysuperapikey',
             'Tracim-Api-Login': '******',
     }
     res = self.testapp.get(
         '/api/v2/auth/whoami',
         status=401,
         headers=headers_auth
     )
     assert isinstance(res.json, dict)
     assert 'code' in res.json.keys()
     assert res.json_body['code'] is None
Exemplo n.º 37
0
    def test_api__test_cookie_auth_token__ok__change_email_dont_break_cookie(self):  # nopep8
        """
        Test if email change doesn't break cookie auth
        :return:
        """
        dbsession = get_tm_session(self.session_factory, transaction.manager)
        admin = dbsession.query(User) \
            .filter(User.email == '*****@*****.**') \
            .one()
        with freeze_time("1999-12-31 23:59:58"):
            params = {
                'email': '*****@*****.**',
                'password': '******',
            }
            res = self.testapp.post_json(
                '/api/v2/auth/login',
                params=params,
                status=200,
            )
            assert 'Set-Cookie' in res.headers
            assert 'session_key' in self.testapp.cookies
            user_session_key_1 = self.testapp.cookies['session_key']

        # change own email
        with freeze_time("1999-12-31 23:59:59"):
            params = {
                'email': '*****@*****.**',
                'loggedin_user_password': '******',
            }
            self.testapp.put_json(
                '/api/v2/users/{}/email'.format(admin.user_id),
                params=params,
                status=200,
            )
            assert 'Set-Cookie' in res.headers
            assert 'session_key' in self.testapp.cookies
            user_session_key_2 = self.testapp.cookies['session_key']
            assert user_session_key_1 == user_session_key_2

        # session_id should not be return before x time
        with freeze_time("2000-01-01 00:00:00"):
            res = self.testapp.get(
                '/api/v2/auth/whoami',
                status=200,
            )
            assert 'Set-Cookie' not in res.headers
            assert 'session_key' in self.testapp.cookies
            user_session_key_3 = self.testapp.cookies['session_key']
            assert user_session_key_3 == user_session_key_2

        # after x time session_id should be renew
        with freeze_time("2000-01-01 00:02:01"):
            res = self.testapp.get(
                '/api/v2/auth/whoami',
                status=200,
            )
            assert 'Set-Cookie' in res.headers
            assert 'session_key' in self.testapp.cookies
            user_session_key_4 = self.testapp.cookies['session_key']
            assert user_session_key_4 != user_session_key_3

        # after too much time, session_id should be revoked
        with freeze_time("2000-01-01 00:12:02"):
            res = self.testapp.get(
                '/api/v2/auth/whoami',
                params=params,
                status=401,
            )
            assert 'Set-Cookie' in res.headers
Exemplo n.º 38
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
Exemplo n.º 39
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']