Log message for revision 102404: Moved ``Products/Five/security.py`` into the AccessControl package.
Changed: U Zope/trunk/doc/CHANGES.rst U Zope/trunk/src/AccessControl/permissions.zcml A Zope/trunk/src/AccessControl/security.py U Zope/trunk/src/Products/Five/browser/metaconfigure.py U Zope/trunk/src/Products/Five/browser/tests/test_menu.py U Zope/trunk/src/Products/Five/browser/tests/test_zope3security.py U Zope/trunk/src/Products/Five/form/metaconfigure.py U Zope/trunk/src/Products/Five/metaconfigure.py U Zope/trunk/src/Products/Five/permissions.zcml U Zope/trunk/src/Products/Five/security.py U Zope/trunk/src/Products/Five/tests/test_security.py U Zope/trunk/src/Products/Five/viewlet/metaconfigure.py U Zope/trunk/src/Testing/ZopeTestCase/placeless.py U Zope/trunk/src/Zope2/utilities/skel/etc/site.zcml -=- Modified: Zope/trunk/doc/CHANGES.rst =================================================================== --- Zope/trunk/doc/CHANGES.rst 2009-07-30 20:17:45 UTC (rev 102403) +++ Zope/trunk/doc/CHANGES.rst 2009-07-30 20:25:28 UTC (rev 102404) @@ -11,6 +11,8 @@ Restructuring +++++++++++++ +- Moved ``Products/Five/security.py`` into the AccessControl package. + - Moved ``Products/Five/traversing.zcml`` directly into the configure.zcml. - Moved zope.security-style permission registrations from Products.Five into Modified: Zope/trunk/src/AccessControl/permissions.zcml =================================================================== --- Zope/trunk/src/AccessControl/permissions.zcml 2009-07-30 20:17:45 UTC (rev 102403) +++ Zope/trunk/src/AccessControl/permissions.zcml 2009-07-30 20:25:28 UTC (rev 102404) @@ -1,6 +1,13 @@ <configure xmlns="http://namespaces.zope.org/zope" i18n_domain="Zope2"> + <!-- Create permissions declared in ZCML if they don't exist already --> + <subscriber + for="zope.security.interfaces.IPermission + zope.component.interfaces.IRegistered" + handler=".security.create_permission_from_permission_directive" + /> + <permission id="zope2.Public" title="Public, everyone can access" Copied: Zope/trunk/src/AccessControl/security.py (from rev 102379, Zope/trunk/src/Products/Five/security.py) =================================================================== --- Zope/trunk/src/AccessControl/security.py (rev 0) +++ Zope/trunk/src/AccessControl/security.py 2009-07-30 20:25:28 UTC (rev 102404) @@ -0,0 +1,175 @@ +############################################################################## +# +# Copyright (c) 2004-2009 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. +# +############################################################################## +"""Security handling +""" + +from zope.component import getUtility +from zope.component import queryUtility +from zope.interface import classProvides +from zope.interface import implements +from zope.security.checker import CheckerPublic +from zope.security.interfaces import IInteraction +from zope.security.interfaces import ISecurityPolicy +from zope.security.interfaces import IPermission +from zope.security.management import thread_local +from zope.security.simplepolicies import ParanoidSecurityPolicy + +from AccessControl.SecurityInfo import ClassSecurityInfo +from AccessControl.SecurityManagement import getSecurityManager +from AccessControl.Permission import _registeredPermissions +from AccessControl.Permission import pname + +import Products + +from AccessControl.Permission import ApplicationDefaultPermissions + +CheckerPublicId = 'zope.Public' +CheckerPrivateId = 'zope2.Private' + +def getSecurityInfo(klass): + sec = {} + info = vars(klass) + if info.has_key('__ac_permissions__'): + sec['__ac_permissions__'] = info['__ac_permissions__'] + for k, v in info.items(): + if k.endswith('__roles__'): + sec[k] = v + return sec + +def clearSecurityInfo(klass): + sec = {} + info = vars(klass) + if info.has_key('__ac_permissions__'): + delattr(klass, '__ac_permissions__') + for k, v in info.items(): + if k.endswith('__roles__'): + delattr(klass, k) + +def checkPermission(permission, object, interaction=None): + """Return whether security policy allows permission on object. + + Arguments: + permission -- A permission name + object -- The object being accessed according to the permission + interaction -- This zope.security concept has no equivalent in Zope 2, + and is ignored. + + checkPermission is guaranteed to return True if permission is + CheckerPublic or None. + """ + if (permission in ('zope.Public', 'zope2.Public') or + permission is None or permission is CheckerPublic): + return True + + if isinstance(permission, basestring): + permission = queryUtility(IPermission, unicode(permission)) + if permission is None: + return False + + if getSecurityManager().checkPermission(permission.title, object): + return True + + return False + +class SecurityPolicy(ParanoidSecurityPolicy): + """Security policy that bridges between zope.security security mechanisms + and Zope 2's security policy. + + Don't let the name of the base class fool you... This really just + delegates to Zope 2's security manager.""" + classProvides(ISecurityPolicy) + implements(IInteraction) + + def checkPermission(self, permission, object): + return checkPermission(permission, object) + +def newInteraction(): + """Con zope.security to use Zope 2's checkPermission. + + zope.security when it does a checkPermission will turn around and + ask the thread local interaction for the checkPermission method. + By making the interaction *be* Zope 2's security manager, we can + con zope.security into using Zope 2's checker... + """ + if getattr(thread_local, 'interaction', None) is None: + thread_local.interaction = SecurityPolicy() + +def _getSecurity(klass): + # a Zope 2 class can contain some attribute that is an instance + # of ClassSecurityInfo. Zope 2 scans through things looking for + # an attribute that has the name __security_info__ first + info = vars(klass) + for k, v in info.items(): + if hasattr(v, '__security_info__'): + return v + # we stuff the name ourselves as __security__, not security, as this + # could theoretically lead to name clashes, and doesn't matter for + # zope 2 anyway. + security = ClassSecurityInfo() + setattr(klass, '__security__', security) + return security + +def protectName(klass, name, permission_id): + """Protect the attribute 'name' on 'klass' using the given + permission""" + security = _getSecurity(klass) + # Zope 2 uses string, not unicode yet + name = str(name) + if permission_id == CheckerPublicId or permission_id is CheckerPublic: + # Sometimes, we already get a processed permission id, which + # can mean that 'zope.Public' has been interchanged for the + # CheckerPublic object + security.declarePublic(name) + elif permission_id == CheckerPrivateId: + security.declarePrivate(name) + else: + permission = getUtility(IPermission, name=permission_id) + # Zope 2 uses string, not unicode yet + perm = str(permission.title) + security.declareProtected(perm, name) + +def protectClass(klass, permission_id): + """Protect the whole class with the given permission""" + security = _getSecurity(klass) + if permission_id == CheckerPublicId or permission_id is CheckerPublic: + # Sometimes, we already get a processed permission id, which + # can mean that 'zope.Public' has been interchanged for the + # CheckerPublic object + security.declareObjectPublic() + elif permission_id == CheckerPrivateId: + security.declareObjectPrivate() + else: + permission = getUtility(IPermission, name=permission_id) + # Zope 2 uses string, not unicode yet + perm = str(permission.title) + security.declareObjectProtected(perm) + +def create_permission_from_permission_directive(permission, event): + """When a new IPermission utility is registered (via the <permission /> + directive), create the equivalent Zope2 style permission. + """ + + global _registeredPermissions + + # Zope 2 uses string, not unicode yet + zope2_permission = str(permission.title) + roles = ('Manager',) + + if not _registeredPermissions.has_key(zope2_permission): + _registeredPermissions[zope2_permission] = 1 + + Products.__ac_permissions__ += ((zope2_permission, (), roles,),) + + mangled = pname(zope2_permission) + setattr(ApplicationDefaultPermissions, mangled, roles) Modified: Zope/trunk/src/Products/Five/browser/metaconfigure.py =================================================================== --- Zope/trunk/src/Products/Five/browser/metaconfigure.py 2009-07-30 20:17:45 UTC (rev 102403) +++ Zope/trunk/src/Products/Five/browser/metaconfigure.py 2009-07-30 20:25:28 UTC (rev 102404) @@ -37,6 +37,12 @@ from zope.app.publisher.browser.viewmeta import _handle_menu from zope.app.publisher.browser.viewmeta import _handle_for +from AccessControl.security import getSecurityInfo +from AccessControl.security import protectClass +from AccessControl.security import protectName +from AccessControl.security import CheckerPrivateId +from App.class_init import InitializeClass + from Products.Five.browser import BrowserView from Products.Five.browser.resource import FileResourceFactory from Products.Five.browser.resource import ImageResourceFactory @@ -44,12 +50,7 @@ from Products.Five.browser.resource import DirectoryResourceFactory from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile from Products.Five.metaclass import makeClass -from Products.Five.security import getSecurityInfo -from Products.Five.security import protectClass -from Products.Five.security import protectName -from Products.Five.security import CheckerPrivateId -from App.class_init import InitializeClass def page(_context, name, permission, for_, layer=IDefaultBrowserLayer, template=None, class_=None, Modified: Zope/trunk/src/Products/Five/browser/tests/test_menu.py =================================================================== --- Zope/trunk/src/Products/Five/browser/tests/test_menu.py 2009-07-30 20:17:45 UTC (rev 102403) +++ Zope/trunk/src/Products/Five/browser/tests/test_menu.py 2009-07-30 20:25:28 UTC (rev 102404) @@ -30,7 +30,7 @@ >>> zcml.load_config("permissions.zcml", AccessControl) >>> zcml.load_config('menu.zcml', package=Products.Five.browser.tests) - >>> from Products.Five.security import newInteraction + >>> from AccessControl.security import newInteraction >>> newInteraction() Now for some actual testing... Let's look up the menu we registered: Modified: Zope/trunk/src/Products/Five/browser/tests/test_zope3security.py =================================================================== --- Zope/trunk/src/Products/Five/browser/tests/test_zope3security.py 2009-07-30 20:17:45 UTC (rev 102403) +++ Zope/trunk/src/Products/Five/browser/tests/test_zope3security.py 2009-07-30 20:25:28 UTC (rev 102404) @@ -11,7 +11,7 @@ ... xmlns="http://namespaces.zope.org/zope" ... xmlns:browser="http://namespaces.zope.org/browser"> ... <securityPolicy - ... component="Products.Five.security.FiveSecurityPolicy" /> + ... component="AccessControl.security.SecurityPolicy" /> ... <configure package="Products.Five.browser.tests"> ... <browser:page ... for="OFS.interfaces.IFolder" Modified: Zope/trunk/src/Products/Five/form/metaconfigure.py =================================================================== --- Zope/trunk/src/Products/Five/form/metaconfigure.py 2009-07-30 20:17:45 UTC (rev 102403) +++ Zope/trunk/src/Products/Five/form/metaconfigure.py 2009-07-30 20:25:28 UTC (rev 102404) @@ -26,10 +26,12 @@ from zope.app.publisher.browser.menumeta import menuItemDirective from zope.app.form.browser.metaconfigure import BaseFormDirective from zope.browser.interfaces import IAdding +from zope.publisher.interfaces.browser import IDefaultBrowserLayer +from AccessControl.security import protectClass + from Products.Five.form import EditView, AddView from Products.Five.metaclass import makeClass -from Products.Five.security import protectClass from Products.Five.browser.pagetemplatefile import ZopeTwoPageTemplateFile from Products.Five.browser.metaconfigure import makeClassForTemplate Modified: Zope/trunk/src/Products/Five/metaconfigure.py =================================================================== --- Zope/trunk/src/Products/Five/metaconfigure.py 2009-07-30 20:17:45 UTC (rev 102403) +++ Zope/trunk/src/Products/Five/metaconfigure.py 2009-07-30 20:25:28 UTC (rev 102404) @@ -17,8 +17,8 @@ """ import warnings from zope.security import metaconfigure +from AccessControl.security import protectName from App.class_init import InitializeClass -from Products.Five.security import protectName class ClassDirective(metaconfigure.ClassDirective): Modified: Zope/trunk/src/Products/Five/permissions.zcml =================================================================== --- Zope/trunk/src/Products/Five/permissions.zcml 2009-07-30 20:17:45 UTC (rev 102403) +++ Zope/trunk/src/Products/Five/permissions.zcml 2009-07-30 20:25:28 UTC (rev 102404) @@ -1,20 +1,13 @@ <configure xmlns="http://namespaces.zope.org/zope" i18n_domain="Five"> - <!-- Create permissions declared in ZCML if they don't exist already --> - <subscriber - for="zope.security.interfaces.IPermission - zope.component.interfaces.IRegistered" - handler=".security.create_permission_from_permission_directive" - /> + <include package="AccessControl" file="permissions.zcml" /> <permission id="five.ManageSite" title="Manage Five local sites" /> - <include package="AccessControl" file="permissions.zcml" /> - <!-- CMF Core Permissions --> <permission Modified: Zope/trunk/src/Products/Five/security.py =================================================================== --- Zope/trunk/src/Products/Five/security.py 2009-07-30 20:17:45 UTC (rev 102403) +++ Zope/trunk/src/Products/Five/security.py 2009-07-30 20:25:28 UTC (rev 102404) @@ -18,165 +18,20 @@ from zope.deferredimport import deprecated deprecated("Please import InitializeClass from App.class_init", - initializeClass = 'App.class_init:InitializeClass', - ) + initializeClass = 'App.class_init:InitializeClass', +) -from zope.component import getUtility -from zope.component import queryUtility -from zope.interface import classProvides -from zope.interface import implements -from zope.security.checker import CheckerPublic -from zope.security.interfaces import IInteraction -from zope.security.interfaces import ISecurityPolicy -from zope.security.interfaces import IPermission -from zope.security.management import thread_local -from zope.security.simplepolicies import ParanoidSecurityPolicy - -from AccessControl.SecurityInfo import ClassSecurityInfo -from AccessControl.SecurityManagement import getSecurityManager -from AccessControl.Permission import _registeredPermissions -from AccessControl.Permission import pname - -import Products - -from AccessControl.Permission import ApplicationDefaultPermissions - -CheckerPublicId = 'zope.Public' -CheckerPrivateId = 'zope2.Private' - -def getSecurityInfo(klass): - sec = {} - info = vars(klass) - if info.has_key('__ac_permissions__'): - sec['__ac_permissions__'] = info['__ac_permissions__'] - for k, v in info.items(): - if k.endswith('__roles__'): - sec[k] = v - return sec - -def clearSecurityInfo(klass): - sec = {} - info = vars(klass) - if info.has_key('__ac_permissions__'): - delattr(klass, '__ac_permissions__') - for k, v in info.items(): - if k.endswith('__roles__'): - delattr(klass, k) - -def checkPermission(permission, object, interaction=None): - """Return whether security policy allows permission on object. - - Arguments: - permission -- A permission name - object -- The object being accessed according to the permission - interaction -- This Zope 3 concept has no equivalent in Zope 2, - and is ignored. - - checkPermission is guaranteed to return True if permission is - CheckerPublic or None. - """ - if (permission in ('zope.Public', 'zope2.Public') or - permission is None or permission is CheckerPublic): - return True - - if isinstance(permission, basestring): - permission = queryUtility(IPermission, unicode(permission)) - if permission is None: - return False - - if getSecurityManager().checkPermission(permission.title, object): - return True - - return False - -class FiveSecurityPolicy(ParanoidSecurityPolicy): - """Security policy that bridges between Zope 3 security mechanisms and - Zope 2's security policy. - - Don't let the name of the base class fool you... This really just - delegates to Zope 2's security manager.""" - classProvides(ISecurityPolicy) - implements(IInteraction) - - def checkPermission(self, permission, object): - return checkPermission(permission, object) - -def newInteraction(): - """Con Zope 3 to use Zope 2's checkPermission. - - Zope 3 when it does a checkPermission will turn around and - ask the thread local interaction for the checkPermission method. - By making the interaction *be* Zope 2's security manager, we can - con Zope 3 into using Zope 2's checker... - """ - if getattr(thread_local, 'interaction', None) is None: - thread_local.interaction = FiveSecurityPolicy() - -def _getSecurity(klass): - # a Zope 2 class can contain some attribute that is an instance - # of ClassSecurityInfo. Zope 2 scans through things looking for - # an attribute that has the name __security_info__ first - info = vars(klass) - for k, v in info.items(): - if hasattr(v, '__security_info__'): - return v - # we stuff the name ourselves as __security__, not security, as this - # could theoretically lead to name clashes, and doesn't matter for - # zope 2 anyway. - security = ClassSecurityInfo() - setattr(klass, '__security__', security) - return security - -def protectName(klass, name, permission_id): - """Protect the attribute 'name' on 'klass' using the given - permission""" - security = _getSecurity(klass) - # Zope 2 uses string, not unicode yet - name = str(name) - if permission_id == CheckerPublicId or permission_id is CheckerPublic: - # Sometimes, we already get a processed permission id, which - # can mean that 'zope.Public' has been interchanged for the - # CheckerPublic object - security.declarePublic(name) - elif permission_id == CheckerPrivateId: - security.declarePrivate(name) - else: - permission = getUtility(IPermission, name=permission_id) - # Zope 2 uses string, not unicode yet - perm = str(permission.title) - security.declareProtected(perm, name) - -def protectClass(klass, permission_id): - """Protect the whole class with the given permission""" - security = _getSecurity(klass) - if permission_id == CheckerPublicId or permission_id is CheckerPublic: - # Sometimes, we already get a processed permission id, which - # can mean that 'zope.Public' has been interchanged for the - # CheckerPublic object - security.declareObjectPublic() - elif permission_id == CheckerPrivateId: - security.declareObjectPrivate() - else: - permission = getUtility(IPermission, name=permission_id) - # Zope 2 uses string, not unicode yet - perm = str(permission.title) - security.declareObjectProtected(perm) - -def create_permission_from_permission_directive(permission, event): - """When a new IPermission utility is registered (via the <permission /> - directive), create the equivalent Zope2 style permission. - """ - - global _registeredPermissions - - # Zope 2 uses string, not unicode yet - zope2_permission = str(permission.title) - roles = ('Manager',) - - if not _registeredPermissions.has_key(zope2_permission): - _registeredPermissions[zope2_permission] = 1 - - Products.__ac_permissions__ += ((zope2_permission, (), roles,),) - - mangled = pname(zope2_permission) - setattr(ApplicationDefaultPermissions, mangled, roles) +deprecated("Please import from AccessControl.security", + CheckerPublicId = 'AccessControl.security:CheckerPublicId', + CheckerPrivateId = 'AccessControl.security:CheckerPrivateId', + getSecurityInfo = 'AccessControl.security:getSecurityInfo', + clearSecurityInfo = 'AccessControl.security:clearSecurityInfo', + checkPermission = 'AccessControl.security:checkPermission', + FiveSecurityPolicy = 'AccessControl.security:SecurityPolicy', + newInteraction = 'AccessControl.security:newInteraction', + _getSecurity = 'AccessControl.security:_getSecurity', + protectName = 'AccessControl.security:protectName', + protectClass = 'AccessControl.security:protectClass', + create_permission_from_permission_directive = \ + 'AccessControl.security:create_permission_from_permission_directive', +) Modified: Zope/trunk/src/Products/Five/tests/test_security.py =================================================================== --- Zope/trunk/src/Products/Five/tests/test_security.py 2009-07-30 20:17:45 UTC (rev 102403) +++ Zope/trunk/src/Products/Five/tests/test_security.py 2009-07-30 20:25:28 UTC (rev 102404) @@ -151,7 +151,7 @@ Before we end we should clean up after ourselves: - >>> from Products.Five.security import clearSecurityInfo + >>> from AccessControl.security import clearSecurityInfo >>> clearSecurityInfo(Dummy1) >>> clearSecurityInfo(Dummy2) @@ -292,8 +292,8 @@ has the permission to access an object. The function delegates to the security policy's checkPermission() method. - Five has the same function, Five.security.checkPermission, but in - a Zope2-compatible implementation. It too uses the currently + 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. @@ -310,7 +310,7 @@ a) zope2.Public (which should always be available to everyone) - >>> from Products.Five.security import checkPermission + >>> from AccessControl.security import checkPermission >>> checkPermission('zope2.Public', self.folder) True @@ -342,7 +342,7 @@ >>> from zope.security.management import endInteraction >>> endInteraction() - >>> from Products.Five.security import newInteraction + >>> from AccessControl.security import newInteraction >>> newInteraction() a) zope2.Public (which should always be available to everyone) Modified: Zope/trunk/src/Products/Five/viewlet/metaconfigure.py =================================================================== --- Zope/trunk/src/Products/Five/viewlet/metaconfigure.py 2009-07-30 20:17:45 UTC (rev 102403) +++ Zope/trunk/src/Products/Five/viewlet/metaconfigure.py 2009-07-30 20:25:28 UTC (rev 102404) @@ -20,17 +20,15 @@ from zope.app.publisher.browser import viewmeta from zope.component import zcml from zope.configuration.exceptions import ConfigurationError -from zope.interface import classImplements -from zope.interface import implements from zope.interface import Interface from zope.browser.interfaces import IBrowserView from zope.publisher.interfaces.browser import IDefaultBrowserLayer from zope.viewlet import interfaces +from AccessControl.security import protectClass +from AccessControl.security import protectName from App.class_init import InitializeClass -from App.special_dtml import DTMLFile -from Products.Five.security import protectClass -from Products.Five.security import protectName + from Products.Five.viewlet import manager from Products.Five.viewlet import viewlet @@ -157,9 +155,6 @@ new_class = type(class_.__name__, (class_, viewlet.SimpleAttributeViewlet), cdict) - if hasattr(class_, '__implements__'): - classImplements(new_class, IBrowserPublisher) - else: # Create a new class for the viewlet template alone. new_class = viewlet.SimpleViewletClass(template, name=name, Modified: Zope/trunk/src/Testing/ZopeTestCase/placeless.py =================================================================== --- Zope/trunk/src/Testing/ZopeTestCase/placeless.py 2009-07-30 20:17:45 UTC (rev 102403) +++ Zope/trunk/src/Testing/ZopeTestCase/placeless.py 2009-07-30 20:25:28 UTC (rev 102404) @@ -19,8 +19,8 @@ from zope.component.eventtesting import PlacelessSetup as EventPlacelessSetup from zope.container.testing import PlacelessSetup as ContainerPlacelessSetup from zope.i18n.testing import PlacelessSetup as I18nPlacelessSetup -from zope.security.management import newInteraction from zope.security.testing import addCheckerPublic +from AccessControl.security import newInteraction class PlacelessSetup(CAPlacelessSetup, Modified: Zope/trunk/src/Zope2/utilities/skel/etc/site.zcml =================================================================== --- Zope/trunk/src/Zope2/utilities/skel/etc/site.zcml 2009-07-30 20:17:45 UTC (rev 102403) +++ Zope/trunk/src/Zope2/utilities/skel/etc/site.zcml 2009-07-30 20:25:28 UTC (rev 102404) @@ -21,6 +21,6 @@ <securityPolicy - component="Products.Five.security.FiveSecurityPolicy" /> + component="AccessControl.security.SecurityPolicy" /> </configure> _______________________________________________ Zope-Checkins maillist - Zope-Checkins@zope.org http://mail.zope.org/mailman/listinfo/zope-checkins