blob: c49f3613ba79eeac664417e1705623bfeac7a37d [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
Andrea Frittoli8bbdb162014-01-06 11:06:13 +000016import json
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053017
18from lxml import etree
19
vponomaryov960eeb42014-02-22 18:25:25 +020020from tempest.common import rest_client
Matthew Treinish28f164c2014-03-04 18:55:06 +000021from tempest.common import xml_utils as common
Matthew Treinish684d8992014-01-30 16:27:40 +000022from tempest import config
Andrea Frittoli8bbdb162014-01-06 11:06:13 +000023from tempest import exceptions
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053024
Matthew Treinish684d8992014-01-30 16:27:40 +000025CONF = config.CONF
26
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053027XMLNS = "http://docs.openstack.org/identity/api/v3"
28
29
vponomaryov960eeb42014-02-22 18:25:25 +020030class IdentityV3ClientXML(rest_client.RestClient):
31 TYPE = "xml"
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053032
Andrea Frittoli8bbdb162014-01-06 11:06:13 +000033 def __init__(self, auth_provider):
34 super(IdentityV3ClientXML, self).__init__(auth_provider)
Matthew Treinish684d8992014-01-30 16:27:40 +000035 self.service = CONF.identity.catalog_type
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053036 self.endpoint_url = 'adminURL'
Andrea Frittoli8bbdb162014-01-06 11:06:13 +000037 self.api_version = "v3"
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053038
39 def _parse_projects(self, node):
40 array = []
41 for child in node.getchildren():
42 tag_list = child.tag.split('}', 1)
43 if tag_list[1] == "project":
Haiwei Xuaad85db2014-03-05 05:17:39 +090044 array.append(common.xml_to_json(child))
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053045 return array
46
nayna-patel4df72dc2013-05-29 10:27:24 +000047 def _parse_domains(self, node):
48 array = []
49 for child in node.getchildren():
50 tag_list = child.tag.split('}', 1)
51 if tag_list[1] == "domain":
Haiwei Xuaad85db2014-03-05 05:17:39 +090052 array.append(common.xml_to_json(child))
nayna-patel4df72dc2013-05-29 10:27:24 +000053 return array
54
wanglianmin29b0f4c2014-03-06 19:09:16 +080055 def _parse_groups(self, node):
56 array = []
57 for child in node.getchildren():
58 tag_list = child.tag.split('}', 1)
59 if tag_list[1] == "group":
60 array.append(common.xml_to_json(child))
61 return array
62
Zhi Kun Liue8136f02014-01-07 18:56:28 +080063 def _parse_group_users(self, node):
64 array = []
65 for child in node.getchildren():
66 tag_list = child.tag.split('}', 1)
67 if tag_list[1] == "user":
Haiwei Xuaad85db2014-03-05 05:17:39 +090068 array.append(common.xml_to_json(child))
Zhi Kun Liue8136f02014-01-07 18:56:28 +080069 return array
70
nayna-patel755d8142013-07-16 06:45:34 +000071 def _parse_roles(self, node):
72 array = []
73 for child in node.getchildren():
74 tag_list = child.tag.split('}', 1)
75 if tag_list[1] == "role":
Haiwei Xuaad85db2014-03-05 05:17:39 +090076 array.append(common.xml_to_json(child))
nayna-patel755d8142013-07-16 06:45:34 +000077 return array
78
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053079 def _parse_array(self, node):
80 array = []
81 for child in node.getchildren():
Haiwei Xuaad85db2014-03-05 05:17:39 +090082 array.append(common.xml_to_json(child))
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053083 return array
84
85 def _parse_body(self, body):
Haiwei Xuaad85db2014-03-05 05:17:39 +090086 _json = common.xml_to_json(body)
Andrea Frittoli8bbdb162014-01-06 11:06:13 +000087 return _json
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +053088
89 def create_user(self, user_name, **kwargs):
90 """Creates a user."""
91 password = kwargs.get('password', None)
92 email = kwargs.get('email', None)
93 en = kwargs.get('enabled', 'true')
94 project_id = kwargs.get('project_id', None)
95 description = kwargs.get('description', None)
96 domain_id = kwargs.get('domain_id', 'default')
Haiwei Xuaad85db2014-03-05 05:17:39 +090097 post_body = common.Element("user",
98 xmlns=XMLNS,
99 name=user_name,
100 password=password,
101 description=description,
102 email=email,
103 enabled=str(en).lower(),
104 project_id=project_id,
105 domain_id=domain_id)
106 resp, body = self.post('users', str(common.Document(post_body)))
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530107 body = self._parse_body(etree.fromstring(body))
108 return resp, body
109
110 def update_user(self, user_id, name, **kwargs):
111 """Updates a user."""
nayna-patel755d8142013-07-16 06:45:34 +0000112 resp, body = self.get_user(user_id)
113 email = kwargs.get('email', body['email'])
114 en = kwargs.get('enabled', body['enabled'])
115 project_id = kwargs.get('project_id', body['project_id'])
116 description = kwargs.get('description', body['description'])
117 domain_id = kwargs.get('domain_id', body['domain_id'])
Haiwei Xuaad85db2014-03-05 05:17:39 +0900118 update_user = common.Element("user",
119 xmlns=XMLNS,
120 name=name,
121 email=email,
122 project_id=project_id,
123 domain_id=domain_id,
124 description=description,
125 enabled=str(en).lower())
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530126 resp, body = self.patch('users/%s' % user_id,
Haiwei Xuaad85db2014-03-05 05:17:39 +0900127 str(common.Document(update_user)))
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530128 body = self._parse_body(etree.fromstring(body))
129 return resp, body
130
131 def list_user_projects(self, user_id):
132 """Lists the projects on which a user has roles assigned."""
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200133 resp, body = self.get('users/%s/projects' % user_id)
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530134 body = self._parse_projects(etree.fromstring(body))
135 return resp, body
136
137 def get_users(self):
138 """Get the list of users."""
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200139 resp, body = self.get("users")
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530140 body = self._parse_array(etree.fromstring(body))
141 return resp, body
142
143 def get_user(self, user_id):
144 """GET a user."""
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200145 resp, body = self.get("users/%s" % user_id)
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530146 body = self._parse_body(etree.fromstring(body))
147 return resp, body
148
149 def delete_user(self, user_id):
150 """Deletes a User."""
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200151 resp, body = self.delete("users/%s" % user_id)
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530152 return resp, body
153
154 def create_project(self, name, **kwargs):
155 """Creates a project."""
156 description = kwargs.get('description', None)
157 en = kwargs.get('enabled', 'true')
158 domain_id = kwargs.get('domain_id', 'default')
Haiwei Xuaad85db2014-03-05 05:17:39 +0900159 post_body = common.Element("project",
160 xmlns=XMLNS,
161 description=description,
162 domain_id=domain_id,
163 enabled=str(en).lower(),
164 name=name)
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530165 resp, body = self.post('projects',
Haiwei Xuaad85db2014-03-05 05:17:39 +0900166 str(common.Document(post_body)))
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530167 body = self._parse_body(etree.fromstring(body))
168 return resp, body
169
Nayna Patele6331362013-08-12 06:59:48 +0000170 def list_projects(self):
171 """Get the list of projects."""
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200172 resp, body = self.get("projects")
Nayna Patele6331362013-08-12 06:59:48 +0000173 body = self._parse_projects(etree.fromstring(body))
174 return resp, body
175
176 def update_project(self, project_id, **kwargs):
177 """Updates a Project."""
178 resp, body = self.get_project(project_id)
179 name = kwargs.get('name', body['name'])
180 desc = kwargs.get('description', body['description'])
181 en = kwargs.get('enabled', body['enabled'])
182 domain_id = kwargs.get('domain_id', body['domain_id'])
Haiwei Xuaad85db2014-03-05 05:17:39 +0900183 post_body = common.Element("project",
184 xmlns=XMLNS,
185 name=name,
186 description=desc,
187 enabled=str(en).lower(),
188 domain_id=domain_id)
Nayna Patele6331362013-08-12 06:59:48 +0000189 resp, body = self.patch('projects/%s' % project_id,
Haiwei Xuaad85db2014-03-05 05:17:39 +0900190 str(common.Document(post_body)))
Nayna Patele6331362013-08-12 06:59:48 +0000191 body = self._parse_body(etree.fromstring(body))
192 return resp, body
193
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530194 def get_project(self, project_id):
195 """GET a Project."""
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200196 resp, body = self.get("projects/%s" % project_id)
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530197 body = self._parse_body(etree.fromstring(body))
198 return resp, body
199
200 def delete_project(self, project_id):
201 """Delete a project."""
202 resp, body = self.delete('projects/%s' % str(project_id))
203 return resp, body
204
205 def create_role(self, name):
206 """Create a Role."""
Haiwei Xuaad85db2014-03-05 05:17:39 +0900207 post_body = common.Element("role",
208 xmlns=XMLNS,
209 name=name)
210 resp, body = self.post('roles', str(common.Document(post_body)))
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530211 body = self._parse_body(etree.fromstring(body))
212 return resp, body
213
214 def get_role(self, role_id):
215 """GET a Role."""
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200216 resp, body = self.get('roles/%s' % str(role_id))
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530217 body = self._parse_body(etree.fromstring(body))
218 return resp, body
219
nayna-patel755d8142013-07-16 06:45:34 +0000220 def update_role(self, name, role_id):
221 """Updates a Role."""
Haiwei Xuaad85db2014-03-05 05:17:39 +0900222 post_body = common.Element("role",
223 xmlns=XMLNS,
224 name=name)
nayna-patel755d8142013-07-16 06:45:34 +0000225 resp, body = self.patch('roles/%s' % str(role_id),
Haiwei Xuaad85db2014-03-05 05:17:39 +0900226 str(common.Document(post_body)))
nayna-patel755d8142013-07-16 06:45:34 +0000227 body = self._parse_body(etree.fromstring(body))
228 return resp, body
229
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530230 def delete_role(self, role_id):
231 """Delete a role."""
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200232 resp, body = self.delete('roles/%s' % str(role_id))
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530233 return resp, body
234
235 def assign_user_role(self, project_id, user_id, role_id):
236 """Add roles to a user on a tenant."""
237 resp, body = self.put('projects/%s/users/%s/roles/%s' %
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200238 (project_id, user_id, role_id), '')
rajalakshmi-ganesan7312bb52013-01-29 20:03:42 +0530239 return resp, body
nayna-patel4df72dc2013-05-29 10:27:24 +0000240
241 def create_domain(self, name, **kwargs):
242 """Creates a domain."""
243 description = kwargs.get('description', None)
244 en = kwargs.get('enabled', True)
Haiwei Xuaad85db2014-03-05 05:17:39 +0900245 post_body = common.Element("domain",
246 xmlns=XMLNS,
247 name=name,
248 description=description,
249 enabled=str(en).lower())
250 resp, body = self.post('domains', str(common.Document(post_body)))
nayna-patel4df72dc2013-05-29 10:27:24 +0000251 body = self._parse_body(etree.fromstring(body))
252 return resp, body
253
254 def list_domains(self):
255 """Get the list of domains."""
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200256 resp, body = self.get("domains")
nayna-patel4df72dc2013-05-29 10:27:24 +0000257 body = self._parse_domains(etree.fromstring(body))
258 return resp, body
259
260 def delete_domain(self, domain_id):
261 """Delete a domain."""
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200262 resp, body = self.delete('domains/%s' % domain_id)
nayna-patel4df72dc2013-05-29 10:27:24 +0000263 return resp, body
264
265 def update_domain(self, domain_id, **kwargs):
266 """Updates a domain."""
267 resp, body = self.get_domain(domain_id)
268 description = kwargs.get('description', body['description'])
269 en = kwargs.get('enabled', body['enabled'])
270 name = kwargs.get('name', body['name'])
Haiwei Xuaad85db2014-03-05 05:17:39 +0900271 post_body = common.Element("domain",
272 xmlns=XMLNS,
273 name=name,
274 description=description,
275 enabled=str(en).lower())
nayna-patel4df72dc2013-05-29 10:27:24 +0000276 resp, body = self.patch('domains/%s' % domain_id,
Haiwei Xuaad85db2014-03-05 05:17:39 +0900277 str(common.Document(post_body)))
nayna-patel4df72dc2013-05-29 10:27:24 +0000278 body = self._parse_body(etree.fromstring(body))
279 return resp, body
280
281 def get_domain(self, domain_id):
282 """Get Domain details."""
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200283 resp, body = self.get('domains/%s' % domain_id)
nayna-patel4df72dc2013-05-29 10:27:24 +0000284 body = self._parse_body(etree.fromstring(body))
285 return resp, body
nayna-patelb35f7232013-06-28 07:08:44 +0000286
287 def get_token(self, resp_token):
288 """GET a Token Details."""
289 headers = {'Content-Type': 'application/xml',
290 'Accept': 'application/xml',
291 'X-Subject-Token': resp_token}
292 resp, body = self.get("auth/tokens", headers=headers)
293 body = self._parse_body(etree.fromstring(body))
294 return resp, body
295
296 def delete_token(self, resp_token):
297 """Delete a Given Token."""
298 headers = {'X-Subject-Token': resp_token}
299 resp, body = self.delete("auth/tokens", headers=headers)
300 return resp, body
301
nayna-patel755d8142013-07-16 06:45:34 +0000302 def create_group(self, name, **kwargs):
303 """Creates a group."""
304 description = kwargs.get('description', None)
305 domain_id = kwargs.get('domain_id', 'default')
306 project_id = kwargs.get('project_id', None)
Haiwei Xuaad85db2014-03-05 05:17:39 +0900307 post_body = common.Element("group",
308 xmlns=XMLNS,
309 name=name,
310 description=description,
311 domain_id=domain_id,
312 project_id=project_id)
313 resp, body = self.post('groups', str(common.Document(post_body)))
nayna-patel755d8142013-07-16 06:45:34 +0000314 body = self._parse_body(etree.fromstring(body))
315 return resp, body
316
Zhi Kun Liue8136f02014-01-07 18:56:28 +0800317 def get_group(self, group_id):
318 """Get group details."""
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200319 resp, body = self.get('groups/%s' % group_id)
Zhi Kun Liue8136f02014-01-07 18:56:28 +0800320 body = self._parse_body(etree.fromstring(body))
321 return resp, body
322
323 def update_group(self, group_id, **kwargs):
324 """Updates a group."""
325 resp, body = self.get_group(group_id)
326 name = kwargs.get('name', body['name'])
327 description = kwargs.get('description', body['description'])
Haiwei Xuaad85db2014-03-05 05:17:39 +0900328 post_body = common.Element("group",
329 xmlns=XMLNS,
330 name=name,
331 description=description)
Zhi Kun Liue8136f02014-01-07 18:56:28 +0800332 resp, body = self.patch('groups/%s' % group_id,
Haiwei Xuaad85db2014-03-05 05:17:39 +0900333 str(common.Document(post_body)))
Zhi Kun Liue8136f02014-01-07 18:56:28 +0800334 body = self._parse_body(etree.fromstring(body))
335 return resp, body
336
nayna-patel755d8142013-07-16 06:45:34 +0000337 def delete_group(self, group_id):
338 """Delete a group."""
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200339 resp, body = self.delete('groups/%s' % group_id)
nayna-patel755d8142013-07-16 06:45:34 +0000340 return resp, body
341
Zhi Kun Liue8136f02014-01-07 18:56:28 +0800342 def add_group_user(self, group_id, user_id):
343 """Add user into group."""
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200344 resp, body = self.put('groups/%s/users/%s' % (group_id, user_id), '')
Zhi Kun Liue8136f02014-01-07 18:56:28 +0800345 return resp, body
346
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)
Zhi Kun Liue8136f02014-01-07 18:56:28 +0800350 body = self._parse_group_users(etree.fromstring(body))
351 return resp, body
352
wanglianmin29b0f4c2014-03-06 19:09:16 +0800353 def list_user_groups(self, user_id):
354 """Lists the groups which a user belongs to."""
355 resp, body = self.get('users/%s/groups' % user_id)
356 body = self._parse_groups(etree.fromstring(body))
357 return resp, body
358
Zhi Kun Liue8136f02014-01-07 18:56:28 +0800359 def delete_group_user(self, group_id, user_id):
360 """Delete user in group."""
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200361 resp, body = self.delete('groups/%s/users/%s' % (group_id, user_id))
Zhi Kun Liue8136f02014-01-07 18:56:28 +0800362 return resp, body
363
nayna-patel755d8142013-07-16 06:45:34 +0000364 def assign_user_role_on_project(self, project_id, user_id, role_id):
365 """Add roles to a user on a project."""
366 resp, body = self.put('projects/%s/users/%s/roles/%s' %
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200367 (project_id, user_id, role_id), '')
nayna-patel755d8142013-07-16 06:45:34 +0000368 return resp, body
369
370 def assign_user_role_on_domain(self, domain_id, user_id, role_id):
371 """Add roles to a user on a domain."""
372 resp, body = self.put('domains/%s/users/%s/roles/%s' %
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200373 (domain_id, user_id, role_id), '')
nayna-patel755d8142013-07-16 06:45:34 +0000374 return resp, body
375
376 def list_user_roles_on_project(self, project_id, user_id):
377 """list roles of a user on a project."""
378 resp, body = self.get('projects/%s/users/%s/roles' %
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200379 (project_id, user_id))
nayna-patel755d8142013-07-16 06:45:34 +0000380 body = self._parse_roles(etree.fromstring(body))
381 return resp, body
382
383 def list_user_roles_on_domain(self, domain_id, user_id):
384 """list roles of a user on a domain."""
385 resp, body = self.get('domains/%s/users/%s/roles' %
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200386 (domain_id, user_id))
nayna-patel755d8142013-07-16 06:45:34 +0000387 body = self._parse_roles(etree.fromstring(body))
388 return resp, body
389
390 def revoke_role_from_user_on_project(self, project_id, user_id, role_id):
391 """Delete role of a user on a project."""
392 resp, body = self.delete('projects/%s/users/%s/roles/%s' %
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200393 (project_id, user_id, role_id))
nayna-patel755d8142013-07-16 06:45:34 +0000394 return resp, body
395
396 def revoke_role_from_user_on_domain(self, domain_id, user_id, role_id):
397 """Delete role of a user on a domain."""
398 resp, body = self.delete('domains/%s/users/%s/roles/%s' %
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200399 (domain_id, user_id, role_id))
nayna-patel755d8142013-07-16 06:45:34 +0000400 return resp, body
401
402 def assign_group_role_on_project(self, project_id, group_id, role_id):
403 """Add roles to a user on a project."""
404 resp, body = self.put('projects/%s/groups/%s/roles/%s' %
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200405 (project_id, group_id, role_id), '')
nayna-patel755d8142013-07-16 06:45:34 +0000406 return resp, body
407
408 def assign_group_role_on_domain(self, domain_id, group_id, role_id):
409 """Add roles to a user on a domain."""
410 resp, body = self.put('domains/%s/groups/%s/roles/%s' %
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200411 (domain_id, group_id, role_id), '')
nayna-patel755d8142013-07-16 06:45:34 +0000412 return resp, body
413
414 def list_group_roles_on_project(self, project_id, group_id):
415 """list roles of a user on a project."""
416 resp, body = self.get('projects/%s/groups/%s/roles' %
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200417 (project_id, group_id))
nayna-patel755d8142013-07-16 06:45:34 +0000418 body = self._parse_roles(etree.fromstring(body))
419 return resp, body
420
421 def list_group_roles_on_domain(self, domain_id, group_id):
422 """list roles of a user on a domain."""
423 resp, body = self.get('domains/%s/groups/%s/roles' %
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200424 (domain_id, group_id))
nayna-patel755d8142013-07-16 06:45:34 +0000425 body = self._parse_roles(etree.fromstring(body))
426 return resp, body
427
428 def revoke_role_from_group_on_project(self, project_id, group_id, role_id):
429 """Delete role of a user on a project."""
430 resp, body = self.delete('projects/%s/groups/%s/roles/%s' %
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200431 (project_id, group_id, role_id))
nayna-patel755d8142013-07-16 06:45:34 +0000432 return resp, body
433
434 def revoke_role_from_group_on_domain(self, domain_id, group_id, role_id):
435 """Delete role of a user on a domain."""
436 resp, body = self.delete('domains/%s/groups/%s/roles/%s' %
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200437 (domain_id, group_id, role_id))
nayna-patel755d8142013-07-16 06:45:34 +0000438 return resp, body
439
nayna-patelb35f7232013-06-28 07:08:44 +0000440
vponomaryov960eeb42014-02-22 18:25:25 +0200441class V3TokenClientXML(rest_client.RestClient):
442 TYPE = "xml"
nayna-patelb35f7232013-06-28 07:08:44 +0000443
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000444 def __init__(self):
445 super(V3TokenClientXML, self).__init__(None)
446 auth_url = CONF.identity.uri_v3
Matthew Treinishdb2c5972014-01-31 22:18:59 +0000447 if not auth_url and CONF.identity_feature_enabled.api_v3:
448 raise exceptions.InvalidConfiguration('you must specify a v3 uri '
449 'if using the v3 identity '
450 'api')
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000451 if 'auth/tokens' not in auth_url:
452 auth_url = auth_url.rstrip('/') + '/auth/tokens'
nayna-patelb35f7232013-06-28 07:08:44 +0000453
454 self.auth_url = auth_url
nayna-patelb35f7232013-06-28 07:08:44 +0000455
Brant Knudsonc5553292014-03-15 11:06:05 -0500456 def auth(self, user=None, password=None, tenant=None, user_type='id',
457 domain=None, token=None):
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000458 """
459 :param user: user id or name, as specified in user_type
Brant Knudsonc5553292014-03-15 11:06:05 -0500460 :param domain: the user and tenant domain
461 :param token: a token to re-scope.
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000462
463 Accepts different combinations of credentials. Restrictions:
464 - tenant and domain are only name (no id)
465 - user domain and tenant domain are assumed identical
Brant Knudsonc5553292014-03-15 11:06:05 -0500466 - domain scope is not supported here
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000467 Sample sample valid combinations:
Brant Knudsonc5553292014-03-15 11:06:05 -0500468 - token
469 - token, tenant, domain
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000470 - user_id, password
471 - username, password, domain
472 - username, password, tenant, domain
473 Validation is left to the server side.
474 """
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000475
Haiwei Xuaad85db2014-03-05 05:17:39 +0900476 methods = common.Element('methods')
Haiwei Xuaad85db2014-03-05 05:17:39 +0900477 identity = common.Element('identity')
Brant Knudsonc5553292014-03-15 11:06:05 -0500478
479 if token:
480 method = common.Element('method')
481 method.append(common.Text('token'))
482 methods.append(method)
483
484 token = common.Element('token', id=token)
485 identity.append(token)
486
487 if user and password:
488 if user_type == 'id':
489 _user = common.Element('user', id=user, password=password)
490 else:
491 _user = common.Element('user', name=user, password=password)
492 if domain is not None:
493 _domain = common.Element('domain', name=domain)
494 _user.append(_domain)
495
496 password = common.Element('password')
497 password.append(_user)
498 method = common.Element('method')
499 method.append(common.Text('password'))
500 methods.append(method)
501 identity.append(password)
502
nayna-patelb35f7232013-06-28 07:08:44 +0000503 identity.append(methods)
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000504
Haiwei Xuaad85db2014-03-05 05:17:39 +0900505 auth = common.Element('auth')
nayna-patelb35f7232013-06-28 07:08:44 +0000506 auth.append(identity)
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000507
508 if tenant is not None:
Haiwei Xuaad85db2014-03-05 05:17:39 +0900509 project = common.Element('project', name=tenant)
Brant Knudsonc5553292014-03-15 11:06:05 -0500510 _domain = common.Element('domain', name=domain)
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000511 project.append(_domain)
Haiwei Xuaad85db2014-03-05 05:17:39 +0900512 scope = common.Element('scope')
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000513 scope.append(project)
514 auth.append(scope)
515
Haiwei Xuaad85db2014-03-05 05:17:39 +0900516 resp, body = self.post(self.auth_url, body=str(common.Document(auth)))
nayna-patelb35f7232013-06-28 07:08:44 +0000517 return resp, body
518
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000519 def request(self, method, url, headers=None, body=None):
520 """A simple HTTP request interface."""
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200521 if headers is None:
522 # Always accept 'json', for xml token client too.
523 # Because XML response is not easily
524 # converted to the corresponding JSON one
525 headers = self.get_headers(accept_type="json")
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000526 resp, resp_body = self.http_obj.request(url, method,
527 headers=headers, body=body)
Sean Dague89a85912014-03-19 16:37:29 -0400528 self._log_request(method, url, resp)
Andrea Frittoli8bbdb162014-01-06 11:06:13 +0000529
530 if resp.status in [401, 403]:
531 resp_body = json.loads(resp_body)
532 raise exceptions.Unauthorized(resp_body['error']['message'])
533 elif resp.status not in [200, 201, 204]:
534 raise exceptions.IdentityError(
535 'Unexpected status code {0}'.format(resp.status))
536
537 return resp, json.loads(resp_body)
538
539 def get_token(self, user, password, tenant, domain='Default',
540 auth_data=False):
541 """
542 :param user: username
543 Returns (token id, token data) for supplied credentials
544 """
545 resp, body = self.auth(user, password, tenant, user_type='name',
546 domain=domain)
547
548 token = resp.get('x-subject-token')
549 if auth_data:
550 return token, body['token']
551 else:
552 return token