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

zopefoundation / Products.PluggableAuthService / 5303493172

pending completion
5303493172

push

github

web-flow
Drop support for Python 2.7, 3.5, 3.6. (#116)

* Drop zserver extra in setup.py. Thus dropping FTP support.
* Drop support for Zope < 5.
Co-authored-by: Jens Vagelpohl <jens@plyp.com>

1288 of 1745 branches covered (73.81%)

Branch coverage included in aggregate %.

127 of 127 new or added lines in 30 files covered. (100.0%)

9619 of 10349 relevant lines covered (92.95%)

0.93 hits per line

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

98.14
/src/Products/PluggableAuthService/tests/test_utils.py
1
##############################################################################
2
#
3
# Copyright (c) 2006 Zope Foundation and Contributors
4
#
5
# This software is subject to the provisions of the Zope Public License,
6
# Version 2.1 (ZPL).  A copy of the ZPL should accompany this
7
# 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
import unittest
1✔
15

16

17
class Test_createViewName(unittest.TestCase):
1✔
18

19
    def _callFUT(self, *args, **kw):
1✔
20
        from ..utils import createViewName
1✔
21
        return createViewName(*args, **kw)
1✔
22

23
    def test_simple(self):
1✔
24
        self.assertEqual(self._callFUT('foo', 'bar'), b'foo-bar')
1✔
25

26
    def test_no_user_handle(self):
1✔
27
        self.assertEqual(self._callFUT('foo', None), b'foo')
1✔
28

29
    def test_latin1_umlaut_in_method(self):
1✔
30
        self.assertEqual(self._callFUT('f\366o'), b'f\xc3\xb6o')
1✔
31

32
    def test_utf8_umlaut_in_method(self):
1✔
33
        self.assertEqual(self._callFUT(b'f\303\266o'), b'f\303\266o')
1✔
34

35
    def test_unicode_umlaut_in_method(self):
1✔
36
        self.assertEqual(self._callFUT('f\366o'), b'f\xc3\xb6o')
1✔
37

38
    def test_latin1_umlaut_in_handle(self):
1✔
39
        self.assertEqual(self._callFUT('foo', 'b\344r'), b'foo-b\xc3\xa4r')
1✔
40

41
    def test_utf8_umlaut_in_handle(self):
1✔
42
        self.assertEqual(self._callFUT('foo', b'b\303\244r'),
1✔
43
                         b'foo-b\xc3\xa4r')
44

45
    def test_unicode_umlaut_in_handle(self):
1✔
46
        self.assertEqual(self._callFUT('foo', 'b\344r'), b'foo-b\303\244r')
1✔
47

48

49
class Test_createKeywords(unittest.TestCase):
1✔
50

51
    def _callFUT(self, *args, **kw):
1✔
52
        from ..utils import createKeywords
1✔
53
        return createKeywords(*args, **kw)
1✔
54

55
    def test_simple(self):
1✔
56
        _ITEMS = (('foo', 'bar'),)
1✔
57
        hashed = _createHashedValue(_ITEMS)
1✔
58
        self.assertEqual(self._callFUT(foo='bar'),
1✔
59
                         {'keywords': hashed})
60

61
    def test_createKeywords_multiple(self):
1✔
62
        _ITEMS = (('foo', 'bar'), ('baz', 'peng'))
1✔
63
        hashed = _createHashedValue(_ITEMS)
1✔
64
        self.assertEqual(self._callFUT(foo='bar', baz='peng'),
1✔
65
                         {'keywords': hashed})
66

67
    def test_createKeywords_latin1_umlaut(self):
1✔
68
        _ITEMS = (('foo', 'bar'), ('baz', 'M\344dchen'))
1✔
69
        hashed = _createHashedValue(_ITEMS)
1✔
70
        self.assertEqual(self._callFUT(foo='bar', baz='M\344dchen'),
1✔
71
                         {'keywords': hashed})
72

73
    def test_createKeywords_utf8_umlaut(self):
1✔
74
        _ITEMS = (('foo', 'bar'), ('baz', 'M\303\244dchen'))
1✔
75
        hashed = _createHashedValue(_ITEMS)
1✔
76
        self.assertEqual(self._callFUT(foo='bar', baz='M\303\244dchen'),
1✔
77
                         {'keywords': hashed})
78

79
    def test_createKeywords_unicode_umlaut(self):
1✔
80
        _ITEMS = (('foo', 'bar'), ('baz', 'M\344dchen'))
1✔
81
        hashed = _createHashedValue(_ITEMS)
1✔
82
        self.assertEqual(self._callFUT(foo='bar', baz='M\344dchen'),
1✔
83
                         {'keywords': hashed})
84

85
    def test_createKeywords_utf16_umlaut(self):
1✔
86
        _ITEMS = (('foo', 'bar'), ('baz', 'M\344dchen'.encode('utf-16')))
1✔
87
        hashed = _createHashedValue(_ITEMS)
1✔
88
        self.assertEqual(self._callFUT(foo='bar',
1✔
89
                                       baz='M\344dchen'.encode('utf-16')),
90
                         {'keywords': hashed})
91

92
    def test_createKeywords_unicode_chinese(self):
1✔
93
        _ITEMS = (('foo', 'bar'), ('baz', '\u03a4\u03b6'))
1✔
94
        hashed = _createHashedValue(_ITEMS)
1✔
95
        self.assertEqual(self._callFUT(foo='bar', baz='\u03a4\u03b6'),
1✔
96
                         {'keywords': hashed})
97

98

99
def _makeRequestWSession(**session):
1✔
100
    from zope.interface import implementer
1✔
101
    from zope.publisher.interfaces.browser import IBrowserRequest
1✔
102

103
    @implementer(IBrowserRequest)
1✔
104
    class _Request(dict):
1✔
105
        pass
1✔
106

107
    request = _Request()
1✔
108
    request.SESSION = session.copy()
1✔
109
    request.form = {}
1✔
110
    return request
1✔
111

112

113
class Test_getCSRFToken(unittest.TestCase):
1✔
114

115
    def _callFUT(self, *args, **kw):
1✔
116
        from ..utils import getCSRFToken
1✔
117
        return getCSRFToken(*args, **kw)
1✔
118

119
    def test_wo_token_in_request(self):
1✔
120
        request = _makeRequestWSession()
1✔
121
        token = self._callFUT(request)
1✔
122
        self.assertTrue(isinstance(token, str))
1✔
123
        self.assertFalse(set(token) - set('0123456789abcdef'))
1✔
124

125
    def test_w_token_in_request(self):
1✔
126
        request = _makeRequestWSession()
1✔
127
        request.SESSION['_csrft_'] = 'deadbeef'
1✔
128
        token = self._callFUT(request)
1✔
129
        self.assertEqual(token, 'deadbeef')
1✔
130

131
    def test_session_fails_truth_test(self):
1✔
132
        # Some session implementations may not be recognized as
133
        # valid sessions because when empty they fail a simple truth test.
134
        # Using a dict here as an example.
135
        request = _makeRequestWSession()
1✔
136
        request.SESSION = {}
1✔
137
        self._callFUT(request)
1✔
138

139
        # After the call, the returned token must also be in the session
140
        # if getCSRFToken has recognized our session as such.
141
        self.assertIn('_csrft_', request.SESSION)
1✔
142

143

144
class Test_checkCSRFToken(unittest.TestCase):
1✔
145

146
    def _callFUT(self, *args, **kw):
1✔
147
        from ..utils import checkCSRFToken
1✔
148
        return checkCSRFToken(*args, **kw)
1✔
149

150
    def test_wo_token_in_session_or_form_w_raises(self):
1✔
151
        from zExceptions import Forbidden
1✔
152
        request = _makeRequestWSession()
1✔
153
        self.assertRaises(Forbidden, self._callFUT, request)
1✔
154

155
    def test_wo_token_in_session_or_form_wo_raises(self):
1✔
156
        request = _makeRequestWSession()
1✔
157
        self.assertFalse(self._callFUT(request, raises=False))
1✔
158

159
    def test_wo_token_in_session_w_token_in_form_w_raises(self):
1✔
160
        from zExceptions import Forbidden
1✔
161
        request = _makeRequestWSession()
1✔
162
        request.form['csrf_token'] = 'deadbeef'
1✔
163
        self.assertRaises(Forbidden, self._callFUT, request)
1✔
164

165
    def test_wo_token_in_session_w_token_in_form_wo_raises(self):
1✔
166
        request = _makeRequestWSession()
1✔
167
        request.form['csrf_token'] = 'deadbeef'
1✔
168
        self.assertFalse(self._callFUT(request, raises=False))
1✔
169

170
    def test_w_token_in_session_wo_token_in_form_w_raises(self):
1✔
171
        from zExceptions import Forbidden
1✔
172
        request = _makeRequestWSession(_csrft_='deadbeef')
1✔
173
        self.assertRaises(Forbidden, self._callFUT, request)
1✔
174

175
    def test_w_token_in_session_wo_token_in_form_wo_raises(self):
1✔
176
        request = _makeRequestWSession(_csrft_='deadbeef')
1✔
177
        self.assertFalse(self._callFUT(request, raises=False))
1✔
178

179
    def test_w_token_in_session_w_token_in_form_miss_w_raises(self):
1✔
180
        from zExceptions import Forbidden
1✔
181
        request = _makeRequestWSession(_csrft_='deadbeef')
1✔
182
        request.form['csrf_token'] = 'bab3l0f'
1✔
183
        self.assertRaises(Forbidden, self._callFUT, request)
1✔
184

185
    def test_w_token_in_session_w_token_in_form_miss_wo_raises(self):
1✔
186
        request = _makeRequestWSession(_csrft_='deadbeef')
1✔
187
        request.form['csrf_token'] = 'bab3l0f'
1✔
188
        self.assertFalse(self._callFUT(request, raises=False))
1✔
189

190
    def test_w_token_in_session_w_token_in_form_hit(self):
1✔
191
        request = _makeRequestWSession(_csrft_='deadbeef')
1✔
192
        request.form['csrf_token'] = 'deadbeef'
1✔
193
        self.assertTrue(self._callFUT(request))
1✔
194

195

196
class CSRFTokenTests(unittest.TestCase):
1✔
197

198
    def _getTargetClass(self):
1✔
199
        from ..utils import CSRFToken
1✔
200
        return CSRFToken
1✔
201

202
    def _makeOne(self, context=None, request=None):
1✔
203
        if context is None:
1!
204
            context = object()
1✔
205
        if request is None:
1!
206
            request = _makeRequestWSession()
×
207
        return self._getTargetClass()(context, request)
1✔
208

209
    def test_wo_token_in_request(self):
1✔
210
        request = _makeRequestWSession()
1✔
211
        token = self._makeOne(request=request)
1✔
212
        value = token.token()
1✔
213
        self.assertTrue(isinstance(value, str))
1✔
214
        self.assertFalse(set(value) - set('0123456789abcdef'))
1✔
215

216
    def test_w_token_in_request(self):
1✔
217
        request = _makeRequestWSession()
1✔
218
        request.SESSION['_csrft_'] = 'deadbeef'
1✔
219
        token = self._makeOne(request=request)
1✔
220
        self.assertEqual(token.token(), 'deadbeef')
1✔
221

222
    def test___call___raises(self):
1✔
223
        from zExceptions import Forbidden
1✔
224
        request = _makeRequestWSession()
1✔
225
        request.SESSION['_csrft_'] = 'deadbeef'
1✔
226
        token = self._makeOne(request=request)
1✔
227
        self.assertRaises(Forbidden, token)
1✔
228

229

230
class Test_csrf_only(unittest.TestCase):
1✔
231

232
    def _callFUT(self, *args, **kw):
1✔
233
        from ..utils import csrf_only
1✔
234
        return csrf_only(*args, **kw)
1✔
235

236
    def test_w_function_no_REQUEST(self):
1✔
237
        def no_request(foo, bar, **kw):
1✔
238
            """I haz no REQUEST"""
239
        self.assertRaises(ValueError, self._callFUT, no_request)
1✔
240

241
    def test_w_function_w_positional_REQUEST(self):
1✔
242
        from zExceptions import Forbidden
1✔
243

244
        def w_positional_request(foo, bar, REQUEST):
1✔
245
            """I haz REQUEST as positional arg"""
246
            return 42
1✔
247

248
        wrapped = self._callFUT(w_positional_request)
1✔
249
        self.assertEqual(wrapped.__name__, w_positional_request.__name__)
1✔
250
        self.assertEqual(wrapped.__module__, w_positional_request.__module__)
1✔
251
        self.assertEqual(wrapped.__doc__, w_positional_request.__doc__)
1✔
252
        self.assertRaises(Forbidden, wrapped, foo=None, bar=None,
1✔
253
                          REQUEST=_makeRequestWSession())
254
        req = _makeRequestWSession(_csrft_='deadbeef')
1✔
255
        req.form['csrf_token'] = 'deadbeef'
1✔
256
        self.assertEqual(wrapped(foo=None, bar=None, REQUEST=req), 42)
1✔
257

258
    def test_w_function_w_optional_REQUEST(self):
1✔
259
        from zExceptions import Forbidden
1✔
260

261
        def w_optional_request(foo, bar, REQUEST=None):
1✔
262
            """I haz REQUEST as kw arg"""
263
            return 42
1✔
264

265
        wrapped = self._callFUT(w_optional_request)
1✔
266
        self.assertEqual(wrapped.__name__, w_optional_request.__name__)
1✔
267
        self.assertEqual(wrapped.__module__, w_optional_request.__module__)
1✔
268
        self.assertEqual(wrapped.__doc__, w_optional_request.__doc__)
1✔
269
        self.assertRaises(Forbidden, wrapped, foo=None, bar=None,
1✔
270
                          REQUEST=_makeRequestWSession())
271
        req = _makeRequestWSession(_csrft_='deadbeef')
1✔
272
        req.form['csrf_token'] = 'deadbeef'
1✔
273
        self.assertEqual(wrapped(foo=None, bar=None, REQUEST=req), 42)
1✔
274

275

276
class Test_utils(unittest.TestCase):
1✔
277

278
    def test_url_local(self):
1✔
279
        from ..utils import url_local
1✔
280

281
        # Protocol and host will be removed
282
        url_input = 'https://evil-site.com/exploit?arg1=val1&arg2=val2'
1✔
283
        self.assertEqual(url_local(url_input), '/exploit?arg1=val1&arg2=val2')
1✔
284

285
        # Site-local paths are unchanged
286
        url_input = '/local/path?arg1=val1&arg2=val2'
1✔
287
        self.assertEqual(url_local(url_input), url_input)
1✔
288

289
        # Empty paths are unchanged
290
        for url_input in ('', None):
1✔
291
            self.assertEqual(url_local(url_input), url_input)
1✔
292

293

294
def _createHashedValue(items):
1✔
295
    from hashlib import sha1 as sha
1✔
296

297
    hasher = sha()
1✔
298
    items = sorted(items)
1✔
299
    for k, v in items:
1✔
300
        if isinstance(k, str):
1!
301
            k = k.encode('utf-8')
1✔
302
        hasher.update(k)
1✔
303
        if isinstance(v, str):
1✔
304
            v = v.encode('utf-8')
1✔
305
        hasher.update(v)
1✔
306
    return hasher.hexdigest()
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