Raise ValueError if empty value coming into encrypt_header_val
encrypt_header_val is used to translate a raw header value into an encrypted value. Semantically, a header with an empty value won't be stored and all callers seem to remove such a header before calling encrypted_header_val. So if no reason for returning ('', None), I think it's better to change it to raise ValueError not to cause another error for users of the return value. (e.g. dump_crypto_meta) Plus this patch addes a few unit tests for those cases above. Change-Id: Ic1237f4afb8c0e466be5ce59fe31b667c39242b0
This commit is contained in:
@@ -39,9 +39,10 @@ def encrypt_header_val(crypto, value, key):
|
|||||||
:returns: a tuple of (encrypted value, crypto_meta) where crypto_meta is a
|
:returns: a tuple of (encrypted value, crypto_meta) where crypto_meta is a
|
||||||
dict of form returned by
|
dict of form returned by
|
||||||
:py:func:`~swift.common.middleware.crypto.Crypto.get_crypto_meta`
|
:py:func:`~swift.common.middleware.crypto.Crypto.get_crypto_meta`
|
||||||
|
:raises ValueError: if value is empty
|
||||||
"""
|
"""
|
||||||
if not value:
|
if not value:
|
||||||
return '', None
|
raise ValueError('empty value is not acceptable')
|
||||||
|
|
||||||
crypto_meta = crypto.create_crypto_meta()
|
crypto_meta = crypto.create_crypto_meta()
|
||||||
crypto_ctxt = crypto.create_encryption_ctxt(key, crypto_meta['iv'])
|
crypto_ctxt = crypto.create_encryption_ctxt(key, crypto_meta['iv'])
|
||||||
|
@@ -536,6 +536,7 @@ class TestEncrypter(unittest.TestCase):
|
|||||||
env = {'REQUEST_METHOD': 'POST',
|
env = {'REQUEST_METHOD': 'POST',
|
||||||
CRYPTO_KEY_CALLBACK: fetch_crypto_keys}
|
CRYPTO_KEY_CALLBACK: fetch_crypto_keys}
|
||||||
hdrs = {'x-object-meta-test': 'encrypt me',
|
hdrs = {'x-object-meta-test': 'encrypt me',
|
||||||
|
'x-object-meta-test2': '',
|
||||||
'x-object-sysmeta-test': 'do not encrypt me'}
|
'x-object-sysmeta-test': 'do not encrypt me'}
|
||||||
req = Request.blank('/v1/a/c/o', environ=env, body=body, headers=hdrs)
|
req = Request.blank('/v1/a/c/o', environ=env, body=body, headers=hdrs)
|
||||||
key = fetch_crypto_keys()['object']
|
key = fetch_crypto_keys()['object']
|
||||||
@@ -551,6 +552,8 @@ class TestEncrypter(unittest.TestCase):
|
|||||||
|
|
||||||
# user meta is encrypted
|
# user meta is encrypted
|
||||||
self._verify_user_metadata(req_hdrs, 'Test', 'encrypt me', key)
|
self._verify_user_metadata(req_hdrs, 'Test', 'encrypt me', key)
|
||||||
|
# unless it had no value
|
||||||
|
self.assertEqual('', req_hdrs['X-Object-Meta-Test2'])
|
||||||
|
|
||||||
# sysmeta is not encrypted
|
# sysmeta is not encrypted
|
||||||
self.assertEqual('do not encrypt me',
|
self.assertEqual('do not encrypt me',
|
||||||
@@ -878,6 +881,36 @@ class TestEncrypter(unittest.TestCase):
|
|||||||
req.get_response(app)
|
req.get_response(app)
|
||||||
self.assertEqual(FakeAppThatExcepts.MESSAGE, catcher.exception.body)
|
self.assertEqual(FakeAppThatExcepts.MESSAGE, catcher.exception.body)
|
||||||
|
|
||||||
|
def test_encrypt_header_val(self):
|
||||||
|
# Prepare key and Crypto instance
|
||||||
|
object_key = fetch_crypto_keys()['object']
|
||||||
|
|
||||||
|
# - Normal string can be crypted
|
||||||
|
encrypted = encrypter.encrypt_header_val(Crypto(), 'aaa', object_key)
|
||||||
|
# sanity: return value is 2 item tuple
|
||||||
|
self.assertEqual(2, len(encrypted))
|
||||||
|
crypted_val, crypt_info = encrypted
|
||||||
|
expected_crypt_val = base64.b64encode(
|
||||||
|
encrypt('aaa', object_key, FAKE_IV))
|
||||||
|
expected_crypt_info = {
|
||||||
|
'cipher': 'AES_CTR_256', 'iv': 'This is an IV123'}
|
||||||
|
self.assertEqual(expected_crypt_val, crypted_val)
|
||||||
|
self.assertEqual(expected_crypt_info, crypt_info)
|
||||||
|
|
||||||
|
# - Empty string raises a ValueError for safety
|
||||||
|
with self.assertRaises(ValueError) as cm:
|
||||||
|
encrypter.encrypt_header_val(Crypto(), '', object_key)
|
||||||
|
|
||||||
|
self.assertEqual('empty value is not acceptable',
|
||||||
|
cm.exception.message)
|
||||||
|
|
||||||
|
# - None also raises a ValueError for safety
|
||||||
|
with self.assertRaises(ValueError) as cm:
|
||||||
|
encrypter.encrypt_header_val(Crypto(), None, object_key)
|
||||||
|
|
||||||
|
self.assertEqual('empty value is not acceptable',
|
||||||
|
cm.exception.message)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
Reference in New Issue
Block a user