[FIX] P3: hash/hmac payload must be bytes
This commit is contained in:
@@ -433,7 +433,7 @@ class Escpos:
|
||||
|
||||
print('print_b64_img')
|
||||
|
||||
id = md5(img).digest()
|
||||
id = md5(img.encode('utf-8')).digest()
|
||||
|
||||
if id not in self.img_cache:
|
||||
print('not in cache')
|
||||
|
||||
@@ -570,7 +570,7 @@ class MailThread(models.AbstractModel):
|
||||
def _generate_notification_token(self, base_link, params):
|
||||
secret = self.env['ir.config_parameter'].sudo().get_param('database.secret')
|
||||
token = '%s?%s' % (base_link, ' '.join('%s=%s' % (key, params[key]) for key in sorted(params)))
|
||||
hm = hmac.new(str(secret), token, hashlib.sha1).hexdigest()
|
||||
hm = hmac.new(secret.encode('utf-8'), token.encode('utf-8'), hashlib.sha1).hexdigest()
|
||||
return hm
|
||||
|
||||
@api.multi
|
||||
|
||||
@@ -430,7 +430,7 @@ class MassMailing(models.Model):
|
||||
secret = self.env["ir.config_parameter"].sudo().get_param(
|
||||
"database.secret")
|
||||
token = (self.env.cr.dbname, self.id, int(res_id), tools.ustr(email))
|
||||
return hmac.new(str(secret), repr(token), hashlib.sha512).hexdigest()
|
||||
return hmac.new(secret.encode('utf-8'), repr(token).encode('utf-8'), hashlib.sha512).hexdigest()
|
||||
|
||||
def _compute_next_departure(self):
|
||||
cron_next_call = self.env.ref('mass_mailing.ir_cron_mass_mailing_queue').sudo().nextcall
|
||||
|
||||
@@ -583,7 +583,7 @@ class PaymentTransaction(models.Model):
|
||||
token = '%s%s%s' % (self.callback_model_id.model,
|
||||
self.callback_res_id,
|
||||
self.sudo().callback_method)
|
||||
return hmac.new(str(secret), token, hashlib.sha256).hexdigest()
|
||||
return hmac.new(secret.encode('utf-8'), token.encode('utf-8'), hashlib.sha256).hexdigest()
|
||||
|
||||
# --------------------------------------------------
|
||||
# FORM RELATED METHODS
|
||||
|
||||
@@ -54,7 +54,7 @@ class AcquirerAdyen(models.Model):
|
||||
escapeVal(v)
|
||||
for v in chain(pycompat.keys(parms), pycompat.values(parms))
|
||||
)
|
||||
hm = hmac.new(hmac_key, signing_string, hashlib.sha256)
|
||||
hm = hmac.new(hmac_key, signing_string.encode('utf-8'), hashlib.sha256)
|
||||
return base64.b64encode(hm.digest())
|
||||
|
||||
assert inout in ('in', 'out')
|
||||
|
||||
@@ -54,7 +54,7 @@ class PaymentAcquirerAuthorize(models.Model):
|
||||
values['x_fp_timestamp'],
|
||||
values['x_amount'],
|
||||
values['x_currency_code']])
|
||||
return hmac.new(str(values['x_trans_key']), data, hashlib.md5).hexdigest()
|
||||
return hmac.new(values['x_trans_key'].encode('utf-8'), data.encode('utf-8'), hashlib.md5).hexdigest()
|
||||
|
||||
@api.multi
|
||||
def authorize_form_generate_values(self, values):
|
||||
|
||||
@@ -39,7 +39,7 @@ class AuthorizeForm(AuthorizeCommon):
|
||||
values['x_fp_timestamp'],
|
||||
values['x_amount'],
|
||||
]) + '^'
|
||||
return hmac.new(str(values['x_trans_key']), data, hashlib.md5).hexdigest()
|
||||
return hmac.new(values['x_trans_key'].encode('utf-8'), data.encode('utf-8'), hashlib.md5).hexdigest()
|
||||
|
||||
def test_10_Authorize_form_render(self):
|
||||
self.assertEqual(self.authorize.environment, 'test', 'test without test environment')
|
||||
|
||||
@@ -49,7 +49,7 @@ class PaymentAcquirerPayumoney(models.Model):
|
||||
sign = ''.join('%s|' % (values.get(k) or '') for k in keys)
|
||||
sign = self.payumoney_merchant_salt + sign + self.payumoney_merchant_key
|
||||
|
||||
shasign = hashlib.sha512(sign).hexdigest()
|
||||
shasign = hashlib.sha512(sign.encode('utf-8')).hexdigest()
|
||||
return shasign
|
||||
|
||||
@api.multi
|
||||
|
||||
@@ -66,7 +66,7 @@ class AcquirerSips(models.Model):
|
||||
if self.environment == 'prod':
|
||||
key = getattr(self, 'sips_secret')
|
||||
|
||||
shasign = sha256(data + key)
|
||||
shasign = sha256((data + key).encode('utf-8'))
|
||||
return shasign.hexdigest()
|
||||
|
||||
@api.multi
|
||||
|
||||
@@ -315,7 +315,7 @@ class Image(models.AbstractModel):
|
||||
if max_width or max_height:
|
||||
max_size = '%sx%s' % (max_width, max_height)
|
||||
|
||||
sha = hashlib.sha1(getattr(record, '__last_update')).hexdigest()[0:7]
|
||||
sha = hashlib.sha1(getattr(record, '__last_update').encode('utf-8')).hexdigest()[0:7]
|
||||
max_size = '' if max_size is None else '/%s' % max_size
|
||||
src = '/web/image/%s/%s/%s%s?unique=%s' % (record._name, record.id, field_name, max_size, sha)
|
||||
|
||||
|
||||
@@ -584,7 +584,7 @@ class Website(models.Model):
|
||||
def image_url(self, record, field, size=None):
|
||||
""" Returns a local url that points to the image field of a given browse record. """
|
||||
sudo_record = record.sudo()
|
||||
sha = hashlib.sha1(getattr(sudo_record, '__last_update')).hexdigest()[0:7]
|
||||
sha = hashlib.sha1(getattr(sudo_record, '__last_update').encode('utf-8')).hexdigest()[0:7]
|
||||
size = '' if size is None else '/%s' % size
|
||||
return '/web/image/%s/%s/%s%s?unique=%s' % (record._name, record.id, field, size, sha)
|
||||
|
||||
|
||||
@@ -66,11 +66,12 @@ class Users(models.Model):
|
||||
and is a hash based on a (secret) uuid generated by the forum module,
|
||||
the user_id, the email and currently the day (to be updated if necessary). """
|
||||
forum_uuid = self.env['ir.config_parameter'].sudo().get_param('website_forum.uuid')
|
||||
return hashlib.sha256('%s-%s-%s-%s' % (
|
||||
return hashlib.sha256((u'%s-%s-%s-%s' % (
|
||||
datetime.now().replace(hour=0, minute=0, second=0, microsecond=0),
|
||||
forum_uuid,
|
||||
user_id,
|
||||
email)).hexdigest()
|
||||
email
|
||||
)).encode('utf-8')).hexdigest()
|
||||
|
||||
@api.one
|
||||
def send_forum_validation_email(self, forum_id=None):
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from werkzeug.exceptions import NotFound, Forbidden
|
||||
|
||||
from odoo import http
|
||||
|
||||
@@ -68,4 +68,4 @@ class MailGroup(models.Model):
|
||||
str(self.id),
|
||||
str(partner_id),
|
||||
action])
|
||||
return hmac.new(secret.encode('utf-8'), data).hexdigest()
|
||||
return hmac.new(secret.encode('utf-8'), data.encode('utf-8')).hexdigest()
|
||||
|
||||
@@ -195,7 +195,7 @@ class IrAttachment(models.Model):
|
||||
for attach in self:
|
||||
# compute the fields that depend on datas
|
||||
value = attach.datas
|
||||
bin_data = value and base64.b64decode(value) or ''
|
||||
bin_data = base64.b64decode(value) if value else b''
|
||||
vals = {
|
||||
'file_size': len(bin_data),
|
||||
'checksum': self._compute_checksum(bin_data),
|
||||
@@ -220,7 +220,7 @@ class IrAttachment(models.Model):
|
||||
:param bin_data : datas in its binary form
|
||||
"""
|
||||
# an empty file has a checksum too (for caching)
|
||||
return hashlib.sha1(bin_data or '').hexdigest()
|
||||
return hashlib.sha1(bin_data or b'').hexdigest()
|
||||
|
||||
def _compute_mimetype(self, values):
|
||||
""" compute the mimetype of the given values
|
||||
|
||||
@@ -16,8 +16,8 @@ _logger = logging.getLogger(__name__)
|
||||
A dictionary holding some configuration parameters to be initialized when the database is created.
|
||||
"""
|
||||
_default_parameters = {
|
||||
"database.secret": lambda: str(uuid.uuid4()),
|
||||
"database.uuid": lambda: str(uuid.uuid1()),
|
||||
"database.secret": lambda: pycompat.text_type(uuid.uuid4()),
|
||||
"database.uuid": lambda: pycompat.text_type(uuid.uuid1()),
|
||||
"database.create_date": fields.Datetime.now,
|
||||
"web.base.url": lambda: "http://localhost:%s" % config.get('xmlrpc_port'),
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ class IrHttp(models.AbstractModel):
|
||||
attach = env['ir.attachment'].search_read(domain, fields)
|
||||
if attach:
|
||||
wdate = attach[0]['__last_update']
|
||||
datas = attach[0]['datas'] or ''
|
||||
datas = attach[0]['datas'] or b''
|
||||
name = attach[0]['name']
|
||||
checksum = attach[0]['checksum'] or hashlib.sha1(datas).hexdigest()
|
||||
|
||||
@@ -288,7 +288,7 @@ class IrHttp(models.AbstractModel):
|
||||
if module_resource_path.startswith(module_path):
|
||||
with open(module_resource_path, 'rb') as f:
|
||||
content = base64.b64encode(f.read())
|
||||
last_update = str(os.path.getmtime(module_resource_path))
|
||||
last_update = pycompat.text_type(os.path.getmtime(module_resource_path))
|
||||
|
||||
if not module_resource_path:
|
||||
module_resource_path = obj.url
|
||||
@@ -324,7 +324,7 @@ class IrHttp(models.AbstractModel):
|
||||
|
||||
# cache
|
||||
etag = bool(request) and request.httprequest.headers.get('If-None-Match')
|
||||
retag = '"%s"' % hashlib.md5(last_update).hexdigest()
|
||||
retag = '"%s"' % hashlib.md5(last_update.encode('utf-8')).hexdigest()
|
||||
status = status or (304 if etag == retag else 200)
|
||||
headers.append(('ETag', retag))
|
||||
headers.append(('Cache-Control', 'max-age=%s' % (STATIC_CACHE if unique else 0)))
|
||||
|
||||
@@ -149,7 +149,7 @@ class AssetsBundle(object):
|
||||
Not really a full checksum.
|
||||
We compute a SHA1 on the rendered bundle + max linked files last_modified date
|
||||
"""
|
||||
check = json.dumps(self.files) + ",".join(self.remains) + str(self.last_modified)
|
||||
check = json.dumps(self.files) + b",".join(self.remains) + self.last_modified.encode('utf-8')
|
||||
return hashlib.sha1(check).hexdigest()
|
||||
|
||||
def clean_attachments(self, type):
|
||||
|
||||
@@ -665,7 +665,7 @@ class Partner(models.Model):
|
||||
return partners.id or self.name_create(email)[0]
|
||||
|
||||
def _get_gravatar_image(self, email):
|
||||
email_hash = hashlib.md5(email.lower()).hexdigest()
|
||||
email_hash = hashlib.md5(email.lower().encode('utf-8')).hexdigest()
|
||||
url = "https://www.gravatar.com/avatar/" + email_hash
|
||||
try:
|
||||
res = requests.get(url, params={'d': '404', 's': '128'}, timeout=5)
|
||||
|
||||
@@ -9,6 +9,8 @@ from odoo.tests.common import TransactionCase
|
||||
|
||||
|
||||
class TranslationToolsTestCase(unittest.TestCase):
|
||||
def assertItemsEqual(self, a, b, msg=None):
|
||||
self.assertEqual(sorted(a), sorted(b), msg)
|
||||
|
||||
def test_quote_unquote(self):
|
||||
|
||||
|
||||
+2
-2
@@ -392,7 +392,7 @@ class WebRequest(object):
|
||||
msg = '%s%s' % (token, max_ts)
|
||||
secret = self.env['ir.config_parameter'].sudo().get_param('database.secret')
|
||||
assert secret, "CSRF protection requires a configured database secret"
|
||||
hm = hmac.new(str(secret), msg, hashlib.sha1).hexdigest()
|
||||
hm = hmac.new(secret.encode('ascii'), msg.encode('utf-8'), hashlib.sha1).hexdigest()
|
||||
return '%so%s' % (hm, max_ts)
|
||||
|
||||
def validate_csrf(self, csrf):
|
||||
@@ -416,7 +416,7 @@ class WebRequest(object):
|
||||
msg = '%s%s' % (token, max_ts)
|
||||
secret = self.env['ir.config_parameter'].sudo().get_param('database.secret')
|
||||
assert secret, "CSRF protection requires a configured database secret"
|
||||
hm_expected = hmac.new(str(secret), msg, hashlib.sha1).hexdigest()
|
||||
hm_expected = hmac.new(secret.encode('ascii'), msg.encode('utf-8'), hashlib.sha1).hexdigest()
|
||||
return consteq(hm, hm_expected)
|
||||
|
||||
def route(route=None, **kw):
|
||||
|
||||
@@ -337,7 +337,7 @@ def generate_table_alias(src_table_alias, joined_tables=[]):
|
||||
# We have to fit a crc32 hash and one underscore
|
||||
# into a 63 character alias. The remaining space we can use to add
|
||||
# a human readable prefix.
|
||||
alias_hash = hex(crc32(alias))[2:]
|
||||
alias_hash = hex(crc32(alias.encode('utf-8')))[2:].decode('utf-8')
|
||||
ALIAS_PREFIX_LENGTH = 63 - len(alias_hash) - 1
|
||||
alias = "%s_%s" % (
|
||||
alias[:ALIAS_PREFIX_LENGTH], alias_hash)
|
||||
|
||||
Reference in New Issue
Block a user