Merge "Add ID to managed objects"
Jenkins authored 6 years ago
Gerrit Code Review committed 6 years ago
27 | 27 | class ManagedObject(object): |
28 | 28 | """Base class to represent all managed objects.""" |
29 | 29 | |
30 | def __init__(self, name=None, created=None): | |
30 | def __init__(self, name=None, created=None, id=None): | |
31 | 31 | """Managed Object |
32 | 32 | |
33 | 33 | :param name: the name of the managed object. |
34 | 34 | :param created: the time a managed object was created. |
35 | :param id: the ID of the object, generated after storing the object. | |
35 | 36 | """ |
36 | 37 | self._name = name |
37 | 38 | |
41 | 42 | else: |
42 | 43 | raise ValueError('created must be of long type, actual type %s' % |
43 | 44 | type(created)) |
45 | ||
46 | self._id = id | |
47 | ||
48 | @property | |
49 | def id(self): | |
50 | """Returns the ID of the managed object. | |
51 | ||
52 | Returns the ID of the managed object or None if this object does not | |
53 | have one. If the ID is None, the object has not been persisted yet. | |
54 | """ | |
55 | return self._id | |
44 | 56 | |
45 | 57 | @property |
46 | 58 | def name(self): |
24 | 24 | class OpaqueData(managed_object.ManagedObject): |
25 | 25 | """This class represents opaque data.""" |
26 | 26 | |
27 | def __init__(self, data, name=None, created=None): | |
27 | def __init__(self, data, name=None, created=None, id=None): | |
28 | 28 | """Create a new OpaqueData object. |
29 | 29 | |
30 | 30 | Expected type for data is a bytestring. |
31 | 31 | """ |
32 | 32 | self._data = data |
33 | super(OpaqueData, self).__init__(name=name, created=created) | |
33 | super(OpaqueData, self).__init__(name=name, created=created, id=id) | |
34 | 34 | |
35 | 35 | @property |
36 | 36 | def format(self): |
24 | 24 | class Passphrase(managed_object.ManagedObject): |
25 | 25 | """This class represents a passphrase.""" |
26 | 26 | |
27 | def __init__(self, passphrase, name=None, created=None): | |
27 | def __init__(self, passphrase, name=None, created=None, id=None): | |
28 | 28 | """Create a new Passphrase object. |
29 | 29 | |
30 | 30 | The expected type for the passphrase is a bytestring. |
31 | 31 | """ |
32 | 32 | self._passphrase = passphrase |
33 | super(Passphrase, self).__init__(name=name, created=created) | |
33 | super(Passphrase, self).__init__(name=name, created=created, id=id) | |
34 | 34 | |
35 | 35 | @property |
36 | 36 | def format(self): |
25 | 25 | """This class represents private keys.""" |
26 | 26 | |
27 | 27 | def __init__(self, algorithm, bit_length, key, |
28 | name=None, created=None): | |
28 | name=None, created=None, id=None): | |
29 | 29 | """Create a new PrivateKey object. |
30 | 30 | |
31 | 31 | The arguments specify the algorithm and bit length for the asymmetric |
34 | 34 | self._alg = algorithm |
35 | 35 | self._bit_length = bit_length |
36 | 36 | self._key = key |
37 | super(PrivateKey, self).__init__(name=name, created=created) | |
37 | super(PrivateKey, self).__init__(name=name, created=created, id=id) | |
38 | 38 | |
39 | 39 | @property |
40 | 40 | def algorithm(self): |
25 | 25 | """This class represents public keys.""" |
26 | 26 | |
27 | 27 | def __init__(self, algorithm, bit_length, key, |
28 | name=None, created=None): | |
28 | name=None, created=None, id=None): | |
29 | 29 | """Create a new PublicKey object. |
30 | 30 | |
31 | 31 | The arguments specify the algorithm and bit length for the asymmetric |
35 | 35 | self._alg = algorithm |
36 | 36 | self._bit_length = bit_length |
37 | 37 | self._key = key |
38 | super(PublicKey, self).__init__(name=name, created=created) | |
38 | super(PublicKey, self).__init__(name=name, created=created, id=id) | |
39 | 39 | |
40 | 40 | @property |
41 | 41 | def algorithm(self): |
25 | 25 | """This class represents symmetric keys.""" |
26 | 26 | |
27 | 27 | def __init__(self, algorithm, bit_length, key, |
28 | name=None, created=None): | |
28 | name=None, created=None, id=None): | |
29 | 29 | """Create a new SymmetricKey object. |
30 | 30 | |
31 | 31 | The arguments specify the algorithm and bit length for the symmetric |
34 | 34 | self._alg = algorithm |
35 | 35 | self._bit_length = bit_length |
36 | 36 | self._key = key |
37 | super(SymmetricKey, self).__init__(name=name, created=created) | |
37 | super(SymmetricKey, self).__init__(name=name, created=created, id=id) | |
38 | 38 | |
39 | 39 | @property |
40 | 40 | def algorithm(self): |
24 | 24 | class X509(certificate.Certificate): |
25 | 25 | """This class represents X.509 certificates.""" |
26 | 26 | |
27 | def __init__(self, data, name=None, created=None): | |
27 | def __init__(self, data, name=None, created=None, id=None): | |
28 | 28 | """Create a new X509 object. |
29 | 29 | |
30 | 30 | The data should be in a bytestring. |
31 | 31 | """ |
32 | 32 | self._data = data |
33 | super(X509, self).__init__(name=name, created=created) | |
33 | super(X509, self).__init__(name=name, created=created, id=id) | |
34 | 34 | |
35 | 35 | @property |
36 | 36 | def format(self): |
483 | 483 | else: |
484 | 484 | secret_data = self._get_secret_data(secret) |
485 | 485 | |
486 | if secret.secret_ref: | |
487 | object_id = self._retrieve_secret_uuid(secret.secret_ref) | |
488 | else: | |
489 | object_id = None | |
490 | ||
486 | 491 | # convert created ISO8601 in Barbican to POSIX |
487 | 492 | if secret.created: |
488 | 493 | time_stamp = timeutils.parse_isotime( |
494 | 499 | secret.bit_length, |
495 | 500 | secret_data, |
496 | 501 | secret.name, |
497 | created) | |
502 | created, | |
503 | object_id) | |
498 | 504 | else: |
499 | 505 | return secret_type(secret_data, |
500 | 506 | secret.name, |
501 | created) | |
507 | created, | |
508 | object_id) | |
502 | 509 | |
503 | 510 | def _get_secret(self, context, object_id): |
504 | 511 | """Returns the metadata of the secret. |
136 | 136 | self.assertEqual(managed_object.get_encoded(), |
137 | 137 | retrieved_object.get_encoded()) |
138 | 138 | self.assertFalse(managed_object.is_metadata_only()) |
139 | self.assertFalse(retrieved_object.is_metadata_only()) | |
140 | self.assertIsNotNone(retrieved_object.id) | |
139 | 141 | |
140 | 142 | @utils.parameterized_dataset({ |
141 | 143 | 'symmetric_key': [_get_test_symmetric_key()], |
154 | 156 | metadata_only=True) |
155 | 157 | self.assertFalse(managed_object.is_metadata_only()) |
156 | 158 | self.assertTrue(retrieved_object.is_metadata_only()) |
159 | self.assertIsNotNone(retrieved_object.id) | |
157 | 160 | |
158 | 161 | @utils.parameterized_dataset({ |
159 | 162 | 'symmetric_key': [_get_test_symmetric_key()], |
170 | 173 | retrieved_object = self.key_mgr.get(self.ctxt, uuid) |
171 | 174 | self.assertEqual(managed_object.get_encoded(), |
172 | 175 | retrieved_object.get_encoded()) |
176 | self.assertIsNotNone(retrieved_object.id) | |
173 | 177 | |
174 | 178 | @utils.parameterized_dataset({ |
175 | 179 | 'symmetric_key': [_get_test_symmetric_key()], |
188 | 192 | # check if the object we created is in the list |
189 | 193 | retrieved_objects = self.key_mgr.list(self.ctxt) |
190 | 194 | self.assertTrue(managed_object in retrieved_objects) |
191 | for obj in retrieved_objects: | |
192 | self.assertFalse(obj.is_metadata_only()) | |
195 | for retrieved_object in retrieved_objects: | |
196 | self.assertFalse(retrieved_object.is_metadata_only()) | |
197 | self.assertIsNotNone(retrieved_object.id) | |
193 | 198 | |
194 | 199 | @utils.parameterized_dataset({ |
195 | 200 | 'symmetric_key': [_get_test_symmetric_key()], |
210 | 215 | # check if the object we created is in the list |
211 | 216 | retrieved_objects = self.key_mgr.list(self.ctxt, metadata_only=True) |
212 | 217 | self.assertTrue(expected_obj in retrieved_objects) |
213 | for obj in retrieved_objects: | |
214 | self.assertTrue(obj.is_metadata_only()) | |
218 | for retrieved_object in retrieved_objects: | |
219 | self.assertTrue(retrieved_object.is_metadata_only()) | |
220 | self.assertIsNotNone(retrieved_object.id) | |
215 | 221 | |
216 | 222 | @utils.parameterized_dataset({ |
217 | 223 | 'query_by_object_type': { |
232 | 238 | retrieved_objects = self.key_mgr.list(self.ctxt, **query_dict) |
233 | 239 | for retrieved_object in retrieved_objects: |
234 | 240 | self.assertEqual(type(object_1), type(retrieved_object)) |
241 | self.assertIsNotNone(retrieved_object.id) | |
235 | 242 | self.assertTrue(object_1 in retrieved_objects) |
162 | 162 | raise exception.Forbidden() |
163 | 163 | |
164 | 164 | key_id = self._generate_key_id() |
165 | managed_object._id = key_id | |
165 | 166 | self.keys[key_id] = managed_object |
166 | 167 | |
167 | 168 | return key_id |
206 | 206 | original_secret_metadata.bit_length = mock.sentinel.bit |
207 | 207 | original_secret_metadata.secret_type = 'symmetric' |
208 | 208 | |
209 | key_id = "43ed09c3-e551-4c24-b612-e619abe9b534" | |
210 | key_ref = ("http://localhost:9311/v1/secrets/" + key_id) | |
211 | original_secret_metadata.secret_ref = key_ref | |
212 | ||
209 | 213 | created = timeutils.parse_isotime('2015-10-20 18:51:17+00:00') |
210 | 214 | original_secret_metadata.created = created |
211 | 215 | created_formatted = timeutils.parse_isotime(str(created)) |
221 | 225 | key = self.key_mgr.get(self.ctxt, self.key_id) |
222 | 226 | |
223 | 227 | self.get.assert_called_once_with(self.secret_ref) |
228 | self.assertEqual(key_id, key.id) | |
224 | 229 | self.assertEqual(key_name, key.name) |
225 | 230 | self.assertEqual(original_secret_data, key.get_encoded()) |
226 | 231 | self.assertEqual(created_posix, key.created) |
377 | 382 | original_secret_metadata.bit_length = mock.sentinel.bit |
378 | 383 | original_secret_metadata.secret_type = 'symmetric' |
379 | 384 | |
385 | key_id = "43ed09c3-e551-4c24-b612-e619abe9b534" | |
386 | key_ref = ("http://localhost:9311/v1/secrets/" + key_id) | |
387 | original_secret_metadata.secret_ref = key_ref | |
388 | ||
380 | 389 | created = timeutils.parse_isotime('2015-10-20 18:51:17+00:00') |
381 | 390 | original_secret_metadata.created = created |
382 | 391 | created_formatted = timeutils.parse_isotime(str(created)) |
397 | 406 | key = key_list[0] |
398 | 407 | |
399 | 408 | self.list.assert_called_once() |
409 | self.assertEqual(key_id, key.id) | |
400 | 410 | self.assertEqual(key_name, key.name) |
401 | 411 | self.assertEqual(original_secret_data, key.get_encoded()) |
402 | 412 | self.assertEqual(created_posix, key.created) |
69 | 69 | key_id = self.key_mgr.create_key(self.context, length=length) |
70 | 70 | key = self.key_mgr.get(self.context, key_id) |
71 | 71 | self.assertEqual(length / 8, len(key.get_encoded())) |
72 | self.assertIsNotNone(key.id) | |
72 | 73 | |
73 | 74 | def test_create_key_with_name(self): |
74 | 75 | name = 'my key' |
75 | 76 | key_id = self.key_mgr.create_key(self.context, name=name) |
76 | 77 | key = self.key_mgr.get(self.context, key_id) |
77 | 78 | self.assertEqual(name, key.name) |
79 | self.assertIsNotNone(key.id) | |
78 | 80 | |
79 | 81 | def test_create_key_with_algorithm(self): |
80 | 82 | algorithm = 'DES' |
81 | 83 | key_id = self.key_mgr.create_key(self.context, algorithm=algorithm) |
82 | 84 | key = self.key_mgr.get(self.context, key_id) |
83 | 85 | self.assertEqual(algorithm, key.algorithm) |
86 | self.assertIsNotNone(key.id) | |
84 | 87 | |
85 | 88 | def test_create_key_null_context(self): |
86 | 89 | self.assertRaises(exception.Forbidden, |
93 | 96 | self.context, 'RSA', length, name=name) |
94 | 97 | |
95 | 98 | private_key = self.key_mgr.get(self.context, private_key_uuid) |
99 | self.assertIsNotNone(private_key.id) | |
96 | 100 | public_key = self.key_mgr.get(self.context, public_key_uuid) |
101 | self.assertIsNotNone(public_key.id) | |
97 | 102 | |
98 | 103 | crypto_private_key = get_cryptography_private_key(private_key) |
99 | 104 | crypto_public_key = get_cryptography_public_key(public_key) |
152 | 157 | actual_key = self.key_mgr.get(self.context, key_id) |
153 | 158 | self.assertEqual(_key, actual_key) |
154 | 159 | |
160 | self.assertIsNotNone(actual_key.id) | |
161 | ||
155 | 162 | def test_store_key_and_get_metadata(self): |
156 | 163 | secret_key = bytes(b'0' * 64) |
157 | 164 | _key = sym_key.SymmetricKey('AES', 64 * 8, secret_key) |
163 | 170 | self.assertIsNone(actual_key.get_encoded()) |
164 | 171 | self.assertTrue(actual_key.is_metadata_only()) |
165 | 172 | |
173 | self.assertIsNotNone(actual_key.id) | |
174 | ||
166 | 175 | def test_store_key_and_get_metadata_and_get_key(self): |
167 | 176 | secret_key = bytes(b'0' * 64) |
168 | 177 | _key = sym_key.SymmetricKey('AES', 64 * 8, secret_key) |
180 | 189 | self.assertIsNotNone(actual_key.get_encoded()) |
181 | 190 | self.assertFalse(actual_key.is_metadata_only()) |
182 | 191 | |
192 | self.assertIsNotNone(actual_key.id) | |
193 | ||
183 | 194 | def test_store_null_context(self): |
184 | 195 | self.assertRaises(exception.Forbidden, |
185 | 196 | self.key_mgr.store, None, None) |
219 | 230 | self.assertEqual(2, len(keys)) |
220 | 231 | self.assertTrue(key1 in keys) |
221 | 232 | self.assertTrue(key2 in keys) |
233 | ||
234 | for key in keys: | |
235 | self.assertIsNotNone(key.id) | |
222 | 236 | |
223 | 237 | def test_list_keys_metadata_only(self): |
224 | 238 | key1 = sym_key.SymmetricKey('AES', 64 * 8, bytes(b'0' * 64)) |
232 | 246 | for key in keys: |
233 | 247 | self.assertTrue(key.is_metadata_only()) |
234 | 248 | self.assertTrue(key.bit_length in bit_length_list) |
249 | ||
250 | for key in keys: | |
251 | self.assertIsNotNone(key.id) |