blob: a63b45ca6f1a1275a95c61f56d00917f195da091 [file] [log] [blame]
Jane Zadorozhna9c938c62015-07-01 17:06:16 +03001# Copyright 2015 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
Lance Bragstada2c4ebc2015-10-05 20:34:39 +000016import time
Jane Zadorozhna9c938c62015-07-01 17:06:16 +030017
nicolasc98a3252018-12-17 13:06:02 -080018import testtools
19
Jane Zadorozhna9c938c62015-07-01 17:06:16 +030020from tempest.api.identity import base
Rodrigo Duarte Sousa2d78e8e2016-09-28 10:38:08 -030021from tempest import config
Andrea Frittoli (andreaf)db9672e2016-02-23 14:07:24 -050022from tempest.lib.common.utils import data_utils
Ken'ichi Ohmichieeabdd22017-01-27 17:46:00 -080023from tempest.lib import decorators
Andrea Frittoli (andreaf)db9672e2016-02-23 14:07:24 -050024from tempest.lib import exceptions
Jane Zadorozhna9c938c62015-07-01 17:06:16 +030025
26
Rodrigo Duarte Sousa2d78e8e2016-09-28 10:38:08 -030027CONF = config.CONF
28
29
Jane Zadorozhna9c938c62015-07-01 17:06:16 +030030class IdentityUsersTest(base.BaseIdentityV2Test):
zhufl8e3aacd2020-04-27 14:46:46 +080031 """Test user password in identity v2 API"""
Jane Zadorozhna9c938c62015-07-01 17:06:16 +030032
33 @classmethod
34 def resource_setup(cls):
35 super(IdentityUsersTest, cls).resource_setup()
Jordan Pittier8160d312017-04-18 11:52:23 +020036 cls.creds = cls.os_primary.credentials
Jane Zadorozhna9c938c62015-07-01 17:06:16 +030037 cls.username = cls.creds.username
38 cls.password = cls.creds.password
39 cls.tenant_name = cls.creds.tenant_name
40
Rodrigo Duarte Sousa2d78e8e2016-09-28 10:38:08 -030041 def _update_password(self, user_id, original_password, password):
Daniel Mellado82c83a52015-12-09 15:16:49 +000042 self.non_admin_users_client.update_user_own_password(
Rodrigo Duarte Sousa2d78e8e2016-09-28 10:38:08 -030043 user_id, password=password, original_password=original_password)
44
Morgan Fainberg5b2c7452016-02-02 20:15:47 -080045 # NOTE(morganfainberg): Fernet tokens are not subsecond aware and
46 # Keystone should only be precise to the second. Sleep to ensure
Yaroslav Lobankovcbcb6112016-03-08 12:30:01 -060047 # we are passing the second boundary.
Lance Bragstada2c4ebc2015-10-05 20:34:39 +000048 time.sleep(1)
49
Jane Zadorozhna9c938c62015-07-01 17:06:16 +030050 # check authorization with new password
51 self.non_admin_token_client.auth(self.username,
Rodrigo Duarte Sousa2d78e8e2016-09-28 10:38:08 -030052 password,
Jane Zadorozhna9c938c62015-07-01 17:06:16 +030053 self.tenant_name)
54
Rodrigo Duarte Sousa2d78e8e2016-09-28 10:38:08 -030055 # Reset auth to get a new token with the new password
56 self.non_admin_users_client.auth_provider.clear_auth()
57 self.non_admin_users_client.auth_provider.credentials.password = (
58 password)
59
60 def _restore_password(self, user_id, old_pass, new_pass):
61 if CONF.identity_feature_enabled.security_compliance:
62 # First we need to clear the password history
63 unique_count = CONF.identity.user_unique_last_password_count
zhufl8e9a0732017-01-26 16:15:21 +080064 for _ in range(unique_count):
Rodrigo Duarte Sousa2d78e8e2016-09-28 10:38:08 -030065 random_pass = data_utils.rand_password()
66 self._update_password(
67 user_id, original_password=new_pass, password=random_pass)
68 new_pass = random_pass
69
70 self._update_password(
71 user_id, original_password=new_pass, password=old_pass)
72 # Reset auth again to verify the password restore does work.
73 # Clear auth restores the original credentials and deletes
74 # cached auth data
75 self.non_admin_users_client.auth_provider.clear_auth()
76 # NOTE(lbragstad): Fernet tokens are not subsecond aware and
77 # Keystone should only be precise to the second. Sleep to ensure we
78 # are passing the second boundary before attempting to
79 # authenticate.
80 time.sleep(1)
81 self.non_admin_users_client.auth_provider.set_auth()
82
Ken'ichi Ohmichieeabdd22017-01-27 17:46:00 -080083 @decorators.idempotent_id('165859c9-277f-4124-9479-a7d1627b0ca7')
nicolasc98a3252018-12-17 13:06:02 -080084 @testtools.skipIf(CONF.identity_feature_enabled.immutable_user_source,
85 'Skipped because environment has an '
86 'immutable user source and solely '
87 'provides read-only access to users.')
Rodrigo Duarte Sousa2d78e8e2016-09-28 10:38:08 -030088 def test_user_update_own_password(self):
zhufl8e3aacd2020-04-27 14:46:46 +080089 """test updating user's own password via v2 API"""
Rodrigo Duarte Sousa2d78e8e2016-09-28 10:38:08 -030090 old_pass = self.creds.password
91 old_token = self.non_admin_users_client.token
92 new_pass = data_utils.rand_password()
93 user_id = self.creds.user_id
94
Ken'ichi Ohmichi553d7cb2018-07-13 22:53:03 +000095 # to change password back. important for use_dynamic_credentials=false
Rodrigo Duarte Sousa2d78e8e2016-09-28 10:38:08 -030096 self.addCleanup(self._restore_password, user_id, old_pass, new_pass)
97
98 # user updates own password
99 self._update_password(
100 user_id, original_password=old_pass, password=new_pass)
101
Jane Zadorozhna9c938c62015-07-01 17:06:16 +0300102 # authorize with old token should lead to Unauthorized
103 self.assertRaises(exceptions.Unauthorized,
104 self.non_admin_token_client.auth_token,
Rodrigo Duarte Sousa2d78e8e2016-09-28 10:38:08 -0300105 old_token)
Jane Zadorozhna9c938c62015-07-01 17:06:16 +0300106
107 # authorize with old password should lead to Unauthorized
108 self.assertRaises(exceptions.Unauthorized,
109 self.non_admin_token_client.auth,
110 self.username,
111 old_pass,
112 self.tenant_name)