blob: 59902bb159a31de549d29cea34629112e1f2589d [file] [log] [blame]
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +05301# Copyright 2013 OpenStack Foundation
2# All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
15
16import json
nayna-patel2db83b32014-05-15 11:41:03 +000017import urllib
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053018
Haiwei Xuaad85db2014-03-05 05:17:39 +090019from tempest.common import rest_client
Matthew Treinish684d8992014-01-30 16:27:40 +000020from tempest import config
Andrea Frittoli8bbdb162014-01-06 11:06:13 +000021from tempest import exceptions
Ken'ichi Ohmichi5e397992014-12-17 09:03:19 +000022from tempest.services.identity.v3.json import base
Matthew Treinish684d8992014-01-30 16:27:40 +000023
24CONF = config.CONF
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053025
26
Ken'ichi Ohmichi5e397992014-12-17 09:03:19 +000027class IdentityV3ClientJSON(base.IdentityV3Client):
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053028
Brad Pokorny769cddc2014-10-02 12:19:33 -070029 def create_user(self, user_name, password=None, project_id=None,
30 email=None, domain_id='default', **kwargs):
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053031 """Creates a user."""
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053032 en = kwargs.get('enabled', True)
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053033 description = kwargs.get('description', None)
root34345472014-11-23 15:23:07 +020034 default_project_id = kwargs.get('default_project_id')
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053035 post_body = {
36 'project_id': project_id,
root34345472014-11-23 15:23:07 +020037 'default_project_id': default_project_id,
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053038 'description': description,
39 'domain_id': domain_id,
40 'email': email,
41 'enabled': en,
42 'name': user_name,
43 'password': password
44 }
45 post_body = json.dumps({'user': post_body})
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +020046 resp, body = self.post('users', post_body)
David Kranze9d2f422014-07-02 13:57:41 -040047 self.expected_success(201, resp.status)
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053048 body = json.loads(body)
David Kranzd8ccb792014-12-29 11:32:05 -050049 return rest_client.ResponseBody(resp, body['user'])
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053050
51 def update_user(self, user_id, name, **kwargs):
52 """Updates a user."""
David Kranzd8ccb792014-12-29 11:32:05 -050053 body = self.get_user(user_id)
nayna-patel755d8142013-07-16 06:45:34 +000054 email = kwargs.get('email', body['email'])
55 en = kwargs.get('enabled', body['enabled'])
56 project_id = kwargs.get('project_id', body['project_id'])
root34345472014-11-23 15:23:07 +020057 if 'default_project_id' in body.keys():
58 default_project_id = kwargs.get('default_project_id',
59 body['default_project_id'])
60 else:
61 default_project_id = kwargs.get('default_project_id')
nayna-patel755d8142013-07-16 06:45:34 +000062 description = kwargs.get('description', body['description'])
63 domain_id = kwargs.get('domain_id', body['domain_id'])
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053064 post_body = {
65 'name': name,
66 'email': email,
67 'enabled': en,
68 'project_id': project_id,
root34345472014-11-23 15:23:07 +020069 'default_project_id': default_project_id,
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053070 'id': user_id,
71 'domain_id': domain_id,
72 'description': description
73 }
74 post_body = json.dumps({'user': post_body})
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +020075 resp, body = self.patch('users/%s' % user_id, post_body)
David Kranze9d2f422014-07-02 13:57:41 -040076 self.expected_success(200, resp.status)
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053077 body = json.loads(body)
David Kranzd8ccb792014-12-29 11:32:05 -050078 return rest_client.ResponseBody(resp, body['user'])
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053079
ravikumar-venkatesand35d6442014-05-05 12:14:45 +000080 def update_user_password(self, user_id, password, original_password):
81 """Updates a user password."""
82 update_user = {
83 'password': password,
84 'original_password': original_password
85 }
86 update_user = json.dumps({'user': update_user})
87 resp, _ = self.post('users/%s/password' % user_id, update_user)
88 self.expected_success(204, resp.status)
David Kranzd8ccb792014-12-29 11:32:05 -050089 return rest_client.ResponseBody(resp)
ravikumar-venkatesand35d6442014-05-05 12:14:45 +000090
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053091 def list_user_projects(self, user_id):
92 """Lists the projects on which a user has roles assigned."""
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +020093 resp, body = self.get('users/%s/projects' % user_id)
David Kranze9d2f422014-07-02 13:57:41 -040094 self.expected_success(200, resp.status)
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053095 body = json.loads(body)
David Kranzd8ccb792014-12-29 11:32:05 -050096 return rest_client.ResponseBodyList(resp, body['projects'])
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053097
nayna-patel2db83b32014-05-15 11:41:03 +000098 def get_users(self, params=None):
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053099 """Get the list of users."""
nayna-patel2db83b32014-05-15 11:41:03 +0000100 url = 'users'
101 if params:
102 url += '?%s' % urllib.urlencode(params)
103 resp, body = self.get(url)
David Kranze9d2f422014-07-02 13:57:41 -0400104 self.expected_success(200, resp.status)
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530105 body = json.loads(body)
David Kranzd8ccb792014-12-29 11:32:05 -0500106 return rest_client.ResponseBodyList(resp, body['users'])
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530107
108 def get_user(self, user_id):
109 """GET a user."""
110 resp, body = self.get("users/%s" % user_id)
David Kranze9d2f422014-07-02 13:57:41 -0400111 self.expected_success(200, resp.status)
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530112 body = json.loads(body)
David Kranzd8ccb792014-12-29 11:32:05 -0500113 return rest_client.ResponseBody(resp, body['user'])
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530114
115 def delete_user(self, user_id):
116 """Deletes a User."""
117 resp, body = self.delete("users/%s" % user_id)
David Kranze9d2f422014-07-02 13:57:41 -0400118 self.expected_success(204, resp.status)
David Kranzd8ccb792014-12-29 11:32:05 -0500119 return rest_client.ResponseBody(resp, body)
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530120
121 def create_project(self, name, **kwargs):
122 """Creates a project."""
123 description = kwargs.get('description', None)
124 en = kwargs.get('enabled', True)
125 domain_id = kwargs.get('domain_id', 'default')
126 post_body = {
127 'description': description,
128 'domain_id': domain_id,
129 'enabled': en,
130 'name': name
131 }
132 post_body = json.dumps({'project': post_body})
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200133 resp, body = self.post('projects', post_body)
David Kranze9d2f422014-07-02 13:57:41 -0400134 self.expected_success(201, resp.status)
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530135 body = json.loads(body)
David Kranzd8ccb792014-12-29 11:32:05 -0500136 return rest_client.ResponseBody(resp, body['project'])
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530137
nayna-patel153e9dd2014-05-16 09:00:05 +0000138 def list_projects(self, params=None):
139 url = "projects"
140 if params:
141 url += '?%s' % urllib.urlencode(params)
142 resp, body = self.get(url)
David Kranze9d2f422014-07-02 13:57:41 -0400143 self.expected_success(200, resp.status)
Nayna Patele6331362013-08-12 06:59:48 +0000144 body = json.loads(body)
David Kranzd8ccb792014-12-29 11:32:05 -0500145 return rest_client.ResponseBodyList(resp, body['projects'])
Nayna Patele6331362013-08-12 06:59:48 +0000146
147 def update_project(self, project_id, **kwargs):
David Kranzd8ccb792014-12-29 11:32:05 -0500148 body = self.get_project(project_id)
Nayna Patele6331362013-08-12 06:59:48 +0000149 name = kwargs.get('name', body['name'])
150 desc = kwargs.get('description', body['description'])
151 en = kwargs.get('enabled', body['enabled'])
152 domain_id = kwargs.get('domain_id', body['domain_id'])
153 post_body = {
154 'id': project_id,
155 'name': name,
156 'description': desc,
157 'enabled': en,
158 'domain_id': domain_id,
159 }
160 post_body = json.dumps({'project': post_body})
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200161 resp, body = self.patch('projects/%s' % project_id, post_body)
David Kranze9d2f422014-07-02 13:57:41 -0400162 self.expected_success(200, resp.status)
Nayna Patele6331362013-08-12 06:59:48 +0000163 body = json.loads(body)
David Kranzd8ccb792014-12-29 11:32:05 -0500164 return rest_client.ResponseBody(resp, body['project'])
Nayna Patele6331362013-08-12 06:59:48 +0000165
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530166 def get_project(self, project_id):
167 """GET a Project."""
168 resp, body = self.get("projects/%s" % project_id)
David Kranze9d2f422014-07-02 13:57:41 -0400169 self.expected_success(200, resp.status)
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530170 body = json.loads(body)
David Kranzd8ccb792014-12-29 11:32:05 -0500171 return rest_client.ResponseBody(resp, body['project'])
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530172
173 def delete_project(self, project_id):
174 """Delete a project."""
175 resp, body = self.delete('projects/%s' % str(project_id))
David Kranze9d2f422014-07-02 13:57:41 -0400176 self.expected_success(204, resp.status)
David Kranzd8ccb792014-12-29 11:32:05 -0500177 return rest_client.ResponseBody(resp, body)
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530178
179 def create_role(self, name):
180 """Create a Role."""
181 post_body = {
182 'name': name
183 }
184 post_body = json.dumps({'role': post_body})
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200185 resp, body = self.post('roles', post_body)
David Kranze9d2f422014-07-02 13:57:41 -0400186 self.expected_success(201, resp.status)
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530187 body = json.loads(body)
David Kranzd8ccb792014-12-29 11:32:05 -0500188 return rest_client.ResponseBody(resp, body['role'])
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530189
190 def get_role(self, role_id):
191 """GET a Role."""
192 resp, body = self.get('roles/%s' % str(role_id))
David Kranze9d2f422014-07-02 13:57:41 -0400193 self.expected_success(200, resp.status)
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530194 body = json.loads(body)
David Kranzd8ccb792014-12-29 11:32:05 -0500195 return rest_client.ResponseBody(resp, body['role'])
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530196
wanglianmina3e84ea2014-03-26 17:30:33 +0800197 def list_roles(self):
198 """Get the list of Roles."""
199 resp, body = self.get("roles")
David Kranze9d2f422014-07-02 13:57:41 -0400200 self.expected_success(200, resp.status)
wanglianmina3e84ea2014-03-26 17:30:33 +0800201 body = json.loads(body)
David Kranzd8ccb792014-12-29 11:32:05 -0500202 return rest_client.ResponseBodyList(resp, body['roles'])
wanglianmina3e84ea2014-03-26 17:30:33 +0800203
nayna-patel755d8142013-07-16 06:45:34 +0000204 def update_role(self, name, role_id):
205 """Create a Role."""
206 post_body = {
207 'name': name
208 }
209 post_body = json.dumps({'role': post_body})
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200210 resp, body = self.patch('roles/%s' % str(role_id), post_body)
David Kranze9d2f422014-07-02 13:57:41 -0400211 self.expected_success(200, resp.status)
nayna-patel755d8142013-07-16 06:45:34 +0000212 body = json.loads(body)
David Kranzd8ccb792014-12-29 11:32:05 -0500213 return rest_client.ResponseBody(resp, body['role'])
nayna-patel755d8142013-07-16 06:45:34 +0000214
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530215 def delete_role(self, role_id):
216 """Delete a role."""
217 resp, body = self.delete('roles/%s' % str(role_id))
David Kranze9d2f422014-07-02 13:57:41 -0400218 self.expected_success(204, resp.status)
David Kranzd8ccb792014-12-29 11:32:05 -0500219 return rest_client.ResponseBody(resp, body)
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530220
221 def assign_user_role(self, project_id, user_id, role_id):
222 """Add roles to a user on a project."""
223 resp, body = self.put('projects/%s/users/%s/roles/%s' %
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200224 (project_id, user_id, role_id), None)
David Kranze9d2f422014-07-02 13:57:41 -0400225 self.expected_success(204, resp.status)
David Kranzd8ccb792014-12-29 11:32:05 -0500226 return rest_client.ResponseBody(resp, body)
nayna-patel4df72dc2013-05-29 10:27:24 +0000227
228 def create_domain(self, name, **kwargs):
229 """Creates a domain."""
230 description = kwargs.get('description', None)
231 en = kwargs.get('enabled', True)
232 post_body = {
233 'description': description,
234 'enabled': en,
235 'name': name
236 }
237 post_body = json.dumps({'domain': post_body})
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200238 resp, body = self.post('domains', post_body)
David Kranze9d2f422014-07-02 13:57:41 -0400239 self.expected_success(201, resp.status)
nayna-patel4df72dc2013-05-29 10:27:24 +0000240 body = json.loads(body)
David Kranzd8ccb792014-12-29 11:32:05 -0500241 return rest_client.ResponseBody(resp, body['domain'])
nayna-patel4df72dc2013-05-29 10:27:24 +0000242
243 def delete_domain(self, domain_id):
244 """Delete a domain."""
245 resp, body = self.delete('domains/%s' % str(domain_id))
David Kranze9d2f422014-07-02 13:57:41 -0400246 self.expected_success(204, resp.status)
David Kranzd8ccb792014-12-29 11:32:05 -0500247 return rest_client.ResponseBody(resp, body)
nayna-patel4df72dc2013-05-29 10:27:24 +0000248
249 def list_domains(self):
250 """List Domains."""
251 resp, body = self.get('domains')
David Kranze9d2f422014-07-02 13:57:41 -0400252 self.expected_success(200, resp.status)
nayna-patel4df72dc2013-05-29 10:27:24 +0000253 body = json.loads(body)
David Kranzd8ccb792014-12-29 11:32:05 -0500254 return rest_client.ResponseBodyList(resp, body['domains'])
nayna-patel4df72dc2013-05-29 10:27:24 +0000255
256 def update_domain(self, domain_id, **kwargs):
257 """Updates a domain."""
David Kranzd8ccb792014-12-29 11:32:05 -0500258 body = self.get_domain(domain_id)
nayna-patel4df72dc2013-05-29 10:27:24 +0000259 description = kwargs.get('description', body['description'])
260 en = kwargs.get('enabled', body['enabled'])
261 name = kwargs.get('name', body['name'])
262 post_body = {
263 'description': description,
264 'enabled': en,
265 'name': name
266 }
267 post_body = json.dumps({'domain': post_body})
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200268 resp, body = self.patch('domains/%s' % domain_id, post_body)
David Kranze9d2f422014-07-02 13:57:41 -0400269 self.expected_success(200, resp.status)
nayna-patel4df72dc2013-05-29 10:27:24 +0000270 body = json.loads(body)
David Kranzd8ccb792014-12-29 11:32:05 -0500271 return rest_client.ResponseBody(resp, body['domain'])
nayna-patel4df72dc2013-05-29 10:27:24 +0000272
273 def get_domain(self, domain_id):
274 """Get Domain details."""
275 resp, body = self.get('domains/%s' % domain_id)
David Kranze9d2f422014-07-02 13:57:41 -0400276 self.expected_success(200, resp.status)
nayna-patel4df72dc2013-05-29 10:27:24 +0000277 body = json.loads(body)
David Kranzd8ccb792014-12-29 11:32:05 -0500278 return rest_client.ResponseBody(resp, body['domain'])
nayna-patelb35f7232013-06-28 07:08:44 +0000279
280 def get_token(self, resp_token):
281 """Get token details."""
282 headers = {'X-Subject-Token': resp_token}
283 resp, body = self.get("auth/tokens", headers=headers)
David Kranze9d2f422014-07-02 13:57:41 -0400284 self.expected_success(200, resp.status)
nayna-patelb35f7232013-06-28 07:08:44 +0000285 body = json.loads(body)
David Kranzd8ccb792014-12-29 11:32:05 -0500286 return rest_client.ResponseBody(resp, body['token'])
nayna-patelb35f7232013-06-28 07:08:44 +0000287
288 def delete_token(self, resp_token):
289 """Deletes token."""
290 headers = {'X-Subject-Token': resp_token}
291 resp, body = self.delete("auth/tokens", headers=headers)
David Kranze9d2f422014-07-02 13:57:41 -0400292 self.expected_success(204, resp.status)
David Kranzd8ccb792014-12-29 11:32:05 -0500293 return rest_client.ResponseBody(resp, body)
nayna-patelb35f7232013-06-28 07:08:44 +0000294
nayna-patel755d8142013-07-16 06:45:34 +0000295 def create_group(self, name, **kwargs):
296 """Creates a group."""
297 description = kwargs.get('description', None)
298 domain_id = kwargs.get('domain_id', 'default')
299 project_id = kwargs.get('project_id', None)
300 post_body = {
301 'description': description,
302 'domain_id': domain_id,
303 'project_id': project_id,
304 'name': name
305 }
306 post_body = json.dumps({'group': post_body})
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200307 resp, body = self.post('groups', post_body)
David Kranze9d2f422014-07-02 13:57:41 -0400308 self.expected_success(201, resp.status)
nayna-patel755d8142013-07-16 06:45:34 +0000309 body = json.loads(body)
David Kranzd8ccb792014-12-29 11:32:05 -0500310 return rest_client.ResponseBody(resp, body['group'])
nayna-patel755d8142013-07-16 06:45:34 +0000311
Zhi Kun Liue8136f02014-01-07 18:56:28 +0800312 def get_group(self, group_id):
313 """Get group details."""
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200314 resp, body = self.get('groups/%s' % group_id)
David Kranze9d2f422014-07-02 13:57:41 -0400315 self.expected_success(200, resp.status)
Zhi Kun Liue8136f02014-01-07 18:56:28 +0800316 body = json.loads(body)
David Kranzd8ccb792014-12-29 11:32:05 -0500317 return rest_client.ResponseBody(resp, body['group'])
Zhi Kun Liue8136f02014-01-07 18:56:28 +0800318
319 def update_group(self, group_id, **kwargs):
320 """Updates a group."""
David Kranzd8ccb792014-12-29 11:32:05 -0500321 body = self.get_group(group_id)
Zhi Kun Liue8136f02014-01-07 18:56:28 +0800322 name = kwargs.get('name', body['name'])
323 description = kwargs.get('description', body['description'])
324 post_body = {
325 'name': name,
326 'description': description
327 }
328 post_body = json.dumps({'group': post_body})
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200329 resp, body = self.patch('groups/%s' % group_id, post_body)
David Kranze9d2f422014-07-02 13:57:41 -0400330 self.expected_success(200, resp.status)
Zhi Kun Liue8136f02014-01-07 18:56:28 +0800331 body = json.loads(body)
David Kranzd8ccb792014-12-29 11:32:05 -0500332 return rest_client.ResponseBody(resp, body['group'])
Zhi Kun Liue8136f02014-01-07 18:56:28 +0800333
nayna-patel755d8142013-07-16 06:45:34 +0000334 def delete_group(self, group_id):
335 """Delete a group."""
336 resp, body = self.delete('groups/%s' % str(group_id))
David Kranze9d2f422014-07-02 13:57:41 -0400337 self.expected_success(204, resp.status)
David Kranzd8ccb792014-12-29 11:32:05 -0500338 return rest_client.ResponseBody(resp, body)
nayna-patel755d8142013-07-16 06:45:34 +0000339
Zhi Kun Liue8136f02014-01-07 18:56:28 +0800340 def add_group_user(self, group_id, user_id):
341 """Add user into group."""
342 resp, body = self.put('groups/%s/users/%s' % (group_id, user_id),
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200343 None)
David Kranze9d2f422014-07-02 13:57:41 -0400344 self.expected_success(204, resp.status)
David Kranzd8ccb792014-12-29 11:32:05 -0500345 return rest_client.ResponseBody(resp, body)
Zhi Kun Liue8136f02014-01-07 18:56:28 +0800346
347 def list_group_users(self, group_id):
348 """List users in group."""
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200349 resp, body = self.get('groups/%s/users' % group_id)
David Kranze9d2f422014-07-02 13:57:41 -0400350 self.expected_success(200, resp.status)
Zhi Kun Liue8136f02014-01-07 18:56:28 +0800351 body = json.loads(body)
David Kranzd8ccb792014-12-29 11:32:05 -0500352 return rest_client.ResponseBodyList(resp, body['users'])
Zhi Kun Liue8136f02014-01-07 18:56:28 +0800353
wanglianmin29b0f4c2014-03-06 19:09:16 +0800354 def list_user_groups(self, user_id):
355 """Lists groups which a user belongs to."""
356 resp, body = self.get('users/%s/groups' % user_id)
David Kranze9d2f422014-07-02 13:57:41 -0400357 self.expected_success(200, resp.status)
wanglianmin29b0f4c2014-03-06 19:09:16 +0800358 body = json.loads(body)
David Kranzd8ccb792014-12-29 11:32:05 -0500359 return rest_client.ResponseBodyList(resp, body['groups'])
wanglianmin29b0f4c2014-03-06 19:09:16 +0800360
Zhi Kun Liue8136f02014-01-07 18:56:28 +0800361 def delete_group_user(self, group_id, user_id):
362 """Delete user in group."""
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200363 resp, body = self.delete('groups/%s/users/%s' % (group_id, user_id))
David Kranze9d2f422014-07-02 13:57:41 -0400364 self.expected_success(204, resp.status)
David Kranzd8ccb792014-12-29 11:32:05 -0500365 return rest_client.ResponseBody(resp, body)
Zhi Kun Liue8136f02014-01-07 18:56:28 +0800366
nayna-patel755d8142013-07-16 06:45:34 +0000367 def assign_user_role_on_project(self, project_id, user_id, role_id):
368 """Add roles to a user on a project."""
369 resp, body = self.put('projects/%s/users/%s/roles/%s' %
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200370 (project_id, user_id, role_id), None)
David Kranze9d2f422014-07-02 13:57:41 -0400371 self.expected_success(204, resp.status)
David Kranzd8ccb792014-12-29 11:32:05 -0500372 return rest_client.ResponseBody(resp, body)
nayna-patel755d8142013-07-16 06:45:34 +0000373
374 def assign_user_role_on_domain(self, domain_id, user_id, role_id):
375 """Add roles to a user on a domain."""
376 resp, body = self.put('domains/%s/users/%s/roles/%s' %
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200377 (domain_id, user_id, role_id), None)
David Kranze9d2f422014-07-02 13:57:41 -0400378 self.expected_success(204, resp.status)
David Kranzd8ccb792014-12-29 11:32:05 -0500379 return rest_client.ResponseBody(resp, body)
nayna-patel755d8142013-07-16 06:45:34 +0000380
381 def list_user_roles_on_project(self, project_id, user_id):
382 """list roles of a user on a project."""
383 resp, body = self.get('projects/%s/users/%s/roles' %
384 (project_id, user_id))
David Kranze9d2f422014-07-02 13:57:41 -0400385 self.expected_success(200, resp.status)
nayna-patel755d8142013-07-16 06:45:34 +0000386 body = json.loads(body)
David Kranzd8ccb792014-12-29 11:32:05 -0500387 return rest_client.ResponseBodyList(resp, body['roles'])
nayna-patel755d8142013-07-16 06:45:34 +0000388
389 def list_user_roles_on_domain(self, domain_id, user_id):
390 """list roles of a user on a domain."""
391 resp, body = self.get('domains/%s/users/%s/roles' %
392 (domain_id, user_id))
David Kranze9d2f422014-07-02 13:57:41 -0400393 self.expected_success(200, resp.status)
nayna-patel755d8142013-07-16 06:45:34 +0000394 body = json.loads(body)
David Kranzd8ccb792014-12-29 11:32:05 -0500395 return rest_client.ResponseBodyList(resp, body['roles'])
nayna-patel755d8142013-07-16 06:45:34 +0000396
397 def revoke_role_from_user_on_project(self, project_id, user_id, role_id):
398 """Delete role of a user on a project."""
399 resp, body = self.delete('projects/%s/users/%s/roles/%s' %
400 (project_id, user_id, role_id))
David Kranze9d2f422014-07-02 13:57:41 -0400401 self.expected_success(204, resp.status)
David Kranzd8ccb792014-12-29 11:32:05 -0500402 return rest_client.ResponseBody(resp, body)
nayna-patel755d8142013-07-16 06:45:34 +0000403
404 def revoke_role_from_user_on_domain(self, domain_id, user_id, role_id):
405 """Delete role of a user on a domain."""
406 resp, body = self.delete('domains/%s/users/%s/roles/%s' %
407 (domain_id, user_id, role_id))
David Kranze9d2f422014-07-02 13:57:41 -0400408 self.expected_success(204, resp.status)
David Kranzd8ccb792014-12-29 11:32:05 -0500409 return rest_client.ResponseBody(resp, body)
nayna-patel755d8142013-07-16 06:45:34 +0000410
411 def assign_group_role_on_project(self, project_id, group_id, role_id):
412 """Add roles to a user on a project."""
413 resp, body = self.put('projects/%s/groups/%s/roles/%s' %
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200414 (project_id, group_id, role_id), None)
David Kranze9d2f422014-07-02 13:57:41 -0400415 self.expected_success(204, resp.status)
David Kranzd8ccb792014-12-29 11:32:05 -0500416 return rest_client.ResponseBody(resp, body)
nayna-patel755d8142013-07-16 06:45:34 +0000417
418 def assign_group_role_on_domain(self, domain_id, group_id, role_id):
419 """Add roles to a user on a domain."""
420 resp, body = self.put('domains/%s/groups/%s/roles/%s' %
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200421 (domain_id, group_id, role_id), None)
David Kranze9d2f422014-07-02 13:57:41 -0400422 self.expected_success(204, resp.status)
David Kranzd8ccb792014-12-29 11:32:05 -0500423 return rest_client.ResponseBody(resp, body)
nayna-patel755d8142013-07-16 06:45:34 +0000424
425 def list_group_roles_on_project(self, project_id, group_id):
426 """list roles of a user on a project."""
427 resp, body = self.get('projects/%s/groups/%s/roles' %
428 (project_id, group_id))
David Kranze9d2f422014-07-02 13:57:41 -0400429 self.expected_success(200, resp.status)
nayna-patel755d8142013-07-16 06:45:34 +0000430 body = json.loads(body)
David Kranzd8ccb792014-12-29 11:32:05 -0500431 return rest_client.ResponseBodyList(resp, body['roles'])
nayna-patel755d8142013-07-16 06:45:34 +0000432
433 def list_group_roles_on_domain(self, domain_id, group_id):
434 """list roles of a user on a domain."""
435 resp, body = self.get('domains/%s/groups/%s/roles' %
436 (domain_id, group_id))
David Kranze9d2f422014-07-02 13:57:41 -0400437 self.expected_success(200, resp.status)
nayna-patel755d8142013-07-16 06:45:34 +0000438 body = json.loads(body)
David Kranzd8ccb792014-12-29 11:32:05 -0500439 return rest_client.ResponseBodyList(resp, body['roles'])
nayna-patel755d8142013-07-16 06:45:34 +0000440
441 def revoke_role_from_group_on_project(self, project_id, group_id, role_id):
442 """Delete role of a user on a project."""
443 resp, body = self.delete('projects/%s/groups/%s/roles/%s' %
444 (project_id, group_id, role_id))
David Kranze9d2f422014-07-02 13:57:41 -0400445 self.expected_success(204, resp.status)
David Kranzd8ccb792014-12-29 11:32:05 -0500446 return rest_client.ResponseBody(resp, body)
nayna-patel755d8142013-07-16 06:45:34 +0000447
448 def revoke_role_from_group_on_domain(self, domain_id, group_id, role_id):
449 """Delete role of a user on a domain."""
450 resp, body = self.delete('domains/%s/groups/%s/roles/%s' %
451 (domain_id, group_id, role_id))
David Kranze9d2f422014-07-02 13:57:41 -0400452 self.expected_success(204, resp.status)
David Kranzd8ccb792014-12-29 11:32:05 -0500453 return rest_client.ResponseBody(resp, body)
nayna-patel755d8142013-07-16 06:45:34 +0000454
Steven Hardybf70c5c2013-10-30 21:55:16 +0000455 def create_trust(self, trustor_user_id, trustee_user_id, project_id,
456 role_names, impersonation, expires_at):
457 """Creates a trust."""
458 roles = [{'name': n} for n in role_names]
459 post_body = {
460 'trustor_user_id': trustor_user_id,
461 'trustee_user_id': trustee_user_id,
462 'project_id': project_id,
463 'impersonation': impersonation,
464 'roles': roles,
465 'expires_at': expires_at
466 }
467 post_body = json.dumps({'trust': post_body})
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200468 resp, body = self.post('OS-TRUST/trusts', post_body)
David Kranze9d2f422014-07-02 13:57:41 -0400469 self.expected_success(201, resp.status)
Steven Hardybf70c5c2013-10-30 21:55:16 +0000470 body = json.loads(body)
David Kranzd8ccb792014-12-29 11:32:05 -0500471 return rest_client.ResponseBody(resp, body['trust'])
Steven Hardybf70c5c2013-10-30 21:55:16 +0000472
473 def delete_trust(self, trust_id):
474 """Deletes a trust."""
475 resp, body = self.delete("OS-TRUST/trusts/%s" % trust_id)
David Kranze9d2f422014-07-02 13:57:41 -0400476 self.expected_success(204, resp.status)
David Kranzd8ccb792014-12-29 11:32:05 -0500477 return rest_client.ResponseBody(resp, body)
Steven Hardybf70c5c2013-10-30 21:55:16 +0000478
479 def get_trusts(self, trustor_user_id=None, trustee_user_id=None):
480 """GET trusts."""
481 if trustor_user_id:
482 resp, body = self.get("OS-TRUST/trusts?trustor_user_id=%s"
483 % trustor_user_id)
484 elif trustee_user_id:
485 resp, body = self.get("OS-TRUST/trusts?trustee_user_id=%s"
486 % trustee_user_id)
487 else:
488 resp, body = self.get("OS-TRUST/trusts")
David Kranze9d2f422014-07-02 13:57:41 -0400489 self.expected_success(200, resp.status)
Steven Hardybf70c5c2013-10-30 21:55:16 +0000490 body = json.loads(body)
David Kranzd8ccb792014-12-29 11:32:05 -0500491 return rest_client.ResponseBodyList(resp, body['trusts'])
Steven Hardybf70c5c2013-10-30 21:55:16 +0000492
493 def get_trust(self, trust_id):
494 """GET trust."""
495 resp, body = self.get("OS-TRUST/trusts/%s" % trust_id)
David Kranze9d2f422014-07-02 13:57:41 -0400496 self.expected_success(200, resp.status)
Steven Hardybf70c5c2013-10-30 21:55:16 +0000497 body = json.loads(body)
David Kranzd8ccb792014-12-29 11:32:05 -0500498 return rest_client.ResponseBody(resp, body['trust'])
Steven Hardybf70c5c2013-10-30 21:55:16 +0000499
500 def get_trust_roles(self, trust_id):
501 """GET roles delegated by a trust."""
502 resp, body = self.get("OS-TRUST/trusts/%s/roles" % trust_id)
David Kranze9d2f422014-07-02 13:57:41 -0400503 self.expected_success(200, resp.status)
Steven Hardybf70c5c2013-10-30 21:55:16 +0000504 body = json.loads(body)
David Kranzd8ccb792014-12-29 11:32:05 -0500505 return rest_client.ResponseBodyList(resp, body['roles'])
Steven Hardybf70c5c2013-10-30 21:55:16 +0000506
507 def get_trust_role(self, trust_id, role_id):
508 """GET role delegated by a trust."""
509 resp, body = self.get("OS-TRUST/trusts/%s/roles/%s"
510 % (trust_id, role_id))
David Kranze9d2f422014-07-02 13:57:41 -0400511 self.expected_success(200, resp.status)
Steven Hardybf70c5c2013-10-30 21:55:16 +0000512 body = json.loads(body)
David Kranzd8ccb792014-12-29 11:32:05 -0500513 return rest_client.ResponseBody(resp, body['role'])
Steven Hardybf70c5c2013-10-30 21:55:16 +0000514
515 def check_trust_role(self, trust_id, role_id):
516 """HEAD Check if role is delegated by a trust."""
517 resp, body = self.head("OS-TRUST/trusts/%s/roles/%s"
518 % (trust_id, role_id))
Morgan Fainberg883311d2014-07-03 13:13:10 -0700519 self.expected_success(200, resp.status)
David Kranzd8ccb792014-12-29 11:32:05 -0500520 return rest_client.ResponseBody(resp, body)
Steven Hardybf70c5c2013-10-30 21:55:16 +0000521
nayna-patelb35f7232013-06-28 07:08:44 +0000522
Haiwei Xuaad85db2014-03-05 05:17:39 +0900523class V3TokenClientJSON(rest_client.RestClient):
nayna-patelb35f7232013-06-28 07:08:44 +0000524
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000525 def __init__(self):
Ken'ichi Ohmichie9f50412015-01-05 04:57:26 +0000526 super(V3TokenClientJSON, self).__init__(None, None, None)
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000527 auth_url = CONF.identity.uri_v3
ajayaa1fdc78a2014-07-09 16:51:13 +0530528 if not auth_url:
Matthew Treinishdb2c5972014-01-31 22:18:59 +0000529 raise exceptions.InvalidConfiguration('you must specify a v3 uri '
530 'if using the v3 identity '
531 'api')
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000532 if 'auth/tokens' not in auth_url:
533 auth_url = auth_url.rstrip('/') + '/auth/tokens'
nayna-patelb35f7232013-06-28 07:08:44 +0000534
535 self.auth_url = auth_url
nayna-patelb35f7232013-06-28 07:08:44 +0000536
Brant Knudsonc5553292014-03-15 11:06:05 -0500537 def auth(self, user=None, password=None, tenant=None, user_type='id',
538 domain=None, token=None):
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000539 """
540 :param user: user id or name, as specified in user_type
541 :param domain: the user and tenant domain
Brant Knudsonc5553292014-03-15 11:06:05 -0500542 :param token: a token to re-scope.
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000543
544 Accepts different combinations of credentials. Restrictions:
545 - tenant and domain are only name (no id)
546 - user domain and tenant domain are assumed identical
547 - domain scope is not supported here
548 Sample sample valid combinations:
Brant Knudsonc5553292014-03-15 11:06:05 -0500549 - token
550 - token, tenant, domain
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000551 - user_id, password
552 - username, password, domain
553 - username, password, tenant, domain
554 Validation is left to the server side.
555 """
nayna-patelb35f7232013-06-28 07:08:44 +0000556 creds = {
557 'auth': {
558 'identity': {
Brant Knudsonc5553292014-03-15 11:06:05 -0500559 'methods': [],
nayna-patelb35f7232013-06-28 07:08:44 +0000560 }
561 }
562 }
Brant Knudsonc5553292014-03-15 11:06:05 -0500563 id_obj = creds['auth']['identity']
564 if token:
565 id_obj['methods'].append('token')
566 id_obj['token'] = {
567 'id': token
568 }
569 if user and password:
570 id_obj['methods'].append('password')
571 id_obj['password'] = {
572 'user': {
573 'password': password,
574 }
575 }
576 if user_type == 'id':
577 id_obj['password']['user']['id'] = user
578 else:
579 id_obj['password']['user']['name'] = user
580 if domain is not None:
581 _domain = dict(name=domain)
582 id_obj['password']['user']['domain'] = _domain
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000583 if tenant is not None:
Brant Knudsonc5553292014-03-15 11:06:05 -0500584 _domain = dict(name=domain)
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000585 project = dict(name=tenant, domain=_domain)
586 scope = dict(project=project)
587 creds['auth']['scope'] = scope
588
nayna-patelb35f7232013-06-28 07:08:44 +0000589 body = json.dumps(creds)
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200590 resp, body = self.post(self.auth_url, body=body)
David Kranzfb3efa72014-08-28 16:58:25 -0400591 self.expected_success(201, resp.status)
David Kranzd8ccb792014-12-29 11:32:05 -0500592 return rest_client.ResponseBody(resp, body)
nayna-patelb35f7232013-06-28 07:08:44 +0000593
Sergey Murashov4fccd322014-03-22 09:58:52 +0400594 def request(self, method, url, extra_headers=False, headers=None,
595 body=None):
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000596 """A simple HTTP request interface."""
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200597 if headers is None:
598 # Always accept 'json', for xml token client too.
599 # Because XML response is not easily
600 # converted to the corresponding JSON one
601 headers = self.get_headers(accept_type="json")
Sergey Murashov4fccd322014-03-22 09:58:52 +0400602 elif extra_headers:
603 try:
604 headers.update(self.get_headers(accept_type="json"))
605 except (ValueError, TypeError):
606 headers = self.get_headers(accept_type="json")
607
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000608 resp, resp_body = self.http_obj.request(url, method,
609 headers=headers, body=body)
Sean Dague89a85912014-03-19 16:37:29 -0400610 self._log_request(method, url, resp)
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000611
612 if resp.status in [401, 403]:
613 resp_body = json.loads(resp_body)
614 raise exceptions.Unauthorized(resp_body['error']['message'])
615 elif resp.status not in [200, 201, 204]:
616 raise exceptions.IdentityError(
617 'Unexpected status code {0}'.format(resp.status))
618
619 return resp, json.loads(resp_body)
620
621 def get_token(self, user, password, tenant, domain='Default',
622 auth_data=False):
623 """
624 :param user: username
625 Returns (token id, token data) for supplied credentials
626 """
David Kranzd8ccb792014-12-29 11:32:05 -0500627 body = self.auth(user, password, tenant, user_type='name',
628 domain=domain)
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000629
David Kranzd8ccb792014-12-29 11:32:05 -0500630 token = body.response.get('x-subject-token')
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000631 if auth_data:
632 return token, body['token']
633 else:
634 return token