You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1094 lines
36 KiB
1094 lines
36 KiB
<?php
|
|
/*
|
|
** Zabbix
|
|
** Copyright (C) 2001-2023 Zabbix SIA
|
|
**
|
|
** This program is free software; you can redistribute it and/or modify
|
|
** it under the terms of the GNU General Public License as published by
|
|
** the Free Software Foundation; either version 2 of the License, or
|
|
** (at your option) any later version.
|
|
**
|
|
** This program is distributed in the hope that it will be useful,
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
** GNU General Public License for more details.
|
|
**
|
|
** You should have received a copy of the GNU General Public License
|
|
** along with this program; if not, write to the Free Software
|
|
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
**/
|
|
|
|
|
|
require_once dirname(__FILE__).'/../../include/CWebTest.php';
|
|
require_once dirname(__FILE__).'/../behaviors/CMessageBehavior.php';
|
|
|
|
/**
|
|
* @onBefore prepareUserData
|
|
*
|
|
* @backup config, users
|
|
*/
|
|
class testUsersPasswordComplexity extends CWebTest {
|
|
|
|
const ACTION_UPDATE = true;
|
|
const OWN_PASSWORD = true;
|
|
const ADMIN_USERID = 1;
|
|
|
|
/**
|
|
* Attach MessageBehavior to the test.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getBehaviors() {
|
|
return ['class' => CMessageBehavior::class];
|
|
}
|
|
|
|
/**
|
|
* Id of user that created for future updating.
|
|
*
|
|
* @var integer
|
|
*/
|
|
protected static $userid;
|
|
|
|
/**
|
|
* Password for user which is being changed in scenarios.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected static $user_password = 'Iamrobot1!';
|
|
|
|
/**
|
|
* Password for Admin which is being changed in scenarios.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected static $admin_password = 'zabbix';
|
|
|
|
/**
|
|
* Add user for updating.
|
|
*/
|
|
public function prepareUserData() {
|
|
$response = CDataHelper::call('user.create', [
|
|
[
|
|
'username' => 'update-user',
|
|
'passwd' => 'Iamrobot1!',
|
|
'autologin' => 1,
|
|
'autologout' => 0,
|
|
'roleid' => 1,
|
|
'usrgrps' => [
|
|
[
|
|
'usrgrpid' => '7'
|
|
]
|
|
]
|
|
]
|
|
]);
|
|
|
|
$this->assertArrayHasKey('userids', $response);
|
|
self::$userid = $response['userids'][0];
|
|
}
|
|
|
|
public function getFormValidationData() {
|
|
return [
|
|
[
|
|
[
|
|
'expected' => TEST_BAD,
|
|
'fields' => ['Minimum password length' => '0']
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'expected' => TEST_BAD,
|
|
'fields' => ['Minimum password length' => '71']
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'expected' => TEST_BAD,
|
|
'fields' => ['Minimum password length' => '-ab']
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'expected' => TEST_BAD,
|
|
'fields' => ['Minimum password length' => '!@']
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'expected' => TEST_BAD,
|
|
'fields' => ['Minimum password length' => '']
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'fields' => ['Minimum password length' => '1'],
|
|
'db_passwd_min_length' => 1
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'fields' => ['Minimum password length' => '50'],
|
|
'db_passwd_min_length' => 50
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'fields' => ['Minimum password length' => '70'],
|
|
'db_passwd_min_length' => 70
|
|
]
|
|
],
|
|
// Negative number will be converted to positive when focus-out.
|
|
[
|
|
[
|
|
'fields' => ['Minimum password length' => '-8'],
|
|
'db_passwd_min_length' => 8
|
|
]
|
|
]
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Check password form fields validation.
|
|
*
|
|
* @dataProvider getFormValidationData
|
|
*/
|
|
public function testUsersPasswordComplexity_FormValidation($data) {
|
|
if (CTestArrayHelper::get($data, 'expected', TEST_GOOD) === TEST_BAD) {
|
|
$old_hash = CDBHelper::getHash('SELECT * FROM config');
|
|
}
|
|
|
|
$this->page->login()->open('zabbix.php?action=authentication.edit');
|
|
$form = $this->query('id:authentication-form')->asForm()->one();
|
|
$form->fill($data['fields']);
|
|
$form->submit();
|
|
|
|
if (CTestArrayHelper::get($data, 'expected', TEST_GOOD) === TEST_BAD) {
|
|
$this->assertMessage(TEST_BAD, 'Cannot update authentication',
|
|
'Invalid parameter "/passwd_min_length": value must be one of 1-70.'
|
|
);
|
|
$this->assertEquals($old_hash, CDBHelper::getHash('SELECT * FROM config'));
|
|
}
|
|
else {
|
|
$this->assertMessage(TEST_GOOD, 'Authentication settings updated');
|
|
// Check length fields saved in db, other fields remained default.
|
|
$db_expected = ['passwd_min_length' => $data['db_passwd_min_length'], 'passwd_check_rules' => 8];
|
|
$this->assertEquals([$db_expected],
|
|
CDBHelper::getAll('SELECT passwd_min_length, passwd_check_rules FROM config')
|
|
);
|
|
}
|
|
}
|
|
|
|
public function getCommonPasswordData() {
|
|
return [
|
|
[
|
|
// Check default password complexity settings.
|
|
[
|
|
'auth_fields' => [
|
|
'Minimum password length' => '8',
|
|
'id:passwd_check_rules_case' => false,
|
|
'id:passwd_check_rules_digits' => false,
|
|
'id:passwd_check_rules_special' => false,
|
|
'id:passwd_check_rules_simple' => true
|
|
],
|
|
'db_passwd_check_rules' => 8,
|
|
'Password' => 'iamrobot',
|
|
'hint' => "Password requirements:".
|
|
"\nmust be at least 8 characters long".
|
|
"\nmust not contain user's name, surname or username".
|
|
"\nmust not be one of common or context-specific passwords"
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'auth_fields' => [
|
|
'Minimum password length' => '1',
|
|
'id:passwd_check_rules_case' => false,
|
|
'id:passwd_check_rules_digits' => false,
|
|
'id:passwd_check_rules_special' => false,
|
|
'id:passwd_check_rules_simple' => false
|
|
],
|
|
'db_passwd_check_rules' => 0,
|
|
'Password' => 'a'
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'auth_fields' => [
|
|
'Minimum password length' => '1',
|
|
'id:passwd_check_rules_case' => true,
|
|
'id:passwd_check_rules_digits' => true,
|
|
'id:passwd_check_rules_special' => true,
|
|
'id:passwd_check_rules_simple' => true
|
|
],
|
|
'db_passwd_check_rules' => 15,
|
|
'Password' => 'aA1!',
|
|
'hint' => "Password requirements:".
|
|
"\nmust contain at least one lowercase and one uppercase Latin letter (A-Z, a-z)".
|
|
"\nmust contain at least one digit (0-9)".
|
|
"\nmust contain at least one special character ( !\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~)".
|
|
"\nmust not contain user's name, surname or username".
|
|
"\nmust not be one of common or context-specific passwords"
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'expected' => TEST_BAD,
|
|
'auth_fields' => [
|
|
'Minimum password length' => '1',
|
|
'id:passwd_check_rules_case' => true,
|
|
'id:passwd_check_rules_digits' => true,
|
|
'id:passwd_check_rules_special' => true,
|
|
'id:passwd_check_rules_simple' => true
|
|
],
|
|
'db_passwd_check_rules' => 15,
|
|
'Password' => '',
|
|
'hint' => "Password requirements:".
|
|
"\nmust contain at least one lowercase and one uppercase Latin letter (A-Z, a-z)".
|
|
"\nmust contain at least one digit (0-9)".
|
|
"\nmust contain at least one special character ( !\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~)".
|
|
"\nmust not contain user's name, surname or username".
|
|
"\nmust not be one of common or context-specific passwords",
|
|
'error' => 'Incorrect value for field "Password": cannot be empty.'
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'expected' => TEST_BAD,
|
|
'auth_fields' => [
|
|
'Minimum password length' => '1',
|
|
'id:passwd_check_rules_case' => true,
|
|
'id:passwd_check_rules_digits' => true,
|
|
'id:passwd_check_rules_special' => true,
|
|
'id:passwd_check_rules_simple' => true
|
|
],
|
|
'db_passwd_check_rules' => 15,
|
|
'Password' => 'a',
|
|
'hint' => "Password requirements:".
|
|
"\nmust contain at least one lowercase and one uppercase Latin letter (A-Z, a-z)".
|
|
"\nmust contain at least one digit (0-9)".
|
|
"\nmust contain at least one special character ( !\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~)".
|
|
"\nmust not contain user's name, surname or username".
|
|
"\nmust not be one of common or context-specific passwords",
|
|
'error' => 'Incorrect value for field "/1/passwd": must contain at least one lowercase and one uppercase Latin letter.'
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'expected' => TEST_BAD,
|
|
'auth_fields' => [
|
|
'Minimum password length' => '1',
|
|
'id:passwd_check_rules_case' => false,
|
|
'id:passwd_check_rules_digits' => false,
|
|
'id:passwd_check_rules_special' => false,
|
|
'id:passwd_check_rules_simple' => false
|
|
],
|
|
'db_passwd_check_rules' => 0,
|
|
'Password' => '',
|
|
'error' => 'Incorrect value for field "Password": cannot be empty.'
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'auth_fields' => [
|
|
'Minimum password length' => '3',
|
|
'id:passwd_check_rules_case' => true,
|
|
'id:passwd_check_rules_digits' => false,
|
|
'id:passwd_check_rules_special' => false,
|
|
'id:passwd_check_rules_simple' => false
|
|
],
|
|
'db_passwd_check_rules' => 1,
|
|
'Password' => 'Tes',
|
|
'hint' => "Password requirements:".
|
|
"\nmust be at least 3 characters long".
|
|
"\nmust contain at least one lowercase and one uppercase Latin letter (A-Z, a-z)"
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'expected' => TEST_BAD,
|
|
'auth_fields' => [
|
|
'Minimum password length' => '3',
|
|
'id:passwd_check_rules_case' => true,
|
|
'id:passwd_check_rules_digits' => false,
|
|
'id:passwd_check_rules_special' => false,
|
|
'id:passwd_check_rules_simple' => false
|
|
],
|
|
'db_passwd_check_rules' => 1,
|
|
'Password' => 'Te',
|
|
'hint' => "Password requirements:".
|
|
"\nmust be at least 3 characters long".
|
|
"\nmust contain at least one lowercase and one uppercase Latin letter (A-Z, a-z)",
|
|
'error' => 'Incorrect value for field "/1/passwd": must be at least 3 characters long.'
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'expected' => TEST_BAD,
|
|
'auth_fields' => [
|
|
'Minimum password length' => '2',
|
|
'id:passwd_check_rules_case' => true,
|
|
'id:passwd_check_rules_digits' => false,
|
|
'id:passwd_check_rules_special' => false,
|
|
'id:passwd_check_rules_simple' => false
|
|
],
|
|
'db_passwd_check_rules' => 1,
|
|
'Password' => 'tes',
|
|
'hint' => "Password requirements:".
|
|
"\nmust be at least 2 characters long".
|
|
"\nmust contain at least one lowercase and one uppercase Latin letter (A-Z, a-z)",
|
|
'error' => 'Incorrect value for field "/1/passwd": must contain at least one lowercase and one uppercase Latin letter.'
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'auth_fields' => [
|
|
'Minimum password length' => '70',
|
|
'id:passwd_check_rules_case' => false,
|
|
'id:passwd_check_rules_digits' => false,
|
|
'id:passwd_check_rules_special' => false,
|
|
'id:passwd_check_rules_simple' => false
|
|
],
|
|
'db_passwd_check_rules' => 0,
|
|
'Password' => str_repeat('a', 70),
|
|
'hint' => "Password requirements:".
|
|
"\nmust be at least 70 characters long"
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'expected' => TEST_BAD,
|
|
'auth_fields' => [
|
|
'Minimum password length' => '70',
|
|
'id:passwd_check_rules_case' => false,
|
|
'id:passwd_check_rules_digits' => false,
|
|
'id:passwd_check_rules_special' => false,
|
|
'id:passwd_check_rules_simple' => false
|
|
],
|
|
'db_passwd_check_rules' => 0,
|
|
'Password' => str_repeat('a', 69),
|
|
'hint' => "Password requirements:".
|
|
"\nmust be at least 70 characters long",
|
|
'error' => 'Incorrect value for field "/1/passwd": must be at least 70 characters long.'
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'auth_fields' => [
|
|
'Minimum password length' => '70',
|
|
'id:passwd_check_rules_case' => false,
|
|
'id:passwd_check_rules_digits' => false,
|
|
'id:passwd_check_rules_special' => false,
|
|
'id:passwd_check_rules_simple' => false
|
|
],
|
|
'db_passwd_check_rules' => 0,
|
|
'Password' => str_repeat('a', 71),
|
|
'hint' => "Password requirements:".
|
|
"\nmust be at least 70 characters long"
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'auth_fields' => [
|
|
'Minimum password length' => '70',
|
|
'id:passwd_check_rules_case' => true,
|
|
'id:passwd_check_rules_digits' => false,
|
|
'id:passwd_check_rules_special' => false,
|
|
'id:passwd_check_rules_simple' => false
|
|
],
|
|
'db_passwd_check_rules' => 1,
|
|
'Password' => str_repeat('a', 35).str_repeat('A', 36),
|
|
'hint' => "Password requirements:".
|
|
"\nmust be at least 70 characters long".
|
|
"\nmust contain at least one lowercase and one uppercase Latin letter (A-Z, a-z)"
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'expected' => TEST_BAD,
|
|
'auth_fields' => [
|
|
'Minimum password length' => '70',
|
|
'id:passwd_check_rules_case' => true,
|
|
'id:passwd_check_rules_digits' => false,
|
|
'id:passwd_check_rules_special' => false,
|
|
'id:passwd_check_rules_simple' => false
|
|
],
|
|
'db_passwd_check_rules' => 1,
|
|
'Password' => str_repeat('a', 80),
|
|
'hint' => "Password requirements:".
|
|
"\nmust be at least 70 characters long".
|
|
"\nmust contain at least one lowercase and one uppercase Latin letter (A-Z, a-z)",
|
|
'error' => 'Incorrect value for field "/1/passwd": must contain at least one lowercase and one uppercase Latin letter.'
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'expected' => TEST_BAD,
|
|
'auth_fields' => [
|
|
'Minimum password length' => '8',
|
|
'id:passwd_check_rules_case' => false,
|
|
'id:passwd_check_rules_digits' => true,
|
|
'id:passwd_check_rules_special' => false,
|
|
'id:passwd_check_rules_simple' => false
|
|
],
|
|
'db_passwd_check_rules' => 2,
|
|
'Password' => 'secure_password',
|
|
'hint' => "Password requirements:".
|
|
"\nmust be at least 8 characters long".
|
|
"\nmust contain at least one digit (0-9)",
|
|
'error' => 'Incorrect value for field "/1/passwd": must contain at least one digit.'
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'expected' => TEST_BAD,
|
|
'auth_fields' => [
|
|
'Minimum password length' => '8',
|
|
'id:passwd_check_rules_case' => true,
|
|
'id:passwd_check_rules_digits' => true,
|
|
'id:passwd_check_rules_special' => false,
|
|
'id:passwd_check_rules_simple' => false
|
|
],
|
|
'db_passwd_check_rules' => 3,
|
|
'Password' => 'Secure_Password',
|
|
'hint' => "Password requirements:".
|
|
"\nmust be at least 8 characters long".
|
|
"\nmust contain at least one lowercase and one uppercase Latin letter (A-Z, a-z)".
|
|
"\nmust contain at least one digit (0-9)",
|
|
'error' => 'Incorrect value for field "/1/passwd": must contain at least one digit.'
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'auth_fields' => [
|
|
'Minimum password length' => '8',
|
|
'id:passwd_check_rules_case' => true,
|
|
'id:passwd_check_rules_digits' => true,
|
|
'id:passwd_check_rules_special' => false,
|
|
'id:passwd_check_rules_simple' => false
|
|
],
|
|
'db_passwd_check_rules' => 3,
|
|
'Password' => 'Secure_Password1',
|
|
'hint' => "Password requirements:".
|
|
"\nmust be at least 8 characters long".
|
|
"\nmust contain at least one lowercase and one uppercase Latin letter (A-Z, a-z)".
|
|
"\nmust contain at least one digit (0-9)"
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'auth_fields' => [
|
|
'Minimum password length' => '8',
|
|
'id:passwd_check_rules_case' => false,
|
|
'id:passwd_check_rules_digits' => true,
|
|
'id:passwd_check_rules_special' => false,
|
|
'id:passwd_check_rules_simple' => false
|
|
],
|
|
'db_passwd_check_rules' => 2,
|
|
'Password' => 'secure_password1',
|
|
'hint' => "Password requirements:".
|
|
"\nmust be at least 8 characters long".
|
|
"\nmust contain at least one digit (0-9)"
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'auth_fields' => [
|
|
'Minimum password length' => '8',
|
|
'id:passwd_check_rules_case' => false,
|
|
'id:passwd_check_rules_digits' => true,
|
|
'id:passwd_check_rules_special' => false,
|
|
'id:passwd_check_rules_simple' => false
|
|
],
|
|
'db_passwd_check_rules' => 2,
|
|
'Password' => '99009900',
|
|
'hint' => "Password requirements:".
|
|
"\nmust be at least 8 characters long".
|
|
"\nmust contain at least one digit (0-9)"
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'auth_fields' => [
|
|
'Minimum password length' => '8',
|
|
'id:passwd_check_rules_case' => false,
|
|
'id:passwd_check_rules_digits' => true,
|
|
'id:passwd_check_rules_special' => false,
|
|
'id:passwd_check_rules_simple' => false
|
|
],
|
|
'db_passwd_check_rules' => 2,
|
|
'Password' => '12345678',
|
|
'hint' => "Password requirements:".
|
|
"\nmust be at least 8 characters long".
|
|
"\nmust contain at least one digit (0-9)"
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'expected' => TEST_BAD,
|
|
'auth_fields' => [
|
|
'Minimum password length' => '8',
|
|
'id:passwd_check_rules_case' => false,
|
|
'id:passwd_check_rules_digits' => true,
|
|
'id:passwd_check_rules_special' => false,
|
|
'id:passwd_check_rules_simple' => true
|
|
],
|
|
'db_passwd_check_rules' => 10,
|
|
'Password' => '12345678',
|
|
'hint' => "Password requirements:".
|
|
"\nmust be at least 8 characters long".
|
|
"\nmust contain at least one digit (0-9)".
|
|
"\nmust not contain user's name, surname or username".
|
|
"\nmust not be one of common or context-specific passwords",
|
|
'error' => 'Incorrect value for field "/1/passwd": must not be one of common or context-specific passwords.'
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'auth_fields' => [
|
|
'Minimum password length' => '8',
|
|
'id:passwd_check_rules_case' => false,
|
|
'id:passwd_check_rules_digits' => true,
|
|
'id:passwd_check_rules_special' => true,
|
|
'id:passwd_check_rules_simple' => false
|
|
],
|
|
'db_passwd_check_rules' => 6,
|
|
'Password' => 'secure_password1#():}',
|
|
'hint' => "Password requirements:".
|
|
"\nmust be at least 8 characters long".
|
|
"\nmust contain at least one digit (0-9)".
|
|
"\nmust contain at least one special character ( !\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~)"
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'expected' => TEST_BAD,
|
|
'auth_fields' => [
|
|
'Minimum password length' => '8',
|
|
'id:passwd_check_rules_case' => false,
|
|
'id:passwd_check_rules_digits' => true,
|
|
'id:passwd_check_rules_special' => true,
|
|
'id:passwd_check_rules_simple' => false
|
|
],
|
|
'db_passwd_check_rules' => 6,
|
|
'Password' => 'securepassword1',
|
|
'hint' => "Password requirements:".
|
|
"\nmust be at least 8 characters long".
|
|
"\nmust contain at least one digit (0-9)".
|
|
"\nmust contain at least one special character ( !\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~)",
|
|
'error' => 'Incorrect value for field "/1/passwd": must contain at least one special character.'
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'expected' => TEST_BAD,
|
|
'auth_fields' => [
|
|
'Minimum password length' => '8',
|
|
'id:passwd_check_rules_case' => false,
|
|
'id:passwd_check_rules_digits' => true,
|
|
'id:passwd_check_rules_special' => true,
|
|
'id:passwd_check_rules_simple' => false
|
|
],
|
|
'db_passwd_check_rules' => 6,
|
|
'Password' => 'securepassword#',
|
|
'hint' => "Password requirements:".
|
|
"\nmust be at least 8 characters long".
|
|
"\nmust contain at least one digit (0-9)".
|
|
"\nmust contain at least one special character ( !\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~)",
|
|
'error' => 'Incorrect value for field "/1/passwd": must contain at least one digit.'
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'auth_fields' => [
|
|
'Minimum password length' => '8',
|
|
'id:passwd_check_rules_case' => false,
|
|
'id:passwd_check_rules_digits' => false,
|
|
'id:passwd_check_rules_special' => true,
|
|
'id:passwd_check_rules_simple' => false
|
|
],
|
|
'db_passwd_check_rules' => 4,
|
|
'Password' => 'securepassword#',
|
|
'hint' => "Password requirements:".
|
|
"\nmust be at least 8 characters long".
|
|
"\nmust contain at least one special character ( !\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~)"
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'expected' => TEST_BAD,
|
|
'auth_fields' => [
|
|
'Minimum password length' => '8',
|
|
'id:passwd_check_rules_case' => false,
|
|
'id:passwd_check_rules_digits' => false,
|
|
'id:passwd_check_rules_special' => true,
|
|
'id:passwd_check_rules_simple' => false
|
|
],
|
|
'db_passwd_check_rules' => 4,
|
|
'Password' => 'securepassword',
|
|
'hint' => "Password requirements:".
|
|
"\nmust be at least 8 characters long".
|
|
"\nmust contain at least one special character ( !\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~)",
|
|
'error' => 'Incorrect value for field "/1/passwd": must contain at least one special character.'
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'auth_fields' => [
|
|
'Minimum password length' => '8',
|
|
'id:passwd_check_rules_case' => false,
|
|
'id:passwd_check_rules_digits' => false,
|
|
'id:passwd_check_rules_special' => true,
|
|
'id:passwd_check_rules_simple' => false
|
|
],
|
|
'db_passwd_check_rules' => 4,
|
|
'Password' => "( !\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~)",
|
|
'hint' => "Password requirements:".
|
|
"\nmust be at least 8 characters long".
|
|
"\nmust contain at least one special character ( !\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~)"
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'expected' => TEST_BAD,
|
|
'auth_fields' => [
|
|
'Minimum password length' => '8',
|
|
'id:passwd_check_rules_case' => false,
|
|
'id:passwd_check_rules_digits' => false,
|
|
'id:passwd_check_rules_special' => true,
|
|
'id:passwd_check_rules_simple' => true
|
|
],
|
|
'db_passwd_check_rules' => 12,
|
|
'Password' => "zabbix",
|
|
'hint' => "Password requirements:".
|
|
"\nmust be at least 8 characters long".
|
|
"\nmust contain at least one special character ( !\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~)".
|
|
"\nmust not contain user's name, surname or username".
|
|
"\nmust not be one of common or context-specific passwords",
|
|
'error' => 'Incorrect value for field "/1/passwd": must be at least 8 characters long.'
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'expected' => TEST_BAD,
|
|
'auth_fields' => [
|
|
'Minimum password length' => '4',
|
|
'id:passwd_check_rules_case' => false,
|
|
'id:passwd_check_rules_digits' => false,
|
|
'id:passwd_check_rules_special' => true,
|
|
'id:passwd_check_rules_simple' => true
|
|
],
|
|
'db_passwd_check_rules' => 12,
|
|
'Password' => "zabbix",
|
|
'hint' => "Password requirements:".
|
|
"\nmust be at least 4 characters long".
|
|
"\nmust contain at least one special character ( !\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~)".
|
|
"\nmust not contain user's name, surname or username".
|
|
"\nmust not be one of common or context-specific passwords",
|
|
'error' => 'Incorrect value for field "/1/passwd": must contain at least one special character.'
|
|
]
|
|
]
|
|
];
|
|
}
|
|
|
|
public function getUserPasswordData() {
|
|
return [
|
|
[
|
|
[
|
|
'expected' => TEST_BAD,
|
|
'auth_fields' => [
|
|
'Minimum password length' => '4',
|
|
'id:passwd_check_rules_case' => false,
|
|
'id:passwd_check_rules_digits' => false,
|
|
'id:passwd_check_rules_special' => false,
|
|
'id:passwd_check_rules_simple' => true
|
|
],
|
|
'db_passwd_check_rules' => 8,
|
|
'Password' => "zabbix",
|
|
'hint' => "Password requirements:".
|
|
"\nmust be at least 4 characters long".
|
|
"\nmust not contain user's name, surname or username".
|
|
"\nmust not be one of common or context-specific passwords",
|
|
'error' => 'Incorrect value for field "/1/passwd": must not be one of common or context-specific passwords.'
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'expected' => TEST_BAD,
|
|
'auth_fields' => [
|
|
'Minimum password length' => '4',
|
|
'id:passwd_check_rules_case' => true,
|
|
'id:passwd_check_rules_digits' => false,
|
|
'id:passwd_check_rules_special' => false,
|
|
'id:passwd_check_rules_simple' => true
|
|
],
|
|
'db_passwd_check_rules' => 9,
|
|
'Password' => 'Admin',
|
|
'hint' => "Password requirements:".
|
|
"\nmust be at least 4 characters long".
|
|
"\nmust contain at least one lowercase and one uppercase Latin letter (A-Z, a-z)".
|
|
"\nmust not contain user's name, surname or username".
|
|
"\nmust not be one of common or context-specific passwords",
|
|
'error' => "Incorrect value for field \"/1/passwd\": must not be one of common or context-specific passwords."
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'expected' => TEST_BAD,
|
|
'auth_fields' => [
|
|
'Minimum password length' => '4',
|
|
'id:passwd_check_rules_case' => false,
|
|
'id:passwd_check_rules_digits' => false,
|
|
'id:passwd_check_rules_special' => false,
|
|
'id:passwd_check_rules_simple' => true
|
|
],
|
|
'db_passwd_check_rules' => 8,
|
|
'Password' => 'admin',
|
|
'hint' => "Password requirements:".
|
|
"\nmust be at least 4 characters long".
|
|
"\nmust not contain user's name, surname or username".
|
|
"\nmust not be one of common or context-specific passwords",
|
|
'error' => "Incorrect value for field \"/1/passwd\": must not be one of common or context-specific passwords."
|
|
]
|
|
]
|
|
];
|
|
}
|
|
|
|
public function getAdminPasswordData() {
|
|
return [
|
|
[
|
|
[
|
|
'expected' => TEST_BAD,
|
|
'auth_fields' => [
|
|
'Minimum password length' => '4',
|
|
'id:passwd_check_rules_case' => false,
|
|
'id:passwd_check_rules_digits' => false,
|
|
'id:passwd_check_rules_special' => false,
|
|
'id:passwd_check_rules_simple' => true
|
|
],
|
|
'db_passwd_check_rules' => 8,
|
|
'Password' => 'Admin',
|
|
'hint' => "Password requirements:".
|
|
"\nmust be at least 4 characters long".
|
|
"\nmust not contain user's name, surname or username".
|
|
"\nmust not be one of common or context-specific passwords",
|
|
'error' => "Incorrect value for field \"/1/passwd\": must not contain user's name, surname or username."
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'expected' => TEST_BAD,
|
|
'auth_fields' => [
|
|
'Minimum password length' => '4',
|
|
'id:passwd_check_rules_case' => false,
|
|
'id:passwd_check_rules_digits' => false,
|
|
'id:passwd_check_rules_special' => false,
|
|
'id:passwd_check_rules_simple' => true
|
|
],
|
|
'db_passwd_check_rules' => 8,
|
|
'Password' => 'admin',
|
|
'hint' => "Password requirements:".
|
|
"\nmust be at least 4 characters long".
|
|
"\nmust not contain user's name, surname or username".
|
|
"\nmust not be one of common or context-specific passwords",
|
|
'error' => "Incorrect value for field \"/1/passwd\": must not contain user's name, surname or username."
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'expected' => TEST_BAD,
|
|
'auth_fields' => [
|
|
'Minimum password length' => '4',
|
|
'id:passwd_check_rules_case' => false,
|
|
'id:passwd_check_rules_digits' => false,
|
|
'id:passwd_check_rules_special' => false,
|
|
'id:passwd_check_rules_simple' => true
|
|
],
|
|
'db_passwd_check_rules' => 8,
|
|
'Password' => 'admin1',
|
|
'hint' => "Password requirements:".
|
|
"\nmust be at least 4 characters long".
|
|
"\nmust not contain user's name, surname or username".
|
|
"\nmust not be one of common or context-specific passwords",
|
|
'error' => "Incorrect value for field \"/1/passwd\": must not contain user's name, surname or username."
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'expected' => TEST_BAD,
|
|
'auth_fields' => [
|
|
'Minimum password length' => '8',
|
|
'id:passwd_check_rules_case' => false,
|
|
'id:passwd_check_rules_digits' => false,
|
|
'id:passwd_check_rules_special' => false,
|
|
'id:passwd_check_rules_simple' => true
|
|
],
|
|
'db_passwd_check_rules' => 8,
|
|
'Password' => 'admin',
|
|
'hint' => "Password requirements:".
|
|
"\nmust be at least 8 characters long".
|
|
"\nmust not contain user's name, surname or username".
|
|
"\nmust not be one of common or context-specific passwords",
|
|
'error' => "Incorrect value for field \"/1/passwd\": must be at least 8 characters long."
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'expected' => TEST_BAD,
|
|
'auth_fields' => [
|
|
'Minimum password length' => '4',
|
|
'id:passwd_check_rules_case' => false,
|
|
'id:passwd_check_rules_digits' => false,
|
|
'id:passwd_check_rules_special' => false,
|
|
'id:passwd_check_rules_simple' => true
|
|
],
|
|
'db_passwd_check_rules' => 8,
|
|
'Password' => 'zabbix',
|
|
'hint' => "Password requirements:".
|
|
"\nmust be at least 4 characters long".
|
|
"\nmust not contain user's name, surname or username".
|
|
"\nmust not be one of common or context-specific passwords",
|
|
'error' => "Incorrect value for field \"/1/passwd\": must not contain user's name, surname or username."
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'expected' => TEST_BAD,
|
|
'auth_fields' => [
|
|
'Minimum password length' => '4',
|
|
'id:passwd_check_rules_case' => false,
|
|
'id:passwd_check_rules_digits' => false,
|
|
'id:passwd_check_rules_special' => false,
|
|
'id:passwd_check_rules_simple' => true
|
|
],
|
|
'db_passwd_check_rules' => 8,
|
|
'Password' => 'password',
|
|
'hint' => "Password requirements:".
|
|
"\nmust be at least 4 characters long".
|
|
"\nmust not contain user's name, surname or username".
|
|
"\nmust not be one of common or context-specific passwords",
|
|
'error' => "Incorrect value for field \"/1/passwd\": must not be one of common or context-specific passwords."
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'expected' => TEST_BAD,
|
|
'auth_fields' => [
|
|
'Minimum password length' => '4',
|
|
'id:passwd_check_rules_case' => false,
|
|
'id:passwd_check_rules_digits' => false,
|
|
'id:passwd_check_rules_special' => false,
|
|
'id:passwd_check_rules_simple' => true
|
|
],
|
|
'db_passwd_check_rules' => 8,
|
|
'Password' => 'password',
|
|
'hint' => "Password requirements:".
|
|
"\nmust be at least 4 characters long".
|
|
"\nmust not contain user's name, surname or username".
|
|
"\nmust not be one of common or context-specific passwords",
|
|
'error' => "Incorrect value for field \"/1/passwd\": must not be one of common or context-specific passwords."
|
|
]
|
|
],
|
|
[
|
|
[
|
|
'auth_fields' => [
|
|
'Minimum password length' => '4',
|
|
'id:passwd_check_rules_case' => false,
|
|
'id:passwd_check_rules_digits' => false,
|
|
'id:passwd_check_rules_special' => false,
|
|
'id:passwd_check_rules_simple' => true
|
|
],
|
|
'db_passwd_check_rules' => 8,
|
|
'Password' => 'securepassword',
|
|
'hint' => "Password requirements:".
|
|
"\nmust be at least 4 characters long".
|
|
"\nmust not contain user's name, surname or username".
|
|
"\nmust not be one of common or context-specific passwords"
|
|
]
|
|
]
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Check user creation with password complexity rules.
|
|
*
|
|
* @dataProvider getCommonPasswordData
|
|
* @dataProvider getUserPasswordData
|
|
*/
|
|
public function testUsersPasswordComplexity_CreateUserPassword($data) {
|
|
$this->checkPasswordComplexity($data, self::$admin_password);
|
|
}
|
|
|
|
/**
|
|
* Check user changes his own password accordingly to complexity rules.
|
|
*
|
|
* @dataProvider getCommonPasswordData
|
|
* @dataProvider getUserPasswordData
|
|
*/
|
|
public function testUsersPasswordComplexity_ChangeOwnUserPassword($data) {
|
|
$this->checkPasswordComplexity($data, self::$admin_password, self::$userid, self::ACTION_UPDATE,
|
|
self::OWN_PASSWORD, self::$user_password
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Check Admin changes his own password accordingly to complexity rules.
|
|
*
|
|
* @dataProvider getCommonPasswordData
|
|
* @dataProvider getAdminPasswordData
|
|
*/
|
|
public function testUsersPasswordComplexity_ChangeOwnAdminPassword($data) {
|
|
$this->checkPasswordComplexity($data, self::$admin_password, self::ADMIN_USERID, self::ACTION_UPDATE, self::OWN_PASSWORD);
|
|
}
|
|
|
|
/**
|
|
* Check user update with password complexity rules.
|
|
*
|
|
* @dataProvider getCommonPasswordData
|
|
* @dataProvider getUserPasswordData
|
|
*/
|
|
public function testUsersPasswordComplexity_UpdateUserPassword($data) {
|
|
$this->checkPasswordComplexity($data, self::$admin_password, self::$userid, self::ACTION_UPDATE);
|
|
}
|
|
|
|
/**
|
|
* Check admin user password update accordingly to complexity rules.
|
|
*
|
|
* @dataProvider getCommonPasswordData
|
|
* @dataProvider getAdminPasswordData
|
|
*/
|
|
public function testUsersPasswordComplexity_UpdateAdminPassword($data) {
|
|
$this->checkPasswordComplexity($data, self::$admin_password, self::ADMIN_USERID, self::ACTION_UPDATE);
|
|
}
|
|
|
|
/**
|
|
* Check password complexity rules for user creation or update.
|
|
*
|
|
* @param array $data data provider
|
|
* @param string $admin_password password used for Admin user login
|
|
* @param int $userid id of the user whose password is changed
|
|
* @param boolean $update false if create, true if update
|
|
* @param $own $own true if user changes his password himself
|
|
*/
|
|
private function checkPasswordComplexity($data, $admin_password, $userid = null, $update = false, $own = false,
|
|
$user_password = null) {
|
|
if (CTestArrayHelper::get($data, 'expected', TEST_GOOD) === TEST_BAD) {
|
|
$old_hash = CDBHelper::getHash('SELECT * FROM users ORDER BY userid');
|
|
}
|
|
|
|
$this->page->userLogin('Admin', $admin_password);
|
|
$this->page->open('zabbix.php?action=authentication.edit');
|
|
$auth_form = $this->query('id:authentication-form')->asForm()->waitUntilPresent()->one();
|
|
$auth_form->fill($data['auth_fields']);
|
|
$auth_form->submit();
|
|
$this->page->waitUntilReady();
|
|
$this->assertMessage(TEST_GOOD, 'Authentication settings updated');
|
|
$this->assertEquals($data['db_passwd_check_rules'],
|
|
CDBHelper::getValue('SELECT passwd_check_rules FROM config')
|
|
);
|
|
|
|
if ($update) {
|
|
if ($own) {
|
|
if ($userid !== 1) {
|
|
$this->page->userLogin('update-user', $user_password);
|
|
}
|
|
|
|
$this->page->open('zabbix.php?action=userprofile.edit');
|
|
$this->clickChangePassword();
|
|
}
|
|
else {
|
|
$this->page->open('zabbix.php?action=user.edit&userid='.$userid);
|
|
$this->clickChangePassword();
|
|
}
|
|
}
|
|
else {
|
|
$this->page->open('zabbix.php?action=user.edit');
|
|
}
|
|
|
|
// Check user password creation accordingly to complexity settings.
|
|
$user_form = $this->query('name:user_form')->asForm()->waitUntilPresent()->one();
|
|
$username = ($userid === 1)
|
|
? 'Admin'
|
|
: ($update ? 'update-user' : 'username'.time());
|
|
|
|
if ($update === false && $own === false) {
|
|
$user_form->fill([
|
|
'Username' => $username,
|
|
'Groups' => ['Zabbix administrators']
|
|
]);
|
|
}
|
|
|
|
if (array_key_exists('hint', $data)) {
|
|
// Summon hint-box and assert text accordingly to password complexity settings, then close hint-box.
|
|
$user_form->getLabel('Password')->query('xpath:./button[@data-hintbox]')->one()->click();
|
|
$hint = $user_form->query('xpath://div[@class="overlay-dialogue"]')->waitUntilPresent();
|
|
$this->assertEquals($data['hint'], $hint->one()->getText());
|
|
$hint->one()->query('xpath:.//button[@class="btn-overlay-close"]')->one()->click();
|
|
$hint->waitUntilNotPresent();
|
|
}
|
|
else {
|
|
// If password can be 1 symbol long and doesn't have any complexity rules hint is not shown at all.
|
|
$this->assertFalse($user_form->getLabel('Password')->query('xpath:./button[@data-hintbox]')->exists());
|
|
}
|
|
|
|
if ($own || $userid === 1) {
|
|
$user_form->fill(['Current password' => ($userid === 1) ? self::$admin_password : self::$user_password]);
|
|
}
|
|
|
|
$user_form->fill([
|
|
'Password' => $data['Password'],
|
|
'Password (once again)' => $data['Password']
|
|
]);
|
|
|
|
if ($update === false) {
|
|
$user_form->selectTab('Permissions');
|
|
$user_form->fill(['Role' => 'User role']);
|
|
}
|
|
|
|
$user_form->submit();
|
|
|
|
if ($this->page->isAlertPresent()) {
|
|
$this->page->acceptAlert();
|
|
}
|
|
|
|
if (CTestArrayHelper::get($data, 'expected', TEST_GOOD) === TEST_BAD) {
|
|
$this->assertMessage(TEST_BAD, 'Cannot '.($update ? 'update' : 'add').' user', $data['error']);
|
|
$this->assertEquals($old_hash, CDBHelper::getHash('SELECT * FROM users ORDER BY userid'));
|
|
}
|
|
else {
|
|
if ($own || $userid === 1) {
|
|
// If user updates his own password he is being logged out, so check Login screen.
|
|
$this->page->assertTitle('Zabbix');
|
|
$this->assertTrue($this->query('button:Sign in')->one()->isClickable());
|
|
}
|
|
else {
|
|
$this->assertMessage(TEST_GOOD, 'User '.($update ? 'updated' : 'added'));
|
|
}
|
|
|
|
// Check user saved in db.
|
|
$this->assertEquals(1, CDBHelper::getCount('SELECT * FROM users WHERE username ='.zbx_dbstr($username)));
|
|
|
|
// Check success login with new password.
|
|
$this->page->userLogin($username, $data['Password']);
|
|
$this->assertTrue($this->query('xpath://a[@title='.zbx_dbstr(($userid === 1) ? 'Admin (Zabbix Administrator)'
|
|
: $username).' and text()="User settings"]')->exists()
|
|
);
|
|
|
|
// Write new password for next case.
|
|
if (($userid === 1) && ($own || $update)) {
|
|
self::$admin_password = $data['Password'];
|
|
}
|
|
elseif ($own) {
|
|
self::$user_password = $data['Password'];
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Click button "Change password" and wait until both password fields are editable.
|
|
*/
|
|
private function clickChangePassword() {
|
|
$this->query('button:Change password')->waitUntilClickable()->one()->click();
|
|
$this->query('id:password1')->waitUntilPresent()->one();
|
|
$this->query('id:password2')->waitUntilPresent()->one();
|
|
}
|
|
}
|