def check_csrf_token(request, token='csrf_token', header='X-CSRF-Token', raises=True): """ Check the CSRF token in the request's session against the value in ``request.params.get(token)`` 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.params``. 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 param or by header doesn't match the value supplied by ``request.session.get_csrf_token()``, and ``raises`` is ``True``, this function will raise an :exc:`pyramid.exceptions.BadCSRFToken` exception. If the check does succeed and ``raises`` is ``False``, this function will return ``False``. If the CSRF check is successful, this function will return ``True`` unconditionally. Note that using this function requires that a :term:`session factory` is configured. .. versionadded:: 1.4a2 """ supplied_token = request.params.get(token, request.headers.get(header, "")) expected_token = request.session.get_csrf_token() if strings_differ(bytes_(expected_token), bytes_(supplied_token)): if raises: raise BadCSRFToken('check_csrf_token(): Invalid token') return False return True
def test_blob(self): import ptah.cms blob = ptah.cms.blob_storage.add(BytesIO(bytes_('blob data','utf-8'))) self.assertTrue(ptah.cms.IBlob.providedBy(blob)) self.assertEqual(blob.read(), bytes_('blob data','utf-8')) self.assertTrue(ptah.cms.IBlobStorage.providedBy(ptah.cms.blob_storage))
def signed_serialize(data, secret): """Serialize any pickleable structure (``data``) and sign it using the ``secret`` (must be a string). Return the serialization, which includes the signature as its first 40 bytes. The ``signed_deserialize`` method will deserialize such a value. This function is useful for creating signed cookies. For example: .. code-block:: python cookieval = signed_serialize({'a':1}, 'secret') response.set_cookie('signed_cookie', cookieval) .. deprecated:: 1.10 This function will be removed in :app:`Pyramid` 2.0. It is using pickle-based serialization, which is considered vulnerable to remote code execution attacks and will no longer be used by the default session factories at that time. """ pickled = pickle.dumps(data, pickle.HIGHEST_PROTOCOL) try: # bw-compat with pyramid <= 1.5b1 where latin1 is the default secret = bytes_(secret) except UnicodeEncodeError: secret = bytes_(secret, 'utf-8') sig = hmac.new(secret, pickled, hashlib.sha1).hexdigest() return sig + native_(base64.b64encode(pickled))
def test_blob(self): import ptahcms blob = ptahcms.blob_storage.add(BytesIO(bytes_('blob data', 'utf-8'))) self.assertTrue(ptahcms.IBlob.providedBy(blob)) self.assertEqual(blob.read(), bytes_('blob data', 'utf-8')) self.assertTrue(ptahcms.IBlobStorage.providedBy(ptahcms.blob_storage))
def signed_deserialize(serialized, secret, hmac=hmac): """ Deserialize the value returned from ``signed_serialize``. If the value cannot be deserialized for any reason, a :exc:`ValueError` exception will be raised. This function is useful for deserializing a signed cookie value created by ``signed_serialize``. For example: .. code-block:: python cookieval = request.cookies['signed_cookie'] data = signed_deserialize(cookieval, 'secret') """ # hmac parameterized only for unit tests try: input_sig, pickled = (bytes_(serialized[:40]), base64.b64decode(bytes_(serialized[40:]))) except (binascii.Error, TypeError) as e: # Badly formed data can make base64 die raise ValueError('Badly formed base64 data: %s' % e) try: # bw-compat with pyramid <= 1.5b1 where latin1 is the default secret = bytes_(secret) except UnicodeEncodeError: secret = bytes_(secret, 'utf-8') sig = bytes_(hmac.new(secret, pickled, hashlib.sha1).hexdigest()) # Avoid timing attacks (see # http://seb.dbzteam.org/crypto/python-oauth-timing-hmac.pdf) if strings_differ(sig, input_sig): raise ValueError('Invalid signature') return pickle.loads(pickled)
def pbkdf2_bin(data, salt, iterations=1000, keylen=24, hashfunc=None): """Returns a binary digest for the PBKDF2 hash algorithm of `data` with the given `salt`. It iterates `iterations` time and produces a key of `keylen` bytes. By default SHA-1 is used as hash function, a different hashlib `hashfunc` can be provided. """ hashfunc = hashfunc or hashlib.sha1 mac = hmac.new(bytes_(data), None, hashfunc) def _pseudorandom(x, mac=mac): h = mac.copy() h.update(bytes_(x)) if PY3: # pragma: no cover return [x for x in h.digest()] else: # pragma: no cover return map(ord, h.digest()) buf = [] for block in range_(1, -(-keylen // mac.digest_size) + 1): rv = u = _pseudorandom(bytes_(salt) + _pack_int(block)) for i in range_(iterations - 1): if PY3: # pragma: no cover u = _pseudorandom(bytes(u)) else: # pragma: no cover u = _pseudorandom(''.join(map(chr, u))) rv = starmap(xor, zip(rv, u)) buf.extend(rv) if PY3: # pragma: no cover return bytes(buf)[:keylen] else: # pragma: no cover return ''.join(map(chr, buf))[:keylen]
def oauth_response(result): headers, body, status = result return Response(body=body, status=status, headers={ bytes_(name, 'utf-8'): bytes_(value, 'utf-8') for name, value in headers.iteritems() })
def signed_deserialize(serialized, secret, hmac=hmac): """ Deserialize the value returned from ``signed_serialize``. If the value cannot be deserialized for any reason, a :exc:`ValueError` exception will be raised. This function is useful for deserializing a signed cookie value created by ``signed_serialize``. For example: .. code-block:: python cookieval = request.cookies['signed_cookie'] data = signed_deserialize(cookieval, 'secret') """ # hmac parameterized only for unit tests try: input_sig, pickled = (serialized[:40], base64.b64decode(bytes_(serialized[40:]))) except (binascii.Error, TypeError) as e: # Badly formed data can make base64 die raise ValueError('Badly formed base64 data: %s' % e) sig = hmac.new(bytes_(secret), pickled, sha1).hexdigest() # Avoid timing attacks (see # http://seb.dbzteam.org/crypto/python-oauth-timing-hmac.pdf) if strings_differ(sig, input_sig): raise ValueError('Invalid signature') return pickle.loads(pickled)
def unsign_session_id(cookie, secret): cookie = bytes_(cookie) input_sig, session_id = (cookie[:32], cookie[32:]) sig = hmac.new(bytes_(secret), session_id, sha1).digest() # Avoid timing attacks (see # http://seb.dbzteam.org/crypto/python-oauth-timing-hmac.pdf) if strings_differ(base64.b32encode(sig), input_sig): raise ValueError('Invalid signature') return session_id
def calculate_digest(ip, timestamp, secret, userid, tokens, user_data): secret = bytes_(secret, 'utf-8') userid = bytes_(userid, 'utf-8') tokens = bytes_(tokens, 'utf-8') user_data = bytes_(user_data, 'utf-8') digest0 = md5( encode_ip_timestamp(ip, timestamp) + secret + userid + b'\0' + tokens + b'\0' + user_data).hexdigest() digest = md5(bytes_(digest0) + secret).hexdigest() return digest
def test_blob_write(self): import ptah blob_uri = ptah.cms.blob_storage.add( BytesIO(bytes_('blob data','utf-8'))).__uri__ blob = ptah.resolve(blob_uri) blob.write(bytes_('new data','utf-8')) transaction.commit() blob = ptah.resolve(blob_uri) self.assertEqual(blob.read(), bytes_('new data','utf-8'))
def test_blob_write(self): import ptahcms blob_uri = ptahcms.blob_storage.add( BytesIO(bytes_('blob data', 'utf-8'))).__uri__ blob = ptah.resolve(blob_uri) blob.write(bytes_('new data', 'utf-8')) transaction.commit() blob = ptah.resolve(blob_uri) self.assertEqual(blob.read(), bytes_('new data', 'utf-8'))
def check_csrf_token(request, token='csrf_token', header='X-CSRF-Token', raises=True): """ Check the CSRF token in the request's session 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 doesn't match the value supplied by ``request.session.get_csrf_token()``, 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. Note that using this function requires that a :term:`session factory` is configured. 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. """ supplied_token = "" # 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 token is not None: supplied_token = request.POST.get(token, "") # If we were unable to locate a CSRF token in a request body, then we'll # check to see if there are any headers that have a value for us. if supplied_token == "" and header is not None: supplied_token = request.headers.get(header, "") expected_token = request.session.get_csrf_token() if strings_differ(bytes_(expected_token), bytes_(supplied_token)): if raises: raise BadCSRFToken('check_csrf_token(): Invalid token') return False return True
def test_blob_resolver(self): import ptah blob = ptah.cms.blob_storage.add(BytesIO(bytes_('blob data', 'utf-8'))) blob_uri = blob.__uri__ transaction.commit() blob = ptah.resolve(blob_uri) self.assertEqual(blob.__uri__, blob_uri) self.assertEqual(blob.read(), bytes_('blob data', 'utf-8'))
def test_blob_resolver(self): import ptahcms blob = ptahcms.blob_storage.add(BytesIO(bytes_('blob data','utf-8'))) blob_uri = blob.__uri__ transaction.commit() blob = ptah.resolve(blob_uri) self.assertEqual(blob.__uri__, blob_uri) self.assertEqual(blob.read(), bytes_('blob data','utf-8'))
def calculate_digest(ip, timestamp, secret, userid, tokens, user_data, hashalg='md5'): secret = bytes_(secret, 'utf-8') userid = bytes_(userid, 'utf-8') tokens = bytes_(tokens, 'utf-8') user_data = bytes_(user_data, 'utf-8') hash_obj = hashlib.new(hashalg) hash_obj.update( encode_ip_timestamp(ip, timestamp) + secret + userid + b'\0' + tokens + b'\0' + user_data) digest = hash_obj.hexdigest() hash_obj2 = hashlib.new(hashalg) hash_obj2.update(bytes_(digest) + secret) return hash_obj2.hexdigest()
def test_blob_rest_data(self): import ptah.cms from ptah.cms.rest import blobData blob = ptah.cms.blob_storage.add(BytesIO(bytes_('blob data', 'utf-8')), filename='test.txt', mimetype='text/plain') response = blobData(blob, self.request) self.assertEqual(response.body, bytes_('blob data', 'utf-8')) self.assertEqual( response.headerlist, [('Content-Disposition', bytes_('filename="test.txt"', 'utf-8')), ('Content-Length', '9')])
def test_blob_rest_data(self): import ptah.cms from ptah.cms.rest import blobData blob = ptah.cms.blob_storage.add( BytesIO(bytes_('blob data','utf-8')), filename='test.txt', mimetype='text/plain') response = blobData(blob, self.request) self.assertEqual(response.body, bytes_('blob data','utf-8')) self.assertEqual( response.headerlist, [('Content-Disposition', bytes_('filename="test.txt"','utf-8')), ('Content-Length', '9')])
def test_password_ssha(self): from ptah.password import SSHAPasswordManager manager = SSHAPasswordManager() password = text_("right А", 'utf-8') encoded = manager.encode(password, salt=bytes_("",'utf-8')) self.assertEqual( encoded, bytes_('{ssha}BLTuxxVMXzouxtKVb7gLgNxzdAI=','ascii')) self.assertTrue(manager.check(encoded, password)) self.assertFalse(manager.check(encoded, password + "wrong")) encoded = manager.encode(password) self.assertTrue(manager.check(encoded, password))
def test_member_representer(self, member_representer, collection, monkeypatch): mb = next(iter(collection)) rpr_str = member_representer.to_string(mb) mb_reloaded = member_representer.from_string(rpr_str) assert mb.id == mb_reloaded.id # Check unicode handling. mb.text = u'h\xfclfe' bytes_val = bytes_(mb.text, encoding=member_representer.encoding) attr = get_domain_class_attribute(MyEntity, 'text') def test(member, exp_val): rpr_text = member_representer.to_string(member) assert isinstance(rpr_text, text_type) rpr_bytes = member_representer.to_bytes(member) assert isinstance(rpr_bytes, binary_type) mb_reloaded_str = member_representer.from_string(rpr_text) assert isinstance(mb_reloaded_str.text, attr.attr_type) assert mb_reloaded_str.text == exp_val mb_reloaded_bytes = member_representer.from_bytes(rpr_bytes) assert isinstance(mb_reloaded_bytes.text, attr.attr_type) assert mb_reloaded_bytes.text == exp_val # de = member_representer.resource_to_data(member) assert isinstance(de, MemberDataElement) rpr_data_bytes = member_representer.data_to_bytes(de) assert isinstance(rpr_data_bytes, binary_type) # In PY3, the attr type will be text, in PY2 bytes. if not issubclass(attr.attr_type, binary_type): monkeypatch.setattr(attr, 'attr_type', binary_type) test(mb, bytes_val) # In PY3, the attr type will be text, in PY2 bytes. if not issubclass(attr.attr_type, text_type): monkeypatch.setattr(attr, 'attr_type', text_type) test(mb, mb.text)
def forbidden_view(context, request): msg = context.message result = context.result message = msg + '\n' + str(result) resp = HTTPForbidden() resp.body = bytes_(message) return resp
def test_render_template_with_escaped_single_braces(self): inst = self._makeOne() result = inst.render_template('{{a}} {{b}} \{a\} \{b', { 'a': '1', 'b': '2' }) self.assertEqual(result, bytes_('1 2 \{a\} \{b'))
def encode_ip_timestamp(ip, timestamp): ip_chars = ''.join(map(chr, map(int, ip.split('.')))) t = int(timestamp) ts = ((t & 0xff000000) >> 24, (t & 0xff0000) >> 16, (t & 0xff00) >> 8, t & 0xff) ts_chars = ''.join(map(chr, ts)) return bytes_(ip_chars + ts_chars)
def encode(self, password, salt=None): if salt is None: salt = urandom(4) hash = sha1(self._encoder(password)[0]) hash.update(salt) return bytes_('{ssha}', 'ascii') + urlsafe_b64encode(hash.digest() + salt)
def dummy_signed_deserialize(serialized, secret): import base64 from pyramid.compat import pickle, bytes_ serialized_data = base64.b64decode( serialized[len(base64.b64encode(bytes_(secret))):]) return pickle.loads(serialized_data)
def test_render_template_with_breaking_escaped_braces(self): inst = self._makeOne() result = inst.render_template('{{a}} {{b}} \\{\\{a\\} \\{b\\}\\}', { 'a': '1', 'b': '2' }) self.assertEqual(result, bytes_('1 2 \\{\\{a\\} \\{b\\}\\}'))
def __init__(self, request): self.request = request now = time.time() created = renewed = now new = True value = None state = {} cookieval = request.cookies.get(self._cookie_name) if cookieval is not None: try: value = serializer.loads(bytes_(cookieval)) except ValueError: # the cookie failed to deserialize, dropped value = None if value is not None: try: renewed, created, state = value new = False if now - renewed > self._timeout: # expire the session because it was not renewed # before the timeout threshold state = {} except TypeError: # value failed to unpack properly or renewed was not # a numeric type so we'll fail deserialization here state = {} self.created = created self.accessed = renewed self.renewed = renewed self.new = new dict.__init__(self, state)
def make_param_predicates(param_type, param, params_attr, weights, weight, predicates, hash): if not is_nonstr_iter(param): param = (param,) param = sorted(param) text = "%s_param %r" % (param_type, param) reqs = [] for p in param: pair = p.split('=', 1) if len(pair) == 1: pair = pair+[None] reqs.append(pair) if len(reqs) == 1 and reqs[0][1] is None: text = "%s_param %s" % (param_type, param[0]) def param_predicate(context, request): params = getattr(request, params_attr) for k, v in reqs: if v is None: return k in params if params.get(k) != v: return False return True param_predicate.__text__ = text weights.append(1 << weight) predicates.append(param_predicate) for p in param: hash.update(bytes_('%s_param:%r' % (param_type, p)))
def _pseudorandom(x, mac=mac): h = mac.copy() h.update(bytes_(x)) if PY3: # pragma: no cover return [x for x in h.digest()] else: # pragma: no cover return map(ord, h.digest())
def test_mailtmpl_attachment_inline(self): cls = self._make_one() tmpl = cls(Content(), DummyRequest()) self.assertEqual(tmpl.get_attachments(), []) tmpl.add_attachment(bytes_('File data', 'utf-8'), 'text/plain', 'file.txt', 'inline') self.assertEqual(tmpl.get_attachments(), [(bytes_( 'File data', 'utf-8'), 'text/plain', 'file.txt', 'inline')]) msg = tmpl() payload = msg.get_payload()[0] payload = payload.get_payload()[-1] self.assertEqual(payload['Content-Disposition'], bytes_('inline; filename="file.txt"', 'utf-8'))
def generate_session_key(): """ Generate a session key :return: session key """ random = os.urandom(24) return base64.b64encode(bytes_(random))
def _create_file(self, text): d, fn = tempfile.mkstemp() self._files.append(fn) with open(fn, 'wb') as f: f.write(bytes_(text, 'utf-8')) return fn
def make(self, config, **kw): # Given a configurator and a list of keywords, a predicate list is # computed. Elsewhere in the code, we evaluate predicates using a # generator expression. All predicates associated with a view or # route must evaluate true for the view or route to "match" during a # request. The fastest predicate should be evaluated first, then the # next fastest, and so on, as if one returns false, the remainder of # the predicates won't need to be evaluated. # # While we compute predicates, we also compute a predicate hash (aka # phash) that can be used by a caller to identify identical predicate # lists. ordered = self.sorter.sorted() phash = md5() weights = [] preds = [] for n, (name, predicate_factory) in enumerate(ordered): vals = kw.pop(name, None) if vals is None: # XXX should this be a sentinel other than None? continue if not isinstance(vals, predvalseq): vals = (vals, ) for val in vals: pred = predicate_factory(val, config) hashes = pred.phash() if not is_nonstr_iter(hashes): hashes = [hashes] for h in hashes: phash.update(bytes_(h)) weights.append(1 << n + 1) preds.append(pred) if kw: raise ConfigurationError('Unknown predicate values: %r' % (kw, )) # A "order" is computed for the predicate list. An order is # a scoring. # # Each predicate is associated with a weight value. The weight of a # predicate symbolizes the relative potential "importance" of the # predicate to all other predicates. A larger weight indicates # greater importance. # # All weights for a given predicate list are bitwise ORed together # to create a "score"; this score is then subtracted from # MAX_ORDER and divided by an integer representing the number of # predicates+1 to determine the order. # # For views, the order represents the ordering in which a "multiview" # ( a collection of views that share the same context/request/name # triad but differ in other ways via predicates) will attempt to call # its set of views. Views with lower orders will be tried first. # The intent is to a) ensure that views with more predicates are # always evaluated before views with fewer predicates and b) to # ensure a stable call ordering of views that share the same number # of predicates. Views which do not have any predicates get an order # of MAX_ORDER, meaning that they will be tried very last. score = 0 for bit in weights: score = score | bit order = (MAX_ORDER - score) / (len(preds) + 1) return order, preds, phash.hexdigest()
def test_settings_initialize_load_settings_include(self): from ptah.settings import init_settings path = os.path.join(self.dir, 'settings.cfg') f = open(path, 'wb') f.write(bytes_('[DEFAULT]\ngroup.node1 = value\n\n','ascii')) f.close() node1 = ptah.form.TextField( 'node1', default = 'default1') node2 = ptah.form.IntegerField( 'node2', default = 10) ptah.register_settings('group', node1, node2) self.init_ptah() init_settings(self.config, {'include': path}) group = ptah.get_settings('group', self.request.registry) self.assertEqual(group['node1'], 'value') self.assertEqual(group['node2'], 10)
def make(self, config, **kw): # Given a configurator and a list of keywords, a predicate list is # computed. Elsewhere in the code, we evaluate predicates using a # generator expression. All predicates associated with a view or # route must evaluate true for the view or route to "match" during a # request. The fastest predicate should be evaluated first, then the # next fastest, and so on, as if one returns false, the remainder of # the predicates won't need to be evaluated. # # While we compute predicates, we also compute a predicate hash (aka # phash) that can be used by a caller to identify identical predicate # lists. ordered = self.sorter.sorted() phash = md5() weights = [] preds = [] for n, (name, predicate_factory) in enumerate(ordered): vals = kw.pop(name, None) if vals is None: # XXX should this be a sentinel other than None? continue if not isinstance(vals, predvalseq): vals = (vals,) for val in vals: pred = predicate_factory(val, config) hashes = pred.phash() if not is_nonstr_iter(hashes): hashes = [hashes] for h in hashes: phash.update(bytes_(h)) weights.append(1 << n + 1) preds.append(pred) if kw: raise ConfigurationError("Unknown predicate values: %r" % (kw,)) # A "order" is computed for the predicate list. An order is # a scoring. # # Each predicate is associated with a weight value. The weight of a # predicate symbolizes the relative potential "importance" of the # predicate to all other predicates. A larger weight indicates # greater importance. # # All weights for a given predicate list are bitwise ORed together # to create a "score"; this score is then subtracted from # MAX_ORDER and divided by an integer representing the number of # predicates+1 to determine the order. # # For views, the order represents the ordering in which a "multiview" # ( a collection of views that share the same context/request/name # triad but differ in other ways via predicates) will attempt to call # its set of views. Views with lower orders will be tried first. # The intent is to a) ensure that views with more predicates are # always evaluated before views with fewer predicates and b) to # ensure a stable call ordering of views that share the same number # of predicates. Views which do not have any predicates get an order # of MAX_ORDER, meaning that they will be tried very last. score = 0 for bit in weights: score = score | bit order = (MAX_ORDER - score) / (len(preds) + 1) return order, preds, phash.hexdigest()
def secret_is_invalid(secret): # Make sure we don't generate valid key accidentally try: secret_bytes = base64.urlsafe_b64decode(bytes_(secret)) return len(secret_bytes) not in SECRET_SIZES except: return True
def test_unauthenticated_userid_invalid_payload(self): import base64 request = testing.DummyRequest() request.headers['Authorization'] = 'Basic %s' % base64.b64encode( bytes_('chrisrpassword')).decode('ascii') policy = self._makeOne(None) self.assertEqual(policy.unauthenticated_userid(request), None)
def forbidden_view(context, request): msg = context.message result = context.result message = msg + "\n" + str(result) resp = HTTPForbidden() resp.body = bytes_(message) return resp
def check(self, encoded_password, password): # urlsafe_b64decode() cannot handle unicode input string. We # encode to ascii. This is safe as the encoded_password string # should not contain non-ascii characters anyway. encoded_password = bytes_(encoded_password, 'ascii') byte_string = urlsafe_b64decode(encoded_password[6:]) salt = byte_string[20:] return encoded_password == self.encode(password, salt)
def data_to_bytes(self, data_element, encoding=None): """ Overwritten so we can insert the `?xml` processing directive. """ if encoding is None: encoding = self.encoding text = self.__tmpl % (encoding, self.data_to_string(data_element)) return bytes_(text, encoding=encoding)
def to_bytes(self, obj, encoding=None): """ Overwritten so we can insert the `?xml` processing directive. """ if encoding is None: encoding = self.encoding text = self.__tmpl % (encoding, self.to_string(obj)) return bytes_(text, encoding=encoding)
def test_extracted_json_values(self): """Extracted JSON values are unicode in PY2.""" body = '{"foo": "bar", "currency": "\xe2\x82\xac"}' request = Request.blank("/", body=compat.bytes_(body)) data = extract_cstruct(request) self.assertEqual(type(data["body"]["foo"]), compat.text_type) self.assertEqual(type(data["body"]["currency"]), compat.text_type) self.assertEqual(data["body"]["currency"], u"€")
def test_mailtmpl_headers_encoding(self): cls = self._make_one() tmpl = cls(Content(), DummyRequest()) tmpl.add_header('X-Mailer', 'ptah', True) msg = tmpl() self.assertEqual(msg['X-Mailer'].encode(), bytes_('=?utf-8?q?ptah?='))
def template_renderer(self, content, vars, filename=None): content = native_(content, fsenc) try: return bytes_( substitute_double_braces(content, TypeMapper(vars)), fsenc) except Exception as e: _add_except(e, ' in file %s' % filename) raise
def bytes_from_data(self, data_element, encoding=None): """ Overwritten so we can insert the `?xml` processing directive. """ if encoding is None: encoding = self.encoding text = self.__tmpl % (encoding, self.string_from_data(data_element)) return bytes_(text, encoding=encoding)
def test_extracted_json_values(self): """Extracted JSON values are unicode in PY2.""" body = '{"foo": "bar", "currency": "\xe2\x82\xac"}' request = Request.blank('/', body=compat.bytes_(body)) data = extract_cstruct(request) self.assertEqual(type(data['body']['foo']), compat.text_type) self.assertEqual(type(data['body']['currency']), compat.text_type) self.assertEqual(data['body']['currency'], u'€')
def test_blob_metadata(self): import ptah.cms blob = ptah.cms.blob_storage.add( BytesIO(bytes_('blob data','utf-8')), filename='test.txt', mimetype='text/plain') self.assertEqual(blob.filename, 'test.txt') self.assertEqual(blob.mimetype, 'text/plain')
def test_mailtmpl_attachment_inline(self): cls = self._make_one() tmpl = cls(Content(), DummyRequest()) self.assertEqual(tmpl.get_attachments(), []) tmpl.add_attachment(bytes_('File data','utf-8'), 'text/plain', 'file.txt', 'inline') self.assertEqual( tmpl.get_attachments(), [(bytes_('File data','utf-8'), 'text/plain', 'file.txt', 'inline')]) msg = tmpl() payload = msg.get_payload()[0] payload = payload.get_payload()[-1] self.assertEqual( payload['Content-Disposition'], bytes_('inline; filename="file.txt"','utf-8'))