Codebase list python-castellan / e43302c
Copy cinder.keymgr to castellan This patch adds the code found in cinder.keymgr to castellan, except for the barbican wrapper and the barbican test case. The ConfKeyManager is also not included, since it is insecure and not suitable for production, and the MockKeyManager is suitable for testing. Change-Id: I1139262581720be47a09b46f01f4bfb85a764d9a Brianna Poulos 9 years ago
16 changed file(s) with 843 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory
1 # All Rights Reserved.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License"); you may
4 # not use this file except in compliance with the License. You may obtain
5 # a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 # License for the specific language governing permissions and limitations
13 # under the License.
14
15 """
16 Castellan exception subclasses
17 """
18
19 import six.moves.urllib.parse as urlparse
20
21 from castellan.openstack.common import _i18n as u
22
23 _FATAL_EXCEPTION_FORMAT_ERRORS = False
24
25
26 class RedirectException(Exception):
27 def __init__(self, url):
28 self.url = urlparse.urlparse(url)
29
30
31 class CastellanException(Exception):
32 """Base Castellan Exception
33
34 To correctly use this class, inherit from it and define
35 a 'message' property. That message will get printf'd
36 with the keyword arguments provided to the constructor.
37 """
38 message = u._("An unknown exception occurred")
39
40 def __init__(self, message_arg=None, *args, **kwargs):
41 if not message_arg:
42 message_arg = self.message
43 try:
44 self.message = message_arg.format(**kwargs)
45 except Exception as e:
46 if _FATAL_EXCEPTION_FORMAT_ERRORS:
47 raise e
48 else:
49 # at least get the core message out if something happened
50 pass
51 super(CastellanException, self).__init__(self.message)
52
53
54 class Forbidden(CastellanException):
55 message = u._("You are not authorized to complete this action.")
0 # Copyright 2011-2012 OpenStack LLC.
1 # All Rights Reserved.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License"); you may
4 # not use this file except in compliance with the License. You may obtain
5 # a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 # License for the specific language governing permissions and limitations
13 # under the License.
14
15 from oslo_utils import uuidutils
16
17 from castellan.openstack.common import local
18 from castellan.openstack.common import policy
19
20
21 class RequestContext(object):
22 """User security context object
23
24 Stores information about the security context under which the user
25 accesses the system, as well as additional request information.
26 """
27
28 def __init__(self, auth_token=None, user=None, project=None, roles=None,
29 is_admin=False, read_only=False, show_deleted=False,
30 owner_is_project=True, service_catalog=None,
31 policy_enforcer=None):
32 self.auth_token = auth_token
33 self.user = user
34 self.project = project
35 self.roles = roles or []
36 self.read_only = read_only
37 self.owner_is_project = owner_is_project
38 self.request_id = uuidutils.generate_uuid()
39 self.service_catalog = service_catalog
40 self.policy_enforcer = policy_enforcer or policy.Enforcer()
41 self.is_admin = is_admin
42
43 if not hasattr(local.store, 'context'):
44 self.update_store()
45
46 def to_dict(self):
47 return {
48 'request_id': self.request_id,
49 'user': self.user,
50 'user_id': self.user,
51 'project': self.project,
52 'project_id': self.project,
53 'roles': self.roles,
54 'auth_token': self.auth_token,
55 'service_catalog': self.service_catalog,
56 }
57
58 @classmethod
59 def from_dict(cls, values):
60 return cls(**values)
61
62 def update_store(self):
63 local.store.context = self
64
65 @property
66 def owner(self):
67 """Return the owner to correlate with key."""
68 if self.owner_is_project:
69 return self.project
70 return self.user
0 # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory
1 # All Rights Reserved.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License"); you may
4 # not use this file except in compliance with the License. You may obtain
5 # a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 # License for the specific language governing permissions and limitations
13 # under the License.
14
15 from oslo.utils import importutils
16 from oslo_config import cfg
17
18 keymgr_opts = [
19 cfg.StrOpt('api_class',
20 help='The full class name of the key manager API class'),
21 ]
22
23 CONF = cfg.CONF
24 CONF.register_opts(keymgr_opts, group='keymgr')
25
26
27 def API():
28 cls = importutils.import_class(CONF.keymgr.api_class)
29 return cls()
0 # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory
1 # All Rights Reserved.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License"); you may
4 # not use this file except in compliance with the License. You may obtain
5 # a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 # License for the specific language governing permissions and limitations
13 # under the License.
14
15 """
16 Base Key and SymmetricKey Classes
17
18 This module defines the Key and SymmetricKey classes. The Key class is the base
19 class to represent all encryption keys. The basis for this class was copied
20 from Java.
21 """
22
23 import abc
24
25 import six
26
27
28 @six.add_metaclass(abc.ABCMeta)
29 class Key(object):
30 """Base class to represent all keys."""
31
32 @abc.abstractmethod
33 def get_algorithm(self):
34 """Returns the key's algorithm.
35
36 Returns the key's algorithm. For example, "DSA" indicates that this key
37 is a DSA key and "AES" indicates that this key is an AES key.
38 """
39 pass
40
41 @abc.abstractmethod
42 def get_format(self):
43 """Returns the encoding format.
44
45 Returns the key's encoding format or None if this key is not encoded.
46 """
47 pass
48
49 @abc.abstractmethod
50 def get_encoded(self):
51 """Returns the key in the format specified by its encoding."""
52 pass
0 # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory
1 # All Rights Reserved.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License"); you may
4 # not use this file except in compliance with the License. You may obtain
5 # a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 # License for the specific language governing permissions and limitations
13 # under the License.
14
15 """
16 Key manager API
17 """
18
19 import abc
20
21 import six
22
23
24 @six.add_metaclass(abc.ABCMeta)
25 class KeyManager(object):
26 """Base Key Manager Interface
27
28 A Key Manager is responsible for managing encryption keys for volumes. A
29 Key Manager is responsible for creating, reading, and deleting keys.
30 """
31
32 @abc.abstractmethod
33 def create_key(self, context, algorithm='AES', length=256,
34 expiration=None, **kwargs):
35 """Creates a key.
36
37 This method creates a key and returns the key's UUID. If the specified
38 context does not permit the creation of keys, then a NotAuthorized
39 exception should be raised.
40 """
41 pass
42
43 @abc.abstractmethod
44 def store_key(self, context, key, expiration=None, **kwargs):
45 """Stores (i.e., registers) a key with the key manager.
46
47 This method stores the specified key and returns its UUID that
48 identifies it within the key manager. If the specified context does
49 not permit the creation of keys, then a NotAuthorized exception should
50 be raised.
51 """
52 pass
53
54 @abc.abstractmethod
55 def copy_key(self, context, key_id, **kwargs):
56 """Copies (i.e., clones) a key stored by the key manager.
57
58 This method copies the specified key and returns the copy's UUID. If
59 the specified context does not permit copying keys, then a
60 NotAuthorized error should be raised.
61
62 Implementation note: This method should behave identically to
63 store_key(context, get_key(context, <encryption key UUID>))
64 although it is preferable to perform this operation within the key
65 manager to avoid unnecessary handling of the key material.
66 """
67 pass
68
69 @abc.abstractmethod
70 def get_key(self, context, key_id, **kwargs):
71 """Retrieves the specified key.
72
73 Implementations should verify that the caller has permissions to
74 retrieve the key by checking the context object passed in as context.
75 If the user lacks permission then a NotAuthorized exception is raised.
76
77 If the specified key does not exist, then a KeyError should be raised.
78 Implementations should preclude users from discerning the UUIDs of
79 keys that belong to other users by repeatedly calling this method.
80 That is, keys that belong to other users should be considered "non-
81 existent" and completely invisible.
82 """
83 pass
84
85 @abc.abstractmethod
86 def delete_key(self, context, key_id, **kwargs):
87 """Deletes the specified key.
88
89 Implementations should verify that the caller has permission to delete
90 the key by checking the context object (context). A NotAuthorized
91 exception should be raised if the caller lacks permission.
92
93 If the specified key does not exist, then a KeyError should be raised.
94 Implementations should preclude users from discerning the UUIDs of
95 keys that belong to other users by repeatedly calling this method.
96 That is, keys that belong to other users should be considered "non-
97 existent" and completely invisible.
98 """
99 pass
0 # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory
1 # All Rights Reserved.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License"); you may
4 # not use this file except in compliance with the License. You may obtain
5 # a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 # License for the specific language governing permissions and limitations
13 # under the License.
14
15 """
16 Key manager implementation that raises NotImplementedError
17 """
18
19 from castellan.keymgr import key_mgr
20
21
22 class NotImplementedKeyManager(key_mgr.KeyManager):
23 """Key Manager Interface that raises NotImplementedError for all operations
24
25 """
26
27 def create_key(self, context, algorithm='AES', length=256,
28 expiration=None, **kwargs):
29 raise NotImplementedError()
30
31 def store_key(self, context, key, expiration=None, **kwargs):
32 raise NotImplementedError()
33
34 def copy_key(self, context, key_id, **kwargs):
35 raise NotImplementedError()
36
37 def get_key(self, context, key_id, **kwargs):
38 raise NotImplementedError()
39
40 def delete_key(self, context, key_id, **kwargs):
41 raise NotImplementedError()
0 # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory
1 # All Rights Reserved.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License"); you may
4 # not use this file except in compliance with the License. You may obtain
5 # a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 # License for the specific language governing permissions and limitations
13 # under the License.
14
15 """
16 Base SymmetricKey Class
17
18 This module defines the SymmetricKey class.
19 """
20
21 from castellan.keymgr import key
22
23
24 class SymmetricKey(key.Key):
25 """This class represents symmetric keys."""
26
27 def __init__(self, alg, key):
28 """Create a new SymmetricKey object.
29
30 The arguments specify the algorithm for the symmetric encryption and
31 the bytes for the key.
32 """
33 self.alg = alg
34 self.key = key
35
36 def get_algorithm(self):
37 """Returns the algorithm for symmetric encryption."""
38 return self.alg
39
40 def get_format(self):
41 """This method returns 'RAW'."""
42 return "RAW"
43
44 def get_encoded(self):
45 """Returns the key in its encoded format."""
46 return self.key
47
48 def __eq__(self, other):
49 if isinstance(other, SymmetricKey):
50 return (self.alg == other.alg and
51 self.key == other.key)
52 return NotImplemented
53
54 def __ne__(self, other):
55 result = self.__eq__(other)
56 if result is NotImplemented:
57 return result
58 return not result
0 # Copyright 2011 Justin Santa Barbara
1 # Copyright 2012 OpenStack Foundation
2 # All Rights Reserved.
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License"); you may
5 # not use this file except in compliance with the License. You may obtain
6 # a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 # License for the specific language governing permissions and limitations
14 # under the License.
15
16 """Implementation of a fake key manager."""
17
18
19 from castellan.tests.keymgr import mock_key_mgr
20
21
22 def fake_api():
23 return mock_key_mgr.MockKeyManager()
0 # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory
1 # All Rights Reserved.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License"); you may
4 # not use this file except in compliance with the License. You may obtain
5 # a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 # License for the specific language governing permissions and limitations
13 # under the License.
14
15 """
16 A mock implementation of a key manager that stores keys in a dictionary.
17
18 This key manager implementation is primarily intended for testing. In
19 particular, it does not store keys persistently. Lack of a centralized key
20 store also makes this implementation unsuitable for use among different
21 services.
22
23 Note: Instantiating this class multiple times will create separate key stores.
24 Keys created in one instance will not be accessible from other instances of
25 this class.
26 """
27
28 import array
29 import binascii
30 import random
31 import uuid
32
33 from castellan.common import exception
34 from castellan.keymgr import key_mgr
35 from castellan.keymgr import symmetric_key as sym_key
36
37
38 class MockKeyManager(key_mgr.KeyManager):
39
40 """Mocking manager for integration tests.
41
42 This mock key manager implementation supports all the methods specified
43 by the key manager interface. This implementation stores keys within a
44 dictionary, and as a result, it is not acceptable for use across different
45 services. Side effects (e.g., raising exceptions) for each method are
46 handled as specified by the key manager interface.
47
48 This key manager is not suitable for use in production deployments.
49 """
50
51 def __init__(self):
52 self.keys = {}
53
54 def _generate_hex_key(self, **kwargs):
55 key_length = kwargs.get('key_length', 256)
56 # hex digit => 4 bits
57 length = int(key_length / 4)
58 hex_encoded = self._generate_password(length=length,
59 symbolgroups='0123456789ABCDEF')
60 return hex_encoded
61
62 def _generate_key(self, **kwargs):
63 _hex = self._generate_hex_key(**kwargs)
64 return sym_key.SymmetricKey(
65 'AES',
66 array.array('B', binascii.unhexlify(_hex)).tolist())
67
68 def create_key(self, context, **kwargs):
69 """Creates a key.
70
71 This implementation returns a UUID for the created key. A
72 Forbidden exception is raised if the specified context is None.
73 """
74 if context is None:
75 raise exception.Forbidden()
76
77 key = self._generate_key(**kwargs)
78 return self.store_key(context, key)
79
80 def _generate_key_id(self):
81 key_id = str(uuid.uuid4())
82 while key_id in self.keys:
83 key_id = str(uuid.uuid4())
84
85 return key_id
86
87 def store_key(self, context, key, **kwargs):
88 """Stores (i.e., registers) a key with the key manager."""
89 if context is None:
90 raise exception.Forbidden()
91
92 key_id = self._generate_key_id()
93 self.keys[key_id] = key
94
95 return key_id
96
97 def copy_key(self, context, key_id, **kwargs):
98 if context is None:
99 raise exception.Forbidden()
100
101 copied_key_id = self._generate_key_id()
102 self.keys[copied_key_id] = self.keys[key_id]
103
104 return copied_key_id
105
106 def get_key(self, context, key_id, **kwargs):
107 """Retrieves the key identified by the specified id.
108
109 This implementation returns the key that is associated with the
110 specified UUID. A Forbidden exception is raised if the specified
111 context is None; a KeyError is raised if the UUID is invalid.
112 """
113 if context is None:
114 raise exception.Forbidden()
115
116 return self.keys[key_id]
117
118 def delete_key(self, context, key_id, **kwargs):
119 """Deletes the key identified by the specified id.
120
121 A Forbidden exception is raised if the context is None and a
122 KeyError is raised if the UUID is invalid.
123 """
124 if context is None:
125 raise exception.Forbidden()
126
127 del self.keys[key_id]
128
129 def _generate_password(self, length, symbolgroups):
130 """Generate a random password from the supplied symbol groups.
131
132 At least one symbol from each group will be included. Unpredictable
133 results if length is less than the number of symbol groups.
134
135 Believed to be reasonably secure (with a reasonable password length!)
136 """
137 # NOTE(jerdfelt): Some password policies require at least one character
138 # from each group of symbols, so start off with one random character
139 # from each symbol group
140 password = [random.choice(s) for s in symbolgroups]
141 # If length < len(symbolgroups), the leading characters will only
142 # be from the first length groups. Try our best to not be predictable
143 # by shuffling and then truncating.
144 random.shuffle(password)
145 password = password[:length]
146 length -= len(password)
147
148 # then fill with random characters from all symbol groups
149 symbols = ''.join(symbolgroups)
150 password.extend([random.choice(symbols) for _i in range(length)])
151
152 # finally shuffle to ensure first x characters aren't from a
153 # predictable group
154 random.shuffle(password)
155
156 return ''.join(password)
0 # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory
1 # All Rights Reserved.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License"); you may
4 # not use this file except in compliance with the License. You may obtain
5 # a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 # License for the specific language governing permissions and limitations
13 # under the License.
14
15 """
16 Test cases for the key classes.
17 """
18
19 import array
20 import binascii
21
22 from castellan.keymgr import symmetric_key as sym_key
23 from castellan.tests import base
24
25
26 class KeyTestCase(base.TestCase):
27
28 def _create_key(self):
29 raise NotImplementedError()
30
31 def setUp(self):
32 super(KeyTestCase, self).setUp()
33
34 self.key = self._create_key()
35
36
37 class SymmetricKeyTestCase(KeyTestCase):
38
39 def _create_key(self):
40 return sym_key.SymmetricKey(self.algorithm, self.encoded)
41
42 def setUp(self):
43 self.algorithm = 'AES'
44 self.encoded = array.array('B', binascii.unhexlify('0' * 64)).tolist()
45
46 super(SymmetricKeyTestCase, self).setUp()
47
48 def test_get_algorithm(self):
49 self.assertEqual(self.key.get_algorithm(), self.algorithm)
50
51 def test_get_format(self):
52 self.assertEqual(self.key.get_format(), 'RAW')
53
54 def test_get_encoded(self):
55 self.assertEqual(self.key.get_encoded(), self.encoded)
56
57 def test___eq__(self):
58 self.assertTrue(self.key == self.key)
59
60 self.assertFalse(self.key is None)
61 self.assertFalse(None == self.key)
62
63 def test___ne__(self):
64 self.assertFalse(self.key != self.key)
65
66 self.assertTrue(self.key is not None)
67 self.assertTrue(None != self.key)
0 # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory
1 # All Rights Reserved.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License"); you may
4 # not use this file except in compliance with the License. You may obtain
5 # a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 # License for the specific language governing permissions and limitations
13 # under the License.
14
15 """
16 Test cases for the key manager.
17 """
18
19 from castellan.tests import base
20
21
22 class KeyManagerTestCase(base.TestCase):
23
24 def _create_key_manager(self):
25 raise NotImplementedError()
26
27 def setUp(self):
28 super(KeyManagerTestCase, self).setUp()
29
30 self.key_mgr = self._create_key_manager()
0 # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory
1 # All Rights Reserved.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License"); you may
4 # not use this file except in compliance with the License. You may obtain
5 # a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 # License for the specific language governing permissions and limitations
13 # under the License.
14
15 """
16 Test cases for the mock key manager.
17 """
18
19 import array
20 import binascii
21
22 from castellan.common import exception
23 from castellan import context
24 from castellan.keymgr import symmetric_key as sym_key
25 from castellan.tests.keymgr import mock_key_mgr
26 from castellan.tests.keymgr import test_key_mgr
27
28
29 class MockKeyManagerTestCase(test_key_mgr.KeyManagerTestCase):
30
31 def _create_key_manager(self):
32 return mock_key_mgr.MockKeyManager()
33
34 def setUp(self):
35 super(MockKeyManagerTestCase, self).setUp()
36
37 self.context = context.RequestContext('fake', 'fake')
38
39 def test_create_key(self):
40 key_id_1 = self.key_mgr.create_key(self.context)
41 key_id_2 = self.key_mgr.create_key(self.context)
42 # ensure that the UUIDs are unique
43 self.assertNotEqual(key_id_1, key_id_2)
44
45 def test_create_key_with_length(self):
46 for length in [64, 128, 256]:
47 key_id = self.key_mgr.create_key(self.context, key_length=length)
48 key = self.key_mgr.get_key(self.context, key_id)
49 self.assertEqual(length / 8, len(key.get_encoded()))
50
51 def test_create_null_context(self):
52 self.assertRaises(exception.Forbidden,
53 self.key_mgr.create_key, None)
54
55 def test_store_and_get_key(self):
56 secret_key = array.array('B', binascii.unhexlify('0' * 64)).tolist()
57 _key = sym_key.SymmetricKey('AES', secret_key)
58 key_id = self.key_mgr.store_key(self.context, _key)
59
60 actual_key = self.key_mgr.get_key(self.context, key_id)
61 self.assertEqual(_key, actual_key)
62
63 def test_store_null_context(self):
64 self.assertRaises(exception.Forbidden,
65 self.key_mgr.store_key, None, None)
66
67 def test_copy_key(self):
68 key_id = self.key_mgr.create_key(self.context)
69 key = self.key_mgr.get_key(self.context, key_id)
70
71 copied_key_id = self.key_mgr.copy_key(self.context, key_id)
72 copied_key = self.key_mgr.get_key(self.context, copied_key_id)
73
74 self.assertNotEqual(key_id, copied_key_id)
75 self.assertEqual(key, copied_key)
76
77 def test_copy_null_context(self):
78 self.assertRaises(exception.Forbidden,
79 self.key_mgr.copy_key, None, None)
80
81 def test_get_null_context(self):
82 self.assertRaises(exception.Forbidden,
83 self.key_mgr.get_key, None, None)
84
85 def test_get_unknown_key(self):
86 self.assertRaises(KeyError, self.key_mgr.get_key, self.context, None)
87
88 def test_delete_key(self):
89 key_id = self.key_mgr.create_key(self.context)
90 self.key_mgr.delete_key(self.context, key_id)
91
92 self.assertRaises(KeyError, self.key_mgr.get_key, self.context,
93 key_id)
94
95 def test_delete_null_context(self):
96 self.assertRaises(exception.Forbidden,
97 self.key_mgr.delete_key, None, None)
98
99 def test_delete_unknown_key(self):
100 self.assertRaises(KeyError, self.key_mgr.delete_key, self.context,
101 None)
0 # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory
1 # All Rights Reserved.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License"); you may
4 # not use this file except in compliance with the License. You may obtain
5 # a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 # License for the specific language governing permissions and limitations
13 # under the License.
14
15 """
16 Test cases for the not implemented key manager.
17 """
18
19 from castellan.keymgr import not_implemented_key_mgr
20 from castellan.tests.keymgr import test_key_mgr
21
22
23 class NotImplementedKeyManagerTestCase(test_key_mgr.KeyManagerTestCase):
24
25 def _create_key_manager(self):
26 return not_implemented_key_mgr.NotImplementedKeyManager()
27
28 def test_create_key(self):
29 self.assertRaises(NotImplementedError,
30 self.key_mgr.create_key, None)
31
32 def test_store_key(self):
33 self.assertRaises(NotImplementedError,
34 self.key_mgr.store_key, None, None)
35
36 def test_copy_key(self):
37 self.assertRaises(NotImplementedError,
38 self.key_mgr.copy_key, None, None)
39
40 def test_get_key(self):
41 self.assertRaises(NotImplementedError,
42 self.key_mgr.get_key, None, None)
43
44 def test_delete_key(self):
45 self.assertRaises(NotImplementedError,
46 self.key_mgr.delete_key, None, None)
33
44 pbr>=0.6,!=0.7,<1.0
55 Babel>=1.3
6 oslo.config>=1.6.0 # Apache-2.0
7 oslo.serialization>=1.2.0 # Apache-2.0
8 oslo.utils>=1.2.0 # Apache-2.0