Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 43 additions & 23 deletions kmip/demos/pie/locate.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,44 +13,64 @@
# License for the specific language governing permissions and limitations
# under the License.

from kmip.core.enums import NameType
from kmip.core.enums import Operation

from kmip.core.attributes import Name

from kmip.core.objects import Attribute
import calendar
import logging
import sys
import time

from kmip.core import enums
from kmip.core.factories.attributes import AttributeFactory
from kmip.demos import utils

from kmip.pie import client

import logging
import sys


if __name__ == '__main__':
logger = utils.build_console_logger(logging.INFO)

# Build and parse arguments
parser = utils.build_cli_parser(Operation.LOCATE)
parser = utils.build_cli_parser(enums.Operation.LOCATE)
opts, args = parser.parse_args(sys.argv[1:])

config = opts.config
name = opts.name
initial_dates = opts.initial_dates

attribute_factory = AttributeFactory()

# Exit early if name is not specified
if name is None:
logger.error('No name provided, exiting early from demo')
sys.exit()
# Build attributes if any are specified
attributes = []
if name:
attributes.append(
attribute_factory.create_attribute(enums.AttributeType.NAME, name)
)
for initial_date in initial_dates:
try:
t = time.strptime(initial_date)
except ValueError, TypeError:
logger.error(
"Invalid initial date provided: {}".format(initial_date)
)
logger.info(
"Date values should be formatted like this: "
"'Tue Jul 23 18:39:01 2019'"
)
sys.exit(-1)

try:
t = calendar.timegm(t)
except Exception:
logger.error(
"Failed to convert initial date time tuple "
"to an integer: {}".format(t)
)
sys.exit(-2)

# Build name attribute
# TODO Push this into the AttributeFactory
attribute_name = Attribute.AttributeName('Name')
name_value = Name.NameValue(name)
name_type = Name.NameType(NameType.UNINTERPRETED_TEXT_STRING)
value = Name.create(name_value=name_value, name_type=name_type)
name_obj = Attribute(attribute_name=attribute_name, attribute_value=value)
attributes = [name_obj]
attributes.append(
attribute_factory.create_attribute(
enums.AttributeType.INITIAL_DATE,
t
)
)

# Build the client and connect to the server
with client.ProxyKmipClient(
Expand Down
95 changes: 56 additions & 39 deletions kmip/demos/units/locate.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,42 +13,30 @@
# License for the specific language governing permissions and limitations
# under the License.

from kmip.core.enums import CredentialType
from kmip.core.enums import NameType
from kmip.core.enums import Operation
from kmip.core.enums import ResultStatus

from kmip.core.attributes import Name
import calendar
import logging
import sys
import time

from kmip.core import enums
from kmip.core.factories.attributes import AttributeFactory
from kmip.core.factories.credentials import CredentialFactory

from kmip.core.objects import Attribute

from kmip.demos import utils

from kmip.services.kmip_client import KMIPProxy

import logging
import sys
from kmip.services import kmip_client


if __name__ == '__main__':
logger = utils.build_console_logger(logging.INFO)

# Build and parse arguments
parser = utils.build_cli_parser(Operation.LOCATE)
parser = utils.build_cli_parser(enums.Operation.LOCATE)
opts, args = parser.parse_args(sys.argv[1:])

username = opts.username
password = opts.password
config = opts.config
name = opts.name

# Exit early if the UUID is not specified
if name is None:
logger.error('No name provided, exiting early from demo')
sys.exit()
initial_dates = opts.initial_dates

attribute_factory = AttributeFactory()
credential_factory = CredentialFactory()
Expand All @@ -58,34 +46,63 @@
if (username is None) and (password is None):
credential = None
else:
credential_type = CredentialType.USERNAME_AND_PASSWORD
credential_value = {'Username': username,
'Password': password}
credential = credential_factory.create_credential(credential_type,
credential_value)
credential_type = enums.CredentialType.USERNAME_AND_PASSWORD
credential_value = {
"Username": username,
"Password": password
}
credential = credential_factory.create_credential(
credential_type,
credential_value
)

# Build the client and connect to the server
client = KMIPProxy(config=config, config_file=opts.config_file)
client = kmip_client.KMIPProxy(config=config, config_file=opts.config_file)
client.open()

# Build name attribute
# TODO (peter-hamilton) Push this into the AttributeFactory
attribute_name = Attribute.AttributeName('Name')
name_value = Name.NameValue(name)
name_type = Name.NameType(NameType.UNINTERPRETED_TEXT_STRING)
value = Name.create(name_value=name_value, name_type=name_type)
name_obj = Attribute(attribute_name=attribute_name, attribute_value=value)
attributes = [name_obj]

# Locate UUID of specified SYMMETRIC_KEY object
result = client.locate(attributes=attributes,
credential=credential)
# Build attributes if any are specified
attributes = []
if name:
attributes.append(
attribute_factory.create_attribute(enums.AttributeType.NAME, name)
)
for initial_date in initial_dates:
try:
t = time.strptime(initial_date)
except ValueError:
logger.error(
"Invalid initial date provided: {}".format(initial_date)
)
logger.info(
"Date values should be formatted like this: "
"'Tue Jul 23 18:39:01 2019'"
)
sys.exit(-1)

try:
t = calendar.timegm(t)
except Exception:
logger.error(
"Failed to convert initial date time tuple "
"to an integer: {}".format(t)
)
sys.exit(-2)

attributes.append(
attribute_factory.create_attribute(
enums.AttributeType.INITIAL_DATE,
t
)
)

result = client.locate(attributes=attributes, credential=credential)
client.close()

# Display operation results
logger.info('locate() result status: {0}'.format(
result.result_status.value))

if result.result_status.value == ResultStatus.SUCCESS:
if result.result_status.value == enums.ResultStatus.SUCCESS:
logger.info('located UUIDs:')
for uuid in result.uuids:
logger.info('{0}'.format(uuid))
Expand Down
14 changes: 14 additions & 0 deletions kmip/demos/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,20 @@ def build_cli_parser(operation=None):
default=None,
dest="name",
help="Name of secret to retrieve from the KMIP server")
parser.add_option(
"--initial-date",
action="append",
type="str",
default=[],
dest="initial_dates",
help=(
"Initial date(s) in UTC of the secret to retrieve from the "
"KMIP server. Use once to perform an exact date match. Use "
"twice to create a date range that the secret's date should "
"be within. The value format should look like this: "
"'Tue Jul 23 18:39:01 2019'"
)
)
elif operation is Operation.REGISTER:
parser.add_option(
"-f",
Expand Down
126 changes: 113 additions & 13 deletions kmip/services/server/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -652,7 +652,7 @@ def _get_attribute_from_managed_object(self, managed_object, attr_name):
names.append(name)
return names
elif attr_name == 'Object Type':
return managed_object._object_type
return managed_object.object_type
elif attr_name == 'Cryptographic Algorithm':
return managed_object.cryptographic_algorithm
elif attr_name == 'Cryptographic Length':
Expand Down Expand Up @@ -926,6 +926,63 @@ def is_allowed(
else:
return False

def _is_valid_date(self, date_type, value, start, end):
date_type = date_type.value.lower()

if start is not None:
if end is not None:
if value < start:
self._logger.debug(
"Failed match: object's {} ({}) is less than "
"the starting {} ({}).".format(
date_type,
time.asctime(time.gmtime(value)),
date_type,
time.asctime(time.gmtime(start))
)
)
return False
elif value > end:
self._logger.debug(
"Failed match: object's {} ({}) is greater than "
"the ending {} ({}).".format(
date_type,
time.asctime(time.gmtime(value)),
date_type,
time.asctime(time.gmtime(end))
)
)
return False
else:
if start != value:
self._logger.debug(
"Failed match: object's {} ({}) does not match "
"the specified {} ({}).".format(
date_type,
time.asctime(time.gmtime(value)),
date_type,
time.asctime(time.gmtime(start))
)
)
return False
return True

def _track_date_attributes(self, date_type, date_values, value):
if date_values.get("start") is None:
date_values["start"] = value
elif date_values.get("end") is None:
if value > date_values.get("start"):
date_values["end"] = value
else:
date_values["end"] = date_values.get("start")
date_values["start"] = value
else:
raise exceptions.InvalidField(
"Too many {} attributes provided. "
"Include one for an exact match. "
"Include two for a ranged match.".format(date_type.value)
)

def _get_object_with_access_controls(
self,
uid,
Expand Down Expand Up @@ -1549,20 +1606,63 @@ def _process_locate(self, payload):
managed_objects_filtered = []

# Filter the objects based on given attributes.
# TODO: Currently will only filter for 'Name'.
# Needs to add other attributes.
for managed_object in managed_objects:
for attribute in payload.attributes:
attribute_name = attribute.attribute_name.value
attribute_value = attribute.attribute_value
attr = self._get_attribute_from_managed_object(
managed_object, attribute_name)
if attribute_name == 'Name':
names = attr
if attribute_value not in names:
self._logger.debug(
"Evaluating object: {}".format(
managed_object.unique_identifier
)
)

add_object = True
initial_date = {}

for payload_attribute in payload.attributes:
name = payload_attribute.attribute_name.value
value = payload_attribute.attribute_value
attribute = self._get_attribute_from_managed_object(
managed_object,
name
)
if attribute is None:
continue
elif name == "Name":
if value not in attribute:
self._logger.debug(
"Failed match: "
"the specified name ({}) does not match "
"any of the object's names ({}).".format(
value,
attribute
)
)
add_object = False
break
# TODO: filtering on other attributes
else:
elif name == enums.AttributeType.INITIAL_DATE.value:
initial_date["value"] = attribute
self._track_date_attributes(
enums.AttributeType.INITIAL_DATE,
initial_date,
value.value
)
else:
if value != attribute:
add_object = False
break

if initial_date.get("value"):
add_object &= self._is_valid_date(
enums.AttributeType.INITIAL_DATE,
initial_date.get("value"),
initial_date.get("start"),
initial_date.get("end")
)

if add_object:
self._logger.debug(
"Locate filter matched object: {}".format(
managed_object.unique_identifier
)
)
managed_objects_filtered.append(managed_object)

managed_objects = managed_objects_filtered
Expand Down
Loading