def test_generator_functional_oldstyle(self): self.generates('/:x', {'x': ''}, '/') self.generates('/:x', {'x': 'a'}, '/a') self.generates('zzz/:x', {'x': 'abc'}, '/zzz/abc') self.generates( 'zzz/:x*traverse', {'x': 'abc', 'traverse': ''}, '/zzz/abc' ) self.generates( 'zzz/:x*traverse', {'x': 'abc', 'traverse': '/def/g'}, '/zzz/abc/def/g', ) self.generates( '/:x', {'x': text_(b'/La Pe\xc3\xb1a', 'utf-8')}, '//La%20Pe%C3%B1a', ) self.generates( '/:x*y', {'x': text_(b'/La Pe\xc3\xb1a', 'utf-8'), 'y': '/rest/of/path'}, '//La%20Pe%C3%B1a/rest/of/path', ) self.generates( '*traverse', {'traverse': ('a', text_(b'La Pe\xf1a'))}, '/a/La%20Pe%C3%B1a', ) self.generates('/foo/:id.html', {'id': 'bar'}, '/foo/bar.html') self.generates('/foo/:_', {'_': '20'}, '/foo/20') self.generates('/foo/:_abc', {'_abc': '20'}, '/foo/20') self.generates('/foo/:abc_def', {'abc_def': '20'}, '/foo/20')
def test_absolute_unicode_found(self): # test for bug wiggy found in wild, traceback stack: # root = '/%E6%B5%81%E8%A1%8C%E8%B6%8B%E5%8A%BF' # wiggy's code: section=find_resource(page, root) # find_resource L76: D = traverse(resource, path) # traverse L291: return traverser(request) # __call__ line 568: vpath_tuple = traversal_path(vpath) # lru_cached line 91: f(*arg) # traversal_path line 443: path.encode('ascii') # UnicodeEncodeError: 'ascii' codec can't encode characters in # position 1-12: ordinal not in range(128) # # solution: encode string to ascii in pyramid.traversal.traverse # before passing it along to webob as path_info from pyramid.traversal import ResourceTreeTraverser unprintable = DummyContext() root = DummyContext(unprintable) unprintable.__parent__ = root unprintable.__name__ = text_( b'/\xe6\xb5\x81\xe8\xa1\x8c\xe8\xb6\x8b\xe5\x8a\xbf', 'utf-8' ) root.__parent__ = None root.__name__ = None traverser = ResourceTreeTraverser self._registerTraverser(traverser) result = self._callFUT( root, text_(b'/%E6%B5%81%E8%A1%8C%E8%B6%8B%E5%8A%BF') ) self.assertEqual(result, unprintable)
def test_pattern_with_high_order_literal(self): pattern = text_(b'/La Pe\xc3\xb1a/{x}', 'utf-8') matcher, generator = self._callFUT(pattern) self.assertEqual( matcher(text_(b'/La Pe\xc3\xb1a/x', 'utf-8')), {'x': 'x'} ) self.assertEqual(generator({'x': '1'}), '/La%20Pe%C3%B1a/1')
def test_matcher_functional_oldstyle(self): self.matches('/:x', '', None) self.matches('/:x', '/', None) self.matches('/abc/:def', '/abc/', None) self.matches('/:x', '/a', {'x': 'a'}) self.matches('zzz/:x', '/zzz/abc', {'x': 'abc'}) self.matches( 'zzz/:x*traverse', '/zzz/abc', {'x': 'abc', 'traverse': ()} ) self.matches( 'zzz/:x*traverse', '/zzz/abc/def/g', {'x': 'abc', 'traverse': ('def', 'g')}, ) self.matches('*traverse', '/zzz/abc', {'traverse': ('zzz', 'abc')}) self.matches('*traverse', '/zzz/ abc', {'traverse': ('zzz', ' abc')}) # '/La%20Pe%C3%B1a' # pattern, path, expected self.matches( ':x', text_(b'/La Pe\xc3\xb1a', 'utf-8'), {'x': text_(b'La Pe\xc3\xb1a', 'utf-8')}, ) # '/La%20Pe%C3%B1a/x' self.matches( '*traverse', text_(b'/La Pe\xc3\xb1a/x', 'utf-8'), {'traverse': (text_(b'La Pe\xc3\xb1a', 'utf-8'), 'x')}, ) self.matches('/foo/:id.html', '/foo/bar.html', {'id': 'bar'}) self.matches('/foo/:id_html', '/foo/bar_html', {'id_html': 'bar_html'}) self.matches('zzz/:_', '/zzz/abc', {'_': 'abc'}) self.matches('zzz/:_abc', '/zzz/abc', {'_abc': 'abc'}) self.matches('zzz/:abc_def', '/zzz/abc', {'abc_def': 'abc'})
def test_docs_sample_generate(self): # sample from urldispatch.rst pattern = text_(b'/La Pe\xc3\xb1a/{city}', 'utf-8') _, generator = self._callFUT(pattern) self.assertEqual( generator({'city': text_(b'Qu\xc3\xa9bec', 'utf-8')}), '/La%20Pe%C3%B1a/Qu%C3%A9bec', )
def test_generate_with_string_remainder_and_unicode_replacement(self): pattern = text_(b'/abc*remainder', 'utf-8') _, generator = self._callFUT(pattern) result = generator( {'remainder': text_(b'/Qu\xc3\xa9bec/La Pe\xc3\xb1a', 'utf-8')}) self.assertEqual(result, '/abc/Qu%C3%A9bec/La%20Pe%C3%B1a') # should be a native string self.assertEqual(type(result), str)
def test_generate_with_string_remainder_and_unicode_replacement(self): pattern = text_(b'/abc*remainder', 'utf-8') _, generator = self._callFUT(pattern) result = generator( {'remainder': text_(b'/Qu\xc3\xa9bec/La Pe\xc3\xb1a', 'utf-8')} ) self.assertEqual(result, '/abc/Qu%C3%A9bec/La%20Pe%C3%B1a') # should be a native string self.assertEqual(type(result), str)
def call_app_with_subpath_as_path_info(request, app): # Copy the request. Use the source request's subpath (if it exists) as # the new request's PATH_INFO. Set the request copy's SCRIPT_NAME to the # prefix before the subpath. Call the application with the new request # and return a response. # # Postconditions: # - SCRIPT_NAME and PATH_INFO are empty or start with / # - At least one of SCRIPT_NAME or PATH_INFO are set. # - SCRIPT_NAME is not '/' (it should be '', and PATH_INFO should # be '/'). environ = request.environ script_name = environ.get('SCRIPT_NAME', '') path_info = environ.get('PATH_INFO', '/') subpath = list(getattr(request, 'subpath', ())) new_script_name = '' # compute new_path_info new_path_info = '/' + '/'.join( [text_(x.encode('utf-8'), 'latin-1') for x in subpath] ) if new_path_info != '/': # don't want a sole double-slash if path_info != '/': # if orig path_info is '/', we're already done if path_info.endswith('/'): # readd trailing slash stripped by subpath (traversal) # conversion new_path_info += '/' # compute new_script_name workback = (script_name + path_info).split('/') tmp = [] while workback: if tmp == subpath: break el = workback.pop() if el: tmp.insert(0, text_(bytes_(el, 'latin-1'), 'utf-8')) # strip all trailing slashes from workback to avoid appending undue slashes # to end of script_name while workback and (workback[-1] == ''): workback = workback[:-1] new_script_name = '/'.join(workback) new_request = request.copy() new_request.environ['SCRIPT_NAME'] = new_script_name new_request.environ['PATH_INFO'] = new_path_info return new_request.get_response(app)
def test_subpath_path_info_and_script_name_have_utf8(self): encoded = text_(b'La Pe\xc3\xb1a') decoded = text_(bytes_(encoded), 'utf-8') request = DummyRequest( {'PATH_INFO': '/' + encoded, 'SCRIPT_NAME': '/' + encoded} ) request.subpath = (decoded,) response = self._callFUT(request, 'app') self.assertTrue(request.copied) self.assertEqual(response, 'app') self.assertEqual(request.environ['SCRIPT_NAME'], '/' + encoded) self.assertEqual(request.environ['PATH_INFO'], '/' + encoded)
def test_matcher_functional_newstyle(self): self.matches('/{x}', '', None) self.matches('/{x}', '/', None) self.matches('/abc/{def}', '/abc/', None) self.matches('/{x}', '/a', {'x': 'a'}) self.matches('zzz/{x}', '/zzz/abc', {'x': 'abc'}) self.matches('zzz/{x}*traverse', '/zzz/abc', { 'x': 'abc', 'traverse': () }) self.matches( 'zzz/{x}*traverse', '/zzz/abc/def/g', { 'x': 'abc', 'traverse': ('def', 'g') }, ) self.matches('*traverse', '/zzz/abc', {'traverse': ('zzz', 'abc')}) self.matches('*traverse', '/zzz/ abc', {'traverse': ('zzz', ' abc')}) # '/La%20Pe%C3%B1a' self.matches( '{x}', text_(b'/La Pe\xc3\xb1a', 'utf-8'), {'x': text_(b'La Pe\xc3\xb1a', 'utf-8')}, ) # '/La%20Pe%C3%B1a/x' self.matches( '*traverse', text_(b'/La Pe\xc3\xb1a/x'), {'traverse': (text_(b'La Pe\xc3\xb1a'), 'x')}, ) self.matches('/foo/{id}.html', '/foo/bar.html', {'id': 'bar'}) self.matches( '/{num:[0-9]+}/*traverse', '/555/abc/def', { 'num': '555', 'traverse': ('abc', 'def') }, ) self.matches( '/{num:[0-9]*}/*traverse', '/555/abc/def', { 'num': '555', 'traverse': ('abc', 'def') }, ) self.matches('zzz/{_}', '/zzz/abc', {'_': 'abc'}) self.matches('zzz/{_abc}', '/zzz/abc', {'_abc': 'abc'}) self.matches('zzz/{abc_def}', '/zzz/abc', {'abc_def': 'abc'})
def test_add_route_with_path_info_regex(self): config = self._makeOne(autocommit=True) config.add_route( 'name', 'path', path_info=text_(br'/La Pe\w*', 'utf-8') ) route = self._assertRoute(config, 'name', 'path', 1) predicate = route.predicates[0] request = self._makeRequest(config) request.upath_info = text_(b'/La Pe\xc3\xb1a', 'utf-8') self.assertEqual(predicate(None, request), True) request = self._makeRequest(config) request.upath_info = text_('/') self.assertEqual(predicate(None, request), False)
def test___call__traverse_matches_with_highorder_chars(self): inst = self._makeOne(text_(b'/La Pe\xc3\xb1a/{x}', 'utf-8')) info = {'match': {'x': text_(b'Qu\xc3\xa9bec', 'utf-8')}} request = Dummy() result = inst(info, request) self.assertEqual(result, True) self.assertEqual( info['match']['traverse'], ( text_(b'La Pe\xc3\xb1a', 'utf-8'), text_(b'Qu\xc3\xa9bec', 'utf-8'), ), )
def test_subpath_path_info_and_script_name_have_utf8(self): encoded = text_(b'La Pe\xc3\xb1a') decoded = text_(bytes_(encoded), 'utf-8') request = DummyRequest({ 'PATH_INFO': '/' + encoded, 'SCRIPT_NAME': '/' + encoded }) request.subpath = (decoded, ) response = self._callFUT(request, 'app') self.assertTrue(request.copied) self.assertEqual(response, 'app') self.assertEqual(request.environ['SCRIPT_NAME'], '/' + encoded) self.assertEqual(request.environ['PATH_INFO'], '/' + encoded)
def test_call_withconn_getitem_withpath_withsubpath(self): foo = DummyContext() root = DummyContext(foo) policy = self._makeOne(root) environ = self._getEnviron() request = DummyRequest(environ, path_info=text_('/foo/bar/baz/buz')) result = policy(request) self.assertEqual(result['context'], foo) self.assertEqual(result['view_name'], 'bar') self.assertEqual(result['subpath'], ('baz', 'buz')) self.assertEqual(result['traversed'], (text_('foo'),)) self.assertEqual(result['root'], root) self.assertEqual(result['virtual_root'], root) self.assertEqual(result['virtual_root_path'], ())
def test_generator_functional_newstyle(self): self.generates('/{x}', {'x': ''}, '/') self.generates('/{x}', {'x': 'a'}, '/a') self.generates('/{x}', {'x': 'a/b/c'}, '/a/b/c') self.generates('/{x}', {'x': ':@&+$,'}, '/:@&+$,') self.generates('zzz/{x}', {'x': 'abc'}, '/zzz/abc') self.generates('zzz/{x}*traverse', { 'x': 'abc', 'traverse': '' }, '/zzz/abc') self.generates( 'zzz/{x}*traverse', { 'x': 'abc', 'traverse': '/def/g' }, '/zzz/abc/def/g', ) self.generates( 'zzz/{x}*traverse', { 'x': ':@&+$,', 'traverse': '/:@&+$,' }, '/zzz/:@&+$,/:@&+$,', ) self.generates( '/{x}', {'x': text_(b'/La Pe\xc3\xb1a', 'utf-8')}, '//La%20Pe%C3%B1a', ) self.generates( '/{x}*y', { 'x': text_(b'/La Pe\xc3\xb1a', 'utf-8'), 'y': '/rest/of/path' }, '//La%20Pe%C3%B1a/rest/of/path', ) self.generates( '*traverse', {'traverse': ('a', text_(b'La Pe\xf1a'))}, '/a/La%20Pe%C3%B1a', ) self.generates('/foo/{id}.html', {'id': 'bar'}, '/foo/bar.html') self.generates('/foo/{_}', {'_': '20'}, '/foo/20') self.generates('/foo/{_abc}', {'_abc': '20'}, '/foo/20') self.generates('/foo/{abc_def}', {'abc_def': '20'}, '/foo/20')
def test_route_url(self): environ = { 'PATH_INFO': '/', 'SERVER_NAME': 'example.com', 'SERVER_PORT': '5432', 'QUERY_STRING': 'la=La%20Pe%C3%B1a', 'wsgi.url_scheme': 'http', } from pyramid.interfaces import IRoutesMapper inst = self._makeOne(environ) mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) self.config.registry.registerUtility(mapper, IRoutesMapper) result = inst.route_url( 'flub', 'extra1', 'extra2', a=1, b=2, c=3, _query={'a': 1}, _anchor=text_("foo"), ) self.assertEqual( result, 'http://example.com:5432/1/2/3/extra1/extra2?a=1#foo')
def test_pattern_generate_with_high_order_dynamic(self): pattern = '/{x}' _, generator = self._callFUT(pattern) self.assertEqual( generator({'x': text_(b'La Pe\xc3\xb1a', 'utf-8')}), '/La%20Pe%C3%B1a', )
def test_generate_with_string_remainder_and_nonstring_replacement(self): pattern = text_(b'/abc/*remainder', 'utf-8') _, generator = self._callFUT(pattern) result = generator({'remainder': None}) self.assertEqual(result, '/abc/None') # should be a native string self.assertEqual(type(result), str)
def test_utf16(self): from pyramid.exceptions import URLDecodeError la = text_(b'La Pe\xc3\xb1a', 'utf-8').encode('utf-16') encoded = quote(la) path = '/'.join([encoded, encoded]) self.assertRaises(URLDecodeError, self._callFUT, path)
def test_utf8(self): la = b'La Pe\xc3\xb1a' encoded = quote(la) decoded = text_(la, 'utf-8') path = '/'.join([encoded, encoded]) result = self._callFUT(path) self.assertEqual(result, (decoded, decoded))
def test_unicode(self): class DummyUnicodeObject(object): def __unicode__(self): return text_('42') duo = DummyUnicodeObject() self.assertEqual(self._callFUT(duo), text_('42'))
def test_traverse_matches_with_highorder_chars(self): order, predicates, phash = self._callFUT( traverse=text_(b'/La Pe\xc3\xb1a/{x}', 'utf-8')) self.assertEqual(len(predicates), 1) pred = predicates[0] info = {'match': {'x': text_(b'Qu\xc3\xa9bec', 'utf-8')}} request = DummyRequest() result = pred(info, request) self.assertEqual(result, True) self.assertEqual( info['match']['traverse'], ( text_(b'La Pe\xc3\xb1a', 'utf-8'), text_(b'Qu\xc3\xa9bec', 'utf-8'), ), )
def _set_cookie(self, response): if not self._cookie_on_exception: exception = getattr(self.request, 'exception', None) if ( exception is not None ): # dont set a cookie during exceptions return False cookieval = text_( serializer.dumps((self.accessed, self.created, dict(self))) ) if len(cookieval) > 4064: raise ValueError( 'Cookie value is too long to store (%s bytes)' % len(cookieval) ) response.set_cookie( self._cookie_name, value=cookieval, max_age=self._cookie_max_age, path=self._cookie_path, domain=self._cookie_domain, secure=self._cookie_secure, httponly=self._cookie_httponly, samesite=self._cookie_samesite, ) return True
def test_unicode(self): class DummyUnicodeObject: def __str__(self): return text_('42') duo = DummyUnicodeObject() self.assertEqual(self._callFUT(duo), text_('42'))
def test_route_url(self): environ = { 'PATH_INFO': '/', 'SERVER_NAME': 'example.com', 'SERVER_PORT': '5432', 'QUERY_STRING': 'la=La%20Pe%C3%B1a', 'wsgi.url_scheme': 'http', } from pyramid.interfaces import IRoutesMapper inst = self._makeOne(environ) mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) self.config.registry.registerUtility(mapper, IRoutesMapper) result = inst.route_url( 'flub', 'extra1', 'extra2', a=1, b=2, c=3, _query={'a': 1}, _anchor=text_("foo"), ) self.assertEqual( result, 'http://example.com:5432/1/2/3/extra1/extra2?a=1#foo' )
def test_call_with_vh_root_highorder(self): path = text_(b'Qu\xc3\xa9bec', 'utf-8') bar = DummyContext(None, 'bar') foo = DummyContext(bar, path) root = DummyContext(foo, 'root') policy = self._makeOne(root) vhm_root = b'/Qu\xc3\xa9bec'.decode('latin-1') environ = self._getEnviron(HTTP_X_VHM_ROOT=vhm_root) request = DummyRequest(environ, path_info=text_('/bar')) result = policy(request) self.assertEqual(result['context'], bar) self.assertEqual(result['view_name'], '') self.assertEqual(result['subpath'], ()) self.assertEqual(result['traversed'], (path, text_('bar'))) self.assertEqual(result['root'], policy.root) self.assertEqual(result['virtual_root'], foo) self.assertEqual(result['virtual_root_path'], (path,))
def test_body_template_unicode(self): cls = self._getTargetSubclass() la = text_(b'/La Pe\xc3\xb1a', 'utf-8') environ = _makeEnviron(unicodeval=la) exc = cls(body_template='${unicodeval}') start_response = DummyStartResponse() body = list(exc(environ, start_response))[0] self.assertEqual(body, b'200 OK\n\n/La Pe\xc3\xb1a')
def test_call_with_vh_root3(self): environ = self._getEnviron(HTTP_X_VHM_ROOT='/') baz = DummyContext() bar = DummyContext(baz) foo = DummyContext(bar) root = DummyContext(foo) policy = self._makeOne(root) request = DummyRequest(environ, path_info=text_('/foo/bar/baz')) result = policy(request) self.assertEqual(result['context'], baz) self.assertEqual(result['view_name'], '') self.assertEqual(result['subpath'], ()) self.assertEqual(result['traversed'], (text_('foo'), text_('bar'), text_('baz'))) self.assertEqual(result['root'], root) self.assertEqual(result['virtual_root'], root) self.assertEqual(result['virtual_root_path'], ())
def test_traverse_matches_with_highorder_chars(self): order, predicates, phash = self._callFUT( traverse=text_(b'/La Pe\xc3\xb1a/{x}', 'utf-8') ) self.assertEqual(len(predicates), 1) pred = predicates[0] info = {'match': {'x': text_(b'Qu\xc3\xa9bec', 'utf-8')}} request = DummyRequest() result = pred(info, request) self.assertEqual(result, True) self.assertEqual( info['match']['traverse'], ( text_(b'La Pe\xc3\xb1a', 'utf-8'), text_(b'Qu\xc3\xa9bec', 'utf-8'), ), )
def test_call_with_vh_root3(self): environ = self._getEnviron(HTTP_X_VHM_ROOT='/') baz = DummyContext() bar = DummyContext(baz) foo = DummyContext(bar) root = DummyContext(foo) policy = self._makeOne(root) request = DummyRequest(environ, path_info=text_('/foo/bar/baz')) result = policy(request) self.assertEqual(result['context'], baz) self.assertEqual(result['view_name'], '') self.assertEqual(result['subpath'], ()) self.assertEqual( result['traversed'], (text_('foo'), text_('bar'), text_('baz')) ) self.assertEqual(result['root'], root) self.assertEqual(result['virtual_root'], root) self.assertEqual(result['virtual_root_path'], ())
def test__make_response_result_is_iterable(self): from pyramid.response import Response request = testing.DummyRequest() request.response = Response() helper = self._makeOne('loo.foo') la = text_('/La Pe\xc3\xb1a', 'utf-8') response = helper._make_response([la.encode('utf-8')], request) self.assertEqual(response.body, la.encode('utf-8'))
def check_csrf_token(request, token='csrf_token', header='X-CSRF-Token', raises=True): """ Check the CSRF token returned by the :class:`pyramid.interfaces.ICSRFStoragePolicy` implementation against the value in ``request.POST.get(token)`` (if a POST request) or ``request.headers.get(header)``. If a ``token`` keyword is not supplied to this function, the string ``csrf_token`` will be used to look up the token in ``request.POST``. If a ``header`` keyword is not supplied to this function, the string ``X-CSRF-Token`` will be used to look up the token in ``request.headers``. If the value supplied by post or by header cannot be verified by the :class:`pyramid.interfaces.ICSRFStoragePolicy`, and ``raises`` is ``True``, this function will raise an :exc:`pyramid.exceptions.BadCSRFToken` exception. If the values differ and ``raises`` is ``False``, this function will return ``False``. If the CSRF check is successful, this function will return ``True`` unconditionally. See :ref:`auto_csrf_checking` for information about how to secure your application automatically against CSRF attacks. .. versionadded:: 1.4a2 .. versionchanged:: 1.7a1 A CSRF token passed in the query string of the request is no longer considered valid. It must be passed in either the request body or a header. .. versionchanged:: 1.9 Moved from :mod:`pyramid.session` to :mod:`pyramid.csrf` and updated to use the configured :class:`pyramid.interfaces.ICSRFStoragePolicy` to verify the CSRF token. """ supplied_token = "" # We first check the headers for a csrf token, as that is significantly # cheaper than checking the POST body if header is not None: supplied_token = request.headers.get(header, "") # If this is a POST/PUT/etc request, then we'll check the body to see if it # has a token. We explicitly use request.POST here because CSRF tokens # should never appear in an URL as doing so is a security issue. We also # explicitly check for request.POST here as we do not support sending form # encoded data over anything but a request.POST. if supplied_token == "" and token is not None: supplied_token = request.POST.get(token, "") policy = request.registry.getUtility(ICSRFStoragePolicy) if not policy.check_csrf_token(request, text_(supplied_token)): if raises: raise BadCSRFToken('check_csrf_token(): Invalid token') return False return True
def _no_escape(value): if value is None: return '' if not isinstance(value, str): if isinstance(value, bytes): value = text_(value, 'utf-8') else: value = str(value) return value
def check_csrf_token( request, token='csrf_token', header='X-CSRF-Token', raises=True ): """ Check the CSRF token returned by the :class:`pyramid.interfaces.ICSRFStoragePolicy` implementation against the value in ``request.POST.get(token)`` (if a POST request) or ``request.headers.get(header)``. If a ``token`` keyword is not supplied to this function, the string ``csrf_token`` will be used to look up the token in ``request.POST``. If a ``header`` keyword is not supplied to this function, the string ``X-CSRF-Token`` will be used to look up the token in ``request.headers``. If the value supplied by post or by header cannot be verified by the :class:`pyramid.interfaces.ICSRFStoragePolicy`, and ``raises`` is ``True``, this function will raise an :exc:`pyramid.exceptions.BadCSRFToken` exception. If the values differ and ``raises`` is ``False``, this function will return ``False``. If the CSRF check is successful, this function will return ``True`` unconditionally. See :ref:`auto_csrf_checking` for information about how to secure your application automatically against CSRF attacks. .. versionadded:: 1.4a2 .. versionchanged:: 1.7a1 A CSRF token passed in the query string of the request is no longer considered valid. It must be passed in either the request body or a header. .. versionchanged:: 1.9 Moved from :mod:`pyramid.session` to :mod:`pyramid.csrf` and updated to use the configured :class:`pyramid.interfaces.ICSRFStoragePolicy` to verify the CSRF token. """ supplied_token = "" # We first check the headers for a csrf token, as that is significantly # cheaper than checking the POST body if header is not None: supplied_token = request.headers.get(header, "") # If this is a POST/PUT/etc request, then we'll check the body to see if it # has a token. We explicitly use request.POST here because CSRF tokens # should never appear in an URL as doing so is a security issue. We also # explicitly check for request.POST here as we do not support sending form # encoded data over anything but a request.POST. if supplied_token == "" and token is not None: supplied_token = request.POST.get(token, "") policy = request.registry.getUtility(ICSRFStoragePolicy) if not policy.check_csrf_token(request, text_(supplied_token)): if raises: raise BadCSRFToken('check_csrf_token(): Invalid token') return False return True
def test_generate_with_mixedtype_values(self): pattern = '/{city}/{state}' _, generator = self._callFUT(pattern) result = generator({ 'city': text_(b'Qu\xc3\xa9bec', 'utf-8'), 'state': b'La Pe\xc3\xb1a', }) self.assertEqual(result, '/Qu%C3%A9bec/La%20Pe%C3%B1a') # should be a native string self.assertEqual(type(result), str)
def test_json_body_alternate_charset(self): import json request = self._makeOne({'REQUEST_METHOD': 'POST'}) inp = text_(b'/\xe6\xb5\x81\xe8\xa1\x8c\xe8\xb6\x8b\xe5\x8a\xbf', 'utf-8') body = bytes(json.dumps({'a': inp}), 'utf-16') request.body = body request.content_type = 'application/json; charset=utf-16' self.assertEqual(request.json_body, {'a': inp})
def test_matcher_functional_newstyle(self): self.matches('/{x}', '', None) self.matches('/{x}', '/', None) self.matches('/abc/{def}', '/abc/', None) self.matches('/{x}', '/a', {'x': 'a'}) self.matches('zzz/{x}', '/zzz/abc', {'x': 'abc'}) self.matches( 'zzz/{x}*traverse', '/zzz/abc', {'x': 'abc', 'traverse': ()} ) self.matches( 'zzz/{x}*traverse', '/zzz/abc/def/g', {'x': 'abc', 'traverse': ('def', 'g')}, ) self.matches('*traverse', '/zzz/abc', {'traverse': ('zzz', 'abc')}) self.matches('*traverse', '/zzz/ abc', {'traverse': ('zzz', ' abc')}) # '/La%20Pe%C3%B1a' self.matches( '{x}', text_(b'/La Pe\xc3\xb1a', 'utf-8'), {'x': text_(b'La Pe\xc3\xb1a', 'utf-8')}, ) # '/La%20Pe%C3%B1a/x' self.matches( '*traverse', text_(b'/La Pe\xc3\xb1a/x'), {'traverse': (text_(b'La Pe\xc3\xb1a'), 'x')}, ) self.matches('/foo/{id}.html', '/foo/bar.html', {'id': 'bar'}) self.matches( '/{num:[0-9]+}/*traverse', '/555/abc/def', {'num': '555', 'traverse': ('abc', 'def')}, ) self.matches( '/{num:[0-9]*}/*traverse', '/555/abc/def', {'num': '555', 'traverse': ('abc', 'def')}, ) self.matches('zzz/{_}', '/zzz/abc', {'_': 'abc'}) self.matches('zzz/{_abc}', '/zzz/abc', {'_abc': 'abc'}) self.matches('zzz/{abc_def}', '/zzz/abc', {'abc_def': 'abc'})
def _no_escape(value): if value is None: return '' if not isinstance(value, str): if hasattr(value, '__unicode__'): value = value.__unicode__() if isinstance(value, bytes): value = text_(value, 'utf-8') else: value = str(value) return value
def test_json_body_alternate_charset(self): import json request = self._makeOne({'REQUEST_METHOD': 'POST'}) inp = text_( b'/\xe6\xb5\x81\xe8\xa1\x8c\xe8\xb6\x8b\xe5\x8a\xbf', 'utf-8' ) body = bytes(json.dumps({'a': inp}), 'utf-16') request.body = body request.content_type = 'application/json; charset=utf-16' self.assertEqual(request.json_body, {'a': inp})
def test_call_with_vh_root_path_root(self): policy = self._makeOne(None) environ = self._getEnviron(HTTP_X_VHM_ROOT='/') request = DummyRequest(environ, path_info=text_('/')) result = policy(request) self.assertEqual(result['context'], None) self.assertEqual(result['view_name'], '') self.assertEqual(result['subpath'], ()) self.assertEqual(result['traversed'], ()) self.assertEqual(result['root'], policy.root) self.assertEqual(result['virtual_root'], policy.root) self.assertEqual(result['virtual_root_path'], ())
def test_call_pathel_with_no_getitem(self): policy = self._makeOne(None) environ = self._getEnviron() request = DummyRequest(environ, path_info=text_('/foo/bar')) result = policy(request) self.assertEqual(result['context'], None) self.assertEqual(result['view_name'], 'foo') self.assertEqual(result['subpath'], ('bar',)) self.assertEqual(result['traversed'], ()) self.assertEqual(result['root'], policy.root) self.assertEqual(result['virtual_root'], policy.root) self.assertEqual(result['virtual_root_path'], ())
def test_generate_with_mixedtype_values(self): pattern = '/{city}/{state}' _, generator = self._callFUT(pattern) result = generator( { 'city': text_(b'Qu\xc3\xa9bec', 'utf-8'), 'state': b'La Pe\xc3\xb1a', } ) self.assertEqual(result, '/Qu%C3%A9bec/La%20Pe%C3%B1a') # should be a native string self.assertEqual(type(result), str)
def test_call_withconn_getitem_emptypath_nosubpath(self): root = DummyContext() policy = self._makeOne(root) environ = self._getEnviron() request = DummyRequest(environ, path_info=text_('')) result = policy(request) self.assertEqual(result['context'], root) self.assertEqual(result['view_name'], '') self.assertEqual(result['subpath'], ()) self.assertEqual(result['traversed'], ()) self.assertEqual(result['root'], root) self.assertEqual(result['virtual_root'], root) self.assertEqual(result['virtual_root_path'], ())