zope.securitypolicy-3.7.0/000755 000766 000024 00000000000 11447361755 015505 5ustar00macstaff000000 000000 zope.securitypolicy-3.7.0/CHANGES.txt000644 000766 000024 00000005224 11447361751 017315 0ustar00macstaff000000 000000 ======= CHANGES ======= 3.7.0 (2010-09-25) ------------------ - LP #131115: Clean up inconsistency in ``getSetting`` interface definitions and actual usage for the various security maps. - LP #564525: fix permission moved from ``zope.app.dublincore`` namespace to ``zope.dublincore``. - Removed unused imports and pep8 cleanup. - Use doctest module instead of the deprecated zope.testing.doctest. - AnnotationGrantInfo implements IGrantInfo. - Added test extra to declare test dependency on ``zope.component [test]``. - Added an extra named `dublincore` to express optional dependency on `zope.dublincore >= 3.7`. - Added tests for ZCML files making sure they include everything they need. 3.6.1 (2009-07-24) ------------------ - Make tests work when the default and Zope vocabulary registry compete in the cleanup. 3.6.0 (2009-03-14) ------------------ - Change ``zope.app.security`` dependency to the new ``zope.authentication`` package, dropping a big number of unused dependencies. - Get rid of ``zope.app.testing`` and other testing dependencices. - Add ``ZODB3`` to install dependencies, because we use `Persistent` class. We didn't fail before, because it was installed implicitly. 3.5.1 (2009-03-10) ------------------ - Don't depend on the `hook` extra of zope.component, as we don't need it explicitly. - Import security settings (Allow, Deny, Unset) in the ``interfaces`` module from the ``zope.securitypolicy.settings``, added in previous release instead of old ``zope.app.security.settings``. The ``zope.app.security`` will be adapted to import them from ``zope.securitypolicy.interfaces``. - Use `_z_instances` instead of `__instances__` for storing instances for ``zope.securitypolicy.settings.PermissionSetting`` singleton implementation, because __*__ name pattern is reserved for special names in python. - Add security protections for the `PermissionSetting`. - Improve documentation formatting, add it to the package's long description. - Remove unneeded dependencies. - Remove old zpkg-related files and zcml slugs. 3.5.0 (2009-01-31) ------------------ - Include settings that were previously imported from zope.app.security. 3.4.2 (2009-01-28) ------------------ - Changed mailing list address to zope-dev at zope.org. Fix package homepage to the pypi page. - Fix test in buildout which still depended on zope.app.securitypolicy by mistake. - Remove explicit dependency on zope.app.form from ``setup.py``; nothing in the code directly depends on this. 3.4.1 (2008-06-02) ------------------ - Fix reference to deprecated security policy from ZCML. 3.4.0 (2007-09-25) ------------------ - Initial documented release zope.securitypolicy-3.7.0/COPYRIGHT.txt000644 000766 000024 00000000040 11447361751 017604 0ustar00macstaff000000 000000 Zope Foundation and Contributorszope.securitypolicy-3.7.0/LICENSE.txt000644 000766 000024 00000004026 11447361751 017326 0ustar00macstaff000000 000000 Zope Public License (ZPL) Version 2.1 A copyright notice accompanies this license document that identifies the copyright holders. This license has been certified as open source. It has also been designated as GPL compatible by the Free Software Foundation (FSF). Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions in source code must retain the accompanying copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the accompanying copyright notice, this list of conditions, and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Names of the copyright holders must not be used to endorse or promote products derived from this software without prior written permission from the copyright holders. 4. The right to distribute this software or to use it for any purpose does not give you the right to use Servicemarks (sm) or Trademarks (tm) of the copyright holders. Use of them is covered by separate agreement with the copyright holders. 5. If any files are modified, you must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. Disclaimer THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. zope.securitypolicy-3.7.0/PKG-INFO000644 000766 000024 00000066606 11447361755 016620 0ustar00macstaff000000 000000 Metadata-Version: 1.0 Name: zope.securitypolicy Version: 3.7.0 Summary: Default security policy for Zope3 Home-page: http://pypi.python.org/pypi/zope.securitypolicy Author: Zope Foundation and Contributors Author-email: zope-dev@zope.org License: ZPL 2.1 Description: This package provides an useful security policy for Zope3. It's the default security policy used in "zope3 the application" and many other zope-based projects. .. contents:: ============================ Classic Zope Security Policy ============================ This package implements a role-based security policy similar to the policy found in Zope 2. The security policy is responsible for deciding whether an interaction has a permission on an object. This security policy does this using grant and denial information. Managers can grant or deny: - roles to principals, - permissions to principals, and - permissions to roles Grants and denials are stored as annotations on objects. To store grants and denials, objects must be annotatable: >>> import zope.interface >>> from zope.annotation.interfaces import IAttributeAnnotatable >>> class Ob: ... zope.interface.implements(IAttributeAnnotatable) >>> ob = Ob() We use objects to represent principals. These objects implement an interface named `IPrincipal`, but the security policy only uses the `id` and `groups` attributes: >>> class Principal: ... def __init__(self, id): ... self.id = id ... self.groups = [] >>> principal = Principal('bob') Roles and permissions are also represented by objects, however, for the purposes of the security policy, only string `ids` are used. The security policy provides a factory for creating interactions: >>> import zope.securitypolicy.zopepolicy >>> interaction = zope.securitypolicy.zopepolicy.ZopeSecurityPolicy() An interaction represents a specific interaction between some principals (normally users) and the system. Normally, we are only concerned with the interaction of one principal with the system, although we can have interactions of multiple principals. Multiple-principal interactions normally occur when untrusted users store code on a system for later execution. When untrusted code is executing, the authors of the code participate in the interaction. An interaction has a permission on an object only if all of the principals participating in the interaction have access to the object. The `checkPermission` method on interactions is used to test whether an interaction has a permission for an object. An interaction without participants always has every permission: >>> interaction.checkPermission('P1', ob) True In this example, 'P1' is a permission id. Normally, interactions have participants: >>> class Participation: ... interaction = None >>> participation = Participation() >>> participation.principal = principal >>> interaction.add(participation) If we have participants, then we don't have a permission unless there are grants: >>> interaction.checkPermission('P1', ob) False Note, however, that we always have the CheckerPublic permission: >>> from zope.security.checker import CheckerPublic >>> interaction.checkPermission(CheckerPublic, ob) True We make grants and denials on objects by adapting them to various granting interfaces. The objects returned from the adaptation are object-specific manager objects: >>> from zope.securitypolicy import interfaces >>> roleper = interfaces.IRolePermissionManager(ob) >>> prinrole = interfaces.IPrincipalRoleManager(ob) >>> prinper = interfaces.IPrincipalPermissionManager(ob) The computations involved in checking permissions can be significant. To reduce the computational cost, caching is used extensively. We could invalidate the cache as we make grants, but the adapters for making grants will automatically invalidate the cache of the current interaction. They use the security-management apis to do this. To take advantage of the cache invalidation, we'll need to let the security-management system manage our interactions. First, we'll set our security policy as the default: >>> import zope.security.management >>> oldpolicy = zope.security.management.setSecurityPolicy( ... zope.securitypolicy.zopepolicy.ZopeSecurityPolicy) and then we'll create a new interaction: >>> participation = Participation() >>> participation.principal = principal >>> zope.security.management.newInteraction(participation) >>> interaction = zope.security.management.getInteraction() We normally provide access by granting permissions to roles for an object: >>> roleper.grantPermissionToRole('P1', 'R1') and then granting roles to principals for an object (local roles): >>> prinrole.assignRoleToPrincipal('R1', 'bob') The combination of these grants, which we call a role-based grant, provides the permission: >>> interaction.checkPermission('P1', ob) True We can also provide a permission directly: >>> prinper.grantPermissionToPrincipal('P2', 'bob') >>> interaction.checkPermission('P2', ob) True Permission grants or denials override role-based grant or denials. So if we deny P1: >>> prinper.denyPermissionToPrincipal('P1', 'bob') we cause the interaction to lack the permission, despite the role grants: >>> interaction.checkPermission('P1', ob) False Similarly, even if we have a role-based denial of P2: >>> roleper.denyPermissionToRole('P2', 'R1') we still have access, because of the permission-based grant: >>> interaction.checkPermission('P2', ob) True A role-based denial doesn't actually deny a permission; rather it prevents the granting of a permission. So, if we have both grants and denials based on roles, we have access: >>> roleper.grantPermissionToRole('P3', 'R1') >>> roleper.grantPermissionToRole('P3', 'R2') >>> roleper.denyPermissionToRole('P3', 'R3') >>> prinrole.removeRoleFromPrincipal('R2', 'bob') >>> prinrole.assignRoleToPrincipal('R3', 'bob') >>> interaction.checkPermission('P3', ob) True Global grants ------------- Grants made to an object are said to be "local". We can also make global grants: >>> from zope.securitypolicy.rolepermission import \ ... rolePermissionManager as roleperG >>> from zope.securitypolicy.principalpermission import \ ... principalPermissionManager as prinperG >>> from zope.securitypolicy.principalrole import \ ... principalRoleManager as prinroleG And the same rules apply to global grants and denials. >>> roleperG.grantPermissionToRole('P1G', 'R1G', False) In these tests, we aren't bothering to define any roles, permissions, or principals, so we pass an extra argument that tells the granting routines not to check the validity of the values. >>> prinroleG.assignRoleToPrincipal('R1G', 'bob', False) >>> interaction.checkPermission('P1G', ob) True >>> prinperG.grantPermissionToPrincipal('P2G', 'bob', False) >>> interaction.checkPermission('P2G', ob) True >>> prinperG.denyPermissionToPrincipal('P1G', 'bob', False) >>> interaction.checkPermission('P1G', ob) False >>> roleperG.denyPermissionToRole('P2G', 'R1G', False) >>> interaction.checkPermission('P2G', ob) True >>> roleperG.grantPermissionToRole('P3G', 'R1G', False) >>> roleperG.grantPermissionToRole('P3G', 'R2G', False) >>> roleperG.denyPermissionToRole('P3G', 'R3G', False) >>> prinroleG.removeRoleFromPrincipal('R2G', 'bob', False) >>> prinroleG.assignRoleToPrincipal('R3G', 'bob', False) >>> interaction.checkPermission('P3G', ob) True Local versus global grants -------------------------- We, of course, acquire global grants by default: >>> interaction.checkPermission('P1G', ob) False >>> interaction.checkPermission('P2G', ob) True >>> interaction.checkPermission('P3G', ob) True Local role-based grants do not override global principal-specific denials: >>> roleper.grantPermissionToRole('P1G', 'R1G') >>> prinrole.assignRoleToPrincipal('R1G', 'bob') >>> interaction.checkPermission('P1G', ob) False And local role-based denials don't override global principal-grants: >>> roleper.denyPermissionToRole('P2G', 'R1G') >>> interaction.checkPermission('P2G', ob) True A local role-based deny can cancel a global role-based grant: >>> roleper.denyPermissionToRole('P3G', 'R1G') >>> interaction.checkPermission('P3G', ob) False and a local role-based grant can override a global role-based denial: >>> roleperG.denyPermissionToRole('P4G', 'R1G', False) >>> prinroleG.assignRoleToPrincipal('R1G', "bob", False) >>> interaction.checkPermission('P4G', ob) False >>> roleper.grantPermissionToRole('P4G', 'R1G') >>> interaction.checkPermission('P4G', ob) True >>> prinroleG.removeRoleFromPrincipal('R1G', "bob", False) >>> interaction.checkPermission('P4G', ob) True Of course, a local permission-based grant or denial overrides any global setting and overrides local role-based grants or denials: >>> prinper.grantPermissionToPrincipal('P3G', 'bob') >>> interaction.checkPermission('P3G', ob) True >>> prinper.denyPermissionToPrincipal('P2G', 'bob') >>> interaction.checkPermission('P2G', ob) False Sublocations ------------ We can have sub-locations. A sublocation of a location is an object whose `__parent__` attribute is the location: >>> ob2 = Ob() >>> ob2.__parent__ = ob By default, sublocations acquire grants from higher locations: >>> interaction.checkPermission('P1', ob2) False >>> interaction.checkPermission('P2', ob2) True >>> interaction.checkPermission('P3', ob2) True >>> interaction.checkPermission('P1G', ob2) False >>> interaction.checkPermission('P2G', ob2) False >>> interaction.checkPermission('P3G', ob2) True >>> interaction.checkPermission('P4G', ob2) True Sublocation role-based grants do not override their parent principal-specific denials: >>> roleper2 = interfaces.IRolePermissionManager(ob2) >>> prinrole2 = interfaces.IPrincipalRoleManager(ob2) >>> prinper2 = interfaces.IPrincipalPermissionManager(ob2) >>> roleper2.grantPermissionToRole('P1', 'R1') >>> prinrole2.assignRoleToPrincipal('R1', 'bob') >>> interaction.checkPermission('P1', ob2) False And local role-based denials don't override their parents principal-grant: >>> roleper2.denyPermissionToRole('P2', 'R1') >>> interaction.checkPermission('P2', ob2) True A local role-based deny can cancel a parent role-based grant: >>> roleper2.denyPermissionToRole('P3', 'R1') >>> interaction.checkPermission('P3', ob2) False and a local role-based grant can override a parent role-based denial: >>> roleper.denyPermissionToRole('P4', 'R1') >>> prinrole.assignRoleToPrincipal('R1', 'bob') >>> interaction.checkPermission('P4', ob2) False >>> roleper2.grantPermissionToRole('P4', 'R1') >>> interaction.checkPermission('P4', ob2) True >>> prinrole.removeRoleFromPrincipal('R1', 'bob') >>> interaction.checkPermission('P4', ob2) True Of course, a local permission-based grant or denial overrides any global setting and overrides local role-based grants or denials: >>> prinper.grantPermissionToPrincipal('P3', 'bob') >>> interaction.checkPermission('P3', ob2) True >>> prinper.denyPermissionToPrincipal('P2', 'bob') >>> interaction.checkPermission('P2', ob2) False If an object is not annotatable, but does have a parent, it will get its grants from its parent: >>> class C: ... pass >>> ob3 = C() >>> ob3.__parent__ = ob >>> interaction.checkPermission('P1', ob3) False >>> interaction.checkPermission('P2', ob3) False >>> interaction.checkPermission('P3', ob3) True >>> interaction.checkPermission('P1G', ob3) False >>> interaction.checkPermission('P2G', ob3) False >>> interaction.checkPermission('P3G', ob3) True >>> interaction.checkPermission('P4G', ob3) True The same results will be had if there are multiple non-annotatable objects: >>> ob3.__parent__ = C() >>> ob3.__parent__.__parent__ = ob >>> interaction.checkPermission('P1', ob3) False >>> interaction.checkPermission('P2', ob3) False >>> interaction.checkPermission('P3', ob3) True >>> interaction.checkPermission('P1G', ob3) False >>> interaction.checkPermission('P2G', ob3) False >>> interaction.checkPermission('P3G', ob3) True >>> interaction.checkPermission('P4G', ob3) True and if an object doesn't have a parent: >>> ob4 = C() it will have whatever grants were made globally: >>> interaction.checkPermission('P1', ob4) False >>> interaction.checkPermission('P2', ob4) False >>> interaction.checkPermission('P3', ob4) False >>> interaction.checkPermission('P1G', ob4) False >>> interaction.checkPermission('P2G', ob4) True >>> interaction.checkPermission('P3G', ob4) False >>> interaction.checkPermission('P4G', ob4) False >>> prinroleG.assignRoleToPrincipal('R1G', "bob", False) >>> interaction.checkPermission('P3G', ob4) True We'll get the same result if we have a non-annotatable parent without a parent: >>> ob3.__parent__ = C() >>> interaction.checkPermission('P1', ob3) False >>> interaction.checkPermission('P2', ob3) False >>> interaction.checkPermission('P3', ob3) False >>> interaction.checkPermission('P1G', ob3) False >>> interaction.checkPermission('P2G', ob3) True >>> interaction.checkPermission('P3G', ob3) True >>> interaction.checkPermission('P4G', ob3) False The Anonymous role ------------------ The security policy defines a special role named "zope.Anonymous". All principals have this role and the role cannot be taken away. >>> roleperG.grantPermissionToRole('P5', 'zope.Anonymous', False) >>> interaction.checkPermission('P5', ob2) True Proxies ------- Objects may be proxied: >>> from zope.security.checker import ProxyFactory >>> ob = ProxyFactory(ob) >>> interaction.checkPermission('P1', ob) False >>> interaction.checkPermission('P2', ob) False >>> interaction.checkPermission('P3', ob) True >>> interaction.checkPermission('P1G', ob) False >>> interaction.checkPermission('P2G', ob) False >>> interaction.checkPermission('P3G', ob) True >>> interaction.checkPermission('P4G', ob) True as may their parents: >>> ob3 = C() >>> ob3.__parent__ = ob >>> interaction.checkPermission('P1', ob3) False >>> interaction.checkPermission('P2', ob3) False >>> interaction.checkPermission('P3', ob3) True >>> interaction.checkPermission('P1G', ob3) False >>> interaction.checkPermission('P2G', ob3) False >>> interaction.checkPermission('P3G', ob3) True >>> interaction.checkPermission('P4G', ob3) True Groups ------ Principals may have groups. Groups are also principals (and, thus, may have groups). If a principal has groups, the groups are available as group ids in the principal's `groups` attribute. The interaction has to convert these group ids to group objects, so that it can tell whether the groups have groups. It does this by calling the `getPrincipal` method on the principal authentication service, which is responsible for, among other things, converting a principal id to a principal. For our examples here, we'll create and register a stub principal authentication service: >>> from zope.authentication.interfaces import IAuthentication >>> class FauxPrincipals(object): ... zope.interface.implements(IAuthentication) ... def __init__(self): ... self.data = {} ... def __setitem__(self, key, value): ... self.data[key] = value ... def __getitem__(self, key): ... return self.data[key] ... def getPrincipal(self, id): ... return self.data[id] >>> auth = FauxPrincipals() >>> from zope.component import provideUtility >>> provideUtility(auth, IAuthentication) Let's define a group: >>> auth['g1'] = Principal('g1') Let's put the principal in our group. We do that by adding the group id to the new principals groups: >>> principal.groups.append('g1') Of course, the principal doesn't have permissions not granted: >>> interaction.checkPermission('gP1', ob) False Now, if we grant a permission to the group: >>> prinper.grantPermissionToPrincipal('gP1', 'g1') We see that our principal has the permission: >>> interaction.checkPermission('gP1', ob) True This works even if the group grant is global: >>> interaction.checkPermission('gP1G', ob) False >>> prinperG.grantPermissionToPrincipal('gP1G', 'g1', True) >>> interaction.checkPermission('gP1G', ob) True Grants are, of course, acquired: >>> interaction.checkPermission('gP1', ob2) True >>> interaction.checkPermission('gP1G', ob2) True Inner grants can override outer grants: >>> prinper2.denyPermissionToPrincipal('gP1', 'g1') >>> interaction.checkPermission('gP1', ob2) False But principal grants always trump group grants: >>> prinper2.grantPermissionToPrincipal('gP1', 'bob') >>> interaction.checkPermission('gP1', ob2) True Groups can have groups too: >>> auth['g2'] = Principal('g2') >>> auth['g1'].groups.append('g2') If we grant to the new group: >>> prinper.grantPermissionToPrincipal('gP2', 'g2') Then we, of course have that permission too: >>> interaction.checkPermission('gP2', ob2) True Just as principal grants override group grants, group grants can override other group grants: >>> prinper.denyPermissionToPrincipal('gP2', 'g1') >>> interaction.checkPermission('gP2', ob2) False Principals can be in more than one group. Let's define a new group: >>> auth['g3'] = Principal('g3') >>> principal.groups.append('g3') >>> prinper.grantPermissionToPrincipal('gP2', 'g3') Now, the principal has two groups. In one group, the permission 'gP2' is denied, but in the other, it is allowed. In a case like this, the permission is allowed: >>> interaction.checkPermission('gP2', ob2) True In a case where a principal has two or more groups, the group denies prevent allows from their parents. They don't prevent the principal from getting an allow from another principal. Grants can be inherited from ancestor groups through multiple paths. Let's grant a permission to g2 and deny it to g1: >>> prinper.grantPermissionToPrincipal('gP3', 'g2') >>> prinper.denyPermissionToPrincipal('gP3', 'g1') Now, as before, the deny in g1 blocks the grant in g2: >>> interaction.checkPermission('gP3', ob2) False Let's make g2 a group of g3: >>> auth['g3'].groups.append('g2') Now, we get g2's grant through g3, and access is allowed: >>> interaction.invalidate_cache() >>> interaction.checkPermission('gP3', ob2) True We can assign roles to groups: >>> prinrole.assignRoleToPrincipal('gR1', 'g2') and get permissions through the roles: >>> roleper.grantPermissionToRole('gP4', 'gR1') >>> interaction.checkPermission('gP4', ob2) True we can override role assignments to groups through subgroups: >>> prinrole.removeRoleFromPrincipal('gR1', 'g1') >>> prinrole.removeRoleFromPrincipal('gR1', 'g3') >>> interaction.checkPermission('gP4', ob2) False and through principals: >>> prinrole.assignRoleToPrincipal('gR1', 'bob') >>> interaction.checkPermission('gP4', ob2) True We clean up the changes we made in these examples: >>> zope.security.management.endInteraction() >>> ignore = zope.security.management.setSecurityPolicy(oldpolicy) ======= CHANGES ======= 3.7.0 (2010-09-25) ------------------ - LP #131115: Clean up inconsistency in ``getSetting`` interface definitions and actual usage for the various security maps. - LP #564525: fix permission moved from ``zope.app.dublincore`` namespace to ``zope.dublincore``. - Removed unused imports and pep8 cleanup. - Use doctest module instead of the deprecated zope.testing.doctest. - AnnotationGrantInfo implements IGrantInfo. - Added test extra to declare test dependency on ``zope.component [test]``. - Added an extra named `dublincore` to express optional dependency on `zope.dublincore >= 3.7`. - Added tests for ZCML files making sure they include everything they need. 3.6.1 (2009-07-24) ------------------ - Make tests work when the default and Zope vocabulary registry compete in the cleanup. 3.6.0 (2009-03-14) ------------------ - Change ``zope.app.security`` dependency to the new ``zope.authentication`` package, dropping a big number of unused dependencies. - Get rid of ``zope.app.testing`` and other testing dependencices. - Add ``ZODB3`` to install dependencies, because we use `Persistent` class. We didn't fail before, because it was installed implicitly. 3.5.1 (2009-03-10) ------------------ - Don't depend on the `hook` extra of zope.component, as we don't need it explicitly. - Import security settings (Allow, Deny, Unset) in the ``interfaces`` module from the ``zope.securitypolicy.settings``, added in previous release instead of old ``zope.app.security.settings``. The ``zope.app.security`` will be adapted to import them from ``zope.securitypolicy.interfaces``. - Use `_z_instances` instead of `__instances__` for storing instances for ``zope.securitypolicy.settings.PermissionSetting`` singleton implementation, because __*__ name pattern is reserved for special names in python. - Add security protections for the `PermissionSetting`. - Improve documentation formatting, add it to the package's long description. - Remove unneeded dependencies. - Remove old zpkg-related files and zcml slugs. 3.5.0 (2009-01-31) ------------------ - Include settings that were previously imported from zope.app.security. 3.4.2 (2009-01-28) ------------------ - Changed mailing list address to zope-dev at zope.org. Fix package homepage to the pypi page. - Fix test in buildout which still depended on zope.app.securitypolicy by mistake. - Remove explicit dependency on zope.app.form from ``setup.py``; nothing in the code directly depends on this. 3.4.1 (2008-06-02) ------------------ - Fix reference to deprecated security policy from ZCML. 3.4.0 (2007-09-25) ------------------ - Initial documented release Keywords: zope3 security policy Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: Web Environment Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: Zope Public License Classifier: Programming Language :: Python Classifier: Natural Language :: English Classifier: Operating System :: OS Independent Classifier: Topic :: Internet :: WWW/HTTP Classifier: Framework :: Zope3 zope.securitypolicy-3.7.0/README.txt000644 000766 000024 00000000240 11447361751 017173 0ustar00macstaff000000 000000 This package provides an useful security policy for Zope3. It's the default security policy used in "zope3 the application" and many other zope-based projects. zope.securitypolicy-3.7.0/bootstrap.py000644 000766 000024 00000003302 11447361751 020066 0ustar00macstaff000000 000000 ############################################################################## # # Copyright (c) 2006 Zope Foundation 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. # ############################################################################## """Bootstrap a buildout-based project Simply run this script in a directory containing a buildout.cfg. The script accepts buildout command-line options, so you can use the -c option to specify an alternate configuration file. """ import os, shutil, sys, tempfile, urllib2 tmpeggs = tempfile.mkdtemp() ez = {} exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py' ).read() in ez ez['use_setuptools'](to_dir=tmpeggs, download_delay=0) import pkg_resources cmd = 'from setuptools.command.easy_install import main; main()' if sys.platform == 'win32': cmd = '"%s"' % cmd # work around spawn lamosity on windows ws = pkg_resources.working_set assert os.spawnle( os.P_WAIT, sys.executable, sys.executable, '-c', cmd, '-mqNxd', tmpeggs, 'zc.buildout', dict(os.environ, PYTHONPATH= ws.find(pkg_resources.Requirement.parse('setuptools')).location ), ) == 0 ws.add_entry(tmpeggs) ws.require('zc.buildout') import zc.buildout.buildout zc.buildout.buildout.main(sys.argv[1:] + ['bootstrap']) shutil.rmtree(tmpeggs) zope.securitypolicy-3.7.0/buildout.cfg000644 000766 000024 00000000170 11447361751 020007 0ustar00macstaff000000 000000 [buildout] develop = . parts = test [test] recipe = zc.recipe.testrunner eggs = zope.securitypolicy [test, dublincore] zope.securitypolicy-3.7.0/setup.cfg000644 000766 000024 00000000073 11447361755 017326 0ustar00macstaff000000 000000 [egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 zope.securitypolicy-3.7.0/setup.py000644 000766 000024 00000005251 11447361751 017216 0ustar00macstaff000000 000000 ############################################################################## # # Copyright (c) 2006 Zope Foundation 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. # ############################################################################## # This package is developed by the Zope Toolkit project, documented here: # http://docs.zope.org/zopetoolkit # When developing and releasing this package, please follow the documented # Zope Toolkit policies as described by this documentation. ############################################################################## """Setup for zope.securitypolicy package """ import os from setuptools import setup, find_packages def read(*rnames): return open(os.path.join(os.path.dirname(__file__), *rnames)).read() setup(name='zope.securitypolicy', version='3.7.0', author='Zope Foundation and Contributors', author_email='zope-dev@zope.org', description='Default security policy for Zope3', long_description=( read('README.txt') + '\n.. contents::\n\n' + read('src', 'zope', 'securitypolicy', 'zopepolicy.txt') + '\n\n' + read('CHANGES.txt')), keywords="zope3 security policy", classifiers=[ 'Development Status :: 5 - Production/Stable', 'Environment :: Web Environment', 'Intended Audience :: Developers', 'License :: OSI Approved :: Zope Public License', 'Programming Language :: Python', 'Natural Language :: English', 'Operating System :: OS Independent', 'Topic :: Internet :: WWW/HTTP', 'Framework :: Zope3'], url='http://pypi.python.org/pypi/zope.securitypolicy', license='ZPL 2.1', packages=find_packages('src'), package_dir={'': 'src'}, namespace_packages=['zope'], install_requires=[ 'setuptools', 'ZODB3', 'zope.annotation', 'zope.authentication', 'zope.component', 'zope.configuration', 'zope.i18nmessageid', 'zope.interface', 'zope.location', 'zope.schema', 'zope.security', ], extras_require=dict( test=[ 'zope.component [test]', ], dublincore=[ 'zope.dublincore >= 3.7', ]), include_package_data=True, zip_safe=False, ) zope.securitypolicy-3.7.0/src/000755 000766 000024 00000000000 11447361755 016274 5ustar00macstaff000000 000000 zope.securitypolicy-3.7.0/src/zope/000755 000766 000024 00000000000 11447361755 017251 5ustar00macstaff000000 000000 zope.securitypolicy-3.7.0/src/zope.securitypolicy.egg-info/000755 000766 000024 00000000000 11447361755 024031 5ustar00macstaff000000 000000 zope.securitypolicy-3.7.0/src/zope.securitypolicy.egg-info/PKG-INFO000644 000766 000024 00000066606 11447361753 025142 0ustar00macstaff000000 000000 Metadata-Version: 1.0 Name: zope.securitypolicy Version: 3.7.0 Summary: Default security policy for Zope3 Home-page: http://pypi.python.org/pypi/zope.securitypolicy Author: Zope Foundation and Contributors Author-email: zope-dev@zope.org License: ZPL 2.1 Description: This package provides an useful security policy for Zope3. It's the default security policy used in "zope3 the application" and many other zope-based projects. .. contents:: ============================ Classic Zope Security Policy ============================ This package implements a role-based security policy similar to the policy found in Zope 2. The security policy is responsible for deciding whether an interaction has a permission on an object. This security policy does this using grant and denial information. Managers can grant or deny: - roles to principals, - permissions to principals, and - permissions to roles Grants and denials are stored as annotations on objects. To store grants and denials, objects must be annotatable: >>> import zope.interface >>> from zope.annotation.interfaces import IAttributeAnnotatable >>> class Ob: ... zope.interface.implements(IAttributeAnnotatable) >>> ob = Ob() We use objects to represent principals. These objects implement an interface named `IPrincipal`, but the security policy only uses the `id` and `groups` attributes: >>> class Principal: ... def __init__(self, id): ... self.id = id ... self.groups = [] >>> principal = Principal('bob') Roles and permissions are also represented by objects, however, for the purposes of the security policy, only string `ids` are used. The security policy provides a factory for creating interactions: >>> import zope.securitypolicy.zopepolicy >>> interaction = zope.securitypolicy.zopepolicy.ZopeSecurityPolicy() An interaction represents a specific interaction between some principals (normally users) and the system. Normally, we are only concerned with the interaction of one principal with the system, although we can have interactions of multiple principals. Multiple-principal interactions normally occur when untrusted users store code on a system for later execution. When untrusted code is executing, the authors of the code participate in the interaction. An interaction has a permission on an object only if all of the principals participating in the interaction have access to the object. The `checkPermission` method on interactions is used to test whether an interaction has a permission for an object. An interaction without participants always has every permission: >>> interaction.checkPermission('P1', ob) True In this example, 'P1' is a permission id. Normally, interactions have participants: >>> class Participation: ... interaction = None >>> participation = Participation() >>> participation.principal = principal >>> interaction.add(participation) If we have participants, then we don't have a permission unless there are grants: >>> interaction.checkPermission('P1', ob) False Note, however, that we always have the CheckerPublic permission: >>> from zope.security.checker import CheckerPublic >>> interaction.checkPermission(CheckerPublic, ob) True We make grants and denials on objects by adapting them to various granting interfaces. The objects returned from the adaptation are object-specific manager objects: >>> from zope.securitypolicy import interfaces >>> roleper = interfaces.IRolePermissionManager(ob) >>> prinrole = interfaces.IPrincipalRoleManager(ob) >>> prinper = interfaces.IPrincipalPermissionManager(ob) The computations involved in checking permissions can be significant. To reduce the computational cost, caching is used extensively. We could invalidate the cache as we make grants, but the adapters for making grants will automatically invalidate the cache of the current interaction. They use the security-management apis to do this. To take advantage of the cache invalidation, we'll need to let the security-management system manage our interactions. First, we'll set our security policy as the default: >>> import zope.security.management >>> oldpolicy = zope.security.management.setSecurityPolicy( ... zope.securitypolicy.zopepolicy.ZopeSecurityPolicy) and then we'll create a new interaction: >>> participation = Participation() >>> participation.principal = principal >>> zope.security.management.newInteraction(participation) >>> interaction = zope.security.management.getInteraction() We normally provide access by granting permissions to roles for an object: >>> roleper.grantPermissionToRole('P1', 'R1') and then granting roles to principals for an object (local roles): >>> prinrole.assignRoleToPrincipal('R1', 'bob') The combination of these grants, which we call a role-based grant, provides the permission: >>> interaction.checkPermission('P1', ob) True We can also provide a permission directly: >>> prinper.grantPermissionToPrincipal('P2', 'bob') >>> interaction.checkPermission('P2', ob) True Permission grants or denials override role-based grant or denials. So if we deny P1: >>> prinper.denyPermissionToPrincipal('P1', 'bob') we cause the interaction to lack the permission, despite the role grants: >>> interaction.checkPermission('P1', ob) False Similarly, even if we have a role-based denial of P2: >>> roleper.denyPermissionToRole('P2', 'R1') we still have access, because of the permission-based grant: >>> interaction.checkPermission('P2', ob) True A role-based denial doesn't actually deny a permission; rather it prevents the granting of a permission. So, if we have both grants and denials based on roles, we have access: >>> roleper.grantPermissionToRole('P3', 'R1') >>> roleper.grantPermissionToRole('P3', 'R2') >>> roleper.denyPermissionToRole('P3', 'R3') >>> prinrole.removeRoleFromPrincipal('R2', 'bob') >>> prinrole.assignRoleToPrincipal('R3', 'bob') >>> interaction.checkPermission('P3', ob) True Global grants ------------- Grants made to an object are said to be "local". We can also make global grants: >>> from zope.securitypolicy.rolepermission import \ ... rolePermissionManager as roleperG >>> from zope.securitypolicy.principalpermission import \ ... principalPermissionManager as prinperG >>> from zope.securitypolicy.principalrole import \ ... principalRoleManager as prinroleG And the same rules apply to global grants and denials. >>> roleperG.grantPermissionToRole('P1G', 'R1G', False) In these tests, we aren't bothering to define any roles, permissions, or principals, so we pass an extra argument that tells the granting routines not to check the validity of the values. >>> prinroleG.assignRoleToPrincipal('R1G', 'bob', False) >>> interaction.checkPermission('P1G', ob) True >>> prinperG.grantPermissionToPrincipal('P2G', 'bob', False) >>> interaction.checkPermission('P2G', ob) True >>> prinperG.denyPermissionToPrincipal('P1G', 'bob', False) >>> interaction.checkPermission('P1G', ob) False >>> roleperG.denyPermissionToRole('P2G', 'R1G', False) >>> interaction.checkPermission('P2G', ob) True >>> roleperG.grantPermissionToRole('P3G', 'R1G', False) >>> roleperG.grantPermissionToRole('P3G', 'R2G', False) >>> roleperG.denyPermissionToRole('P3G', 'R3G', False) >>> prinroleG.removeRoleFromPrincipal('R2G', 'bob', False) >>> prinroleG.assignRoleToPrincipal('R3G', 'bob', False) >>> interaction.checkPermission('P3G', ob) True Local versus global grants -------------------------- We, of course, acquire global grants by default: >>> interaction.checkPermission('P1G', ob) False >>> interaction.checkPermission('P2G', ob) True >>> interaction.checkPermission('P3G', ob) True Local role-based grants do not override global principal-specific denials: >>> roleper.grantPermissionToRole('P1G', 'R1G') >>> prinrole.assignRoleToPrincipal('R1G', 'bob') >>> interaction.checkPermission('P1G', ob) False And local role-based denials don't override global principal-grants: >>> roleper.denyPermissionToRole('P2G', 'R1G') >>> interaction.checkPermission('P2G', ob) True A local role-based deny can cancel a global role-based grant: >>> roleper.denyPermissionToRole('P3G', 'R1G') >>> interaction.checkPermission('P3G', ob) False and a local role-based grant can override a global role-based denial: >>> roleperG.denyPermissionToRole('P4G', 'R1G', False) >>> prinroleG.assignRoleToPrincipal('R1G', "bob", False) >>> interaction.checkPermission('P4G', ob) False >>> roleper.grantPermissionToRole('P4G', 'R1G') >>> interaction.checkPermission('P4G', ob) True >>> prinroleG.removeRoleFromPrincipal('R1G', "bob", False) >>> interaction.checkPermission('P4G', ob) True Of course, a local permission-based grant or denial overrides any global setting and overrides local role-based grants or denials: >>> prinper.grantPermissionToPrincipal('P3G', 'bob') >>> interaction.checkPermission('P3G', ob) True >>> prinper.denyPermissionToPrincipal('P2G', 'bob') >>> interaction.checkPermission('P2G', ob) False Sublocations ------------ We can have sub-locations. A sublocation of a location is an object whose `__parent__` attribute is the location: >>> ob2 = Ob() >>> ob2.__parent__ = ob By default, sublocations acquire grants from higher locations: >>> interaction.checkPermission('P1', ob2) False >>> interaction.checkPermission('P2', ob2) True >>> interaction.checkPermission('P3', ob2) True >>> interaction.checkPermission('P1G', ob2) False >>> interaction.checkPermission('P2G', ob2) False >>> interaction.checkPermission('P3G', ob2) True >>> interaction.checkPermission('P4G', ob2) True Sublocation role-based grants do not override their parent principal-specific denials: >>> roleper2 = interfaces.IRolePermissionManager(ob2) >>> prinrole2 = interfaces.IPrincipalRoleManager(ob2) >>> prinper2 = interfaces.IPrincipalPermissionManager(ob2) >>> roleper2.grantPermissionToRole('P1', 'R1') >>> prinrole2.assignRoleToPrincipal('R1', 'bob') >>> interaction.checkPermission('P1', ob2) False And local role-based denials don't override their parents principal-grant: >>> roleper2.denyPermissionToRole('P2', 'R1') >>> interaction.checkPermission('P2', ob2) True A local role-based deny can cancel a parent role-based grant: >>> roleper2.denyPermissionToRole('P3', 'R1') >>> interaction.checkPermission('P3', ob2) False and a local role-based grant can override a parent role-based denial: >>> roleper.denyPermissionToRole('P4', 'R1') >>> prinrole.assignRoleToPrincipal('R1', 'bob') >>> interaction.checkPermission('P4', ob2) False >>> roleper2.grantPermissionToRole('P4', 'R1') >>> interaction.checkPermission('P4', ob2) True >>> prinrole.removeRoleFromPrincipal('R1', 'bob') >>> interaction.checkPermission('P4', ob2) True Of course, a local permission-based grant or denial overrides any global setting and overrides local role-based grants or denials: >>> prinper.grantPermissionToPrincipal('P3', 'bob') >>> interaction.checkPermission('P3', ob2) True >>> prinper.denyPermissionToPrincipal('P2', 'bob') >>> interaction.checkPermission('P2', ob2) False If an object is not annotatable, but does have a parent, it will get its grants from its parent: >>> class C: ... pass >>> ob3 = C() >>> ob3.__parent__ = ob >>> interaction.checkPermission('P1', ob3) False >>> interaction.checkPermission('P2', ob3) False >>> interaction.checkPermission('P3', ob3) True >>> interaction.checkPermission('P1G', ob3) False >>> interaction.checkPermission('P2G', ob3) False >>> interaction.checkPermission('P3G', ob3) True >>> interaction.checkPermission('P4G', ob3) True The same results will be had if there are multiple non-annotatable objects: >>> ob3.__parent__ = C() >>> ob3.__parent__.__parent__ = ob >>> interaction.checkPermission('P1', ob3) False >>> interaction.checkPermission('P2', ob3) False >>> interaction.checkPermission('P3', ob3) True >>> interaction.checkPermission('P1G', ob3) False >>> interaction.checkPermission('P2G', ob3) False >>> interaction.checkPermission('P3G', ob3) True >>> interaction.checkPermission('P4G', ob3) True and if an object doesn't have a parent: >>> ob4 = C() it will have whatever grants were made globally: >>> interaction.checkPermission('P1', ob4) False >>> interaction.checkPermission('P2', ob4) False >>> interaction.checkPermission('P3', ob4) False >>> interaction.checkPermission('P1G', ob4) False >>> interaction.checkPermission('P2G', ob4) True >>> interaction.checkPermission('P3G', ob4) False >>> interaction.checkPermission('P4G', ob4) False >>> prinroleG.assignRoleToPrincipal('R1G', "bob", False) >>> interaction.checkPermission('P3G', ob4) True We'll get the same result if we have a non-annotatable parent without a parent: >>> ob3.__parent__ = C() >>> interaction.checkPermission('P1', ob3) False >>> interaction.checkPermission('P2', ob3) False >>> interaction.checkPermission('P3', ob3) False >>> interaction.checkPermission('P1G', ob3) False >>> interaction.checkPermission('P2G', ob3) True >>> interaction.checkPermission('P3G', ob3) True >>> interaction.checkPermission('P4G', ob3) False The Anonymous role ------------------ The security policy defines a special role named "zope.Anonymous". All principals have this role and the role cannot be taken away. >>> roleperG.grantPermissionToRole('P5', 'zope.Anonymous', False) >>> interaction.checkPermission('P5', ob2) True Proxies ------- Objects may be proxied: >>> from zope.security.checker import ProxyFactory >>> ob = ProxyFactory(ob) >>> interaction.checkPermission('P1', ob) False >>> interaction.checkPermission('P2', ob) False >>> interaction.checkPermission('P3', ob) True >>> interaction.checkPermission('P1G', ob) False >>> interaction.checkPermission('P2G', ob) False >>> interaction.checkPermission('P3G', ob) True >>> interaction.checkPermission('P4G', ob) True as may their parents: >>> ob3 = C() >>> ob3.__parent__ = ob >>> interaction.checkPermission('P1', ob3) False >>> interaction.checkPermission('P2', ob3) False >>> interaction.checkPermission('P3', ob3) True >>> interaction.checkPermission('P1G', ob3) False >>> interaction.checkPermission('P2G', ob3) False >>> interaction.checkPermission('P3G', ob3) True >>> interaction.checkPermission('P4G', ob3) True Groups ------ Principals may have groups. Groups are also principals (and, thus, may have groups). If a principal has groups, the groups are available as group ids in the principal's `groups` attribute. The interaction has to convert these group ids to group objects, so that it can tell whether the groups have groups. It does this by calling the `getPrincipal` method on the principal authentication service, which is responsible for, among other things, converting a principal id to a principal. For our examples here, we'll create and register a stub principal authentication service: >>> from zope.authentication.interfaces import IAuthentication >>> class FauxPrincipals(object): ... zope.interface.implements(IAuthentication) ... def __init__(self): ... self.data = {} ... def __setitem__(self, key, value): ... self.data[key] = value ... def __getitem__(self, key): ... return self.data[key] ... def getPrincipal(self, id): ... return self.data[id] >>> auth = FauxPrincipals() >>> from zope.component import provideUtility >>> provideUtility(auth, IAuthentication) Let's define a group: >>> auth['g1'] = Principal('g1') Let's put the principal in our group. We do that by adding the group id to the new principals groups: >>> principal.groups.append('g1') Of course, the principal doesn't have permissions not granted: >>> interaction.checkPermission('gP1', ob) False Now, if we grant a permission to the group: >>> prinper.grantPermissionToPrincipal('gP1', 'g1') We see that our principal has the permission: >>> interaction.checkPermission('gP1', ob) True This works even if the group grant is global: >>> interaction.checkPermission('gP1G', ob) False >>> prinperG.grantPermissionToPrincipal('gP1G', 'g1', True) >>> interaction.checkPermission('gP1G', ob) True Grants are, of course, acquired: >>> interaction.checkPermission('gP1', ob2) True >>> interaction.checkPermission('gP1G', ob2) True Inner grants can override outer grants: >>> prinper2.denyPermissionToPrincipal('gP1', 'g1') >>> interaction.checkPermission('gP1', ob2) False But principal grants always trump group grants: >>> prinper2.grantPermissionToPrincipal('gP1', 'bob') >>> interaction.checkPermission('gP1', ob2) True Groups can have groups too: >>> auth['g2'] = Principal('g2') >>> auth['g1'].groups.append('g2') If we grant to the new group: >>> prinper.grantPermissionToPrincipal('gP2', 'g2') Then we, of course have that permission too: >>> interaction.checkPermission('gP2', ob2) True Just as principal grants override group grants, group grants can override other group grants: >>> prinper.denyPermissionToPrincipal('gP2', 'g1') >>> interaction.checkPermission('gP2', ob2) False Principals can be in more than one group. Let's define a new group: >>> auth['g3'] = Principal('g3') >>> principal.groups.append('g3') >>> prinper.grantPermissionToPrincipal('gP2', 'g3') Now, the principal has two groups. In one group, the permission 'gP2' is denied, but in the other, it is allowed. In a case like this, the permission is allowed: >>> interaction.checkPermission('gP2', ob2) True In a case where a principal has two or more groups, the group denies prevent allows from their parents. They don't prevent the principal from getting an allow from another principal. Grants can be inherited from ancestor groups through multiple paths. Let's grant a permission to g2 and deny it to g1: >>> prinper.grantPermissionToPrincipal('gP3', 'g2') >>> prinper.denyPermissionToPrincipal('gP3', 'g1') Now, as before, the deny in g1 blocks the grant in g2: >>> interaction.checkPermission('gP3', ob2) False Let's make g2 a group of g3: >>> auth['g3'].groups.append('g2') Now, we get g2's grant through g3, and access is allowed: >>> interaction.invalidate_cache() >>> interaction.checkPermission('gP3', ob2) True We can assign roles to groups: >>> prinrole.assignRoleToPrincipal('gR1', 'g2') and get permissions through the roles: >>> roleper.grantPermissionToRole('gP4', 'gR1') >>> interaction.checkPermission('gP4', ob2) True we can override role assignments to groups through subgroups: >>> prinrole.removeRoleFromPrincipal('gR1', 'g1') >>> prinrole.removeRoleFromPrincipal('gR1', 'g3') >>> interaction.checkPermission('gP4', ob2) False and through principals: >>> prinrole.assignRoleToPrincipal('gR1', 'bob') >>> interaction.checkPermission('gP4', ob2) True We clean up the changes we made in these examples: >>> zope.security.management.endInteraction() >>> ignore = zope.security.management.setSecurityPolicy(oldpolicy) ======= CHANGES ======= 3.7.0 (2010-09-25) ------------------ - LP #131115: Clean up inconsistency in ``getSetting`` interface definitions and actual usage for the various security maps. - LP #564525: fix permission moved from ``zope.app.dublincore`` namespace to ``zope.dublincore``. - Removed unused imports and pep8 cleanup. - Use doctest module instead of the deprecated zope.testing.doctest. - AnnotationGrantInfo implements IGrantInfo. - Added test extra to declare test dependency on ``zope.component [test]``. - Added an extra named `dublincore` to express optional dependency on `zope.dublincore >= 3.7`. - Added tests for ZCML files making sure they include everything they need. 3.6.1 (2009-07-24) ------------------ - Make tests work when the default and Zope vocabulary registry compete in the cleanup. 3.6.0 (2009-03-14) ------------------ - Change ``zope.app.security`` dependency to the new ``zope.authentication`` package, dropping a big number of unused dependencies. - Get rid of ``zope.app.testing`` and other testing dependencices. - Add ``ZODB3`` to install dependencies, because we use `Persistent` class. We didn't fail before, because it was installed implicitly. 3.5.1 (2009-03-10) ------------------ - Don't depend on the `hook` extra of zope.component, as we don't need it explicitly. - Import security settings (Allow, Deny, Unset) in the ``interfaces`` module from the ``zope.securitypolicy.settings``, added in previous release instead of old ``zope.app.security.settings``. The ``zope.app.security`` will be adapted to import them from ``zope.securitypolicy.interfaces``. - Use `_z_instances` instead of `__instances__` for storing instances for ``zope.securitypolicy.settings.PermissionSetting`` singleton implementation, because __*__ name pattern is reserved for special names in python. - Add security protections for the `PermissionSetting`. - Improve documentation formatting, add it to the package's long description. - Remove unneeded dependencies. - Remove old zpkg-related files and zcml slugs. 3.5.0 (2009-01-31) ------------------ - Include settings that were previously imported from zope.app.security. 3.4.2 (2009-01-28) ------------------ - Changed mailing list address to zope-dev at zope.org. Fix package homepage to the pypi page. - Fix test in buildout which still depended on zope.app.securitypolicy by mistake. - Remove explicit dependency on zope.app.form from ``setup.py``; nothing in the code directly depends on this. 3.4.1 (2008-06-02) ------------------ - Fix reference to deprecated security policy from ZCML. 3.4.0 (2007-09-25) ------------------ - Initial documented release Keywords: zope3 security policy Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: Web Environment Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: Zope Public License Classifier: Programming Language :: Python Classifier: Natural Language :: English Classifier: Operating System :: OS Independent Classifier: Topic :: Internet :: WWW/HTTP Classifier: Framework :: Zope3 zope.securitypolicy-3.7.0/src/zope.securitypolicy.egg-info/SOURCES.txt000644 000766 000024 00000003663 11447361753 025723 0ustar00macstaff000000 000000 CHANGES.txt COPYRIGHT.txt LICENSE.txt README.txt bootstrap.py buildout.cfg setup.py src/zope/__init__.py src/zope.securitypolicy.egg-info/PKG-INFO src/zope.securitypolicy.egg-info/SOURCES.txt src/zope.securitypolicy.egg-info/dependency_links.txt src/zope.securitypolicy.egg-info/namespace_packages.txt src/zope.securitypolicy.egg-info/not-zip-safe src/zope.securitypolicy.egg-info/requires.txt src/zope.securitypolicy.egg-info/top_level.txt src/zope/securitypolicy/__init__.py src/zope/securitypolicy/configure.zcml src/zope/securitypolicy/grantinfo.py src/zope/securitypolicy/interfaces.py src/zope/securitypolicy/meta.zcml src/zope/securitypolicy/metaconfigure.py src/zope/securitypolicy/metadirectives.py src/zope/securitypolicy/principalpermission.py src/zope/securitypolicy/principalrole.py src/zope/securitypolicy/role.py src/zope/securitypolicy/rolepermission.py src/zope/securitypolicy/securitymap.py src/zope/securitypolicy/securitypolicy.zcml src/zope/securitypolicy/settings.py src/zope/securitypolicy/vocabulary.py src/zope/securitypolicy/zopepolicy.py src/zope/securitypolicy/zopepolicy.txt src/zope/securitypolicy/tests/__init__.py src/zope/securitypolicy/tests/mapping.zcml src/zope/securitypolicy/tests/role.zcml src/zope/securitypolicy/tests/role_duplicate.zcml src/zope/securitypolicy/tests/test_annotationprincipalpermissionmanager.py src/zope/securitypolicy/tests/test_annotationprincipalrolemanager.py src/zope/securitypolicy/tests/test_annotationrolepermissionmanager.py src/zope/securitypolicy/tests/test_principalpermissionmanager.py src/zope/securitypolicy/tests/test_principalrolemanager.py src/zope/securitypolicy/tests/test_role.py src/zope/securitypolicy/tests/test_rolepermissionmanager.py src/zope/securitypolicy/tests/test_securitydirectives.py src/zope/securitypolicy/tests/test_securitymap.py src/zope/securitypolicy/tests/test_settings.py src/zope/securitypolicy/tests/test_vocabulary.py src/zope/securitypolicy/tests/test_zopepolicy.pyzope.securitypolicy-3.7.0/src/zope.securitypolicy.egg-info/dependency_links.txt000644 000766 000024 00000000001 11447361753 030075 0ustar00macstaff000000 000000 zope.securitypolicy-3.7.0/src/zope.securitypolicy.egg-info/namespace_packages.txt000644 000766 000024 00000000005 11447361753 030355 0ustar00macstaff000000 000000 zope zope.securitypolicy-3.7.0/src/zope.securitypolicy.egg-info/not-zip-safe000644 000766 000024 00000000001 11447361752 026254 0ustar00macstaff000000 000000 zope.securitypolicy-3.7.0/src/zope.securitypolicy.egg-info/requires.txt000644 000766 000024 00000000343 11447361753 026427 0ustar00macstaff000000 000000 setuptools ZODB3 zope.annotation zope.authentication zope.component zope.configuration zope.i18nmessageid zope.interface zope.location zope.schema zope.security [test] zope.component [test] [dublincore] zope.dublincore >= 3.7zope.securitypolicy-3.7.0/src/zope.securitypolicy.egg-info/top_level.txt000644 000766 000024 00000000005 11447361753 026554 0ustar00macstaff000000 000000 zope zope.securitypolicy-3.7.0/src/zope/__init__.py000644 000766 000024 00000000070 11447361751 021353 0ustar00macstaff000000 000000 __import__('pkg_resources').declare_namespace(__name__) zope.securitypolicy-3.7.0/src/zope/securitypolicy/000755 000766 000024 00000000000 11447361755 022340 5ustar00macstaff000000 000000 zope.securitypolicy-3.7.0/src/zope/securitypolicy/__init__.py000644 000766 000024 00000001222 11447361751 024442 0ustar00macstaff000000 000000 ############################################################################## # # Copyright (c) 2004 Zope Foundation 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. # ############################################################################## """Securitypolicy """ zope.securitypolicy-3.7.0/src/zope/securitypolicy/configure.zcml000644 000766 000024 00000006460 11447361751 025212 0ustar00macstaff000000 000000 zope.securitypolicy-3.7.0/src/zope/securitypolicy/grantinfo.py000644 000766 000024 00000005261 11447361751 024701 0ustar00macstaff000000 000000 ############################################################################## # # Copyright (c) 2004 Zope Foundation 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. # ############################################################################## """Grant info """ from zope.annotation.interfaces import IAnnotations from zope.interface import implements from zope.securitypolicy.interfaces import Unset from zope.securitypolicy.interfaces import IGrantInfo from zope.securitypolicy.principalpermission import \ AnnotationPrincipalPermissionManager prinperkey = AnnotationPrincipalPermissionManager.key del AnnotationPrincipalPermissionManager from zope.securitypolicy.principalrole import \ AnnotationPrincipalRoleManager prinrolekey = AnnotationPrincipalRoleManager.key del AnnotationPrincipalRoleManager from zope.securitypolicy.rolepermission import \ AnnotationRolePermissionManager rolepermkey = AnnotationRolePermissionManager.key del AnnotationRolePermissionManager class AnnotationGrantInfo(object): implements(IGrantInfo) prinper = prinrole = permrole = {} def __init__(self, context): self._context = context annotations = IAnnotations(context, None) if annotations is not None: prinper = annotations.get(prinperkey) if prinper is not None: self.prinper = prinper._bycol # by principals prinrole = annotations.get(prinrolekey) if prinrole is not None: self.prinrole = prinrole._bycol # by principals roleper = annotations.get(rolepermkey) if roleper is not None: self.permrole = roleper._byrow # by permission def __nonzero__(self): return bool(self.prinper or self.prinrole or self.permrole) def principalPermissionGrant(self, principal, permission): prinper = self.prinper.get(principal) if prinper: return prinper.get(permission, Unset) return Unset def getRolesForPermission(self, permission): permrole = self.permrole.get(permission) if permrole: return permrole.items() return () def getRolesForPrincipal(self, principal): prinrole = self.prinrole.get(principal) if prinrole: return prinrole.items() return () zope.securitypolicy-3.7.0/src/zope/securitypolicy/interfaces.py000644 000766 000024 00000016520 11447361751 025035 0ustar00macstaff000000 000000 ############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation 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 map to hold matrix-like relationships. In all cases, 'setting' values are one of the defined constants `Allow`, `Deny`, or `Unset`. """ from zope.interface import Interface from zope.schema import TextLine, Text # These are the "setting" values returned by several methods defined # in these interfaces. The implementation may move to another # location in the future, so this should be the preferred module to # import these from. from zope.securitypolicy.settings import Allow, Deny, Unset class IRole(Interface): """A role object.""" id = TextLine( title=u"Id", description=u"Id as which this role will be known and used.", readonly=True, required=True) title = TextLine( title=u"Title", description=u"Provides a title for the role.", required=True) description = Text( title=u"Description", description=u"Provides a description for the role.", required=False) class IPrincipalRoleMap(Interface): """Mappings between principals and roles.""" def getPrincipalsForRole(role_id): """Get the principals that have been granted a role. Return the list of (principal id, setting) who have been assigned or removed from a role. If no principals have been assigned this role, then the empty list is returned. """ def getRolesForPrincipal(principal_id): """Get the roles granted to a principal. Return the list of (role id, setting) assigned or removed from this principal. If no roles have been assigned to this principal, then the empty list is returned. """ def getSetting(role_id, principal_id, default=Unset): """Return the setting for this principal, role combination """ def getPrincipalsAndRoles(): """Get all settings. Return all the principal/role combinations along with the setting for each combination as a sequence of tuples with the role id, principal id, and setting, in that order. """ class IPrincipalRoleManager(IPrincipalRoleMap): """Management interface for mappings between principals and roles.""" def assignRoleToPrincipal(role_id, principal_id): """Assign the role to the principal.""" def removeRoleFromPrincipal(role_id, principal_id): """Remove a role from the principal.""" def unsetRoleForPrincipal(role_id, principal_id): """Unset the role for the principal.""" class IRolePermissionMap(Interface): """Mappings between roles and permissions.""" def getPermissionsForRole(role_id): """Get the premissions granted to a role. Return a sequence of (permission id, setting) tuples for the given role. If no permissions have been granted to this role, then the empty list is returned. """ def getRolesForPermission(permission_id): """Get the roles that have a permission. Return a sequence of (role id, setting) tuples for the given permission. If no roles have been granted this permission, then the empty list is returned. """ def getSetting(permission_id, role_id, default=Unset): """Return the setting for the given permission id and role id If there is no setting, Unset is returned """ def getRolesAndPermissions(): """Return a sequence of (permission_id, role_id, setting) here. The settings are returned as a sequence of permission, role, setting tuples. If no principal/role assertions have been made here, then the empty list is returned. """ class IRolePermissionManager(IRolePermissionMap): """Management interface for mappings between roles and permissions.""" def grantPermissionToRole(permission_id, role_id): """Bind the permission to the role. """ def denyPermissionToRole(permission_id, role_id): """Deny the permission to the role """ def unsetPermissionFromRole(permission_id, role_id): """Clear the setting of the permission to the role. """ class IPrincipalPermissionMap(Interface): """Mappings between principals and permissions.""" def getPrincipalsForPermission(permission_id): """Get the principas that have a permission. Return the list of (principal_id, setting) tuples that describe security assertions for this permission. If no principals have been set for this permission, then the empty list is returned. """ def getPermissionsForPrincipal(principal_id): """Get the permissions granted to a principal. Return the list of (permission, setting) tuples that describe security assertions for this principal. If no permissions have been set for this principal, then the empty list is returned. """ def getSetting(permission_id, principal_id, default=Unset): """Get the setting for a permission and principal. Get the setting (Allow/Deny/Unset) for a given permission and principal. """ def getPrincipalsAndPermissions(): """Get all principal permission settings. Get the principal security assertions here in the form of a list of three tuple containing (permission id, principal id, setting) """ class IPrincipalPermissionManager(IPrincipalPermissionMap): """Management interface for mappings between principals and permissions.""" def grantPermissionToPrincipal(permission_id, principal_id): """Assert that the permission is allowed for the principal. """ def denyPermissionToPrincipal(permission_id, principal_id): """Assert that the permission is denied to the principal. """ def unsetPermissionForPrincipal(permission_id, principal_id): """Remove the permission (either denied or allowed) from the principal. """ class IGrantInfo(Interface): """Get grant info needed for checking access """ def principalPermissionGrant(principal, permission): """Return the principal-permission grant if any The return value is one of Allow, Deny, or Unset """ def getRolesForPermission(permission): """Return the role grants for the permission The role grants are an iterable of role, setting tuples, where setting is either Allow or Deny. """ def getRolesForPrincipal(principal): """Return the role grants for the principal The role grants are an iterable of role, setting tuples, where setting is either Allow or Deny. """ class IGrantVocabulary(Interface): """Marker interface for register the RadioWidget.""" zope.securitypolicy-3.7.0/src/zope/securitypolicy/meta.zcml000644 000766 000024 00000001255 11447361751 024154 0ustar00macstaff000000 000000 zope.securitypolicy-3.7.0/src/zope/securitypolicy/metaconfigure.py000644 000766 000024 00000006360 11447361751 025543 0ustar00macstaff000000 000000 ############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation 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. # ############################################################################## """ Register security related configuration directives. """ from zope.configuration.exceptions import ConfigurationError from zope.component.zcml import utility from zope.securitypolicy.interfaces import IRole from zope.securitypolicy.role import Role from zope.securitypolicy.rolepermission import \ rolePermissionManager as role_perm_mgr from zope.securitypolicy.principalpermission import \ principalPermissionManager as principal_perm_mgr from zope.securitypolicy.principalrole import \ principalRoleManager as principal_role_mgr def grant(_context, principal=None, role=None, permission=None): nspecified = ((principal is not None) + (role is not None) + (permission is not None)) if nspecified != 2: raise ConfigurationError( "Exactly two of the principal, role, and permission attributes " "must be specified") if principal: if role: _context.action( discriminator=('grantRoleToPrincipal', role, principal), callable=principal_role_mgr.assignRoleToPrincipal, args=(role, principal), ) else: _context.action( discriminator=('grantPermissionToPrincipal', permission, principal), callable=principal_perm_mgr.grantPermissionToPrincipal, args=(permission, principal), ) else: _context.action( discriminator=('grantPermissionToRole', permission, role), callable=role_perm_mgr.grantPermissionToRole, args=(permission, role), ) def grantAll(_context, principal=None, role=None): """Grant all permissions to a role or principal """ nspecified = ((principal is not None) + (role is not None)) if nspecified != 1: raise ConfigurationError( "Exactly one of the principal and role attributes " "must be specified") if principal: _context.action( discriminator=('grantAllPermissionsToPrincipal', principal), callable=principal_perm_mgr.grantAllPermissionsToPrincipal, args=(principal, ), ) else: _context.action( discriminator=('grantAllPermissionsToRole', role), callable=role_perm_mgr.grantAllPermissionsToRole, args=(role, ), ) def defineRole(_context, id, title, description=''): role = Role(id, title, description) utility(_context, IRole, role, name=id) zope.securitypolicy-3.7.0/src/zope/securitypolicy/metadirectives.py000644 000766 000024 00000002760 11447361751 025723 0ustar00macstaff000000 000000 ############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation 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. # ############################################################################## """Grant Directive Schema """ from zope.interface import Interface from zope.schema import Id from zope.security.zcml import Permission, IPermissionDirective class IGrantAllDirective(Interface): """Grant Permissions to roles and principals and roles to principals.""" principal = Id( title=u"Principal", description=u"Specifies the Principal to be mapped.", required=False) role = Id( title=u"Role", description=u"Specifies the Role to be mapped.", required=False) class IGrantDirective(IGrantAllDirective): """Grant Permissions to roles and principals and roles to principals.""" permission = Permission( title=u"Permission", description=u"Specifies the Permission to be mapped.", required=False) class IDefineRoleDirective(IPermissionDirective): """Define a new role.""" zope.securitypolicy-3.7.0/src/zope/securitypolicy/principalpermission.py000644 000766 000024 00000011122 11447361751 026775 0ustar00macstaff000000 000000 ############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation 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. # ############################################################################## """Mappings between principals and permissions, stored in an object locally. """ from zope.interface import implements from zope.security.permission import allPermissions from zope.authentication.principal import checkPrincipal from zope.securitypolicy.interfaces import Allow, Deny, Unset from zope.securitypolicy.interfaces import IPrincipalPermissionManager from zope.securitypolicy.securitymap import SecurityMap from zope.securitypolicy.securitymap import AnnotationSecurityMap class AnnotationPrincipalPermissionManager(AnnotationSecurityMap): """Mappings between principals and permissions.""" # the annotation key is a holdover from this module's old # location, but cannot change without breaking existing databases # It is also is misspelled, but that's OK. It just has to be unique. # we'll keep it as is, to prevent breaking old data: key = 'zopel.app.security.AnnotationPrincipalPermissionManager' implements(IPrincipalPermissionManager) def grantPermissionToPrincipal(self, permission_id, principal_id): AnnotationSecurityMap.addCell(self, permission_id, principal_id, Allow) def denyPermissionToPrincipal(self, permission_id, principal_id): AnnotationSecurityMap.addCell(self, permission_id, principal_id, Deny) unsetPermissionForPrincipal = AnnotationSecurityMap.delCell getPrincipalsForPermission = AnnotationSecurityMap.getRow getPermissionsForPrincipal = AnnotationSecurityMap.getCol def getSetting(self, permission_id, principal_id, default=Unset): return AnnotationSecurityMap.queryCell( self, permission_id, principal_id, default) getPrincipalsAndPermissions = AnnotationSecurityMap.getAllCells class PrincipalPermissionManager(SecurityMap): """Mappings between principals and permissions.""" implements(IPrincipalPermissionManager) def grantPermissionToPrincipal(self, permission_id, principal_id, check=True): ''' See the interface IPrincipalPermissionManager ''' if check: checkPrincipal(None, principal_id) self.addCell(permission_id, principal_id, Allow) def grantAllPermissionsToPrincipal(self, principal_id): ''' See the interface IPrincipalPermissionManager ''' for permission_id in allPermissions(None): self.grantPermissionToPrincipal(permission_id, principal_id, False) def denyPermissionToPrincipal(self, permission_id, principal_id, check=True): ''' See the interface IPrincipalPermissionManager ''' if check: checkPrincipal(None, principal_id) self.addCell(permission_id, principal_id, Deny) def unsetPermissionForPrincipal(self, permission_id, principal_id): ''' See the interface IPrincipalPermissionManager ''' # Don't check validity intentionally. # After all, we certianly want to unset invalid ids. self.delCell(permission_id, principal_id) def getPrincipalsForPermission(self, permission_id): ''' See the interface IPrincipalPermissionManager ''' return self.getRow(permission_id) def getPermissionsForPrincipal(self, principal_id): ''' See the interface IPrincipalPermissionManager ''' return self.getCol(principal_id) def getSetting(self, permission_id, principal_id, default=Unset): ''' See the interface IPrincipalPermissionManager ''' return self.queryCell(permission_id, principal_id, default) def getPrincipalsAndPermissions(self): ''' See the interface IPrincipalPermissionManager ''' return self.getAllCells() # Permissions are our rows, and principals are our columns principalPermissionManager = PrincipalPermissionManager() # Register our cleanup with Testing.CleanUp to make writing unit tests # simpler. try: from zope.testing.cleanup import addCleanUp except ImportError: pass else: addCleanUp(principalPermissionManager._clear) del addCleanUp zope.securitypolicy-3.7.0/src/zope/securitypolicy/principalrole.py000644 000766 000024 00000007647 11447361751 025567 0ustar00macstaff000000 000000 ############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation 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. # ############################################################################## """Mappings between principals and roles, stored in an object locally. """ from zope.interface import implements from zope.authentication.principal import checkPrincipal from zope.securitypolicy.interfaces import Allow, Deny, Unset from zope.securitypolicy.interfaces import IPrincipalRoleManager from zope.securitypolicy.securitymap import SecurityMap from zope.securitypolicy.securitymap import AnnotationSecurityMap from zope.securitypolicy.role import checkRole class AnnotationPrincipalRoleManager(AnnotationSecurityMap): """Mappings between principals and roles.""" # the annotation key is a holdover from this module's old # location, but cannot change without breaking existing databases key = 'zope.app.security.AnnotationPrincipalRoleManager' implements(IPrincipalRoleManager) def assignRoleToPrincipal(self, role_id, principal_id): AnnotationSecurityMap.addCell(self, role_id, principal_id, Allow) def removeRoleFromPrincipal(self, role_id, principal_id): AnnotationSecurityMap.addCell(self, role_id, principal_id, Deny) unsetRoleForPrincipal = AnnotationSecurityMap.delCell getPrincipalsForRole = AnnotationSecurityMap.getRow getRolesForPrincipal = AnnotationSecurityMap.getCol def getSetting(self, role_id, principal_id, default=Unset): return AnnotationSecurityMap.queryCell( self, role_id, principal_id, default) getPrincipalsAndRoles = AnnotationSecurityMap.getAllCells class PrincipalRoleManager(SecurityMap): """Mappings between principals and roles.""" implements(IPrincipalRoleManager) def assignRoleToPrincipal(self, role_id, principal_id, check=True): ''' See the interface IPrincipalRoleManager ''' if check: checkPrincipal(None, principal_id) checkRole(None, role_id) self.addCell(role_id, principal_id, Allow) def removeRoleFromPrincipal(self, role_id, principal_id, check=True): ''' See the interface IPrincipalRoleManager ''' if check: checkPrincipal(None, principal_id) checkRole(None, role_id) self.addCell(role_id, principal_id, Deny) def unsetRoleForPrincipal(self, role_id, principal_id): ''' See the interface IPrincipalRoleManager ''' # Don't check validity intentionally. # After all, we certainly want to unset invalid ids. self.delCell(role_id, principal_id) def getPrincipalsForRole(self, role_id): ''' See the interface IPrincipalRoleMap ''' return self.getRow(role_id) def getRolesForPrincipal(self, principal_id): ''' See the interface IPrincipalRoleMap ''' return self.getCol(principal_id) def getSetting(self, role_id, principal_id, default=Unset): ''' See the interface IPrincipalRoleMap ''' return self.queryCell(role_id, principal_id, default) def getPrincipalsAndRoles(self): ''' See the interface IPrincipalRoleMap ''' return self.getAllCells() # Roles are our rows, and principals are our columns principalRoleManager = PrincipalRoleManager() # Register our cleanup with Testing.CleanUp to make writing unit tests # simpler. try: from zope.testing.cleanup import addCleanUp except ImportError: pass else: addCleanUp(principalRoleManager._clear) del addCleanUp zope.securitypolicy-3.7.0/src/zope/securitypolicy/role.py000644 000766 000024 00000006221 11447361751 023650 0ustar00macstaff000000 000000 ############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation 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. # ############################################################################## """Role implementation """ __docformat__ = 'restructuredtext' from persistent import Persistent from zope.interface import implements from zope.component import getUtilitiesFor from zope.location import Location from zope.securitypolicy.interfaces import IRole from zope.i18nmessageid import ZopeMessageFactory as _ NULL_ID = _('') class Role(object): implements(IRole) def __init__(self, id, title, description=""): self.id = id self.title = title self.description = description class LocalRole(Persistent, Location): implements(IRole) def __init__(self, title, description=""): self.id = NULL_ID self.title = title self.description = description def setIdOnActivation(role, event): """Set the permission id upon registration activation. Let's see how this notifier can be used. First we need to create an event using the permission instance and a registration stub: >>> class Registration: ... def __init__(self, obj, name): ... self.component = obj ... self.name = name >>> role1 = LocalRole('Role 1', 'A first role') >>> role1.id u'' >>> import zope.component.interfaces >>> event = zope.component.interfaces.Registered( ... Registration(role1, 'role1')) Now we pass the event into this function, and the id of the role should be set to 'role1'. >>> setIdOnActivation(role1, event) >>> role1.id 'role1' """ role.id = event.object.name def unsetIdOnDeactivation(role, event): """Unset the permission id up registration deactivation. Let's see how this notifier can be used. First we need to create an event using the permission instance and a registration stub: >>> class Registration: ... def __init__(self, obj, name): ... self.component = obj ... self.name = name >>> role1 = LocalRole('Role 1', 'A first role') >>> role1.id = 'role1' >>> import zope.component.interfaces >>> event = zope.component.interfaces.Unregistered( ... Registration(role1, 'role1')) Now we pass the event into this function, and the id of the role should be set to NULL_ID. >>> unsetIdOnDeactivation(role1, event) >>> role1.id u'' """ role.id = NULL_ID def checkRole(context, role_id): names = [name for name, util in getUtilitiesFor(IRole, context)] if not role_id in names: raise ValueError("Undefined role id", role_id) zope.securitypolicy-3.7.0/src/zope/securitypolicy/rolepermission.py000644 000766 000024 00000007751 11447361751 025772 0ustar00macstaff000000 000000 ############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation 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. # ############################################################################## """Permission to Roles Manager (Adapter) """ from zope.interface import implements from zope.security.permission import allPermissions from zope.securitypolicy.role import checkRole from zope.securitypolicy.interfaces import Allow, Deny, Unset from zope.securitypolicy.interfaces import IRolePermissionManager from zope.securitypolicy.securitymap import AnnotationSecurityMap from zope.securitypolicy.securitymap import SecurityMap class AnnotationRolePermissionManager(AnnotationSecurityMap): """Provide adapter that manages role permission data in an object attribute """ # the annotation key is a holdover from this module's old # location, but cannot change without breaking existing databases key = 'zope.app.security.AnnotationRolePermissionManager' implements(IRolePermissionManager) def grantPermissionToRole(self, permission_id, role_id): AnnotationSecurityMap.addCell(self, permission_id, role_id, Allow) def denyPermissionToRole(self, permission_id, role_id): AnnotationSecurityMap.addCell(self, permission_id, role_id, Deny) unsetPermissionFromRole = AnnotationSecurityMap.delCell getRolesForPermission = AnnotationSecurityMap.getRow getPermissionsForRole = AnnotationSecurityMap.getCol getRolesAndPermissions = AnnotationSecurityMap.getAllCells def getSetting(self, permission_id, role_id, default=Unset): return AnnotationSecurityMap.queryCell( self, permission_id, role_id, default) class RolePermissionManager(SecurityMap): """Mappings between roles and permissions.""" implements(IRolePermissionManager) def grantPermissionToRole(self, permission_id, role_id, check=True): '''See interface IRolePermissionMap''' if check: checkRole(None, role_id) self.addCell(permission_id, role_id, Allow) def grantAllPermissionsToRole(self, role_id): for permission_id in allPermissions(None): self.grantPermissionToRole(permission_id, role_id, False) def denyPermissionToRole(self, permission_id, role_id, check=True): '''See interface IRolePermissionMap''' if check: checkRole(None, role_id) self.addCell(permission_id, role_id, Deny) def unsetPermissionFromRole(self, permission_id, role_id): '''See interface IRolePermissionMap''' # Don't check validity intentionally. # After all, we certianly want to unset invalid ids. self.delCell(permission_id, role_id) def getRolesForPermission(self, permission_id): '''See interface IRolePermissionMap''' return self.getRow(permission_id) def getPermissionsForRole(self, role_id): '''See interface IRolePermissionMap''' return self.getCol(role_id) def getSetting(self, permission_id, role_id, default=Unset): '''See interface IRolePermissionMap''' return self.queryCell(permission_id, role_id, default) def getRolesAndPermissions(self): '''See interface IRolePermissionMap''' return self.getAllCells() # Permissions are our rows, and roles are our columns rolePermissionManager = RolePermissionManager() # Register our cleanup with Testing.CleanUp to make writing unit tests # simpler. try: from zope.testing.cleanup import addCleanUp except ImportError: pass else: addCleanUp(rolePermissionManager._clear) del addCleanUp zope.securitypolicy-3.7.0/src/zope/securitypolicy/securitymap.py000644 000766 000024 00000011272 11447361751 025256 0ustar00macstaff000000 000000 ############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation 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 two-dimensional array type (in context of security) """ from persistent import Persistent from zope.annotation import IAnnotations from zope.security.management import queryInteraction class SecurityMap(object): def __init__(self): self._clear() def _clear(self): self._byrow = {} self._bycol = {} def __nonzero__(self): return bool(self._byrow) def addCell(self, rowentry, colentry, value): # setdefault may get expensive if an empty mapping is # expensive to create, for PersistentDict for instance. row = self._byrow.get(rowentry) if row: if row.get(colentry) is value: return False else: row = self._byrow[rowentry] = {} col = self._bycol.get(colentry) if not col: col = self._bycol[colentry] = {} row[colentry] = value col[rowentry] = value self._invalidated_interaction_cache() return True def _invalidated_interaction_cache(self): # Invalidate this threads interaction cache interaction = queryInteraction() if interaction is not None: try: invalidate_cache = interaction.invalidate_cache except AttributeError: pass else: invalidate_cache() def delCell(self, rowentry, colentry): row = self._byrow.get(rowentry) if row and (colentry in row): del row[colentry] if not row: del self._byrow[rowentry] col = self._bycol[colentry] del col[rowentry] if not col: del self._bycol[colentry] self._invalidated_interaction_cache() return True return False def queryCell(self, rowentry, colentry, default=None): row = self._byrow.get(rowentry) if row: return row.get(colentry, default) else: return default def getCell(self, rowentry, colentry): marker = object() cell = self.queryCell(rowentry, colentry, marker) if cell is marker: raise KeyError('Not a valid row and column pair.') return cell def getRow(self, rowentry): row = self._byrow.get(rowentry) if row: return row.items() else: return [] def getCol(self, colentry): col = self._bycol.get(colentry) if col: return col.items() else: return [] def getAllCells(self): res = [] for r in self._byrow.keys(): for c in self._byrow[r].items(): res.append((r,) + c) return res class PersistentSecurityMap(SecurityMap, Persistent): def addCell(self, rowentry, colentry, value): if SecurityMap.addCell(self, rowentry, colentry, value): self._p_changed = 1 def delCell(self, rowentry, colentry): if SecurityMap.delCell(self, rowentry, colentry): self._p_changed = 1 class AnnotationSecurityMap(SecurityMap): def __init__(self, context): self.__parent__ = context self._context = context annotations = IAnnotations(self._context) map = annotations.get(self.key) if map is None: self._byrow = {} self._bycol = {} else: self._byrow = map._byrow self._bycol = map._bycol self.map = map def _changed(self): map = self.map if isinstance(map, PersistentSecurityMap): map._p_changed = 1 else: map = PersistentSecurityMap() map._byrow = self._byrow map._bycol = self._bycol annotations = IAnnotations(self._context) annotations[self.key] = map def addCell(self, rowentry, colentry, value): if SecurityMap.addCell(self, rowentry, colentry, value): self._changed() def delCell(self, rowentry, colentry): if SecurityMap.delCell(self, rowentry, colentry): self._changed() zope.securitypolicy-3.7.0/src/zope/securitypolicy/securitypolicy.zcml000644 000766 000024 00000001737 11447361751 026322 0ustar00macstaff000000 000000 zope.securitypolicy-3.7.0/src/zope/securitypolicy/settings.py000644 000766 000024 00000004531 11447361751 024551 0ustar00macstaff000000 000000 ############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation 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 setting constants. The `Allow`, `Deny`, and `Unset` constants are exposed by the `zope.securitypolicy.interfaces` module, and should be imported from there. """ class PermissionSetting(object): """PermissionSettings should be considered as immutable. They can be compared by identity. They are identified by their name. """ def __new__(cls, name, description=None): """Keep a dict of PermissionSetting instances, indexed by name. If the name already exists in the dict, return that instance rather than creating a new one. """ instances = cls.__dict__.get('_z_instances') if instances is None: cls._z_instances = instances = {} it = instances.get(name) if it is None: instances[name] = it = object.__new__(cls) it._init(name, description) return it def _init(self, name, description): self.__name = name self.__description = description def getDescription(self): return self.__description def getName(self): return self.__name def __str__(self): return "PermissionSetting: %s" % self.__name __repr__ = __str__ # register PermissionSettings to be symbolic constants by identity, # even when pickled and unpickled. import copy_reg copy_reg.constructor(PermissionSetting) copy_reg.pickle(PermissionSetting, PermissionSetting.getName, PermissionSetting) Allow = PermissionSetting('Allow', 'Explicit allow setting for permissions') Deny = PermissionSetting('Deny', 'Explicit deny setting for permissions') Unset = PermissionSetting('Unset', 'Unset constant that denotes no setting for permission') zope.securitypolicy-3.7.0/src/zope/securitypolicy/tests/000755 000766 000024 00000000000 11447361755 023502 5ustar00macstaff000000 000000 zope.securitypolicy-3.7.0/src/zope/securitypolicy/vocabulary.py000644 000766 000024 00000005030 11447361751 025053 0ustar00macstaff000000 000000 ############################################################################## # # Copyright (c) 2004 Zope Foundation 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. # ############################################################################## """Role Id Vocabulary. This vocabulary provides role IDs. """ __docformat__ = 'restructuredtext' import zope.component from zope.interface import implements, classProvides from zope.schema.vocabulary import SimpleTerm, SimpleVocabulary from zope.schema.interfaces import IVocabularyFactory from zope.securitypolicy.interfaces import IRole from zope.securitypolicy.interfaces import IGrantVocabulary class RoleIdsVocabulary(SimpleVocabulary): """A vocabular of role IDs. Term values are the role ID strings Term are stored by title To illustrate, we need to register the role IDs vocab: >>> from zope.schema import vocabulary >>> from zope.component.testing import setUp, tearDown >>> setUp() >>> vocabulary.setVocabularyRegistry(None) >>> registry = vocabulary.getVocabularyRegistry() >>> registry.register('Role Ids', RoleIdsVocabulary) Let's register some sample roles to test against them >>> from zope.securitypolicy.interfaces import IRole >>> from zope.securitypolicy.role import Role >>> from zope.component import provideUtility >>> provideUtility(Role('a_id','a_title'), IRole, 'a_id') >>> provideUtility(Role('b_id','b_title'), IRole, 'b_id') Let's lookup the roles using the vocabulary >>> vocab = registry.get(None, 'Role Ids') >>> vocab.getTermByToken('a_id').value u'a_id' >>> vocab.getTermByToken('b_id').value u'b_id' >>> tearDown() """ classProvides(IVocabularyFactory) def __init__(self, context): terms = [] roles = zope.component.getUtilitiesFor(IRole, context) for name, role in roles: terms.append(SimpleTerm(name, name, name)) super(RoleIdsVocabulary, self).__init__(terms) class GrantVocabulary(SimpleVocabulary): """A vocabular for getting the RadioWidget via the Choice field.""" classProvides(IVocabularyFactory) implements(IGrantVocabulary) zope.securitypolicy-3.7.0/src/zope/securitypolicy/zopepolicy.py000644 000766 000024 00000031064 11447361751 025107 0ustar00macstaff000000 000000 ############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation 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. # ############################################################################## """Define Zope's default security policy """ import zope.interface from zope.component import getUtility from zope.security.checker import CheckerPublic from zope.security.management import system_user from zope.security.simplepolicies import ParanoidSecurityPolicy from zope.security.interfaces import ISecurityPolicy from zope.security.proxy import removeSecurityProxy from zope.authentication.interfaces import ( PrincipalLookupError, IAuthentication) from zope.securitypolicy.principalpermission import principalPermissionManager globalPrincipalPermissionSetting = principalPermissionManager.getSetting from zope.securitypolicy.rolepermission import rolePermissionManager globalRolesForPermission = rolePermissionManager.getRolesForPermission from zope.securitypolicy.principalrole import principalRoleManager globalRolesForPrincipal = principalRoleManager.getRolesForPrincipal from zope.securitypolicy.interfaces import Allow, Deny, Unset from zope.securitypolicy.interfaces import IRolePermissionMap from zope.securitypolicy.interfaces import IPrincipalPermissionMap from zope.securitypolicy.interfaces import IPrincipalRoleMap SettingAsBoolean = {Allow: True, Deny: False, Unset: None, None: None} class CacheEntry: pass class ZopeSecurityPolicy(ParanoidSecurityPolicy): zope.interface.classProvides(ISecurityPolicy) def __init__(self, *args, **kw): ParanoidSecurityPolicy.__init__(self, *args, **kw) self._cache = {} def invalidate_cache(self): self._cache = {} def cache(self, parent): cache = self._cache.get(id(parent)) if cache: cache = cache[0] else: cache = CacheEntry() self._cache[id(parent)] = cache, parent return cache def cached_decision(self, parent, principal, groups, permission): # Return the decision for a principal and permission cache = self.cache(parent) try: cache_decision = cache.decision except AttributeError: cache_decision = cache.decision = {} cache_decision_prin = cache_decision.get(principal) if not cache_decision_prin: cache_decision_prin = cache_decision[principal] = {} try: return cache_decision_prin[permission] except KeyError: pass # cache_decision_prin[permission] is the cached decision for a # principal and permission. decision = self.cached_prinper(parent, principal, groups, permission) if (decision is None) and groups: decision = self._group_based_cashed_prinper(parent, principal, groups, permission) if decision is not None: cache_decision_prin[permission] = decision return decision roles = self.cached_roles(parent, permission) if roles: prin_roles = self.cached_principal_roles(parent, principal) if groups: prin_roles = self.cached_principal_roles_w_groups( parent, principal, groups, prin_roles) for role, setting in prin_roles.items(): if setting and (role in roles): cache_decision_prin[permission] = decision = True return decision cache_decision_prin[permission] = decision = False return decision def cached_prinper(self, parent, principal, groups, permission): # Compute the permission, if any, for the principal. cache = self.cache(parent) try: cache_prin = cache.prin except AttributeError: cache_prin = cache.prin = {} cache_prin_per = cache_prin.get(principal) if not cache_prin_per: cache_prin_per = cache_prin[principal] = {} try: return cache_prin_per[permission] except KeyError: pass if parent is None: prinper = SettingAsBoolean[ globalPrincipalPermissionSetting(permission, principal, None)] cache_prin_per[permission] = prinper return prinper prinper = IPrincipalPermissionMap(parent, None) if prinper is not None: prinper = SettingAsBoolean[ prinper.getSetting(permission, principal, None)] if prinper is not None: cache_prin_per[permission] = prinper return prinper parent = removeSecurityProxy(getattr(parent, '__parent__', None)) prinper = self.cached_prinper(parent, principal, groups, permission) cache_prin_per[permission] = prinper return prinper def _group_based_cashed_prinper(self, parent, principal, groups, permission): denied = False for group_id, ggroups in groups: decision = self.cached_prinper(parent, group_id, ggroups, permission) if (decision is None) and ggroups: decision = self._group_based_cashed_prinper( parent, group_id, ggroups, permission) if decision is None: continue if decision: return decision denied = True if denied: return False return None def cached_roles(self, parent, permission): cache = self.cache(parent) try: cache_roles = cache.roles except AttributeError: cache_roles = cache.roles = {} try: return cache_roles[permission] except KeyError: pass if parent is None: roles = dict( [(role, 1) for (role, setting) in globalRolesForPermission(permission) if setting is Allow]) cache_roles[permission] = roles return roles roles = self.cached_roles( removeSecurityProxy(getattr(parent, '__parent__', None)), permission) roleper = IRolePermissionMap(parent, None) if roleper: roles = roles.copy() for role, setting in roleper.getRolesForPermission(permission): if setting is Allow: roles[role] = 1 elif role in roles: del roles[role] cache_roles[permission] = roles return roles def cached_principal_roles_w_groups(self, parent, principal, groups, prin_roles): denied = {} allowed = {} for group_id, ggroups in groups: group_roles = dict(self.cached_principal_roles(parent, group_id)) if ggroups: group_roles = self.cached_principal_roles_w_groups( parent, group_id, ggroups, group_roles) for role, setting in group_roles.items(): if setting: allowed[role] = setting else: denied[role] = setting denied.update(allowed) denied.update(prin_roles) return denied def cached_principal_roles(self, parent, principal): cache = self.cache(parent) try: cache_principal_roles = cache.principal_roles except AttributeError: cache_principal_roles = cache.principal_roles = {} try: return cache_principal_roles[principal] except KeyError: pass if parent is None: roles = dict( [(role, SettingAsBoolean[setting]) for (role, setting) in globalRolesForPrincipal(principal)]) roles['zope.Anonymous'] = True # Everybody has Anonymous cache_principal_roles[principal] = roles return roles roles = self.cached_principal_roles( removeSecurityProxy(getattr(parent, '__parent__', None)), principal) prinrole = IPrincipalRoleMap(parent, None) if prinrole: roles = roles.copy() for role, setting in prinrole.getRolesForPrincipal(principal): roles[role] = SettingAsBoolean[setting] cache_principal_roles[principal] = roles return roles def checkPermission(self, permission, object): if permission is CheckerPublic: return True object = removeSecurityProxy(object) seen = {} for participation in self.participations: principal = participation.principal if principal is system_user: continue # always allow system_user if principal.id in seen: continue if not self.cached_decision( object, principal.id, self._groupsFor(principal), permission, ): return False seen[principal.id] = 1 return True def _findGroupsFor(self, principal, getPrincipal, seen): result = [] for group_id in getattr(principal, 'groups', ()): if group_id in seen: # Dang, we have a cycle. We don't want to # raise an exception here (or do we), so we'll skip it continue seen.append(group_id) try: group = getPrincipal(group_id) except PrincipalLookupError: # It's bad if we have an undefined principal, # but we don't want to fail here. But we won't # honor any grants for the group. We'll just skip it. continue result.append((group_id, self._findGroupsFor(group, getPrincipal, seen))) seen.pop() return tuple(result) def _groupsFor(self, principal): groups = self._cache.get(principal.id) if groups is None: groups = getattr(principal, 'groups', ()) if groups: getPrincipal = getUtility(IAuthentication).getPrincipal groups = self._findGroupsFor(principal, getPrincipal, []) else: groups = () self._cache[principal.id] = groups return groups def settingsForObject(ob): """Analysis tool to show all of the grants to a process """ result = [] while ob is not None: data = {} result.append((getattr(ob, '__name__', '(no name)'), data)) principalPermissions = IPrincipalPermissionMap(ob, None) if principalPermissions is not None: settings = principalPermissions.getPrincipalsAndPermissions() settings.sort() data['principalPermissions'] = [ {'principal': pr, 'permission': p, 'setting': s} for (p, pr, s) in settings] principalRoles = IPrincipalRoleMap(ob, None) if principalRoles is not None: settings = principalRoles.getPrincipalsAndRoles() data['principalRoles'] = [ {'principal': p, 'role': r, 'setting': s} for (r, p, s) in settings] rolePermissions = IRolePermissionMap(ob, None) if rolePermissions is not None: settings = rolePermissions.getRolesAndPermissions() data['rolePermissions'] = [ {'permission': p, 'role': r, 'setting': s} for (p, r, s) in settings] ob = getattr(ob, '__parent__', None) data = {} result.append(('global settings', data)) settings = principalPermissionManager.getPrincipalsAndPermissions() settings.sort() data['principalPermissions'] = [ {'principal': pr, 'permission': p, 'setting': s} for (p, pr, s) in settings] settings = principalRoleManager.getPrincipalsAndRoles() data['principalRoles'] = [ {'principal': p, 'role': r, 'setting': s} for (r, p, s) in settings] settings = rolePermissionManager.getRolesAndPermissions() data['rolePermissions'] = [ {'permission': p, 'role': r, 'setting': s} for (p, r, s) in settings] return result zope.securitypolicy-3.7.0/src/zope/securitypolicy/zopepolicy.txt000644 000766 000024 00000045143 11447361751 025301 0ustar00macstaff000000 000000 ============================ Classic Zope Security Policy ============================ This package implements a role-based security policy similar to the policy found in Zope 2. The security policy is responsible for deciding whether an interaction has a permission on an object. This security policy does this using grant and denial information. Managers can grant or deny: - roles to principals, - permissions to principals, and - permissions to roles Grants and denials are stored as annotations on objects. To store grants and denials, objects must be annotatable: >>> import zope.interface >>> from zope.annotation.interfaces import IAttributeAnnotatable >>> class Ob: ... zope.interface.implements(IAttributeAnnotatable) >>> ob = Ob() We use objects to represent principals. These objects implement an interface named `IPrincipal`, but the security policy only uses the `id` and `groups` attributes: >>> class Principal: ... def __init__(self, id): ... self.id = id ... self.groups = [] >>> principal = Principal('bob') Roles and permissions are also represented by objects, however, for the purposes of the security policy, only string `ids` are used. The security policy provides a factory for creating interactions: >>> import zope.securitypolicy.zopepolicy >>> interaction = zope.securitypolicy.zopepolicy.ZopeSecurityPolicy() An interaction represents a specific interaction between some principals (normally users) and the system. Normally, we are only concerned with the interaction of one principal with the system, although we can have interactions of multiple principals. Multiple-principal interactions normally occur when untrusted users store code on a system for later execution. When untrusted code is executing, the authors of the code participate in the interaction. An interaction has a permission on an object only if all of the principals participating in the interaction have access to the object. The `checkPermission` method on interactions is used to test whether an interaction has a permission for an object. An interaction without participants always has every permission: >>> interaction.checkPermission('P1', ob) True In this example, 'P1' is a permission id. Normally, interactions have participants: >>> class Participation: ... interaction = None >>> participation = Participation() >>> participation.principal = principal >>> interaction.add(participation) If we have participants, then we don't have a permission unless there are grants: >>> interaction.checkPermission('P1', ob) False Note, however, that we always have the CheckerPublic permission: >>> from zope.security.checker import CheckerPublic >>> interaction.checkPermission(CheckerPublic, ob) True We make grants and denials on objects by adapting them to various granting interfaces. The objects returned from the adaptation are object-specific manager objects: >>> from zope.securitypolicy import interfaces >>> roleper = interfaces.IRolePermissionManager(ob) >>> prinrole = interfaces.IPrincipalRoleManager(ob) >>> prinper = interfaces.IPrincipalPermissionManager(ob) The computations involved in checking permissions can be significant. To reduce the computational cost, caching is used extensively. We could invalidate the cache as we make grants, but the adapters for making grants will automatically invalidate the cache of the current interaction. They use the security-management apis to do this. To take advantage of the cache invalidation, we'll need to let the security-management system manage our interactions. First, we'll set our security policy as the default: >>> import zope.security.management >>> oldpolicy = zope.security.management.setSecurityPolicy( ... zope.securitypolicy.zopepolicy.ZopeSecurityPolicy) and then we'll create a new interaction: >>> participation = Participation() >>> participation.principal = principal >>> zope.security.management.newInteraction(participation) >>> interaction = zope.security.management.getInteraction() We normally provide access by granting permissions to roles for an object: >>> roleper.grantPermissionToRole('P1', 'R1') and then granting roles to principals for an object (local roles): >>> prinrole.assignRoleToPrincipal('R1', 'bob') The combination of these grants, which we call a role-based grant, provides the permission: >>> interaction.checkPermission('P1', ob) True We can also provide a permission directly: >>> prinper.grantPermissionToPrincipal('P2', 'bob') >>> interaction.checkPermission('P2', ob) True Permission grants or denials override role-based grant or denials. So if we deny P1: >>> prinper.denyPermissionToPrincipal('P1', 'bob') we cause the interaction to lack the permission, despite the role grants: >>> interaction.checkPermission('P1', ob) False Similarly, even if we have a role-based denial of P2: >>> roleper.denyPermissionToRole('P2', 'R1') we still have access, because of the permission-based grant: >>> interaction.checkPermission('P2', ob) True A role-based denial doesn't actually deny a permission; rather it prevents the granting of a permission. So, if we have both grants and denials based on roles, we have access: >>> roleper.grantPermissionToRole('P3', 'R1') >>> roleper.grantPermissionToRole('P3', 'R2') >>> roleper.denyPermissionToRole('P3', 'R3') >>> prinrole.removeRoleFromPrincipal('R2', 'bob') >>> prinrole.assignRoleToPrincipal('R3', 'bob') >>> interaction.checkPermission('P3', ob) True Global grants ------------- Grants made to an object are said to be "local". We can also make global grants: >>> from zope.securitypolicy.rolepermission import \ ... rolePermissionManager as roleperG >>> from zope.securitypolicy.principalpermission import \ ... principalPermissionManager as prinperG >>> from zope.securitypolicy.principalrole import \ ... principalRoleManager as prinroleG And the same rules apply to global grants and denials. >>> roleperG.grantPermissionToRole('P1G', 'R1G', False) In these tests, we aren't bothering to define any roles, permissions, or principals, so we pass an extra argument that tells the granting routines not to check the validity of the values. >>> prinroleG.assignRoleToPrincipal('R1G', 'bob', False) >>> interaction.checkPermission('P1G', ob) True >>> prinperG.grantPermissionToPrincipal('P2G', 'bob', False) >>> interaction.checkPermission('P2G', ob) True >>> prinperG.denyPermissionToPrincipal('P1G', 'bob', False) >>> interaction.checkPermission('P1G', ob) False >>> roleperG.denyPermissionToRole('P2G', 'R1G', False) >>> interaction.checkPermission('P2G', ob) True >>> roleperG.grantPermissionToRole('P3G', 'R1G', False) >>> roleperG.grantPermissionToRole('P3G', 'R2G', False) >>> roleperG.denyPermissionToRole('P3G', 'R3G', False) >>> prinroleG.removeRoleFromPrincipal('R2G', 'bob', False) >>> prinroleG.assignRoleToPrincipal('R3G', 'bob', False) >>> interaction.checkPermission('P3G', ob) True Local versus global grants -------------------------- We, of course, acquire global grants by default: >>> interaction.checkPermission('P1G', ob) False >>> interaction.checkPermission('P2G', ob) True >>> interaction.checkPermission('P3G', ob) True Local role-based grants do not override global principal-specific denials: >>> roleper.grantPermissionToRole('P1G', 'R1G') >>> prinrole.assignRoleToPrincipal('R1G', 'bob') >>> interaction.checkPermission('P1G', ob) False And local role-based denials don't override global principal-grants: >>> roleper.denyPermissionToRole('P2G', 'R1G') >>> interaction.checkPermission('P2G', ob) True A local role-based deny can cancel a global role-based grant: >>> roleper.denyPermissionToRole('P3G', 'R1G') >>> interaction.checkPermission('P3G', ob) False and a local role-based grant can override a global role-based denial: >>> roleperG.denyPermissionToRole('P4G', 'R1G', False) >>> prinroleG.assignRoleToPrincipal('R1G', "bob", False) >>> interaction.checkPermission('P4G', ob) False >>> roleper.grantPermissionToRole('P4G', 'R1G') >>> interaction.checkPermission('P4G', ob) True >>> prinroleG.removeRoleFromPrincipal('R1G', "bob", False) >>> interaction.checkPermission('P4G', ob) True Of course, a local permission-based grant or denial overrides any global setting and overrides local role-based grants or denials: >>> prinper.grantPermissionToPrincipal('P3G', 'bob') >>> interaction.checkPermission('P3G', ob) True >>> prinper.denyPermissionToPrincipal('P2G', 'bob') >>> interaction.checkPermission('P2G', ob) False Sublocations ------------ We can have sub-locations. A sublocation of a location is an object whose `__parent__` attribute is the location: >>> ob2 = Ob() >>> ob2.__parent__ = ob By default, sublocations acquire grants from higher locations: >>> interaction.checkPermission('P1', ob2) False >>> interaction.checkPermission('P2', ob2) True >>> interaction.checkPermission('P3', ob2) True >>> interaction.checkPermission('P1G', ob2) False >>> interaction.checkPermission('P2G', ob2) False >>> interaction.checkPermission('P3G', ob2) True >>> interaction.checkPermission('P4G', ob2) True Sublocation role-based grants do not override their parent principal-specific denials: >>> roleper2 = interfaces.IRolePermissionManager(ob2) >>> prinrole2 = interfaces.IPrincipalRoleManager(ob2) >>> prinper2 = interfaces.IPrincipalPermissionManager(ob2) >>> roleper2.grantPermissionToRole('P1', 'R1') >>> prinrole2.assignRoleToPrincipal('R1', 'bob') >>> interaction.checkPermission('P1', ob2) False And local role-based denials don't override their parents principal-grant: >>> roleper2.denyPermissionToRole('P2', 'R1') >>> interaction.checkPermission('P2', ob2) True A local role-based deny can cancel a parent role-based grant: >>> roleper2.denyPermissionToRole('P3', 'R1') >>> interaction.checkPermission('P3', ob2) False and a local role-based grant can override a parent role-based denial: >>> roleper.denyPermissionToRole('P4', 'R1') >>> prinrole.assignRoleToPrincipal('R1', 'bob') >>> interaction.checkPermission('P4', ob2) False >>> roleper2.grantPermissionToRole('P4', 'R1') >>> interaction.checkPermission('P4', ob2) True >>> prinrole.removeRoleFromPrincipal('R1', 'bob') >>> interaction.checkPermission('P4', ob2) True Of course, a local permission-based grant or denial overrides any global setting and overrides local role-based grants or denials: >>> prinper.grantPermissionToPrincipal('P3', 'bob') >>> interaction.checkPermission('P3', ob2) True >>> prinper.denyPermissionToPrincipal('P2', 'bob') >>> interaction.checkPermission('P2', ob2) False If an object is not annotatable, but does have a parent, it will get its grants from its parent: >>> class C: ... pass >>> ob3 = C() >>> ob3.__parent__ = ob >>> interaction.checkPermission('P1', ob3) False >>> interaction.checkPermission('P2', ob3) False >>> interaction.checkPermission('P3', ob3) True >>> interaction.checkPermission('P1G', ob3) False >>> interaction.checkPermission('P2G', ob3) False >>> interaction.checkPermission('P3G', ob3) True >>> interaction.checkPermission('P4G', ob3) True The same results will be had if there are multiple non-annotatable objects: >>> ob3.__parent__ = C() >>> ob3.__parent__.__parent__ = ob >>> interaction.checkPermission('P1', ob3) False >>> interaction.checkPermission('P2', ob3) False >>> interaction.checkPermission('P3', ob3) True >>> interaction.checkPermission('P1G', ob3) False >>> interaction.checkPermission('P2G', ob3) False >>> interaction.checkPermission('P3G', ob3) True >>> interaction.checkPermission('P4G', ob3) True and if an object doesn't have a parent: >>> ob4 = C() it will have whatever grants were made globally: >>> interaction.checkPermission('P1', ob4) False >>> interaction.checkPermission('P2', ob4) False >>> interaction.checkPermission('P3', ob4) False >>> interaction.checkPermission('P1G', ob4) False >>> interaction.checkPermission('P2G', ob4) True >>> interaction.checkPermission('P3G', ob4) False >>> interaction.checkPermission('P4G', ob4) False >>> prinroleG.assignRoleToPrincipal('R1G', "bob", False) >>> interaction.checkPermission('P3G', ob4) True We'll get the same result if we have a non-annotatable parent without a parent: >>> ob3.__parent__ = C() >>> interaction.checkPermission('P1', ob3) False >>> interaction.checkPermission('P2', ob3) False >>> interaction.checkPermission('P3', ob3) False >>> interaction.checkPermission('P1G', ob3) False >>> interaction.checkPermission('P2G', ob3) True >>> interaction.checkPermission('P3G', ob3) True >>> interaction.checkPermission('P4G', ob3) False The Anonymous role ------------------ The security policy defines a special role named "zope.Anonymous". All principals have this role and the role cannot be taken away. >>> roleperG.grantPermissionToRole('P5', 'zope.Anonymous', False) >>> interaction.checkPermission('P5', ob2) True Proxies ------- Objects may be proxied: >>> from zope.security.checker import ProxyFactory >>> ob = ProxyFactory(ob) >>> interaction.checkPermission('P1', ob) False >>> interaction.checkPermission('P2', ob) False >>> interaction.checkPermission('P3', ob) True >>> interaction.checkPermission('P1G', ob) False >>> interaction.checkPermission('P2G', ob) False >>> interaction.checkPermission('P3G', ob) True >>> interaction.checkPermission('P4G', ob) True as may their parents: >>> ob3 = C() >>> ob3.__parent__ = ob >>> interaction.checkPermission('P1', ob3) False >>> interaction.checkPermission('P2', ob3) False >>> interaction.checkPermission('P3', ob3) True >>> interaction.checkPermission('P1G', ob3) False >>> interaction.checkPermission('P2G', ob3) False >>> interaction.checkPermission('P3G', ob3) True >>> interaction.checkPermission('P4G', ob3) True Groups ------ Principals may have groups. Groups are also principals (and, thus, may have groups). If a principal has groups, the groups are available as group ids in the principal's `groups` attribute. The interaction has to convert these group ids to group objects, so that it can tell whether the groups have groups. It does this by calling the `getPrincipal` method on the principal authentication service, which is responsible for, among other things, converting a principal id to a principal. For our examples here, we'll create and register a stub principal authentication service: >>> from zope.authentication.interfaces import IAuthentication >>> class FauxPrincipals(object): ... zope.interface.implements(IAuthentication) ... def __init__(self): ... self.data = {} ... def __setitem__(self, key, value): ... self.data[key] = value ... def __getitem__(self, key): ... return self.data[key] ... def getPrincipal(self, id): ... return self.data[id] >>> auth = FauxPrincipals() >>> from zope.component import provideUtility >>> provideUtility(auth, IAuthentication) Let's define a group: >>> auth['g1'] = Principal('g1') Let's put the principal in our group. We do that by adding the group id to the new principals groups: >>> principal.groups.append('g1') Of course, the principal doesn't have permissions not granted: >>> interaction.checkPermission('gP1', ob) False Now, if we grant a permission to the group: >>> prinper.grantPermissionToPrincipal('gP1', 'g1') We see that our principal has the permission: >>> interaction.checkPermission('gP1', ob) True This works even if the group grant is global: >>> interaction.checkPermission('gP1G', ob) False >>> prinperG.grantPermissionToPrincipal('gP1G', 'g1', True) >>> interaction.checkPermission('gP1G', ob) True Grants are, of course, acquired: >>> interaction.checkPermission('gP1', ob2) True >>> interaction.checkPermission('gP1G', ob2) True Inner grants can override outer grants: >>> prinper2.denyPermissionToPrincipal('gP1', 'g1') >>> interaction.checkPermission('gP1', ob2) False But principal grants always trump group grants: >>> prinper2.grantPermissionToPrincipal('gP1', 'bob') >>> interaction.checkPermission('gP1', ob2) True Groups can have groups too: >>> auth['g2'] = Principal('g2') >>> auth['g1'].groups.append('g2') If we grant to the new group: >>> prinper.grantPermissionToPrincipal('gP2', 'g2') Then we, of course have that permission too: >>> interaction.checkPermission('gP2', ob2) True Just as principal grants override group grants, group grants can override other group grants: >>> prinper.denyPermissionToPrincipal('gP2', 'g1') >>> interaction.checkPermission('gP2', ob2) False Principals can be in more than one group. Let's define a new group: >>> auth['g3'] = Principal('g3') >>> principal.groups.append('g3') >>> prinper.grantPermissionToPrincipal('gP2', 'g3') Now, the principal has two groups. In one group, the permission 'gP2' is denied, but in the other, it is allowed. In a case like this, the permission is allowed: >>> interaction.checkPermission('gP2', ob2) True In a case where a principal has two or more groups, the group denies prevent allows from their parents. They don't prevent the principal from getting an allow from another principal. Grants can be inherited from ancestor groups through multiple paths. Let's grant a permission to g2 and deny it to g1: >>> prinper.grantPermissionToPrincipal('gP3', 'g2') >>> prinper.denyPermissionToPrincipal('gP3', 'g1') Now, as before, the deny in g1 blocks the grant in g2: >>> interaction.checkPermission('gP3', ob2) False Let's make g2 a group of g3: >>> auth['g3'].groups.append('g2') Now, we get g2's grant through g3, and access is allowed: >>> interaction.invalidate_cache() >>> interaction.checkPermission('gP3', ob2) True We can assign roles to groups: >>> prinrole.assignRoleToPrincipal('gR1', 'g2') and get permissions through the roles: >>> roleper.grantPermissionToRole('gP4', 'gR1') >>> interaction.checkPermission('gP4', ob2) True we can override role assignments to groups through subgroups: >>> prinrole.removeRoleFromPrincipal('gR1', 'g1') >>> prinrole.removeRoleFromPrincipal('gR1', 'g3') >>> interaction.checkPermission('gP4', ob2) False and through principals: >>> prinrole.assignRoleToPrincipal('gR1', 'bob') >>> interaction.checkPermission('gP4', ob2) True We clean up the changes we made in these examples: >>> zope.security.management.endInteraction() >>> ignore = zope.security.management.setSecurityPolicy(oldpolicy) zope.securitypolicy-3.7.0/src/zope/securitypolicy/tests/__init__.py000644 000766 000024 00000003262 11447361751 025612 0ustar00macstaff000000 000000 ############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation 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. # ############################################################################## from zope.interface import implements from zope.authentication.interfaces import IAuthentication, PrincipalLookupError from zope.security.interfaces import IPrincipal class DummyPrincipalRegistry(object): """Dummy principal registry that only implements getPrincipal and definePrincipal method that are needed for securitypolicy tests.""" implements(IAuthentication) def __init__(self): self._principals = {} def getPrincipal(self, id): if id not in self._principals: raise PrincipalLookupError(id) return self._principals[id] def definePrincipal(self, id, title=u'', description=u''): p = DummyPrincipal(id, title, description) self._principals[id] = p return p principalRegistry = DummyPrincipalRegistry() class DummyPrincipal(object): """Very simple principal implementation""" implements(IPrincipal) def __init__(self, id, title=u'', description=u''): self.id = id self.title = title self.description = description zope.securitypolicy-3.7.0/src/zope/securitypolicy/tests/mapping.zcml000644 000766 000024 00000000524 11447361751 026021 0ustar00macstaff000000 000000 zope.securitypolicy-3.7.0/src/zope/securitypolicy/tests/role.zcml000644 000766 000024 00000000446 11447361751 025332 0ustar00macstaff000000 000000 zope.securitypolicy-3.7.0/src/zope/securitypolicy/tests/role_duplicate.zcml000644 000766 000024 00000000653 11447361751 027364 0ustar00macstaff000000 000000 zope.securitypolicy-3.7.0/src/zope/securitypolicy/tests/test_annotationprincipalpermissionmanager.py000644 000766 000024 00000015332 11447361751 034633 0ustar00macstaff000000 000000 ############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation 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 handler for Annotation Principal Permission Manager module. """ import unittest from zope.component import provideAdapter, provideUtility from zope.component.testing import PlacelessSetup from zope.interface import implements from zope.annotation.attribute import AttributeAnnotations from zope.annotation.interfaces import IAttributeAnnotatable from zope.security.interfaces import IPermission from zope.security.permission import Permission from zope.securitypolicy.interfaces import Allow, Deny, Unset from zope.securitypolicy.principalpermission import \ AnnotationPrincipalPermissionManager from zope.securitypolicy.tests import principalRegistry class Manageable(object): implements(IAttributeAnnotatable) class Test(PlacelessSetup, unittest.TestCase): def setUp(self): super(Test, self).setUp() provideAdapter(AttributeAnnotations) def _make_principal(self, id=None, title=None): p = principalRegistry.definePrincipal( id or 'APrincipal', title or 'A Principal') return p.id def testUnboundPrincipalPermission(self): manager = AnnotationPrincipalPermissionManager(Manageable()) provideUtility(Permission('APerm', 'title'), IPermission, 'APerm') permission = 'APerm' principal = self._make_principal() self.assertEqual(manager.getPrincipalsForPermission(permission), []) self.assertEqual(manager.getPermissionsForPrincipal(principal), []) def testPrincipalPermission(self): manager = AnnotationPrincipalPermissionManager(Manageable()) provideUtility(Permission('APerm', 'title'), IPermission, 'APerm') permission = 'APerm' principal = self._make_principal() # check that an allow permission is saved correctly manager.grantPermissionToPrincipal(permission, principal) self.assertEqual(manager.getPrincipalsForPermission(permission), [(principal, Allow)]) self.assertEqual(manager.getPermissionsForPrincipal(principal), [(permission, Allow)]) # check that the allow permission is removed. manager.unsetPermissionForPrincipal(permission, principal) self.assertEqual(manager.getPrincipalsForPermission(permission), []) self.assertEqual(manager.getPermissionsForPrincipal(principal), []) # now put a deny in there, check it's set. manager.denyPermissionToPrincipal(permission, principal) self.assertEqual(manager.getPrincipalsForPermission(permission), [(principal, Deny)]) self.assertEqual(manager.getPermissionsForPrincipal(principal), [(permission, Deny)]) # test for deny followed by allow . The latter should override. manager.grantPermissionToPrincipal(permission, principal) self.assertEqual(manager.getPrincipalsForPermission(permission), [(principal, Allow)]) self.assertEqual(manager.getPermissionsForPrincipal(principal), [(permission, Allow)]) # check that allow followed by allow is just a single allow. manager.grantPermissionToPrincipal(permission, principal) self.assertEqual(manager.getPrincipalsForPermission(permission), [(principal, Allow)]) self.assertEqual(manager.getPermissionsForPrincipal(principal), [(permission, Allow)]) # check that two unsets in a row quietly ignores the second one. manager.unsetPermissionForPrincipal(permission, principal) manager.unsetPermissionForPrincipal(permission, principal) self.assertEqual(manager.getPrincipalsForPermission(permission), []) self.assertEqual(manager.getPermissionsForPrincipal(principal), []) # check the result of getSetting() when it's empty. self.assertEqual(manager.getSetting(permission, principal), Unset) # check the result of getSetting() when it's allowed. manager.grantPermissionToPrincipal(permission, principal) self.assertEqual(manager.getSetting(permission, principal), Allow) # check the result of getSetting() when it's denied. manager.denyPermissionToPrincipal(permission, principal) self.assertEqual(manager.getSetting(permission, principal), Deny) def testManyPermissionsOnePrincipal(self): manager = AnnotationPrincipalPermissionManager(Manageable()) provideUtility(Permission('Perm One', 'title'), IPermission, 'Perm One') perm1 = 'Perm One' provideUtility(Permission('Perm Two', 'title'), IPermission, 'Perm Two') perm2 = 'Perm Two' prin1 = self._make_principal() manager.grantPermissionToPrincipal(perm1, prin1) manager.grantPermissionToPrincipal(perm2, prin1) perms = manager.getPermissionsForPrincipal(prin1) self.assertEqual(len(perms), 2) self.failUnless((perm1, Allow) in perms) self.failUnless((perm2, Allow) in perms) manager.denyPermissionToPrincipal(perm2, prin1) perms = manager.getPermissionsForPrincipal(prin1) self.assertEqual(len(perms), 2) self.failUnless((perm1, Allow) in perms) self.failUnless((perm2, Deny) in perms) def testManyPrincipalsOnePermission(self): manager = AnnotationPrincipalPermissionManager(Manageable()) provideUtility(Permission('Perm One', 'title'), IPermission, 'Perm One') perm1 = 'Perm One' prin1 = self._make_principal() prin2 = self._make_principal('Principal 2', 'Principal Two') manager.grantPermissionToPrincipal(perm1, prin1) manager.denyPermissionToPrincipal(perm1, prin2) principals = manager.getPrincipalsForPermission(perm1) self.assertEqual(len(principals), 2) self.failUnless((prin1, Allow) in principals) self.failUnless((prin2, Deny) in principals) def test_suite(): loader=unittest.TestLoader() return loader.loadTestsFromTestCase(Test) if __name__=='__main__': unittest.TextTestRunner().run(test_suite()) zope.securitypolicy-3.7.0/src/zope/securitypolicy/tests/test_annotationprincipalrolemanager.py000644 000766 000024 00000014410 11447361751 033400 0ustar00macstaff000000 000000 ############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation 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 handler for PrincipalRoleManager module. """ import unittest import zope.component from zope.interface import implements from zope.annotation.interfaces import IAttributeAnnotatable from zope.component.testing import PlacelessSetup from zope.annotation.attribute import AttributeAnnotations from zope.securitypolicy.principalrole import AnnotationPrincipalRoleManager from zope.securitypolicy.interfaces import Allow, Deny, Unset from zope.securitypolicy.interfaces import IRole from zope.securitypolicy.role import Role from zope.securitypolicy.tests import principalRegistry class Manageable(object): implements(IAttributeAnnotatable) def defineRole(id, title=None, description=None): role = Role(id, title, description) zope.component.provideUtility(role, IRole, name=role.id) return role class Test(PlacelessSetup, unittest.TestCase): def setUp(self): PlacelessSetup.setUp(self) zope.component.provideAdapter(AttributeAnnotations) def _make_principal(self, id=None, title=None): p = principalRegistry.definePrincipal( id or 'APrincipal', title or 'A Principal') return p.id def _make_roleManager(self, obj=None): if obj is None: obj = Manageable() return AnnotationPrincipalRoleManager(obj) def testUnboundPrincipalRole(self): principalRoleManager = self._make_roleManager() role = defineRole('ARole', 'A Role').id principal = self._make_principal() self.assertEqual( principalRoleManager.getPrincipalsForRole(role), []) self.assertEqual( principalRoleManager.getRolesForPrincipal(principal), []) def testPrincipalRoleAllow(self): principalRoleManager = self._make_roleManager() role = defineRole('ARole', 'A Role').id principal = self._make_principal() principalRoleManager.assignRoleToPrincipal(role, principal) self.assertEqual(principalRoleManager.getPrincipalsForRole(role), [(principal, Allow)]) self.assertEqual(principalRoleManager.getRolesForPrincipal(principal), [(role, Allow)]) def testPrincipalRoleDeny(self): principalRoleManager = self._make_roleManager() role = defineRole('ARole', 'A Role').id principal = self._make_principal() principalRoleManager.removeRoleFromPrincipal(role, principal) self.assertEqual(principalRoleManager.getPrincipalsForRole(role), [(principal, Deny)]) self.assertEqual(principalRoleManager.getRolesForPrincipal(principal), [(role, Deny)]) def testPrincipalRoleUnset(self): principalRoleManager = self._make_roleManager() role = defineRole('ARole', 'A Role').id principal = self._make_principal() principalRoleManager.removeRoleFromPrincipal(role, principal) principalRoleManager.unsetRoleForPrincipal(role, principal) self.assertEqual(principalRoleManager.getPrincipalsForRole(role), []) self.assertEqual(principalRoleManager.getRolesForPrincipal(principal), []) self.assertEqual(principalRoleManager.getSetting(principal, role), Unset) self.assertEqual(principalRoleManager.getSetting(principal, role, 1), 1) def testManyRolesOnePrincipal(self): principalRoleManager = self._make_roleManager() role1 = defineRole('Role One', 'Role #1').id role2 = defineRole('Role Two', 'Role #2').id prin1 = self._make_principal() principalRoleManager.assignRoleToPrincipal(role1, prin1) principalRoleManager.assignRoleToPrincipal(role2, prin1) roles = principalRoleManager.getRolesForPrincipal(prin1) self.assertEqual(len(roles), 2) self.failUnless((role1, Allow) in roles) self.failUnless((role2, Allow) in roles) def testManyPrincipalsOneRole(self): principalRoleManager = self._make_roleManager() role1 = defineRole('Role One', 'Role #1').id prin1 = self._make_principal() prin2 = self._make_principal('Principal 2', 'Principal Two') principalRoleManager.assignRoleToPrincipal(role1, prin1) principalRoleManager.assignRoleToPrincipal(role1, prin2) principals = principalRoleManager.getPrincipalsForRole(role1) self.assertEqual(len(principals), 2) self.failUnless((prin1, Allow) in principals) self.failUnless((prin2, Allow) in principals) def testPrincipalsAndRoles(self): principalRoleManager = self._make_roleManager() principalsAndRoles = principalRoleManager.getPrincipalsAndRoles() self.assertEqual(len(principalsAndRoles), 0) role1 = defineRole('Role One', 'Role #1').id role2 = defineRole('Role Two', 'Role #2').id prin1 = self._make_principal() prin2 = self._make_principal('Principal 2', 'Principal Two') principalRoleManager.assignRoleToPrincipal(role1, prin1) principalRoleManager.assignRoleToPrincipal(role1, prin2) principalRoleManager.assignRoleToPrincipal(role2, prin1) principalsAndRoles = principalRoleManager.getPrincipalsAndRoles() self.assertEqual(len(principalsAndRoles), 3) self.failUnless((role1, prin1, Allow) in principalsAndRoles) self.failUnless((role1, prin2, Allow) in principalsAndRoles) self.failUnless((role2, prin1, Allow) in principalsAndRoles) def test_suite(): loader=unittest.TestLoader() return loader.loadTestsFromTestCase(Test) if __name__=='__main__': unittest.TextTestRunner().run(test_suite()) zope.securitypolicy-3.7.0/src/zope/securitypolicy/tests/test_annotationrolepermissionmanager.py000644 000766 000024 00000007013 11447361751 033610 0ustar00macstaff000000 000000 ############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation 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 handler for Annotation Role Permission Manager. """ import unittest from zope.component import provideUtility, provideAdapter from zope.component.testing import PlacelessSetup from zope.interface import implements from zope.annotation.attribute import AttributeAnnotations from zope.annotation.interfaces import IAttributeAnnotatable from zope.security.interfaces import IPermission from zope.security.permission import Permission from zope.securitypolicy.role import Role from zope.securitypolicy.interfaces import Allow, Deny, Unset from zope.securitypolicy.interfaces import IRole from zope.securitypolicy.rolepermission import AnnotationRolePermissionManager class Manageable(object): implements(IAttributeAnnotatable) class Test(PlacelessSetup, unittest.TestCase): def setUp(self): PlacelessSetup.setUp(self) provideAdapter(AttributeAnnotations) read = Permission('read', 'Read Something') provideUtility(read, IPermission, read.id) self.read = read.id write = Permission('write', 'Write Something') provideUtility(write, IPermission, write.id) self.write = write.id peon = Role('peon', 'Poor Slob') provideUtility(peon, IRole, peon.id) self.peon = peon.id manager = Role('manager', 'Supreme Being') provideUtility(manager, IRole, manager.id) self.manager = manager.id def testNormal(self): obj = Manageable() mgr = AnnotationRolePermissionManager(obj) mgr.grantPermissionToRole(self.read,self.manager) mgr.grantPermissionToRole(self.write,self.manager) mgr.grantPermissionToRole(self.write,self.manager) mgr.grantPermissionToRole(self.read,self.peon) l = list(mgr.getPermissionsForRole(self.manager)) self.failUnless((self.read, Allow) in l) self.failUnless((self.write, Allow) in l) l = list(mgr.getPermissionsForRole(self.peon)) self.failUnless([(self.read, Allow)] == l) l = list(mgr.getRolesForPermission(self.read)) self.failUnless((self.manager, Allow) in l) self.failUnless((self.peon, Allow) in l) l = list(mgr.getRolesForPermission(self.write)) self.assertEqual(l, [(self.manager, Allow)]) mgr.denyPermissionToRole(self.read, self.peon) l = list(mgr.getPermissionsForRole(self.peon)) self.assertEqual(l, [(self.read, Deny)]) mgr.unsetPermissionFromRole(self.read, self.peon) l = list(mgr.getRolesForPermission(self.read)) self.assertEqual(l, [(self.manager, Allow)]) self.assertEqual(mgr.getSetting(self.read, self.peon), Unset) self.assertEqual(mgr.getSetting(self.read, self.peon, 1), 1) def test_suite(): loader=unittest.TestLoader() return loader.loadTestsFromTestCase(Test) if __name__=='__main__': unittest.TextTestRunner().run(test_suite()) zope.securitypolicy-3.7.0/src/zope/securitypolicy/tests/test_principalpermissionmanager.py000644 000766 000024 00000016151 11447361751 032540 0ustar00macstaff000000 000000 ############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation 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 handler for PrincipalPermissionManager module. """ import unittest from zope.component import provideUtility from zope.component.testing import PlacelessSetup from zope.security.interfaces import IPermission from zope.security.permission import Permission from zope.authentication.interfaces import IAuthentication from zope.securitypolicy.interfaces import Allow, Deny, Unset from zope.securitypolicy.principalpermission import \ principalPermissionManager as manager from zope.securitypolicy.tests import principalRegistry def definePermission(id, title=None, description=None): perm = Permission(id, title, description) provideUtility(perm, IPermission, perm.id) return perm class Test(PlacelessSetup, unittest.TestCase): def setUp(self): super(Test, self).setUp() provideUtility(principalRegistry, IAuthentication) def _make_principal(self, id=None, title=None): p = principalRegistry.definePrincipal( id or 'APrincipal', title or 'A Principal') return p.id def testUnboundPrincipalPermission(self): permission = definePermission('APerm', 'title').id principal = self._make_principal() self.assertEqual(manager.getPrincipalsForPermission(permission), []) self.assertEqual(manager.getPermissionsForPrincipal(principal), []) def test_invalidPrincipal(self): permission = definePermission('APerm', 'title').id self.assertRaises(ValueError, manager.grantPermissionToPrincipal, permission, 'principal') def testPrincipalPermission(self): permission = definePermission('APerm', 'title').id principal = self._make_principal() # check that an allow permission is saved correctly manager.grantPermissionToPrincipal(permission, principal) self.assertEqual(manager.getPrincipalsForPermission(permission), [(principal, Allow)]) self.assertEqual(manager.getPermissionsForPrincipal(principal), [(permission, Allow)]) # check that the allow permission is removed. manager.unsetPermissionForPrincipal(permission, principal) self.assertEqual(manager.getPrincipalsForPermission(permission), []) self.assertEqual(manager.getPermissionsForPrincipal(principal), []) # now put a deny in there, check it's set. manager.denyPermissionToPrincipal(permission, principal) self.assertEqual(manager.getPrincipalsForPermission(permission), [(principal, Deny)]) self.assertEqual(manager.getPermissionsForPrincipal(principal), [(permission, Deny)]) # test for deny followed by allow . The latter should override. manager.grantPermissionToPrincipal(permission, principal) self.assertEqual(manager.getPrincipalsForPermission(permission), [(principal, Allow)]) self.assertEqual(manager.getPermissionsForPrincipal(principal), [(permission, Allow)]) # check that allow followed by allow is just a single allow. manager.grantPermissionToPrincipal(permission, principal) self.assertEqual(manager.getPrincipalsForPermission(permission), [(principal, Allow)]) self.assertEqual(manager.getPermissionsForPrincipal(principal), [(permission, Allow)]) # check that two unsets in a row quietly ignores the second one. manager.unsetPermissionForPrincipal(permission, principal) manager.unsetPermissionForPrincipal(permission, principal) self.assertEqual(manager.getPrincipalsForPermission(permission), []) self.assertEqual(manager.getPermissionsForPrincipal(principal), []) # check the result of getSetting() when it's empty. self.assertEqual(manager.getSetting(permission, principal), Unset) # check the result of getSetting() when it's empty and a default # passed in self.assertEqual(manager.getSetting(permission, principal, 1), 1) # check the result of getSetting() when it's allowed. manager.grantPermissionToPrincipal(permission, principal) self.assertEqual(manager.getSetting(permission, principal), Allow) # check the result of getSetting() when it's denied. manager.denyPermissionToPrincipal(permission, principal) self.assertEqual(manager.getSetting(permission, principal), Deny) def testManyPermissionsOnePrincipal(self): perm1 = definePermission('Perm One', 'title').id perm2 = definePermission('Perm Two', 'title').id prin1 = self._make_principal() manager.grantPermissionToPrincipal(perm1, prin1) manager.grantPermissionToPrincipal(perm2, prin1) perms = manager.getPermissionsForPrincipal(prin1) self.assertEqual(len(perms), 2) self.failUnless((perm1,Allow) in perms) self.failUnless((perm2,Allow) in perms) manager.denyPermissionToPrincipal(perm2, prin1) perms = manager.getPermissionsForPrincipal(prin1) self.assertEqual(len(perms), 2) self.failUnless((perm1,Allow) in perms) self.failUnless((perm2,Deny) in perms) perms = manager.getPrincipalsAndPermissions() self.failUnless((perm1,prin1,Allow) in perms) self.failUnless((perm2,prin1,Deny) in perms) def testAllPermissions(self): perm1 = definePermission('Perm One', 'title').id perm2 = definePermission('Perm Two', 'title').id prin1 = self._make_principal() manager.grantAllPermissionsToPrincipal(prin1) perms = manager.getPermissionsForPrincipal(prin1) self.assertEqual(len(perms), 2) self.failUnless((perm1,Allow) in perms) self.failUnless((perm2,Allow) in perms) def testManyPrincipalsOnePermission(self): perm1 = definePermission('Perm One', 'title').id prin1 = self._make_principal() prin2 = self._make_principal('Principal 2', 'Principal Two') manager.grantPermissionToPrincipal(perm1, prin1) manager.denyPermissionToPrincipal(perm1, prin2) principals = manager.getPrincipalsForPermission(perm1) self.assertEqual(len(principals), 2) self.failUnless((prin1,Allow) in principals) self.failUnless((prin2,Deny) in principals) def test_suite(): loader=unittest.TestLoader() return loader.loadTestsFromTestCase(Test) if __name__=='__main__': unittest.TextTestRunner().run(test_suite()) zope.securitypolicy-3.7.0/src/zope/securitypolicy/tests/test_principalrolemanager.py000644 000766 000024 00000014042 11447361751 031306 0ustar00macstaff000000 000000 ############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation 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 handler for PrincipalRoleManager module. """ import unittest from zope.component import provideUtility from zope.component.testing import PlacelessSetup from zope.authentication.interfaces import IAuthentication from zope.securitypolicy.role import Role from zope.securitypolicy.interfaces import Allow, Deny, Unset from zope.securitypolicy.interfaces import IRole from zope.securitypolicy.principalrole import principalRoleManager from zope.securitypolicy.tests import principalRegistry def defineRole(id, title=None, description=None): role = Role(id, title, description) provideUtility(role, IRole, role.id) return role class Test(PlacelessSetup, unittest.TestCase): def setUp(self): super(Test, self).setUp() provideUtility(principalRegistry, IAuthentication) def _make_principal(self, id=None, title=None): p = principalRegistry.definePrincipal( id or 'APrincipal', title or 'A Principal') return p.id def testUnboundPrincipalRole(self): role = defineRole('ARole', 'A Role').id principal = self._make_principal() self.assertEqual(principalRoleManager.getPrincipalsForRole(role), []) self.assertEqual(principalRoleManager.getRolesForPrincipal(principal), []) def testPrincipalRoleAllow(self): role = defineRole('ARole', 'A Role').id principal = self._make_principal() principalRoleManager.assignRoleToPrincipal(role, principal) self.assertEqual(principalRoleManager.getPrincipalsForRole(role), [(principal, Allow)]) self.assertEqual(principalRoleManager.getRolesForPrincipal(principal), [(role, Allow)]) def testPrincipalRoleDeny(self): role = defineRole('ARole', 'A Role').id principal = self._make_principal() principalRoleManager.removeRoleFromPrincipal(role, principal) self.assertEqual(principalRoleManager.getPrincipalsForRole(role), [(principal, Deny)]) self.assertEqual(principalRoleManager.getRolesForPrincipal(principal), [(role, Deny)]) def testPrincipalRoleUnset(self): role = defineRole('ARole', 'A Role').id principal = self._make_principal() principalRoleManager.removeRoleFromPrincipal(role, principal) principalRoleManager.unsetRoleForPrincipal(role, principal) self.assertEqual(principalRoleManager.getPrincipalsForRole(role), []) self.assertEqual(principalRoleManager.getRolesForPrincipal(principal), []) self.assertEqual(principalRoleManager.getSetting(principal, role), Unset) self.assertEqual(principalRoleManager.getSetting(principal, role, 1), 1) def test_invalidPrincipal(self): self.assertRaises(ValueError, principalRoleManager.assignRoleToPrincipal, 'role1', 'prin1') role1 = defineRole('Role One', 'Role #1').id self.assertRaises(ValueError, principalRoleManager.assignRoleToPrincipal, role1, 'prin1') def test_invalidRole(self): prin1 = self._make_principal() self.assertRaises(ValueError, principalRoleManager.assignRoleToPrincipal, 'role1', prin1) def testManyRolesOnePrincipal(self): role1 = defineRole('Role One', 'Role #1').id role2 = defineRole('Role Two', 'Role #2').id prin1 = self._make_principal() principalRoleManager.assignRoleToPrincipal(role1, prin1) principalRoleManager.assignRoleToPrincipal(role2, prin1) roles = principalRoleManager.getRolesForPrincipal(prin1) self.assertEqual(len(roles), 2) self.failUnless((role1, Allow) in roles) self.failUnless((role2, Allow) in roles) def testManyPrincipalsOneRole(self): role1 = defineRole('Role One', 'Role #1').id prin1 = self._make_principal() prin2 = self._make_principal('Principal 2', 'Principal Two') principalRoleManager.assignRoleToPrincipal(role1, prin1) principalRoleManager.assignRoleToPrincipal(role1, prin2) principals = principalRoleManager.getPrincipalsForRole(role1) self.assertEqual(len(principals), 2) self.failUnless((prin1, Allow) in principals) self.failUnless((prin2, Allow) in principals) def testPrincipalsAndRoles(self): role1 = defineRole('Role One', 'Role #1').id role2 = defineRole('Role Two', 'Role #2').id prin1 = self._make_principal() prin2 = self._make_principal('Principal 2', 'Principal Two') principalRoleManager.assignRoleToPrincipal(role1, prin1) principalRoleManager.assignRoleToPrincipal(role1, prin2) principalRoleManager.assignRoleToPrincipal(role2, prin1) principalsAndRoles = principalRoleManager.getPrincipalsAndRoles() self.assertEqual(len(principalsAndRoles), 3) self.failUnless((role1, prin1, Allow) in principalsAndRoles) self.failUnless((role1, prin2, Allow) in principalsAndRoles) self.failUnless((role2, prin1, Allow) in principalsAndRoles) def test_suite(): loader=unittest.TestLoader() return loader.loadTestsFromTestCase(Test) if __name__=='__main__': unittest.TextTestRunner().run(test_suite()) zope.securitypolicy-3.7.0/src/zope/securitypolicy/tests/test_role.py000644 000766 000024 00000001617 11447361751 026055 0ustar00macstaff000000 000000 ############################################################################## # # Copyright (c) 2004 Zope Foundation 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. # ############################################################################## """Doctests for 'permission' module. """ from doctest import DocTestSuite import unittest def test_suite(): return unittest.TestSuite(( DocTestSuite('zope.securitypolicy.role'), )) if __name__ == '__main__': unittest.main(defaultTest='test_suite') zope.securitypolicy-3.7.0/src/zope/securitypolicy/tests/test_rolepermissionmanager.py000644 000766 000024 00000012620 11447361751 031515 0ustar00macstaff000000 000000 ############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation 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 handler for RolePermissionManager module. """ import unittest from zope.component import provideUtility from zope.component.testing import PlacelessSetup from zope.security.interfaces import IPermission from zope.security.permission import Permission from zope.securitypolicy.role import Role from zope.securitypolicy.interfaces import Allow, Deny, Unset from zope.securitypolicy.interfaces import IRole from zope.securitypolicy.rolepermission import \ rolePermissionManager as manager def defineRole(id, title=None, description=None): role = Role(id, title, description) provideUtility(role, IRole, role.id) return role def definePermission(id, title=None, description=None): perm = Permission(id, title, description) provideUtility(perm, IPermission, perm.id) return perm class Test(PlacelessSetup, unittest.TestCase): def testUnboundRolePermission(self): permission = definePermission('APerm', 'aPerm title').id role = defineRole('ARole', 'A Role').id self.assertEqual(manager.getRolesForPermission(permission), []) self.assertEqual(manager.getPermissionsForRole(role), []) self.assertEqual(manager.getSetting(permission, role), Unset) self.assertEqual(manager.getSetting(permission, role, 1), 1) def testRolePermission(self): permission = definePermission('APerm', 'aPerm title').id role = defineRole('ARole', 'A Role').id manager.grantPermissionToRole(permission, role) self.assertEqual(manager.getRolesForPermission(permission), [(role,Allow)]) self.assertEqual(manager.getPermissionsForRole(role), [(permission,Allow)]) def testManyPermissionsOneRole(self): perm1 = definePermission('Perm One', 'P1').id perm2 = definePermission('Perm Two', 'P2').id perm3 = definePermission('Perm Three', 'P3').id role1 = defineRole('Role One', 'Role #1').id perms = manager.getPermissionsForRole(role1) self.assertEqual(len(perms), 0) manager.grantPermissionToRole(perm1, role1) manager.grantPermissionToRole(perm2, role1) manager.grantPermissionToRole(perm2, role1) manager.denyPermissionToRole(perm3, role1) perms = manager.getPermissionsForRole(role1) self.assertEqual(len(perms), 3) self.failUnless((perm1,Allow) in perms) self.failUnless((perm2,Allow) in perms) self.failUnless((perm3,Deny) in perms) manager.unsetPermissionFromRole(perm1, role1) perms = manager.getPermissionsForRole(role1) self.assertEqual(len(perms), 2) self.failUnless((perm2,Allow) in perms) def testAllPermissions(self): perm1 = definePermission('Perm One', 'P1').id perm2 = definePermission('Perm Two', 'P2').id perm3 = definePermission('Perm Three', 'P3').id role1 = defineRole('Role One', 'Role #1').id perms = manager.getPermissionsForRole(role1) self.assertEqual(len(perms), 0) manager.grantAllPermissionsToRole(role1) perms = manager.getPermissionsForRole(role1) self.assertEqual(len(perms), 3) self.failUnless((perm1, Allow) in perms) self.failUnless((perm2, Allow) in perms) self.failUnless((perm3, Allow) in perms) def testManyRolesOnePermission(self): perm1 = definePermission('Perm One', 'title').id role1 = defineRole('Role One', 'Role #1').id role2 = defineRole('Role Two', 'Role #2').id roles = manager.getRolesForPermission(perm1) self.assertEqual(len(roles), 0) manager.grantPermissionToRole(perm1, role1) manager.grantPermissionToRole(perm1, role2) manager.grantPermissionToRole(perm1, role2) manager.denyPermissionToRole(perm1, role1) roles = manager.getRolesForPermission(perm1) self.assertEqual(len(roles), 2) self.failIf((role1,Allow) in roles) self.failUnless((role1,Deny) in roles) self.failUnless((role2,Allow) in roles) manager.unsetPermissionFromRole(perm1, role1) roles = manager.getRolesForPermission(perm1) self.assertEqual(len(roles), 1) self.failUnless((role2,Allow) in roles) def test_invalidRole(self): self.assertRaises(ValueError, manager.grantPermissionToRole, 'perm1', 'role1' ) perm1 = definePermission('Perm One', 'title').id self.assertRaises(ValueError, manager.grantPermissionToRole, perm1, 'role1' ) def test_suite(): loader=unittest.TestLoader() return loader.loadTestsFromTestCase(Test) if __name__=='__main__': unittest.TextTestRunner().run(test_suite()) zope.securitypolicy-3.7.0/src/zope/securitypolicy/tests/test_securitydirectives.py000644 000766 000024 00000010273 11447361751 031043 0ustar00macstaff000000 000000 ############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation 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 Directives Tests """ import unittest import zope.component from zope.configuration import xmlconfig from zope.configuration.config import ConfigurationConflictError from zope.security.interfaces import IPermission from zope.security.permission import Permission from zope.component.testing import PlacelessSetup from zope.authentication.interfaces import IAuthentication from zope.securitypolicy.role import Role from zope.securitypolicy.interfaces import Allow from zope.securitypolicy.interfaces import IRole from zope.securitypolicy.rolepermission import \ rolePermissionManager as role_perm_mgr from zope.securitypolicy.principalpermission import \ principalPermissionManager as principal_perm_mgr from zope.securitypolicy.principalrole import \ principalRoleManager as principal_role_mgr import zope.securitypolicy.tests from zope.securitypolicy.tests import principalRegistry def defineRole(id, title=None, description=None): role = Role(id, title, description) zope.component.provideUtility(role, IRole, role.id) return role class TestBase(PlacelessSetup): def setUp(self): super(TestBase, self).setUp() zope.component.provideUtility(principalRegistry, IAuthentication) class TestRoleDirective(TestBase, unittest.TestCase): def testRegister(self): xmlconfig.file("role.zcml", zope.securitypolicy.tests) role = zope.component.getUtility(IRole, "zope.Everyperson") self.failUnless(role.id.endswith('Everyperson')) self.assertEqual(role.title, 'Tout le monde') self.assertEqual(role.description, 'The common man, woman, person, or thing') def testDuplicationRegistration(self): self.assertRaises(ConfigurationConflictError, xmlconfig.file, "role_duplicate.zcml", zope.securitypolicy.tests) class TestSecurityMapping(TestBase, unittest.TestCase): def setUp(self): super(TestSecurityMapping, self).setUp() zope.component.provideUtility(Permission('zope.Foo', ''), IPermission, 'zope.Foo') defineRole("zope.Bar", '', '') principalRegistry.definePrincipal("zope.Blah", '', '') self.context = xmlconfig.file("mapping.zcml", zope.securitypolicy.tests) def test_PermRoleMap(self): roles = role_perm_mgr.getRolesForPermission("zope.Foo") perms = role_perm_mgr.getPermissionsForRole("zope.Bar") self.assertEqual(len(roles), 1) self.failUnless(("zope.Bar",Allow) in roles) self.assertEqual(len(perms), 1) self.failUnless(("zope.Foo",Allow) in perms) def test_PermPrincipalMap(self): principals = principal_perm_mgr.getPrincipalsForPermission("zope.Foo") perms = principal_perm_mgr.getPermissionsForPrincipal("zope.Blah") self.assertEqual(len(principals), 1) self.failUnless(("zope.Blah", Allow) in principals) self.assertEqual(len(perms), 1) self.failUnless(("zope.Foo", Allow) in perms) def test_RolePrincipalMap(self): principals = principal_role_mgr.getPrincipalsForRole("zope.Bar") roles = principal_role_mgr.getRolesForPrincipal("zope.Blah") self.assertEqual(len(principals), 1) self.failUnless(("zope.Blah", Allow) in principals) self.assertEqual(len(roles), 1) self.failUnless(("zope.Bar", Allow) in roles) def test_suite(): return unittest.TestSuite(( unittest.makeSuite(TestRoleDirective), unittest.makeSuite(TestSecurityMapping), )) if __name__ == '__main__': unittest.main() zope.securitypolicy-3.7.0/src/zope/securitypolicy/tests/test_securitymap.py000644 000766 000024 00000012476 11447361751 027466 0ustar00macstaff000000 000000 ############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation 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 SecurityMap implementations """ import unittest from zope.securitypolicy.securitymap import SecurityMap from zope.securitypolicy.securitymap import PersistentSecurityMap from zope.security.management import setSecurityPolicy, getInteraction from zope.security.management import newInteraction, endInteraction class InteractionStub: invalidated = 0 def invalidate_cache(self): self.invalidated += 1 class TestSecurityMap(unittest.TestCase): def setUp(self): self.oldpolicy = setSecurityPolicy(InteractionStub) newInteraction() def tearDown(self): endInteraction() setSecurityPolicy(self.oldpolicy) def _getSecurityMap(self): return SecurityMap() def test_addCell(self): map = self._getSecurityMap() self.assertEqual(getInteraction().invalidated, 0) map.addCell(0, 0, 'aa') self.assertEqual(getInteraction().invalidated, 1) self.assertEqual(map._byrow[0][0], 'aa') self.assertEqual(map._bycol[0][0], 'aa') map.addCell(1, 0, 'ba') self.assertEqual(getInteraction().invalidated, 2) self.assertEqual(map._byrow[1][0], 'ba') self.assertEqual(map._bycol[0][1], 'ba') map.addCell(5, 3, 'fd') self.assertEqual(getInteraction().invalidated, 3) self.assertEqual(map._byrow[5][3], 'fd') self.assertEqual(map._bycol[3][5], 'fd') def test_addCell_noninteger(self): map = self._getSecurityMap() map.addCell(0.3, 0.4, 'entry') self.assertEqual(map._byrow[0.3][0.4], 'entry') self.assertEqual(map._bycol[0.4][0.3], 'entry') marker = object() map.addCell('a', 'b', marker) self.assertEqual(map._byrow['a']['b'], marker) self.assertEqual(map._bycol['b']['a'], marker) def test_delCell(self): map = self._getSecurityMap() self.assertEqual(getInteraction().invalidated, 0) map._byrow[0] = {} map._bycol[1] = {} map._byrow[0][1] = 'aa' map._bycol[1][0] = 'aa' map.delCell(0, 1) self.assertEqual(getInteraction().invalidated, 1) self.assertEqual(map._byrow.get(0), None) self.assertEqual(map._bycol.get(1), None) def test_queryCell(self): map = self._getSecurityMap() map._byrow[0] = {} map._bycol[1] = {} map._byrow[0][1] = 'aa' map._bycol[1][0] = 'aa' marker = object() self.assertEqual(map.queryCell(0, 1), 'aa') self.assertEqual(map.queryCell(1, 0), None) self.assertEqual(map.queryCell(1, 0, marker), marker) def test_getCell(self): map = self._getSecurityMap() map._byrow[0] = {} map._bycol[1] = {} map._byrow[0][1] = 'aa' map._bycol[1][0] = 'aa' self.assertEqual(map.getCell(0, 1), 'aa') self.assertRaises(KeyError, map.getCell, 1, 0) def test_getRow(self): map = self._getSecurityMap() map._byrow[0] = {} map._byrow[0][1] = 'ab' map._byrow[0][2] = 'ac' map._byrow[1] = {} map._byrow[1][1] = 'bb' map._bycol[1] = {} map._bycol[1][0] = 'ab' map._bycol[1][1] = 'bb' map._bycol[2] = {} map._bycol[2][0] = 'ac' self.assertEqual(map.getRow(0), [(1, 'ab'), (2, 'ac')]) self.assertEqual(map.getRow(1), [(1, 'bb')]) self.assertEqual(map.getRow(2), []) def test_getCol(self): map = self._getSecurityMap() map._byrow[0] = {} map._byrow[0][1] = 'ab' map._byrow[0][2] = 'ac' map._byrow[1] = {} map._byrow[1][1] = 'bb' map._bycol[1] = {} map._bycol[1][0] = 'ab' map._bycol[1][1] = 'bb' map._bycol[2] = {} map._bycol[2][0] = 'ac' self.assertEqual(map.getCol(1), [(0, 'ab'), (1, 'bb')]) self.assertEqual(map.getCol(2), [(0, 'ac')]) self.assertEqual(map.getCol(0), []) def test_getAllCells(self): map = self._getSecurityMap() map._byrow[0] = {} map._byrow[0][1] = 'ab' map._byrow[0][2] = 'ac' map._byrow[1] = {} map._byrow[1][1] = 'bb' map._bycol[1] = {} map._bycol[1][0] = 'ab' map._bycol[1][1] = 'bb' map._bycol[2] = {} map._bycol[2][0] = 'ac' self.assertEqual(map.getCol(1), [(0, 'ab'), (1, 'bb')]) self.assertEqual(map.getCol(2), [(0, 'ac')]) self.assertEqual(map.getCol(0), []) class TestPersistentSecurityMap(TestSecurityMap): def _getSecurityMap(self): return PersistentSecurityMap() def test_suite(): return unittest.TestSuite(( unittest.makeSuite(TestSecurityMap), unittest.makeSuite(TestPersistentSecurityMap), )) zope.securitypolicy-3.7.0/src/zope/securitypolicy/tests/test_settings.py000644 000766 000024 00000002316 11447361751 026751 0ustar00macstaff000000 000000 ############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation 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 Settings Tests """ import unittest from cPickle import Pickler, Unpickler from StringIO import StringIO from zope.securitypolicy.interfaces import Allow 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()) zope.securitypolicy-3.7.0/src/zope/securitypolicy/tests/test_vocabulary.py000644 000766 000024 00000001615 11447361751 027261 0ustar00macstaff000000 000000 ############################################################################## # # Copyright (c) 2004 Zope Foundation 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. # ############################################################################## """Role vocabluary doc tests. """ from doctest import DocTestSuite import unittest def test_suite(): return unittest.TestSuite(( DocTestSuite('zope.securitypolicy.vocabulary'), )) if __name__ == '__main__': unittest.main(defaultTest='test_suite') zope.securitypolicy-3.7.0/src/zope/securitypolicy/tests/test_zopepolicy.py000644 000766 000024 00000005664 11447361751 027317 0ustar00macstaff000000 000000 ############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation 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. # ############################################################################## """Tests the zope policy. """ from doctest import DocFileSuite import unittest from zope.component import provideAdapter from zope.component.testing import setUp as componentSetUp from zope.component.testing import tearDown as componentTearDown from zope.annotation.interfaces import IAnnotatable from zope.annotation.attribute import AttributeAnnotations from zope.security.management import endInteraction from zope.securitypolicy.interfaces import IGrantInfo from zope.securitypolicy.interfaces import IPrincipalRoleManager from zope.securitypolicy.interfaces import IPrincipalPermissionManager from zope.securitypolicy.interfaces import IRolePermissionManager from zope.securitypolicy.principalpermission import \ AnnotationPrincipalPermissionManager from zope.securitypolicy.principalrole import \ AnnotationPrincipalRoleManager from zope.securitypolicy.rolepermission import \ AnnotationRolePermissionManager from zope.securitypolicy.grantinfo import \ AnnotationGrantInfo class TestZCML(unittest.TestCase): def testMetaZCML(self): import zope.configuration import zope.securitypolicy zope.configuration.xmlconfig.file("meta.zcml", zope.securitypolicy) def testConfigureZCML(self): import zope.configuration import zope.securitypolicy zope.configuration.xmlconfig.file("configure.zcml", zope.securitypolicy) def testSecuritypolicyZCML(self): import zope.configuration import zope.securitypolicy zope.configuration.xmlconfig.file( "securitypolicy.zcml", zope.securitypolicy) def setUp(test): componentSetUp() endInteraction() provideAdapter(AttributeAnnotations) provideAdapter(AnnotationPrincipalPermissionManager, (IAnnotatable,), IPrincipalPermissionManager) provideAdapter(AnnotationPrincipalRoleManager, (IAnnotatable,), IPrincipalRoleManager) provideAdapter(AnnotationRolePermissionManager, (IAnnotatable,), IRolePermissionManager) provideAdapter(AnnotationGrantInfo, (IAnnotatable,), IGrantInfo) def test_suite(): return unittest.TestSuite(( DocFileSuite('zopepolicy.txt', package='zope.securitypolicy', setUp=setUp, tearDown=componentTearDown), unittest.makeSuite(TestZCML), ))