Codebase list python-castellan / 4271073
Merge tag '0.4.0' into debian/mitaka castellan 0.4.0 release Thomas Goirand 8 years ago
41 changed file(s) with 2181 addition(s) and 178 deletion(s). Raw diff Collapse all Expand all
+0
-6
MANIFEST.in less more
0 include AUTHORS
1 include ChangeLog
2 exclude .gitignore
3 exclude .gitreview
4
5 global-exclude *.pyc
0 # Copyright (c) IBM
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 Credential Object Class
17
18 This module defines the Credential class. The Credential class is the base
19 class to represent all credentials which a KeyMaster can use for
20 authenticating.
21 """
22
23 import abc
24
25 import six
26
27
28 @six.add_metaclass(abc.ABCMeta)
29 class Credential(object):
30 """Base class to represent all credentials."""
31
32 def __init__(self):
33 pass
0 # Copyright (c) 2015 IBM
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 Keystone Password Credential
16
17 This module defines the Keystone Password credential.
18 """
19 from castellan.common.credentials import password
20
21
22 class KeystonePassword(password.Password):
23 """This class represents a keystone password credential."""
24
25 def __init__(self, password, username=None, user_id=None,
26 user_domain_id=None, user_domain_name=None, trust_id=None,
27 domain_id=None, domain_name=None, project_id=None,
28 project_name=None, project_domain_id=None,
29 project_domain_name=None, reauthenticate=True):
30 """Create a new Keystone Password Credential.
31
32 :param string password: Password for authentication.
33 :param string username: Username for authentication.
34 :param string user_id: User ID for authentication.
35 :param string user_domain_id: User's domain ID for authentication.
36 :param string user_domain_name: User's domain name for authentication.
37 :param string trust_id: Trust ID for trust scoping.
38 :param string domain_id: Domain ID for domain scoping.
39 :param string domain_name: Domain name for domain scoping.
40 :param string project_id: Project ID for project scoping.
41 :param string project_name: Project name for project scoping.
42 :param string project_domain_id: Project's domain ID for project.
43 :param string project_domain_name: Project's domain name for project.
44 :param bool reauthenticate: Allow fetching a new token if the current
45 one is going to expire. (optional) default True
46 """
47
48 self._user_id = user_id
49 self._user_domain_id = user_domain_id
50 self._user_domain_name = user_domain_name
51 self._trust_id = trust_id
52 self._domain_id = domain_id
53 self._domain_name = domain_name
54 self._project_id = project_id
55 self._project_name = project_name
56 self._project_domain_id = project_domain_id
57 self._project_domain_name = project_domain_name
58 self._reauthenticate = reauthenticate
59
60 super(KeystonePassword, self).__init__(username,
61 password)
62
63 @property
64 def user_id(self):
65 """This method returns a user_id."""
66 return self._user_id
67
68 @property
69 def user_domain_id(self):
70 """This method returns a user_domain_id."""
71 return self._user_domain_id
72
73 @property
74 def user_domain_name(self):
75 """This method returns a user_domain_name."""
76 return self._user_domain_name
77
78 @property
79 def trust_id(self):
80 """This method returns a trust_id."""
81 return self._trust_id
82
83 @property
84 def domain_id(self):
85 """This method returns a domain_id."""
86 return self._domain_id
87
88 @property
89 def domain_name(self):
90 """This method returns a domain_name."""
91 return self._domain_name
92
93 @property
94 def project_id(self):
95 """This method returns a project_id."""
96 return self._project_id
97
98 @property
99 def project_name(self):
100 """This method returns a project_name."""
101 return self._project_name
102
103 @property
104 def project_domain_id(self):
105 """This method returns a project_domain_id."""
106 return self._project_domain_id
107
108 @property
109 def project_domain_name(self):
110 """This method returns a project_domain_name."""
111 return self._project_domain_name
112
113 @property
114 def reauthenticate(self):
115 """This method returns reauthenticate."""
116 return self._reauthenticate
117
118 def __eq__(self, other):
119 if isinstance(other, KeystonePassword):
120 return (
121 self._password == other._password and
122 self._username == other._username and
123 self._user_id == other._user_id and
124 self._user_domain_id == other._user_domain_id and
125 self._user_domain_name == other._user_domain_name and
126 self._trust_id == other._trust_id and
127 self._domain_id == other._domain_id and
128 self._domain_name == other._domain_name and
129 self._project_id == other._project_id and
130 self._project_name == other._project_name and
131 self._project_domain_id == other._project_domain_id and
132 self._project_domain_name == other._project_domain_name and
133 self._reauthenticate == other._reauthenticate)
134 else:
135 return False
136
137 def __ne__(self, other):
138 result = self.__eq__(other)
139 return not result
0 # Copyright (c) 2015 IBM
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 Keystone Token Credential
16
17 This module defines the Keystone Token credential.
18 """
19 from castellan.common.credentials import token
20
21
22 class KeystoneToken(token.Token):
23 """This class represents a keystone token credential."""
24
25 def __init__(self, token, trust_id=None, domain_id=None, domain_name=None,
26 project_id=None, project_name=None, project_domain_id=None,
27 project_domain_name=None, reauthenticate=True):
28 """Create a new Keystone Token Credential.
29
30 :param string token: Token for authentication. The type of token
31 formats accepted are UUID, PKI, and Fernet.
32 :param string trust_id: Trust ID for trust scoping.
33 :param string domain_id: Domain ID for domain scoping.
34 :param string domain_name: Domain name for domain scoping.
35 :param string project_id: Project ID for project scoping.
36 :param string project_name: Project name for project scoping.
37 :param string project_domain_id: Project's domain ID for project.
38 :param string project_domain_name: Project's domain name for project.
39 :param bool reauthenticate: Allow fetching a new token if the current
40 one is going to expire. (optional) default True
41 """
42
43 self._trust_id = trust_id
44 self._domain_id = domain_id
45 self._domain_name = domain_name
46 self._project_id = project_id
47 self._project_name = project_name
48 self._project_domain_id = project_domain_id
49 self._project_domain_name = project_domain_name
50 self._reauthenticate = reauthenticate
51
52 super(KeystoneToken, self).__init__(token)
53
54 @property
55 def trust_id(self):
56 """This method returns a trust_id."""
57 return self._trust_id
58
59 @property
60 def domain_id(self):
61 """This method returns a domain_id."""
62 return self._domain_id
63
64 @property
65 def domain_name(self):
66 """This method returns a domain_name."""
67 return self._domain_name
68
69 @property
70 def project_id(self):
71 """This method returns a project_id."""
72 return self._project_id
73
74 @property
75 def project_name(self):
76 """This method returns a project_name."""
77 return self._project_name
78
79 @property
80 def project_domain_id(self):
81 """This method returns a project_domain_id."""
82 return self._project_domain_id
83
84 @property
85 def project_domain_name(self):
86 """This method returns a project_domain_name."""
87 return self._project_domain_name
88
89 @property
90 def reauthenticate(self):
91 """This method returns reauthenticate."""
92 return self._reauthenticate
93
94 def __eq__(self, other):
95 if isinstance(other, KeystoneToken):
96 return (
97 self._token == other._token and
98 self._trust_id == other._trust_id and
99 self._domain_id == other._domain_id and
100 self._domain_name == other._domain_name and
101 self._project_id == other._project_id and
102 self._project_name == other._project_name and
103 self._project_domain_id == other._project_domain_id and
104 self._project_domain_name == other._project_domain_name and
105 self._reauthenticate == other._reauthenticate)
106 else:
107 return False
108
109 def __ne__(self, other):
110 result = self.__eq__(other)
111 return not result
0 # Copyright (c) 2015 IBM
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 Base Password Credential
16
17 This module defines the Password credential.
18 """
19
20 from castellan.common.credentials import credential
21
22
23 class Password(credential.Credential):
24 """This class represents a password credential."""
25
26 def __init__(self, username, password):
27 """Create a new Password credential.
28
29 :param string password: Password for authentication.
30 :param string username: Username for authentication.
31 """
32
33 self._username = username
34 self._password = password
35
36 @property
37 def username(self):
38 """This method returns a username."""
39 return self._username
40
41 @property
42 def password(self):
43 """This method returns a password."""
44 return self._password
45
46 def __eq__(self, other):
47 if isinstance(other, Password):
48 return (self._username == other._username and
49 self._password == other._password)
50 else:
51 return False
52
53 def __ne__(self, other):
54 result = self.__eq__(other)
55 return not result
0 # Copyright (c) 2015 IBM
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 Base Token Credential
16
17 This module defines the Token credential.
18 """
19
20 from castellan.common.credentials import credential
21
22
23 class Token(credential.Credential):
24 """This class represents a token credential."""
25
26 def __init__(self, token):
27 """Create a new Token credential.
28
29 :param string token: Token for authentication.
30 """
31
32 self._token = token
33
34 @property
35 def token(self):
36 """This method returns a token."""
37 return self._token
38
39 def __eq__(self, other):
40 if isinstance(other, Token):
41 return (self._token == other._token)
42 else:
43 return False
44
45 def __ne__(self, other):
46 result = self.__eq__(other)
47 return not result
6161
6262 class ManagedObjectNotFoundError(CastellanException):
6363 message = u._("Key not found, uuid: %(uuid)s")
64
65
66 class AuthTypeInvalidError(CastellanException):
67 message = u._("Invalid auth_type was specified, auth_type: %(type)s")
68
69
70 class InsufficientCredentialDataError(CastellanException):
71 message = u._("Insufficient credential data was provided, either "
72 "\"token\" must be set in the passed conf, or a context "
73 "with an \"auth_token\" property must be passed.")
1818 This module defines the ManagedObject class. The ManagedObject class
1919 is the base class to represent all objects managed by the key manager.
2020 """
21
2221 import abc
2322
2423 import six
2827 class ManagedObject(object):
2928 """Base class to represent all managed objects."""
3029
31 def __init__(self, name=None):
32 """Managed Object has a name, defaulted to None."""
30 def __init__(self, name=None, created=None):
31 """Managed Object
32
33 :param name: the name of the managed object.
34 :param created: the time a managed object was created.
35 """
3336 self._name = name
37
38 # If None or POSIX times
39 if not created or type(created) == int:
40 self._created = created
41 else:
42 raise ValueError('created must be of long type, actual type %s' %
43 type(created))
3444
3545 @property
3646 def name(self):
3949 Returns the object's name or None if this object does not have one.
4050 """
4151 return self._name
52
53 @property
54 def created(self):
55 """Returns the POSIX time(long) of the object that was created.
56
57 Returns the POSIX time(long) of the object that was created or None if
58 the object does not have one, meaning it has not been persisted.
59 """
60 return self._created
4261
4362 @abc.abstractproperty
4463 def format(self):
2424 class OpaqueData(managed_object.ManagedObject):
2525 """This class represents opaque data."""
2626
27 def __init__(self, data, name=None):
27 def __init__(self, data, name=None, created=None):
2828 """Create a new OpaqueData object.
2929
3030 Expected type for data is a bytestring.
3131 """
3232 self._data = data
33 super(OpaqueData, self).__init__(name=name)
33 super(OpaqueData, self).__init__(name=name, created=created)
3434
3535 @property
3636 def format(self):
4343
4444 def __eq__(self, other):
4545 if isinstance(other, OpaqueData):
46 return (self._data == other._data and
47 self._name == other._name)
46 return (self._data == other._data)
4847 else:
4948 return False
5049
2424 class Passphrase(managed_object.ManagedObject):
2525 """This class represents a passphrase."""
2626
27 def __init__(self, passphrase, name=None):
27 def __init__(self, passphrase, name=None, created=None):
2828 """Create a new Passphrase object.
2929
3030 The expected type for the passphrase is a bytestring.
3131 """
3232 self._passphrase = passphrase
33 super(Passphrase, self).__init__(name=name)
33 super(Passphrase, self).__init__(name=name, created=created)
3434
3535 @property
3636 def format(self):
4343
4444 def __eq__(self, other):
4545 if isinstance(other, Passphrase):
46 return (self._passphrase == other._passphrase and
47 self._name == other._name)
46 return (self._passphrase == other._passphrase)
4847 else:
4948 return False
5049
2424 class PrivateKey(key.Key):
2525 """This class represents private keys."""
2626
27 def __init__(self, algorithm, bit_length, key, name=None):
27 def __init__(self, algorithm, bit_length, key,
28 name=None, created=None):
2829 """Create a new PrivateKey object.
2930
3031 The arguments specify the algorithm and bit length for the asymmetric
3334 self._alg = algorithm
3435 self._bit_length = bit_length
3536 self._key = key
36 super(PrivateKey, self).__init__(name=name)
37 super(PrivateKey, self).__init__(name=name, created=created)
3738
3839 @property
3940 def algorithm(self):
5859 if isinstance(other, PrivateKey):
5960 return (self._alg == other._alg and
6061 self._bit_length == other._bit_length and
61 self._key == other._key and
62 self._name == other._name)
62 self._key == other._key)
6363 else:
6464 return False
6565
2424 class PublicKey(key.Key):
2525 """This class represents public keys."""
2626
27 def __init__(self, algorithm, bit_length, key, name=None):
27 def __init__(self, algorithm, bit_length, key,
28 name=None, created=None):
2829 """Create a new PublicKey object.
2930
3031 The arguments specify the algorithm and bit length for the asymmetric
3435 self._alg = algorithm
3536 self._bit_length = bit_length
3637 self._key = key
37 super(PublicKey, self).__init__(name=name)
38 super(PublicKey, self).__init__(name=name, created=created)
3839
3940 @property
4041 def algorithm(self):
5960 if isinstance(other, PublicKey):
6061 return (self._alg == other._alg and
6162 self._bit_length == other._bit_length and
62 self._key == other._key and
63 self._name == other._name)
63 self._key == other._key)
6464 else:
6565 return False
6666
2424 class SymmetricKey(key.Key):
2525 """This class represents symmetric keys."""
2626
27 def __init__(self, algorithm, bit_length, key, name=None):
27 def __init__(self, algorithm, bit_length, key,
28 name=None, created=None):
2829 """Create a new SymmetricKey object.
2930
3031 The arguments specify the algorithm and bit length for the symmetric
3334 self._alg = algorithm
3435 self._bit_length = bit_length
3536 self._key = key
36 super(SymmetricKey, self).__init__(name=name)
37 super(SymmetricKey, self).__init__(name=name, created=created)
3738
3839 @property
3940 def algorithm(self):
5859 if isinstance(other, SymmetricKey):
5960 return (self._alg == other._alg and
6061 self._bit_length == other._bit_length and
61 self._key == other._key and
62 self._name == other._name)
62 self._key == other._key)
6363 else:
6464 return False
6565
2424 class X509(certificate.Certificate):
2525 """This class represents X.509 certificates."""
2626
27 def __init__(self, data, name=None):
27 def __init__(self, data, name=None, created=None):
2828 """Create a new X509 object.
2929
3030 The data should be in a bytestring.
3131 """
3232 self._data = data
33 super(X509, self).__init__(name=name)
33 super(X509, self).__init__(name=name, created=created)
3434
3535 @property
3636 def format(self):
4343
4444 def __eq__(self, other):
4545 if isinstance(other, X509):
46 return (self._data == other._data and
47 self._name == other._name)
46 return (self._data == other._data)
4847 else:
4948 return False
5049
0 # Copyright (c) 2016 IBM
1 # Licensed under the Apache License, Version 2.0 (the "License");
2 # you may not use this file except in compliance with the License.
3 # You may obtain a copy of the License at
4 #
5 # http://www.apache.org/licenses/LICENSE-2.0
6 #
7 # Unless required by applicable law or agreed to in writing, software
8 # distributed under the License is distributed on an "AS IS" BASIS,
9 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
10 # implied.
11 # See the License for the specific language governing permissions and
12 # limitations under the License.
13
14 """
15 Common utilities for Castellan.
16 """
17
18 from castellan.common.credentials import keystone_password
19 from castellan.common.credentials import keystone_token
20 from castellan.common.credentials import password
21 from castellan.common.credentials import token
22 from castellan.common import exception
23
24 from oslo_config import cfg
25 from oslo_log import log as logging
26
27
28 LOG = logging.getLogger(__name__)
29
30 credential_opts = [
31 # auth_type opt
32 cfg.StrOpt('auth_type', default=None,
33 help="The type of authentication credential to create. "
34 "Possible values are 'token', 'password', 'keystone_token', "
35 "and 'keystone_password'. Required if no context is passed to "
36 "the credential factory."),
37
38 # token opt
39 cfg.StrOpt('token', default=None,
40 help="Token for authentication. Required for 'token' and "
41 "'keystone_token' auth_type if no context is passed to the "
42 "credential factory."),
43
44 # password opts
45 cfg.StrOpt('username', default=None,
46 help="Username for authentication. Required for 'password' "
47 "auth_type. Optional for the 'keystone_password' auth_type."),
48 cfg.StrOpt('password', default=None,
49 help="Password for authentication. Required for 'password' and "
50 "'keystone_password' auth_type."),
51
52 # keystone credential opts
53 cfg.StrOpt('user_id', default=None,
54 help="User ID for authentication. Optional for "
55 "'keystone_token' and 'keystone_password' auth_type."),
56 cfg.StrOpt('user_domain_id', default=None,
57 help="User's domain ID for authentication. Optional for "
58 "'keystone_token' and 'keystone_password' auth_type."),
59 cfg.StrOpt('user_domain_name', default=None,
60 help="User's domain name for authentication. Optional for "
61 "'keystone_token' and 'keystone_password' auth_type."),
62 cfg.StrOpt('trust_id', default=None,
63 help="Trust ID for trust scoping. Optional for "
64 "'keystone_token' and 'keystone_password' auth_type."),
65 cfg.StrOpt('domain_id', default=None,
66 help="Domain ID for domain scoping. Optional for "
67 "'keystone_token' and 'keystone_password' auth_type."),
68 cfg.StrOpt('domain_name', default=None,
69 help="Domain name for domain scoping. Optional for "
70 "'keystone_token' and 'keystone_password' auth_type."),
71 cfg.StrOpt('project_id', default=None,
72 help="Project ID for project scoping. Optional for "
73 "'keystone_token' and 'keystone_password' auth_type."),
74 cfg.StrOpt('project_name', default=None,
75 help="Project name for project scoping. Optional for "
76 "'keystone_token' and 'keystone_password' auth_type."),
77 cfg.StrOpt('project_domain_id', default=None,
78 help="Project's domain ID for project. Optional for "
79 "'keystone_token' and 'keystone_password' auth_type."),
80 cfg.StrOpt('project_domain_name', default=None,
81 help="Project's domain name for project. Optional for "
82 "'keystone_token' and 'keystone_password' auth_type."),
83 cfg.BoolOpt('reauthenticate', default=True,
84 help="Allow fetching a new token if the current one is "
85 "going to expire. Optional for 'keystone_token' and "
86 "'keystone_password' auth_type.")
87 ]
88
89 OPT_GROUP = 'key_manager'
90
91
92 def credential_factory(conf=None, context=None):
93 """This function provides a factory for credentials.
94
95 It is used to create an appropriare credential object
96 from a passed configuration. This should be called before
97 making any calls to a key manager.
98
99 :param conf: Configuration file which this factory method uses
100 to generate a credential object. Note: In the future it will
101 become a required field.
102 :param context: Context used for authentication. It can be used
103 in conjunction with the configuration file. If no conf is passed,
104 then the context object will be converted to a KeystoneToken and
105 returned. If a conf is passed then only the 'token' is grabbed from
106 the context for the authentication types that require a token.
107 :returns: A credential object used for authenticating with the
108 Castellan key manager. Type of credential returned depends on
109 config and/or context passed.
110 """
111 if conf:
112 conf.register_opts(credential_opts, group=OPT_GROUP)
113
114 if conf.key_manager.auth_type == 'token':
115 if conf.key_manager.token:
116 auth_token = conf.key_manager.token
117 elif context:
118 auth_token = context.auth_token
119 else:
120 raise exception.InsufficientCredentialDataError()
121
122 return token.Token(auth_token)
123
124 elif conf.key_manager.auth_type == 'password':
125 return password.Password(
126 conf.key_manager.username,
127 conf.key_manager.password)
128
129 elif conf.key_manager.auth_type == 'keystone_password':
130 return keystone_password.KeystonePassword(
131 conf.key_manager.password,
132 username=conf.key_manager.username,
133 user_id=conf.key_manager.user_id,
134 user_domain_id=conf.key_manager.user_domain_id,
135 user_domain_name=conf.key_manager.user_domain_name,
136 trust_id=conf.key_manager.trust_id,
137 domain_id=conf.key_manager.domain_id,
138 domain_name=conf.key_manager.domain_name,
139 project_id=conf.key_manager.project_id,
140 project_name=conf.key_manager.project_name,
141 project_domain_id=conf.key_manager.domain_id,
142 project_domain_name=conf.key_manager.domain_name,
143 reauthenticate=conf.key_manager.reauthenticate)
144
145 elif conf.key_manager.auth_type == 'keystone_token':
146 if conf.key_manager.token:
147 auth_token = conf.key_manager.token
148 elif context:
149 auth_token = context.auth_token
150 else:
151 raise exception.InsufficientCredentialDataError()
152
153 return keystone_token.KeystoneToken(
154 auth_token,
155 trust_id=conf.key_manager.trust_id,
156 domain_id=conf.key_manager.domain_id,
157 domain_name=conf.key_manager.domain_name,
158 project_id=conf.key_manager.project_id,
159 project_name=conf.key_manager.project_name,
160 project_domain_id=conf.key_manager.domain_id,
161 project_domain_name=conf.key_manager.domain_name,
162 reauthenticate=conf.key_manager.reauthenticate)
163
164 else:
165 LOG.error("Invalid auth_type specified.")
166 raise exception.AuthTypeInvalidError(
167 type=conf.key_manager.auth_type)
168
169 # for compatibility between _TokenData and RequestContext
170 if hasattr(context, 'tenant') and context.tenant:
171 project_id = context.tenant
172 elif hasattr(context, 'project_id') and context.project_id:
173 project_id = context.project_id
174
175 return keystone_token.KeystoneToken(
176 context.auth_token,
177 project_id=project_id)
2727 conf.register_opts(key_manager_opts, group='key_manager')
2828
2929 cls = importutils.import_class(conf.key_manager.api_class)
30 return cls(configuration=conf)
30 return cls(configuration=conf)
1515 """
1616 Key manager implementation for Barbican
1717 """
18 import calendar
1819 import time
1920
2021 from cryptography.hazmat import backends
3940
4041 from barbicanclient import client as barbican_client
4142 from barbicanclient import exceptions as barbican_exceptions
43 from oslo_utils import timeutils
4244 from six.moves import urllib
45
4346
4447 barbican_opts = [
4548 cfg.StrOpt('barbican_endpoint',
99102 LOG.error(msg)
100103 raise exception.Forbidden(msg)
101104
102 if not hasattr(context, 'tenant') or context.tenant is None:
103 msg = u._("Unable to create Barbican Client without tenant "
104 "attribute in context object.")
105 LOG.error(msg)
106 raise exception.KeyManagerError(reason=msg)
107
108105 if self._barbican_client and self._current_context == context:
109106 return self._barbican_client
110107
111108 try:
112 self._current_context = context
113109 auth = self._get_keystone_auth(context)
114110 sess = session.Session(auth=auth)
115111
117113 self._barbican_client = barbican_client.Client(
118114 session=sess,
119115 endpoint=self._barbican_endpoint)
116 self._current_context = context
120117
121118 except Exception as e:
122119 LOG.error(u._LE("Error creating Barbican client: %s"), e)
129126 return self._barbican_client
130127
131128 def _get_keystone_auth(self, context):
132 # TODO(kfarr): support keystone v2
133 auth = identity.v3.Token(
134 auth_url=self.conf.barbican.auth_endpoint,
135 token=context.auth_token,
136 project_id=context.tenant,
137 domain_id=context.user_domain,
138 project_domain_id=context.project_domain)
139 return auth
129 auth_url = self.conf.barbican.auth_endpoint
130
131 if context.__class__.__name__ is 'KeystonePassword':
132 return identity.v3.Password(
133 auth_url=auth_url,
134 username=context.username,
135 password=context.password,
136 user_id=context.user_id,
137 user_domain_id=context.user_domain_id,
138 user_domain_name=context.user_domain_name,
139 trust_id=context.trust_id,
140 domain_id=context.domain_id,
141 domain_name=context.domain_name,
142 project_id=context.project_id,
143 project_name=context.project_name,
144 project_domain_id=context.project_domain_id,
145 project_domain_name=context.project_domain_name,
146 reauthenticate=context.reauthenticate)
147 elif context.__class__.__name__ is 'KeystoneToken':
148 return identity.v3.Token(
149 auth_url=auth_url,
150 token=context.token,
151 trust_id=context.trust_id,
152 domain_id=context.domain_id,
153 domain_name=context.domain_name,
154 project_id=context.project_id,
155 project_name=context.project_name,
156 project_domain_id=context.project_domain_id,
157 project_domain_name=context.project_domain_name,
158 reauthenticate=context.reauthenticate)
159 # this will be kept for oslo.context compatibility until
160 # projects begin to use utils.credential_factory
161 elif context.__class__.__name__ is 'RequestContext':
162 return identity.v3.Token(
163 auth_url=auth_url,
164 token=context.auth_token,
165 project_id=context.tenant)
166 else:
167 msg = "context must be of type KeystonePassword, KeystoneToken, "
168 "or RequestContext."
169 LOG.error(msg)
170 raise exception.Forbidden(reason=msg)
140171
141172 def _get_barbican_endpoint(self, auth, sess):
142173 if self.conf.barbican.barbican_endpoint:
332363 Barbican key creation is done asynchronously, so this loop continues
333364 checking until the order is active or a timeout occurs.
334365 """
335 active = u'ACTIVE'
366 active_status = u'ACTIVE'
367 error_status = u'ERROR'
336368 number_of_retries = self.conf.barbican.number_of_retries
337369 retry_delay = self.conf.barbican.retry_delay
338370 order = barbican_client.orders.get(order_ref)
339371 time.sleep(.25)
340372 for n in range(number_of_retries):
341 if order.status != active:
373 if order.status == error_status:
374 kwargs = {"status": error_status,
375 "code": order.error_status_code,
376 "reason": order.error_reason}
377 msg = u._LE("Order is in %(status)s status - status code: "
378 "%(code)s, status reason: %(reason)s") % kwargs
379 LOG.error(msg)
380 raise exception.KeyManagerError(reason=msg)
381 if order.status != active_status:
342382 kwargs = {'attempt': n,
343383 'total': number_of_retries,
344384 'status': order.status,
345 'active': active,
385 'active': active_status,
346386 'delay': retry_delay}
347387 msg = u._LI("Retry attempt #%(attempt)i out of %(total)i: "
348388 "Order status is '%(status)s'. Waiting for "
354394 else:
355395 return order
356396 msg = u._LE("Exceeded retries: Failed to find '%(active)s' status "
357 "within %(num_retries)i retries") % {'active': active,
358 'num_retries':
359 number_of_retries}
397 "within %(num_retries)i retries") % {
398 'active': active_status,
399 'num_retries': number_of_retries}
360400 LOG.error(msg)
361401 raise exception.KeyManagerError(reason=msg)
362402
420460
421461 secret_data = self._get_secret_data(secret)
422462
463 # convert created ISO8601 in Barbican to POSIX
464 if secret.created:
465 time_stamp = timeutils.parse_isotime(
466 str(secret.created)).timetuple()
467 created = calendar.timegm(time_stamp)
468
423469 if issubclass(secret_type, key_base_class.Key):
424470 return secret_type(secret.algorithm,
425471 secret.bit_length,
426472 secret_data,
427 secret.name)
473 secret.name,
474 created)
428475 else:
429476 return secret_type(secret_data,
430 secret.name)
477 secret.name,
478 created)
431479
432480 def _get_secret(self, context, object_id):
433481 """Returns the metadata of the secret.
1919 from castellan.key_manager import barbican_key_manager as bkm
2020 except ImportError:
2121 bkm = None
22 from castellan.common import utils
2223
2324 _DEFAULT_LOG_LEVELS = ['castellan=WARN']
2425
9394
9495 :returns: a list of (group_name, opts) tuples
9596 """
96 opts = [('key_manager', km.key_manager_opts)]
97 key_manager_opts = []
98 key_manager_opts.extend(km.key_manager_opts)
99 key_manager_opts.extend(utils.credential_opts)
100 opts = [('key_manager', key_manager_opts)]
101
97102 if bkm is not None:
98103 opts.append((bkm.BARBICAN_OPT_GROUP, bkm.barbican_opts))
99104 return opts
2020
2121 identity_group = cfg.OptGroup(name='identity')
2222 identity_options = [
23 cfg.StrOpt('uri',
23 cfg.StrOpt('auth_url',
2424 default='http://localhost:5000/v3',
2525 help='Keystone endpoint'),
2626 cfg.StrOpt('username',
3131 help='Password used with Keystone username'),
3232 cfg.StrOpt('project_name',
3333 default='admin',
34 help='Name of project, used by the given username')]
34 help='Name of project, used by the given username'),
35 cfg.StrOpt('user_domain_name',
36 default='Default',
37 help='Name of domain, used by the given username'),
38 cfg.StrOpt('project_domain_name',
39 default='Default',
40 help='Name of domain, used by the given project')]
3541
3642
3743 def setup_config(config_file=''):
4349
4450 config_to_load = []
4551 local_config = './../../../etc/castellan/castellan-functional.conf'
52 main_config = '/etc/castellan/castellan-functional.conf'
4653 if os.path.isfile(config_file):
4754 config_to_load.append(config_file)
4855 elif os.path.isfile(local_config):
4956 config_to_load.append(local_config)
50 else:
51 config_to_load.append('/etc/castellan/castellan-functional.conf')
57 elif os.path.isfile(main_config):
58 config_to_load.append(main_config)
5259
5360 TEST_CONF(
5461 (), # Required to load an anonymous config
2020
2121 import uuid
2222
23 from keystoneclient.auth.identity import v3
24 from keystoneclient import session
2325 from keystoneclient.v3 import client
2426 from oslo_config import cfg
2527 from oslo_context import context
2628 from oslotest import base
2729
30 from castellan.common.credentials import keystone_password
31 from castellan.common.credentials import keystone_token
2832 from castellan.common import exception
2933 from castellan.key_manager import barbican_key_manager
3034 from castellan.tests.functional import config
4549 username = CONF.identity.username
4650 password = CONF.identity.password
4751 project_name = CONF.identity.project_name
48 auth_url = CONF.identity.uri
49 keystone_client = client.Client(username=username,
50 password=password,
51 project_name=project_name,
52 auth_url=auth_url,
53 project_domain_id='default')
52 auth_url = CONF.identity.auth_url
53 user_domain_name = CONF.identity.user_domain_name
54 project_domain_name = CONF.identity.project_domain_name
55
56 auth = v3.Password(auth_url=auth_url,
57 username=username,
58 password=password,
59 project_name=project_name,
60 user_domain_name=user_domain_name,
61 project_domain_name=project_domain_name)
62 sess = session.Session(auth=auth)
63 keystone_client = client.Client(session=sess)
64
5465 project_list = keystone_client.projects.list(name=project_name)
5566
5667 self.ctxt = context.RequestContext(
57 auth_token=keystone_client.auth_token,
68 auth_token=auth.auth_ref.auth_token,
5869 tenant=project_list[0].id)
5970
6071 def tearDown(self):
104115
105116 self.assertRaises(exception.Forbidden,
106117 self.key_mgr.store, None, key)
118
119
120 class BarbicanKeyManagerKSPasswordTestCase(test_key_manager.KeyManagerTestCase,
121 base.BaseTestCase):
122
123 def _create_key_manager(self):
124 return barbican_key_manager.BarbicanKeyManager(cfg.CONF)
125
126 def setUp(self):
127 super(BarbicanKeyManagerKSPasswordTestCase, self).setUp()
128 username = CONF.identity.username
129 password = CONF.identity.password
130 project_name = CONF.identity.project_name
131 user_domain_name = CONF.identity.user_domain_name
132 project_domain_name = CONF.identity.project_domain_name
133
134 self.ctxt = keystone_password.KeystonePassword(
135 username=username,
136 password=password,
137 project_name=project_name,
138 user_domain_name=user_domain_name,
139 project_domain_name=project_domain_name)
140
141 def tearDown(self):
142 super(BarbicanKeyManagerKSPasswordTestCase, self).tearDown()
143
144 def test_create_null_context(self):
145 self.assertRaises(exception.Forbidden,
146 self.key_mgr.create_key, None, 'AES', 256)
147
148 def test_create_key_pair_null_context(self):
149 self.assertRaises(exception.Forbidden,
150 self.key_mgr.create_key_pair, None, 'RSA', 2048)
151
152 def test_delete_null_context(self):
153 key_uuid = self._get_valid_object_uuid(
154 test_key_manager._get_test_symmetric_key())
155 self.addCleanup(self.key_mgr.delete, self.ctxt, key_uuid)
156 self.assertRaises(exception.Forbidden,
157 self.key_mgr.delete, None, key_uuid)
158
159 def test_delete_null_object(self):
160 self.assertRaises(exception.KeyManagerError,
161 self.key_mgr.delete, self.ctxt, None)
162
163 def test_delete_unknown_object(self):
164 unknown_uuid = str(uuid.uuid4())
165 self.assertRaises(exception.ManagedObjectNotFoundError,
166 self.key_mgr.delete, self.ctxt, unknown_uuid)
167
168 def test_get_null_context(self):
169 key_uuid = self._get_valid_object_uuid(
170 test_key_manager._get_test_symmetric_key())
171 self.assertRaises(exception.Forbidden,
172 self.key_mgr.get, None, key_uuid)
173
174 def test_get_null_object(self):
175 self.assertRaises(exception.KeyManagerError,
176 self.key_mgr.get, self.ctxt, None)
177
178 def test_get_unknown_key(self):
179 bad_key_uuid = str(uuid.uuid4())
180 self.assertRaises(exception.ManagedObjectNotFoundError,
181 self.key_mgr.get, self.ctxt, bad_key_uuid)
182
183 def test_store_null_context(self):
184 key = test_key_manager._get_test_symmetric_key()
185
186 self.assertRaises(exception.Forbidden,
187 self.key_mgr.store, None, key)
188
189
190 class BarbicanKeyManagerKSTokenTestCase(test_key_manager.KeyManagerTestCase,
191 base.BaseTestCase):
192
193 def _create_key_manager(self):
194 return barbican_key_manager.BarbicanKeyManager(cfg.CONF)
195
196 def setUp(self):
197 super(BarbicanKeyManagerKSTokenTestCase, self).setUp()
198 username = CONF.identity.username
199 password = CONF.identity.password
200 project_name = CONF.identity.project_name
201 auth_url = CONF.identity.auth_url
202 user_domain_name = CONF.identity.user_domain_name
203 project_domain_name = CONF.identity.project_domain_name
204
205 auth = v3.Password(auth_url=auth_url,
206 username=username,
207 password=password,
208 project_name=project_name,
209 user_domain_name=user_domain_name,
210 project_domain_name=project_domain_name)
211 sess = session.Session(auth=auth)
212 keystone_client = client.Client(session=sess)
213
214 project_list = keystone_client.projects.list(name=project_name)
215
216 self.ctxt = keystone_token.KeystoneToken(
217 token=auth.auth_ref.auth_token,
218 project_id=project_list[0].id)
219
220 def tearDown(self):
221 super(BarbicanKeyManagerKSTokenTestCase, self).tearDown()
222
223 def test_create_null_context(self):
224 self.assertRaises(exception.Forbidden,
225 self.key_mgr.create_key, None, 'AES', 256)
226
227 def test_create_key_pair_null_context(self):
228 self.assertRaises(exception.Forbidden,
229 self.key_mgr.create_key_pair, None, 'RSA', 2048)
230
231 def test_delete_null_context(self):
232 key_uuid = self._get_valid_object_uuid(
233 test_key_manager._get_test_symmetric_key())
234 self.addCleanup(self.key_mgr.delete, self.ctxt, key_uuid)
235 self.assertRaises(exception.Forbidden,
236 self.key_mgr.delete, None, key_uuid)
237
238 def test_delete_null_object(self):
239 self.assertRaises(exception.KeyManagerError,
240 self.key_mgr.delete, self.ctxt, None)
241
242 def test_delete_unknown_object(self):
243 unknown_uuid = str(uuid.uuid4())
244 self.assertRaises(exception.ManagedObjectNotFoundError,
245 self.key_mgr.delete, self.ctxt, unknown_uuid)
246
247 def test_get_null_context(self):
248 key_uuid = self._get_valid_object_uuid(
249 test_key_manager._get_test_symmetric_key())
250 self.assertRaises(exception.Forbidden,
251 self.key_mgr.get, None, key_uuid)
252
253 def test_get_null_object(self):
254 self.assertRaises(exception.KeyManagerError,
255 self.key_mgr.get, self.ctxt, None)
256
257 def test_get_unknown_key(self):
258 bad_key_uuid = str(uuid.uuid4())
259 self.assertRaises(exception.ManagedObjectNotFoundError,
260 self.key_mgr.get, self.ctxt, bad_key_uuid)
261
262 def test_store_null_context(self):
263 key = test_key_manager._get_test_symmetric_key()
264
265 self.assertRaises(exception.Forbidden,
266 self.key_mgr.store, None, key)
0 # Copyright (c) 2015 IBM
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 keystone password credential
17 """
18
19 from castellan.common.credentials import keystone_password
20 from castellan.tests import base
21
22
23 class KeystonePasswordTestCase(base.TestCase):
24
25 def _create_ks_password_credential(self):
26 return keystone_password.KeystonePassword(
27 self.password,
28 username=self.username,
29 user_id=self.user_id,
30 user_domain_id=self.user_domain_id,
31 user_domain_name=self.user_domain_name,
32 trust_id=self.trust_id,
33 domain_id=self.domain_id,
34 domain_name=self.domain_name,
35 project_id=self.project_id,
36 project_name=self.project_name,
37 project_domain_id=self.project_domain_id,
38 project_domain_name=self.project_domain_name,
39 reauthenticate=self.reauthenticate)
40
41 def setUp(self):
42 self.password = "Pa$$w0rd1",
43 self.username = "admin",
44 self.user_id = "1adb2391c009443aa5224b316d4a06ae",
45 self.user_domain_id = "default",
46 self.user_domain_name = "default",
47 self.trust_id = "14b38a8296f144148138466ce9280940",
48 self.domain_id = "default",
49 self.domain_name = "default",
50 self.project_id = "1099302ec608486f9879ba2466c60720",
51 self.project_name = "demo",
52 self.project_domain_id = "default",
53 self.project_domain_name = "default",
54 self.reauthenticate = True
55
56 self.ks_password_credential = self._create_ks_password_credential()
57
58 super(KeystonePasswordTestCase, self).setUp()
59
60 def test_get_password(self):
61 self.assertEqual(self.password,
62 self.ks_password_credential.password)
63
64 def test_get_username(self):
65 self.assertEqual(self.username,
66 self.ks_password_credential.username)
67
68 def test_get_user_id(self):
69 self.assertEqual(self.user_id,
70 self.ks_password_credential.user_id)
71
72 def test_get_user_domain_id(self):
73 self.assertEqual(self.user_domain_id,
74 self.ks_password_credential.user_domain_id)
75
76 def test_get_user_domain_name(self):
77 self.assertEqual(self.user_domain_name,
78 self.ks_password_credential.user_domain_name)
79
80 def test_get_trust_id(self):
81 self.assertEqual(self.trust_id,
82 self.ks_password_credential.trust_id)
83
84 def test_get_domain_id(self):
85 self.assertEqual(self.domain_id,
86 self.ks_password_credential.domain_id)
87
88 def test_get_domain_name(self):
89 self.assertEqual(self.domain_name,
90 self.ks_password_credential.domain_name)
91
92 def test_get_project_id(self):
93 self.assertEqual(self.project_id,
94 self.ks_password_credential.project_id)
95
96 def test_get_project_name(self):
97 self.assertEqual(self.project_name,
98 self.ks_password_credential.project_name)
99
100 def test_get_project_domain_id(self):
101 self.assertEqual(self.project_domain_id,
102 self.ks_password_credential.project_domain_id)
103
104 def test_get_project_domain_name(self):
105 self.assertEqual(self.project_domain_name,
106 self.ks_password_credential.project_domain_name)
107
108 def test_get_reauthenticate(self):
109 self.assertEqual(self.reauthenticate,
110 self.ks_password_credential.reauthenticate)
111
112 def test___eq__(self):
113 self.assertTrue(self.ks_password_credential ==
114 self.ks_password_credential)
115 self.assertTrue(self.ks_password_credential is
116 self.ks_password_credential)
117
118 self.assertFalse(self.ks_password_credential is None)
119 self.assertFalse(None == self.ks_password_credential)
120
121 other_ks_password_credential = keystone_password.KeystonePassword(
122 self.password,
123 username=self.username,
124 user_id=self.user_id,
125 user_domain_id=self.user_domain_id,
126 user_domain_name=self.user_domain_name,
127 trust_id=self.trust_id,
128 domain_id=self.domain_id,
129 domain_name=self.domain_name,
130 project_id=self.project_id,
131 project_name=self.project_name,
132 project_domain_id=self.project_domain_id,
133 project_domain_name=self.project_domain_name,
134 reauthenticate=self.reauthenticate)
135 self.assertTrue(self.ks_password_credential ==
136 other_ks_password_credential)
137 self.assertFalse(self.ks_password_credential is
138 other_ks_password_credential)
139
140 def test___ne___none(self):
141 self.assertTrue(self.ks_password_credential is not None)
142 self.assertTrue(None != self.ks_password_credential)
143
144 def test___ne___password(self):
145 other_password = "wheresmyCat??"
146
147 other_ks_password_credential = keystone_password.KeystonePassword(
148 other_password,
149 username=self.username,
150 user_id=self.user_id,
151 user_domain_id=self.user_domain_id,
152 user_domain_name=self.user_domain_name,
153 trust_id=self.trust_id,
154 domain_id=self.domain_id,
155 domain_name=self.domain_name,
156 project_id=self.project_id,
157 project_name=self.project_name,
158 project_domain_id=self.project_domain_id,
159 project_domain_name=self.project_domain_name,
160 reauthenticate=self.reauthenticate)
161
162 self.assertTrue(self.ks_password_credential !=
163 other_ks_password_credential)
164
165 def test___ne___username(self):
166 other_username = "service"
167
168 other_ks_password_credential = keystone_password.KeystonePassword(
169 self.password,
170 username=other_username,
171 user_id=self.user_id,
172 user_domain_id=self.user_domain_id,
173 user_domain_name=self.user_domain_name,
174 trust_id=self.trust_id,
175 domain_id=self.domain_id,
176 domain_name=self.domain_name,
177 project_id=self.project_id,
178 project_name=self.project_name,
179 project_domain_id=self.project_domain_id,
180 project_domain_name=self.project_domain_name,
181 reauthenticate=self.reauthenticate)
182
183 self.assertTrue(self.ks_password_credential !=
184 other_ks_password_credential)
185
186 def test___ne___user_id(self):
187 other_user_id = "service"
188
189 other_ks_password_credential = keystone_password.KeystonePassword(
190 self.password,
191 username=self.username,
192 user_id=other_user_id,
193 user_domain_id=self.user_domain_id,
194 user_domain_name=self.user_domain_name,
195 trust_id=self.trust_id,
196 domain_id=self.domain_id,
197 domain_name=self.domain_name,
198 project_id=self.project_id,
199 project_name=self.project_name,
200 project_domain_id=self.project_domain_id,
201 project_domain_name=self.project_domain_name,
202 reauthenticate=self.reauthenticate)
203
204 self.assertTrue(self.ks_password_credential !=
205 other_ks_password_credential)
206
207 def test___ne___user_domain_id(self):
208 other_user_domain_id = "domain0"
209
210 other_ks_password_credential = keystone_password.KeystonePassword(
211 self.password,
212 username=self.username,
213 user_id=self.user_id,
214 user_domain_id=other_user_domain_id,
215 user_domain_name=self.user_domain_name,
216 trust_id=self.trust_id,
217 domain_id=self.domain_id,
218 domain_name=self.domain_name,
219 project_id=self.project_id,
220 project_name=self.project_name,
221 project_domain_id=self.project_domain_id,
222 project_domain_name=self.project_domain_name,
223 reauthenticate=self.reauthenticate)
224
225 self.assertTrue(self.ks_password_credential !=
226 other_ks_password_credential)
227
228 def test___ne___user_domain_name(self):
229 other_user_domain_name = "domain0"
230
231 other_ks_password_credential = keystone_password.KeystonePassword(
232 self.password,
233 username=self.username,
234 user_id=self.user_id,
235 user_domain_id=self.domain_id,
236 user_domain_name=other_user_domain_name,
237 trust_id=self.trust_id,
238 domain_id=self.domain_id,
239 domain_name=self.domain_name,
240 project_id=self.project_id,
241 project_name=self.project_name,
242 project_domain_id=self.project_domain_id,
243 project_domain_name=self.project_domain_name,
244 reauthenticate=self.reauthenticate)
245
246 self.assertTrue(self.ks_password_credential !=
247 other_ks_password_credential)
248
249 def test___ne___trust_id(self):
250 other_trust_id = "00000000000000"
251
252 other_ks_password_credential = keystone_password.KeystonePassword(
253 self.password,
254 username=self.username,
255 user_id=self.user_id,
256 user_domain_id=self.user_domain_id,
257 user_domain_name=self.user_domain_name,
258 trust_id=other_trust_id,
259 domain_id=self.domain_id,
260 domain_name=self.domain_name,
261 project_id=self.project_id,
262 project_name=self.project_name,
263 project_domain_id=self.project_domain_id,
264 project_domain_name=self.project_domain_name,
265 reauthenticate=self.reauthenticate)
266
267 self.assertTrue(self.ks_password_credential !=
268 other_ks_password_credential)
269
270 def test___ne___domain_id(self):
271 other_domain_id = "domain0"
272
273 other_ks_password_credential = keystone_password.KeystonePassword(
274 self.password,
275 username=self.username,
276 user_id=self.user_id,
277 user_domain_id=self.user_domain_id,
278 user_domain_name=self.user_domain_name,
279 trust_id=self.trust_id,
280 domain_id=other_domain_id,
281 domain_name=self.domain_name,
282 project_id=self.project_id,
283 project_name=self.project_name,
284 project_domain_id=self.project_domain_id,
285 project_domain_name=self.project_domain_name,
286 reauthenticate=self.reauthenticate)
287
288 self.assertTrue(self.ks_password_credential !=
289 other_ks_password_credential)
290
291 def test___ne___domain_name(self):
292 other_domain_name = "domain0"
293
294 other_ks_password_credential = keystone_password.KeystonePassword(
295 self.password,
296 username=self.username,
297 user_id=self.user_id,
298 user_domain_id=self.user_domain_id,
299 user_domain_name=self.user_domain_name,
300 trust_id=self.trust_id,
301 domain_id=self.domain_id,
302 domain_name=other_domain_name,
303 project_id=self.project_id,
304 project_name=self.project_name,
305 project_domain_id=self.project_domain_id,
306 project_domain_name=self.project_domain_name,
307 reauthenticate=self.reauthenticate)
308
309 self.assertTrue(self.ks_password_credential !=
310 other_ks_password_credential)
311
312 def test___ne___project_id(self):
313 other_project_id = "00000000000000"
314
315 other_ks_password_credential = keystone_password.KeystonePassword(
316 self.password,
317 username=self.username,
318 user_id=self.user_id,
319 user_domain_id=self.user_domain_id,
320 user_domain_name=self.user_domain_name,
321 trust_id=self.trust_id,
322 domain_id=self.domain_id,
323 domain_name=self.domain_name,
324 project_id=other_project_id,
325 project_name=self.project_name,
326 project_domain_id=self.project_domain_id,
327 project_domain_name=self.project_domain_name,
328 reauthenticate=self.reauthenticate)
329
330 self.assertTrue(self.ks_password_credential !=
331 other_ks_password_credential)
332
333 def test___ne___project_name(self):
334 other_project_name = "proj0"
335
336 other_ks_password_credential = keystone_password.KeystonePassword(
337 self.password,
338 username=self.username,
339 user_id=self.user_id,
340 user_domain_id=self.user_domain_id,
341 user_domain_name=self.user_domain_name,
342 trust_id=self.trust_id,
343 domain_id=self.domain_id,
344 domain_name=self.domain_name,
345 project_id=self.project_id,
346 project_name=other_project_name,
347 project_domain_id=self.project_domain_id,
348 project_domain_name=self.project_domain_name,
349 reauthenticate=self.reauthenticate)
350
351 self.assertTrue(self.ks_password_credential !=
352 other_ks_password_credential)
353
354 def test___ne___project_domain_id(self):
355 other_project_domain_id = "domain0"
356
357 other_ks_password_credential = keystone_password.KeystonePassword(
358 self.password,
359 username=self.username,
360 user_id=self.user_id,
361 user_domain_id=self.user_domain_id,
362 user_domain_name=self.user_domain_name,
363 trust_id=self.trust_id,
364 domain_id=self.domain_id,
365 domain_name=self.domain_name,
366 project_id=self.project_id,
367 project_name=self.project_name,
368 project_domain_id=other_project_domain_id,
369 project_domain_name=self.project_domain_name,
370 reauthenticate=self.reauthenticate)
371
372 self.assertTrue(self.ks_password_credential !=
373 other_ks_password_credential)
374
375 def test___ne___project_domain_name(self):
376 other_project_domain_name = "domain0"
377
378 other_ks_password_credential = keystone_password.KeystonePassword(
379 self.password,
380 username=self.username,
381 user_id=self.user_id,
382 user_domain_id=self.user_domain_id,
383 user_domain_name=self.user_domain_name,
384 trust_id=self.trust_id,
385 domain_id=self.domain_id,
386 domain_name=self.domain_name,
387 project_id=self.project_id,
388 project_name=self.project_name,
389 project_domain_id=self.project_domain_id,
390 project_domain_name=other_project_domain_name,
391 reauthenticate=self.reauthenticate)
392
393 self.assertTrue(self.ks_password_credential !=
394 other_ks_password_credential)
395
396 def test___ne___reauthenticate(self):
397 other_reauthenticate = False
398
399 other_ks_password_credential = keystone_password.KeystonePassword(
400 self.password,
401 username=self.username,
402 user_id=self.user_id,
403 user_domain_id=self.user_domain_id,
404 user_domain_name=self.user_domain_name,
405 trust_id=self.trust_id,
406 domain_id=self.domain_id,
407 domain_name=self.domain_name,
408 project_id=self.project_id,
409 project_name=self.project_name,
410 project_domain_id=self.project_domain_id,
411 project_domain_name=self.project_domain_name,
412 reauthenticate=other_reauthenticate)
413
414 self.assertTrue(self.ks_password_credential !=
415 other_ks_password_credential)
0 # Copyright (c) 2015 IBM
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 keystone token credential
17 """
18
19 from castellan.common.credentials import keystone_token
20 from castellan.tests import base
21
22
23 class KeystoneTokenTestCase(base.TestCase):
24
25 def _create_ks_token_credential(self):
26 return keystone_token.KeystoneToken(
27 self.token,
28 trust_id=self.trust_id,
29 domain_id=self.domain_id,
30 domain_name=self.domain_name,
31 project_id=self.project_id,
32 project_name=self.project_name,
33 project_domain_id=self.project_domain_id,
34 project_domain_name=self.project_domain_name,
35 reauthenticate=self.reauthenticate)
36
37 def setUp(self):
38 self.token = "8a4aa147d58141c39a7a22905b90ba4e",
39 self.trust_id = "14b38a8296f144148138466ce9280940",
40 self.domain_id = "default",
41 self.domain_name = "default",
42 self.project_id = "1099302ec608486f9879ba2466c60720",
43 self.project_name = "demo",
44 self.project_domain_id = "default",
45 self.project_domain_name = "default",
46 self.reauthenticate = True
47
48 self.ks_token_credential = self._create_ks_token_credential()
49
50 super(KeystoneTokenTestCase, self).setUp()
51
52 def test_get_token(self):
53 self.assertEqual(self.token,
54 self.ks_token_credential.token)
55
56 def test_get_trust_id(self):
57 self.assertEqual(self.trust_id,
58 self.ks_token_credential.trust_id)
59
60 def test_get_domain_id(self):
61 self.assertEqual(self.domain_id,
62 self.ks_token_credential.domain_id)
63
64 def test_get_domain_name(self):
65 self.assertEqual(self.domain_name,
66 self.ks_token_credential.domain_name)
67
68 def test_get_project_id(self):
69 self.assertEqual(self.project_id,
70 self.ks_token_credential.project_id)
71
72 def test_get_project_name(self):
73 self.assertEqual(self.project_name,
74 self.ks_token_credential.project_name)
75
76 def test_get_project_domain_id(self):
77 self.assertEqual(self.project_domain_id,
78 self.ks_token_credential.project_domain_id)
79
80 def test_get_project_domain_name(self):
81 self.assertEqual(self.project_domain_name,
82 self.ks_token_credential.project_domain_name)
83
84 def test_get_reauthenticate(self):
85 self.assertEqual(self.reauthenticate,
86 self.ks_token_credential.reauthenticate)
87
88 def test___eq__(self):
89 self.assertTrue(self.ks_token_credential ==
90 self.ks_token_credential)
91 self.assertTrue(self.ks_token_credential is
92 self.ks_token_credential)
93
94 self.assertFalse(self.ks_token_credential is None)
95 self.assertFalse(None == self.ks_token_credential)
96
97 other_ks_token_credential = keystone_token.KeystoneToken(
98 self.token,
99 trust_id=self.trust_id,
100 domain_id=self.domain_id,
101 domain_name=self.domain_name,
102 project_id=self.project_id,
103 project_name=self.project_name,
104 project_domain_id=self.project_domain_id,
105 project_domain_name=self.project_domain_name,
106 reauthenticate=self.reauthenticate)
107 self.assertTrue(self.ks_token_credential ==
108 other_ks_token_credential)
109 self.assertFalse(self.ks_token_credential is
110 other_ks_token_credential)
111
112 def test___ne___none(self):
113 self.assertTrue(self.ks_token_credential is not None)
114 self.assertTrue(None != self.ks_token_credential)
115
116 def test___ne___token(self):
117 other_token = "5c59e3217d3d4dd297589b297aee2a6f"
118
119 other_ks_token_credential = keystone_token.KeystoneToken(
120 other_token,
121 trust_id=self.trust_id,
122 domain_id=self.domain_id,
123 domain_name=self.domain_name,
124 project_id=self.project_id,
125 project_name=self.project_name,
126 project_domain_id=self.project_domain_id,
127 project_domain_name=self.project_domain_name,
128 reauthenticate=self.reauthenticate)
129
130 self.assertTrue(self.ks_token_credential !=
131 other_ks_token_credential)
132
133 def test___ne___trust_id(self):
134 other_trust_id = "00000000000000"
135
136 other_ks_token_credential = keystone_token.KeystoneToken(
137 self.token,
138 trust_id=other_trust_id,
139 domain_id=self.domain_id,
140 domain_name=self.domain_name,
141 project_id=self.project_id,
142 project_name=self.project_name,
143 project_domain_id=self.project_domain_id,
144 project_domain_name=self.project_domain_name,
145 reauthenticate=self.reauthenticate)
146
147 self.assertTrue(self.ks_token_credential !=
148 other_ks_token_credential)
149
150 def test___ne___domain_id(self):
151 other_domain_id = "domain0"
152
153 other_ks_token_credential = keystone_token.KeystoneToken(
154 self.token,
155 trust_id=self.trust_id,
156 domain_id=other_domain_id,
157 domain_name=self.domain_name,
158 project_id=self.project_id,
159 project_name=self.project_name,
160 project_domain_id=self.project_domain_id,
161 project_domain_name=self.project_domain_name,
162 reauthenticate=self.reauthenticate)
163
164 self.assertTrue(self.ks_token_credential !=
165 other_ks_token_credential)
166
167 def test___ne___domain_name(self):
168 other_domain_name = "domain0"
169
170 other_ks_token_credential = keystone_token.KeystoneToken(
171 self.token,
172 trust_id=self.trust_id,
173 domain_id=self.domain_id,
174 domain_name=other_domain_name,
175 project_id=self.project_id,
176 project_name=self.project_name,
177 project_domain_id=self.project_domain_id,
178 project_domain_name=self.project_domain_name,
179 reauthenticate=self.reauthenticate)
180
181 self.assertTrue(self.ks_token_credential !=
182 other_ks_token_credential)
183
184 def test___ne___project_id(self):
185 other_project_id = "00000000000000"
186
187 other_ks_token_credential = keystone_token.KeystoneToken(
188 self.token,
189 trust_id=self.trust_id,
190 domain_id=self.domain_id,
191 domain_name=self.domain_name,
192 project_id=other_project_id,
193 project_name=self.project_name,
194 project_domain_id=self.project_domain_id,
195 project_domain_name=self.project_domain_name,
196 reauthenticate=self.reauthenticate)
197
198 self.assertTrue(self.ks_token_credential !=
199 other_ks_token_credential)
200
201 def test___ne___project_name(self):
202 other_project_name = "proj0"
203
204 other_ks_token_credential = keystone_token.KeystoneToken(
205 self.token,
206 trust_id=self.trust_id,
207 domain_id=self.domain_id,
208 domain_name=self.domain_name,
209 project_id=self.project_id,
210 project_name=other_project_name,
211 project_domain_id=self.project_domain_id,
212 project_domain_name=self.project_domain_name,
213 reauthenticate=self.reauthenticate)
214
215 self.assertTrue(self.ks_token_credential !=
216 other_ks_token_credential)
217
218 def test___ne___project_domain_id(self):
219 other_project_domain_id = "domain0"
220
221 other_ks_token_credential = keystone_token.KeystoneToken(
222 self.token,
223 trust_id=self.trust_id,
224 domain_id=self.domain_id,
225 domain_name=self.domain_name,
226 project_id=self.project_id,
227 project_name=self.project_name,
228 project_domain_id=other_project_domain_id,
229 project_domain_name=self.project_domain_name,
230 reauthenticate=self.reauthenticate)
231
232 self.assertTrue(self.ks_token_credential !=
233 other_ks_token_credential)
234
235 def test___ne___project_domain_name(self):
236 other_project_domain_name = "domain0"
237
238 other_ks_token_credential = keystone_token.KeystoneToken(
239 self.token,
240 trust_id=self.trust_id,
241 domain_id=self.domain_id,
242 domain_name=self.domain_name,
243 project_id=self.project_id,
244 project_name=self.project_name,
245 project_domain_id=self.project_domain_id,
246 project_domain_name=other_project_domain_name,
247 reauthenticate=self.reauthenticate)
248
249 self.assertTrue(self.ks_token_credential !=
250 other_ks_token_credential)
251
252 def test___ne___reauthenticate(self):
253 other_reauthenticate = False
254
255 other_ks_token_credential = keystone_token.KeystoneToken(
256 self.token,
257 trust_id=self.trust_id,
258 domain_id=self.domain_id,
259 domain_name=self.domain_name,
260 project_id=self.project_id,
261 project_name=self.project_name,
262 project_domain_id=self.project_domain_id,
263 project_domain_name=self.project_domain_name,
264 reauthenticate=other_reauthenticate)
265
266 self.assertTrue(self.ks_token_credential !=
267 other_ks_token_credential)
0 # Copyright (c) 2015 IBM
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 password credential
17 """
18
19 from castellan.common.credentials import password
20 from castellan.tests import base
21
22
23 class PasswordTestCase(base.TestCase):
24
25 def _create_password_credential(self):
26 return password.Password(self.username,
27 self.password)
28
29 def setUp(self):
30 self.username = "admin"
31 self.password = "Pa$$w0rd1"
32
33 self.password_credential = self._create_password_credential()
34
35 super(PasswordTestCase, self).setUp()
36
37 def test_get_username(self):
38 self.assertEqual(self.username, self.password_credential.username)
39
40 def test_get_password(self):
41 self.assertEqual(self.password, self.password_credential.password)
42
43 def test___eq__(self):
44 self.assertTrue(self.password_credential == self.password_credential)
45 self.assertTrue(self.password_credential is self.password_credential)
46
47 self.assertFalse(self.password_credential is None)
48 self.assertFalse(None == self.password_credential)
49
50 other_password_credential = password.Password(self.username,
51 self.password)
52 self.assertTrue(self.password_credential == other_password_credential)
53 self.assertFalse(self.password_credential is other_password_credential)
54
55 def test___ne___none(self):
56 self.assertTrue(self.password_credential is not None)
57 self.assertTrue(None != self.password_credential)
58
59 def test___ne___username(self):
60 other_username = "service"
61 other_password_credential = password.Password(other_username,
62 self.password)
63 self.assertTrue(self.password_credential != other_password_credential)
64
65 def test___ne___password(self):
66 other_password = "i143Cats"
67 other_password_credential = password.Password(self.username,
68 other_password)
69 self.assertTrue(self.password_credential != other_password_credential)
0 # Copyright (c) 2015 IBM
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 token credential
17 """
18
19 from castellan.common.credentials import token
20 from castellan.tests import base
21
22
23 class TokenTestCase(base.TestCase):
24
25 def _create_token_credential(self):
26 return token.Token(self.token)
27
28 def setUp(self):
29 self.token = "8a4aa147d58141c39a7a22905b90ba4e"
30 self.token_credential = self._create_token_credential()
31 super(TokenTestCase, self).setUp()
32
33 def test_get_token(self):
34 self.assertEqual(self.token, self.token_credential.token)
35
36 def test___eq__(self):
37 self.assertTrue(self.token_credential == self.token_credential)
38 self.assertTrue(self.token_credential is self.token_credential)
39
40 self.assertFalse(self.token_credential is None)
41 self.assertFalse(None == self.token_credential)
42
43 other_token_credential = token.Token(self.token)
44 self.assertTrue(self.token_credential == other_token_credential)
45 self.assertFalse(self.token_credential is other_token_credential)
46
47 def test___ne___none(self):
48 self.assertTrue(self.token_credential is not None)
49 self.assertTrue(None != self.token_credential)
50
51 def test___ne___token(self):
52 other_token = "fe32af1fe47e4744a48254e60ae80012"
53 other_token_credential = token.Token(other_token)
54 self.assertTrue(self.token_credential != other_token_credential)
5252 This key manager is not suitable for use in production deployments.
5353 """
5454
55 def __init__(self):
55 def __init__(self, configuration=None):
56 self.conf = configuration
5657 self.keys = {}
5758
5859 def _generate_hex_key(self, key_length):
6465
6566 def _generate_key(self, **kwargs):
6667 name = kwargs.get('name', None)
68 algorithm = kwargs.get('algorithm', 'AES')
6769 key_length = kwargs.get('key_length', 256)
6870 _hex = self._generate_hex_key(key_length)
6971 return sym_key.SymmetricKey(
70 'AES',
72 algorithm,
7173 key_length,
7274 bytes(binascii.unhexlify(_hex)),
7375 name)
1515 """
1616 Test cases for the barbican key manager.
1717 """
18 import calendar
1819
1920 from barbicanclient import exceptions as barbican_exceptions
2021 import mock
2122 from oslo_config import cfg
23 from oslo_utils import timeutils
2224
2325 from castellan.common import exception
2426 from castellan.common.objects import symmetric_key as sym_key
186188 original_secret_metadata.bit_length = mock.sentinel.bit
187189 original_secret_metadata.secret_type = 'symmetric'
188190
191 created = timeutils.parse_isotime('2015-10-20 18:51:17+00:00')
192 original_secret_metadata.created = created
193 created_formatted = timeutils.parse_isotime(str(created))
194 created_posix = calendar.timegm(created_formatted.timetuple())
195
189196 key_name = 'my key'
190197 original_secret_metadata.name = key_name
191198
198205 self.get.assert_called_once_with(self.secret_ref)
199206 self.assertEqual(key_name, key.name)
200207 self.assertEqual(original_secret_data, key.get_encoded())
208 self.assertEqual(created_posix, key.created)
201209
202210 def test_get_null_context(self):
203211 self.key_mgr._barbican_client = None
320328
321329 self.assertEqual(number_of_retries + 1,
322330 self.mock_barbican.orders.get.call_count)
331
332 def test_get_active_order_error(self):
333 order_ref_url = ("http://localhost:9311/v1/orders/"
334 "4fe939b7-72bc-49aa-bd1e-e979589858af")
335
336 error_order = mock.Mock()
337 error_order.status = u'ERROR'
338 error_order.order_ref = order_ref_url
339 error_order.error_status_code = u"500"
340 error_order.error_reason = u"Test Error"
341
342 self.mock_barbican.orders.get.return_value = error_order
343
344 self.assertRaises(exception.KeyManagerError,
345 self.key_mgr._get_active_order,
346 self.mock_barbican,
347 order_ref_url)
348
349 self.assertEqual(1, self.mock_barbican.orders.get.call_count)
7070 key_id = self.key_mgr.create_key(self.context, name=name)
7171 key = self.key_mgr.get(self.context, key_id)
7272 self.assertEqual(name, key.name)
73
74 def test_create_key_with_algorithm(self):
75 algorithm = 'DES'
76 key_id = self.key_mgr.create_key(self.context, algorithm=algorithm)
77 key = self.key_mgr.get(self.context, key_id)
78 self.assertEqual(algorithm, key.algorithm)
7379
7480 def test_create_key_null_context(self):
7581 self.assertRaises(exception.Forbidden,
1515 """
1616 Test cases for the opaque data class.
1717 """
18
1918 from castellan.common.objects import opaque_data
2019 from castellan.tests import base
2120
2322 class OpaqueDataTestCase(base.TestCase):
2423
2524 def _create_data(self):
26 return opaque_data.OpaqueData(self.data, self.name)
25 return opaque_data.OpaqueData(self.data,
26 self.name,
27 self.created)
2728
2829 def setUp(self):
2930 self.data = bytes(b"secret opaque data")
3031 self.name = 'my opaque'
32 self.created = 1448088699
3133 self.opaque_data = self._create_data()
3234
3335 super(OpaqueDataTestCase, self).setUp()
4143 def test_get_name(self):
4244 self.assertEqual(self.name, self.opaque_data.name)
4345
46 def test_get_created(self):
47 self.assertEqual(self.created, self.opaque_data.created)
48
49 def test_get_created_none(self):
50 created = None
51 data = opaque_data.OpaqueData(self.data,
52 self.name,
53 created)
54
55 self.assertEqual(created, data.created)
56
4457 def test___eq__(self):
4558 self.assertTrue(self.opaque_data == self.opaque_data)
4659 self.assertTrue(self.opaque_data is self.opaque_data)
4861 self.assertFalse(self.opaque_data is None)
4962 self.assertFalse(None == self.opaque_data)
5063
51 other_opaque_data = opaque_data.OpaqueData(self.data, self.name)
64 other_opaque_data = opaque_data.OpaqueData(self.data)
5265 self.assertTrue(self.opaque_data == other_opaque_data)
5366 self.assertFalse(self.opaque_data is other_opaque_data)
5467
5972 def test___ne___data(self):
6073 other_opaque = opaque_data.OpaqueData(b'other data', self.name)
6174 self.assertTrue(self.opaque_data != other_opaque)
62
63 def test___ne___name(self):
64 other_opaque = opaque_data.OpaqueData(self.data, "other opaque")
65 self.assertTrue(self.opaque_data != other_opaque)
1515 """
1616 Test cases for the passphrase class.
1717 """
18
1918 from castellan.common.objects import passphrase
2019 from castellan.tests import base
2120
2423
2524 def _create_passphrase(self):
2625 return passphrase.Passphrase(self.passphrase_data,
27 self.name)
26 self.name,
27 self.created)
2828
2929 def setUp(self):
3030 self.passphrase_data = bytes(b"secret passphrase")
3131 self.name = 'my phrase'
32 self.created = 1448088699
3233 self.passphrase = self._create_passphrase()
3334
3435 super(PassphraseTestCase, self).setUp()
4243 def test_get_name(self):
4344 self.assertEqual(self.name, self.passphrase.name)
4445
46 def test_get_created(self):
47 self.assertEqual(self.created, self.passphrase.created)
48
49 def test_get_created_none(self):
50 created = None
51 phrase = passphrase.Passphrase(self.passphrase_data,
52 self.name,
53 created)
54
55 self.assertEqual(created, phrase.created)
56
4557 def test___eq__(self):
4658 self.assertTrue(self.passphrase == self.passphrase)
4759 self.assertTrue(self.passphrase is self.passphrase)
4961 self.assertFalse(self.passphrase is None)
5062 self.assertFalse(None == self.passphrase)
5163
52 other_passphrase = passphrase.Passphrase(self.passphrase_data,
53 self.name)
64 other_passphrase = passphrase.Passphrase(self.passphrase_data)
5465 self.assertTrue(self.passphrase == other_passphrase)
5566 self.assertFalse(self.passphrase is other_passphrase)
5667
6172 def test___ne___data(self):
6273 other_phrase = passphrase.Passphrase(b"other passphrase", self.name)
6374 self.assertTrue(self.passphrase != other_phrase)
64
65 def test___ne__name(self):
66 other_phrase = passphrase.Passphrase(self.passphrase_data,
67 "other phrase")
68 self.assertTrue(self.passphrase != other_phrase)
1515 """
1616 Test cases for the private key class.
1717 """
18
1918 from castellan.common.objects import private_key
2019 from castellan.tests import base
2120 from castellan.tests import utils
2524
2625 def _create_key(self):
2726 return private_key.PrivateKey(self.algorithm,
28 self.length,
27 self.bit_length,
2928 self.encoded,
30 self.name)
29 self.name,
30 self.created)
3131
3232 def setUp(self):
3333 self.algorithm = 'RSA'
34 self.length = 2048
34 self.bit_length = 2048
3535 self.encoded = bytes(utils.get_private_key_der())
3636 self.name = 'my key'
37 self.created = 1448088699
3738
3839 super(PrivateKeyTestCase, self).setUp()
3940
4041 def test_get_algorithm(self):
4142 self.assertEqual(self.algorithm, self.key.algorithm)
4243
43 def test_get_length(self):
44 self.assertEqual(self.length, self.key.bit_length)
44 def test_get_bit_length(self):
45 self.assertEqual(self.bit_length, self.key.bit_length)
4546
4647 def test_get_name(self):
4748 self.assertEqual(self.name, self.key.name)
5253 def test_get_encoded(self):
5354 self.assertEqual(self.encoded, self.key.get_encoded())
5455
56 def test_get_created(self):
57 self.assertEqual(self.created, self.key.created)
58
59 def test_get_created_none(self):
60 created = None
61 key = private_key.PrivateKey(self.algorithm,
62 self.bit_length,
63 self.encoded,
64 self.name,
65 created)
66
67 self.assertEqual(created, key.created)
68
5569 def test___eq__(self):
5670 self.assertTrue(self.key == self.key)
5771 self.assertTrue(self.key is self.key)
6074 self.assertFalse(None == self.key)
6175
6276 other_key = private_key.PrivateKey(self.algorithm,
63 self.length,
64 self.encoded,
65 self.name)
77 self.bit_length,
78 self.encoded)
6679 self.assertTrue(self.key == other_key)
6780 self.assertFalse(self.key is other_key)
6881
7285
7386 def test___ne___algorithm(self):
7487 other_key = private_key.PrivateKey('DSA',
75 self.length,
88 self.bit_length,
7689 self.encoded,
7790 self.name)
7891 self.assertTrue(self.key != other_key)
7992
80 def test___ne___length(self):
93 def test___ne___bit_length(self):
8194 other_key = private_key.PrivateKey(self.algorithm,
8295 4096,
8396 self.encoded,
87100 def test___ne___encoded(self):
88101 different_encoded = bytes(utils.get_private_key_der()) + b'\x00'
89102 other_key = private_key.PrivateKey(self.algorithm,
90 self.length,
103 self.bit_length,
91104 different_encoded,
92105 self.name)
93106 self.assertTrue(self.key != other_key)
94
95 def test___ne___name(self):
96 other_key = private_key.PrivateKey(self.algorithm,
97 self.length,
98 self.encoded,
99 'other key')
100 self.assertTrue(self.key != other_key)
1515 """
1616 Test cases for the public key class.
1717 """
18
1918 from castellan.common.objects import public_key
2019 from castellan.tests import base
2120 from castellan.tests import utils
2524
2625 def _create_key(self):
2726 return public_key.PublicKey(self.algorithm,
28 self.length,
27 self.bit_length,
2928 self.encoded,
30 self.name)
29 self.name,
30 self.created)
3131
3232 def setUp(self):
3333 self.algorithm = 'RSA'
34 self.length = 2048
34 self.bit_length = 2048
3535 self.encoded = bytes(utils.get_public_key_der())
3636 self.name = 'my key'
37 self.created = 1448088699
3738
3839 super(PublicKeyTestCase, self).setUp()
3940
4041 def test_get_algorithm(self):
4142 self.assertEqual(self.algorithm, self.key.algorithm)
4243
43 def test_get_length(self):
44 self.assertEqual(self.length, self.key.bit_length)
44 def test_get_bit_length(self):
45 self.assertEqual(self.bit_length, self.key.bit_length)
4546
4647 def test_get_name(self):
4748 self.assertEqual(self.name, self.key.name)
5253 def test_get_encoded(self):
5354 self.assertEqual(self.encoded, self.key.get_encoded())
5455
56 def test_get_created(self):
57 self.assertEqual(self.created, self.key.created)
58
59 def test_get_created_none(self):
60 created = None
61 key = public_key.PublicKey(self.algorithm,
62 self.bit_length,
63 self.encoded,
64 self.name,
65 created)
66
67 self.assertEqual(created, key.created)
68
5569 def test___eq__(self):
5670 self.assertTrue(self.key == self.key)
5771 self.assertTrue(self.key is self.key)
6074 self.assertFalse(None == self.key)
6175
6276 other_key = public_key.PublicKey(self.algorithm,
63 self.length,
64 self.encoded,
65 self.name)
77 self.bit_length,
78 self.encoded)
6679 self.assertTrue(self.key == other_key)
6780 self.assertFalse(self.key is other_key)
6881
7285
7386 def test___ne___algorithm(self):
7487 other_key = public_key.PublicKey('DSA',
75 self.length,
88 self.bit_length,
7689 self.encoded,
7790 self.name)
7891 self.assertTrue(self.key != other_key)
7992
80 def test___ne___length(self):
93 def test___ne___bit_length(self):
8194 other_key = public_key.PublicKey(self.algorithm,
8295 4096,
8396 self.encoded,
87100 def test___ne___encoded(self):
88101 different_encoded = bytes(utils.get_public_key_der()) + b'\x00'
89102 other_key = public_key.PublicKey(self.algorithm,
90 self.length,
103 self.bit_length,
91104 different_encoded,
92105 self.name)
93106 self.assertTrue(self.key != other_key)
94
95 def test___ne__name(self):
96 other_key = public_key.PublicKey(self.algorithm,
97 self.length,
98 self.encoded,
99 'other key')
100 self.assertTrue(self.key != other_key)
1515 """
1616 Test cases for the symmetric key class.
1717 """
18
1918 from castellan.common.objects import symmetric_key as sym_key
2019 from castellan.tests import base
2120
2625 return sym_key.SymmetricKey(self.algorithm,
2726 self.bit_length,
2827 self.encoded,
29 self.name)
28 self.name,
29 self.created)
3030
3131 def setUp(self):
3232 self.algorithm = 'AES'
3333 self.encoded = bytes(b'0' * 64)
3434 self.bit_length = len(self.encoded) * 8
3535 self.name = 'my key'
36 self.created = 1448088699
3637
3738 super(SymmetricKeyTestCase, self).setUp()
3839
5152 def test_get_bit_length(self):
5253 self.assertEqual(self.bit_length, self.key.bit_length)
5354
55 def test_get_created(self):
56 self.assertEqual(self.created, self.key.created)
57
58 def test_get_created_none(self):
59 created = None
60 key = sym_key.SymmetricKey(self.algorithm,
61 self.bit_length,
62 self.encoded,
63 self.name,
64 created)
65
66 self.assertEqual(created, key.created)
67
5468 def test___eq__(self):
5569 self.assertTrue(self.key == self.key)
5670 self.assertTrue(self.key is self.key)
6074
6175 other_key = sym_key.SymmetricKey(self.algorithm,
6276 self.bit_length,
63 self.encoded,
64 self.name)
77 self.encoded)
6578 self.assertTrue(self.key == other_key)
6679 self.assertFalse(self.key is other_key)
6780
7689 self.name)
7790 self.assertTrue(self.key != other_key)
7891
79 def test___ne___length(self):
92 def test___ne___bit_length(self):
8093 other_key = sym_key.SymmetricKey(self.algorithm,
8194 self.bit_length * 2,
8295 self.encoded,
90103 different_encoded,
91104 self.name)
92105 self.assertTrue(self.key != other_key)
93
94 def test___ne___name(self):
95 other_key = sym_key.SymmetricKey(self.algorithm,
96 self.bit_length,
97 self.encoded,
98 'other key')
99 self.assertTrue(self.key != other_key)
1515 """
1616 Test cases for the X.509 certificate class.
1717 """
18
1918 from castellan.common.objects import x_509
2019 from castellan.tests import base
2120 from castellan.tests import utils
2423 class X509TestCase(base.CertificateTestCase):
2524
2625 def _create_cert(self):
27 return x_509.X509(self.data, self.name)
26 return x_509.X509(self.data,
27 self.name,
28 self.created)
2829
2930 def setUp(self):
3031 self.data = utils.get_certificate_der()
3132 self.name = 'my cert'
33 self.created = 1448088699
3234
3335 super(X509TestCase, self).setUp()
3436
4143 def test_get_encoded(self):
4244 self.assertEqual(self.data, self.cert.get_encoded())
4345
46 def test_get_created(self):
47 self.assertEqual(self.created, self.cert.created)
48
49 def test_get_created_none(self):
50 created = None
51 cert = x_509.X509(self.data,
52 self.name,
53 created)
54
55 self.assertEqual(created, cert.created)
56
4457 def test___eq__(self):
4558 self.assertTrue(self.cert == self.cert)
4659 self.assertTrue(self.cert is self.cert)
4861 self.assertFalse(self.cert is None)
4962 self.assertFalse(None == self.cert)
5063
51 other_x_509 = x_509.X509(self.data, self.name)
64 other_x_509 = x_509.X509(self.data)
5265 self.assertTrue(self.cert == other_x_509)
5366 self.assertFalse(self.cert is other_x_509)
5467
5972 def test___ne___data(self):
6073 other_x509 = x_509.X509(b'\x00\x00\x00', self.name)
6174 self.assertTrue(self.cert != other_x509)
62
63 def test___ne__name(self):
64 other_x509 = x_509.X509(self.data, "other x509")
65 self.assertTrue(self.cert != other_x509)
0 # Copyright (c) 2016 IBM
1 # Licensed under the Apache License, Version 2.0 (the "License");
2 # you may not use this file except in compliance with the License.
3 # You may obtain a copy of the License at
4 #
5 # http://www.apache.org/licenses/LICENSE-2.0
6 #
7 # Unless required by applicable law or agreed to in writing, software
8 # distributed under the License is distributed on an "AS IS" BASIS,
9 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
10 # implied.
11 # See the License for the specific language governing permissions and
12 # limitations under the License.
13
14 """
15 Test Common utilities for Castellan.
16 """
17
18 from castellan.common import exception
19 from castellan.common import utils
20 from castellan.tests import base
21
22 from oslo_config import cfg
23 from oslo_config import fixture as config_fixture
24 from oslo_context import context
25
26 CONF = cfg.CONF
27
28
29 class TestUtils(base.TestCase):
30
31 def setUp(self):
32 super(TestUtils, self).setUp()
33 self.config_fixture = self.useFixture(config_fixture.Config(CONF))
34 CONF.register_opts(utils.credential_opts, group=utils.OPT_GROUP)
35
36 def test_token_credential(self):
37 token_value = 'ec9799cd921e4e0a8ab6111c08ebf065'
38
39 self.config_fixture.config(
40 auth_type='token',
41 token=token_value,
42 group='key_manager'
43 )
44
45 token_context = utils.credential_factory(conf=CONF)
46 token_context_class = token_context.__class__.__name__
47
48 self.assertEqual('Token', token_context_class)
49 self.assertEqual(token_value, token_context.token)
50
51 def test_token_credential_with_context(self):
52 token_value = 'ec9799cd921e4e0a8ab6111c08ebf065'
53 ctxt = context.RequestContext(auth_token=token_value)
54
55 self.config_fixture.config(
56 auth_type='token',
57 group='key_manager'
58 )
59
60 token_context = utils.credential_factory(conf=CONF, context=ctxt)
61 token_context_class = token_context.__class__.__name__
62
63 self.assertEqual('Token', token_context_class)
64 self.assertEqual(token_value, token_context.token)
65
66 def test_token_credential_config_override_context(self):
67 ctxt_token_value = '00000000000000000000000000000000'
68 ctxt = context.RequestContext(auth_token=ctxt_token_value)
69
70 conf_token_value = 'ec9799cd921e4e0a8ab6111c08ebf065'
71
72 self.config_fixture.config(
73 auth_type='token',
74 token=conf_token_value,
75 group='key_manager'
76 )
77
78 token_context = utils.credential_factory(conf=CONF, context=ctxt)
79 token_context_class = token_context.__class__.__name__
80
81 self.assertEqual('Token', token_context_class)
82 self.assertEqual(conf_token_value, token_context.token)
83
84 def test_token_credential_exception(self):
85 self.config_fixture.config(
86 auth_type='token',
87 group='key_manager'
88 )
89
90 self.assertRaises(exception.InsufficientCredentialDataError,
91 utils.credential_factory,
92 CONF)
93
94 def test_password_credential(self):
95 password_value = 'p4ssw0rd'
96
97 self.config_fixture.config(
98 auth_type='password',
99 password=password_value,
100 group='key_manager'
101 )
102
103 password_context = utils.credential_factory(conf=CONF)
104 password_context_class = password_context.__class__.__name__
105
106 self.assertEqual('Password', password_context_class)
107 self.assertEqual(password_value, password_context.password)
108
109 def test_keystone_token_credential(self):
110 token_value = 'ec9799cd921e4e0a8ab6111c08ebf065'
111
112 self.config_fixture.config(
113 auth_type='keystone_token',
114 token=token_value,
115 group='key_manager'
116 )
117
118 ks_token_context = utils.credential_factory(conf=CONF)
119 ks_token_context_class = ks_token_context.__class__.__name__
120
121 self.assertEqual('KeystoneToken', ks_token_context_class)
122 self.assertEqual(token_value, ks_token_context.token)
123
124 def test_keystone_token_credential_with_context(self):
125 token_value = 'ec9799cd921e4e0a8ab6111c08ebf065'
126 ctxt = context.RequestContext(auth_token=token_value)
127
128 self.config_fixture.config(
129 auth_type='keystone_token',
130 group='key_manager'
131 )
132
133 ks_token_context = utils.credential_factory(conf=CONF, context=ctxt)
134 ks_token_context_class = ks_token_context.__class__.__name__
135
136 self.assertEqual('KeystoneToken', ks_token_context_class)
137 self.assertEqual(token_value, ks_token_context.token)
138
139 def test_keystone_token_credential_config_override_context(self):
140 ctxt_token_value = 'ec9799cd921e4e0a8ab6111c08ebf065'
141 ctxt = context.RequestContext(auth_token=ctxt_token_value)
142
143 conf_token_value = 'ec9799cd921e4e0a8ab6111c08ebf065'
144
145 self.config_fixture.config(
146 auth_type='keystone_token',
147 token=conf_token_value,
148 group='key_manager'
149 )
150
151 ks_token_context = utils.credential_factory(conf=CONF, context=ctxt)
152 ks_token_context_class = ks_token_context.__class__.__name__
153
154 self.assertEqual('KeystoneToken', ks_token_context_class)
155 self.assertEqual(conf_token_value, ks_token_context.token)
156
157 def test_keystone_token_credential_exception(self):
158 self.config_fixture.config(
159 auth_type='keystone_token',
160 group='key_manager'
161 )
162
163 self.assertRaises(exception.InsufficientCredentialDataError,
164 utils.credential_factory,
165 CONF)
166
167 def test_keystone_password_credential(self):
168 password_value = 'p4ssw0rd'
169
170 self.config_fixture.config(
171 auth_type='keystone_password',
172 password=password_value,
173 group='key_manager'
174 )
175
176 ks_password_context = utils.credential_factory(conf=CONF)
177 ks_password_context_class = ks_password_context.__class__.__name__
178
179 self.assertEqual('KeystonePassword', ks_password_context_class)
180 self.assertEqual(password_value, ks_password_context.password)
181
182 def test_oslo_context_to_keystone_token(self):
183 auth_token_value = '16bd612f28ec479b8ffe8e124fc37b43'
184 tenant_value = '00c6ef5ad2984af2acd7d42c299935c0'
185
186 ctxt = context.RequestContext(
187 auth_token=auth_token_value,
188 tenant=tenant_value)
189
190 ks_token_context = utils.credential_factory(context=ctxt)
191 ks_token_context_class = ks_token_context.__class__.__name__
192
193 self.assertEqual('KeystoneToken', ks_token_context_class)
194 self.assertEqual(auth_token_value, ks_token_context.token)
195 self.assertEqual(tenant_value, ks_token_context.project_id)
196
197 def test_invalid_auth_type(self):
198 self.config_fixture.config(
199 auth_type='hotdog',
200 group='key_manager'
201 )
202
203 self.assertRaises(exception.AuthTypeInvalidError,
204 utils.credential_factory,
205 conf=CONF)
66 consider the key manager behavior you wish to encapsulate and the OpenStack
77 deployments on which your application will run.
88
9 Basic usage
10 ~~~~~~~~~~~
11
12 Castellan works on the principle of providing an abstracted key manager based
13 on your configuration. In this manner, several different management services
14 can be supported through a single interface.
15
16 In addition to the key manager, Castellan also provides primitives for
17 various types of secrets (for example, asymmetric keys, simple passphrases,
18 and certificates). These primitives are used in conjunction with the key
19 manager to create, store, retrieve, and destroy managed secrets.
20
21 Another fundamental concept to using Castellan is the context object, most
9 Authentication
10 ~~~~~~~~~~~~~~
11
12 A fundamental concept to using Castellan is the credential context object.
13 Castellan supports the following credentials for authentication:
14
15 * Token
16 * Password
17 * Keystone Token
18 * Keystone Password
19
20 In order to use these credentials, valid configuration parameters must be
21 provided.
22
23 .. code:: ini
24
25 # token credential
26 # token variable not required, token can be obtained from context
27 [castellan]
28 auth_type = 'token'
29 token = '5b4de0bb77064f289f7cc58e33bea8c7'
30
31 # password credential
32 [castellan]
33 auth_type = 'password'
34 username = 'admin'
35 password = 'passw0rd1'
36
37 # keystone token credential
38 [castellan]
39 auth_type = 'keystone_token'
40 token = '5b4de0bb77064f289f7cc58e33bea8c7'
41 project_id = 'a1e19934af81420d980a5d02b4afe9fb'
42
43 # keystone password credential
44 [castellan]
45 auth_type = 'keystone_password'
46 username = 'admin'
47 password = 'passw0rd1'
48 project_id = '1099302ec608486f9879ba2466c60720'
49 user_domain_name = 'default'
50
51 .. note::
52
53 Keystone Token and Password authentication is achieved using
54 keystoneclient.auth.identity.v3 Token and Password auth plugins.
55 There are a variety of different variables which can be set for the
56 keystone credential options.
57
58
59 The configuration must be passed to a credential factory which will
60 generate the appropriate context.
61
62 .. code:: python
63
64 from castellan.common import utils
65
66 CONF = <your_configuration>
67 context = utils.credential_factory(conf=CONF, context=None)
68
69 Now you can go ahead and pass the context and use it for authentication.
70
71 .. note::
72
73 There is a special case for a token. Since a user may not want to store a
74 token in the configuration, the user can pass a context object containing
75 an 'auth_token' as well as a configuration file with 'token' as the
76 auth type.
77
78
79 An oslo context object can also be used for authentication, it is
2280 frequently inherited from ``oslo.context.RequestContext``. This object
2381 represents information that is contained in the current request, and is
2482 usually populated in the WSGI pipeline. The information contained in this
47105 ctxt = context.RequestContext(auth_token=keystone_client.auth_token,
48106 tenant=project_list[0].id)
49107
50 ctxt can then be passed into any key_manager api call which requires
51 a RequestContext object.
108 ctxt can then be passed into any key_manager api call.
109
110
111 Basic usage
112 ~~~~~~~~~~~
113
114 Castellan works on the principle of providing an abstracted key manager based
115 on your configuration. In this manner, several different management services
116 can be supported through a single interface.
117
118 In addition to the key manager, Castellan also provides primitives for
119 various types of secrets (for example, asymmetric keys, simple passphrases,
120 and certificates). These primitives are used in conjunction with the key
121 manager to create, store, retrieve, and destroy managed secrets.
52122
53123 **Example. Creating and storing a key.**
54124
192262 .. code:: console
193263
194264 $ tox -e genconfig
265
266
267 Parsing the configuration files
268 -------------------------------
269
270 Castellan does not parse the configuration files by default. When you create
271 the files and occupy them, you still need to manipulate the
272 ``oslo_config.cfg.ConfigOpts`` object before passing it to the
273 ``castellan.key_manager.API`` object. You can create a list of locations where
274 the configuration files reside. If multiple configuration files are
275 specified, the variables will be used from the most recently parsed file and
276 overwrite any previous variables. In the example below, the configuration
277 file in the ``/etc/castellan`` directory will overwrite the values found in
278 the file in the user's home directory. If a file is not found in one of the
279 specified locations, then a file not found error will occur.
280
281 **Example. Parsing the config files.**
282
283 .. code:: python
284
285 from oslo_config import cfg
286 from castellan import key_manager
287
288 conf = cfg.ConfigOpts()
289 conf(['~/castellan.conf', '/etc/castellan/castellan.conf'])
290 manager = key_manager.API(configuration=conf)
291
292 There are two options for parsing the Castellan values from a
293 configuration file:
294
295 - The values can be placed in a separate file.
296 - You can include the values in a configuration file you already use.
297
298 In order to see all of the default values used by Castellan, generate a
299 sample configuration by referring to the section directly above.
195300
196301 Adding castellan to configuration files
197302 ---------------------------------------
11 # of appearance. Changing the order has an impact on the overall integration
22 # process, which may cause wedges in the gate later.
33
4 pbr>=1.6
5 Babel>=1.3
6 cryptography>=1.0 # Apache-2.0
7 oslo.config>=2.7.0 # Apache-2.0
4 pbr>=1.6 # Apache-2.0
5 Babel>=1.3 # BSD
6 cryptography>=1.0 # BSD/Apache-2.0
7 oslo.config>=3.7.0 # Apache-2.0
88 oslo.context>=0.2.0 # Apache-2.0
9 oslo.log>=1.12.0 # Apache-2.0
9 oslo.log>=1.14.0 # Apache-2.0
1010 oslo.policy>=0.5.0 # Apache-2.0
1111 oslo.serialization>=1.10.0 # Apache-2.0
12 oslo.utils>=2.8.0 # Apache-2.0
12 oslo.utils>=3.5.0 # Apache-2.0
1414 Programming Language :: Python
1515 Programming Language :: Python :: 2
1616 Programming Language :: Python :: 2.7
17 Programming Language :: Python :: 2.6
1817 Programming Language :: Python :: 3
1918 Programming Language :: Python :: 3.4
2019
00 # The order of packages is significant, because pip processes them in the order
11 # of appearance. Changing the order has an impact on the overall integration
22 # process, which may cause wedges in the gate later.
3 hacking<0.11,>=0.10.2 # Apache-2.0
34
4 hacking<0.10,>=0.9.2
5
6 coverage>=3.6
7 discover
8 python-barbicanclient>=3.3.0
9 python-subunit>=0.0.18
10 sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2
5 coverage>=3.6 # Apache-2.0
6 discover # BSD
7 python-barbicanclient>=3.3.0 # Apache-2.0
8 python-subunit>=0.0.18 # Apache-2.0/BSD
9 sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2 # BSD
1110 oslosphinx!=3.4.0,>=2.5.0 # Apache-2.0
1211 oslotest>=1.10.0 # Apache-2.0
13 testrepository>=0.0.18
14 testscenarios>=0.4
15 testtools>=1.4.0
12 testrepository>=0.0.18 # Apache-2.0/BSD
13 testscenarios>=0.4 # Apache-2.0/BSD
14 testtools>=1.4.0 # MIT
00 [tox]
11 minversion = 1.6
2 envlist = py34,py26,py27,pypy,pep8
2 envlist = py34,py27,pypy,pep8
33 skipsdist = True
44
55 [testenv]
4747 # E123, E125 skipped as they are invalid PEP-8.
4848
4949 show-source = True
50 ignore = E123,E125,H803
50 ignore = E123,E125
5151 exclude=.venv,.git,.tox,dist,doc,*openstack/common*,*lib/python*,*egg,build