Esempio n. 1
0
    def test_unit__delete_revision__ok__with_unsafe_context(
            self, admin_user, session, content_type_list):

        with unprotected_content_revision(session) as unsafe_session:
            workspace = Workspace(label="TEST_WORKSPACE_1", owner=admin_user)
            unsafe_session.add(workspace)
            unsafe_session.flush()
            content = Content(
                owner=admin_user,
                workspace=workspace,
                type=content_type_list.Page.slug,
                label="TEST_CONTENT_1",
                description="TEST_CONTENT_DESCRIPTION_1",
                revision_type=ActionDescription.CREATION,
                is_deleted=False,
                is_archived=False,
            )
            unsafe_session.add(content)
            unsafe_session.flush()
            with new_revision(session=unsafe_session,
                              tm=transaction.manager,
                              content=content):
                content.description = "TEST_CONTENT_DESCRIPTION_1_UPDATED"
            unsafe_session.add(content)
            unsafe_session.flush()
            unsafe_session.delete(content.revisions[0])
            unsafe_session.flush()
Esempio n. 2
0
    def take_app_action(self, parsed_args: argparse.Namespace,
                        app_context: AppEnvironment) -> None:
        self._session = app_context["request"].dbsession
        self._app_config = app_context["registry"].settings["CFG"]

        if parsed_args.dry_run_mode:
            print("(!) Running in dry-run mode, not change will be applied.")
            app_context["request"].tm.doom()

        with unprotected_content_revision(self._session) as session:
            uapi = UserApi(
                config=self._app_config,
                session=session,
                current_user=None,
                show_deleted=True,
                show_deactivated=True,
            )
            user_list = []  # type: typing.List[User]
            for login in parsed_args.logins:
                try:
                    user = uapi.get_one_by_login(login)
                    user_list.append(user)
                except UserDoesNotExist as exc:
                    print('ERROR: user with email "{}" does not exist'.format(
                        login))
                    raise exc
            for user in user_list:
                print("~~~~~~~~~~")
                cleanup_lib = CleanupLib(session,
                                         self._app_config,
                                         dry_run_mode=parsed_args.dry_run_mode)
                print("anonymize user {}.".format(user.user_id))
                cleanup_lib.anonymize_user(
                    user,
                    anonymized_user_display_name=parsed_args.anonymize_name)
                self._session.flush()
                print('user {} anonymized to "{} <{}/{}>".'.format(
                    user.user_id, user.display_name, user.email,
                    user.username))
                print("~~~~~~~~~~")
Esempio n. 3
0
    def test_unit__delete_content__ok__nominal_case(
        self,
        session,
        app_config,
        content_type_list,
        content_api_factory,
        workspace_api_factory,
        share_lib_factory,
    ) -> None:

        content_api = content_api_factory.get(show_deleted=True,
                                              show_active=True,
                                              show_archived=True)
        workspace_api = workspace_api_factory.get()
        test_workspace = workspace_api.create_workspace("test_workspace")
        folder = content_api.create(
            label="test-folder",
            content_type_slug=content_type_list.Folder.slug,
            workspace=test_workspace,
            do_save=True,
            do_notify=False,
        )
        folder_id = folder.content_id
        file_ = content_api.create(
            content_type_slug=content_type_list.File.slug,
            workspace=test_workspace,
            parent=folder,
            label="Test file",
            do_save=True,
            do_notify=False,
        )
        file_id = file_.content_id
        comment = content_api.create_comment(workspace=test_workspace,
                                             parent=file_,
                                             content="Toto",
                                             do_save=True,
                                             do_notify=False)
        comment_id = comment.content_id
        share_api = share_lib_factory.get()
        shares = share_api.share_content(file_, emails=["*****@*****.**"])
        share_id = shares[0].share_id
        session.flush()
        transaction.commit()
        assert content_api.get_one(folder_id,
                                   content_type=content_type_list.Any_SLUG)
        assert content_api.get_one(file_id,
                                   content_type=content_type_list.Any_SLUG)
        assert content_api.get_one(comment_id,
                                   content_type=content_type_list.Any_SLUG)
        assert session.query(ContentShare).filter(
            ContentShare.share_id == share_id).one()

        with unprotected_content_revision(session) as unprotected_session:
            cleanup_lib = CleanupLib(app_config=app_config,
                                     session=unprotected_session)
            cleanup_lib.delete_content(folder)
            session.flush()
        transaction.commit()
        with pytest.raises(ContentNotFound):
            content_api.get_one(folder_id,
                                content_type=content_type_list.Any_SLUG)
        with pytest.raises(ContentNotFound):
            content_api.get_one(file_id,
                                content_type=content_type_list.Any_SLUG)
        with pytest.raises(ContentNotFound):
            content_api.get_one(comment_id,
                                content_type=content_type_list.Any_SLUG)
        with pytest.raises(NoResultFound):
            session.query(ContentShare).filter(
                ContentShare.share_id == share_id).one()
Esempio n. 4
0
    def test_unit__delete_revision__ok__delete_older_revision(
        self,
        admin_user,
        session,
        app_config,
        content_type_list,
        content_api_factory,
        workspace_api_factory,
        share_lib_factory,
        upload_permission_lib_factory,
    ) -> None:

        content_api = content_api_factory.get(show_deleted=True,
                                              show_active=True,
                                              show_archived=True)
        workspace_api = workspace_api_factory.get()
        test_workspace = workspace_api.create_workspace("test_workspace")
        session.add(test_workspace)
        folder = content_api.create(
            label="test-folder",
            content_type_slug=content_type_list.Folder.slug,
            workspace=test_workspace,
            do_save=True,
            do_notify=False,
        )
        file_ = content_api.create(
            content_type_slug=content_type_list.File.slug,
            workspace=test_workspace,
            parent=folder,
            label="Test file",
            do_save=True,
            do_notify=False,
        )
        with new_revision(session=session,
                          tm=transaction.manager,
                          content=file_):
            content_api.update_file_data(file_,
                                         "Test_file.txt",
                                         new_mimetype="plain/text",
                                         new_content=b"Test file")
        content_api.mark_read(file_)
        file_id = file_.content_id
        revisions = file_.revisions
        session.flush()
        transaction.commit()
        assert len(revisions) == 2
        first_revision_id = revisions[0].revision_id
        second_revision_id = revisions[1].revision_id
        content = content_api.get_one(file_id,
                                      content_type=content_type_list.Any_SLUG)
        assert content
        assert content.revision.revision_id == second_revision_id
        assert (session.query(ContentRevisionRO).filter(
            ContentRevisionRO.revision_id == first_revision_id).one())
        assert (session.query(ContentRevisionRO).filter(
            ContentRevisionRO.revision_id == second_revision_id).one())
        assert (session.query(RevisionReadStatus).filter(
            RevisionReadStatus.revision_id == first_revision_id).one())
        assert (session.query(RevisionReadStatus).filter(
            RevisionReadStatus.revision_id == second_revision_id).one())

        with unprotected_content_revision(session) as unprotected_session:
            cleanup_lib = CleanupLib(app_config=app_config,
                                     session=unprotected_session)
            cleanup_lib.delete_revision(revision=revisions[0])
            session.flush()
        transaction.commit()
        assert content
        assert content.revision.revision_id == second_revision_id
        assert (session.query(ContentRevisionRO).filter(
            ContentRevisionRO.revision_id == second_revision_id).one())
        with pytest.raises(NoResultFound):
            assert (session.query(ContentRevisionRO).filter(
                ContentRevisionRO.revision_id == first_revision_id).one())
        assert (session.query(RevisionReadStatus).filter(
            RevisionReadStatus.revision_id == second_revision_id).one())
        with pytest.raises(NoResultFound):
            assert (session.query(RevisionReadStatus).filter(
                RevisionReadStatus.revision_id == first_revision_id).one())
Esempio n. 5
0
    def test_unit__delete_user_associated_data__ok__nominal_case(
        self,
        admin_user,
        session,
        app_config,
        content_type_list,
        content_api_factory,
        workspace_api_factory,
        share_lib_factory,
        upload_permission_lib_factory,
    ) -> None:

        content_api = content_api_factory.get(show_deleted=True,
                                              show_active=True,
                                              show_archived=True)
        workspace_api = workspace_api_factory.get()
        test_workspace = workspace_api.create_workspace("test_workspace")
        session.add(test_workspace)
        session.flush()
        workspace_id = test_workspace.workspace_id
        folder = content_api.create(
            label="test-folder",
            content_type_slug=content_type_list.Folder.slug,
            workspace=test_workspace,
            do_save=True,
            do_notify=False,
        )
        folder_id = folder.content_id
        folder2 = content_api.create(
            label="test-folder2",
            content_type_slug=content_type_list.Folder.slug,
            workspace=test_workspace,
            do_save=True,
            do_notify=False,
        )
        folder2_id = folder2.content_id
        file_ = content_api.create(
            content_type_slug=content_type_list.File.slug,
            workspace=test_workspace,
            parent=folder,
            label="Test file",
            do_save=True,
            do_notify=False,
        )
        file_id = file_.content_id
        comment = content_api.create_comment(workspace=test_workspace,
                                             parent=file_,
                                             content="Toto",
                                             do_save=True,
                                             do_notify=False)
        comment_id = comment.content_id
        share_api = share_lib_factory.get()
        shares = share_api.share_content(file_, emails=["*****@*****.**"])
        share_id = shares[0].share_id
        upload_permission_lib = upload_permission_lib_factory.get()
        upload_permissions = upload_permission_lib.add_permission_to_workspace(
            workspace=test_workspace, emails=["*****@*****.**"])
        upload_permission_id = upload_permissions[0].upload_permission_id
        session.flush()
        transaction.commit()
        assert content_api.get_one(folder_id,
                                   content_type=content_type_list.Any_SLUG)
        assert content_api.get_one(file_id,
                                   content_type=content_type_list.Any_SLUG)
        assert content_api.get_one(comment_id,
                                   content_type=content_type_list.Any_SLUG)
        assert session.query(ContentShare).filter(
            ContentShare.share_id == share_id).one()
        assert (session.query(UploadPermission).filter(
            UploadPermission.upload_permission_id ==
            upload_permission_id).one())
        session.query(Workspace).filter(
            Workspace.workspace_id == workspace_id).one()

        with unprotected_content_revision(session) as unprotected_session:
            cleanup_lib = CleanupLib(app_config=app_config,
                                     session=unprotected_session)
            cleanup_lib.delete_user_associated_data(admin_user)
            session.flush()
        transaction.commit()
        # INFO - G.M - 2019-12-20 - workspace is not deleted by this method
        session.query(Workspace).filter(
            Workspace.workspace_id == workspace_id).one()
        with pytest.raises(NoResultFound):
            session.query(UserRoleInWorkspace).filter(
                UserRoleInWorkspace.workspace_id == workspace_id).one()
        with pytest.raises(NoResultFound):
            session.query(UploadPermission).filter(
                UploadPermission.workspace_id == workspace_id).one()
        with pytest.raises(ContentNotFound):
            content_api.get_one(folder2_id,
                                content_type=content_type_list.Any_SLUG)
        with pytest.raises(ContentNotFound):
            content_api.get_one(folder_id,
                                content_type=content_type_list.Any_SLUG)
        with pytest.raises(ContentNotFound):
            content_api.get_one(file_id,
                                content_type=content_type_list.Any_SLUG)
        with pytest.raises(ContentNotFound):
            content_api.get_one(comment_id,
                                content_type=content_type_list.Any_SLUG)
        with pytest.raises(NoResultFound):
            session.query(ContentShare).filter(
                ContentShare.share_id == share_id).one()
        with pytest.raises(NoResultFound):
            session.query(UploadPermission).filter(
                UploadPermission.upload_permission_id ==
                upload_permission_id).one()
Esempio n. 6
0
    def take_app_action(self, parsed_args: argparse.Namespace,
                        app_context: AppEnvironment) -> None:
        self._session = app_context["request"].dbsession
        self._app_config = app_context["registry"].settings["CFG"]

        delete_user_revision = parsed_args.force or parsed_args.delete_revisions
        delete_owned_sharespaces = (parsed_args.force
                                    or parsed_args.best_effort
                                    or parsed_args.delete_sharespaces)
        anonymize_if_required = parsed_args.best_effort or parsed_args.anonymize_if_required

        if parsed_args.dry_run_mode:
            print("(!) Running in dry-run mode, no changes will be applied.")
            app_context["request"].tm.doom()
        if parsed_args.force:
            print("(!) Running in force mode")
        if parsed_args.best_effort:
            print("(!) Running in best-effort mode")

        if delete_user_revision:
            print(
                "/!\\ Delete all user revisions, database created may be broken /!\\."
            )
        if delete_owned_sharespaces:
            print("(!) User owned sharespaces will be deleted too.")
        if anonymize_if_required:
            print("(!) Will anonymize user if not possible to delete it")
            if parsed_args.anonymize_name:
                print('(!) Custom anonymize name choosen is: "{}"'.format(
                    parsed_args.anonymize_name))
        print("")
        deleted_user_ids = set()  # typing.Set[int]
        deleted_workspace_ids = set()  # typing.Set[int]
        with unprotected_content_revision(self._session) as session:
            uapi = UserApi(
                config=self._app_config,
                session=session,
                current_user=None,
                show_deleted=True,
                show_deactivated=True,
            )
            user_list = []  # type: typing.List[User]
            for login in parsed_args.logins:
                try:
                    user = uapi.get_one_by_login(login)
                    user_list.append(user)
                except UserDoesNotExist as exc:
                    print(
                        'ERROR: user with email/username "{}" does not exist'.
                        format(login))
                    raise exc
            print("~~~~")
            print("Deletion of user from Database")
            print("~~~~\n")
            print("~~~~")
            for user in user_list:
                cleanup_lib = CleanupLib(session,
                                         self._app_config,
                                         dry_run_mode=parsed_args.dry_run_mode)
                deleted_user_ids_result = self._delete_user_database_info(
                    user,
                    force_delete_all_user_revisions=delete_user_revision,
                    anonymize_if_required=anonymize_if_required,
                    delete_owned_workspaces=delete_owned_sharespaces,
                    anonymized_user_display_name=parsed_args.anonymize_name,
                    cleanup_lib=cleanup_lib,
                )
                deleted_user_ids.add(deleted_user_ids_result.user_id)
                deleted_workspace_ids.update(
                    deleted_user_ids_result.workspace_ids)
                print("~~~~")
            print(
                "deletion of user(s) from database process almost finished, change will be applied at end "
                "of this script.\n")
            print("~~~~")
            print("Deletion of Caldav Agenda\n")
            app_lib = ApplicationApi(app_list=app_list)
            if app_lib.exist(AGENDA__APP_SLUG):
                # INFO - G.M - 2019-12-13 - cleanup agenda at end of process
                if deleted_workspace_ids:
                    deleted_workspace_ids_str = [
                        '"{}"'.format(workspace_id)
                        for workspace_id in deleted_workspace_ids
                    ]
                    print("delete agenda of workspaces {}".format(
                        ", ".join(deleted_workspace_ids_str)))
                    for workspace_id in deleted_workspace_ids:
                        try:
                            cleanup_lib.delete_workspace_agenda(workspace_id)
                        except AgendaNotFoundError:
                            print(
                                'Warning: Cannot delete agenda for workspace "{}", agenda not found. Agenda path may be incorrect or agenda not created'
                                .format(workspace_id))
                            print(traceback.format_exc())

                if deleted_user_ids:
                    deleted_user_ids_str = [
                        '"{}"'.format(user_id) for user_id in deleted_user_ids
                    ]
                    print("delete agenda of users {}".format(
                        ", ".join(deleted_user_ids_str)))
                    for user_id in deleted_user_ids:
                        try:
                            cleanup_lib.delete_user_agenda(user_id)
                        except AgendaNotFoundError:
                            print(
                                'Warning: Cannot delete agenda for user "{}", agenda not found. Agenda path may be incorrect or agenda not created'
                                .format(user_id))
                            print(traceback.format_exc())
            else:
                print(
                    "Warning ! Agenda app not enabled, agenda will not be deleted."
                )
            print("~~~~")
            print("deletion of Agenda process finished")
            print("~~~~")
            if parsed_args.dry_run_mode:
                print("Finished (dry-run mode, no change applied)")
            else:
                print("Finished")