[Zope3-checkins] CVS: Zope3/src/zope/app/security/tests - __init__.py:1.1.2.1 test_basicauthadapter.py:1.1.2.1 test_loginpassword.py:1.1.2.1 test_module.py:1.1.2.1 test_modulehookup.py:1.1.2.1 test_permissionfield.py:1.1.2.1 test_protectclass.py:1.1.2.1 test_protectsubclass.py:1.1.2.1 test_securitydirectives.py:1.1.2.1 test_settings.py:1.1.2.1 test_zsp.py:1.1.2.1

Jim Fulton jim@zope.com
Mon, 23 Dec 2002 14:32:23 -0500


Update of /cvs-repository/Zope3/src/zope/app/security/tests
In directory cvs.zope.org:/tmp/cvs-serv19908/zope/app/security/tests

Added Files:
      Tag: NameGeddon-branch
	__init__.py test_basicauthadapter.py test_loginpassword.py 
	test_module.py test_modulehookup.py test_permissionfield.py 
	test_protectclass.py test_protectsubclass.py 
	test_securitydirectives.py test_settings.py test_zsp.py 
Log Message:
Initial renaming before debugging

=== Added File Zope3/src/zope/app/security/tests/__init__.py ===
#
# This file is necessary to make this directory a package.


=== Added File Zope3/src/zope/app/security/tests/test_basicauthadapter.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
# 
##############################################################################
import unittest, sys

from zope.app.security.basicauthadapter import BasicAuthAdapter

class Request:

    def __init__(self, lpw):
        self.lpw = lpw

    def _authUserPW(self):
        return self.lpw

    challenge = None
    def unauthorized(self, challenge):
        self.challenge = challenge


class Test(unittest.TestCase):

    def testBasicAuthAdapter(self):
        r = Request(None)
        a = BasicAuthAdapter(r)
        self.assertEqual(a.getLogin(), None)
        self.assertEqual(a.getPassword(), None)
        r = Request(("tim", "123"))
        a = BasicAuthAdapter(r)
        self.assertEqual(a.getLogin(), "tim")
        self.assertEqual(a.getPassword(), "123")

    def testUnauthorized(self):
        r = Request(None)
        a = BasicAuthAdapter(r)
        a.needLogin("tim")
        self.assertEqual(r.challenge, "basic realm=tim")

def test_suite():
    loader=unittest.TestLoader()
    return loader.loadTestsFromTestCase(Test)

if __name__=='__main__':
    unittest.TextTestRunner().run(test_suite())


=== Added File Zope3/src/zope/app/security/tests/test_loginpassword.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
# 
##############################################################################
import unittest, sys

from zope.app.security.loginpassword import LoginPassword

class Test(unittest.TestCase):

    def testLoginPassword(self):
        lp = LoginPassword("tim", "123")
        self.assertEqual(lp.getLogin(), "tim")
        self.assertEqual(lp.getPassword(), "123")
        lp = LoginPassword(None, None)
        self.assertEqual(lp.getLogin(), None)
        self.assertEqual(lp.getPassword(), None)
        lp = LoginPassword(None, "123")
        self.assertEqual(lp.getLogin(), None)
        self.assertEqual(lp.getPassword(), None)
        lp = LoginPassword("tim", None)
        self.assertEqual(lp.getLogin(), "tim")
        self.assertEqual(lp.getPassword(), "")
        lp.needLogin("tim") # This method should exist

def test_suite():
    loader=unittest.TestLoader()
    return loader.loadTestsFromTestCase(Test)

if __name__=='__main__':
    unittest.TextTestRunner().run(test_suite())


=== Added File Zope3/src/zope/app/security/tests/test_module.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
# 
##############################################################################
"""This empty module is for containing objects used in the course of tests.

(There is a problem with the way the unit tests interact with the modules
being tests, so the objects can't be expected to show up in place.)"""


=== Added File Zope3/src/zope/app/security/tests/test_modulehookup.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
# 
##############################################################################
"""Preliminaries to hookup a test suite with the external TestModule.

This is necessary because the test framework interferes with seeing changes in
the running modules via the module namespace.  This enables having some
subject classes, instances, permissions, etc, that don't live in the test
modules, themselves."""

from zope.interface import Interface

PREFIX = "Zope.App.Security.tests.TestModule."
import zope.app.security.tests.test_module
TestModule.test_class = None
class I(Interface):
    def m1():
        pass
    def m2():
        pass

class I2(I):
    def m4():
        pass
    

TestModule.I = I
TestModule.I2 = I2

template_bracket = """<zopeConfigure
   xmlns="http://namespaces.zope.org/zope" >
   %s
</zopeConfigure>"""


=== Added File Zope3/src/zope/app/security/tests/test_permissionfield.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
# 
##############################################################################
"""Permission fields tests

$Id: test_permissionfield.py,v 1.1.2.1 2002/12/23 19:32:21 jim Exp $
"""

from unittest import TestCase, TestSuite, main, makeSuite
from zope.app.security.permissionfield import PermissionField
from zope.schema.interfaces import ValidationError
from zope.app.tests.placelesssetup import PlacelessSetup
from zope.app.security.registries.permissionregistry import permissionRegistry
from zope.app.interfaces.security import IPermissionService
from zope.component.service \
     import serviceManager, defineService
from zope.app.security.registries.permissionregistry import Permission

class TestPermissionField(PlacelessSetup, TestCase):

    def test_validate(self):
        defineService("Permissions", IPermissionService)
        serviceManager.provideService("Permissions", permissionRegistry)
        dummy = Permission('dummy', 'Dummy', 'Dummy permission')
        field = PermissionField()
        self.assertRaises(ValidationError, field.validate, dummy)
        permissionRegistry.definePermission('read', 'Read', 'Read something')
        field.validate(permissionRegistry.getPermission('read'))

def test_suite():
    return TestSuite((makeSuite(TestPermissionField),))


if __name__=='__main__':
    main(defaultTest='test_suite')



=== Added File Zope3/src/zope/app/security/tests/test_protectclass.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
# 
##############################################################################
""" Test handler for 'protectClass' directive """

import unittest

from zope.app.security.tests.test_modulehookup import *
from zope.app.security.registries.permissionregistry import permissionRegistry
from zope.testing.cleanup import CleanUp # Base class w registry cleanup
from zope.app.security.protectclass import protectName, protectLikeUnto
from zope.app.security.protectclass import protectSetAttribute

NOTSET = []

P1 = "extravagant"
P2 = "paltry"

class Test(CleanUp, unittest.TestCase):

    def setUp(self):
        permissionRegistry.definePermission(P1, P1)
        permissionRegistry.definePermission(P2, P2)
        
        class B:
            def m1(self):
                return "m1"
            def m2(self):
                return "m2"
        class C(B):
            __implements__ = I
            def m3(self):
                return "m3"
            def m4(self):
                return "m4"
        TestModule.test_base = B
        TestModule.test_class = C
        TestModule.test_instance = C()
        self.assertState()

    def tearDown(self):
        CleanUp.tearDown(self)
        TestModule.test_class = None

    def assertState(self, m1P=NOTSET, m2P=NOTSET, m3P=NOTSET):
        "Verify that class, instance, and methods have expected permissions."

        from zope.security.checker import selectChecker
        from zope.exceptions import Forbidden

        checker = selectChecker(TestModule.test_instance)
        self.assertEqual(checker.permission_id('m1'), (m1P or None))
        self.assertEqual(checker.permission_id('m2'), (m2P or None))
        self.assertEqual(checker.permission_id('m3'), (m3P or None))

    # "testSimple*" exercises tags that do NOT have children.  This mode
    # inherently sets the instances as well as the class attributes.

    def testSimpleMethodsPlural(self):
        protectName(TestModule.test_class, 'm1', P1)
        protectName(TestModule.test_class, 'm3', P1)
        self.assertState(m1P=P1, m3P=P1)

    def testLikeUntoOnly(self):
        protectName(TestModule.test_base, 'm1', P1)
        protectName(TestModule.test_base, 'm2', P1)
        protectLikeUnto(TestModule.test_class, TestModule.test_base)
        # m1 and m2 are in the interface, so should be set, and m3 should not:
        self.assertState(m1P=P1, m2P=P1)

    def assertSetattrState(self, m1P=NOTSET, m2P=NOTSET, m3P=NOTSET):
        "Verify that class, instance, and methods have expected permissions."

        from zope.security.checker import selectChecker
        from zope.exceptions import Forbidden

        checker = selectChecker(TestModule.test_instance)
        self.assertEqual(checker.setattr_permission_id('m1'), (m1P or None))
        self.assertEqual(checker.setattr_permission_id('m2'), (m2P or None))
        self.assertEqual(checker.setattr_permission_id("m3"), (m3P or None))

    def testSetattr(self):
        protectSetAttribute(TestModule.test_class, 'm1', P1)
        protectSetAttribute(TestModule.test_class, 'm3', P1)
        self.assertSetattrState(m1P=P1, m3P=P1)

    def testLikeUntoAsDefault(self):
        protectName(TestModule.test_base, 'm1', P1)
        protectName(TestModule.test_base, 'm2', P1)
        protectLikeUnto(TestModule.test_class, TestModule.test_base)
        protectName(TestModule.test_class, 'm2', P2)
        protectName(TestModule.test_class, 'm3', P2)
        # m1 and m2 are in the interface, so should be set, and m3 should not:
        self.assertState(m1P=P1, m2P=P2, m3P=P2)
        
def test_suite():
    loader=unittest.TestLoader()
    return loader.loadTestsFromTestCase(Test)

if __name__=='__main__':
    unittest.TextTestRunner().run(test_suite())


=== Added File Zope3/src/zope/app/security/tests/test_protectsubclass.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
# 
##############################################################################
"""Test proper protection of inherited methods

Revision information:
$Id: test_protectsubclass.py,v 1.1.2.1 2002/12/23 19:32:21 jim Exp $
"""

from unittest import TestCase, TestSuite, main, makeSuite
from zope.testing.cleanup import CleanUp # Base class w registry cleanup
from zope.app.security.protectclass import protectName
from zope.app.security.registries.permissionregistry import permissionRegistry
from zope.security.checker import selectChecker

class Test(CleanUp, TestCase):

    def testInherited(self):

        class B1(object):
            def g(self): return 'B1.g'

        class B2(object):
            def h(self): return 'B2.h'

        class S(B1, B2):
            pass

        permissionRegistry.definePermission('B1', '')
        permissionRegistry.definePermission('S', '')
        protectName(B1, 'g', 'B1')
        protectName(S, 'g', 'S')
        protectName(S, 'h', 'S')

        self.assertEqual(selectChecker(B1()).permission_id('g'), 'B1')
        self.assertEqual(selectChecker(B2()).permission_id('h'), None)
        self.assertEqual(selectChecker(S()).permission_id('g'), 'S')
        self.assertEqual(selectChecker(S()).permission_id('h'), 'S')

        self.assertEqual(S().g(), 'B1.g')
        self.assertEqual(S().h(), 'B2.h')
        

def test_suite():
    return makeSuite(Test)

if __name__=='__main__':
    main(defaultTest='test_suite')


=== Added File Zope3/src/zope/app/security/tests/test_securitydirectives.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
# 
##############################################################################
"""

$Id: test_securitydirectives.py,v 1.1.2.1 2002/12/23 19:32:21 jim Exp $
"""

import unittest
from StringIO import StringIO

from zope.configuration.xmlconfig import ZopeXMLConfigurationError
from zope.configuration.xmlconfig import XMLConfig, xmlconfig

from zope.testing.cleanup import CleanUp # Base class w registry cleanup

import Zope.App.Security
from zope.app.security.settings import Allow, Deny
from zope.app.security.registries.principalregistry import principalRegistry
from zope.app.security.registries.permissionregistry \
        import permissionRegistry as pregistry
from zope.app.security.registries.roleregistry import roleRegistry as rregistry
from zope.app.security.grants.global.rolepermissionmanager \
        import rolePermissionManager as role_perm_mgr
from zope.app.security.grants.global.principalpermissionmanager \
    import principalPermissionManager as principal_perm_mgr
from zope.app.security.grants.global.principalrolemanager \
    import principalRoleManager as principal_role_mgr


def configfile(s):
    return StringIO("""<zopeConfigure
      xmlns='http://namespaces.zope.org/zope'>
      %s
      </zopeConfigure>
      """ % s)

class TestPrincipalDirective(CleanUp, unittest.TestCase):
    def setUp(self):
        XMLConfig('meta.zcml', Zope.App.Security)()

    def testRegister(self):
        f = configfile("""<principal id="1"
                             title="Sir Tim Peters"
                             description="Tim Peters"
                             login="tim" password="123" />
                          <principal id="2"
                             title="Sir Jim Fulton"
                             description="Jim Fulton"
                             login="jim" password="123" />""")
        xmlconfig(f)

        reg=principalRegistry
        
        p = reg.getPrincipal('1')
        self.assertEqual(p.getId(), '1')
        self.assertEqual(p.getTitle(), 'Sir Tim Peters')
        self.assertEqual(p.getDescription(), 'Tim Peters')
        p = reg.getPrincipal('2')
        self.assertEqual(p.getId(), '2')
        self.assertEqual(p.getTitle(), 'Sir Jim Fulton')
        self.assertEqual(p.getDescription(), 'Jim Fulton')

        self.assertEqual(len(reg.getPrincipals('')), 2)


class TestPermissionDirective(CleanUp, unittest.TestCase):
    def setUp(self):
        XMLConfig('meta.zcml', Zope.App.Security)()

    def testRegister(self):
        f = configfile("""
 <permission
     id="Can Do It"
     title="A Permissive Permission"
     description="This permission lets you do anything" />""")

        xmlconfig(f)

        perm = pregistry.getPermission("Can Do It")
        self.failUnless(perm.getId().endswith('Can Do It'))
        self.assertEqual(perm.getTitle(), 'A Permissive Permission')
        self.assertEqual(perm.getDescription(),
                         'This permission lets you do anything')

    def testDuplicationRegistration(self):
        f = configfile("""
 <permission
     id="Can Do It"
     title="A Permissive Permission"
     description="This permission lets you do anything" />

 <permission
     id="Can Do It"
     title="A Permissive Permission"
     description="This permission lets you do anything" />
     """)

        #self.assertRaises(AlreadyRegisteredError, xmlconfig, f)
        self.assertRaises(ZopeXMLConfigurationError, xmlconfig, f)
        
class TestRoleDirective(CleanUp, unittest.TestCase):
    def setUp(self):
        XMLConfig('meta.zcml', Zope.App.Security)()

    def testRegister(self):
        f = configfile("""
 <role
     id="Everyperson"
     title="Tout le monde"
     description="The common man, woman, person, or thing" />
     """)

        xmlconfig(f)

        role = rregistry.getRole("Everyperson")
        self.failUnless(role.getId().endswith('Everyperson'))
        self.assertEqual(role.getTitle(), 'Tout le monde')
        self.assertEqual(role.getDescription(),
                         'The common man, woman, person, or thing')
        
    def testDuplicationRegistration(self):
        f = configfile("""
 <role
     id="Everyperson"
     title="Tout le monde"
     description="The common man, woman, person, or thing" />

 <role
     id="Everyperson"
     title="Tout le monde"
     description="The common man, woman, person, or thing" />
     """)

        #self.assertRaises(AlreadyRegisteredError, xmlconfig, f)
        self.assertRaises(ZopeXMLConfigurationError, xmlconfig, f)

class TestRolePermission(CleanUp, unittest.TestCase):

    def setUp( self ):
        XMLConfig('meta.zcml', Zope.App.Security)()

    def testMap( self ):
        f = configfile("""
 <grant
     permission="Foo"
     role="Bar" />
     """)

        xmlconfig(f)

        roles = role_perm_mgr.getRolesForPermission("Foo")
        perms = role_perm_mgr.getPermissionsForRole("Bar")

        self.assertEqual(len( roles ), 1)
        self.failUnless(("Bar",Allow) in roles)

        self.assertEqual(len( perms ), 1)
        self.failUnless(("Foo",Allow) in perms)

class TestPrincipalPermission(CleanUp, unittest.TestCase):

    def setUp( self ):
        XMLConfig('meta.zcml', Zope.App.Security)()

    def testMap( self ):
        f = configfile("""
 <grant
     permission="Foo"
     principal="Bar" />
     """)

        xmlconfig(f)

        principals = principal_perm_mgr.getPrincipalsForPermission("Foo")
        perms = principal_perm_mgr.getPermissionsForPrincipal("Bar")

        self.assertEqual(len( principals ), 1)
        self.failUnless(("Bar", Allow) in principals)

        self.assertEqual(len( perms ), 1)
        self.failUnless(("Foo", Allow) in perms)

class TestPrincipalRole(CleanUp, unittest.TestCase):

    def setUp( self ):
        XMLConfig('meta.zcml', Zope.App.Security)()

    def testMap( self ):
        f = configfile("""
 <grant
     role="Foo"
     principal="Bar" />
     """)

        xmlconfig(f)

        principals = principal_role_mgr.getPrincipalsForRole("Foo")
        roles = principal_role_mgr.getRolesForPrincipal("Bar")

        self.assertEqual(len( principals ), 1)
        self.failUnless(("Bar",Allow) in principals)

        self.assertEqual(len( roles ), 1)
        self.failUnless(("Foo",Allow) in roles)

def test_suite():
    suite = unittest.TestSuite()
    loader = unittest.TestLoader()
    suite.addTest(loader.loadTestsFromTestCase(TestPrincipalDirective))
    suite.addTest(loader.loadTestsFromTestCase(TestPermissionDirective))
    suite.addTest(loader.loadTestsFromTestCase(TestRoleDirective))
    suite.addTest(loader.loadTestsFromTestCase(TestRolePermission))
    suite.addTest(loader.loadTestsFromTestCase(TestPrincipalPermission))
    suite.addTest(loader.loadTestsFromTestCase(TestPrincipalRole))
    return suite


if __name__=='__main__':
    unittest.TextTestRunner().run(test_suite())


=== Added File Zope3/src/zope/app/security/tests/test_settings.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
# 
##############################################################################
import unittest, sys

from zope.app.security.settings import Allow
from cPickle import Pickler, Unpickler
from StringIO import StringIO

class Test(unittest.TestCase):

    def testPickleUnpickle(self):
        s = StringIO()
        p = Pickler(s)
        p.dump(Allow)
        s.seek(0)
        u = Unpickler(s)
        newAllow = u.load()
        
        self.failUnless(newAllow is Allow)

def test_suite():
    loader=unittest.TestLoader()
    return loader.loadTestsFromTestCase(Test)

if __name__=='__main__':
    unittest.TextTestRunner().run(test_suite())


=== Added File Zope3/src/zope/app/security/tests/test_zsp.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
# 
##############################################################################
"""


Revision information: $Id: test_zsp.py,v 1.1.2.1 2002/12/23 19:32:21 jim Exp $
"""

import unittest

from zope.proxy.context.context import ContextWrapper
from zope.component import getService
from zope.app.interfaces.security import IRolePermissionManager
from zope.app.security.registries.permissionregistry import permissionRegistry 
from zope.app.security.registries.principalregistry import principalRegistry 
from zope.app.security.registries.roleregistry import roleRegistry
from zope.app.security.grants.global.principalpermissionmanager \
     import principalPermissionManager 
from zope.app.security.grants.global.rolepermissionmanager \
     import rolePermissionManager 
from zope.app.security.grants.global.principalrolemanager \
     import principalRoleManager 
from zope.app.security.grants.annotationprincipalpermissionmanager \
    import AnnotationPrincipalPermissionManager 
from zope.app.interfaces.security \
    import IPrincipalPermissionManager 
from zope.app.security.grants.annotationprincipalrolemanager \
    import AnnotationPrincipalRoleManager 
from zope.app.security.grants.annotationrolepermissionmanager \
    import AnnotationRolePermissionManager 
from zope.app.interfaces.security import IPrincipalRoleManager 
from zope.app.interfaces.annotation import IAttributeAnnotatable
from zope.app.interfaces.annotation import IAnnotations
from zope.app.attributeannotations import AttributeAnnotations
from zope.app.services.tests.placefulsetup\
           import PlacefulSetup
from zope.app.security.zopesecuritypolicy import permissionsOfPrincipal

class Context:
    def __init__(self, user, stack=[]):
        self.user, self.stack = user, stack
    
class Unprotected:
    pass


class Test(PlacefulSetup, unittest.TestCase):

    def setUp(self):
        PlacefulSetup.setUp(self)
        getService(None,"Adapters").provideAdapter(
                       IAttributeAnnotatable, IAnnotations,
                       AttributeAnnotations)

        # set up some principals
        jim = principalRegistry.definePrincipal('jim', 'Jim', 'Jim Fulton',
                                                'jim', '123')
        self.jim = jim.getId()
        
        tim = principalRegistry.definePrincipal('tim', 'Tim', 'Tim Peters',
                                                'tim', '456')
        self.tim = tim.getId()

        unknown = principalRegistry.defineDefaultPrincipal('unknown', 
                    'Unknown', 'Nothing is known about this principal')
        self.unknown = unknown.getId()
        
        # set up some permissions
        read = permissionRegistry.definePermission('read', 'Read', 
                                                   'Read something')
        self.read = read.getId()
        write = permissionRegistry.definePermission('write', 'Write', 
                                                    'Write something')
        self.write = write.getId()
        create = permissionRegistry.definePermission('create', 'Create',
                                                     'Create something')
        self.create = create.getId()
        update = permissionRegistry.definePermission('update', 'Update',
                                                     'Update something')
        self.update = update

        # ... and some roles...
        peon = roleRegistry.defineRole('Peon', 'Site Peon')
        self.peon = peon.getId()

        manager = roleRegistry.defineRole('Manager', 'Site Manager')
        self.manager = manager.getId()
        
        arole = roleRegistry.defineRole('Another', 'Another Role')
        self.arole = arole.getId()

        # grant and deny some permissions to a principal
        principalPermissionManager.grantPermissionToPrincipal(self.create, self.jim)
        principalPermissionManager.denyPermissionToPrincipal(self.update, self.jim)
        
        # grant and deny some permissions to the roles
        rolePermissionManager.grantPermissionToRole(self.read, self.peon)

        rolePermissionManager.grantPermissionToRole(self.read, self.manager)
        rolePermissionManager.grantPermissionToRole(self.write, self.manager)

        # ... and assign roles to principals
        principalRoleManager.assignRoleToPrincipal(self.peon, self.jim)
        principalRoleManager.assignRoleToPrincipal(self.manager, self.tim)

        self.policy = self._makePolicy()

    def _makePolicy( self ):

        from zope.app.security.zopesecuritypolicy import ZopeSecurityPolicy
        return ZopeSecurityPolicy()

    def testImport( self ):

        from zope.app.security.zopesecuritypolicy import ZopeSecurityPolicy

    def testGlobalCheckPermission(self):
        self.failUnless(
            self.policy.checkPermission(self.read, None, Context(self.jim)))
        self.failUnless(
            self.policy.checkPermission(self.read, None, Context(self.tim)))
        self.failUnless(
            self.policy.checkPermission(self.write, None, Context(self.tim)))

        self.failIf(self.policy.checkPermission(
            self.read, None, Context(self.unknown)))
        self.failIf(self.policy.checkPermission(
            self.write, None, Context(self.unknown)))
        
        self.failIf(
            self.policy.checkPermission(
            self.read, None, Context(self.unknown)))

        self.__assertPermissions(self.jim, ['create', 'read'])
        self.__assertPermissions(self.tim, ['read', 'write'])
        self.__assertPermissions(self.unknown, [])

        rolePermissionManager.grantPermissionToRole(self.read, 'Anonymous')
        
        self.failUnless(
            self.policy.checkPermission(
            self.read, None, Context(self.unknown)))

        self.__assertPermissions(self.unknown, ['read'])

        principalPermissionManager.grantPermissionToPrincipal(
            self.write, self.jim)
        self.failUnless(
            self.policy.checkPermission(self.write, None, Context(self.jim)))

        self.__assertPermissions(self.jim, ['create', 'read', 'write'])

    def __assertPermissions(self, user, expected, object=None):
        permissions = list(permissionsOfPrincipal(user, object))
        permissions.sort()
        self.assertEqual(permissions, expected)
        

    def testPlayfulPrincipalRole(self):
        getService(None,"Adapters").provideAdapter(
            ITest,
            IPrincipalRoleManager, AnnotationPrincipalRoleManager)

        ob1 = TestClass()
        ob2 = TestClass()
        ob3 = TestClass()
        ob  = ContextWrapper(ob3, ContextWrapper(ob2, ob1))
        self.failIf(self.policy.checkPermission(
            self.write, ob, Context(self.jim)))
        AnnotationPrincipalRoleManager(ob).assignRoleToPrincipal(
            self.manager, self.jim)
        self.failUnless(self.policy.checkPermission(
            self.write, ob, Context(self.jim)))
        

    def testPlayfulRolePermissions(self):
        
        ARPM = AnnotationRolePermissionManager
        getService(None,"Adapters").provideAdapter(ITest,
                            IRolePermissionManager, ARPM)
        test = permissionRegistry.definePermission('test', 'Test', '')
        test = test.getId()

        ob1 = TestClass()
        ob2 = TestClass()
        ob3 = TestClass()

        ob  = ContextWrapper(ob3, ContextWrapper(ob2, ob1))

        self.failIf(self.policy.checkPermission(test, ob, Context(self.tim)))
        self.__assertPermissions(self.tim, ['read', 'write'], ob)

        ARPM(ob2).grantPermissionToRole(test, self.manager)
        self.failUnless(self.policy.checkPermission(test, ob,
                                                    Context(self.tim)))
        self.__assertPermissions(self.tim, ['read', 'test', 'write'], ob)

        self.failIf(self.policy.checkPermission(test, ob, Context(self.jim)))
        self.__assertPermissions(self.jim, ['create', 'read'], ob)


        ARPM(ob3).grantPermissionToRole(test, self.peon)
        self.failUnless(self.policy.checkPermission(
            test, ob, Context(self.jim)))
        self.__assertPermissions(self.jim, ['create', 'read', 'test'], ob)



        principalPermissionManager.denyPermissionToPrincipal(
            test, self.jim)
        self.failIf(self.policy.checkPermission(
            test, ob, Context(self.jim)))
        self.__assertPermissions(self.jim, ['create', 'read'], ob)

        principalPermissionManager.unsetPermissionForPrincipal(
            test, self.jim)

        # Make sure multiple conflicting role permissions resolve correctly
        ARPM(ob2).grantPermissionToRole(test, 'Anonymous')
        ARPM(ob2).grantPermissionToRole(test, self.arole)
        ARPM(ob3).denyPermissionToRole(test, self.peon)
        
        new = principalRegistry.definePrincipal('new', 'Newbie', 
                                                'Newbie User', 'new', '098')
        new = new.getId()
        principalRoleManager.assignRoleToPrincipal(self.arole, new)
        self.failUnless(self.policy.checkPermission(test, ob, Context(new)))
        self.__assertPermissions(new, ['test'], ob)

        principalRoleManager.assignRoleToPrincipal(self.peon, new)
        self.failIf(self.policy.checkPermission(test, ob, Context(new)))
        self.__assertPermissions(new, ['read'], ob)
                    
    def testPlayfulPrinciplePermissions(self):
        APPM = AnnotationPrincipalPermissionManager
        getService(None,"Adapters").provideAdapter(ITest,
                       IPrincipalPermissionManager, APPM)

        ob1 = TestClass()
        ob2 = TestClass()
        ob3 = TestClass()

        test = permissionRegistry.definePermission('test', 'Test', '')
        test = test.getId()

        ob  = ContextWrapper(ob3, ContextWrapper(ob2, ob1))
        self.failIf(self.policy.checkPermission(test, ob, Context(self.tim)))

        self.__assertPermissions(self.tim, ['read', 'write'], ob)

        APPM(ob2).grantPermissionToPrincipal(test, self.tim)
        self.failUnless(self.policy.checkPermission(test, ob,
                                                    Context(self.tim)))
        self.__assertPermissions(self.tim, ['read', 'test', 'write'], ob)

        APPM(ob3).denyPermissionToPrincipal(test, self.tim)
        self.failIf(self.policy.checkPermission(test, ob,
                                                Context(self.tim)))
        self.__assertPermissions(self.tim, ['read', 'write'], ob)

        APPM(ob1).denyPermissionToPrincipal(test, self.jim)
        APPM(ob3).grantPermissionToPrincipal(test, self.jim)
        self.failUnless(self.policy.checkPermission(test, ob,
                                                    Context(self.jim)))
        self.__assertPermissions(self.jim, ['create', 'read', 'test'], ob)


        APPM(ob3).unsetPermissionForPrincipal(test, self.jim)
        self.failIf(self.policy.checkPermission(test, ob,
                                                Context(self.jim)))
        self.__assertPermissions(self.jim, ['create', 'read'], ob)

        # make sure placeless principal permissions override placeful ones
        APPM(ob).grantPermissionToPrincipal(test, self.tim)
        principalPermissionManager.denyPermissionToPrincipal(
            test, self.tim)
        self.failIf(self.policy.checkPermission(test, ob,
                                                Context(self.tim)))

        self.__assertPermissions(self.tim, ['read', 'write'], ob)


class ITest(IAttributeAnnotatable):
    pass

class TestClass:
    __implements__ = ITest

    def __init__(self):
        self._roles       = { 'test' : {} }
        self._permissions = { 'Manager' : {} , 'Peon' : {} }
    
def test_suite():
    loader=unittest.TestLoader()
    return loader.loadTestsFromTestCase(Test)

if __name__=='__main__':
    unittest.TextTestRunner().run(test_suite())