Remove copy_key operation

This change removes the copy_key operation from the key manager. The
copy_key operation isn't ideal because few key managers support such
an operation natively. Lack of native support requires the key to be
retrieved and stored in separate steps, which increases the handling
of the key material.

It would be relatively trivial to add this operation back to the
key manager interface at a future point. Once Castellan becomes
widely used by other projects, removing this operation will not be
possible, as it would be a backward-incompatible change.

Change-Id: I1a1dfdb4d4268319f9277fc639027819e70d4a8b
This commit is contained in:
Joel Coffman 2015-07-27 11:50:35 -04:00
parent 20a927cbe4
commit 4088221f28
5 changed files with 0 additions and 103 deletions

View File

@ -185,33 +185,6 @@ class BarbicanKeyManager(key_manager.KeyManager):
with excutils.save_and_reraise_exception():
LOG.error(u._LE("Error storing object: %s"), e)
def copy(self, context, managed_object_id):
"""Copies (i.e., clones) a managed object stored by barbican.
:param context: contains information of the user and the environment
for the request (castellan/context.py)
:param managed_object_id: the UUID of the object to copy
:return: the UUID of the object copy
:raises HTTPAuthError: if object creation fails with 401
:raises HTTPClientError: if object creation failes with 4xx
:raises HTTPServerError: if object creation fails with 5xx
"""
try:
secret = self._get_secret(context, managed_object_id)
secret_data = self._get_secret_data(secret)
# TODO(kfarr) modify to support other types of keys
key = sym_key.SymmetricKey(secret.algorithm,
secret.bit_length,
secret_data)
copy_uuid = self.store(context, key, secret.expiration)
return copy_uuid
except (barbican_exceptions.HTTPAuthError,
barbican_exceptions.HTTPClientError,
barbican_exceptions.HTTPServerError) as e:
with excutils.save_and_reraise_exception():
LOG.error(u._LE("Error copying object: %s"), e)
def _create_secret_ref(self, key_id):
"""Creates the URL required for accessing a secret.

View File

@ -71,21 +71,6 @@ class KeyManager(object):
"""
pass
@abc.abstractmethod
def copy(self, context, managed_object_id):
"""Copies (i.e., clones) a managed object stored by the key manager.
This method copies the specified managed object and returns the copy's
UUID. If the specified context does not permit copying objects, then a
NotAuthorized error should be raised.
Implementation note: This method should behave identically to
store(context, get(context, <object UUID>))
although it is preferable to perform this operation within the key
manager to avoid unnecessary handling of the object material.
"""
pass
@abc.abstractmethod
def get(self, context, managed_object_id):
"""Retrieves the specified managed object.

View File

@ -158,15 +158,6 @@ class MockKeyManager(key_manager.KeyManager):
return key_id
def copy(self, context, managed_object_id, **kwargs):
if context is None:
raise exception.Forbidden()
copied_key_id = self._generate_key_id()
self.keys[copied_key_id] = self.keys[managed_object_id]
return copied_key_id
def get(self, context, managed_object_id, **kwargs):
"""Retrieves the key identified by the specified id.

View File

@ -69,44 +69,6 @@ class BarbicanKeyManagerTestCase(test_key_manager.KeyManagerTestCase):
self.key_mgr._barbican_client = self.mock_barbican
self.key_mgr._current_context = self.ctxt
def test_copy_key(self):
# Create metadata for original secret
original_secret_metadata = mock.Mock()
original_secret_metadata.algorithm = mock.sentinel.alg
original_secret_metadata.bit_length = mock.sentinel.bit
original_secret_metadata.name = mock.sentinel.name
original_secret_metadata.expiration = mock.sentinel.expiration
original_secret_metadata.mode = mock.sentinel.mode
content_types = {'default': 'fake_type'}
original_secret_metadata.content_types = content_types
original_secret_data = mock.Mock()
original_secret_metadata.payload = original_secret_data
# Create href for copied secret
copied_secret = mock.Mock()
copied_secret.store.return_value = (
'http://http://host:9311/v1/secrets/uuid')
# Set get and create return values
self.get.return_value = original_secret_metadata
self.create.return_value = copied_secret
# Copy the original
self.key_mgr.copy(self.ctxt, self.key_id)
# Assert proper methods were called
self.get.assert_called_once_with(self.secret_ref)
self.create.assert_called_once_with(
payload=original_secret_metadata.payload,
algorithm=mock.sentinel.alg,
expiration=mock.sentinel.expiration)
copied_secret.store.assert_called_once_with()
def test_copy_null_context(self):
self.key_mgr._barbican_client = None
self.assertRaises(exception.Forbidden,
self.key_mgr.copy, None, self.key_id)
def test_create_key(self):
# Create order_ref_url and assign return value
order_ref_url = ("http://localhost:9311/v1/orders/"

View File

@ -136,20 +136,6 @@ class MockKeyManagerTestCase(test_key_mgr.KeyManagerTestCase):
self.assertRaises(exception.Forbidden,
self.key_mgr.store, None, None)
def test_copy_key(self):
key_id = self.key_mgr.create_key(self.context)
key = self.key_mgr.get(self.context, key_id)
copied_key_id = self.key_mgr.copy(self.context, key_id)
copied_key = self.key_mgr.get(self.context, copied_key_id)
self.assertNotEqual(key_id, copied_key_id)
self.assertEqual(key, copied_key)
def test_copy_null_context(self):
self.assertRaises(exception.Forbidden,
self.key_mgr.copy, None, None)
def test_get_null_context(self):
self.assertRaises(exception.Forbidden,
self.key_mgr.get, None, None)