Updated to address comments from first attempt

This commit is contained in:
Wyllys Ingersoll 2014-09-09 00:14:02 -04:00
parent b04f5c2dc3
commit a2b71a1f1c
10 changed files with 258 additions and 32 deletions

View File

@ -25,6 +25,7 @@ from kmip.core.primitives import Enumeration
from kmip.core.primitives import TextString from kmip.core.primitives import TextString
from kmip.core.utils import BytearrayStream from kmip.core.utils import BytearrayStream
from enum import Enum
# 3.1 # 3.1
@ -54,6 +55,7 @@ class Name(Struct):
super(self.__class__, self).__init__(tag=Tags.NAME) super(self.__class__, self).__init__(tag=Tags.NAME)
self.name_value = name_value self.name_value = name_value
self.name_type = name_type self.name_type = name_type
self.validate()
def read(self, istream): def read(self, istream):
super(self.__class__, self).read(istream) super(self.__class__, self).read(istream)
@ -88,8 +90,16 @@ class Name(Struct):
@classmethod @classmethod
def create(cls, name_value, name_type): def create(cls, name_value, name_type):
if isinstance(name_value, Name.NameValue):
value = name_value
elif isinstance(name_value, str):
value = cls.NameValue(name_value) value = cls.NameValue(name_value)
if isinstance(name_type, Name.NameType):
n_type = name_type
elif isinstance(name_type, Enum):
n_type = cls.NameType(name_type) n_type = cls.NameType(name_type)
return Name(name_value=value, return Name(name_value=value,
name_type=n_type) name_type=n_type)

View File

@ -24,6 +24,7 @@ from kmip.core.attributes import CustomAttribute
from kmip.core.attributes import Name from kmip.core.attributes import Name
from kmip.core.attributes import ObjectGroup from kmip.core.attributes import ObjectGroup
from kmip.core.attributes import UniqueIdentifier from kmip.core.attributes import UniqueIdentifier
from kmip.core.attributes import ObjectType
from kmip.core import utils from kmip.core import utils
@ -125,15 +126,15 @@ class AttributeValueFactory(object):
def _create_name(self, name): def _create_name(self, name):
if name is not None: if name is not None:
name_value = name.get('name_value') name_value = name.name_value
name_type = name.get('name_type') name_type = name.name_type
return Name.create(name_value, name_type) return Name.create(name_value, name_type)
else: else:
return Name() return Name()
def _create_object_type(self, obj): def _create_object_type(self, obj):
raise NotImplementedError() return ObjectType()
def _create_cryptographic_algorithm(self, alg): def _create_cryptographic_algorithm(self, alg):
return CryptographicAlgorithm(alg) return CryptographicAlgorithm(alg)

View File

@ -21,6 +21,7 @@ from kmip.core.enums import Tags
from kmip.core.objects import KeyWrappingSpecification from kmip.core.objects import KeyWrappingSpecification
from kmip.core.objects import TemplateAttribute from kmip.core.objects import TemplateAttribute
from kmip.core.objects import Attribute
from kmip.core.primitives import Struct from kmip.core.primitives import Struct
from kmip.core.primitives import Enumeration from kmip.core.primitives import Enumeration
@ -474,8 +475,8 @@ class LocateRequestPayload(Struct):
if self.is_tag_next(Tags.OBJECT_GROUP_MEMBER, tstream): if self.is_tag_next(Tags.OBJECT_GROUP_MEMBER, tstream):
self.object_group_member = LocateRequestPayload.ObjectGroupMember() self.object_group_member = LocateRequestPayload.ObjectGroupMember()
self.object_group_member.read(tstream) self.object_group_member.read(tstream)
while self.is_tag_next(Tags.TEMPLATE_ATTRIBUTE, tstream): while self.is_tag_next(Tags.ATTRIBUTE, tstream):
attr = TemplateAttribute() attr = Attribute()
attr.read(tstream) attr.read(tstream)
self.attributes.append(attr) self.attributes.append(attr)
@ -526,7 +527,7 @@ class LocateResponsePayload(Struct):
def write(self, ostream): def write(self, ostream):
tstream = BytearrayStream() tstream = BytearrayStream()
for ui in self.unique_identifier: for ui in self.unique_identifiers:
ui.write(tstream) ui.write(tstream)
# Write the length and value of the request payload # Write the length and value of the request payload

View File

@ -262,8 +262,7 @@ class KMIPImpl(KMIP):
self.logger.debug(msg) self.logger.debug(msg)
uuids = self.repo.locate(maximum_items, storage_status_mask, uuids = self.repo.locate(maximum_items, storage_status_mask,
object_group_member, attributes) object_group_member, attributes)
return LocateResult(ResultStatus(RS.SUCCESS), return LocateResult(ResultStatus(RS.SUCCESS), uuids=uuids)
locate_uuids=uuids)
def _validate_req_field(self, attrs, name, expected, msg, required=True): def _validate_req_field(self, attrs, name, expected, msg, required=True):
self.logger.debug('Validating attribute %s' % name) self.logger.debug('Validating attribute %s' % name)

View File

@ -16,6 +16,7 @@
from kmip.core.enums import AttributeType from kmip.core.enums import AttributeType
from kmip.core.enums import CredentialType from kmip.core.enums import CredentialType
from kmip.core.enums import ObjectType from kmip.core.enums import ObjectType
from kmip.core.enums import ResultStatus
from kmip.core.enums import CryptographicAlgorithm from kmip.core.enums import CryptographicAlgorithm
from kmip.core.enums import CryptographicUsageMask from kmip.core.enums import CryptographicUsageMask
from kmip.core.enums import NameType from kmip.core.enums import NameType
@ -73,6 +74,10 @@ if __name__ == '__main__':
result = client.locate(attributes=attrs, credential=credential) result = client.locate(attributes=attrs, credential=credential)
client.close() client.close()
logger.debug('get() result status: {}'.format(result.result_status.enum)) logger.debug('locate() result status: {}'.
logger.debug('retrieved object type: {}'.format(result.object_type.enum)) format(result.result_status.enum))
logger.debug('Located UUID: {}'.format(result.locate_uuids)) if result.result_status.enum == ResultStatus.SUCCESS:
logger.debug('retrieved object type: {}'.
format(result.object_type.enum))
logger.debug('Located UUIDs: {}'.format(','.join([u.value for u in
result.uuids])))

View File

@ -308,14 +308,14 @@ class KMIPProxy(KMIP):
payload = batch_item.response_payload payload = batch_item.response_payload
if payload is None: if payload is None:
locate_uuids = None uuids = None
else: else:
locate_uuids = payload.unique_identifiers uuids = payload.unique_identifiers
result = LocateResult(batch_item.result_status, result = LocateResult(batch_item.result_status,
batch_item.result_reason, batch_item.result_reason,
batch_item.result_message, batch_item.result_message,
locate_uuids) uuids)
return result return result
def _build_request_message(self, credential, batch_items): def _build_request_message(self, credential, batch_items):

View File

@ -269,7 +269,7 @@ class Processor(object):
result_reason = result.result_reason result_reason = result.result_reason
result_message = result.result_message result_message = result.result_message
uuids = result.locate_uuids uuids = result.uuids
resp_pl = LocateResponsePayload(unique_identifiers=uuids) resp_pl = LocateResponsePayload(unique_identifiers=uuids)

View File

@ -133,8 +133,8 @@ class LocateResult(OperationResult):
result_status, result_status,
result_reason=None, result_reason=None,
result_message=None, result_message=None,
locate_uuids=None): uuids=None):
super(self.__class__, self).__init__(result_status, super(self.__class__, self).__init__(result_status,
result_reason, result_reason,
result_message) result_message)
self.locate_uuids = locate_uuids self.uuids = uuids

View File

@ -47,6 +47,7 @@ from kmip.core.messages.operations import DestroyRequestPayload
from kmip.core.messages.operations import RegisterRequestPayload from kmip.core.messages.operations import RegisterRequestPayload
from kmip.core.messages.operations import DestroyResponsePayload from kmip.core.messages.operations import DestroyResponsePayload
from kmip.core.messages.operations import RegisterResponsePayload from kmip.core.messages.operations import RegisterResponsePayload
from kmip.core.messages.operations import LocateResponsePayload
from kmip.core.primitives import TextString from kmip.core.primitives import TextString
@ -135,8 +136,23 @@ class TestRequestMessage(TestCase):
b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x14\x00\x00\x00\x00' b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x14\x00\x00\x00\x00'
b'\x42\x00\x79\x01\x00\x00\x00\x30\x42\x00\x94\x07\x00\x00\x00\x24' b'\x42\x00\x79\x01\x00\x00\x00\x30\x42\x00\x94\x07\x00\x00\x00\x24'
b'\x66\x62\x34\x62\x35\x62\x39\x63\x2D\x36\x31\x38\x38\x2D\x34\x63' b'\x66\x62\x34\x62\x35\x62\x39\x63\x2D\x36\x31\x38\x38\x2D\x34\x63'
b'\x36\x33\x2D\x38\x31\x34\x32\x2D\x66\x65\x39\x63\x33\x32\x38\x31' )
b'\x32\x39\x66\x63\x00\x00\x00\x00') # kmip-testcases-v1.1 section 3.1.3
self.locate = (
b'\x42\x00\x78\x01\x00\x00\x00\xd0\x42\x00\x77\x01\x00\x00\x00\x38'
b'\x42\x00\x69\x01\x00\x00\x00\x20\x42\x00\x6a\x02\x00\x00\x00\x04'
b'\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x6b\x02\x00\x00\x00\x04'
b'\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x0d\x02\x00\x00\x00\x04'
b'\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x0f\x01\x00\x00\x00\x88'
b'\x42\x00\x5c\x05\x00\x00\x00\x04\x00\x00\x00\x08\x00\x00\x00\x00'
b'\x42\x00\x79\x01\x00\x00\x00\x70\x42\x00\x08\x01\x00\x00\x00\x28'
b'\x42\x00\x0a\x07\x00\x00\x00\x0b\x4f\x62\x6a\x65\x63\x74\x20\x54'
b'\x79\x70\x65\x00\x00\x00\x00\x00\x42\x00\x0b\x05\x00\x00\x00\x04'
b'\x00\x00\x00\x02\x00\x00\x00\x00\x42\x00\x08\x01\x00\x00\x00\x38'
b'\x42\x00\x0a\x07\x00\x00\x00\x04\x4e\x61\x6d\x65\x00\x00\x00\x00'
b'\x42\x00\x0b\x01\x00\x00\x00\x20\x42\x00\x55\x07\x00\x00\x00\x04'
b'\x4b\x65\x79\x31\x00\x00\x00\x00\x42\x00\x54\x05\x00\x00\x00\x04'
b'\x00\x00\x00\x01\x00\x00\x00\x00')
def tearDown(self): def tearDown(self):
super(TestRequestMessage, self).tearDown() super(TestRequestMessage, self).tearDown()
@ -802,6 +818,149 @@ class TestRequestMessage(TestCase):
msg = "Bad request message write: encoding mismatch" msg = "Bad request message write: encoding mismatch"
self.assertEqual(self.register, result, msg) self.assertEqual(self.register, result, msg)
def test_locate_request_read(self):
self.stream = BytearrayStream(self.locate)
request_message = messages.RequestMessage()
request_message.read(self.stream)
request_header = request_message.request_header
msg = "Bad request header type: expected {0}, received{0}"
self.assertIsInstance(request_header, messages.RequestHeader,
msg.format(messages.RequestHeader,
type(request_header)))
protocol_version = request_header.protocol_version
msg = "Bad protocol version type: expected {0}, received {1}"
self.assertIsInstance(protocol_version, contents.ProtocolVersion,
msg.format(contents.ProtocolVersion,
type(protocol_version)))
protocol_version_major = protocol_version.protocol_version_major
msg = "Bad protocol version major type: expected {0}, received {1}"
exp_type = contents.ProtocolVersion.ProtocolVersionMajor
rcv_type = type(protocol_version_major)
self.assertIsInstance(protocol_version_major, exp_type,
msg.format(exp_type, rcv_type))
msg = "Bad protocol version major value: expected {0}, received {1}"
self.assertEqual(1, protocol_version_major.value,
msg.format(1, protocol_version_major.value))
protocol_version_minor = protocol_version.protocol_version_minor
msg = "Bad protocol version minor type: expected {0}, received {1}"
exp_type = contents.ProtocolVersion.ProtocolVersionMinor
rcv_type = type(protocol_version_minor)
self.assertIsInstance(protocol_version_minor, exp_type,
msg.format(exp_type, rcv_type))
msg = "Bad protocol version minor value: expected {0}, received {1}"
self.assertEqual(1, protocol_version_minor.value,
msg.format(1, protocol_version_minor.value))
batch_count = request_header.batch_count
msg = "Bad batch count type: expected {0}, received {1}"
self.assertIsInstance(batch_count, contents.BatchCount,
msg.format(contents.BatchCount,
type(batch_count)))
msg = "Bad batch count value: expected {0}, received {1}"
self.assertEqual(1, batch_count.value,
msg.format(1, batch_count.value))
batch_items = request_message.batch_items
msg = "Bad batch items type: expected {0}, received {1}"
self.assertEquals(1, len(batch_items),
self.msg.format('batch items', 'length',
1, len(batch_items)))
batch_item = batch_items[0]
msg = "Bad batch item type: expected {0}, received {1}"
self.assertIsInstance(batch_item, messages.RequestBatchItem,
msg.format(messages.RequestBatchItem,
type(batch_item)))
operation = batch_item.operation
msg = "Bad operation type: expected {0}, received {1}"
self.assertIsInstance(operation, contents.Operation,
msg.format(contents.Operation,
type(operation)))
msg = "Bad operation value: expected {0}, received {1}"
exp_value = enums.Operation.LOCATE
rcv_value = operation.enum
self.assertEqual(exp_value, rcv_value,
msg.format(exp_value, rcv_value))
request_payload = batch_item.request_payload
msg = "Bad request payload type: expected {0}, received {1}"
exp_type = operations.LocateRequestPayload
rcv_type = type(request_payload)
self.assertIsInstance(request_payload, exp_type,
msg.format(exp_type, rcv_type))
attributes = request_payload.attributes
msg = "Bad attributes type: expected {0}, received {1}"
exp_type = list
rcv_type = type(attributes)
self.assertIsInstance(attributes, exp_type,
msg.format(exp_type, rcv_type))
self.assertEqual(2, len(attributes),
self.msg.format('attribute', 'length',
2, len(attributes)))
attribute_a = attributes[0]
self.assertIsInstance(attribute_a, objects.Attribute,
self.msg.format('attribute', 'type',
objects.Attribute,
type(attribute_a)))
attribute_name = attribute_a.attribute_name
self.assertIsInstance(attribute_name, objects.Attribute.AttributeName,
self.msg.format('attribute name', 'type',
objects.Attribute.AttributeName,
type(attribute_name)))
self.assertEquals('Object Type', attribute_name.value,
self.msg.format('attribute name', 'value',
'Object Type',
attribute_name.value))
attribute_value = attribute_a.attribute_value
exp_type = attr.Enumeration
rcv_type = type(attribute_value)
self.assertIsInstance(attribute_value, exp_type,
self.msg.format('attribute value', 'type',
exp_type, rcv_type))
self.assertEquals(attribute_value.enum, enums.ObjectType.SYMMETRIC_KEY,
self.msg.format('ObjectType', 'value',
enums.ObjectType.SYMMETRIC_KEY,
attribute_value.enum))
attribute_b = attributes[1]
self.assertIsInstance(attribute_b, objects.Attribute,
self.msg.format('attribute', 'type',
objects.Attribute,
type(attribute_a)))
attribute_name = attribute_b.attribute_name
self.assertIsInstance(attribute_name, objects.Attribute.AttributeName,
self.msg.format('attribute name', 'type',
objects.Attribute.AttributeName,
type(attribute_name)))
self.assertEquals('Name', attribute_name.value,
self.msg.format('attribute name', 'value',
'Name',
attribute_name.value))
attribute_value = attribute_b.attribute_value
exp_type = Name
rcv_type = type(attribute_value)
self.assertIsInstance(attribute_value, exp_type,
self.msg.format('attribute value', 'type',
exp_type, rcv_type))
self.assertEquals('Key1', attribute_value.name_value.value,
self.msg.format('name value', 'value',
'Key1',
attribute_value.name_value.value))
class TestResponseMessage(TestCase): class TestResponseMessage(TestCase):
@ -872,6 +1031,20 @@ class TestResponseMessage(TestCase):
b'\x66\x62\x34\x62\x35\x62\x39\x63\x2D\x36\x31\x38\x38\x2D\x34\x63' b'\x66\x62\x34\x62\x35\x62\x39\x63\x2D\x36\x31\x38\x38\x2D\x34\x63'
b'\x36\x33\x2D\x38\x31\x34\x32\x2D\x66\x65\x39\x63\x33\x32\x38\x31' b'\x36\x33\x2D\x38\x31\x34\x32\x2D\x66\x65\x39\x63\x33\x32\x38\x31'
b'\x32\x39\x66\x63\x00\x00\x00\x00') b'\x32\x39\x66\x63\x00\x00\x00\x00')
# kmip-testcases-v1.1 section 3.1.3
self.locate = (
b'\x42\x00\x7b\x01\x00\x00\x00\xb0\x42\x00\x7a\x01\x00\x00\x00\x48'
b'\x42\x00\x69\x01\x00\x00\x00\x20\x42\x00\x6a\x02\x00\x00\x00\x04'
b'\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x6b\x02\x00\x00\x00\x04'
b'\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x92\x09\x00\x00\x00\x08'
b'\x00\x00\x00\x00\x4f\x9a\x54\xe6\x42\x00\x0d\x02\x00\x00\x00\x04'
b'\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x0f\x01\x00\x00\x00\x58'
b'\x42\x00\x5c\x05\x00\x00\x00\x04\x00\x00\x00\x08\x00\x00\x00\x00'
b'\x42\x00\x7f\x05\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00'
b'\x42\x00\x7c\x01\x00\x00\x00\x30\x42\x00\x94\x07\x00\x00\x00\x24'
b'\x34\x39\x61\x31\x63\x61\x38\x38\x2d\x36\x62\x65\x61\x2d\x34\x66'
b'\x62\x32\x2d\x62\x34\x35\x30\x2d\x37\x65\x35\x38\x38\x30\x32\x63'
b'\x33\x30\x33\x38\x00\x00\x00\x00')
def tearDown(self): def tearDown(self):
super(TestResponseMessage, self).tearDown() super(TestResponseMessage, self).tearDown()
@ -1537,3 +1710,38 @@ class TestResponseMessage(TestCase):
msg = "Bad response message write: encoding mismatch" msg = "Bad response message write: encoding mismatch"
self.assertEqual(self.register, result, msg) self.assertEqual(self.register, result, msg)
def test_locate_response_write(self):
prot_ver = contents.ProtocolVersion.create(1, 1)
# Fri Apr 27 10:12:22 CEST 2012
time_stamp = contents.TimeStamp(0x4f9a54e6)
batch_count = contents.BatchCount(1)
resp_hdr = messages.ResponseHeader(protocol_version=prot_ver,
time_stamp=time_stamp,
batch_count=batch_count)
operation = contents.Operation(enums.Operation.LOCATE)
result_status = contents.ResultStatus(enums.ResultStatus.SUCCESS)
uuid = attr.UniqueIdentifier('49a1ca88-6bea-4fb2-b450-7e58802c3038')
resp_pl = LocateResponsePayload(unique_identifiers=[uuid])
batch_item = messages.ResponseBatchItem(operation=operation,
result_status=result_status,
response_payload=resp_pl)
response_message = messages.ResponseMessage(response_header=resp_hdr,
batch_items=[batch_item])
response_message.write(self.stream)
result = self.stream.read()
len_exp = len(self.locate)
len_rcv = len(result)
self.assertEqual(len_exp, len_rcv,
self.msg.format('response message', 'write',
len_exp, len_rcv))
msg = "Bad response message write: encoding mismatch"
self.assertEqual(self.locate, result, msg)

View File

@ -37,7 +37,6 @@ from kmip.core.messages.contents import KeyFormatType
from kmip.core.objects import KeyBlock from kmip.core.objects import KeyBlock
from kmip.core.objects import KeyValueStruct from kmip.core.objects import KeyValueStruct
from kmip.core.objects import TemplateAttribute from kmip.core.objects import TemplateAttribute
from kmip.core.objects import Attribute
from kmip.core.secrets import SymmetricKey from kmip.core.secrets import SymmetricKey
from kmip.core.server import KMIPImpl from kmip.core.server import KMIPImpl
@ -477,14 +476,6 @@ class TestKMIPServer(TestCase):
crypto_length, usage) crypto_length, usage)
return SymmetricKey(key_block) return SymmetricKey(key_block)
def _make_nameattr(self):
name = Attribute.AttributeName('Name')
name_value = Name.NameValue('TESTNAME')
name_type = Name.NameType(NameType.UNINTERPRETED_TEXT_STRING)
value = Name(name_value=name_value, name_type=name_type)
nameattr = Attribute(attribute_name=name, attribute_value=value)
return nameattr
def _get_attrs(self): def _get_attrs(self):
attr_factory = AttributeFactory() attr_factory = AttributeFactory()
algorithm = self._get_alg_attr(self.algorithm_name) algorithm = self._get_alg_attr(self.algorithm_name)
@ -494,7 +485,10 @@ class TestKMIPServer(TestCase):
CryptoUsageMaskEnum.DECRYPT] CryptoUsageMaskEnum.DECRYPT]
usage_mask = attr_factory.create_attribute(attribute_type, usage_mask = attr_factory.create_attribute(attribute_type,
mask_flags) mask_flags)
nameattr = self._make_nameattr() name_value = Name.NameValue(value='TESTNAME')
name_type = Name.NameType(value=NameType.UNINTERPRETED_TEXT_STRING)
value = Name.create(name_value, name_type)
nameattr = attr_factory.create_attribute(AttributeType.NAME, value)
return [algorithm, usage_mask, length, nameattr] return [algorithm, usage_mask, length, nameattr]
def _get_alg_attr(self, alg=None): def _get_alg_attr(self, alg=None):
@ -521,7 +515,15 @@ class TestKMIPServer(TestCase):
def test_locate(self): def test_locate(self):
self._create() self._create()
attrs = [self._make_nameattr()]
name_value = Name.NameValue(value='TESTNAME')
name_type = Name.NameType(value=NameType.UNINTERPRETED_TEXT_STRING)
value = Name.create(name_value, name_type)
attr_factory = AttributeFactory()
nameattr = attr_factory.create_attribute(AttributeType.NAME, value)
attrs = [nameattr]
res = self.kmip.locate(attributes=attrs) res = self.kmip.locate(attributes=attrs)
self.assertEqual(ResultStatus.SUCCESS, res.result_status.enum, self.assertEqual(ResultStatus.SUCCESS, res.result_status.enum,
'locate result status did not return success') 'locate result status did not return success')