summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJose Castro Leon <jose.castro.leon@cern.ch>2017-05-17 14:00:34 +0200
committerChristian Schwede <cschwede@redhat.com>2017-09-26 08:57:11 +0000
commite1a94f39edb6cf777c71c7a511476b1e60436ab9 (patch)
treed7316684686c75e2b97a76fe9f6fc5b1f06cf0ad
parent16d8f0d11f0ab9678b7e99f063fcce23d32c3c3b (diff)
Fix ec2tokens validation in v2 after regression in metadata_ref removalstable/ocata
Since the last patch in the ocata release that removed the metadata_ref, the ec2tokens api is broken due to unable to unpack the result of the authenticate command (4 elements) while expecting to expand it into 5. Change-Id: I71c4b51444ea9f7a3016b68d7dee9a4747e9c0fd Closes-Bug: #1691111 Closes-Bug: #1635389 (cherry picked from commit 820d9d9a84f2a65677a2654b36a4677eaeba59fc)
Notes
Notes (review): Code-Review+1: Harry Rybacki <hrybacki@redhat.com> Code-Review+1: Pablo Iranzo Gómez <Pablo.Iranzo@redhat.com> Code-Review+1: Jose Castro Leon <jose.castro.leon@cern.ch> Code-Review+1: Lance Bragstad <lbragstad@gmail.com> Code-Review+2: Morgan Fainberg <morgan.fainberg@gmail.com> Workflow+1: Morgan Fainberg <morgan.fainberg@gmail.com> Verified+2: Jenkins Submitted-by: Jenkins Submitted-at: Wed, 27 Sep 2017 18:20:12 +0000 Reviewed-on: https://review.openstack.org/507434 Project: openstack/keystone Branch: refs/heads/stable/ocata
-rw-r--r--keystone/contrib/ec2/controllers.py28
-rw-r--r--keystone/tests/unit/test_contrib_ec2_core.py197
2 files changed, 209 insertions, 16 deletions
diff --git a/keystone/contrib/ec2/controllers.py b/keystone/contrib/ec2/controllers.py
index c0c6b50..4ff99ba 100644
--- a/keystone/contrib/ec2/controllers.py
+++ b/keystone/contrib/ec2/controllers.py
@@ -47,6 +47,7 @@ from keystone.common import utils
47from keystone.common import wsgi 47from keystone.common import wsgi
48from keystone import exception 48from keystone import exception
49from keystone.i18n import _ 49from keystone.i18n import _
50from keystone.token import controllers as token_controllers
50 51
51CRED_TYPE_EC2 = 'ec2' 52CRED_TYPE_EC2 = 'ec2'
52 53
@@ -259,22 +260,17 @@ class Ec2Controller(Ec2ControllerCommon, controller.V2Controller):
259 260
260 @controller.v2_ec2_deprecated 261 @controller.v2_ec2_deprecated
261 def authenticate(self, request, credentials=None, ec2Credentials=None): 262 def authenticate(self, request, credentials=None, ec2Credentials=None):
262 (user_ref, tenant_ref, metadata_ref, roles_ref, 263 (user_ref, project_ref, roles_ref, catalog_ref) = self._authenticate(
263 catalog_ref) = self._authenticate(credentials=credentials, 264 credentials=credentials, ec2credentials=ec2Credentials
264 ec2credentials=ec2Credentials) 265 )
265 266
266 # NOTE(morganfainberg): Make sure the data is in correct form since it 267 method_names = ['ec2credential']
267 # might be consumed external to Keystone and this is a v2.0 controller. 268
268 # The token provider does not explicitly care about user_ref version 269 token_id, token_data = self.token_provider_api.issue_token(
269 # in this case, but the data is stored in the token itself and should 270 user_ref['id'], method_names, project_id=project_ref['id'])
270 # match the version 271
271 user_ref = self.v3_to_v2_user(user_ref) 272 v2_helper = token_controllers.V2TokenDataHelper()
272 auth_token_data = dict(user=user_ref, 273 token_data = v2_helper.v3_to_v2_token(token_data, token_id)
273 tenant=tenant_ref,
274 metadata=metadata_ref,
275 id='placeholder')
276 (token_id, token_data) = self.token_provider_api.issue_v2_token(
277 auth_token_data, roles_ref, catalog_ref)
278 return token_data 274 return token_data
279 275
280 @controller.v2_ec2_deprecated 276 @controller.v2_ec2_deprecated
diff --git a/keystone/tests/unit/test_contrib_ec2_core.py b/keystone/tests/unit/test_contrib_ec2_core.py
new file mode 100644
index 0000000..d5f7472
--- /dev/null
+++ b/keystone/tests/unit/test_contrib_ec2_core.py
@@ -0,0 +1,197 @@
1# Copyright 2012 OpenStack Foundation
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
15from keystoneclient.contrib.ec2 import utils as ec2_utils
16from six.moves import http_client
17
18from keystone.contrib.ec2 import controllers
19from keystone.tests import unit
20from keystone.tests.unit import test_v2
21from keystone.tests.unit import test_v3
22
23
24class EC2ContribCoreV2(test_v2.RestfulTestCase):
25 def config_overrides(self):
26 super(EC2ContribCoreV2, self).config_overrides()
27
28 def assertValidAuthenticationResponse(self, r):
29 self.assertIsNotNone(r.result.get('access'))
30 self.assertIsNotNone(r.result['access'].get('token'))
31 self.assertIsNotNone(r.result['access'].get('user'))
32
33 # validate token
34 self.assertIsNotNone(r.result['access']['token'].get('id'))
35 self.assertIsNotNone(r.result['access']['token'].get('expires'))
36 tenant = r.result['access']['token'].get('tenant')
37 if tenant is not None:
38 # validate tenant
39 self.assertIsNotNone(tenant.get('id'))
40 self.assertIsNotNone(tenant.get('name'))
41
42 # validate user
43 self.assertIsNotNone(r.result['access']['user'].get('id'))
44 self.assertIsNotNone(r.result['access']['user'].get('name'))
45
46 def assertValidErrorResponse(self, r):
47 resp = r.result
48 self.assertIsNotNone(resp.get('error'))
49 self.assertIsNotNone(resp['error'].get('code'))
50 self.assertIsNotNone(resp['error'].get('title'))
51 self.assertIsNotNone(resp['error'].get('message'))
52 self.assertEqual(int(resp['error']['code']), r.status_code)
53
54 def test_valid_authentication_response_with_proper_secret(self):
55 cred_blob, credential = unit.new_ec2_credential(
56 self.user_foo['id'], self.tenant_bar['id'])
57
58 self.credential_api.create_credential(
59 credential['id'], credential)
60
61 signer = ec2_utils.Ec2Signer(cred_blob['secret'])
62 credentials = {
63 'access': cred_blob['access'],
64 'secret': cred_blob['secret'],
65 'host': 'localhost',
66 'verb': 'GET',
67 'path': '/',
68 'params': {
69 'SignatureVersion': '2',
70 'Action': 'Test',
71 'Timestamp': '2007-01-31T23:59:59Z'
72 },
73 }
74 credentials['signature'] = signer.generate(credentials)
75 resp = self.public_request(
76 method='POST',
77 path='/v2.0/ec2tokens',
78 body={'credentials': credentials},
79 expected_status=http_client.OK)
80 self.assertValidAuthenticationResponse(resp)
81
82 def test_authenticate_with_empty_body_returns_bad_request(self):
83 self.public_request(
84 method='POST',
85 path='/v2.0/ec2tokens',
86 body={},
87 expected_status=http_client.BAD_REQUEST)
88
89 def test_authenticate_without_json_request_returns_bad_request(self):
90 self.public_request(
91 method='POST',
92 path='/v2.0/ec2tokens',
93 body='not json',
94 expected_status=http_client.BAD_REQUEST)
95
96 def test_authenticate_without_request_body_returns_bad_request(self):
97 self.public_request(
98 method='POST',
99 path='/v2.0/ec2tokens',
100 expected_status=http_client.BAD_REQUEST)
101
102 def test_authenticate_without_proper_secret_returns_unauthorized(self):
103 cred_blob, credential = unit.new_ec2_credential(
104 self.user_foo['id'], self.tenant_bar['id'])
105
106 self.credential_api.create_credential(
107 credential['id'], credential)
108
109 signer = ec2_utils.Ec2Signer('totally not the secret')
110 credentials = {
111 'access': cred_blob['access'],
112 'secret': 'totally not the secret',
113 'host': 'localhost',
114 'verb': 'GET',
115 'path': '/',
116 'params': {
117 'SignatureVersion': '2',
118 'Action': 'Test',
119 'Timestamp': '2007-01-31T23:59:59Z'
120 },
121 }
122 credentials['signature'] = signer.generate(credentials)
123 self.public_request(
124 method='POST',
125 path='/v2.0/ec2tokens',
126 body={'credentials': credentials},
127 expected_status=http_client.UNAUTHORIZED)
128
129
130class EC2ContribCoreV3(test_v3.RestfulTestCase):
131 def setUp(self):
132 super(EC2ContribCoreV3, self).setUp()
133
134 self.cred_blob, self.credential = unit.new_ec2_credential(
135 self.user['id'], self.project_id)
136 self.credential_api.create_credential(
137 self.credential['id'], self.credential)
138
139 self.controller = controllers.Ec2ControllerV3
140
141 def test_valid_authentication_response_with_proper_secret(self):
142 signer = ec2_utils.Ec2Signer(self.cred_blob['secret'])
143 credentials = {
144 'access': self.cred_blob['access'],
145 'secret': self.cred_blob['secret'],
146 'host': 'localhost',
147 'verb': 'GET',
148 'path': '/',
149 'params': {
150 'SignatureVersion': '2',
151 'Action': 'Test',
152 'Timestamp': '2007-01-31T23:59:59Z'
153 },
154 }
155 credentials['signature'] = signer.generate(credentials)
156 resp = self.post(
157 '/ec2tokens',
158 body={'credentials': credentials},
159 expected_status=http_client.OK)
160 self.assertValidProjectScopedTokenResponse(resp, self.user)
161
162 def test_authenticate_with_empty_body_returns_bad_request(self):
163 self.post(
164 '/ec2tokens',
165 body={},
166 expected_status=http_client.BAD_REQUEST)
167
168 def test_authenticate_without_json_request_returns_bad_request(self):
169 self.post(
170 '/ec2tokens',
171 body='not json',
172 expected_status=http_client.BAD_REQUEST)
173
174 def test_authenticate_without_request_body_returns_bad_request(self):
175 self.post(
176 '/ec2tokens',
177 expected_status=http_client.BAD_REQUEST)
178
179 def test_authenticate_without_proper_secret_returns_unauthorized(self):
180 signer = ec2_utils.Ec2Signer('totally not the secret')
181 credentials = {
182 'access': self.cred_blob['access'],
183 'secret': 'totally not the secret',
184 'host': 'localhost',
185 'verb': 'GET',
186 'path': '/',
187 'params': {
188 'SignatureVersion': '2',
189 'Action': 'Test',
190 'Timestamp': '2007-01-31T23:59:59Z'
191 },
192 }
193 credentials['signature'] = signer.generate(credentials)
194 self.post(
195 '/ec2tokens',
196 body={'credentials': credentials},
197 expected_status=http_client.UNAUTHORIZED)