Пример #1
0
    def test_copy_local_groups(self):
        from kotti import DBSession
        from kotti.resources import get_root
        from kotti.security import principals_with_local_roles
        from kotti.security import set_groups

        self.test_principals_with_local_roles()
        root = get_root()
        child = root[u'child']
        self.assertEqual(
            set(principals_with_local_roles(child)),
            set(['bob', 'group:bobsgroup', 'group:franksgroup'])
            )

        # We make a copy of 'child', and we expect the local roles set
        # on 'child' to not be copied over:
        child2 = root['child2'] = child.copy()
        DBSession.flush()
        self.assertEqual(
            set(principals_with_local_roles(child2)),
            set([u'bob', u'group:franksgroup']),
            )
        self.assertEqual(len(principals_with_local_roles(child)), 3)

        # When we now change the local roles of 'child', the copy is
        # unaffected:
        set_groups('group:bobsgroup', child, [])
        self.assertEqual(len(principals_with_local_roles(child)), 2)
        self.assertEqual(len(principals_with_local_roles(child2)), 2)
Пример #2
0
def default_search_content(search_term, request=None):

    searchstring = u'%%%s%%' % search_term

    # generic_filter can be applied to all Node (and subclassed) objects
    generic_filter = or_(Content.name.like(searchstring),
                         Content.title.like(searchstring),
                         Content.description.like(searchstring))

    results = DBSession.query(Content).filter(generic_filter).all()

    # specific result contain objects matching additional criteria
    # but must not match the generic criteria (because these objects
    # are already in the generic_results)
    document_results = DBSession.query(Document).filter(
        and_(Document.body.like(searchstring),
             not_(generic_filter)))

    for results_set in [content_with_tags([searchstring]),
                        document_results.all()]:
        [results.append(c) for c in results_set if not c in results]

    result_dicts = []

    for result in results:
        if has_permission('view', result, request):
            result_dicts.append(dict(
                name=result.name,
                title=result.title,
                description=result.description,
                path=request.resource_path(result)))

    return result_dicts
Пример #3
0
def initialize_sql(engine, drop_all=False):
    DBSession.registry.clear()
    DBSession.configure(bind=engine)
    metadata.bind = engine

    if drop_all or os.environ.get('KOTTI_TEST_DB_STRING'):
        metadata.reflect()
        metadata.drop_all(engine)

    # Allow users of Kotti to cherry pick the tables that they want to use:
    settings = _resolve_dotted(get_settings())
    tables = settings['kotti.use_tables'].strip() or None
    if tables:
        tables = [metadata.tables[name] for name in tables.split()]

    _adjust_for_engine(engine)

    # Allow migrations to set the 'head' stamp in case the database is
    # initialized freshly:
    if not engine.table_names():
        stamp_heads()

    metadata.create_all(engine, tables=tables)
    if os.environ.get('KOTTI_DISABLE_POPULATORS', '0') not in TRUE_VALUES:
        for populate in settings['kotti.populators']:
            populate()
    commit()

    return DBSession
Пример #4
0
    def test_groups_from_users(self):
        from kotti import DBSession
        from kotti.resources import get_root
        from kotti.resources import Node
        from kotti.security import list_groups
        from kotti.security import set_groups

        self.make_bob()
        root = get_root()
        child = root[u'child'] = Node()
        DBSession.flush()

        self.assertEqual(list_groups('bob', root), ['group:bobsgroup'])

        set_groups('group:bobsgroup', root, ['role:editor'])
        set_groups('role:editor', child, ['group:foogroup'])

        self.assertEqual(
            set(list_groups('bob', root)),
            set(['group:bobsgroup', 'role:editor'])
            )
        self.assertEqual(
            set(list_groups('bob', child)),
            set(['group:bobsgroup', 'role:editor', 'group:foogroup'])
            )
Пример #5
0
def initialize_sql(engine, drop_all=False):
    DBSession.registry.clear()
    DBSession.configure(bind=engine)
    metadata.bind = engine

    if drop_all or os.environ.get('KOTTI_TEST_DB_STRING'):
        metadata.reflect()
        metadata.drop_all(engine)

    # Allow users of Kotti to cherry pick the tables that they want to use:
    settings = get_current_registry().settings
    tables = settings['kotti.use_tables'].strip() or None
    if tables:
        if 'settings' not in tables:
            tables += ' settings'
        tables = [metadata.tables[name] for name in tables.split()]

    if engine.dialect.name == 'mysql':  # pragma: no cover
        from sqlalchemy.dialects.mysql.base import LONGBLOB
        File.__table__.c.data.type = LONGBLOB()

    metadata.create_all(engine, tables=tables)
    for populate in get_settings()['kotti.populators']:
        populate()
    commit()

    return DBSession()
Пример #6
0
    def delete_nodes(self):
        """
        Delete nodes view. Renders either a view to delete multiple nodes or
        delete the selected nodes and get back to the referrer of the request.

        :result: Either a redirect response or a dictionary passed to the
                 template for rendering.
        :rtype: pyramid.httpexceptions.HTTPFound or dict
        """
        if 'delete_nodes' in self.request.POST:
            ids = self.request.POST.getall('children-to-delete')
            if not ids:
                self.flash(_(u"Nothing was deleted."), 'info')
            for id in ids:
                item = DBSession.query(Node).get(id)
                self.flash(_(u'${title} was deleted.',
                             mapping=dict(title=item.title)), 'success')
                del self.context[item.name]
            return self.back('@@contents')

        if 'cancel' in self.request.POST:
            self.flash(_(u'No changes were made.'), 'info')
            return self.back('@@contents')

        ids = self._selected_children(add_context=False)
        items = []
        if ids is not None:
            items = DBSession.query(Node).filter(Node.id.in_(ids)).\
                order_by(Node.position).all()
        return {'items': items,
                'states': _states(self.context, self.request)}
Пример #7
0
def view_meetups(request):

    if 'delete' in request.POST:
        todel = request.POST.getall('meetupcheck')

        for mid in todel:

            # print 'mid:%s, len mid:%d'% ( mid, len(mid) )
            meetup = DBSession.query(Act).filter_by(id=int(mid)).first()
            if meetup is not None :
                # print meetup
                if len(meetup.parts) != 0:
                    request.session.flash(u"活动'%s..'由于已经有人报名不能删除!" % meetup.title[:10], 'danger')

                else:
                    meetup.status = Act.STATUS_DELETED
                    request.session.flash(u"活动'%s..'已成功删除!" % meetup.title[:10], 'success')



            DBSession.flush()
        # DBSession.commit()




    return view_meetup_entry()
Пример #8
0
def view_review(context, request):  
    jquery.need()    
    contextbody = jinja2.Markup(context.body)

    user = get_user(request)  

    if request.POST :
    
        if user is None:
            request.session.flash(u"请先登陆..","info")
            came_from = request.url
            return HTTPFound("/login?came_from=%s" % came_from)        
        
        if 'submit' in request.POST:

            
            comment_content = request.params.get("review-comment-input")
            
            comment = Comment()
            comment.type = comment.TYPE_MEETUP_REVIEW
            comment.user_id = user.id
            comment.document_id = context.id 
            
            # ACTION!!!: There is a SQL injection risk here! should be prevented
            comment.content =  comment_content
            DBSession.add( comment)
            DBSession.flush()
            

        
    return  wrap_user2(request, 
                {'context':context, 
                'contextbody': contextbody,
                'comments_count': len(context.comments)                
                })       
Пример #9
0
def initialize_sql(engine, drop_all=False):
    DBSession.registry.clear()
    DBSession.configure(bind=engine)
    metadata.bind = engine

    if drop_all or os.environ.get('KOTTI_TEST_DB_STRING'):
        metadata.reflect()
        metadata.drop_all(engine)

    # Allow users of Kotti to cherry pick the tables that they want to use:
    settings = get_current_registry().settings
    tables = settings['kotti.use_tables'].strip() or None
    if tables:
        tables = [metadata.tables[name] for name in tables.split()]

    if engine.dialect.name == 'mysql':  # pragma: no cover
        from sqlalchemy.dialects.mysql.base import LONGBLOB
        File.__table__.c.data.type = LONGBLOB()

    # Allow migrations to set the 'head' stamp in case the database is
    # initialized freshly:
    if not engine.table_names():
        stamp_heads()

    metadata.create_all(engine, tables=tables)
    if os.environ.get('KOTTI_DISABLE_POPULATORS', '0') not in ('1', 'y'):
        for populate in get_settings()['kotti.populators']:
            populate()
    commit()

    return DBSession
Пример #10
0
def paste_node(context, request):
    session = DBSession()
    id, action = request.session['kotti.paste']
    item = session.query(Node).get(id)
    if item is not None:
        if action == 'cut':
            if not has_permission('edit', item, request):
                raise Forbidden()
            item.__parent__.children.remove(item)
            context.children.append(item)
            del request.session['kotti.paste']
        elif action == 'copy':
            copy = item.copy()
            name = copy.name
            if not name:  # for root
                name = copy.title
            name = title_to_name(name, blacklist=context.keys())
            copy.name = name
            context.children.append(copy)
        request.session.flash(_(u'${title} pasted.',
                                mapping=dict(title=item.title)), 'success')
    else:
        request.session.flash(_(u'Could not paste node. It does not exist anymore.'), 'error')
    if not request.is_xhr:
        location = resource_url(context, request)
        return HTTPFound(location=location)
Пример #11
0
    def add_some_groups():
        session = DBSession()
        root = get_root()
        child = root[u'child'] = Node()
        grandchild = child[u'grandchild'] = Node()
        session.flush()

        # root:
        #   bob               -> group:bobsgroup
        #   frank             -> group:franksgroup
        #   group:franksgroup -> role:editor
        # child:
        #   group:bobsgroup   -> group:franksgroup
        # grandchild:
        #   group:franksgroup -> role:admin
        #   group:franksgroup -> group:bobsgroup

        # bob and frank are a site-wide members of their respective groups:
        set_groups('bob', root, ['group:bobsgroup'])
        set_groups('frank', root, ['group:franksgroup'])

        # franksgroup has a site-wide editor role:
        set_groups('group:franksgroup', root, ['role:editor'])

        # bobsgroup is part of franksgroup on the child level:
        set_groups('group:bobsgroup', child, ['group:franksgroup'])

        # franksgroup has the admin role on the grandchild.
        # and finally, to test recursion, we make franksgroup part of
        # bobsgroup on the grandchild level:
        set_groups('group:franksgroup', grandchild,
                   ['role:owner', 'group:bobsgroup'])
Пример #12
0
 def test_unique_constraint(self):
     # Try to add two children with the same name to the root node:
     session = DBSession()
     root = get_root()
     session.add(Node(name=u'child1', parent=root))
     session.add(Node(name=u'child1', parent=root))
     self.assertRaises(IntegrityError, session.flush)
Пример #13
0
    def view(self):

        session = DBSession()

        query = session.query(SoftwareProject).filter(
                SoftwareProject.parent_id == self.context.id)

        items = query.all()

        # [TODO] Are these calls too expensive?
        [item.refresh_pypi() for item in items]
        [item.refresh_github() for item in items]
        [item.refresh_bitbucket() for item in items]

        if self.context.sort_order_is_ascending:
            items = sorted(items, key=lambda x: x.date)
        else:
            items = sorted(items, key=lambda x: x.date, reverse=True)

        page = self.request.params.get('page', 1)

        settings = collection_settings()

        if settings['use_batching']:
            items = Batch.fromPagenumber(items,
                          pagesize=settings['pagesize'],
                          pagenumber=int(page))

        return {
            'api': template_api(self.context, self.request),
            'macros': get_renderer('templates/macros.pt').implementation(),
            'items': items,
            'settings': settings,
            }
Пример #14
0
 def __getitem__(self, name):
     log.debug( sys._getframe().f_code.co_name )
     log.debug(type(name))
     log.debug(name)
     name = unicode(name)
     try:
         principal = DBSession.query(
             self.stub_factory).filter(
                 self.stub_factory.name == name).one()
         log.debug('principal found :: id={} name={} email={}'.format(
             principal.id, principal.name, principal.email))
         return principal
     except NoResultFound:
         try:
             account = DBSession.query(
                 self.factory).filter(
                     self.factory.email == self.__name2email(name)).one()
             log.debug('account found  id={} email={}'.format(
                 account.id, account.email))
             principal = DBSession.query(
                 self.stub_factory).filter(
                     self.stub_factory.id == account.id).one()
             log.debug('principal found :: id={} name={} email={}'.format(
                 principal.id, principal.name, principal.email))
             return principal
         except NoResultFound:
             log.error('KeyError')
             raise KeyError(name)
Пример #15
0
def resume_view(context, request):
    jquery.need()
    
    user = get_user(request)
    if not user:
        raise UserNotFount()

    if "add_resume" in request.POST:
        title = request.POST['resume_title']
        if title.strip() != '':
            resume = resources.Resume(title=title, user=user)
            #DBSession.add(resume)
            #DBSession.flush()
            #return HTTPFound(location='/resume_edit2/%d' % resume.id)
    elif "operator" in request.POST:
        ops = request.POST['operator']
        print ops
        if ops == 'del_resume':
            id = request.POST['operator_id']
            resume = DBSession.query(resources.Resume).get(id)
            if resume and resume.user_id == user.id:
                DBSession.delete(resume)

    return wrap_user(request,{
            'resumes':user.resumes,
            'pcs':user.position_items,
            })
Пример #16
0
    def test_inherit(self):
        from kotti import DBSession
        from kotti.resources import get_root
        from kotti.resources import Node
        from kotti.security import list_groups
        from kotti.security import list_groups_raw
        from kotti.security import set_groups

        root = get_root()
        child = root[u'child'] = Node()
        DBSession.flush()

        self.assertEqual(list_groups('bob', child), [])
        set_groups('bob', root, ['role:editor'])
        self.assertEqual(list_groups('bob', child), ['role:editor'])

        # Groups from the child are added:
        set_groups('bob', child, ['group:somegroup'])
        self.assertEqual(
            set(list_groups('bob', child)),
            set(['group:somegroup', 'role:editor'])
            )

        # We can ask to list only those groups that are defined locally:
        self.assertEqual(
            list_groups_raw(u'bob', child), set(['group:somegroup']))
Пример #17
0
    def create(
        self,
        content: Union[bytes, FieldStorage],
        filename: Optional[str] = None,
        content_type: Optional[str] = None,
    ) -> str:
        """Saves a new file and returns the file id

        :param content: can either be ``bytes``, another ``file object``
                        or a :class:`cgi.FieldStorage`. When ``filename`` and
                        ``content_type``  parameters are not provided they are
                        deducted from the content itself.

        :param filename: filename for this file
        :type filename: string

        :param content_type: Mimetype of this file
        :type content_type: string

        :return: the unique ``file_id`` associated to this file
        :rtype: string
        """
        new_file_id = str(uuid.uuid1())
        content, filename, content_type = self.fileinfo(content, filename, content_type)
        if hasattr(content, "read"):
            content = content.read()

        fstore = DBStoredFile(
            data=content,
            file_id=new_file_id,
            filename=filename,
            content_type=content_type,
        )
        DBSession.add(fstore)
        return new_file_id
Пример #18
0
 def _get_product(self, sku, subsku):
     """return tuple product & variation"""
     product = DBSession.query(
         VendoProduct).filter_by(sku=sku).one()
     variation = DBSession.query(
         VendoProductVariation).filter_by(sub_sku=subsku).one()
     return product, variation
Пример #19
0
def upgrade():
    sa.orm.events.MapperEvents._clear()  # avoids filedepot magic

    from depot.manager import DepotManager
    from depot.fields.upload import UploadedFile
    from depot.fields.sqlalchemy import UploadedFileField

    from kotti import DBSession, metadata
    from kotti.resources import File

    t = sa.Table("files", metadata)
    t.c.data.type = sa.LargeBinary()
    dn = DepotManager.get_default()

    for obj in DBSession.query(File):
        uploaded_file = UploadedFile({"depot_name": dn, "files": []})
        uploaded_file._thaw()
        uploaded_file.process_content(obj.data, filename=obj.filename, content_type=obj.mimetype)
        stored_file = DepotManager.get().get(uploaded_file["file_id"])
        obj.data = uploaded_file.encode()
        stored_file.last_modified = obj.modification_date

        log.info(
            "Migrated {} bytes for File with pk {} to {}/{}".format(len(obj.data), obj.id, dn, uploaded_file["file_id"])
        )

    DBSession.flush()
    if DBSession.get_bind().name != "sqlite":  # not supported by sqlite
        op.alter_column("files", "data", type_=UploadedFileField())
Пример #20
0
 def __setitem__(self,
                 name: str,
                 principal: Union[Principal, dict]) -> None:
     name = name
     if isinstance(principal, dict):
         principal = self.factory(**principal)
     DBSession.add(principal)
Пример #21
0
 def fruit_categories_bunch(cls, order_by, how_many=10):
     # fruit_categories contain fruits
     ret = []
     fruits = DBSession.query(Fruit).all()
     for r in DBSession.query(FruitCategory).all():
         ret.append(cls.make_record(r, fruits))
     return ret
Пример #22
0
 def __delitem__(self, name):
     name = unicode(name)
     try:
         principal = self._principal_by_name(name)
         DBSession.delete(principal)
     except NoResultFound:
         raise KeyError(name)
Пример #23
0
    def paste_nodes(self):
        """ Paste nodes view.  Paste formerly copied or cutted nodes into the
        current context.  Note that a cutted node can not be pasted into itself.

        :result: Redirect response to the referrer of the request.
        :rtype: pyramid.httpexceptions.HTTPFound
        """
        ids, action = self.request.session["kotti.paste"]
        for count, id in enumerate(ids):
            item = DBSession.query(Node).get(id)
            if item is not None:
                if action == "cut":
                    if not self.request.has_permission("edit", item):
                        raise Forbidden()
                    item.__parent__.children.remove(item)
                    item.name = title_to_name(item.name, blacklist=self.context.keys())
                    self.context[item.name] = item
                    if count is len(ids) - 1:
                        del self.request.session["kotti.paste"]
                elif action == "copy":
                    copy = item.copy()
                    name = copy.name
                    if not name:  # for root
                        name = copy.title
                    name = title_to_name(name, blacklist=self.context.keys())
                    copy.name = name
                    self.context[name] = copy
                self.flash(
                    _("${title} was pasted.", mapping=dict(title=item.title)), "success"
                )
            else:
                self.flash(_("Could not paste node. It no longer exists."), "error")
        DBSession.flush()
        if not self.request.is_xhr:
            return self.back()
Пример #24
0
 def fruit_category(self, cls, id_wanted):
     r = DBSession.query(FruitCategory).filter_by(id=id_wanted).first()
     if r is not None:
         fruits = DBSession.query(Fruit).all()
         return self.make_record(r, fruits)
     else:
         return None
Пример #25
0
    def delete_nodes(self):
        """
        Delete nodes view. Renders either a view to delete multiple nodes or
        delete the selected nodes and get back to the referrer of the request.

        :result: Either a redirect response or a dictionary passed to the
                 template for rendering.
        :rtype: pyramid.httpexceptions.HTTPFound or dict
        """
        if "delete_nodes" in self.request.POST:
            ids = self.request.POST.getall("children-to-delete")
            if not ids:
                self.request.session.flash(_(u"Nothing deleted."), "info")
            for id in ids:
                item = DBSession.query(Node).get(id)
                self.request.session.flash(_(u"${title} deleted.", mapping=dict(title=item.title)), "success")
                del self.context[item.name]
            return self.back("@@contents")

        if "cancel" in self.request.POST:
            self.request.session.flash(_(u"No changes made."), "info")
            return self.back("@@contents")

        ids = self._selected_children(add_context=False)
        items = []
        if ids is not None:
            items = DBSession.query(Node).filter(Node.id.in_(ids)).order_by(Node.position).all()
        return {"items": items, "states": _states(self.context, self.request)}
Пример #26
0
    def rename_nodes(self):
        """
        Rename nodes view. Renders either a view to change the titles and
        names for multiple nodes or handle the changes and get back to the
        referrer of the request.

        :result: Either a redirect response or a dictionary passed to the
                 template for rendering.
        :rtype: pyramid.httpexceptions.HTTPFound or dict
        """
        if "rename_nodes" in self.request.POST:
            ids = self.request.POST.getall("children-to-rename")
            for id in ids:
                item = DBSession.query(Node).get(id)
                name = self.request.POST[id + "-name"]
                title = self.request.POST[id + "-title"]
                if not name or not title:
                    self.request.session.flash(_(u"Name and title are required."), "error")
                    location = resource_url(self.context, self.request) + "@@rename_nodes"
                    return HTTPFound(location=location)
                else:
                    item.name = title_to_name(name, blacklist=self.context.keys())
                    item.title = title
            self.request.session.flash(_(u"Your changes have been saved."), "success")
            return self.back("@@contents")

        if "cancel" in self.request.POST:
            self.request.session.flash(_(u"No changes made."), "info")
            return self.back("@@contents")

        ids = self._selected_children(add_context=False)
        items = []
        if ids is not None:
            items = DBSession.query(Node).filter(Node.id.in_(ids)).all()
        return {"items": items}
Пример #27
0
 def __delitem__(self, name: str) -> None:
     name = name
     try:
         principal = self._principal_by_name(name)
         DBSession.delete(principal)
     except NoResultFound:
         raise KeyError(name)
Пример #28
0
def order_node(context, request):
    P = request.POST

    if 'order-up' in P or 'order-down' in P:
        up, down = P.get('order-up'), P.get('order-down')
        child = DBSession.query(Node).get(int(down or up))
        if up is not None:
            mod = -1
        else:  # pragma: no cover
            mod = 1
        index = context.children.index(child)
        context.children.pop(index)
        context.children.insert(index + mod, child)
        request.session.flash(_(u'${title} moved.',
                                mapping=dict(title=child.title)), 'success')
        if not request.is_xhr:
            return HTTPFound(location=request.url)

    elif 'toggle-visibility' in P:
        child = DBSession.query(Node).get(int(P['toggle-visibility']))
        child.in_navigation ^= True
        mapping = dict(title=child.title)
        if child.in_navigation:
            msg = _(u'${title} is now visible in the navigation.',
                    mapping=mapping)
        else:
            msg = _(u'${title} is no longer visible in the navigation.',
                    mapping=mapping)
        request.session.flash(msg, 'success')
        if not request.is_xhr:
            return HTTPFound(location=request.url)

    return {}
Пример #29
0
    def save_success(self, appstruct):
        appstruct.pop('csrf_token', None)
        DBSession.add( self.add(**appstruct) )

        self.request.session.flash(self.success_message, 'success')
        location = self.success_url
        return HTTPFound(location=location)
Пример #30
0
    def test_principals_with_local_roles(self):
        from kotti import DBSession
        from kotti.resources import get_root
        from kotti.resources import Node
        from kotti.security import map_principals_with_local_roles
        from kotti.security import principals_with_local_roles
        from kotti.security import set_groups

        root = get_root()
        child = root[u'child'] = Node()
        DBSession.flush()

        self.assertEqual(principals_with_local_roles(root), [])
        self.assertEqual(principals_with_local_roles(child), [])
        self.assertEqual(map_principals_with_local_roles(root), [])
        self.assertEqual(map_principals_with_local_roles(child), [])

        set_groups('group:bobsgroup', child, ['role:editor'])
        set_groups('bob', root, ['group:bobsgroup'])
        set_groups('group:franksgroup', root, ['role:editor'])

        self.assertEqual(
            set(principals_with_local_roles(child)),
            set(['bob', 'group:bobsgroup', 'group:franksgroup'])
            )
        self.assertEqual(
            set(principals_with_local_roles(child, inherit=False)),
            set(['group:bobsgroup'])
            )
        self.assertEqual(
            set(principals_with_local_roles(root)),
            set(['bob', 'group:franksgroup'])
            )
Пример #31
0
 def iterkeys(self):
     for (principal_name, ) in DBSession.query(self.factory.name):
         yield principal_name
Пример #32
0
def _before_update(mapper, connection, target):
    session = DBSession.object_session(target)
    if session.is_modified(target, include_collections=False):
        notify(ObjectUpdate(target, get_current_request()))
Пример #33
0
    def test_container_methods(self, db_session):
        from kotti import DBSession
        from kotti.resources import get_root
        from kotti.resources import Node

        # Test some of Node's container methods:
        root = get_root()
        assert root.keys() == []

        child1 = Node(name=u'child1', parent=root)
        DBSession.add(child1)
        assert root.keys() == [u'child1']
        assert root[u'child1'] == child1

        del root[u'child1']
        assert root.keys() == []

        # When we delete a parent node, all its child nodes will be
        # released as well:
        root[u'child2'] = Node()
        root[u'child2'][u'subchild'] = Node()
        assert (DBSession.query(Node).filter(
            Node.name == u'subchild').count() == 1)
        del root[u'child2']
        assert (DBSession.query(Node).filter(
            Node.name == u'subchild').count() == 0)

        # We can pass a tuple as the key to more efficiently reach
        # down to child objects:
        root[u'child3'] = Node()
        subchild33 = Node(name=u'subchild33', parent=root[u'child3'])
        DBSession.add(subchild33)
        del root.__dict__['_children']  # force a different code path
        assert root[u'child3', u'subchild33'] is root[u'child3'][u'subchild33']
        assert root[(u'child3', u'subchild33')] is subchild33
        assert root[(u'child3', u'subchild33')] is subchild33
        with raises(KeyError):
            root[u'child3', u'bad-name']
        root.children  # force a different code path
        with raises(KeyError):
            root[u'child3', u'bad-name']
        del root[u'child3']

        # Overwriting an existing Node is an error; first delete manually!
        child4 = Node(name=u'child4', parent=root)
        DBSession.add(child4)
        assert root.keys() == [u'child4']

        child44 = Node(name=u'child4')
        DBSession.add(child44)
        root[u'child4'] = child44
        with raises(SQLAlchemyError):
            DBSession.flush()
Пример #34
0
def upgrade():
    from depot.manager import DepotManager
    from depot.fields.upload import UploadedFile
    from sqlalchemy import bindparam, Unicode, Column

    from kotti import DBSession, metadata

    files = sa.Table('files', metadata)
    files.c.data.type = sa.LargeBinary()    # this restores to old column type
    dn = DepotManager.get_default()

    _saved = []

    def process(thing):
        id, data, filename, mimetype = thing
        uploaded_file = UploadedFile({'depot_name': dn, 'files': []})
        # noinspection PyProtectedMember
        uploaded_file._thaw()
        uploaded_file.process_content(
            data, filename=filename, content_type=mimetype)
        _saved.append({'nodeid': id, 'data': uploaded_file.encode()})
        log.info(f"Saved data for node id {id}")

    query = DBSession.query(
        files.c.id, files.c.data, files.c.filename, files.c.mimetype
    ).order_by(files.c.id).yield_per(10)

    window_size = 10
    window_idx = 0

    log.info("Starting migration of blob data")

    now = time.time()
    while True:
        start, stop = window_size * window_idx, window_size * (window_idx + 1)
        things = query.slice(start, stop).all()
        if things is None:
            break
        for thing in things:
            process(thing)
        if len(things) < window_size:
            break
        window_idx += 1

    log.info("Files written on disk, saving information to DB")

    op.drop_column('files', 'data')
    op.add_column('files', Column('data', Unicode(4096)))
    files.c.data.type = Unicode(4096)

    update = files.update().where(files.c.id == bindparam('nodeid')).\
        values({files.c.data: bindparam('data')})

    def chunks(l, n):
        for i in range(0, len(l), n):
            yield l[i:i + n]

    for cdata in chunks(_saved, 10):
        DBSession.execute(update, cdata)

    log.info("Blob migration completed in {} seconds".format(
        int(time.time() - now)))
Пример #35
0
def reset_content_owner(event):
    """Reset the owner of the content from the deleted owner."""
    contents = DBSession.query(Content).filter(
        Content.owner == event.object.name).all()
    for content in contents:
        content.owner = None
Пример #36
0
def delete_orphaned_tags(event):
    DBSession.query(Tag).filter(~Tag.content_tags.any()).delete(
        synchronize_session=False)
Пример #37
0
 def expire(event):
     DBSession.flush()
     DBSession.expire_all()
Пример #38
0
def sitemap(request):
    nodes = DBSession.query(Content).with_polymorphic(Content)
    request.response.content_type = "text/xml"
    return {'nodes': nodes}
Пример #39
0
    def activities(self):
        row_size_per_page = 15
        cur_page = 1
        total_rows = DBSession.query(func.count(Activity.id)).scalar()
        total_page_num = int(
            math.ceil(float(total_rows) / float(row_size_per_page)))
        location = '/activities'
        param = 'page'

        if self.request.params.keys():
            cur_page = int(self.request.params.values()[0])

        def get_date(d):
            return d.strftime('%Y-%m-%d %H:%M') if d else ''

        def pagination_data():
            end = total_page_num + 1
            data = []

            for x in range(1, end):
                data.append({
                    'val': x,
                    'url': '%s?%s=%d' % (location, param, x)
                })

            return data

        return {
            'headers': [{
                'key': 'owner',
                'label': _(u'Owner'),
                'structure': False
            }, {
                'key': 'start_dt',
                'label': _(u'Start Date'),
                'structure': False
            }, {
                'key': 'end_dt',
                'label': _(u'End Date'),
                'structure': False
            }, {
                'key': 'summary',
                'label': _(u'Summary'),
                'structure': True
            }, {
                'key': 'issues',
                'label': _(u'Issues'),
                'structure': True
            }, {
                'key': 'engagement',
                'label': _(u'Engagement'),
                'structure': False
            }],
            'data': [{
                'url': self.request.resource_url(i),
                'start_dt': get_date(i.start_dt),
                'end_dt': get_date(i.end_dt),
                'owner': i.owner,
                'summary': i.summary,
                'issues': i.issues,
                'engagement': i.engagement.title
            } for i in DBSession.query(Activity).order_by(
                desc(Activity.start_dt)).slice(
                    row_size_per_page *
                    (cur_page - 1), row_size_per_page * (cur_page)).all()],
            'pagination':
            pagination_data(),
            'navigation': {
                'cur_page': cur_page,
                'total_page': total_page_num,
                'prev': '%s?%s=%d' % (location, param, cur_page - 1),
                'next': '%s?%s=%d' % (location, param, cur_page + 1)
            }
        }
Пример #40
0
 def __setitem__(self, name, principal):
     name = unicode(name)
     if isinstance(principal, dict):
         principal = self.factory(**principal)
     DBSession.add(principal)
Пример #41
0
 def _principal_by_name(cls, name):
     query = bakery(lambda session: session.query(cls.factory).filter(
         cls.factory.name == bindparam('name')))
     return query(DBSession()).params(name=name).one()
Пример #42
0
    def test_works_with_auth(self):
        from kotti import DBSession
        from kotti.resources import get_root
        from kotti.resources import Node
        from kotti.security import get_principals
        from kotti.security import list_groups_callback
        from kotti.security import set_groups

        root = get_root()
        child = root[u'child'] = Node()
        DBSession.flush()

        request = DummyRequest()
        auth = CallbackAuthenticationPolicy()
        auth.unauthenticated_userid = lambda *args: 'bob'
        auth.callback = list_groups_callback

        request.context = root
        self.assertEqual(  # user doesn't exist yet
            auth.effective_principals(request), ['system.Everyone'])

        get_principals()[u'bob'] = dict(name=u'bob')
        self.assertEqual(auth.effective_principals(request),
                         ['system.Everyone', 'system.Authenticated', 'bob'])

        # Define that bob belongs to bobsgroup on the root level:
        set_groups('bob', root, ['group:bobsgroup'])
        request.context = child
        self.assertEqual(
            set(auth.effective_principals(request)),
            set([
                'system.Everyone', 'system.Authenticated', 'bob',
                'group:bobsgroup'
            ]))

        # define that bob belongs to franksgroup in the user db:
        get_principals()[u'bob'].groups = [u'group:franksgroup']
        set_groups('group:franksgroup', child, ['group:anothergroup'])
        self.assertEqual(
            set(auth.effective_principals(request)),
            set([
                'system.Everyone',
                'system.Authenticated',
                'bob',
                'group:bobsgroup',
                'group:franksgroup',
                'group:anothergroup',
            ]))

        # And lastly test that circular group defintions are not a
        # problem here either:
        get_principals()[u'group:franksgroup'] = dict(
            name=u'group:franksgroup',
            title=u"Frank's group",
            groups=[u'group:funnygroup', u'group:bobsgroup'],
        )
        self.assertEqual(
            set(auth.effective_principals(request)),
            set([
                'system.Everyone',
                'system.Authenticated',
                'bob',
                'group:bobsgroup',
                'group:franksgroup',
                'group:anothergroup',
                'group:funnygroup',
            ]))
Пример #43
0
    def test_container_methods(self):
        from kotti import DBSession
        from kotti.resources import get_root
        from kotti.resources import Node

        session = DBSession()

        # Test some of Node's container methods:
        root = get_root()
        self.assertEquals(root.keys(), [])

        child1 = Node(name=u'child1', parent=root)
        session.add(child1)
        self.assertEquals(root.keys(), [u'child1'])
        self.assertEquals(root[u'child1'], child1)

        del root[u'child1']
        self.assertEquals(root.keys(), [])

        # When we delete a parent node, all its child nodes will be
        # released as well:
        root[u'child2'] = Node()
        root[u'child2'][u'subchild'] = Node()
        self.assertEquals(
            session.query(Node).filter(Node.name == u'subchild').count(), 1)
        del root[u'child2']
        self.assertEquals(
            session.query(Node).filter(Node.name == u'subchild').count(), 0)

        # We can pass a tuple as the key to more efficiently reach
        # down to child objects:
        root[u'child3'] = Node()
        subchild33 = Node(name=u'subchild33', parent=root[u'child3'])
        session.add(subchild33)
        del root.__dict__['_children']
        self.assertTrue(
            root[u'child3', u'subchild33'] is root[u'child3'][u'subchild33'])
        self.assertTrue(root[(u'child3', u'subchild33')] is subchild33)
        self.assertRaises(KeyError, root.__getitem__, (u'child3', u'bad-name'))
        del root[u'child3']

        # Overwriting an existing Node is an error; first delete manually!
        child4 = Node(name=u'child4', parent=root)
        session.add(child4)
        self.assertEquals(root.keys(), [u'child4'])

        child44 = Node(name=u'child4')
        session.add(child44)
        root[u'child4'] = child44
        self.assertRaises(SQLAlchemyError, session.flush)
Пример #44
0
def content_with_tags(tag_terms):

    return DBSession.query(Content).join(TagsToContents).join(Tag).filter(
        or_(*[Tag.title.like(tag_term) for tag_term in tag_terms])).all()
Пример #45
0
 def __delitem__(self, key: str) -> None:
     node = self[key]
     self.children.remove(node)
     DBSession.delete(node)
Пример #46
0
 def __setitem__(self, name: str, principal: Union[Principal,
                                                   dict]) -> None:
     name = name
     if isinstance(principal, dict):
         principal = self.factory(**principal)
     DBSession.add(principal)
Пример #47
0
 def __delitem__(self, key):
     node = self[unicode(key)]
     self.children.remove(node)
     DBSession.delete(node)
Пример #48
0
    def clear(self) -> None:

        DBSession.query(Node).filter(Node.parent == self).delete()