• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

zopefoundation / Products.PythonScripts / 16248875199

17 Mar 2025 07:48AM UTC coverage: 86.279%. Remained the same
16248875199

push

github

web-flow
Update Python version support. (#68)

* Drop support for Python 3.8.

* Configuring for zope-product

* Update Python version support.

84 of 144 branches covered (58.33%)

Branch coverage included in aggregate %.

941 of 1044 relevant lines covered (90.13%)

0.9 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.9
/src/Products/PythonScripts/tests/testBindings.py
1
##############################################################################
2
#
3
# Copyright (c) 2003 Zope Foundation 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

15
import unittest
1✔
16

17
import transaction
1✔
18
from AccessControl import ClassSecurityInfo
1✔
19
from AccessControl.class_init import InitializeClass
1✔
20
from OFS.Folder import Folder
1✔
21
from OFS.ObjectManager import ObjectManager
1✔
22

23

24
class UnderprivilegedUser:
1✔
25

26
    def getId(self):
1✔
27
        return 'underprivileged'
×
28

29
    def allowed(self, object, object_roles=None):
1✔
30
        return 0
1✔
31

32

33
class FauxRoot(ObjectManager):
1✔
34

35
    def getPhysicalPath(self):
1✔
36
        return ('',)
1✔
37

38
    def __repr__(self):
1✔
39
        return '<FauxRoot>'
×
40

41

42
class FauxFolder(Folder):
1✔
43

44
    security = ClassSecurityInfo()
1✔
45
    security.declareObjectPrivate()
1✔
46

47
    @security.private
1✔
48
    def __repr__(self):
1✔
49
        return '<FauxFolder: %s>' % self.getId()
1✔
50

51
    @security.public
1✔
52
    def methodWithRoles(self):
1✔
53
        return 'method called'
1✔
54

55

56
InitializeClass(FauxFolder)
1✔
57

58

59
class TestBindings(unittest.TestCase):
1✔
60

61
    def setUp(self):
1✔
62
        from Testing.ZODButil import makeDB
1✔
63
        transaction.begin()
1✔
64
        self.db = makeDB()
1✔
65
        self.connection = self.db.open()
1✔
66

67
    def tearDown(self):
1✔
68
        from AccessControl.SecurityManagement import noSecurityManager
1✔
69
        from Testing.ZODButil import cleanDB
1✔
70
        noSecurityManager()
1✔
71
        transaction.abort()
1✔
72
        self.connection.close()
1✔
73
        self.db.close()
1✔
74
        cleanDB()
1✔
75

76
    def _getRoot(self):
1✔
77
        from Testing.makerequest import makerequest
1✔
78
        return makerequest(FauxRoot())
1✔
79

80
    def _makeTree(self):
1✔
81

82
        root = self._getRoot()
1✔
83

84
        guarded = FauxFolder()
1✔
85
        guarded._setId('guarded')
1✔
86
        guarded.__roles__ = ('Manager', )
1✔
87
        root._setOb('guarded', guarded)
1✔
88
        guarded = root._getOb('guarded')
1✔
89

90
        open = FauxFolder()
1✔
91
        open._setId('open')
1✔
92
        open.__roles__ = ('Anonymous', )
1✔
93
        guarded._setOb('open', open)
1✔
94

95
        bound_unused_container_ps = self._newPS('return 1')
1✔
96
        guarded._setOb('bound_unused_container_ps', bound_unused_container_ps)
1✔
97

98
        bound_used_container_ps = self._newPS('return container.id')
1✔
99
        guarded._setOb('bound_used_container_ps', bound_used_container_ps)
1✔
100

101
        bound_used_container_ok_ps = self._newPS('return container.id')
1✔
102
        open._setOb('bound_used_container_ok_ps', bound_used_container_ok_ps)
1✔
103

104
        bound_unused_context_ps = self._newPS('return 1')
1✔
105
        guarded._setOb('bound_unused_context_ps', bound_unused_context_ps)
1✔
106

107
        bound_used_context_ps = self._newPS('return context.id')
1✔
108
        guarded._setOb('bound_used_context_ps', bound_used_context_ps)
1✔
109

110
        bound_used_context_methodWithRoles_ps = self._newPS(
1✔
111
            'return context.methodWithRoles()')
112
        guarded._setOb('bound_used_context_methodWithRoles_ps',
1✔
113
                       bound_used_context_methodWithRoles_ps)
114

115
        container_ps = self._newPS('return container')
1✔
116
        guarded._setOb('container_ps', container_ps)
1✔
117

118
        container_str_ps = self._newPS('return str(container)')
1✔
119
        guarded._setOb('container_str_ps', container_str_ps)
1✔
120

121
        context_ps = self._newPS('return context')
1✔
122
        guarded._setOb('context_ps', context_ps)
1✔
123

124
        context_str_ps = self._newPS('return str(context)')
1✔
125
        guarded._setOb('context_str_ps', context_str_ps)
1✔
126

127
        return root
1✔
128

129
    def _newPS(self, txt, bind=None):
1✔
130
        from Products.PythonScripts.PythonScript import PythonScript
1✔
131
        ps = PythonScript('ps')
1✔
132
        ps.write(txt)
1✔
133
        ps._makeFunction()
1✔
134
        return ps
1✔
135

136
    # These test that the mere binding of context or container, when the
137
    # user doesn't have access to them, doesn't raise an unauthorized. An
138
    # exception *will* be raised if the script attempts to use them. This
139
    # is a b/w compatibility hack: see Bindings.py for details.
140

141
    def test_bound_unused_container(self):
1✔
142
        from AccessControl.SecurityManagement import newSecurityManager
1✔
143
        newSecurityManager(None, UnderprivilegedUser())
1✔
144
        root = self._makeTree()
1✔
145
        guarded = root._getOb('guarded')
1✔
146
        ps = guarded._getOb('bound_unused_container_ps')
1✔
147
        self.assertEqual(ps(), 1)
1✔
148

149
    def test_bound_used_container(self):
1✔
150
        from AccessControl import Unauthorized
1✔
151
        from AccessControl.SecurityManagement import newSecurityManager
1✔
152
        newSecurityManager(None, UnderprivilegedUser())
1✔
153
        root = self._makeTree()
1✔
154
        guarded = root._getOb('guarded')
1✔
155

156
        ps = guarded._getOb('bound_used_container_ps')
1✔
157
        self.assertRaises(Unauthorized, ps)
1✔
158

159
        ps = guarded._getOb('container_str_ps')
1✔
160
        self.assertRaises(Unauthorized, ps)
1✔
161

162
        ps = guarded._getOb('container_ps')
1✔
163
        container = ps()
1✔
164

165
        with self.assertRaises(Unauthorized):
1✔
166
            container()
1✔
167

168
        self.assertRaises(Unauthorized, container.index_html)
1✔
169
        try:
1✔
170
            str(container)
1✔
171
        except Unauthorized:
1✔
172
            pass
1✔
173
        else:
174
            self.fail("str(container) didn't raise Unauthorized!")
175

176
        ps = guarded._getOb('bound_used_container_ps')
1✔
177
        ps._proxy_roles = ('Manager', )
1✔
178
        ps()
1✔
179

180
        ps = guarded._getOb('container_str_ps')
1✔
181
        ps._proxy_roles = ('Manager', )
1✔
182
        ps()
1✔
183

184
    def test_bound_used_container_allowed(self):
1✔
185
        from AccessControl.SecurityManagement import newSecurityManager
1✔
186
        newSecurityManager(None, UnderprivilegedUser())
1✔
187
        root = self._makeTree()
1✔
188
        guarded = root._getOb('guarded')
1✔
189
        open = guarded._getOb('open')
1✔
190
        ps = open.unrestrictedTraverse('bound_used_container_ok_ps')
1✔
191
        self.assertEqual(ps(), 'open')
1✔
192

193
    def test_bound_unused_context(self):
1✔
194
        from AccessControl.SecurityManagement import newSecurityManager
1✔
195
        newSecurityManager(None, UnderprivilegedUser())
1✔
196
        root = self._makeTree()
1✔
197
        guarded = root._getOb('guarded')
1✔
198
        ps = guarded._getOb('bound_unused_context_ps')
1✔
199
        self.assertEqual(ps(), 1)
1✔
200

201
    def test_bound_used_context(self):
1✔
202
        from AccessControl import Unauthorized
1✔
203
        from AccessControl.SecurityManagement import newSecurityManager
1✔
204
        newSecurityManager(None, UnderprivilegedUser())
1✔
205
        root = self._makeTree()
1✔
206
        guarded = root._getOb('guarded')
1✔
207

208
        ps = guarded._getOb('bound_used_context_ps')
1✔
209
        self.assertRaises(Unauthorized, ps)
1✔
210

211
        ps = guarded._getOb('context_str_ps')
1✔
212
        self.assertRaises(Unauthorized, ps)
1✔
213

214
        ps = guarded._getOb('context_ps')
1✔
215
        context = ps()
1✔
216

217
        # Without using the contextmanager 'assertRaises' tries to access an
218
        # attribute of context, which leads to an error right away.
219
        with self.assertRaises(Unauthorized):
1✔
220
            context()
1✔
221

222
        self.assertRaises(Unauthorized, context.index_html)
1✔
223
        try:
1✔
224
            str(context)
1✔
225
        except Unauthorized:
1✔
226
            pass
1✔
227
        else:
228
            self.fail("str(context) didn't raise Unauthorized!")
229

230
        ps = guarded._getOb('bound_used_context_ps')
1✔
231
        ps._proxy_roles = ('Manager', )
1✔
232
        ps()
1✔
233

234
        ps = guarded._getOb('context_str_ps')
1✔
235
        ps._proxy_roles = ('Manager', )
1✔
236
        ps()
1✔
237

238
    def test_bound_used_context_allowed(self):
1✔
239
        from AccessControl.SecurityManagement import newSecurityManager
1✔
240
        newSecurityManager(None, UnderprivilegedUser())
1✔
241
        root = self._makeTree()
1✔
242
        guarded = root._getOb('guarded')
1✔
243
        open = guarded._getOb('open')
1✔
244
        ps = open.unrestrictedTraverse('bound_used_context_ps')
1✔
245
        self.assertEqual(ps(), 'open')
1✔
246

247
    def test_ok_no_bindings(self):
1✔
248
        from AccessControl.SecurityManagement import newSecurityManager
1✔
249
        newSecurityManager(None, UnderprivilegedUser())
1✔
250
        root = self._makeTree()
1✔
251
        guarded = root._getOb('guarded')
1✔
252
        boundless_ps = self._newPS('return 42')
1✔
253
        guarded._setOb('boundless_ps', boundless_ps)
1✔
254
        boundless_ps = guarded._getOb('boundless_ps')
1✔
255
        # Clear the bindings, so that the script may execute.
256
        boundless_ps.ZBindings_edit({'name_context': '',
1✔
257
                                     'name_container': '',
258
                                     'name_m_self': '',
259
                                     'name_ns': '',
260
                                     'name_subpath': ''})
261
        self.assertEqual(boundless_ps(), 42)
1✔
262

263
    def test_bound_used_context_method_w_roles(self):
1✔
264
        from AccessControl import Unauthorized
1✔
265
        from AccessControl.SecurityManagement import newSecurityManager
1✔
266
        newSecurityManager(None, UnderprivilegedUser())
1✔
267
        root = self._makeTree()
1✔
268
        guarded = root._getOb('guarded')
1✔
269

270
        # Assert that we can call a protected method, even though we have
271
        # no access to the context directly.
272
        ps = guarded._getOb('bound_used_context_ps')
1✔
273
        self.assertRaises(Unauthorized, ps)
1✔
274
        ps = guarded._getOb('bound_used_context_methodWithRoles_ps')
1✔
275
        self.assertEqual(ps(), 'method called')
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc