Add action 'user password set' for identiy v3

This new action will allow a user to change their own password by
either providing the new password as an argument (--password) or by
being prompted to enter the new password.
In both cases user will be prompted to enter their current password
as required by the v3 API.

Closes-Bug: #1337245
Change-Id: I5e1e0fd2b46a4502318da57f7cce2b236fb2d93d
This commit is contained in:
Mouad Benchchaoui 2014-07-10 13:23:35 +02:00 committed by Steve Martinelli
parent 8e12949958
commit 0069adef5c
4 changed files with 84 additions and 3 deletions

View File

@ -233,12 +233,15 @@ def get_effective_log_level():
return min_log_lvl
def get_password(stdin):
def get_password(stdin, prompt=None, confirm=True):
message = prompt or "User Password:"
if hasattr(stdin, 'isatty') and stdin.isatty():
try:
while True:
first_pass = getpass.getpass("User password: ")
second_pass = getpass.getpass("Repeat user password: ")
first_pass = getpass.getpass(message)
if not confirm:
return first_pass
second_pass = getpass.getpass("Repeat " + message)
if first_pass == second_pass:
return first_pass
print("The passwords entered were not the same")

View File

@ -323,6 +323,35 @@ class SetUser(command.Command):
return
class SetPasswordUser(command.Command):
"""Change current user password"""
log = logging.getLogger(__name__ + '.SetPasswordUser')
def get_parser(self, prog_name):
parser = super(SetPasswordUser, self).get_parser(prog_name)
parser.add_argument(
'--password',
metavar='<new-password>',
help='New user password'
)
return parser
def take_action(self, parsed_args):
self.log.debug('take_action(%s)', parsed_args)
identity_client = self.app.client_manager.identity
current_password = utils.get_password(
self.app.stdin, prompt="Current Password:", confirm=False)
password = parsed_args.password
if password is None:
password = utils.get_password(
self.app.stdin, prompt="New Password:")
identity_client.users.update_password(current_password, password)
class ShowUser(show.ShowOne):
"""Show user details"""

View File

@ -13,7 +13,9 @@
# under the License.
#
import contextlib
import copy
import mock
from openstackclient.identity.v3 import user
@ -944,6 +946,52 @@ class TestUserSet(TestUser):
)
class TestUserSetPassword(TestUser):
def setUp(self):
super(TestUserSetPassword, self).setUp()
self.cmd = user.SetPasswordUser(self.app, None)
@staticmethod
@contextlib.contextmanager
def _mock_get_password(*passwords):
mocker = mock.Mock(side_effect=passwords)
with mock.patch("openstackclient.common.utils.get_password", mocker):
yield
def test_user_password_change(self):
current_pass = 'old_pass'
new_pass = 'new_pass'
arglist = [
'--password', new_pass,
]
verifylist = [
('password', new_pass),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
# Mock getting user current password.
with self._mock_get_password(current_pass):
self.cmd.take_action(parsed_args)
self.users_mock.update_password.assert_called_with(
current_pass, new_pass
)
def test_user_create_password_prompt(self):
current_pass = 'old_pass'
new_pass = 'new_pass'
parsed_args = self.check_parser(self.cmd, [], [])
# Mock getting user current and new password.
with self._mock_get_password(current_pass, new_pass):
self.cmd.take_action(parsed_args)
self.users_mock.update_password.assert_called_with(
current_pass, new_pass
)
class TestUserShow(TestUser):
def setUp(self):

View File

@ -242,6 +242,7 @@ openstack.identity.v3 =
user_delete = openstackclient.identity.v3.user:DeleteUser
user_list = openstackclient.identity.v3.user:ListUser
user_set = openstackclient.identity.v3.user:SetUser
user_password_set = openstackclient.identity.v3.user:SetPasswordUser
user_show = openstackclient.identity.v3.user:ShowUser
openstack.image.v1 =