Files
Nic Boet fd93780425 fix: refuse the password admin wherever a password is set refs #5287
The login page's change form and the first-run page refused admin as a
new password, but the user page (Options, Users, and a user's own page
with ZM_USER_SELF_EDIT) and the API (users/add, users/edit) still stored
it. Every login then refused that account.

Check a new password in one place, passwordProblem() in auth.php, and
call it from all four:

- includes/actions/user.php, for an admin's edit and a self edit: the
  save stops with the reason shown on the page. A Password sent as an
  array is refused too (it reached password_hash() before).
- api/app/Model/User.php: an "acceptable" validation rule, so add and
  edit answer with the reason as the validation message. The API loads
  no language file, so passwordProblemText() gives it the English.
- newPasswordProblem() (both login-page forms) checks the confirmation,
  then passwordProblem().

Tests: tests/php/test_default_password.php covers passwordProblem() and
passwordProblemText().
2026-10-16 10:12:53 -05:00

99 lines
2.1 KiB
PHP

<?php
App::uses('AppModel', 'Model');
/**
* User Model
*
*/
class User extends AppModel {
public $validate = array(
'Username' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'A username is required'
)
),
'Password' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'A password is required'
),
'acceptable' => array(
'rule' => array('acceptablePassword')
)
)
);
# The same check as the web interface (passwordProblem() in includes/auth.php):
# true, or the reason as the validation message.
public function acceptablePassword($check) {
$problem = passwordProblem(reset($check));
return ($problem === null) ? true : passwordProblemText($problem);
}
function beforeFind($query) {
if ( empty($query['fields']) ) {
$schema = $this->schema();
unset($schema['Password']);
foreach (array_keys($schema) as $field) {
$query['fields'][] = $this->alias . '.' . $field;
}
return $query;
}
return parent::beforeFind($query);
}
public function beforeSave($options = array()) {
if (!empty($this->data['User']['Password'])) {
$this->data['User']['Password'] = password_hash($this->data['User']['Password'], PASSWORD_BCRYPT);
}
return true;
} # end function beforeSave
/**
* Use table
*
* @var mixed False or table name
*/
public $useTable = 'Users';
/**
* Primary key field
*
* @var string
*/
public $primaryKey = 'Id';
/**
* Display field
*
* @var string
*/
public $displayField = 'Username';
//The Associations below have been created with all possible keys, those that are not needed can be removed
/**
* belongsTo associations
*
* @var array
*/
public $belongsTo = array(
'Role' => array(
'className' => 'Role',
'foreignKey' => 'RoleId',
),
);
/**
* hasMany associations
*
* @var array
*/
public $hasMany = array(
);
}