blob: 5c3cd2667f70936e576258950101b9facb268dc5 [file] [log] [blame]
ZhiQiang Fan39f97222013-09-20 04:49:44 +08001# Copyright 2012 OpenStack Foundation
nayna-patelb35f7232013-06-28 07:08:44 +00002# 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
Jordan Pittiere8791202016-04-25 18:12:16 +020016import six
17
nayna-patelb35f7232013-06-28 07:08:44 +000018from tempest.api.identity import base
ZhangHongtao74e1df52017-03-13 18:32:43 +080019from tempest import config
Ken'ichi Ohmichi7bd25752017-03-10 10:45:39 -080020from tempest.lib.common.utils import data_utils
Ken'ichi Ohmichieeabdd22017-01-27 17:46:00 -080021from tempest.lib import decorators
Andrea Frittoli (andreaf)db9672e2016-02-23 14:07:24 -050022from tempest.lib import exceptions as lib_exc
nayna-patelb35f7232013-06-28 07:08:44 +000023
ZhangHongtao74e1df52017-03-13 18:32:43 +080024CONF = config.CONF
25
nayna-patelb35f7232013-06-28 07:08:44 +000026
Masayuki Igawabe64ed32014-02-19 14:32:03 +090027class TokensV3TestJSON(base.BaseIdentityV3AdminTest):
nayna-patelb35f7232013-06-28 07:08:44 +000028
Ken'ichi Ohmichieeabdd22017-01-27 17:46:00 -080029 @decorators.idempotent_id('0f9f5a5f-d5cd-4a86-8a5b-c5ded151f212')
nayna-patelb35f7232013-06-28 07:08:44 +000030 def test_tokens(self):
31 # Valid user's token is authenticated
32 # Create a User
Ken'ichi Ohmichi96508472015-03-23 01:43:42 +000033 u_name = data_utils.rand_name('user')
nayna-patelb35f7232013-06-28 07:08:44 +000034 u_desc = '%s-description' % u_name
Zack Feldsteind8c5f7a2015-12-14 10:44:07 -060035 u_password = data_utils.rand_password()
zhufl75d51a92017-04-11 16:02:39 +080036 user = self.create_test_user(
37 name=u_name, description=u_desc, password=u_password)
nayna-patelb35f7232013-06-28 07:08:44 +000038 # Perform Authentication
Jamie Lennox97504612015-02-26 16:47:06 +110039 resp = self.token.auth(user_id=user['id'],
40 password=u_password).response
nayna-patelb35f7232013-06-28 07:08:44 +000041 subject_token = resp['x-subject-token']
Pramod Kumar Singh1e8a0ed2017-06-02 16:21:10 +053042 self.client.check_token_existence(subject_token)
nayna-patelb35f7232013-06-28 07:08:44 +000043 # Perform GET Token
Ken'ichi Ohmichi402b8752015-11-09 10:47:16 +000044 token_details = self.client.show_token(subject_token)['token']
nayna-patelb35f7232013-06-28 07:08:44 +000045 self.assertEqual(resp['x-subject-token'], subject_token)
46 self.assertEqual(token_details['user']['id'], user['id'])
47 self.assertEqual(token_details['user']['name'], u_name)
48 # Perform Delete Token
David Kranze9d2f422014-07-02 13:57:41 -040049 self.client.delete_token(subject_token)
Pramod Kumar Singh1e8a0ed2017-06-02 16:21:10 +053050 self.assertRaises(lib_exc.NotFound, self.client.check_token_existence,
nayna-patelb35f7232013-06-28 07:08:44 +000051 subject_token)
52
Ken'ichi Ohmichieeabdd22017-01-27 17:46:00 -080053 @decorators.idempotent_id('565fa210-1da1-4563-999b-f7b5b67cf112')
Brant Knudsonc5553292014-03-15 11:06:05 -050054 def test_rescope_token(self):
Brant Knudson5ee44a42014-03-16 10:55:21 -050055 """Rescope a token.
56
57 An unscoped token can be requested, that token can be used to request a
58 scoped token. The scoped token can be revoked, and the original token
59 used to get a token in a different project.
60
Brant Knudsonc5553292014-03-15 11:06:05 -050061 """
62
63 # Create a user.
Zack Feldsteind8c5f7a2015-12-14 10:44:07 -060064 user_password = data_utils.rand_password()
zhufl75d51a92017-04-11 16:02:39 +080065 user = self.create_test_user(password=user_password)
Brant Knudsonc5553292014-03-15 11:06:05 -050066
Brant Knudson5ee44a42014-03-16 10:55:21 -050067 # Create a couple projects
Ken'ichi Ohmichi96508472015-03-23 01:43:42 +000068 project1_name = data_utils.rand_name(name='project')
zhuflf2f47052017-04-20 15:08:02 +080069 project1 = self.setup_test_project(name=project1_name)
Brant Knudson5ee44a42014-03-16 10:55:21 -050070
Ken'ichi Ohmichi96508472015-03-23 01:43:42 +000071 project2_name = data_utils.rand_name(name='project')
zhuflf2f47052017-04-20 15:08:02 +080072 project2 = self.setup_test_project(name=project2_name)
Yaroslav Lobankov47a93ab2016-02-07 16:32:49 -060073 self.addCleanup(self.projects_client.delete_project, project2['id'])
Brant Knudsonc5553292014-03-15 11:06:05 -050074
75 # Create a role
zhufl66b616a2017-04-11 15:00:32 +080076 role = self.setup_test_role()
Brant Knudsonc5553292014-03-15 11:06:05 -050077
Brant Knudson5ee44a42014-03-16 10:55:21 -050078 # Grant the user the role on both projects.
ghanshyam2e6fb562016-09-06 11:14:31 +090079 self.roles_client.create_user_role_on_project(project1['id'],
Arx Cruz24bcb882016-02-10 15:20:16 +010080 user['id'],
81 role['id'])
Brant Knudson5ee44a42014-03-16 10:55:21 -050082
ghanshyam2e6fb562016-09-06 11:14:31 +090083 self.roles_client.create_user_role_on_project(project2['id'],
Arx Cruz24bcb882016-02-10 15:20:16 +010084 user['id'],
85 role['id'])
Brant Knudsonc5553292014-03-15 11:06:05 -050086
87 # Get an unscoped token.
Jamie Lennox97504612015-02-26 16:47:06 +110088 token_auth = self.token.auth(user_id=user['id'],
David Kranzd8ccb792014-12-29 11:32:05 -050089 password=user_password)
Brant Knudsonc5553292014-03-15 11:06:05 -050090
David Kranzd8ccb792014-12-29 11:32:05 -050091 token_id = token_auth.response['x-subject-token']
Brant Knudsonc5553292014-03-15 11:06:05 -050092 orig_expires_at = token_auth['token']['expires_at']
Brant Knudsonc5553292014-03-15 11:06:05 -050093 orig_user = token_auth['token']['user']
94
Jordan Pittiere8791202016-04-25 18:12:16 +020095 self.assertIsInstance(token_auth['token']['expires_at'], six.text_type)
96 self.assertIsInstance(token_auth['token']['issued_at'], six.text_type)
Brant Knudsonc5553292014-03-15 11:06:05 -050097 self.assertEqual(['password'], token_auth['token']['methods'])
98 self.assertEqual(user['id'], token_auth['token']['user']['id'])
99 self.assertEqual(user['name'], token_auth['token']['user']['name'])
gongxiao5092b812017-04-14 08:50:32 +0800100 self.assertEqual(CONF.identity.default_domain_id,
Brant Knudsonc5553292014-03-15 11:06:05 -0500101 token_auth['token']['user']['domain']['id'])
gongxiao5092b812017-04-14 08:50:32 +0800102 self.assertIsNotNone(token_auth['token']['user']['domain']['name'])
Brant Knudsonc5553292014-03-15 11:06:05 -0500103 self.assertNotIn('catalog', token_auth['token'])
104 self.assertNotIn('project', token_auth['token'])
105 self.assertNotIn('roles', token_auth['token'])
106
107 # Use the unscoped token to get a scoped token.
gongxiao5092b812017-04-14 08:50:32 +0800108 token_auth = self.token.auth(
109 token=token_id,
110 project_name=project1_name,
111 project_domain_id=CONF.identity.default_domain_id)
David Kranzd8ccb792014-12-29 11:32:05 -0500112 token1_id = token_auth.response['x-subject-token']
Brant Knudsonc5553292014-03-15 11:06:05 -0500113
114 self.assertEqual(orig_expires_at, token_auth['token']['expires_at'],
115 'Expiration time should match original token')
Jordan Pittiere8791202016-04-25 18:12:16 +0200116 self.assertIsInstance(token_auth['token']['issued_at'], six.text_type)
Brant Knudsonc5553292014-03-15 11:06:05 -0500117 self.assertEqual(set(['password', 'token']),
118 set(token_auth['token']['methods']))
119 self.assertEqual(orig_user, token_auth['token']['user'],
120 'User should match original token')
121 self.assertIsInstance(token_auth['token']['catalog'], list)
Brant Knudson5ee44a42014-03-16 10:55:21 -0500122 self.assertEqual(project1['id'],
Brant Knudsonc5553292014-03-15 11:06:05 -0500123 token_auth['token']['project']['id'])
Brant Knudson5ee44a42014-03-16 10:55:21 -0500124 self.assertEqual(project1['name'],
Brant Knudsonc5553292014-03-15 11:06:05 -0500125 token_auth['token']['project']['name'])
gongxiao5092b812017-04-14 08:50:32 +0800126 self.assertEqual(CONF.identity.default_domain_id,
Brant Knudsonc5553292014-03-15 11:06:05 -0500127 token_auth['token']['project']['domain']['id'])
gongxiao5092b812017-04-14 08:50:32 +0800128 self.assertIsNotNone(token_auth['token']['project']['domain']['name'])
Brant Knudsonc5553292014-03-15 11:06:05 -0500129 self.assertEqual(1, len(token_auth['token']['roles']))
130 self.assertEqual(role['id'], token_auth['token']['roles'][0]['id'])
131 self.assertEqual(role['name'], token_auth['token']['roles'][0]['name'])
132
Brant Knudson5ee44a42014-03-16 10:55:21 -0500133 # Revoke the unscoped token.
David Kranze9d2f422014-07-02 13:57:41 -0400134 self.client.delete_token(token1_id)
Brant Knudson5ee44a42014-03-16 10:55:21 -0500135
136 # Now get another scoped token using the unscoped token.
gongxiao5092b812017-04-14 08:50:32 +0800137 token_auth = self.token.auth(
138 token=token_id,
139 project_name=project2_name,
140 project_domain_id=CONF.identity.default_domain_id)
Brant Knudson5ee44a42014-03-16 10:55:21 -0500141
142 self.assertEqual(project2['id'],
143 token_auth['token']['project']['id'])
144 self.assertEqual(project2['name'],
145 token_auth['token']['project']['name'])
ZhangHongtao74e1df52017-03-13 18:32:43 +0800146
147 @decorators.idempotent_id('08ed85ce-2ba8-4864-b442-bcc61f16ae89')
148 def test_get_available_project_scopes(self):
jeremy.zhang0343be52017-05-25 21:29:57 +0800149 manager_project_id = self.os_primary.credentials.project_id
Jordan Pittier8160d312017-04-18 11:52:23 +0200150 admin_user_id = self.os_admin.credentials.user_id
ZhangHongtao74e1df52017-03-13 18:32:43 +0800151 admin_role_id = self.get_role_by_name(CONF.identity.admin_role)['id']
152
153 # Grant the user the role on both projects.
154 self.roles_client.create_user_role_on_project(
155 manager_project_id, admin_user_id, admin_role_id)
156 self.addCleanup(
157 self.roles_client.delete_role_from_user_on_project,
158 manager_project_id, admin_user_id, admin_role_id)
159
Jordan Pittier8160d312017-04-18 11:52:23 +0200160 assigned_project_ids = [self.os_admin.credentials.project_id,
ZhangHongtao74e1df52017-03-13 18:32:43 +0800161 manager_project_id]
162
163 # Get available project scopes
164 available_projects =\
165 self.client.list_auth_projects()['projects']
166
167 # create list to save fetched project's id
168 fetched_project_ids = [i['id'] for i in available_projects]
169
170 # verifying the project ids in list
171 missing_project_ids = \
172 [p for p in assigned_project_ids
173 if p not in fetched_project_ids]
174 self.assertEmpty(missing_project_ids,
175 "Failed to find project_id %s in fetched list" %
176 ', '.join(missing_project_ids))