Return payload as text only for text/plain secrets
currently SDK always returns Response.text for secret payload, which is problematic for pure binary secrets, as the value returned is decoded as whatever encoding `chardet` lib has detected on this random binary data. This makes SDK basically unusable for retreving and using binary secrets, as one can not make any educated guess using only sdk-provided data on what encoding to use to get the payload as raw bytes. Instead, do what barbicanclient does, and return raw bytes (Response.content) for everything but content type "text/plain", for which decode those bytes to UTF-8. This will also make it easier to transition from barbicanclient to openstacksdk if needed. Change-Id: I0e5ac1288c0d0423fa3a7a4e63173675b78aae79
This commit is contained in:
parent
93f44c3b62
commit
2692290776
@ -112,7 +112,10 @@ class Secret(resource.Resource):
|
||||
headers={"Accept": content_type},
|
||||
skip_cache=skip_cache,
|
||||
)
|
||||
response["payload"] = payload.text
|
||||
if content_type == "text/plain":
|
||||
response["payload"] = payload.content.decode("UTF-8")
|
||||
else:
|
||||
response["payload"] = payload.content
|
||||
|
||||
# We already have the JSON here so don't call into _translate_response
|
||||
self._update_from_body_attrs(response)
|
||||
|
@ -100,16 +100,14 @@ class TestSecret(base.TestCase):
|
||||
|
||||
sess.get.assert_called_once_with("secrets/id")
|
||||
|
||||
def _test_payload(self, sot, metadata, content_type):
|
||||
content_type = "some/type"
|
||||
|
||||
def _test_payload(self, sot, metadata, content_type="some/type"):
|
||||
metadata_response = mock.Mock()
|
||||
# Use copy because the dict gets consumed.
|
||||
metadata_response.json = mock.Mock(return_value=metadata.copy())
|
||||
|
||||
payload_response = mock.Mock()
|
||||
payload = "secret info"
|
||||
payload_response.text = payload
|
||||
payload = b"secret info"
|
||||
payload_response.content = payload
|
||||
|
||||
sess = mock.Mock()
|
||||
sess.get = mock.Mock(side_effect=[metadata_response, payload_response])
|
||||
@ -129,7 +127,11 @@ class TestSecret(base.TestCase):
|
||||
]
|
||||
)
|
||||
|
||||
self.assertEqual(rv.payload, payload)
|
||||
if content_type == "text/plain":
|
||||
expected_payload = payload.decode("utf-8")
|
||||
else:
|
||||
expected_payload = payload
|
||||
self.assertEqual(rv.payload, expected_payload)
|
||||
self.assertEqual(rv.status, metadata["status"])
|
||||
|
||||
def test_get_with_payload_from_argument(self):
|
||||
@ -146,3 +148,12 @@ class TestSecret(base.TestCase):
|
||||
}
|
||||
sot = secret.Secret(id="id")
|
||||
self._test_payload(sot, metadata, content_type)
|
||||
|
||||
def test_get_with_text_payload(self):
|
||||
content_type = "text/plain"
|
||||
metadata = {
|
||||
"status": "fine",
|
||||
"content_types": {"default": content_type},
|
||||
}
|
||||
sot = secret.Secret(id="id")
|
||||
self._test_payload(sot, metadata, content_type)
|
||||
|
@ -0,0 +1,16 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
For Barbican secrets with detected or provided content type other than
|
||||
"text/plain" SDK now returns the secret payload as raw bytes.
|
||||
For secrets with content type "text/plain", the payload is returned
|
||||
as string, decoded to UTF-8.
|
||||
This behavior is following python-barbicanclient, and allows to use
|
||||
SDK with Barbican secrets that have binary payloads
|
||||
(e.g. "application/octet-stream").
|
||||
upgrade:
|
||||
- |
|
||||
The payload of Barbican secrets with other than "text/plain" content type
|
||||
is now returned as raw bytes.
|
||||
For secrets with content type "text/plain", the payload is returned
|
||||
as string, decoded to UTF-8.
|
Loading…
x
Reference in New Issue
Block a user