Codebase list python-castellan / 4088221
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 Joel Coffman 8 years ago
5 changed file(s) with 0 addition(s) and 103 deletion(s). Raw diff Collapse all Expand all
184184 with excutils.save_and_reraise_exception():
185185 LOG.error(u._LE("Error storing object: %s"), e)
186186
187 def copy(self, context, managed_object_id):
188 """Copies (i.e., clones) a managed object stored by barbican.
189
190 :param context: contains information of the user and the environment
191 for the request (castellan/context.py)
192 :param managed_object_id: the UUID of the object to copy
193 :return: the UUID of the object copy
194 :raises HTTPAuthError: if object creation fails with 401
195 :raises HTTPClientError: if object creation failes with 4xx
196 :raises HTTPServerError: if object creation fails with 5xx
197 """
198
199 try:
200 secret = self._get_secret(context, managed_object_id)
201 secret_data = self._get_secret_data(secret)
202 # TODO(kfarr) modify to support other types of keys
203 key = sym_key.SymmetricKey(secret.algorithm,
204 secret.bit_length,
205 secret_data)
206 copy_uuid = self.store(context, key, secret.expiration)
207 return copy_uuid
208 except (barbican_exceptions.HTTPAuthError,
209 barbican_exceptions.HTTPClientError,
210 barbican_exceptions.HTTPServerError) as e:
211 with excutils.save_and_reraise_exception():
212 LOG.error(u._LE("Error copying object: %s"), e)
213
214187 def _create_secret_ref(self, key_id):
215188 """Creates the URL required for accessing a secret.
216189
7171 pass
7272
7373 @abc.abstractmethod
74 def copy(self, context, managed_object_id):
75 """Copies (i.e., clones) a managed object stored by the key manager.
76
77 This method copies the specified managed object and returns the copy's
78 UUID. If the specified context does not permit copying objects, then a
79 NotAuthorized error should be raised.
80
81 Implementation note: This method should behave identically to
82 store(context, get(context, <object UUID>))
83 although it is preferable to perform this operation within the key
84 manager to avoid unnecessary handling of the object material.
85 """
86 pass
87
88 @abc.abstractmethod
8974 def get(self, context, managed_object_id):
9075 """Retrieves the specified managed object.
9176
157157
158158 return key_id
159159
160 def copy(self, context, managed_object_id, **kwargs):
161 if context is None:
162 raise exception.Forbidden()
163
164 copied_key_id = self._generate_key_id()
165 self.keys[copied_key_id] = self.keys[managed_object_id]
166
167 return copied_key_id
168
169160 def get(self, context, managed_object_id, **kwargs):
170161 """Retrieves the key identified by the specified id.
171162
6767
6868 self.key_mgr._barbican_client = self.mock_barbican
6969 self.key_mgr._current_context = self.ctxt
70
71 def test_copy_key(self):
72 # Create metadata for original secret
73 original_secret_metadata = mock.Mock()
74 original_secret_metadata.algorithm = mock.sentinel.alg
75 original_secret_metadata.bit_length = mock.sentinel.bit
76 original_secret_metadata.name = mock.sentinel.name
77 original_secret_metadata.expiration = mock.sentinel.expiration
78 original_secret_metadata.mode = mock.sentinel.mode
79 content_types = {'default': 'fake_type'}
80 original_secret_metadata.content_types = content_types
81 original_secret_data = mock.Mock()
82 original_secret_metadata.payload = original_secret_data
83
84 # Create href for copied secret
85 copied_secret = mock.Mock()
86 copied_secret.store.return_value = (
87 'http://http://host:9311/v1/secrets/uuid')
88
89 # Set get and create return values
90 self.get.return_value = original_secret_metadata
91 self.create.return_value = copied_secret
92
93 # Copy the original
94 self.key_mgr.copy(self.ctxt, self.key_id)
95
96 # Assert proper methods were called
97 self.get.assert_called_once_with(self.secret_ref)
98 self.create.assert_called_once_with(
99 payload=original_secret_metadata.payload,
100 algorithm=mock.sentinel.alg,
101 expiration=mock.sentinel.expiration)
102 copied_secret.store.assert_called_once_with()
103
104 def test_copy_null_context(self):
105 self.key_mgr._barbican_client = None
106 self.assertRaises(exception.Forbidden,
107 self.key_mgr.copy, None, self.key_id)
10870
10971 def test_create_key(self):
11072 # Create order_ref_url and assign return value
135135 self.assertRaises(exception.Forbidden,
136136 self.key_mgr.store, None, None)
137137
138 def test_copy_key(self):
139 key_id = self.key_mgr.create_key(self.context)
140 key = self.key_mgr.get(self.context, key_id)
141
142 copied_key_id = self.key_mgr.copy(self.context, key_id)
143 copied_key = self.key_mgr.get(self.context, copied_key_id)
144
145 self.assertNotEqual(key_id, copied_key_id)
146 self.assertEqual(key, copied_key)
147
148 def test_copy_null_context(self):
149 self.assertRaises(exception.Forbidden,
150 self.key_mgr.copy, None, None)
151
152138 def test_get_null_context(self):
153139 self.assertRaises(exception.Forbidden,
154140 self.key_mgr.get, None, None)