def add_event( self, calendar: Calendar, event: iCalendarEvent, event_name: str, owner: User, ) -> Content: """ Create Content event type. :param calendar: Event calendar owner :param event: ICS event :param event_name: Event name (ID) like 20160602T083511Z-18100-1001-1-71_Bastien-20160602T083516Z.ics :param owner: Event Owner :return: Created Content """ workspace = None if isinstance(calendar, WorkspaceCalendar): workspace = calendar.related_object elif isinstance(calendar, UserCalendar): pass else: raise UnknownCalendarType('Type "{0}" is not implemented'.format( type(calendar))) content = ContentApi(owner).create(content_type=ContentType.Event, workspace=workspace, do_save=False) self.populate_content_with_event(content, event, event_name) content.revision_type = ActionDescription.CREATION DBSession.add(content) DBSession.flush() transaction.commit() return content
def _load(self, fixture_class): if fixture_class not in self._loaded: fixture = fixture_class(DBSession) fixture.insert() self._loaded.append(fixture_class) DBSession.flush() transaction.commit()
def ensure_calendar_exist(self, workspace: Workspace) -> None: # Note: Cyclic imports from tracim.lib.calendar import CalendarManager from tracim.model.organisational import WorkspaceCalendar calendar_manager = CalendarManager(self._user) try: calendar_manager.enable_calendar_file( calendar_class=WorkspaceCalendar, related_object_id=workspace.workspace_id, raise_=True, ) # If previous calendar file no exist, calendar must be created except FileNotFoundError: self._user.ensure_auth_token() # Ensure database is up-to-date DBSession.flush() transaction.commit() calendar_manager.create_then_remove_fake_event( calendar_class=WorkspaceCalendar, related_object_id=workspace.workspace_id, )
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_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 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 ensure_calendar_exist(self, workspace: Workspace) -> None: # Note: Cyclic imports from tracim.lib.calendar import CalendarManager from tracim.model.organisational import WorkspaceCalendar calendar_manager = CalendarManager(self._user) try: calendar_manager.enable_calendar_file( calendar_class=WorkspaceCalendar, related_object_id=workspace.workspace_id, raise_=True, ) # If previous calendar file no exist, calendar must be created except FileNotFoundError: self._user.ensure_auth_token() # Ensure database is up-to-date DBSession.flush() transaction.commit() calendar_manager.create_then_remove_fake_event( calendar_class=WorkspaceCalendar, related_object_id=workspace.workspace_id, )
def test_serializer_content__menui_api_context__children(self): folder_without_child = Content() folder_without_child.type = ContentType.Folder res = Context(CTX.MENU_API).toDict(folder_without_child) eq_(False, res['children']) folder_with_child = Content() folder_with_child.type = ContentType.Folder folder_without_child.parent = folder_with_child DBSession.add(folder_with_child) DBSession.add(folder_without_child) DBSession.flush() res = Context(CTX.MENU_API).toDict(folder_with_child) eq_(True, res['children']) for curtype in ContentType.all(): if curtype not in (ContentType.Folder, ContentType.Comment): item = Content() item.type = curtype fake_child = Content() fake_child.type = curtype fake_child.parent = item DBSession.add(item) DBSession.add(fake_child) DBSession.flush() res = Context(CTX.MENU_API).toDict(item) eq_(False, res['children'])
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 create_workspace( self, label: str = '', description: str = '', calendar_enabled: bool = False, save_now: bool = False, ) -> Workspace: if not label: label = self.generate_label() workspace = Workspace() workspace.label = label workspace.description = description workspace.calendar_enabled = calendar_enabled # By default, we force the current user to be the workspace manager # And to receive email notifications role = RoleApi(self._user).create_one( self._user, workspace, UserRoleInWorkspace.WORKSPACE_MANAGER, with_notif=True) DBSession.add(workspace) DBSession.add(role) if save_now: DBSession.flush() if calendar_enabled: self.ensure_calendar_exist(workspace) else: self.disable_calendar(workspace) return workspace
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 test_create(self, key='1'): eq_(0, DBSession.query(ContentRevisionRO).filter(ContentRevisionRO.label == 'TEST_CONTENT_%s' % key).count()) eq_(0, DBSession.query(Workspace).filter(Workspace.label == 'TEST_WORKSPACE_%s' % key).count()) user_admin = DBSession.query(User).filter(User.email == '*****@*****.**').one() workspace = Workspace(label="TEST_WORKSPACE_%s" % key) DBSession.add(workspace) DBSession.flush() eq_(1, DBSession.query(Workspace).filter(Workspace.label == 'TEST_WORKSPACE_%s' % key).count()) created_content = self._create_content( owner=user_admin, workspace=workspace, type=ContentType.Page, label='TEST_CONTENT_%s' % key, description='TEST_CONTENT_DESCRIPTION_%s' % key, revision_type=ActionDescription.CREATION ) eq_(1, DBSession.query(ContentRevisionRO).filter(ContentRevisionRO.label == 'TEST_CONTENT_%s' % key).count()) content = DBSession.query(Content).filter(Content.id == created_content.id).one() eq_('TEST_CONTENT_%s' % key, content.label) eq_('TEST_CONTENT_DESCRIPTION_%s' % key, content.description) return created_content
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 create_workspace( self, label: str='', description: str='', calendar_enabled: bool=False, save_now: bool=False, ) -> Workspace: if not label: label = self.generate_label() workspace = Workspace() workspace.label = label workspace.description = description workspace.calendar_enabled = calendar_enabled # By default, we force the current user to be the workspace manager # And to receive email notifications role = RoleApi(self._user).create_one(self._user, workspace, UserRoleInWorkspace.WORKSPACE_MANAGER, with_notif=True) DBSession.add(workspace) DBSession.add(role) if save_now: DBSession.flush() if calendar_enabled: self.ensure_calendar_exist(workspace) else: self.disable_calendar(workspace) return workspace
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 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 create_one(self, user: User, workspace: Workspace, role_level: int, with_notif: bool, flush: bool=True) -> UserRoleInWorkspace: role = self.create_role() role.user_id = user.user_id role.workspace = workspace role.role = role_level role.do_notify = with_notif if flush: DBSession.flush() return role
def create_one(self, user: User, workspace: Workspace, role_level: int, with_notif: bool, flush: bool=True) -> UserRoleInWorkspace: role = self.create_role() role.user_id = user.user_id role.workspace = workspace role.role = role_level if with_notif is not None: from tracim.lib.helpers import on_off_to_boolean role.do_notify = on_off_to_boolean(with_notif) if flush: DBSession.flush() return role
def create_one(self, user: User, workspace: Workspace, role_level: int, with_notif: bool, flush: bool=True) -> UserRoleInWorkspace: role = self.create_role() role.user_id = user.user_id role.workspace = workspace role.role = role_level if with_notif is not None: from tracim.lib.helpers import on_off_to_boolean role.do_notify = on_off_to_boolean(with_notif) if flush: DBSession.flush() return role
def post(self, name, description, calendar_enabled: str='off'): # FIXME - Check user profile user = tmpl_context.current_user workspace_api_controller = WorkspaceApi(user) calendar_enabled = on_off_to_boolean(calendar_enabled) workspace = workspace_api_controller.create_workspace(name, description) workspace.calendar_enabled = calendar_enabled DBSession.flush() tg.flash(_('{} workspace created.').format(workspace.label), CST.STATUS_OK) tg.redirect(self.url()) return
def _create_content_and_test(self, name, workspace, *args, **kwargs) -> Content: """ All extra parameters (*args, **kwargs) are for Content init :return: Created Content instance """ content = Content(*args, **kwargs) content.label = name content.workspace = workspace DBSession.add(content) DBSession.flush() eq_(1, ContentApi.get_canonical_query().filter(Content.label == name).count()) return ContentApi.get_canonical_query().filter(Content.label == name).one()
def _create_content_and_test(self, name, workspace, *args, **kwargs) -> Content: """ All extra parameters (*args, **kwargs) are for Content init :return: Created Content instance """ content = Content(*args, **kwargs) content.label = name content.workspace = workspace DBSession.add(content) DBSession.flush() eq_(1, ContentApi.get_canonical_query().filter(Content.label == name).count()) return ContentApi.get_canonical_query().filter(Content.label == name).one()
def post(self, name, description, calendar_enabled: str = 'off'): # FIXME - Check user profile user = tmpl_context.current_user workspace_api_controller = WorkspaceApi(user) calendar_enabled = on_off_to_boolean(calendar_enabled) workspace = workspace_api_controller.create_workspace( name, description) workspace.calendar_enabled = calendar_enabled DBSession.flush() tg.flash( _('{} workspace created.').format(workspace.label), CST.STATUS_OK) tg.redirect(self.url()) return
def create_user(self, email=None, groups=[], save_now=False) -> User: user = User() if email: user.email = email for group in groups: user.groups.append(group) DBSession.add(user) if save_now: DBSession.flush() return user
def update_event( self, calendar: Calendar, event: iCalendarEvent, event_name: str, current_user: User, ) -> Content: """ Update Content Event :param calendar: Event calendar owner :param event: ICS event :param event_name: Event name (ID) like 20160602T083511Z-18100-1001-1-71_Bastien-20160602T083516Z.ics :param current_user: Current modification asking user :return: Updated Content """ workspace = None if isinstance(calendar, WorkspaceCalendar): workspace = calendar.related_object elif isinstance(calendar, UserCalendar): pass else: raise UnknownCalendarType('Type "{0}" is not implemented' .format(type(calendar))) content_api = ContentApi( current_user, force_show_all_types=True, disable_user_workspaces_filter=True ) content = content_api.find_one_by_unique_property( property_name='name', property_value=event_name, workspace=workspace ) with new_revision(content): self.populate_content_with_event( content, event, event_name ) content.revision_type = ActionDescription.EDITION DBSession.flush() transaction.commit() return content
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 ensure_calendar_exist(self, workspace: Workspace) -> None: # Note: Cyclic imports from tracim.lib.calendar import CalendarManager from tracim.model.organisational import WorkspaceCalendar if workspace.calendar_enabled: self._user.ensure_auth_token() # Ensure database is up-to-date DBSession.flush() transaction.commit() calendar_manager = CalendarManager(self._user) calendar_manager.create_then_remove_fake_event( calendar_class=WorkspaceCalendar, related_object_id=workspace.workspace_id, )
def create_workspace(self, label: str, description: str='', save_now:bool=False) -> Workspace: workspace = Workspace() workspace.label = label workspace.description = description # By default, we force the current user to be the workspace manager # And to receive email notifications role = RoleApi(self._user).create_one(self._user, workspace, UserRoleInWorkspace.WORKSPACE_MANAGER, with_notif=True) DBSession.add(workspace) DBSession.add(role) if save_now: DBSession.flush() return workspace
def _sync_ldap_user(self, email, environ, identity): # Create or get user for connected email if not self._user_api.user_with_email_exists(email): user = User(email=email, imported_from=LDAPAuth.name) DBSession.add(user) else: user = self._user_api.get_one_by_email(email) # Retrieve ldap user attributes self._auth.ldap_user_provider.add_metadata_for_auth(environ, identity) # Update user with ldap attributes user_ldap_values = identity.get('user').copy() for field_name in user_ldap_values: setattr(user, field_name, user_ldap_values[field_name]) DBSession.flush() transaction.commit()
def authenticate(self, environ, identity, allow_auth_token: bool=False): user = self.sa_auth.dbsession.query(self.sa_auth.user_class).filter(and_( self.sa_auth.user_class.is_active == True, self.sa_auth.user_class.email == identity['login'] )).first() if user and user.validate_password(identity['password']): if user.webdav_left_digest_response_hash == '': user.webdav_left_digest_response_hash = '%s:/:%s' % (identity['login'], identity['password']) DBSession.flush() # TODO : temporary fix to update DB, to remove transaction.commit() return identity['login'] if user and allow_auth_token: user.ensure_auth_token() if user.auth_token == identity['password']: return identity['login']
def authenticate(self, environ, identity, allow_auth_token: bool = False): user = self.sa_auth.dbsession.query(self.sa_auth.user_class).filter( and_(self.sa_auth.user_class.is_active == True, self.sa_auth.user_class.email == identity['login'])).first() if user and user.validate_password(identity['password']): if user.webdav_left_digest_response_hash == '': user.webdav_left_digest_response_hash = '%s:/:%s' % ( identity['login'], identity['password']) DBSession.flush() # TODO : temporary fix to update DB, to remove transaction.commit() return identity['login'] if user and allow_auth_token: user.ensure_auth_token() if user.auth_token == identity['password']: return identity['login']
def _sync_ldap_user(self, email, environ, identity): # Create or get user for connected email if not self._user_api.user_with_email_exists(email): user = User(email=email, imported_from=LDAPAuth.name) DBSession.add(user) else: user = self._user_api.get_one_by_email(email) # Retrieve ldap user attributes self._auth.ldap_user_provider.add_metadata_for_auth(environ, identity) # Update user with ldap attributes user_ldap_values = identity.get('user').copy() for field_name in user_ldap_values: setattr(user, field_name, user_ldap_values[field_name]) DBSession.flush() transaction.commit()
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 save(self, content: Content, action_description: str = None, do_flush=True, do_notify=True): """ Save an object, flush the session and set the revision_type property :param content: :param action_description: :return: """ assert action_description is None or action_description in ActionDescription.allowed_values( ) if not action_description: # See if the last action has been modified if content.revision_type == None or len( get_history(content.revision, 'revision_type')) <= 0: # The action has not been modified, so we set it to default edition action_description = ActionDescription.EDITION if action_description: content.revision_type = action_description if do_flush: # INFO - 2015-09-03 - D.A. # There are 2 flush because of the use # of triggers for content creation # # (when creating a content, actually this is an insert of a new # revision in content_revisions ; so the mark_read operation need # to get full real data from database before to be prepared. DBSession.add(content) DBSession.flush() # TODO - 2015-09-03 - D.A. - Do not use triggers # We should create a new ContentRevisionRO object instead of Content # This would help managing view/not viewed status self.mark_read(content, do_flush=True) if do_notify: self.do_notify(content)
def test_create(self): DBSession.flush() transaction.commit() name = 'Damien' email = '*****@*****.**' user = User() user.display_name = name user.email = email DBSession.add(user) DBSession.flush() transaction.commit() new_user = DBSession.query(User).filter(User.display_name==name).one() eq_(new_user.display_name, name) eq_(new_user.email, email) eq_(new_user.email_address, email)
def execute_created_user_actions(self, created_user: User) -> None: """ Execute actions when user just been created :return: """ # NOTE: Cyclic import from tracim.lib.calendar import CalendarManager from tracim.model.organisational import UserCalendar created_user.ensure_auth_token() # Ensure database is up-to-date DBSession.flush() transaction.commit() calendar_manager = CalendarManager(created_user) calendar_manager.create_then_remove_fake_event( calendar_class=UserCalendar, related_object_id=created_user.user_id )
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 test_create(self): DBSession.flush() transaction.commit() name = 'Damien' email = '*****@*****.**' user = User() user.display_name = name user.email = email DBSession.add(user) DBSession.flush() transaction.commit() new_user = DBSession.query(User).filter( User.display_name == name).one() eq_(new_user.display_name, name) eq_(new_user.email, email) eq_(new_user.email_address, email)
def delete_event_with_name(self, event_name: str, current_user: User)\ -> Content: """ Delete Content Event :param event_name: Event name (ID) like 20160602T083511Z-18100-1001-1-71_Bastien-20160602T083516Z.ics :param current_user: Current deletion asking user :return: Deleted Content """ content_api = ContentApi(current_user, force_show_all_types=True) content = content_api.find_one_by_unique_property( property_name='name', property_value=event_name, workspace=None) with new_revision(content): content_api.delete(content) DBSession.flush() transaction.commit() return content
def execute_created_user_actions(self, created_user: User) -> None: """ Execute actions when user just been created :return: """ # NOTE: Cyclic import from tracim.lib.calendar import CalendarManager from tracim.model.organisational import UserCalendar created_user.ensure_auth_token() # Ensure database is up-to-date DBSession.flush() transaction.commit() calendar_manager = CalendarManager(created_user) calendar_manager.create_then_remove_fake_event( calendar_class=UserCalendar, related_object_id=created_user.user_id, )
def update_event( self, calendar: Calendar, event: iCalendarEvent, event_name: str, current_user: User, ) -> Content: """ Update Content Event :param calendar: Event calendar owner :param event: ICS event :param event_name: Event name (ID) like 20160602T083511Z-18100-1001-1-71_Bastien-20160602T083516Z.ics :param current_user: Current modification asking user :return: Updated Content """ workspace = None if isinstance(calendar, WorkspaceCalendar): workspace = calendar.related_object elif isinstance(calendar, UserCalendar): pass else: raise UnknownCalendarType('Type "{0}" is not implemented'.format( type(calendar))) content_api = ContentApi(current_user, force_show_all_types=True, disable_user_workspaces_filter=True) content = content_api.find_one_by_unique_property( property_name='name', property_value=event_name, workspace=workspace) with new_revision(content): self.populate_content_with_event(content, event, event_name) content.revision_type = ActionDescription.EDITION DBSession.flush() transaction.commit() return content
def add_event( self, calendar: Calendar, event: iCalendarEvent, event_name: str, owner: User, ) -> Content: """ Create Content event type. :param calendar: Event calendar owner :param event: ICS event :param event_name: Event name (ID) like 20160602T083511Z-18100-1001-1-71_Bastien-20160602T083516Z.ics :param owner: Event Owner :return: Created Content """ workspace = None if isinstance(calendar, WorkspaceCalendar): workspace = calendar.related_object elif isinstance(calendar, UserCalendar): pass else: raise UnknownCalendarType('Type "{0}" is not implemented' .format(type(calendar))) content = ContentApi(owner).create( content_type=ContentType.Event, workspace=workspace, do_save=False ) self.populate_content_with_event( content, event, event_name ) content.revision_type = ActionDescription.CREATION DBSession.add(content) DBSession.flush() transaction.commit() return content
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)) eq_(2, base_query.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 ensure_auth_token(self) -> None: """ Create auth_token if None, regenerate auth_token if too much old. auth_token validity is set in :return: """ from tracim.config.app_cfg import CFG validity_seconds = CFG.get_instance().USER_AUTH_TOKEN_VALIDITY if not self.auth_token or not self.auth_token_created: self.auth_token = str(uuid.uuid4()) self.auth_token_created = datetime.utcnow() DBSession.flush() return now_seconds = time.mktime(datetime.utcnow().timetuple()) auth_token_seconds = time.mktime(self.auth_token_created.timetuple()) difference = now_seconds - auth_token_seconds if difference > validity_seconds: self.auth_token = uuid.uuid4() self.auth_token_created = datetime.utcnow() DBSession.flush()
def ensure_auth_token(self) -> None: """ Create auth_token if None, regenerate auth_token if too much old. auth_token validity is set in :return: """ from tracim.config.app_cfg import CFG validity_seconds = CFG.get_instance().USER_AUTH_TOKEN_VALIDITY if not self.auth_token or not self.auth_token_created: self.auth_token = uuid.uuid4() self.auth_token_created = datetime.utcnow() DBSession.flush() return now_seconds = time.mktime(datetime.utcnow().timetuple()) auth_token_seconds = time.mktime(self.auth_token_created.timetuple()) difference = now_seconds - auth_token_seconds if difference > validity_seconds: self.auth_token = uuid.uuid4() self.auth_token_created = datetime.utcnow() DBSession.flush()
def delete_event_with_name(self, event_name: str, current_user: User)\ -> Content: """ Delete Content Event :param event_name: Event name (ID) like 20160602T083511Z-18100-1001-1-71_Bastien-20160602T083516Z.ics :param current_user: Current deletion asking user :return: Deleted Content """ content_api = ContentApi(current_user, force_show_all_types=True) content = content_api.find_one_by_unique_property( property_name='name', property_value=event_name, workspace=None ) with new_revision(content): content_api.delete(content) DBSession.flush() transaction.commit() return content
def create_workspace(self, label: str, description: str = '', save_now: bool = False) -> Workspace: workspace = Workspace() workspace.label = label workspace.description = description # By default, we force the current user to be the workspace manager # And to receive email notifications role = RoleApi(self._user).create_one( self._user, workspace, UserRoleInWorkspace.WORKSPACE_MANAGER, with_notif=True) DBSession.add(workspace) DBSession.add(role) if save_now: DBSession.flush() return workspace
def save(self, content: Content, action_description: str=None, do_flush=True, do_notify=True): """ Save an object, flush the session and set the revision_type property :param content: :param action_description: :return: """ assert action_description is None or action_description in ActionDescription.allowed_values() if not action_description: # See if the last action has been modified if content.revision_type==None or len(get_history(content.revision, 'revision_type'))<=0: # The action has not been modified, so we set it to default edition action_description = ActionDescription.EDITION if action_description: content.revision_type = action_description if do_flush: # INFO - 2015-09-03 - D.A. # There are 2 flush because of the use # of triggers for content creation # # (when creating a content, actually this is an insert of a new # revision in content_revisions ; so the mark_read operation need # to get full real data from database before to be prepared. DBSession.add(content) DBSession.flush() # TODO - 2015-09-03 - D.A. - Do not use triggers # We should create a new ContentRevisionRO object instead of Content # This would help managing view/not viewed status self.mark_read(content, do_flush=True) if do_notify: self.do_notify(content)
def test_serializer_content__menui_api_context__children(self): folder_without_child = Content() folder_without_child.type = ContentType.Folder folder_without_child.label = 'folder_without_child' res = Context(CTX.MENU_API).toDict(folder_without_child) eq_(False, res['children']) folder_with_child = Content() folder_with_child.type = ContentType.Folder folder_with_child.label = 'folder_with_child' folder_without_child.parent = folder_with_child DBSession.add(folder_with_child) DBSession.add(folder_without_child) DBSession.flush() res = Context(CTX.MENU_API).toDict(folder_with_child) eq_(True, res['children']) for curtype in ContentType.all(): if curtype not in (ContentType.Folder, ContentType.Comment, ContentType.Event): item = Content() item.type = curtype item.label = 'item' fake_child = Content() fake_child.type = curtype fake_child.label = 'fake_child' fake_child.parent = item DBSession.add(item) DBSession.add(fake_child) DBSession.flush() res = Context(CTX.MENU_API).toDict(item) eq_(False, res['children'])
def flush(self): DBSession.flush()
def _create_content(self, *args, **kwargs): content = Content(*args, **kwargs) DBSession.add(content) DBSession.flush() return content
def put(self, new_profile): # FIXME - Allow only self password or operation for managers current_user = tmpl_context.current_user user = tmpl_context.user group_api = GroupApi(current_user) if current_user.user_id==user.user_id: tg.flash(_('You can\'t change your own profile'), CST.STATUS_ERROR) tg.redirect(self.parent_controller.url()) redirect_url = self.parent_controller.url(skip_id=True) if new_profile not in self.allowed_profiles: tg.flash(_('Unknown profile'), CST.STATUS_ERROR) tg.redirect(redirect_url) pod_user_group = group_api.get_one(Group.TIM_USER) pod_manager_group = group_api.get_one(Group.TIM_MANAGER) pod_admin_group = group_api.get_one(Group.TIM_ADMIN) flash_message = _('User updated.') # this is the default value ; should never appear if new_profile==UserProfileAdminRestController._ALLOWED_PROFILE_USER: if pod_user_group not in user.groups: user.groups.append(pod_user_group) try: user.groups.remove(pod_manager_group) except: pass try: user.groups.remove(pod_admin_group) except: pass flash_message = _('User {} is now a basic user').format(user.get_display_name()) elif new_profile==UserProfileAdminRestController._ALLOWED_PROFILE_MANAGER: if pod_user_group not in user.groups: user.groups.append(pod_user_group) if pod_manager_group not in user.groups: user.groups.append(pod_manager_group) try: user.groups.remove(pod_admin_group) except: pass flash_message = _('User {} can now workspaces').format(user.get_display_name()) elif new_profile==UserProfileAdminRestController._ALLOWED_PROFILE_ADMIN: if pod_user_group not in user.groups: user.groups.append(pod_user_group) if pod_manager_group not in user.groups: user.groups.append(pod_manager_group) if pod_admin_group not in user.groups: user.groups.append(pod_admin_group) flash_message = _('User {} is now an administrator').format(user.get_display_name()) else: logger.error(self, 'Trying to change user {} profile with unexpected profile {}'.format(user.user_id, new_profile)) tg.flash(_('Unknown profile'), CST.STATUS_ERROR) tg.redirect(redirect_url) DBSession.flush() tg.flash(flash_message, CST.STATUS_OK) tg.redirect(redirect_url)
def save(self, role: UserRoleInWorkspace): DBSession.flush()
def delete_one(self, user_id, workspace_id, flush=True): self._get_one_rsc(user_id, workspace_id).delete() if flush: DBSession.flush()