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)
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)
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, ))
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 ) )
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))
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))
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))
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())
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())
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()
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)
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 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
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)
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)
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', )
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
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)
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')
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())
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())
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)
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)
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
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')
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()
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)
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())
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())
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)
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
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())
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()
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
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
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), )
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)
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
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 )
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)
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')
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)