vendor/Five/1.2b-r20590

view tests/test_security.py @ 0:3673ed425f80

Vendor import of Five 1.2b+ (r20590)
author fguillaume
date Fri, 02 Dec 2005 20:25:42 +0000
parents
children
line source
1 ##############################################################################
2 #
3 # Copyright (c) 2004, 2005 Zope Corporation and Contributors.
4 # All Rights Reserved.
5 #
6 # This software is subject to the provisions of the Zope Public License,
7 # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
8 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
9 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
11 # FOR A PARTICULAR PURPOSE.
12 #
13 ##############################################################################
14 """Test security induced by ZCML
16 $Id: test_security.py 20133 2005-11-21 15:30:43Z philikon $
17 """
18 import os, sys
19 if __name__ == '__main__':
20 execfile(os.path.join(sys.path[0], 'framework.py'))
22 from zope.interface import Interface, implements
23 from AccessControl import ClassSecurityInfo
25 class IDummy(Interface):
26 """Just a marker interface"""
28 class Dummy1:
29 implements(IDummy)
30 def foo(self): pass
31 def bar(self): pass
32 def baz(self): pass
33 def keg(self): pass
34 def wot(self): pass
36 class Dummy2(Dummy1):
37 security = ClassSecurityInfo()
38 security.declarePublic('foo')
39 security.declareProtected('View management screens', 'bar')
40 security.declarePrivate('baz')
41 security.declareProtected('View management screens', 'keg')
43 def test_security_equivalence():
44 """This test demonstrates that the traditional declarative security of
45 Zope 2 can be replaced by ZCML statements without any loss of
46 information.
48 >>> from zope.app.tests.placelesssetup import setUp, tearDown
49 >>> setUp()
51 We start out with two classes, ``Dummy1`` and ``Dummy2``. They
52 are identical in every way, except that ``Dummy2`` has security
53 declarations and ``Dummy1`` does not. Before we do anything, none
54 of them have security access controls:
56 >>> from Products.Five.tests.test_security import Dummy1, Dummy2
57 >>> hasattr(Dummy1, '__ac_permissions__')
58 False
59 >>> hasattr(Dummy2, '__ac_permissions__')
60 False
62 Before we can make security declarations through ZCML, we need to
63 register the directive and the permission:
65 >>> import Products.Five
66 >>> from Products.Five import zcml
67 >>> zcml.load_config('meta.zcml', Products.Five)
68 >>> zcml.load_config('permissions.zcml', Products.Five)
70 Now we initialize the security for ``Dummy2`` and provide some
71 ZCML declarations for ``Dummy1``:
73 >>> configure_zcml = '''
74 ... <configure xmlns="http://namespaces.zope.org/zope">
75 ... <content class="Products.Five.tests.test_security.Dummy1">
76 ... <allow attributes="foo" />
77 ... <!--deny attributes="baz" /--> <!-- XXX not yet supported -->
78 ... <require attributes="bar keg"
79 ... permission="zope2.ViewManagementScreens"
80 ... />
81 ... </content>
82 ... </configure>
83 ... '''
84 >>> zcml.load_string(configure_zcml)
86 >>> from Globals import InitializeClass
87 >>> InitializeClass(Dummy2)
89 Now we compare their access controls:
91 >>> ac1 = getattr(Dummy1, '__ac_permissions__')
92 >>> ac2 = getattr(Dummy2, '__ac_permissions__')
93 >>> ac1 == ac2
94 True
96 Now we look at the individual permissions:
98 >>> from AccessControl.ZopeSecurityPolicy import getRoles
99 >>> from AccessControl import ACCESS_PUBLIC
100 >>> from AccessControl import ACCESS_PRIVATE
102 >>> dummy1 = Dummy1()
103 >>> getRoles(dummy1, 'bar', dummy1.bar, ('Def',))
104 ('Manager',)
106 >>> getRoles(dummy1, 'keg', dummy1.keg, ('Def',))
107 ('Manager',)
109 >>> getRoles(dummy1, 'foo', dummy1.foo, ('Def',)) is ACCESS_PUBLIC
110 True
112 #>>> getRoles(dummy1, 'baz', dummy1.baz, ('Def',)) is ACCESS_PRIVATE
113 #True XXX Not yet supported.
115 >>> dummy2 = Dummy2()
116 >>> getRoles(dummy2, 'bar', dummy2.bar, ('Def',))
117 ('Manager',)
119 >>> getRoles(dummy2, 'keg', dummy2.keg, ('Def',))
120 ('Manager',)
122 >>> getRoles(dummy2, 'foo', dummy2.foo, ('Def',)) is ACCESS_PUBLIC
123 True
125 >>> getRoles(dummy2, 'baz', dummy2.baz, ('Def',)) is ACCESS_PRIVATE
126 True
128 Before we end we should clean up after ourselves:
130 >>> from Products.Five.security import clearSecurityInfo
131 >>> clearSecurityInfo(Dummy1)
132 >>> clearSecurityInfo(Dummy2)
134 >>> tearDown()
135 """
137 def test_checkPermission():
138 """
139 Test checkPermission
141 >>> from zope.app.tests.placelesssetup import setUp, tearDown
142 >>> setUp()
144 Zope 3 has a function zope.security.checkPermission which provides
145 an easy way of checking whether the currently authenticated user
146 has the permission to access an object. The function delegates to
147 the security policy's checkPermission() method.
149 Five has the same function, Five.security.checkPermission, but in
150 a Zope2-compatible implementation. It too uses the currently
151 active security policy of Zope 2 for the actual permission
152 checking.
154 >>> import Products.Five
155 >>> from Products.Five import zcml
156 >>> zcml.load_config('meta.zcml', Products.Five)
157 >>> zcml.load_config('permissions.zcml', Products.Five)
159 In the following we want to test Five's checkPermission function.
160 We do that by taking the test's folder and asserting several
161 standard permissions. What we want to assure is that
162 checkPermission translates the Zope 2 permissions correctly,
163 especially the edge cases:
165 a) zope2.Public (which should always be available to everyone)
167 >>> from Products.Five.security import checkPermission
168 >>> checkPermission('zope2.Public', self.folder)
169 True
171 b) zope2.Private (which should never available to anyone)
173 >>> checkPermission('zope.Private', self.folder)
174 False
175 >>> checkPermission('zope2.Private', self.folder)
176 False
178 Any other standard Zope 2 permission will also resolve correctly:
180 >>> checkPermission('zope2.AccessContentsInformation', self.folder)
181 True
183 Invalid permissions will obviously result in a negative response:
185 >>> checkPermission('notapermission', self.folder)
186 False
189 In addition to using Five's ``checkPermission`` function directly,
190 we also expect the same behaviour when we use Zope 3's
191 zope.security.checkPermission function. Code from within Zope 3
192 will use that and therefore it should work transparently. For
193 that to work, a new Five "interaction" needs to be started (the
194 old one from placelesssetup needs to be ended first):
196 >>> from zope.security.management import endInteraction
197 >>> endInteraction()
199 >>> from Products.Five.security import newInteraction
200 >>> newInteraction()
202 a) zope2.Public (which should always be available to everyone)
204 >>> from zope.security import checkPermission
205 >>> checkPermission('zope2.Public', self.folder)
206 True
208 b) zope2.Private (which should never available to anyone)
210 >>> checkPermission('zope.Private', self.folder)
211 False
212 >>> checkPermission('zope2.Private', self.folder)
213 False
215 Any other standard Zope 2 permission will also resolve correctly:
217 >>> checkPermission('zope2.AccessContentsInformation', self.folder)
218 True
220 Invalid permissions will obviously result in a negative response:
222 >>> checkPermission('notapermission', self.folder)
223 False
226 Clean up:
228 >>> tearDown()
229 """
231 def test_suite():
232 from Testing.ZopeTestCase import ZopeDocTestSuite
233 return ZopeDocTestSuite()
235 if __name__ == '__main__':
236 framework()