Example #1
0
    def test_create_user(self):
        self._connect_user(
            '*****@*****.**',
            '*****@*****.**',
        )

        user_count = DBSession.query(User) \
            .filter(User.email == '*****@*****.**').count()
        eq_(0, user_count, 'User should not exist yet')

        # Create a new user
        try_post_user = self.app.post(
            '/admin/users',
            OrderedDict([
                ('name', 'TEST'),
                ('email', '*****@*****.**'),
                ('password', 'password'),
                ('is_tracim_manager', 'off'),
                ('is_tracim_admin', 'off'),
                ('send_email', 'off'),
            ])
        )

        eq_(try_post_user.status_code, 302,
            "Code should be 302, but is %d" % try_post_user.status_code)

        user = DBSession.query(User) \
            .filter(User.email == '*****@*****.**').one()
        ok_(user, msg="User should exist now")
        ok_(user.validate_password('password'))

        # User must have webdav digest
        ok_(user.webdav_left_digest_response_hash)
Example #2
0
    def test_create_user(self):
        self._connect_user(
            '*****@*****.**',
            '*****@*****.**',
        )

        user_count = DBSession.query(User) \
            .filter(User.email == '*****@*****.**').count()
        eq_(0, user_count, 'User should not exist yet')

        # Create a new user
        try_post_user = self.app.post(
            '/admin/users',
            OrderedDict([
                ('name', 'TEST'),
                ('email', '*****@*****.**'),
                ('password', 'password'),
                ('is_tracim_manager', 'off'),
                ('is_tracim_admin', 'off'),
                ('send_email', 'off'),
            ]))

        eq_(try_post_user.status_code, 302,
            "Code should be 302, but is %d" % try_post_user.status_code)

        user = DBSession.query(User) \
            .filter(User.email == '*****@*****.**').one()
        ok_(user, msg="User should exist now")
        ok_(user.validate_password('password'))

        # User must have webdav digest
        ok_(user.webdav_left_digest_response_hash)
Example #3
0
    def test_unit__cant_get_non_access_content__ok__nominal_case(self):
        admin = DBSession.query(User)\
            .filter(User.email == '*****@*****.**').one()
        bob = DBSession.query(User)\
            .filter(User.email == '*****@*****.**').one()

        bob_workspace = WorkspaceApi(bob).create_workspace(
            'bob_workspace',
            save_now=True,
        )
        admin_workspace = WorkspaceApi(admin).create_workspace(
            'admin_workspace',
            save_now=True,
        )

        bob_page = ContentApi(bob).create(
            content_type=ContentType.Page,
            workspace=bob_workspace,
            label='bob_page',
            do_save=True,
        )

        admin_page = ContentApi(bob).create(
            content_type=ContentType.Page,
            workspace=admin_workspace,
            label='admin_page',
            do_save=True,
        )

        bob_viewable = ContentApi(bob).get_all()
        eq_(1, len(bob_viewable), 'Bob should view only one content')
        eq_(
            'bob_page',
            bob_viewable[0].label, 'Bob should not view "{0}" content'.format(
                bob_viewable[0].label, ))
Example #4
0
    def test_unit__rename_content__ok(self):
        provider = self._get_provider()
        environ = self._get_environ(
            provider,
            '*****@*****.**',
        )
        w1f1d1 = provider.getResourceInst(
            '/w1/w1f1/w1f1d1.txt',
            environ,
        )

        content_w1f1d1 = DBSession.query(ContentRevisionRO) \
            .filter(Content.label == 'w1f1d1') \
            .one()  # It must exist only one revision, cf fixtures
        ok_(content_w1f1d1, msg='w1f1d1 should be exist')
        content_w1f1d1_id = content_w1f1d1.content_id

        w1f1d1.moveRecursive('/w1/w1f1/w1f1d1_RENAMED.txt')

        # Database content is renamed
        content_w1f1d1 = DBSession.query(ContentRevisionRO) \
            .filter(ContentRevisionRO.content_id == content_w1f1d1_id) \
            .order_by(ContentRevisionRO.revision_id.desc()) \
            .first()
        eq_(
            'w1f1d1_RENAMED',
            content_w1f1d1.label,
            msg='File should be labeled w1f1d1_RENAMED, not {0}'.format(
                content_w1f1d1.label
            )
        )
Example #5
0
    def test_update_password(self):
        self._connect_user(
            '*****@*****.**',
            'foobarbaz',
        )

        user = DBSession.query(User) \
            .filter(User.email == '*****@*****.**').one()
        webdav_digest = user.webdav_left_digest_response_hash

        try_post_user = self.app.post(
            '/user/{user_id}/password?_method=PUT'.format(
                user_id=user.user_id
            ),
            OrderedDict([
                ('current_password', 'foobarbaz'),
                ('new_password1', 'new-password'),
                ('new_password2', 'new-password'),
            ])
        )
        eq_(try_post_user.status_code, 302,
            "Code should be 302, but is %d" % try_post_user.status_code)

        user = DBSession.query(User) \
            .filter(User.email == '*****@*****.**').one()
        ok_(user.validate_password('new-password'))
        ok_(
            webdav_digest != user.webdav_left_digest_response_hash,
            msg='Webdav digest should be updated',
        )
    def test_internal_groups(self):
        """
        LDAP don't manage groups here: We must retrieve internal groups of tested user
        :return:
        """
        lawrence = DBSession.query(User).filter(
            User.email == '*****@*****.**').one()
        managers = DBSession.query(Group).filter(
            Group.group_name == 'managers').one()
        lawrence_identity = {'user': lawrence}

        # Lawrence is in fixtures: he is in managers group
        self._check_db_user('*****@*****.**', 1)
        assert lawrence in managers.users
        assert False is ini_conf_to_bool(
            config.get('ldap_group_enabled', False))
        assert ['managers'] == config.get('sa_auth').authmetadata.get_groups(
            identity=lawrence_identity, userid=lawrence.email)

        should_groups = ['managers']
        are_groups = config.get('sa_auth').authmetadata.get_groups(
            identity=lawrence_identity, userid=lawrence.email)
        eq_(
            should_groups, are_groups,
            "Permissions should be %s, they are %s" %
            (should_groups, are_groups))
Example #7
0
    def test_unit__move_content__ok(self):
        provider = self._get_provider()
        environ = self._get_environ(
            provider,
            '*****@*****.**',
        )
        w1f1d1 = provider.getResourceInst(
            '/w1/w1f1/w1f1d1.txt',
            environ,
        )

        content_w1f1d1 = DBSession.query(ContentRevisionRO) \
            .filter(Content.label == 'w1f1d1') \
            .one()  # It must exist only one revision, cf fixtures
        ok_(content_w1f1d1, msg='w1f1d1 should be exist')
        content_w1f1d1_id = content_w1f1d1.content_id
        content_w1f1d1_parent = content_w1f1d1.parent
        eq_(
            content_w1f1d1_parent.label,
            'w1f1',
            msg='field parent should be w1f1',
        )

        w1f1d1.moveRecursive('/w1/w1f2/w1f1d1.txt')  # move in f2

        # Database content is moved
        content_w1f1d1 = DBSession.query(ContentRevisionRO) \
            .filter(ContentRevisionRO.content_id == content_w1f1d1_id) \
            .order_by(ContentRevisionRO.revision_id.desc()) \
            .first()
        ok_(content_w1f1d1.parent.label != content_w1f1d1_parent.label,
            msg='file should be moved in w1f2 but is in {0}'.format(
                content_w1f1d1.parent.label))
Example #8
0
    def test_unit__delete_content__ok(self):
        provider = self._get_provider()
        w1f1d1 = provider.getResourceInst(
            '/w1/w1f1/w1f1d1.txt',
            self._get_environ(
                provider,
                '*****@*****.**',
            ))

        content_w1f1d1 = DBSession.query(ContentRevisionRO) \
            .filter(Content.label == 'w1f1d1') \
            .one()  # It must exist only one revision, cf fixtures
        eq_(False,
            content_w1f1d1.is_deleted,
            msg='Content should not be deleted !')
        content_w1f1d1_id = content_w1f1d1.content_id

        w1f1d1.delete()

        DBSession.flush()
        content_w1f1d1 = DBSession.query(ContentRevisionRO) \
            .filter(Content.content_id == content_w1f1d1_id) \
            .order_by(Content.revision_id.desc()) \
            .first()
        eq_(True, content_w1f1d1.is_deleted, msg='Content should be deleted !')

        result = provider.getResourceInst(
            '/w1/w1f1/w1f1d1.txt',
            self._get_environ(
                provider,
                '*****@*****.**',
            ))
        eq_(None,
            result,
            msg='Result should be None instead {0}'.format(result))
Example #9
0
    def _get_content_by_label(self, label: str) -> Content:
        revision = DBSession.query(ContentRevisionRO) \
            .filter(ContentRevisionRO.label == label) \
            .one()

        return DBSession.query(Content) \
            .filter(Content.id == revision.content_id) \
            .one()
    def test_ldap_auth_fail_no_account(self):
        # User is unknown in tracim database
        eq_(0, DBSession.query(User).filter(User.email == '*****@*****.**').count())

        self._connect_user('*****@*****.**', 'no-pass')

        # User is registered in tracim database
        eq_(0, DBSession.query(User).filter(User.email == '*****@*****.**').count())
Example #11
0
    def _base_query(self):
        if self._user.profile.id>=Group.TIM_ADMIN:
            return DBSession.query(Workspace).filter(Workspace.is_deleted==False)

        return DBSession.query(Workspace).\
            join(Workspace.roles).\
            filter(UserRoleInWorkspace.user_id==self._user.user_id).\
            filter(Workspace.is_deleted==False)
    def test_ldap_auth_sync(self):
        # User is unknown in tracim database
        eq_(0, DBSession.query(User).filter(User.email == '*****@*****.**').count())

        self._connect_user('*****@*****.**', 'rms')

        # User is registered in tracim database
        eq_(1, DBSession.query(User).filter(User.email == '*****@*****.**').count())
Example #13
0
    def _get_content_by_label(self, label: str) -> Content:
        revision = DBSession.query(ContentRevisionRO) \
            .filter(ContentRevisionRO.label == label) \
            .one()

        return DBSession.query(Content) \
            .filter(Content.id == revision.content_id) \
            .one()
Example #14
0
    def _create_workspace_and_test(self, name, user) -> Workspace:
        """
        All extra parameters (*args, **kwargs) are for Workspace init
        :return: Created workspace instance
        """
        WorkspaceApi(user).create_workspace(name, save_now=True)

        eq_(1, DBSession.query(Workspace).filter(Workspace.label == name).count())
        return DBSession.query(Workspace).filter(Workspace.label == name).one()
Example #15
0
    def test_create_with_group(self):
        more_args = ['--add-to-group', 'managers', '--add-to-group', 'administrators']
        self._create_user('*****@*****.**', 'toor', more_args=more_args)
        user = DBSession.query(User).filter(User.email == '*****@*****.**').one()
        group_managers = DBSession.query(Group).filter(Group.group_name == 'managers').one()
        group_administrators = DBSession.query(Group).filter(Group.group_name == 'administrators').one()

        ok_(user in group_managers.users)
        ok_(user in group_administrators.users)
Example #16
0
    def _base_query(self):
        if self._user.profile.id >= Group.TIM_ADMIN:
            return DBSession.query(Workspace).filter(
                Workspace.is_deleted == False)

        return DBSession.query(Workspace).\
            join(Workspace.roles).\
            filter(UserRoleInWorkspace.user_id==self._user.user_id).\
            filter(Workspace.is_deleted==False)
Example #17
0
    def _create_workspace_and_test(self, name, user) -> Workspace:
        """
        All extra parameters (*args, **kwargs) are for Workspace init
        :return: Created workspace instance
        """
        WorkspaceApi(user).create_workspace(name, save_now=True)

        eq_(1, DBSession.query(Workspace).filter(Workspace.label == name).count())
        return DBSession.query(Workspace).filter(Workspace.label == name).one()
Example #18
0
    def get_last_unread(self,
                        parent_id: int,
                        content_type: str,
                        workspace: Workspace = None,
                        limit=10) -> [Content]:
        assert parent_id is None or isinstance(parent_id, int)  # DYN_REMOVE
        assert content_type is not None  # DYN_REMOVE
        assert isinstance(content_type, str)  # DYN_REMOVE

        read_revision_ids = DBSession.query(RevisionReadStatus.revision_id) \
            .filter(RevisionReadStatus.user_id==self._user_id)

        not_read_revisions = self._revisions_base_query(workspace) \
            .filter(~ContentRevisionRO.revision_id.in_(read_revision_ids)) \
            .subquery()

        not_read_content_ids_query = DBSession.query(
            distinct(not_read_revisions.c.content_id))
        not_read_content_ids = list(
            map(
                itemgetter(0),
                not_read_content_ids_query,
            ))

        not_read_contents = self._base_query(workspace) \
            .filter(Content.content_id.in_(not_read_content_ids)) \
            .order_by(desc(Content.updated))

        if content_type != ContentType.Any:
            not_read_contents = not_read_contents.filter(
                Content.type == content_type)
        else:
            not_read_contents = not_read_contents.filter(
                Content.type != ContentType.Folder)

        if parent_id:
            not_read_contents = not_read_contents.filter(
                Content.parent_id == parent_id)

        result = []
        for item in not_read_contents:
            new_item = None
            if ContentType.Comment == item.type:
                new_item = item.parent
            else:
                new_item = item

            # INFO - D.A. - 2015-05-20
            # We do not want to show only one item if the last 10 items are
            # comments about one thread for example
            if new_item not in result:
                result.append(new_item)

            if len(result) >= limit:
                break

        return result
Example #19
0
    def test_update(self):
        created_content = self.test_create()
        content = DBSession.query(Content).filter(Content.id == created_content.id).one()
        eq_(1, DBSession.query(ContentRevisionRO).filter(ContentRevisionRO.label == 'TEST_CONTENT_1').count())

        with new_revision(content):
            time.sleep(0.00001)
            content.description = 'TEST_CONTENT_DESCRIPTION_1_UPDATED'
        DBSession.flush()

        eq_(2, DBSession.query(ContentRevisionRO).filter(ContentRevisionRO.label == 'TEST_CONTENT_1').count())
        eq_(1, DBSession.query(Content).filter(Content.id == created_content.id).count())

        with new_revision(content):
            time.sleep(0.00001)
            content.description = 'TEST_CONTENT_DESCRIPTION_1_UPDATED_2'
            content.label = 'TEST_CONTENT_1_UPDATED_2'
        DBSession.flush()

        eq_(1, DBSession.query(ContentRevisionRO).filter(ContentRevisionRO.label == 'TEST_CONTENT_1_UPDATED_2').count())
        eq_(1, DBSession.query(Content).filter(Content.id == created_content.id).count())

        revision_1 = DBSession.query(ContentRevisionRO)\
            .filter(ContentRevisionRO.description == 'TEST_CONTENT_DESCRIPTION_1').one()
        revision_2 = DBSession.query(ContentRevisionRO)\
            .filter(ContentRevisionRO.description == 'TEST_CONTENT_DESCRIPTION_1_UPDATED').one()
        revision_3 = DBSession.query(ContentRevisionRO)\
            .filter(ContentRevisionRO.description == 'TEST_CONTENT_DESCRIPTION_1_UPDATED_2').one()

        # Updated dates must be different
        ok_(revision_1.updated < revision_2.updated < revision_3.updated)
        # Created dates must be equal
        ok_(revision_1.created == revision_2.created == revision_3.created)
Example #20
0
    def test_change_groups(self):
        # create an user in managers group
        more_args = ['--add-to-group', 'managers']
        self._create_user('*****@*****.**', 'toor', more_args=more_args)
        user = DBSession.query(User).filter(User.email == '*****@*****.**').one()
        group_managers = DBSession.query(Group).filter(Group.group_name == 'managers').one()
        group_administrators = DBSession.query(Group).filter(Group.group_name == 'administrators').one()

        ok_(user in group_managers.users)
        ok_(user not in group_administrators.users)

        # Update him and add to administrators group
        add_to_admins_argvs = ['-l', '*****@*****.**', '--add-to-group', 'administrators']
        self._execute_command(UpdateUserCommand, 'gearbox user update', add_to_admins_argvs)
        user = DBSession.query(User).filter(User.email == '*****@*****.**').one()
        group_managers = DBSession.query(Group).filter(Group.group_name == 'managers').one()
        group_administrators = DBSession.query(Group).filter(Group.group_name == 'administrators').one()

        ok_(user in group_managers.users)
        ok_(user in group_administrators.users)

        # remove him from administrators group
        remove_from_admins_argvs = ['-l', '*****@*****.**', '--remove-from-group', 'administrators']
        self._execute_command(UpdateUserCommand, 'gearbox user update', remove_from_admins_argvs)
        user = DBSession.query(User).filter(User.email == '*****@*****.**').one()
        group_managers = DBSession.query(Group).filter(Group.group_name == 'managers').one()
        group_administrators = DBSession.query(Group).filter(Group.group_name == 'administrators').one()

        ok_(user in group_managers.users)
        ok_(user not in group_administrators.users)
Example #21
0
    def test_created_workspace_radicale_calendar(self):
        self._connect_user(
            '*****@*****.**',
            '*****@*****.**',
        )

        workspaces_count = DBSession.query(Workspace)\
            .filter(Workspace.label == 'WTESTCAL').count()
        eq_(0, workspaces_count, 'Workspace should not exist yet !')

        radicale_workspaces_folder = '{0}/workspace'\
            .format(config.get('radicale.server.filesystem.folder'))
        eq_(
            False,
            os.path.isdir(radicale_workspaces_folder),
            'Radicale workskpaces folder should not exist yet',
        )

        # Create a new workspace, his calendar should be created to
        try_post_workspace = self.app.post(
            '/admin/workspaces',
            OrderedDict([
                ('name', 'WTESTCAL'),
                ('description', 'WTESTCALDESCR'),
                ('calendar_enabled', 'on'),
            ])
        )

        eq_(try_post_workspace.status_code, 302,
            "Code should be 302, but is %d" % try_post_workspace.status_code)

        workspaces_calendars = len([
            name for name in os.listdir(radicale_workspaces_folder)
            if name.endswith('.ics')
        ])

        workspace = DBSession.query(Workspace) \
            .filter(Workspace.label == 'WTESTCAL').one()

        eq_(
            1,
            workspaces_calendars,
            'Radicale workspace path should list 1 calendar',
        )
        workspace_calendar = '{0}/{1}.ics'.format(
            radicale_workspaces_folder,
            workspace.workspace_id,
        )
        workspace_calendar_exist = os.path.isfile(workspace_calendar)
        eq_(
            True,
            workspace_calendar_exist,
            'Workspace calendar should be created',
        )
Example #22
0
    def get_last_unread(self, parent_id: int, content_type: str,
                        workspace: Workspace=None, limit=10) -> [Content]:
        assert parent_id is None or isinstance(parent_id, int) # DYN_REMOVE
        assert content_type is not None# DYN_REMOVE
        assert isinstance(content_type, str) # DYN_REMOVE

        read_revision_ids = DBSession.query(RevisionReadStatus.revision_id) \
            .filter(RevisionReadStatus.user_id==self._user_id)

        not_read_revisions = self._revisions_base_query(workspace) \
            .filter(~ContentRevisionRO.revision_id.in_(read_revision_ids)) \
            .subquery()

        not_read_content_ids_query = DBSession.query(
            distinct(not_read_revisions.c.content_id)
        )
        not_read_content_ids = list(map(
            itemgetter(0),
            not_read_content_ids_query,
        ))

        not_read_contents = self._base_query(workspace) \
            .filter(Content.content_id.in_(not_read_content_ids)) \
            .order_by(desc(Content.updated))

        if content_type != ContentType.Any:
            not_read_contents = not_read_contents.filter(
                Content.type==content_type)
        else:
            not_read_contents = not_read_contents.filter(
                Content.type!=ContentType.Folder)

        if parent_id:
            not_read_contents = not_read_contents.filter(
                Content.parent_id==parent_id)

        result = []
        for item in not_read_contents:
            new_item = None
            if ContentType.Comment == item.type:
                new_item = item.parent
            else:
                new_item = item

            # INFO - D.A. - 2015-05-20
            # We do not want to show only one item if the last 10 items are
            # comments about one thread for example
            if new_item not in result:
                result.append(new_item)

            if len(result) >= limit:
                break

        return result
Example #23
0
 def test_children(self):
     admin = DBSession.query(User).filter(User.email == '*****@*****.**').one()
     self._create_thread_and_test(
         workspace_name='workspace_1',
         folder_name='folder_1',
         thread_name='thread_1',
         user=admin
     )
     workspace = DBSession.query(Workspace).filter(Workspace.label == 'workspace_1').one()
     folder = ContentApi.get_canonical_query().filter(Content.label == 'folder_1').one()
     eq_([folder, ], list(workspace.get_valid_children()))
Example #24
0
 def test_children(self):
     admin = DBSession.query(User).filter(User.email == '*****@*****.**').one()
     self._create_thread_and_test(
         workspace_name='workspace_1',
         folder_name='folder_1',
         thread_name='thread_1',
         user=admin
     )
     workspace = DBSession.query(Workspace).filter(Workspace.label == 'workspace_1').one()
     folder = ContentApi.get_canonical_query().filter(Content.label == 'folder_1').one()
     eq_([folder, ], list(workspace.get_valid_children()))
    def test_ldap_attributes_sync(self):
        # User is already know in database
        eq_(1, DBSession.query(User).filter(User.email == '*****@*****.**').count())

        # His display name is Lawrence L.
        lawrence = DBSession.query(User).filter(User.email == '*****@*****.**').one()
        eq_('Lawrence L.', lawrence.display_name)

        # After connexion with LDAP, his display_name is updated (see ldap fixtures)
        self._connect_user('*****@*****.**', 'foobarbaz')
        lawrence = DBSession.query(User).filter(User.email == '*****@*****.**').one()
        eq_('Lawrence Lessig', lawrence.display_name)
Example #26
0
    def test_func__event_create__ok__nominal_case(self):
        lawrence = DBSession.query(User).filter(
            User.email == '*****@*****.**'
        ).one()
        radicale_base_url = CalendarManager.get_base_url()
        client = caldav.DAVClient(
            radicale_base_url,
            username='******',
            password='******'
        )
        user_calendar_url = CalendarManager.get_user_calendar_url(
            lawrence.user_id
        )
        user_calendar = caldav.Calendar(
            parent=client,
            client=client,
            url=user_calendar_url
        )

        event_ics = """BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Example Corp.//CalDAV Client//EN
BEGIN:VEVENT
UID:1234567890
DTSTAMP:20100510T182145Z
DTSTART:20100512T170000Z
DTEND:20100512T180000Z
SUMMARY:This is an event
LOCATION:Here
END:VEVENT
END:VCALENDAR
"""
        user_calendar.add_event(event_ics)
        user_calendar.save()

        daemons.execute_in_thread('radicale', lambda: transaction.commit())
        # TODO - 20160606 - Bastien: lock should be better here ?
        time.sleep(3)  # Wait for be sure transaction commited in daemon
        transaction.commit()
        try:
            event = DBSession.query(Content) \
                .filter(Content.label == 'This is an event') \
                .filter(Content.owner_id == lawrence.user_id) \
                .filter(Content.id == ContentRevisionRO.content_id) \
                .one()
        except NoResultFound:
            ok_(False, 'Content record should exist for '
                       '"This is an event" label')

        eq_(event.properties['location'], 'Here')
        eq_(event.properties['start'], '2010-05-12 18:00:00+0000')
        eq_(event.properties['end'], '2010-05-12 17:00:00+0000')
Example #27
0
    def test_ldap_auth_fail_no_account(self):
        # User is unknown in tracim database
        eq_(
            0,
            DBSession.query(User).filter(
                User.email == '*****@*****.**').count())

        self._connect_user('*****@*****.**', 'no-pass')

        # User is registered in tracim database
        eq_(
            0,
            DBSession.query(User).filter(
                User.email == '*****@*****.**').count())
Example #28
0
    def test_ldap_auth_sync(self):
        # User is unknown in tracim database
        eq_(
            0,
            DBSession.query(User).filter(
                User.email == '*****@*****.**').count())

        self._connect_user('*****@*****.**', 'rms')

        # User is registered in tracim database
        eq_(
            1,
            DBSession.query(User).filter(
                User.email == '*****@*****.**').count())
Example #29
0
    def test_create_with_group(self):
        more_args = [
            '--add-to-group', 'managers', '--add-to-group', 'administrators'
        ]
        self._create_user('*****@*****.**', 'toor', more_args=more_args)
        user = DBSession.query(User).filter(
            User.email == '*****@*****.**').one()
        group_managers = DBSession.query(Group).filter(
            Group.group_name == 'managers').one()
        group_administrators = DBSession.query(Group).filter(
            Group.group_name == 'administrators').one()

        ok_(user in group_managers.users)
        ok_(user in group_administrators.users)
Example #30
0
    def test_creates(self):
        eq_(
            0,
            DBSession.query(ContentRevisionRO).filter(
                ContentRevisionRO.label == 'TEST_CONTENT_1').count())
        eq_(
            0,
            DBSession.query(Workspace).filter(
                Workspace.label == 'TEST_WORKSPACE_1').count())

        user_admin = DBSession.query(User).filter(
            User.email == '*****@*****.**').one()
        workspace = Workspace(label="TEST_WORKSPACE_1")
        DBSession.add(workspace)
        DBSession.flush()
        eq_(
            1,
            DBSession.query(Workspace).filter(
                Workspace.label == 'TEST_WORKSPACE_1').count())

        first_content = self._create_content(
            owner=user_admin,
            workspace=workspace,
            type=ContentType.Page,
            label='TEST_CONTENT_1',
            description='TEST_CONTENT_DESCRIPTION_1',
            revision_type=ActionDescription.CREATION,
            is_deleted=False,  # TODO: pk ?
            is_archived=False,  # TODO: pk ?
            # file_content=None,  # TODO: pk ? (J'ai du mettre nullable=True)
        )

        eq_(
            1,
            DBSession.query(ContentRevisionRO).filter(
                ContentRevisionRO.label == 'TEST_CONTENT_1').count())

        content = DBSession.query(Content).filter(
            Content.id == first_content.id).one()
        eq_('TEST_CONTENT_1', content.label)
        eq_('TEST_CONTENT_DESCRIPTION_1', content.description)

        # Create a second content
        second_content = self._create_content(
            owner=user_admin,
            workspace=workspace,
            type=ContentType.Page,
            label='TEST_CONTENT_2',
            description='TEST_CONTENT_DESCRIPTION_2',
            revision_type=ActionDescription.CREATION)

        eq_(
            1,
            DBSession.query(ContentRevisionRO).filter(
                ContentRevisionRO.label == 'TEST_CONTENT_2').count())

        content = DBSession.query(Content).filter(
            Content.id == second_content.id).one()
        eq_('TEST_CONTENT_2', content.label)
        eq_('TEST_CONTENT_DESCRIPTION_2', content.description)
Example #31
0
    def __revisions_real_base_query(self, workspace: Workspace=None):
        result = DBSession.query(ContentRevisionRO)

        if workspace:
            result = result.filter(ContentRevisionRO.workspace_id==workspace.workspace_id)

        if self._user:
            user = DBSession.query(User).get(self._user_id)
            # Filter according to user workspaces
            workspace_ids = [r.workspace_id for r in user.roles \
                             if r.role>=UserRoleInWorkspace.READER]
            result = result.filter(ContentRevisionRO.workspace_id.in_(workspace_ids))

        return result
Example #32
0
    def test_created_user_radicale_calendar(self):
        self._connect_user(
            '*****@*****.**',
            '*****@*****.**',
        )

        user_count = DBSession.query(User)\
            .filter(User.email == '*****@*****.**').count()
        eq_(0, user_count, 'User should not exist yet')

        radicale_users_folder = '{0}/user'\
            .format(config.get('radicale.server.filesystem.folder'))
        eq_(
            False,
            os.path.isdir(radicale_users_folder),
            'Radicale users folder should not exist yet',
        )

        # Create a new user, his calendar should be created to
        try_post_user = self.app.post(
            '/admin/users',
            OrderedDict([
                ('name', 'TEST'),
                ('email', '*****@*****.**'),
                ('password', '*****@*****.**'),
                ('is_tracim_manager', 'off'),
                ('is_tracim_admin', 'off'),
                ('send_email', 'off'),
            ])
        )

        eq_(try_post_user.status_code, 302,
            "Code should be 302, but is %d" % try_post_user.status_code)

        users_calendars = len([
            name for name in os.listdir(radicale_users_folder)
            if name.endswith('.ics')
        ])

        user = DBSession.query(User) \
            .filter(User.email == '*****@*****.**').one()

        eq_(1, users_calendars, 'Radicale user path should list 1 calendar')
        user_calendar = '{0}/{1}.ics'.format(
            radicale_users_folder,
            user.user_id,
        )
        user_calendar_exist = os.path.isfile(user_calendar)
        eq_(True, user_calendar_exist, 'User calendar should be created')
Example #33
0
    def getLockList(self, path, includeRoot, includeChildren, tokenOnly):
        """Return a list of direct locks for <path>.

        Expired locks are *not* returned (but may be purged).

        path:
            Normalized path (utf8 encoded string, no trailing '/')
        includeRoot:
            False: don't add <path> lock (only makes sense, when includeChildren
            is True).
        includeChildren:
            True: Also check all sub-paths for existing locks.
        tokenOnly:
            True: only a list of token is returned. This may be implemented
            more efficiently by some providers.
        Returns:
            List of valid lock dictionaries (may be empty).
        """
        assert path and path.startswith("/")
        assert includeRoot or includeChildren

        def __appendLocks(toklist):
            # Since we can do this quickly, we use self.get() even if
            # tokenOnly is set, so expired locks are purged.
            for token in toklist:
                lock_db = self.get_lock_db_from_token(token)
                if lock_db:
                    if tokenOnly:
                        lockList.append(lock_db.token)
                    else:
                        lockList.append(from_base_to_dict(lock_db))

        path = normalizeLockRoot(path)
        self._lock.acquireRead()
        try:
            tokList = DBSession.query(Url2Token.token).filter(Url2Token.path == path).all()
            lockList = []
            if includeRoot:
                __appendLocks(tokList)

            if includeChildren:
                for url, in DBSession.query(Url2Token.path).group_by(Url2Token.path):
                    if util.isChildUri(path, url):
                        __appendLocks(DBSession.query(Url2Token.token).filter(Url2Token.path == url))

            return lockList
        finally:
            self._lock.release()
Example #34
0
    def test_new_revision(self):
        admin = DBSession.query(User).filter(
            User.email == '*****@*****.**').one()
        workspace = self._create_workspace_and_test(name='workspace_1',
                                                    user=admin)
        folder = self._create_content_and_test(name='folder_1',
                                               workspace=workspace,
                                               type=ContentType.Folder)
        page = self._create_content_and_test(workspace=workspace,
                                             parent=folder,
                                             name='file_1',
                                             description='content of file_1',
                                             type=ContentType.Page,
                                             owner=admin)

        DBSession.flush()

        # Model create a new instance with list of column
        new_revision_by_model = ContentRevisionRO.new_from(page.revision)
        # Test create a new instance from dynamic listing of model columns mapping
        new_revision_by_test = self._new_from(page.revision)

        new_revision_by_model_dict = self._get_dict_representation(
            new_revision_by_model)
        new_revision_by_test_dict = self._get_dict_representation(
            new_revision_by_test)

        # They must be identical
        eq_(new_revision_by_model_dict, new_revision_by_test_dict)
Example #35
0
 def get_canonical_query(cls):
     """
     Return the Content/ContentRevision base query who join these table on the last revision.
     :return: Content/ContentRevision Query
     :rtype sqlalchemy.orm.query.Query
     """
     return DBSession.query(Content).join(ContentRevisionRO, cls.get_revision_join())
Example #36
0
 def test_unit__get_all_manageable(self):
     admin = DBSession.query(User) \
         .filter(User.email == '*****@*****.**').one()
     uapi = UserApi(admin)
     # Checks a case without workspaces.
     wapi = WorkspaceApi(current_user=admin)
     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(None)
     u = uapi.create_user('[email protected]', [gapi.get_one(Group.TIM_USER)], True)
     wapi = WorkspaceApi(current_user=u)
     rapi = RoleApi(current_user=u)
     off = 'off'
     rapi.create_one(u, w4, UserRoleInWorkspace.READER, off)
     rapi.create_one(u, w3, UserRoleInWorkspace.CONTRIBUTOR, off)
     rapi.create_one(u, w2, UserRoleInWorkspace.CONTENT_MANAGER, off)
     rapi.create_one(u, w1, UserRoleInWorkspace.WORKSPACE_MANAGER, off)
     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, off)
     eq_([w1, w2], wapi.get_all_manageable())
Example #37
0
    def test_password_disabled(self):
        """
        Password change is disabled
        :return:
        """
        lawrence = DBSession.query(User).filter(
            User.email == '*****@*****.**').one()
        self._connect_user('*****@*****.**', 'foobarbaz')
        home = self.app.get('/home/', )

        # HTML button is not here
        eq_(
            None,
            BeautifulSoup(
                home.body).find(attrs={'class': 'change-password-btn'}))

        # If we force passwd update, we got 403
        try_post_passwd = self.app.post('/user/%d/password?_method=PUT' %
                                        lawrence.user_id,
                                        OrderedDict([
                                            ('current_password', 'fooobarbaz'),
                                            ('new_password1', 'foobar'),
                                            ('new_password2', 'foobar'),
                                        ]),
                                        expect_errors=403)
        eq_(try_post_passwd.status_code, 403,
            "Code should be 403, but is %d" % try_post_passwd.status_code)
    def test_new_revision(self):
        admin = DBSession.query(User).filter(User.email == '*****@*****.**').one()
        workspace = self._create_workspace_and_test(name='workspace_1', user=admin)
        folder = self._create_content_and_test(name='folder_1', workspace=workspace, type=ContentType.Folder)
        page = self._create_content_and_test(
            workspace=workspace,
            parent=folder,
            name='file_1',
            description='content of file_1',
            type=ContentType.Page,
            owner=admin
        )

        DBSession.flush()

        # Model create a new instance with list of column
        new_revision_by_model = ContentRevisionRO.new_from(page.revision)
        # Test create a new instance from dynamic listing of model columns mapping
        new_revision_by_test = self._new_from(page.revision)

        new_revision_by_model_dict = self._get_dict_representation(new_revision_by_model)
        new_revision_by_test_dict = self._get_dict_representation(new_revision_by_test)

        # They must be identical
        eq_(new_revision_by_model_dict, new_revision_by_test_dict)
Example #39
0
    def __real_base_query(self, workspace: Workspace=None):
        result = self.get_canonical_query()

        # Exclude non displayable types
        if not self._force_show_all_types:
            result = result.filter(Content.type.in_(self.DISPLAYABLE_CONTENTS))

        if workspace:
            result = result.filter(Content.workspace_id==workspace.workspace_id)

        # Security layer: if user provided, filter
        # with user workspaces privileges
        if self._user and not self._disable_user_workspaces_filter:
            user = DBSession.query(User).get(self._user_id)
            # Filter according to user workspaces
            workspace_ids = [r.workspace_id for r in user.roles \
                             if r.role>=UserRoleInWorkspace.READER]
            result = result.filter(or_(
                Content.workspace_id.in_(workspace_ids),
                # And allow access to non workspace document when he is owner
                and_(
                    Content.workspace_id == None,
                    Content.owner_id == self._user_id,
                )
            ))

        return result
Example #40
0
 def test_unit__get_all_manageable(self):
     admin = DBSession.query(User) \
         .filter(User.email == '*****@*****.**').one()
     uapi = UserApi(admin)
     # Checks a case without workspaces.
     wapi = WorkspaceApi(current_user=admin)
     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(None)
     u = uapi.create_user('[email protected]', [gapi.get_one(Group.TIM_USER)], True)
     wapi = WorkspaceApi(current_user=u)
     rapi = RoleApi(current_user=u)
     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())
Example #41
0
    def test_func__rights_read_workspace_calendar__fail__as_unauthorized(self):
        lawrence = DBSession.query(User).filter(
            User.email == '*****@*****.**'
        ).one()
        workspace = WorkspaceApi(lawrence).create_workspace(
            'workspace_1',
            save_now=False
        )
        workspace.calendar_enabled = True
        DBSession.flush()

        workspace_calendar_url = CalendarManager.get_workspace_calendar_url(
            workspace.workspace_id
        )

        transaction.commit()

        radicale_base_url = CalendarManager.get_base_url()
        client = caldav.DAVClient(
            radicale_base_url,
            username='******',
            password='******'
        )
        caldav.Calendar(
            parent=client,
            client=client,
            url=workspace_calendar_url
        ).events()
Example #42
0
    def delete(self, token):
        """Delete lock.

        Returns True on success. False, if token does not exist, or is expired.
        """
        self._lock.acquireWrite()
        try:
            lock_db = self.__base_query().filter(Lock.token == token).one_or_none()
            _logger.debug("delete %s" % lockString(from_base_to_dict(lock_db)))
            if lock_db is None:
                return False
            # Remove url to lock mapping
            url2token = DBSession.query(Url2Token).filter(
                Url2Token.path == lock_db.root,
                Url2Token.token == token).one_or_none()
            if url2token is not None:
                DBSession.delete(url2token)
            # Remove the lock
            DBSession.delete(lock_db)
            transaction.commit()

            self._flush()
        finally:
            self._lock.release()
        return True
Example #43
0
    def __real_base_query(self, workspace: Workspace = None):
        result = self.get_canonical_query()

        # Exclude non displayable types
        if not self._force_show_all_types:
            result = result.filter(Content.type.in_(self.DISPLAYABLE_CONTENTS))

        if workspace:
            result = result.filter(
                Content.workspace_id == workspace.workspace_id)

        # Security layer: if user provided, filter
        # with user workspaces privileges
        if self._user and not self._disable_user_workspaces_filter:
            user = DBSession.query(User).get(self._user_id)
            # Filter according to user workspaces
            workspace_ids = [r.workspace_id for r in user.roles \
                             if r.role>=UserRoleInWorkspace.READER]
            result = result.filter(
                or_(
                    Content.workspace_id.in_(workspace_ids),
                    # And allow access to non workspace document when he is owner
                    and_(
                        Content.workspace_id == None,
                        Content.owner_id == self._user_id,
                    )))

        return result
Example #44
0
 def get_canonical_query(cls):
     """
     Return the Content/ContentRevision base query who join these table on the last revision.
     :return: Content/ContentRevision Query
     :rtype sqlalchemy.orm.query.Query
     """
     return DBSession.query(Content).join(ContentRevisionRO, cls.get_revision_join())
Example #45
0
    def unit_test__disable_workspace_disable_file__ok__nominal_case(self):
        self._connect_user(
            '*****@*****.**',
            '*****@*****.**',
        )
        radicale_workspaces_folder = '{0}/workspace'.format(
            config.get('radicale.server.filesystem.folder'), )
        delete_radicale_workspaces_folder = '{0}/workspace/deleted'.format(
            config.get('radicale.server.filesystem.folder'), )

        # Core after assume "test_created_workspace_radicale_calendar" is ok
        self.app.post(
            '/admin/workspaces',
            OrderedDict([
                ('name', 'WTESTCAL2'),
                ('description', 'WTESTCAL2DESCR'),
                ('calendar_enabled', 'on'),
            ]))
        created_workspace = DBSession.query(Workspace)\
            .filter(Workspace.label == 'WTESTCAL2')\
            .one()
        disable_response = self.app.put(
            '/admin/workspaces/{}?_method=PUT'.format(
                created_workspace.workspace_id, ),
            OrderedDict([
                ('name', 'WTESTCAL2'),
                ('description', 'WTESTCAL2DESCR'),
                ('calendar_enabled', 'off'),
            ]))
        eq_(disable_response.status_code, 302,
            "Code should be 302, but is %d" % disable_response.status_code)
        workspaces_calendars = [
            name for name in os.listdir(radicale_workspaces_folder)
            if name.endswith('.ics')
        ]
        deleted_workspaces_calendars = [
            name for name in os.listdir(delete_radicale_workspaces_folder)
            if name.endswith('.ics')
        ]

        eq_(
            0,
            len(workspaces_calendars),
            msg='No workspace ics file should exist, but {} found'.format(
                len(workspaces_calendars), ),
        )
        eq_(
            1,
            len(deleted_workspaces_calendars),
            msg='1 deleted workspace ics file should exist, but {} found'.
            format(len(deleted_workspaces_calendars), ),
        )
        workspace_ics_file_name = '{}.ics'.format(
            created_workspace.workspace_id)
        ok_(
            workspace_ics_file_name in deleted_workspaces_calendars,
            '{} should be in deleted workspace calendar folder'.format(
                workspace_ics_file_name),
        )
Example #46
0
    def test_query(self):
        content1 = self.test_create()
        with new_revision(content1):
            content1.description = 'TEST_CONTENT_DESCRIPTION_1_UPDATED'
        DBSession.flush()

        content2 = self.test_create(key='2')
        with new_revision(content2):
            content2.description = 'TEST_CONTENT_DESCRIPTION_2_UPDATED'
        DBSession.flush()

        workspace1 = DBSession.query(Workspace).filter(
            Workspace.label == 'TEST_WORKSPACE_1').one()
        workspace2 = DBSession.query(Workspace).filter(
            Workspace.label == 'TEST_WORKSPACE_2').one()

        # To get Content in database we have to join Content and ContentRevisionRO with particular condition:
        # Join have to be on most recent revision
        join_sub_query = DBSession.query(ContentRevisionRO.revision_id)\
            .filter(ContentRevisionRO.content_id == Content.id)\
            .order_by(ContentRevisionRO.revision_id.desc())\
            .limit(1)\
            .correlate(Content)

        base_query = DBSession.query(Content)\
            .join(ContentRevisionRO, and_(Content.id == ContentRevisionRO.content_id,
                                          ContentRevisionRO.revision_id == join_sub_query))

        pattern = 'TEST_CONTENT_DESCRIPTION_%_UPDATED'
        eq_(2, base_query.filter(Content.description.like(pattern)).count())

        eq_(1, base_query.filter(Content.workspace == workspace1).count())
        eq_(1, base_query.filter(Content.workspace == workspace2).count())

        content1_from_query = base_query.filter(
            Content.workspace == workspace1).one()
        eq_(content1.id, content1_from_query.id)
        eq_('TEST_CONTENT_DESCRIPTION_1_UPDATED',
            content1_from_query.description)

        user_admin = DBSession.query(User).filter(
            User.email == '*****@*****.**').one()
        api = ContentApi(None)

        content1_from_api = api.get_one(content1.id, ContentType.Page,
                                        workspace1)
Example #47
0
    def restore_one(self, workspace_id, flush=True):
        workspace = DBSession.query(Workspace).filter(Workspace.is_deleted==True).filter(Workspace.workspace_id==workspace_id).one()
        workspace.is_deleted = False

        if flush:
            DBSession.flush()

        return workspace
Example #48
0
 def test_create_thread(self, key='1'):
     admin = DBSession.query(User).filter(User.email == '*****@*****.**').one()
     return self._create_thread_and_test(
         workspace_name='workspace_%s' % key,
         folder_name='folder_%s' % key,
         thread_name='thread_%s' % key,
         user=admin
     )
Example #49
0
    def _base_query(self):
        if not self._force_role and self._user.profile.id>=Group.TIM_ADMIN:
            return self._base_query_without_roles()

        return DBSession.query(Workspace).\
            join(Workspace.roles).\
            filter(UserRoleInWorkspace.user_id==self._user.user_id).\
            filter(Workspace.is_deleted==False)
Example #50
0
 def test_update_password(self):
     self._create_user('*****@*****.**', 'toor')
     self._execute_command(
         CreateUserCommand,
         'gearbox user update',
         ['-l', '*****@*****.**', '-p', 'new_password']
     )
     user = DBSession.query(User).filter(User.email == '*****@*****.**').one()
     user.validate_password('new_password')
Example #51
0
 def _get_one_rsc(self, user_id, workspace_id):
     """
     :param user_id:
     :param workspace_id:
     :return: a Query object, filtered query but without fetching the object.
     """
     return DBSession.query(UserRoleInWorkspace).\
         filter(UserRoleInWorkspace.workspace_id==workspace_id).\
         filter(UserRoleInWorkspace.user_id==user_id)