Пример #1
0
    def test_node_lineage_not_loaded_new_parent(self, db_session, root, events):

        from kotti.resources import Node
        from kotti.resources import get_root
        from kotti.events import ObjectEvent
        from kotti.events import objectevent_listeners

        # We want to guarantee that an object event handler can call
        # get_root(), which is only possible if our event handler
        # avoids flushing:
        objectevent_listeners[(ObjectEvent, Node)].append(
            lambda event: get_root())

        parent = root['parent'] = Node()
        child1 = parent['child-1'] = Node()

        db_session.flush()
        child1_id = child1.id
        db_session.expunge_all()

        child2 = Node(name=u'child-2')
        child3 = Node(name=u'child-3')

        child1 = db_session.query(Node).get(child1_id)
        child3.parent = child2
        child2.parent = child1

        assert child3.path == u"/parent/child-1/child-2/child-3/"
Пример #2
0
    def test_clear(self, db_session):
        from kotti import DBSession
        from kotti.resources import get_root
        from kotti.resources import Node

        child = get_root()['child'] = Node()
        assert DBSession.query(Node).filter(Node.name == u'child').all() == [
            child
        ]
        get_root().clear()
        assert DBSession.query(Node).filter(Node.name == u'child').all() == []
Пример #3
0
    def test_parent_copied(self, db_session, root, events, flush):
        from kotti.resources import Node

        c1 = root["c1"] = Node()
        c2 = c1["c2"] = Node()
        c2["c3"] = Node()

        if flush:
            db_session.flush()

        c1copy = root["c1copy"] = c1.copy()

        assert c1copy.path == "/c1copy/"
        assert c1copy["c2"].path == "/c1copy/c2/"
        assert c1copy["c2"]["c3"].path == "/c1copy/c2/c3/"

        c2copy = c2["c2copy"] = c2.copy()

        assert c2copy.path == "/c1/c2/c2copy/"
        assert c2copy["c3"].path == "/c1/c2/c2copy/c3/"
Пример #4
0
    def test_query_api(self, db_session, root, events):
        from kotti.resources import Node
        child1 = root['child-1'] = Node()
        child2 = child1['child-2'] = Node()
        subchild = child2['subchild'] = Node()

        assert db_session.query(Node).filter(
            Node.path.startswith(u'/')).count() == 4

        assert db_session.query(Node).filter(
            Node.path.startswith(u'/child-1/')).count() == 3

        objs = db_session.query(Node).filter(
            Node.path.startswith(u'/child-1/child-2/')).all()

        assert len(objs) == 2
        assert subchild in objs
        assert child2 in objs

        db_session.query(Node).filter(
            Node.path.startswith(u'/child-1/child-3/')).count() == 0
Пример #5
0
    def test_node_copy_variants(self, db_session, root):
        from kotti.resources import Node

        child1 = root['child1'] = Node()
        child1['grandchild'] = Node()
        child2 = root['child2'] = Node()

        # first way; circumventing the Container API
        child2.children.append(child1.copy())

        # second way; canonical way
        child2['child2'] = child1.copy()

        # third way; this is necessary in cases when copy() will
        # attempt to put the new node into the db already, e.g. when
        # the copy is already being back-referenced by some other
        # object in the db.
        child1.copy(parent=child2, name=u'child3')

        assert [child.name for child in child2.children
                ] == ['child1', 'child2', 'child3']
Пример #6
0
    def test_node_copy_with_local_groups(self, db_session, root):
        from kotti.resources import Node
        from kotti.resources import LocalGroup

        child1 = root['child1'] = Node()
        local_group1 = LocalGroup(child1, u'joe', u'role:admin')
        db_session.add(local_group1)
        db_session.flush()

        child2 = root['child2'] = child1.copy()
        db_session.flush()
        assert child2.local_groups == []
Пример #7
0
    def test_container_methods(self, db_session, root):
        from kotti.resources import Node

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

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

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

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

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

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

        child44 = Node(name='child4')
        db_session.add(child44)

        with raises(SQLAlchemyError):
            root['child4'] = child44
            db_session.flush()
Пример #8
0
    def test_query_api(self, db_session, root, events):
        from kotti.resources import Node

        child1 = root["child-1"] = Node()
        child2 = child1["child-2"] = Node()
        subchild = child2["subchild"] = Node()

        assert db_session.query(Node).filter(
            Node.path.startswith("/")).count() == 4

        assert (db_session.query(Node).filter(
            Node.path.startswith("/child-1/")).count() == 3)

        objs = (db_session.query(Node).filter(
            Node.path.startswith("/child-1/child-2/")).all())

        assert len(objs) == 2
        assert subchild in objs
        assert child2 in objs

        db_session.query(Node).filter(
            Node.path.startswith("/child-1/child-3/")).count() == 0
Пример #9
0
    def test_container_methods(self):
        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()
        self.assertEquals(root.keys(), [])

        child1 = Node(name=u'child1', parent=root)
        DBSession.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(
            DBSession.query(Node).filter(Node.name == u'subchild').count(), 1)
        del root[u'child2']
        self.assertEquals(
            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
        self.assertTrue(
            root[u'child3', u'subchild33'] is root[u'child3'][u'subchild33'])
        self.assertTrue(
            root[(u'child3', u'subchild33')] is subchild33)
        self.assertTrue(
            root[(u'child3', u'subchild33')] is subchild33)
        self.assertRaises(KeyError, root.__getitem__, (u'child3', u'bad-name'))
        root.children  # force a different code path
        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)
        DBSession.add(child4)
        self.assertEquals(root.keys(), [u'child4'])

        child44 = Node(name=u'child4')
        DBSession.add(child44)
        root[u'child4'] = child44
        self.assertRaises(SQLAlchemyError, DBSession.flush)
Пример #10
0
    def test_works_with_auth(self, db_session, 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

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

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

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

        get_principals()[u'bob'] = dict(name=u'bob')
        assert (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
        assert (set(auth.effective_principals(request)) == {
            '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'])
        assert (set(auth.effective_principals(request)) == {
            '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'],
        )
        assert (set(auth.effective_principals(request)) == {
            'system.Everyone', 'system.Authenticated', 'bob',
            'group:bobsgroup', 'group:franksgroup', 'group:anothergroup',
            'group:funnygroup'
        })
Пример #11
0
    def add_some_groups():
        from kotti import DBSession
        from kotti.resources import get_root
        from kotti.resources import Node
        from kotti.security import set_groups

        root = get_root()
        child = root[u'child'] = Node()
        grandchild = child[u'grandchild'] = Node()
        DBSession.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_node_copy_with_local_groups(self):
        from kotti import DBSession
        from kotti.resources import get_root
        from kotti.resources import Node
        from kotti.resources import LocalGroup

        root = get_root()
        child1 = root['child1'] = Node()
        local_group1 = LocalGroup(child1, u'joe', u'role:admin')
        DBSession.add(local_group1)
        DBSession.flush()

        child2 = root['child2'] = child1.copy()
        DBSession.flush()
        assert child2.local_groups == []
Пример #13
0
    def test_append_to_empty_acl(self, db_session, root):
        from kotti.resources import Node

        node = root["child"] = Node()
        node.__acl__ = []

        db_session.flush()
        db_session.expire_all()

        node.__acl__.append(("Allow", "system.Authenticated", ["edit"]))
        db_session.flush()
        db_session.expire_all()

        assert node.__acl__ == [
            ("Allow", "role:admin", ALL_PERMISSIONS),
            ("Allow", "system.Authenticated", ["edit"]),
        ]
Пример #14
0
    def test_local_roles_db_cascade(self, db_session, root):
        from kotti.resources import LocalGroup
        from kotti.resources import Node
        from kotti.security import set_groups

        child = root["child"] = Node()
        db_session.flush()

        # We set a local group on child and delete child.  We then
        # expect the LocalGroup entry to have been deleted from the
        # database:
        assert db_session.query(LocalGroup).count() == 0
        set_groups("group:bobsgroup", child, ["role:editor"])
        assert db_session.query(LocalGroup).count() == 1
        del root["child"]
        db_session.flush()
        assert db_session.query(LocalGroup).count() == 0
Пример #15
0
    def test_append_to_empty_acl(self, db_session, root):
        from kotti.resources import Node

        node = root['child'] = Node()
        node.__acl__ = []

        db_session.flush()
        db_session.expire_all()

        node.__acl__.append(('Allow', 'system.Authenticated', ['edit']))
        db_session.flush()
        db_session.expire_all()

        assert node.__acl__ == [
            ('Allow', 'role:admin', ALL_PERMISSIONS),
            ('Allow', 'system.Authenticated', ['edit']),
        ]
Пример #16
0
    def test_groups_from_users(self, db_session, root):
        from kotti.resources import Node
        from kotti.security import list_groups
        from kotti.security import set_groups

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

        assert list_groups('bob', root) == ['group:bobsgroup']

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

        assert (set(list_groups('bob', root)) == set(
            ['group:bobsgroup', 'role:editor']))
        assert (set(list_groups('bob', child)) == set(
            ['group:bobsgroup', 'role:editor', 'group:foogroup']))
Пример #17
0
    def test_inherit(self, db_session, 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

        child = root["child"] = Node()
        db_session.flush()

        assert list_groups("bob", child) == []
        set_groups("bob", root, ["role:editor"])
        assert list_groups("bob", child) == ["role:editor"]

        # Groups from the child are added:
        set_groups("bob", child, ["group:somegroup"])
        assert set(list_groups("bob", child)) == {"group:somegroup", "role:editor"}

        # We can ask to list only those groups that are defined locally:
        assert list_groups_raw("bob", child) == {"group:somegroup"}
Пример #18
0
    def test_groups_from_users(self, db_session, root):
        from kotti.resources import Node
        from kotti.security import list_groups
        from kotti.security import set_groups

        self.make_bob()
        child = root["child"] = Node()
        db_session.flush()

        assert list_groups("bob", root) == ["group:bobsgroup"]

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

        assert set(list_groups("bob", root)) == {"group:bobsgroup", "role:editor"}
        assert set(list_groups("bob", child)) == {
            "group:bobsgroup",
            "role:editor",
            "group:foogroup",
        }
Пример #19
0
    def test_local_roles_db_cascade(self):
        from kotti import DBSession
        from kotti.resources import get_root
        from kotti.resources import LocalGroup
        from kotti.resources import Node
        from kotti.security import set_groups

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

        # We set a local group on child and delete child.  We then
        # expect the LocalGroup entry to have been deleted from the
        # database:
        self.assertEqual(DBSession.query(LocalGroup).count(), 0)
        set_groups('group:bobsgroup', child, ['role:editor'])
        self.assertEqual(DBSession.query(LocalGroup).count(), 1)
        del root[u'child']
        DBSession.flush()
        self.assertEqual(DBSession.query(LocalGroup).count(), 0)
Пример #20
0
    def test_inherit(self, db_session, 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

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

        assert list_groups('bob', child) == []
        set_groups('bob', root, ['role:editor'])
        assert list_groups('bob', child) == ['role:editor']

        # Groups from the child are added:
        set_groups('bob', child, ['group:somegroup'])
        assert (set(list_groups('bob',
                                child)) == {'group:somegroup', 'role:editor'})

        # We can ask to list only those groups that are defined locally:
        assert list_groups_raw(u'bob', child) == {'group:somegroup'}
Пример #21
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']))
Пример #22
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']))
Пример #23
0
    def test_principals_with_local_roles(self, db_session, 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

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

        assert principals_with_local_roles(root) == []
        assert principals_with_local_roles(child) == []
        assert map_principals_with_local_roles(root) == []
        assert 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'])

        assert (set(principals_with_local_roles(child)) == set(
            ['bob', 'group:bobsgroup', 'group:franksgroup']))
        assert (set(principals_with_local_roles(child, inherit=False)) == set(
            ['group:bobsgroup']))
        assert (set(principals_with_local_roles(root)) == set(
            ['bob', 'group:franksgroup']))
Пример #24
0
    def test_works_with_auth(self, db_session, 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

        child = root["child"] = Node()
        db_session.flush()

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

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

        get_principals()["bob"] = dict(name="bob")
        assert 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
        assert set(auth.effective_principals(request)) == {
            "system.Everyone",
            "system.Authenticated",
            "bob",
            "group:bobsgroup",
        }

        # define that bob belongs to franksgroup in the user db:
        get_principals()["bob"].groups = ["group:franksgroup"]
        set_groups("group:franksgroup", child, ["group:anothergroup"])
        assert set(auth.effective_principals(request)) == {
            "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()["group:franksgroup"] = dict(
            name="group:franksgroup",
            title="Frank's group",
            groups=["group:funnygroup", "group:bobsgroup"],
        )
        assert set(auth.effective_principals(request)) == {
            "system.Everyone",
            "system.Authenticated",
            "bob",
            "group:bobsgroup",
            "group:franksgroup",
            "group:anothergroup",
            "group:funnygroup",
        }
Пример #25
0
 def test_replace_root(self, db_session, root, events):
     from kotti.resources import Node
     db_session.delete(root)
     new_root = Node(u'')
     db_session.add(new_root)
     assert new_root.path == '/'
Пример #26
0
 def test_object_moved(self, db_session, root, events):
     from kotti.resources import Node
     child = root['child-1'] = Node()
     subchild = child['subchild'] = Node()
     subchild.parent = root
     assert subchild.path == '/subchild/'