blob: fe3eb032efeb1cef905182b3d2fb7e1af0b588ab [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
16from tempest.api.identity import base
Masayuki Igawa259c1132013-10-31 17:48:44 +090017from tempest.common.utils import data_utils
nayna-patelb35f7232013-06-28 07:08:44 +000018from tempest import exceptions
Matthew Treinish5c660ab2014-05-18 21:14:36 -040019from tempest import test
nayna-patelb35f7232013-06-28 07:08:44 +000020
21
Masayuki Igawabe64ed32014-02-19 14:32:03 +090022class TokensV3TestJSON(base.BaseIdentityV3AdminTest):
nayna-patelb35f7232013-06-28 07:08:44 +000023 _interface = 'json'
24
Matthew Treinish5c660ab2014-05-18 21:14:36 -040025 @test.attr(type='smoke')
nayna-patelb35f7232013-06-28 07:08:44 +000026 def test_tokens(self):
27 # Valid user's token is authenticated
28 # Create a User
Masayuki Igawa259c1132013-10-31 17:48:44 +090029 u_name = data_utils.rand_name('user-')
nayna-patelb35f7232013-06-28 07:08:44 +000030 u_desc = '%s-description' % u_name
31 u_email = '%s@testmail.tm' % u_name
Masayuki Igawa259c1132013-10-31 17:48:44 +090032 u_password = data_utils.rand_name('pass-')
Matthew Treinishdb2c5972014-01-31 22:18:59 +000033 resp, user = self.client.create_user(
nayna-patelb35f7232013-06-28 07:08:44 +000034 u_name, description=u_desc, password=u_password,
35 email=u_email)
Brant Knudsonc5553292014-03-15 11:06:05 -050036 self.assertEqual(201, resp.status)
Matthew Treinishdb2c5972014-01-31 22:18:59 +000037 self.addCleanup(self.client.delete_user, user['id'])
nayna-patelb35f7232013-06-28 07:08:44 +000038 # Perform Authentication
Matthew Treinishdb2c5972014-01-31 22:18:59 +000039 resp, body = self.token.auth(user['id'], u_password)
Brant Knudsonc5553292014-03-15 11:06:05 -050040 self.assertEqual(201, resp.status)
nayna-patelb35f7232013-06-28 07:08:44 +000041 subject_token = resp['x-subject-token']
42 # Perform GET Token
Matthew Treinishdb2c5972014-01-31 22:18:59 +000043 resp, token_details = self.client.get_token(subject_token)
Brant Knudsonc5553292014-03-15 11:06:05 -050044 self.assertEqual(200, resp.status)
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
Matthew Treinishdb2c5972014-01-31 22:18:59 +000049 resp, _ = self.client.delete_token(subject_token)
50 self.assertRaises(exceptions.NotFound, self.client.get_token,
nayna-patelb35f7232013-06-28 07:08:44 +000051 subject_token)
52
Matthew Treinish5c660ab2014-05-18 21:14:36 -040053 @test.attr(type='gate')
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.
64 user_name = data_utils.rand_name(name='user-')
65 user_password = data_utils.rand_name(name='pass-')
66 resp, user = self.client.create_user(user_name, password=user_password)
67 self.assertEqual(201, resp.status)
68 self.addCleanup(self.client.delete_user, user['id'])
69
Brant Knudson5ee44a42014-03-16 10:55:21 -050070 # Create a couple projects
71 project1_name = data_utils.rand_name(name='project-')
72 resp, project1 = self.client.create_project(project1_name)
Brant Knudsonc5553292014-03-15 11:06:05 -050073 self.assertEqual(201, resp.status)
Brant Knudson5ee44a42014-03-16 10:55:21 -050074 self.addCleanup(self.client.delete_project, project1['id'])
75
76 project2_name = data_utils.rand_name(name='project-')
77 resp, project2 = self.client.create_project(project2_name)
78 self.assertEqual(201, resp.status)
79 self.addCleanup(self.client.delete_project, project2['id'])
Brant Knudsonc5553292014-03-15 11:06:05 -050080
81 # Create a role
82 role_name = data_utils.rand_name(name='role-')
83 resp, role = self.client.create_role(role_name)
84 self.assertEqual(201, resp.status)
85 self.addCleanup(self.client.delete_role, role['id'])
86
Brant Knudson5ee44a42014-03-16 10:55:21 -050087 # Grant the user the role on both projects.
88 resp, _ = self.client.assign_user_role(project1['id'], user['id'],
89 role['id'])
90 self.assertEqual(204, resp.status)
91
92 resp, _ = self.client.assign_user_role(project2['id'], user['id'],
Brant Knudsonc5553292014-03-15 11:06:05 -050093 role['id'])
94 self.assertEqual(204, resp.status)
95
96 # Get an unscoped token.
97 resp, token_auth = self.token.auth(user=user['id'],
98 password=user_password)
99 self.assertEqual(201, resp.status)
100
101 token_id = resp['x-subject-token']
102 orig_expires_at = token_auth['token']['expires_at']
103 orig_issued_at = token_auth['token']['issued_at']
104 orig_user = token_auth['token']['user']
105
106 self.assertIsInstance(token_auth['token']['expires_at'], unicode)
107 self.assertIsInstance(token_auth['token']['issued_at'], unicode)
108 self.assertEqual(['password'], token_auth['token']['methods'])
109 self.assertEqual(user['id'], token_auth['token']['user']['id'])
110 self.assertEqual(user['name'], token_auth['token']['user']['name'])
111 self.assertEqual('default',
112 token_auth['token']['user']['domain']['id'])
113 self.assertEqual('Default',
114 token_auth['token']['user']['domain']['name'])
115 self.assertNotIn('catalog', token_auth['token'])
116 self.assertNotIn('project', token_auth['token'])
117 self.assertNotIn('roles', token_auth['token'])
118
119 # Use the unscoped token to get a scoped token.
Brant Knudson5ee44a42014-03-16 10:55:21 -0500120 resp, token_auth = self.token.auth(token=token_id,
121 tenant=project1_name,
Brant Knudsonc5553292014-03-15 11:06:05 -0500122 domain='Default')
Brant Knudson5ee44a42014-03-16 10:55:21 -0500123 token1_id = resp['x-subject-token']
Brant Knudsonc5553292014-03-15 11:06:05 -0500124 self.assertEqual(201, resp.status)
125
126 self.assertEqual(orig_expires_at, token_auth['token']['expires_at'],
127 'Expiration time should match original token')
128 self.assertIsInstance(token_auth['token']['issued_at'], unicode)
129 self.assertNotEqual(orig_issued_at, token_auth['token']['issued_at'])
130 self.assertEqual(set(['password', 'token']),
131 set(token_auth['token']['methods']))
132 self.assertEqual(orig_user, token_auth['token']['user'],
133 'User should match original token')
134 self.assertIsInstance(token_auth['token']['catalog'], list)
Brant Knudson5ee44a42014-03-16 10:55:21 -0500135 self.assertEqual(project1['id'],
Brant Knudsonc5553292014-03-15 11:06:05 -0500136 token_auth['token']['project']['id'])
Brant Knudson5ee44a42014-03-16 10:55:21 -0500137 self.assertEqual(project1['name'],
Brant Knudsonc5553292014-03-15 11:06:05 -0500138 token_auth['token']['project']['name'])
139 self.assertEqual('default',
140 token_auth['token']['project']['domain']['id'])
141 self.assertEqual('Default',
142 token_auth['token']['project']['domain']['name'])
143 self.assertEqual(1, len(token_auth['token']['roles']))
144 self.assertEqual(role['id'], token_auth['token']['roles'][0]['id'])
145 self.assertEqual(role['name'], token_auth['token']['roles'][0]['name'])
146
Brant Knudson5ee44a42014-03-16 10:55:21 -0500147 # Revoke the unscoped token.
148 resp, _ = self.client.delete_token(token1_id)
149 self.assertEqual(204, resp.status)
150
151 # Now get another scoped token using the unscoped token.
152 resp, token_auth = self.token.auth(token=token_id,
153 tenant=project2_name,
154 domain='Default')
155 self.assertEqual(201, resp.status)
156
157 self.assertEqual(project2['id'],
158 token_auth['token']['project']['id'])
159 self.assertEqual(project2['name'],
160 token_auth['token']['project']['name'])
161
nayna-patelb35f7232013-06-28 07:08:44 +0000162
Masayuki Igawabe64ed32014-02-19 14:32:03 +0900163class TokensV3TestXML(TokensV3TestJSON):
nayna-patelb35f7232013-06-28 07:08:44 +0000164 _interface = 'xml'