[Zope-Checkins] SVN: Zope/trunk/ Moved security related ZCML configuration into the AccessControl package.

Hanno Schlichting hannosch at hannosch.eu
Thu Dec 31 16:41:57 EST 2009


Log message for revision 107479:
  Moved security related ZCML configuration into the AccessControl package.
  

Changed:
  U   Zope/trunk/doc/CHANGES.rst
  A   Zope/trunk/src/AccessControl/meta.zcml
  A   Zope/trunk/src/AccessControl/metaconfigure.py
  A   Zope/trunk/src/AccessControl/tests/testZCML.py
  U   Zope/trunk/src/Products/Five/browser/tests/test_zope3security.py
  U   Zope/trunk/src/Products/Five/browser/tests/zope3security.py
  U   Zope/trunk/src/Products/Five/meta.zcml
  U   Zope/trunk/src/Products/Five/metaconfigure.py
  D   Zope/trunk/src/Products/Five/tests/test_security.py

-=-
Modified: Zope/trunk/doc/CHANGES.rst
===================================================================
--- Zope/trunk/doc/CHANGES.rst	2009-12-31 20:40:13 UTC (rev 107478)
+++ Zope/trunk/doc/CHANGES.rst	2009-12-31 21:41:57 UTC (rev 107479)
@@ -35,7 +35,8 @@
 - Removed experimental support for configuring the Twisted HTTP server
   as an alternative to ``ZServer``.
 
-- Moved ``Products/Five/security.py`` into the AccessControl package.
+- Moved ``Products/Five/security.py`` and security related ZCML configuration
+  into the AccessControl package.
 
 - Moved ``Products/Five/traversing.zcml`` directly into the configure.zcml.
 

Added: Zope/trunk/src/AccessControl/meta.zcml
===================================================================
--- Zope/trunk/src/AccessControl/meta.zcml	                        (rev 0)
+++ Zope/trunk/src/AccessControl/meta.zcml	2009-12-31 21:41:57 UTC (rev 107479)
@@ -0,0 +1,41 @@
+<configure
+    xmlns="http://namespaces.zope.org/zope"
+    xmlns:meta="http://namespaces.zope.org/meta">
+
+  <include package="zope.component" file="meta.zcml" />
+  <include package="zope.security" file="meta.zcml" />
+
+  <meta:directives namespace="http://namespaces.zope.org/zope">
+
+    <meta:complexDirective
+        name="class"
+        schema="zope.security.metadirectives.IClassDirective"
+        handler=".metaconfigure.ClassDirective"
+        >
+
+      <meta:subdirective
+          name="implements"
+          schema="zope.security.metadirectives.IImplementsSubdirective"
+          />
+
+      <meta:subdirective
+          name="require"
+          schema="zope.security.metadirectives.IRequireSubdirective"
+          />
+
+      <meta:subdirective
+          name="allow"
+          schema="zope.security.metadirectives.IAllowSubdirective"
+          />
+
+    </meta:complexDirective>
+
+    <meta:directive
+        name="securityPolicy"
+        schema="zope.security.zcml.ISecurityPolicyDirective"
+        handler="zope.security.zcml.securityPolicy"
+        />
+
+  </meta:directives>
+
+</configure>


Property changes on: Zope/trunk/src/AccessControl/meta.zcml
___________________________________________________________________
Added: svn:eol-style
   + native

Copied: Zope/trunk/src/AccessControl/metaconfigure.py (from rev 107450, Zope/trunk/src/Products/Five/metaconfigure.py)
===================================================================
--- Zope/trunk/src/AccessControl/metaconfigure.py	                        (rev 0)
+++ Zope/trunk/src/AccessControl/metaconfigure.py	2009-12-31 21:41:57 UTC (rev 107479)
@@ -0,0 +1,49 @@
+##############################################################################
+#
+# Copyright (c) 2004, 2005 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (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 warnings
+from zope.security import metaconfigure
+from AccessControl.security import protectName
+from App.class_init import InitializeClass
+
+class ClassDirective(metaconfigure.ClassDirective):
+
+    def __protectName(self, name, permission_id):
+        self.__context.action(
+            discriminator = ('five:protectName', self.__class, name),
+            callable = protectName,
+            args = (self.__class, name, permission_id)
+            )
+
+    def __protectSetAttributes(self, names, permission_id):
+        warnings.warn("The set_attribute option of the <require /> directive "
+                      "is not supported in Zope 2. "
+                      "Ignored for %s" % str(self.__class), stacklevel=3)
+
+    def __protectSetSchema(self, schema, permission):
+        warnings.warn("The set_schema option of the <require /> directive "
+                      "is not supported in Zope 2. "
+                      "Ignored for %s" % str(self.__class), stacklevel=3)
+
+    def __mimic(self, _context, class_):
+        warnings.warn("The like_class option of the <require /> directive "
+                      "is not supported in Zope 2. "
+                      "Ignored for %s" % str(self.__class), stacklevel=3)
+
+    def __call__(self):
+        return self.__context.action(
+            discriminator = None,
+            callable = InitializeClass,
+            args = (self.__class,)
+            )

Copied: Zope/trunk/src/AccessControl/tests/testZCML.py (from rev 107450, Zope/trunk/src/Products/Five/tests/test_security.py)
===================================================================
--- Zope/trunk/src/AccessControl/tests/testZCML.py	                        (rev 0)
+++ Zope/trunk/src/AccessControl/tests/testZCML.py	2009-12-31 21:41:57 UTC (rev 107479)
@@ -0,0 +1,381 @@
+##############################################################################
+#
+# Copyright (c) 2004, 2005 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (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 security induced by ZCML
+
+$Id$
+"""
+
+from zope.interface import implements
+from zope.interface import Interface
+from zope.schema import TextLine
+from AccessControl.SecurityInfo import ClassSecurityInfo
+
+class ISuperDummy(Interface):
+    """
+    """
+
+    def superMethod():
+        """
+        """
+
+class IDummy(ISuperDummy):
+    """Just a marker interface"""
+
+    def foo():
+        """
+        """
+
+class Dummy1:
+    implements(IDummy)
+    def foo(self): pass
+    def bar(self): pass
+    def baz(self): pass
+    def keg(self): pass
+    def wot(self): pass
+    def superMethod(self): pass
+
+class Dummy2(Dummy1):
+    security = ClassSecurityInfo()
+    security.declarePublic('foo')
+    security.declareProtected('View management screens', 'bar')
+    security.declarePrivate('baz')
+    security.declareProtected('View management screens', 'keg')
+
+class IDummy3(Interface):
+    attr = TextLine(title=u"Attribute")
+
+class Dummy3:
+    implements(IDummy3)
+    attr = None
+
+class Dummy4:
+    foo = None
+
+def test_security_equivalence():
+    """This test demonstrates that the traditional declarative security of
+    Zope 2 can be replaced by ZCML statements without any loss of
+    information.
+
+      >>> from zope.component.testing import setUp, tearDown
+      >>> setUp()
+
+    We start out with two classes, ``Dummy1`` and ``Dummy2``.  They
+    are identical in every way, except that ``Dummy2`` has security
+    declarations and ``Dummy1`` does not.  Before we do anything, none
+    of them have security access controls:
+
+      >>> from AccessControl.tests.testZCML import Dummy1, Dummy2
+      >>> hasattr(Dummy1, '__ac_permissions__')
+      False
+      >>> hasattr(Dummy2, '__ac_permissions__')
+      False
+
+    Before we can make security declarations through ZCML, we need to
+    register the directive and the permission:
+
+      >>> import AccessControl
+      >>> from zope.configuration.xmlconfig import XMLConfig
+      >>> XMLConfig('meta.zcml', AccessControl)()
+      >>> XMLConfig('permissions.zcml', AccessControl)()
+
+    Now we initialize the security for ``Dummy2`` and provide some
+    ZCML declarations for ``Dummy1``:
+
+      >>> from StringIO import StringIO
+      >>> configure_zcml = StringIO('''
+      ... <configure xmlns="http://namespaces.zope.org/zope">
+      ...   <class class="AccessControl.tests.testZCML.Dummy1">
+      ...     <allow attributes="foo" />
+      ...     <!--deny attributes="baz" /--> <!-- XXX not yet supported -->
+      ...   </class>
+      ...   <class class="AccessControl.tests.testZCML.Dummy1">
+      ...     <require attributes="bar keg"
+      ...              permission="zope2.ViewManagementScreens"
+      ...              />
+      ...   </class>
+      ... </configure>
+      ... ''')
+      >>> from zope.configuration.xmlconfig import xmlconfig
+      >>> xmlconfig(configure_zcml)
+
+      >>> from App.class_init import InitializeClass
+      >>> InitializeClass(Dummy2)
+
+    Now we compare their access controls:
+
+      >>> ac1 = getattr(Dummy1, '__ac_permissions__')
+      >>> ac2 = getattr(Dummy2, '__ac_permissions__')
+      >>> ac1 == ac2
+      True
+
+    Now we look at the individual permissions:
+
+      >>> from AccessControl.ZopeSecurityPolicy import getRoles
+      >>> from AccessControl import ACCESS_PUBLIC
+      >>> from AccessControl import ACCESS_PRIVATE
+
+      >>> dummy1 = Dummy1()
+      >>> getRoles(dummy1, 'bar', dummy1.bar, ('Def',))
+      ('Manager',)
+
+      >>> getRoles(dummy1, 'keg', dummy1.keg, ('Def',))
+      ('Manager',)
+
+      >>> getRoles(dummy1, 'foo', dummy1.foo, ('Def',)) is ACCESS_PUBLIC
+      True
+
+      #>>> getRoles(dummy1, 'baz', dummy1.baz, ('Def',)) is ACCESS_PRIVATE
+      #True XXX Not yet supported.
+
+      >>> dummy2 = Dummy2()
+      >>> getRoles(dummy2, 'bar', dummy2.bar, ('Def',))
+      ('Manager',)
+
+      >>> getRoles(dummy2, 'keg', dummy2.keg, ('Def',))
+      ('Manager',)
+
+      >>> getRoles(dummy2, 'foo', dummy2.foo, ('Def',)) is ACCESS_PUBLIC
+      True
+
+      >>> getRoles(dummy2, 'baz', dummy2.baz, ('Def',)) is ACCESS_PRIVATE
+      True
+
+    Before we end we should clean up after ourselves:
+
+      >>> from AccessControl.security import clearSecurityInfo
+      >>> clearSecurityInfo(Dummy1)
+      >>> clearSecurityInfo(Dummy2)
+
+      >>> tearDown()
+    """
+
+
+def test_set_warnings():
+    """This test demonstrates that set_attributes and set_schema will result
+    in warnings, not errors. This type of protection doesn't make sense in
+    Zope 2, but we want to be able to re-use Zope Toolkit packages that use
+    them without error.
+
+      >>> from zope.component.testing import setUp, tearDown
+      >>> setUp()
+
+    Before we can make security declarations through ZCML, we need to
+    register the directive and the permission:
+
+      >>> import AccessControl
+      >>> from zope.configuration.xmlconfig import XMLConfig
+      >>> XMLConfig('meta.zcml', AccessControl)()
+      >>> XMLConfig('permissions.zcml', AccessControl)()
+
+    Now we provide some ZCML declarations for ``Dummy1``:
+
+      >>> from StringIO import StringIO
+      >>> configure_zcml = StringIO('''
+      ... <configure xmlns="http://namespaces.zope.org/zope">
+      ...
+      ...   <class class="AccessControl.tests.testZCML.Dummy3">
+      ...       <require
+      ...           permission="zope2.View"
+      ...           interface="AccessControl.tests.testZCML.IDummy3"
+      ...           />
+      ...       <require
+      ...           permission="zope2.ChangeConfig"
+      ...           set_schema="AccessControl.tests.testZCML.IDummy3"
+      ...           />
+      ...   </class>
+      ...
+      ...   <class class="AccessControl.tests.testZCML.Dummy4">
+      ...       <require
+      ...           permission="zope2.ChangeConfig"
+      ...           set_attributes="foo"
+      ...           />
+      ...   </class>
+      ...
+      ... </configure>
+      ... ''')
+
+      Running this should not throw an exception (but will print a warning to
+      stderr)
+
+      >>> from zope.configuration.xmlconfig import xmlconfig
+      >>> xmlconfig(configure_zcml)
+      >>> tearDown()
+    """
+
+def test_checkPermission():
+    """
+    Test checkPermission
+
+      >>> from zope.component.testing import setUp, tearDown
+      >>> setUp()
+
+    Zope 3 has a function zope.security.checkPermission which provides
+    an easy way of checking whether the currently authenticated user
+    has the permission to access an object.  The function delegates to
+    the security policy's checkPermission() method.
+
+    Zope2 has the same function, AccessControl.security.checkPermission,
+    but in a Zope2-compatible implementation.  It too uses the currently
+    active security policy of Zope 2 for the actual permission
+    checking.
+
+      >>> import AccessControl
+      >>> from zope.configuration.xmlconfig import XMLConfig
+      >>> XMLConfig('meta.zcml', AccessControl)()
+      >>> XMLConfig('permissions.zcml', AccessControl)()
+
+    In the following we want to test AccessControl's checkPermission function.
+    We do that by taking the test's folder and asserting several
+    standard permissions.  What we want to assure is that
+    checkPermission translates the Zope 2 permissions correctly,
+    especially the edge cases:
+
+    a) zope2.Public (which should always be available to everyone)
+
+      >>> from AccessControl.security import checkPermission
+      >>> checkPermission('zope2.Public', self.folder)
+      True
+
+    b) zope2.Private (which should never available to anyone)
+
+      >>> checkPermission('zope.Private', self.folder)
+      False
+      >>> checkPermission('zope2.Private', self.folder)
+      False
+
+    Any other standard Zope 2 permission will also resolve correctly:
+
+      >>> checkPermission('zope2.AccessContentsInformation', self.folder)
+      True
+
+    Invalid permissions will obviously result in a negative response:
+
+      >>> checkPermission('notapermission', self.folder)
+      False
+
+
+    In addition to using AccessControl's ``checkPermission`` function
+    directly, we also expect the same behaviour when we use zope.security's
+    checkPermission function. Code from within other Zope packages will use
+    that and therefore it should work transparently.
+    For that to work, a new AccessControl "interaction" needs to be started
+    (the old one from placelesssetup needs to be ended first):
+
+      >>> from zope.security.management import endInteraction
+      >>> endInteraction()
+
+      >>> from AccessControl.security import newInteraction
+      >>> newInteraction()
+
+    a) zope2.Public (which should always be available to everyone)
+
+      >>> from zope.security import checkPermission
+      >>> checkPermission('zope2.Public', self.folder)
+      True
+
+    b) zope2.Private (which should never available to anyone)
+
+      >>> checkPermission('zope.Private', self.folder)
+      False
+      >>> checkPermission('zope2.Private', self.folder)
+      False
+
+    Any other standard Zope 2 permission will also resolve correctly:
+
+      >>> checkPermission('zope2.AccessContentsInformation', self.folder)
+      True
+
+    Invalid permissions will obviously result in a negative response:
+
+      >>> checkPermission('notapermission', self.folder)
+      False
+
+    Clean up:
+
+      >>> tearDown()
+    """
+
+def test_register_permission():
+    """This test demonstrates that if the <permission /> directive is used
+    to create a permission that does not already exist, it is created on 
+    startup, with roles defaulting to Manager.
+
+      >>> from Testing.ZopeTestCase.placeless import setUp, tearDown
+      >>> setUp()
+
+    First, we need to configure the relevant parts of AccessControl:
+
+      >>> import AccessControl
+      >>> from zope.configuration.xmlconfig import XMLConfig
+      >>> XMLConfig('meta.zcml', AccessControl)()
+      >>> XMLConfig('permissions.zcml', AccessControl)()
+
+    We can now register a permission in ZCML:
+
+      >>> from StringIO import StringIO
+      >>> configure_zcml = StringIO('''
+      ... <configure xmlns="http://namespaces.zope.org/zope"
+      ...            i18n_domain="test">
+      ...
+      ...   <permission
+      ...       id="AccessControl.tests.DummyPermission"
+      ...       title="AccessControl: Dummy permission"
+      ...       />
+      ...
+      ... </configure>
+      ... ''')
+      >>> from zope.configuration.xmlconfig import xmlconfig
+      >>> xmlconfig(configure_zcml)
+      
+    The permission will be made available globally, with default role set
+    of ('Manager',).
+      
+      >>> roles = self.app.rolesOfPermission('AccessControl: Dummy permission')
+      >>> sorted(r['name'] for r in roles if r['selected'])
+      ['Manager']
+
+    Let's also ensure that permissions are not overwritten if they exist
+    already:
+      
+      >>> from AccessControl.Permission import _registeredPermissions
+      >>> import Products
+      >>> _registeredPermissions['Dummy: Other dummy'] = 1
+      >>> Products.__ac_permissions__ += (('Dummy: Other dummy', (), (),),)
+      >>> self.app.manage_permission('Dummy: Other dummy', roles=['Anonymous'])
+
+      >>> from StringIO import StringIO
+      >>> configure_zcml = StringIO('''
+      ... <configure xmlns="http://namespaces.zope.org/zope"
+      ...            i18n_domain="test">
+      ...
+      ...   <permission
+      ...       id="AccessControl.tests.OtherDummy"
+      ...       title="Dummy: Other dummy"
+      ...       />
+      ...
+      ... </configure>
+      ... ''')
+      >>> from zope.configuration.xmlconfig import xmlconfig
+      >>> xmlconfig(configure_zcml)
+
+      >>> roles = self.app.rolesOfPermission('Dummy: Other dummy')
+      >>> sorted(r['name'] for r in roles if r['selected'])
+      ['Anonymous']
+
+      >>> tearDown()
+    """
+
+def test_suite():
+    from Testing.ZopeTestCase import ZopeDocTestSuite
+    return ZopeDocTestSuite()

Modified: Zope/trunk/src/Products/Five/browser/tests/test_zope3security.py
===================================================================
--- Zope/trunk/src/Products/Five/browser/tests/test_zope3security.py	2009-12-31 20:40:13 UTC (rev 107478)
+++ Zope/trunk/src/Products/Five/browser/tests/test_zope3security.py	2009-12-31 21:41:57 UTC (rev 107479)
@@ -1,11 +1,11 @@
 
 def test_check_permission():
-    """Code (in Zope 3) often uses
+    """Code (in Zope packages) often uses
     zope.security.management.checkPermission to determine whether the
-    current user has a certain permission in a given context.  Five
+    current user has a certain permission in a given context. Five
     inserts its own interaction that assures that such calls still
     work.
-    
+
       >>> configure_zcml = '''
       ... <configure 
       ...     xmlns="http://namespaces.zope.org/zope"
@@ -53,6 +53,80 @@
 
     """
 
+def test_allowed_interface():
+    """This test demonstrates that allowed_interface security declarations work
+    as expected.
+
+      >>> from zope.component.testing import setUp, tearDown
+      >>> setUp()
+
+    Before we can make security declarations through ZCML, we need to
+    register the directive and the permission:
+
+      >>> import AccessControl
+      >>> from zope.configuration.xmlconfig import XMLConfig
+      >>> XMLConfig('meta.zcml', AccessControl)()
+      >>> import Products.Five.browser
+      >>> XMLConfig('meta.zcml', Products.Five.browser)()
+      >>> XMLConfig('permissions.zcml', AccessControl)()
+
+    Now we provide some ZCML declarations for ``Dummy1``:
+
+      >>> from StringIO import StringIO
+      >>> configure_zcml = StringIO('''
+      ... <configure xmlns="http://namespaces.zope.org/zope"
+      ...            xmlns:browser="http://namespaces.zope.org/browser">
+      ...   <browser:page
+      ...       for="*"
+      ...       name="testview"
+      ...       permission="zope2.ViewManagementScreens"
+      ...       class="AccessControl.tests.testZCML.Dummy1"
+      ...       allowed_interface="AccessControl.tests.testZCML.IDummy" />
+      ... </configure>
+      ... ''')
+      >>> from zope.configuration.xmlconfig import xmlconfig
+      >>> xmlconfig(configure_zcml)
+
+    We are going to check that roles are correctly setup, so we need getRoles.
+
+      >>> from AccessControl.ZopeSecurityPolicy import getRoles
+      >>> from AccessControl import ACCESS_PRIVATE
+
+    Due to the nasty voodoo involved in Five's handling of view classes,
+    browser:page doesn't apply security to Dummy1, but rather to the "magic"
+    view class that is created at ZCML parse time.  That means we can't just
+    instanciate with Dummy1() directly and expect a security-aware instance :(.
+    Instead, we'll have to actually lookup the view.  The view was declared for
+    "*", so we just use an instance of Dummy1 ;-).
+
+    Instanciate a Dummy1 object to test with.
+
+      >>> from AccessControl.tests.testZCML import Dummy1
+      >>> dummy1 = Dummy1()
+      >>> from zope.component import getMultiAdapter
+      >>> from zope.publisher.browser import TestRequest
+      >>> request = TestRequest()
+      >>> view = getMultiAdapter((dummy1, request), name="testview")
+
+    As 'foo' is defined in IDummy, it should have the 'Manager' role.
+
+      >>> getRoles(view, 'foo', view.foo, ('Def',))
+      ('Manager',)
+
+    As 'wot' is not defined in IDummy, it should be private.
+
+      >>> getRoles(view, 'wot', view.wot, ('Def',)) is ACCESS_PRIVATE
+      True
+
+    But 'superMethod' is defined on IDummy by inheritance from ISuperDummy, and
+    so should have the 'Manager' role setup.
+
+      >>> getRoles(view, 'superMethod', view.superMethod, ('Def',))
+      ('Manager',)
+
+      >>> tearDown()
+    """
+
 def test_suite():
     from Testing.ZopeTestCase import FunctionalDocTestSuite
     from zope.testing.doctest import ELLIPSIS

Modified: Zope/trunk/src/Products/Five/browser/tests/zope3security.py
===================================================================
--- Zope/trunk/src/Products/Five/browser/tests/zope3security.py	2009-12-31 20:40:13 UTC (rev 107478)
+++ Zope/trunk/src/Products/Five/browser/tests/zope3security.py	2009-12-31 21:41:57 UTC (rev 107479)
@@ -1,4 +1,4 @@
-from Products.Five import BrowserView
+from zope.publisher.browser import BrowserView
 from zope.security.management import checkPermission
 
 class Zope3SecurityView(BrowserView):

Modified: Zope/trunk/src/Products/Five/meta.zcml
===================================================================
--- Zope/trunk/src/Products/Five/meta.zcml	2009-12-31 20:40:13 UTC (rev 107478)
+++ Zope/trunk/src/Products/Five/meta.zcml	2009-12-31 21:41:57 UTC (rev 107479)
@@ -2,8 +2,8 @@
     xmlns="http://namespaces.zope.org/zope"
     xmlns:meta="http://namespaces.zope.org/meta">
 
+  <include package="AccessControl" file="meta.zcml" />
   <include package="zope.component" file="meta.zcml" />
-  <include package="zope.security" file="meta.zcml" />
   <include package="zope.i18n" file="meta.zcml" />
 
   <include package=".browser" file="meta.zcml" />
@@ -17,35 +17,6 @@
         handler="zope.component.zcml.view"
         />
 
-    <meta:complexDirective
-        name="class"
-        schema="zope.security.metadirectives.IClassDirective"
-        handler=".metaconfigure.ClassDirective"
-        >
-
-      <meta:subdirective
-          name="implements"
-          schema="zope.security.metadirectives.IImplementsSubdirective"
-          />
-
-      <meta:subdirective
-          name="require"
-          schema="zope.security.metadirectives.IRequireSubdirective"
-          />
-
-      <meta:subdirective
-          name="allow"
-          schema="zope.security.metadirectives.IAllowSubdirective"
-          />
-
-    </meta:complexDirective>
-
-    <meta:directive
-        name="securityPolicy"
-        schema="zope.security.zcml.ISecurityPolicyDirective"
-        handler="zope.security.zcml.securityPolicy"
-        />
-
   </meta:directives>
 
   <meta:directives namespace="http://namespaces.zope.org/five">

Modified: Zope/trunk/src/Products/Five/metaconfigure.py
===================================================================
--- Zope/trunk/src/Products/Five/metaconfigure.py	2009-12-31 20:40:13 UTC (rev 107478)
+++ Zope/trunk/src/Products/Five/metaconfigure.py	2009-12-31 21:41:57 UTC (rev 107479)
@@ -1,49 +1,2 @@
-##############################################################################
-#
-# Copyright (c) 2004, 2005 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (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.
-#
-##############################################################################
-"""Generic Components ZCML Handlers
-
-$Id$
-"""
-import warnings
-from zope.security import metaconfigure
-from AccessControl.security import protectName
-from App.class_init import InitializeClass
-
-class ClassDirective(metaconfigure.ClassDirective):
-
-    def __protectName(self, name, permission_id):
-        self.__context.action(
-            discriminator = ('five:protectName', self.__class, name),
-            callable = protectName,
-            args = (self.__class, name, permission_id)
-            )
-
-    def __protectSetAttributes(self, names, permission_id):
-        warnings.warn("The set_attribute option of the <require /> directive is not supported in Zope 2. " + \
-                      "Ignored for %s" % str(self.__class), stacklevel=3)
-
-    def __protectSetSchema(self, schema, permission):
-        warnings.warn("The set_schema option of the <require /> directive is not supported in Zope 2. " + \
-                      "Ignored for %s" % str(self.__class), stacklevel=3)
-
-    def __mimic(self, _context, class_):
-        warnings.warn("The like_class option of the <require /> directive is not supported in Zope 2. " + \
-                      "Ignored for %s" % str(self.__class), stacklevel=3)
-
-    def __call__(self):
-        return self.__context.action(
-            discriminator = None,
-            callable = InitializeClass,
-            args = (self.__class,)
-            )
+# BBB
+from AccessControl.metaconfigure import ClassDirective

Deleted: Zope/trunk/src/Products/Five/tests/test_security.py
===================================================================
--- Zope/trunk/src/Products/Five/tests/test_security.py	2009-12-31 20:40:13 UTC (rev 107478)
+++ Zope/trunk/src/Products/Five/tests/test_security.py	2009-12-31 21:41:57 UTC (rev 107479)
@@ -1,445 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2004, 2005 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (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 security induced by ZCML
-
-$Id$
-"""
-
-from zope.interface import implements
-from zope.interface import Interface
-from zope.schema import TextLine
-from AccessControl.SecurityInfo import ClassSecurityInfo
-
-class ISuperDummy(Interface):
-    """
-    """
-
-    def superMethod():
-        """
-        """
-
-class IDummy(ISuperDummy):
-    """Just a marker interface"""
-
-    def foo():
-        """
-        """
-
-class Dummy1:
-    implements(IDummy)
-    def foo(self): pass
-    def bar(self): pass
-    def baz(self): pass
-    def keg(self): pass
-    def wot(self): pass
-    def superMethod(self): pass
-
-class Dummy2(Dummy1):
-    security = ClassSecurityInfo()
-    security.declarePublic('foo')
-    security.declareProtected('View management screens', 'bar')
-    security.declarePrivate('baz')
-    security.declareProtected('View management screens', 'keg')
-
-class IDummy3(Interface):
-    attr = TextLine(title=u"Attribute")
-
-class Dummy3:
-    implements(IDummy3)
-    attr = None
-
-class Dummy4:
-    foo = None
-
-def test_security_equivalence():
-    """This test demonstrates that the traditional declarative security of
-    Zope 2 can be replaced by ZCML statements without any loss of
-    information.
-
-      >>> from zope.component.testing import setUp, tearDown
-      >>> setUp()
-
-    We start out with two classes, ``Dummy1`` and ``Dummy2``.  They
-    are identical in every way, except that ``Dummy2`` has security
-    declarations and ``Dummy1`` does not.  Before we do anything, none
-    of them have security access controls:
-
-      >>> from Products.Five.tests.test_security import Dummy1, Dummy2
-      >>> hasattr(Dummy1, '__ac_permissions__')
-      False
-      >>> hasattr(Dummy2, '__ac_permissions__')
-      False
-
-    Before we can make security declarations through ZCML, we need to
-    register the directive and the permission:
-
-      >>> import Products.Five
-      >>> from Products.Five import zcml
-      >>> zcml.load_config('meta.zcml', Products.Five)
-      >>> zcml.load_config('permissions.zcml', Products.Five)
-
-    Now we initialize the security for ``Dummy2`` and provide some
-    ZCML declarations for ``Dummy1``:
-
-      >>> configure_zcml = '''
-      ... <configure xmlns="http://namespaces.zope.org/zope">
-      ...   <class class="Products.Five.tests.test_security.Dummy1">
-      ...     <allow attributes="foo" />
-      ...     <!--deny attributes="baz" /--> <!-- XXX not yet supported -->
-      ...   </class>
-      ...   <class class="Products.Five.tests.test_security.Dummy1">
-      ...     <require attributes="bar keg"
-      ...              permission="zope2.ViewManagementScreens"
-      ...              />
-      ...   </class>
-      ... </configure>
-      ... '''
-      >>> zcml.load_string(configure_zcml)
-
-      >>> from App.class_init import InitializeClass
-      >>> InitializeClass(Dummy2)
-
-    Now we compare their access controls:
-
-      >>> ac1 = getattr(Dummy1, '__ac_permissions__')
-      >>> ac2 = getattr(Dummy2, '__ac_permissions__')
-      >>> ac1 == ac2
-      True
-
-    Now we look at the individual permissions:
-
-      >>> from AccessControl.ZopeSecurityPolicy import getRoles
-      >>> from AccessControl import ACCESS_PUBLIC
-      >>> from AccessControl import ACCESS_PRIVATE
-
-      >>> dummy1 = Dummy1()
-      >>> getRoles(dummy1, 'bar', dummy1.bar, ('Def',))
-      ('Manager',)
-
-      >>> getRoles(dummy1, 'keg', dummy1.keg, ('Def',))
-      ('Manager',)
-
-      >>> getRoles(dummy1, 'foo', dummy1.foo, ('Def',)) is ACCESS_PUBLIC
-      True
-
-      #>>> getRoles(dummy1, 'baz', dummy1.baz, ('Def',)) is ACCESS_PRIVATE
-      #True XXX Not yet supported.
-
-      >>> dummy2 = Dummy2()
-      >>> getRoles(dummy2, 'bar', dummy2.bar, ('Def',))
-      ('Manager',)
-
-      >>> getRoles(dummy2, 'keg', dummy2.keg, ('Def',))
-      ('Manager',)
-
-      >>> getRoles(dummy2, 'foo', dummy2.foo, ('Def',)) is ACCESS_PUBLIC
-      True
-
-      >>> getRoles(dummy2, 'baz', dummy2.baz, ('Def',)) is ACCESS_PRIVATE
-      True
-
-    Before we end we should clean up after ourselves:
-
-      >>> from AccessControl.security import clearSecurityInfo
-      >>> clearSecurityInfo(Dummy1)
-      >>> clearSecurityInfo(Dummy2)
-
-      >>> tearDown()
-    """
-
-def test_allowed_interface():
-    """This test demonstrates that allowed_interface security declarations work
-    as expected.
-
-      >>> from zope.component.testing import setUp, tearDown
-      >>> setUp()
-
-    Before we can make security declarations through ZCML, we need to
-    register the directive and the permission:
-
-      >>> import Products.Five
-      >>> from Products.Five import zcml
-      >>> zcml.load_config('meta.zcml', Products.Five)
-      >>> import Products.Five.browser
-      >>> zcml.load_config('meta.zcml', Products.Five.browser)
-      >>> zcml.load_config('permissions.zcml', Products.Five)
-
-    Now we provide some ZCML declarations for ``Dummy1``:
-
-      >>> configure_zcml = '''
-      ... <configure xmlns="http://namespaces.zope.org/zope"
-      ...            xmlns:browser="http://namespaces.zope.org/browser">
-      ...   <browser:page
-      ...       for="*"
-      ...       name="testview"
-      ...       permission="zope2.ViewManagementScreens"
-      ...       class="Products.Five.tests.test_security.Dummy1"
-      ...       allowed_interface="Products.Five.tests.test_security.IDummy" />
-      ... </configure>
-      ... '''
-      >>> zcml.load_string(configure_zcml)
-
-    We are going to check that roles are correctly setup, so we need getRoles.
-
-      >>> from AccessControl.ZopeSecurityPolicy import getRoles
-      >>> from AccessControl import ACCESS_PRIVATE
-
-    Due to the nasty voodoo involved in Five's handling of view classes,
-    browser:page doesn't apply security to Dummy1, but rather to the "magic"
-    view class that is created at ZCML parse time.  That means we can't just
-    instanciate with Dummy1() directly and expect a security-aware instance :(.
-    Instead, we'll have to actually lookup the view.  The view was declared for
-    "*", so we just use an instance of Dummy1 ;-).
-
-    Instanciate a Dummy1 object to test with.
-
-      >>> from Products.Five.tests.test_security import Dummy1
-      >>> dummy1 = Dummy1()
-      >>> from zope.component import getMultiAdapter
-      >>> from zope.publisher.browser import TestRequest
-      >>> request = TestRequest()
-      >>> view = getMultiAdapter((dummy1, request), name="testview")
-
-    As 'foo' is defined in IDummy, it should have the 'Manager' role.
-
-      >>> getRoles(view, 'foo', view.foo, ('Def',))
-      ('Manager',)
-
-    As 'wot' is not defined in IDummy, it should be private.
-
-      >>> getRoles(view, 'wot', view.wot, ('Def',)) is ACCESS_PRIVATE
-      True
-
-    But 'superMethod' is defined on IDummy by inheritance from ISuperDummy, and
-    so should have the 'Manager' role setup.
-
-      >>> getRoles(view, 'superMethod', view.superMethod, ('Def',))
-      ('Manager',)
-
-      >>> tearDown()
-    """
-
-def test_set_warnings():
-    """This test demonstrates that set_attributes and set_schema will result
-    in warnings, not errors. This type of protection doesn't make sense in
-    Zope 2, but we want to be able to re-use pure Zope 3 packages that use
-    them without error.
-
-      >>> from zope.component.testing import setUp, tearDown
-      >>> setUp()
-
-    Before we can make security declarations through ZCML, we need to
-    register the directive and the permission:
-
-      >>> import Products.Five
-      >>> from Products.Five import zcml
-      >>> zcml.load_config('meta.zcml', Products.Five)
-      >>> zcml.load_config('permissions.zcml', Products.Five)
-
-    Now we provide some ZCML declarations for ``Dummy1``:
-
-      >>> configure_zcml = '''
-      ... <configure xmlns="http://namespaces.zope.org/zope">
-      ...
-      ...   <class class="Products.Five.tests.test_security.Dummy3">
-      ...       <require
-      ...           permission="zope2.View"
-      ...           interface="Products.Five.tests.test_security.IDummy3"
-      ...           />
-      ...       <require
-      ...           permission="cmf.ModifyPortalContent"
-      ...           set_schema="Products.Five.tests.test_security.IDummy3"
-      ...           />
-      ...   </class>
-      ...
-      ...   <class class="Products.Five.tests.test_security.Dummy4">
-      ...       <require
-      ...           permission="cmf.ModifyPortalContent"
-      ...           set_attributes="foo"
-      ...           />
-      ...   </class>
-      ...
-      ... </configure>
-      ... '''
-      
-      Running this should not throw an exception (but will print a warning to
-      stderr)
-      
-      >>> zcml.load_string(configure_zcml)
-      >>> tearDown()
-    """
-
-def test_checkPermission():
-    """
-    Test checkPermission
-
-      >>> from zope.component.testing import setUp, tearDown
-      >>> setUp()
-
-    Zope 3 has a function zope.security.checkPermission which provides
-    an easy way of checking whether the currently authenticated user
-    has the permission to access an object.  The function delegates to
-    the security policy's checkPermission() method.
-
-    Zope2 has the same function, AccessControl.security.checkPermission,
-    but in a Zope2-compatible implementation.  It too uses the currently
-    active security policy of Zope 2 for the actual permission
-    checking.
-
-      >>> import Products.Five
-      >>> from Products.Five import zcml
-      >>> zcml.load_config('meta.zcml', Products.Five)
-      >>> zcml.load_config('permissions.zcml', Products.Five)
-
-    In the following we want to test Five's checkPermission function.
-    We do that by taking the test's folder and asserting several
-    standard permissions.  What we want to assure is that
-    checkPermission translates the Zope 2 permissions correctly,
-    especially the edge cases:
-
-    a) zope2.Public (which should always be available to everyone)
-
-      >>> from AccessControl.security import checkPermission
-      >>> checkPermission('zope2.Public', self.folder)
-      True
-
-    b) zope2.Private (which should never available to anyone)
-
-      >>> checkPermission('zope.Private', self.folder)
-      False
-      >>> checkPermission('zope2.Private', self.folder)
-      False
-
-    Any other standard Zope 2 permission will also resolve correctly:
-
-      >>> checkPermission('zope2.AccessContentsInformation', self.folder)
-      True
-
-    Invalid permissions will obviously result in a negative response:
-
-      >>> checkPermission('notapermission', self.folder)
-      False
-
-
-    In addition to using Five's ``checkPermission`` function directly,
-    we also expect the same behaviour when we use Zope 3's
-    zope.security.checkPermission function.  Code from within Zope 3
-    will use that and therefore it should work transparently.  For
-    that to work, a new Five "interaction" needs to be started (the
-    old one from placelesssetup needs to be ended first):
-
-      >>> from zope.security.management import endInteraction
-      >>> endInteraction()
-
-      >>> from AccessControl.security import newInteraction
-      >>> newInteraction()
-
-    a) zope2.Public (which should always be available to everyone)
-
-      >>> from zope.security import checkPermission
-      >>> checkPermission('zope2.Public', self.folder)
-      True
-
-    b) zope2.Private (which should never available to anyone)
-
-      >>> checkPermission('zope.Private', self.folder)
-      False
-      >>> checkPermission('zope2.Private', self.folder)
-      False
-
-    Any other standard Zope 2 permission will also resolve correctly:
-
-      >>> checkPermission('zope2.AccessContentsInformation', self.folder)
-      True
-
-    Invalid permissions will obviously result in a negative response:
-
-      >>> checkPermission('notapermission', self.folder)
-      False
-
-
-    Clean up:
-
-      >>> tearDown()
-    """
-
-def test_register_permission():
-    """This test demonstrates that if the <permission /> directive is used
-    to create a permission that does not already exist, it is created on 
-    startup, with roles defaulting to Manager.
-
-      >>> from Testing.ZopeTestCase.placeless import setUp, tearDown
-      >>> setUp()
-
-    First, we need to configure the relevant parts of Five.
-
-      >>> import Products.Five
-      >>> from Products.Five import zcml
-      >>> zcml.load_config('meta.zcml', Products.Five)
-      >>> zcml.load_config('permissions.zcml', Products.Five)
-
-    We can now register a permission in ZCML:
-
-      >>> configure_zcml = '''
-      ... <configure xmlns="http://namespaces.zope.org/zope"
-      ...            i18n_domain="fivetest">
-      ...
-      ...   <permission
-      ...       id="Products.Five.tests.DummyPermission"
-      ...       title="Five: Dummy permission"
-      ...       />
-      ...
-      ... </configure>
-      ... '''
-      >>> zcml.load_string(configure_zcml)
-      
-    The permission will be made available globally, with default role set
-    of ('Manager',).
-      
-      >>> roles = self.app.rolesOfPermission('Five: Dummy permission')
-      >>> sorted(r['name'] for r in roles if r['selected'])
-      ['Manager']
-
-    Let's also ensure that permissions are not overwritten if they exist
-    already:
-      
-      >>> from AccessControl.Permission import _registeredPermissions
-      >>> import Products
-      >>> _registeredPermissions['Five: Other dummy'] = 1
-      >>> Products.__ac_permissions__ += (('Five: Other dummy', (), (),),)
-      >>> self.app.manage_permission('Five: Other dummy', roles=['Anonymous'])
-
-      >>> configure_zcml = '''
-      ... <configure xmlns="http://namespaces.zope.org/zope"
-      ...            i18n_domain="fivetest">
-      ...
-      ...   <permission
-      ...       id="Products.Five.tests.OtherDummy"
-      ...       title="Five: Other dummy"
-      ...       />
-      ...
-      ... </configure>
-      ... '''
-      >>> zcml.load_string(configure_zcml)
-
-      >>> roles = self.app.rolesOfPermission('Five: Other dummy')
-      >>> sorted(r['name'] for r in roles if r['selected'])
-      ['Anonymous']
-
-      >>> tearDown()
-    """
-
-def test_suite():
-    from Testing.ZopeTestCase import ZopeDocTestSuite
-    return ZopeDocTestSuite()



More information about the Zope-Checkins mailing list