Change user passwd in CLI using interacive prompt

`fuel user change-password` now asks for password in interactive
prompt in unix `passwd` style, which is secure
comparing with passing new password as an argument to CLI.
Also tests added.

Change-Id: I88fd38e8bd0bb96dd9b596aa44fa3f7721ee6431
Closes-Bug: 1462343
This commit is contained in:
Sylwester Brzeczkowski
2015-08-06 14:18:45 +02:00
committed by Maciej Kwiek
parent 142dae5693
commit 62c569281c
3 changed files with 82 additions and 13 deletions

View File

@@ -12,6 +12,8 @@
# License for the specific language governing permissions and limitations
# under the License.
from getpass import getpass
from fuelclient.cli.actions.base import Action
import fuelclient.cli.arguments as Args
from fuelclient.cli.error import ArgumentException
@@ -27,19 +29,29 @@ class UserAction(Action):
super(UserAction, self).__init__()
self.args = (
Args.get_new_password_arg(),
Args.get_change_password_arg("Change user password")
Args.get_change_password_arg(
"Change user password. WARNING: This method of changing the "
"password is dangerous - it may be saved in bash history.")
)
self.flag_func_map = (
("change-password", self.change_password),
)
def _get_password_from_prompt(self):
password1 = getpass("Changing password for Fuel User.\nNew Password:")
password2 = getpass("Retype new Password:")
if password1 != password2:
raise ArgumentException("Passwords are not the same.")
return password1
def change_password(self, params):
"""To change user password:
fuel user change-password
"""
if params.newpass:
APIClient.update_own_password(params.newpass)
password = params.newpass
else:
raise ArgumentException(
"Expect password [--newpass NEWPASS]")
password = self._get_password_from_prompt()
APIClient.update_own_password(password)

View File

@@ -289,15 +289,6 @@ class TestHandlers(base.BaseTestCase):
)
class TestUserActions(base.BaseTestCase):
def test_change_password_params(self):
cmd = "user change-password"
msg = "Expect password [--newpass NEWPASS]"
result = self.run_cli_command(cmd, check_errors=False)
self.assertTrue(msg, result)
class TestCharset(base.BaseTestCase):
def test_charset_problem(self):

View File

@@ -0,0 +1,66 @@
# Copyright 2015 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import mock
from fuelclient.cli.actions.user import UserAction
from fuelclient.cli.error import ArgumentException
from fuelclient.tests import base
class TestChangePassword(base.UnitTestCase):
def test_get_password_from_prompt(self):
user_action = UserAction()
passwd = 'secret!'
with mock.patch('fuelclient.cli.actions.user.getpass',
return_value=passwd):
user_passwd = user_action._get_password_from_prompt()
self.assertEqual(passwd, user_passwd)
@mock.patch('fuelclient.cli.actions.user.getpass',
side_effect=['pwd', 'otherpwd'])
def test_get_password_from_prompt_different_passwords(self, mgetpass):
user_action = UserAction()
with self.assertRaisesRegexp(
ArgumentException, 'Passwords are not the same'):
user_action._get_password_from_prompt()
@mock.patch('fuelclient.cli.actions.user.APIClient')
def test_change_password(self, mapiclient):
user_action = UserAction()
params = mock.Mock()
params.newpass = None
password = 'secret'
with mock.patch('fuelclient.cli.actions.user.getpass',
return_value=password) as mgetpass:
user_action.change_password(params)
calls = [
mock.call("Changing password for Fuel User.\nNew Password:"),
mock.call("Retype new Password:"),
]
mgetpass.assert_has_calls(calls)
mapiclient.update_own_password.assert_called_once_with(password)
@mock.patch('fuelclient.cli.actions.user.APIClient')
def test_change_password_w_newpass(self, mapiclient):
user_action = UserAction()
params = mock.Mock()
params.newpass = 'secret'
user_action.change_password(params)
mapiclient.update_own_password.assert_called_once_with(params.newpass)