Fix an issue where smtplib can't handle unicode strings

We probably do get this value as unicode originally but when we store
it, due to a recently fixed bug it will come out as *not* unicode.

So things were accidentally working because py2 smtplib uses hmac
which won't accept unicode.

This change adds a flag to encrypt_field that forces it to skip the
utf8 fixup from before for narrow use cases.
This commit is contained in:
Matthew Jones 2017-02-15 14:05:58 -05:00
parent 6545869684
commit 785a8d0789
3 changed files with 14 additions and 3 deletions

View File

@ -75,7 +75,7 @@ class NotificationTemplate(CommonModel):
setattr(self, '_saved_{}_{}'.format("config", field), value)
self.notification_configuration[field] = ''
else:
encrypted = encrypt_field(self, 'notification_configuration', subfield=field)
encrypted = encrypt_field(self, 'notification_configuration', subfield=field, skip_utf8=True)
self.notification_configuration[field] = encrypted
if 'notification_configuration' not in update_fields:
update_fields.append('notification_configuration')

View File

@ -29,6 +29,14 @@ def test_encrypt_field_with_unicode_string():
assert common.decrypt_field(field, 'value') == value
def test_encrypt_field_force_disable_unicode():
value = u"NothingSpecial"
field = Setting(value=value)
encrypted = field.value = common.encrypt_field(field, 'value', skip_utf8=True)
assert "UTF8" not in encrypted
assert common.decrypt_field(field, 'value') == value
def test_encrypt_subfield():
field = Setting(value={'name': 'ANSIBLE'})
encrypted = field.value = common.encrypt_field(field, 'value', subfield='name')

View File

@ -183,7 +183,7 @@ def get_encryption_key(field_name, pk=None):
return h.digest()[:16]
def encrypt_field(instance, field_name, ask=False, subfield=None):
def encrypt_field(instance, field_name, ask=False, subfield=None, skip_utf8=False):
'''
Return content of the given instance and field name encrypted.
'''
@ -192,7 +192,10 @@ def encrypt_field(instance, field_name, ask=False, subfield=None):
value = value[subfield]
if not value or value.startswith('$encrypted$') or (ask and value == 'ASK'):
return value
utf8 = type(value) == six.text_type
if skip_utf8:
utf8 = False
else:
utf8 = type(value) == six.text_type
value = smart_str(value)
key = get_encryption_key(field_name, getattr(instance, 'pk', None))
cipher = AES.new(key, AES.MODE_ECB)