From 4828e0d84547cbc944cae4490b5b464c28e4e39c Mon Sep 17 00:00:00 2001 From: Peter Hamilton Date: Thu, 6 Dec 2018 16:01:09 -0500 Subject: [PATCH] Fix AttributeError in client Rekey results with missing payloads This change fixes a bug in the KMIPProxy client's support for the Rekey operation. Specifically, if the operation fails and does not return a payload, the client will still try to reference the payload object when checking for TemplateAttribute data. This causes an AttributeError since the payload is None. This change fixes this and adds a unit test that covers this specific case. Fixes #474 --- kmip/services/kmip_client.py | 5 +- kmip/tests/unit/services/test_kmip_client.py | 48 +++++++++++++++++++- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/kmip/services/kmip_client.py b/kmip/services/kmip_client.py index 88674ac..dd70fde 100644 --- a/kmip/services/kmip_client.py +++ b/kmip/services/kmip_client.py @@ -405,8 +405,9 @@ class KMIPProxy(object): if payload: result['unique_identifier'] = payload.unique_identifier - if payload.template_attribute is not None: - result['template_attribute'] = payload.template_attribute + + if payload.template_attribute is not None: + result['template_attribute'] = payload.template_attribute result['result_status'] = batch_item.result_status.value try: diff --git a/kmip/tests/unit/services/test_kmip_client.py b/kmip/tests/unit/services/test_kmip_client.py index f8f76f8..54f7816 100644 --- a/kmip/tests/unit/services/test_kmip_client.py +++ b/kmip/tests/unit/services/test_kmip_client.py @@ -929,9 +929,55 @@ class TestKMIPClient(TestCase): self.assertEqual(None, result.get('result_reason')) self.assertEqual(None, result.get('result_message')) + @mock.patch('kmip.services.kmip_client.KMIPProxy._build_request_message') @mock.patch( - 'kmip.services.kmip_client.KMIPProxy._build_request_message' + 'kmip.services.kmip_client.KMIPProxy._send_and_receive_message' ) + def test_rekey_with_no_payload(self, send_mock, build_mock): + """ + Test that the client correctly handles responses with no payload data. + """ + batch_item = ResponseBatchItem( + operation=Operation(OperationEnum.REKEY), + result_status=ResultStatus(ResultStatusEnum.OPERATION_FAILED), + result_reason=ResultReason(ResultReasonEnum.PERMISSION_DENIED), + result_message=ResultMessage("Permission denied."), + response_payload=None + ) + response = ResponseMessage(batch_items=[batch_item]) + + build_mock.return_value = None + send_mock.return_value = response + + result = self.client.rekey( + uuid='1', + offset=0, + template_attribute=objects.TemplateAttribute( + attributes=[ + objects.Attribute( + attribute_name=objects.Attribute.AttributeName( + 'Activation Date' + ), + attribute_value=primitives.DateTime( + value=1136113200, + tag=enums.Tags.ACTIVATION_DATE + ) + ) + ] + ) + ) + + self.assertEqual( + ResultStatusEnum.OPERATION_FAILED, + result.get('result_status') + ) + self.assertEqual( + ResultReasonEnum.PERMISSION_DENIED, + result.get('result_reason') + ) + self.assertEqual("Permission denied.", result.get('result_message')) + + @mock.patch('kmip.services.kmip_client.KMIPProxy._build_request_message') @mock.patch( 'kmip.services.kmip_client.KMIPProxy._send_and_receive_message' )