Add configurable option for the user password length

Add configurable option for the user password length of the user
defined by the `username` config option. The following parameter
has been added:
- user_password_length: type=int, default=20

The current default password length is 20, making it cumbersome for
users to enter the lengthy password via console.

Change-Id: I37ae75a438f6fd326101c7b8a855c1f39dd1e804
Closes-bug: #1684119
This commit is contained in:
Paula Madalina Crismaru 2017-04-20 10:54:54 +03:00
parent 68a9ae57d4
commit 894b800d31
7 changed files with 43 additions and 19 deletions

View File

@ -291,6 +291,10 @@ class GlobalOptions(conf_base.Options):
help='Ephemeral disk data loss warning path, relative to the '
'ephemeral disk volume path. E.g.: '
'DATALOSS_WARNING_README.txt'),
cfg.IntOpt(
'user_password_length', default=20,
help='The length of the generated password for the user '
'defined by the `username` config option.'),
]
self._cli_options = [

View File

@ -1227,6 +1227,9 @@ class WindowsUtils(base.BaseOSUtils):
:volume_path_names_len.value - 1].split('\0') if n]
def generate_random_password(self, length):
if length < 3:
raise exception.CloudbaseInitException(
"Password can not have less than 3 characters!")
while True:
pwd = super(WindowsUtils, self).generate_random_password(length)
# Make sure that the Windows complexity requirements are met:

View File

@ -50,8 +50,7 @@ class BaseCreateUserPlugin(base.BasePlugin):
def _get_password(osutils):
# Generate a temporary random password to be replaced
# by SetUserPasswordPlugin (starting from Grizzly)
maximum_length = osutils.get_maximum_password_length()
return osutils.generate_random_password(maximum_length)
return osutils.generate_random_password(CONF.user_password_length)
def execute(self, service, shared_data):
user_name = service.get_admin_username() or CONF.username

View File

@ -90,9 +90,8 @@ class SetUserPasswordPlugin(base.BasePlugin):
password, injected = self._get_password(service, shared_data)
if not password:
LOG.debug('Generating a random user password')
maximum_length = osutils.get_maximum_password_length()
password = osutils.generate_random_password(
maximum_length)
CONF.user_password_length)
osutils.set_user_password(user_name, password)
self._change_logon_behaviour(user_name, password_injected=injected)

View File

@ -1376,6 +1376,12 @@ class TestWindowsUtils(testutils.CloudbaseInitTestBase):
mock_generate_random_password.assert_called_once_with(length)
self.assertEqual('Passw0rd', response)
def test_generate_random_password_less_than_3(self):
with self.assertRaises(exception.CloudbaseInitException) as ex:
self._winutils.generate_random_password(2)
self.assertEqual(str(ex.exception),
"Password can not have less than 3 characters!")
def _test_get_logical_drives(self, buf_length, last_error=None):
mock_buf = mock.MagicMock()
mock_buf.__getitem__.side_effect = ['1', '\x00']

View File

@ -42,13 +42,17 @@ class CreateUserPluginTests(unittest.TestCase):
self._create_user = CreateUserPlugin()
def test_get_password(self):
password = "fake password"
mock_osutils = mock.MagicMock()
mock_osutils.generate_random_password.return_value = 'fake password'
response = self._create_user._get_password(mock_osutils)
mock_osutils.get_maximum_password_length.assert_called_once_with()
length = mock_osutils.get_maximum_password_length()
mock_osutils.generate_random_password.assert_called_once_with(length)
self.assertEqual('fake password', response)
max_length = len(password)
mock_osutils.generate_random_password.return_value = "*" * max_length
with testutils.ConfPatcher('user_password_length', len(password)):
response = self._create_user._get_password(mock_osutils)
mock_osutils.generate_random_password.assert_called_once_with(
max_length)
self.assertEqual("*" * max_length, response)
self.assertEqual(len(response), max_length)
@testutils.ConfPatcher('groups', ['Admins'])
@mock.patch('cloudbaseinit.osutils.factory.get_os_utils')

View File

@ -173,7 +173,8 @@ class SetUserPasswordPluginTests(unittest.TestCase):
def _test_set_password(self, mock_get_password,
mock_change_logon_behaviour,
password, can_update_password,
is_password_changed, injected=False):
is_password_changed, max_password_length=20,
injected=False):
expected_password = password
expected_logging = []
user = 'fake_user'
@ -182,16 +183,20 @@ class SetUserPasswordPluginTests(unittest.TestCase):
mock_service = mock.MagicMock()
mock_osutils = mock.MagicMock()
mock_osutils.get_maximum_password_length.return_value = None
if not password:
expected_password = "*" * CONF.user_password_length
mock_osutils.generate_random_password.return_value = expected_password
mock_service.can_update_password = can_update_password
mock_service.is_password_changed.return_value = is_password_changed
with testutils.LogSnatcher('cloudbaseinit.plugins.common.'
'setuserpassword') as snatcher:
response = self._setpassword_plugin._set_password(
mock_service, mock_osutils, user,
mock.sentinel.shared_data)
with testutils.ConfPatcher('user_password_length',
max_password_length):
with testutils.LogSnatcher('cloudbaseinit.plugins.common.'
'setuserpassword') as snatcher:
response = self._setpassword_plugin._set_password(
mock_service, mock_osutils, user,
mock.sentinel.shared_data)
if can_update_password and not is_password_changed:
expected_logging.append('Updating password is not required.')
@ -199,7 +204,6 @@ class SetUserPasswordPluginTests(unittest.TestCase):
if not password:
expected_logging.append('Generating a random user password')
expected_password = password
if not can_update_password or is_password_changed:
mock_get_password.assert_called_once_with(
@ -217,7 +221,12 @@ class SetUserPasswordPluginTests(unittest.TestCase):
is_password_changed=False)
self._test_set_password(password=None,
can_update_password=False,
is_password_changed=False)
is_password_changed=False,
max_password_length=25)
self._test_set_password(password=None,
can_update_password=False,
is_password_changed=False,
max_password_length=10)
self._test_set_password(password='Password',
can_update_password=True,
is_password_changed=True)