Update CoreLibs with phpstan level 8, add qqFileUploader implementation base, add base Test class for testing

This commit is contained in:
Clemens Schwaighofer
2021-10-26 16:35:26 +09:00
parent 736f822363
commit a6b42f243f
45 changed files with 1198 additions and 593 deletions

View File

@@ -72,44 +72,70 @@ use CoreLibs\Check\Password;
class Login extends \CoreLibs\DB\IO
{
/** @var string */
private $euid; // the user id var
// is set to one if login okay, or EUID is set and user is okay to access this page
/** @var bool */
private $permission_okay = false;
/** @var string */
public $login; // pressed login
/** @var string */
private $action; // master action command
/** @var string */
private $username; // login name
/** @var string */
private $password; // login password
/** @var string */
private $logout; // logout button
// login error code, can be matched to the array login_error_msg, which holds the string
/** @var int */
private $login_error = 0;
/** @var bool */
private $password_change = false; // if this is set to true, the user can change passwords
/** @var bool */
private $password_change_ok = false; // password change was successful
// can we reset password and mail to user with new password set screen
/** @var bool */
private $password_forgot = false;
/** @var bool */
private $password_forgot_ok = false; // password forgot mail send ok
/** @var string */
private $change_password;
/** @var string */
private $pw_username;
/** @var string */
private $pw_old_password;
/** @var string */
private $pw_new_password;
/** @var string */
private $pw_new_password_confirm;
/** @var array<string> */
private $pw_change_deny_users = []; // array of users for which the password change is forbidden
/** @var string */
private $logout_target;
/** @var int */
private $max_login_error_count = -1;
/** @var array<string> */
private $lock_deny_users = [];
// if we have password change we need to define some rules
/** @var int */
private $password_min_length = PASSWORD_MIN_LENGTH;
// max length is fixed as 255 (for input type max), if set highter, it will be set back to 255
/** @var int */
private $password_max_length = PASSWORD_MAX_LENGTH;
// can have several regexes, if nothing set, all is ok
/** @var array<string> */
private $password_valid_chars = [
// '^(?=.*\d)(?=.*[A-Za-z])[0-9A-Za-z!@#$%]{8,}$',
// '^(?.*(\pL)u)(?=.*(\pN)u)(?=.*([^\pL\pN])u).{8,}',
];
// all possible login error conditions
/** @var array<mixed> */
private $login_error_msg = [];
// this is an array holding all strings & templates passed from the outside (translation)
/** @var array<mixed> */
private $login_template = [
'strings' => [],
'password_change' => '',
@@ -117,18 +143,23 @@ class Login extends \CoreLibs\DB\IO
];
// acl vars
/** @var array<mixed> */
public $acl = [];
/** @var array<mixed> */
public $default_acl_list = [];
// login html, if we are on an ajax page
/** @var string|null */
private $login_html = '';
/** @var bool */
private $login_is_ajax_page = false;
// language
/** @var \CoreLibs\Language\L10n */
public $l;
/**
* constructor, does ALL, opens db, works through connection checks, closes itself
* @param array $db_config db config array
* @param array<mixed> $db_config db config array
*/
public function __construct(array $db_config)
{
@@ -225,7 +256,7 @@ class Login extends \CoreLibs\DB\IO
$_SESSION['DEFAULT_ACL_LIST'] = [];
// read the current edit_access_right list into an array
$q = "SELECT level, type, name FROM edit_access_right WHERE level >= 0 ORDER BY level";
while ($res = $this->dbReturn($q)) {
while (is_array($res = $this->dbReturn($q))) {
// level to description format (numeric)
$this->default_acl_list[$res['level']] = [
'type' => $res['type'],
@@ -387,8 +418,11 @@ class Login extends \CoreLibs\DB\IO
// password match is done in script, against old plain or new blowfish encypted
. "(LOWER(username) = '" . $this->dbEscapeString(strtolower($this->username)) . "') ";
$res = $this->dbReturn($q);
// username is wrong, but we throw for wrong username and wrong password the same error
if (!$this->cursor_ext[md5($q)]['num_rows']) {
if (!is_array($res)) {
$this->login_error = 1009;
$this->permission_okay = false;
} elseif (!$this->cursor_ext[md5($q)]['num_rows']) {
// username is wrong, but we throw for wrong username and wrong password the same error
$this->login_error = 1010;
} else {
// if login errors is half of max errors and the last login error
@@ -426,7 +460,7 @@ class Login extends \CoreLibs\DB\IO
$_SESSION['EUID'] = $this->euid = $res['edit_user_id'];
// check if user is okay
$this->loginCheckPermissions();
if (!$this->login_error) {
if ($this->login_error == 0) {
// now set all session vars and read page permissions
$GLOBALS['DEBUG_ALL'] = $_SESSION['DEBUG_ALL'] = $res['debug'];
$GLOBALS['DB_DEBUG'] = $_SESSION['DB_DEBUG'] = $res['db_debug'];
@@ -470,6 +504,9 @@ class Login extends \CoreLibs\DB\IO
. "AND epa.enabled = 1 AND epa.edit_group_id = " . $res["edit_group_id"] . " "
. "ORDER BY ep.order_number";
while ($res = $this->dbReturn($q)) {
if (!is_array($res)) {
break;
}
// page id array for sub data readout
$edit_page_ids[$res['edit_page_id']] = $res['cuid'];
// create the array for pages
@@ -496,22 +533,20 @@ class Login extends \CoreLibs\DB\IO
$pages_acl[$res['filename']] = $res['level'];
} // for each page
// get the visible groups for all pages and write them to the pages
$_edit_page_id = 0;
$q = "SELECT epvg.edit_page_id, name, flag "
. "FROM edit_visible_group evp, edit_page_visible_group epvg "
. "WHERE evp.edit_visible_group_id = epvg.edit_visible_group_id "
. "AND epvg.edit_page_id IN (" . join(', ', array_keys($edit_page_ids)) . ") "
. "ORDER BY epvg.edit_page_id";
while ($res = $this->dbReturn($q)) {
while (is_array($res = $this->dbReturn($q))) {
$pages[$edit_page_ids[$res['edit_page_id']]]['visible'][$res['name']] = $res['flag'];
}
// get the same for the query strings
$_edit_page_id = 0;
$q = "SELECT eqs.edit_page_id, name, value, dynamic FROM edit_query_string eqs "
. "WHERE enabled = 1 AND edit_page_id "
. "IN (" . join(', ', array_keys($edit_page_ids)) . ") "
. "ORDER BY eqs.edit_page_id";
while ($res = $this->dbReturn($q)) {
while (is_array($res = $this->dbReturn($q))) {
$pages[$edit_page_ids[$res['edit_page_id']]]['query'][] = [
'name' => $res['name'],
'value' => $res['value'],
@@ -519,14 +554,13 @@ class Login extends \CoreLibs\DB\IO
];
}
// get the page content and add them to the page
$_edit_page_id = 0;
$q = "SELECT epc.edit_page_id, epc.name, epc.uid, epc.order_number, "
. "epc.online, ear.level, ear.type "
. "FROM edit_page_content epc, edit_access_right ear "
. "WHERE epc.edit_access_right_id = ear.edit_access_right_id AND "
. "epc.edit_page_id IN (" . join(', ', array_keys($edit_page_ids)) . ") "
. "ORDER BY epc.order_number";
while ($res = $this->dbReturn($q)) {
while (is_array($res = $this->dbReturn($q))) {
$pages[$edit_page_ids[$res['edit_page_id']]]['content'][$res['uid']] = [
'name' => $res['name'],
'uid' => $res['uid'],
@@ -550,13 +584,13 @@ class Login extends \CoreLibs\DB\IO
$unit_access = [];
$eauid = [];
$unit_acl = [];
while ($res = $this->dbReturn($q)) {
while (is_array($res = $this->dbReturn($q))) {
// read edit access data fields and drop them into the unit access array
$q_sub = "SELECT name, value "
. "FROM edit_access_data "
. "WHERE enabled = 1 AND edit_access_id = " . $res['edit_access_id'];
$ea_data = [];
while ($res_sub = $this->dbReturn($q_sub)) {
while (is_array($res_sub = $this->dbReturn($q_sub))) {
$ea_data[$res_sub['name']] = $res_sub['value'];
}
// build master unit array
@@ -583,7 +617,7 @@ class Login extends \CoreLibs\DB\IO
$_SESSION['EAID'] = $eauid;
} // user has permission to THIS page
} // user was not enabled or other login error
if ($this->login_error) {
if ($this->login_error && is_array($res)) {
$login_error_date_first = '';
if ($res['login_error_count'] == 0) {
$login_error_date_first = ", login_error_date_first = NOW()";
@@ -633,6 +667,11 @@ class Login extends \CoreLibs\DB\IO
. "AND filename = '" . $this->page_name . "' "
. "AND eg.enabled = 1 AND epa.enabled = 1";
$res = $this->dbReturnRow($q);
if (!is_array($res)) {
$this->login_error = 109;
$this->permission_okay = false;
return $this->permission_okay;
}
// unset mem limit if debug is set to 1
// if (
// ($GLOBALS["DEBUG_ALL"] || $GLOBALS["DB_DEBUG"] ||
@@ -795,10 +834,14 @@ class Login extends \CoreLibs\DB\IO
/**
* checks if this edit access id is valid
* @param int|null $edit_access_id access id pk to check
* @return bool true/false: if the edit access is not in the valid list: false
* @return bool true/false: if the edit access is not
* in the valid list: false
*/
public function loginCheckEditAccess($edit_access_id): bool
{
if ($edit_access_id === null) {
return false;
}
if (array_key_exists($edit_access_id, $this->acl['unit'])) {
return true;
} else {
@@ -943,7 +986,7 @@ class Login extends \CoreLibs\DB\IO
/**
* prints out login html part if no permission (error) is set
* @return ?string html data for login page, or null for nothing
* @return string|null html data for login page, or null for nothing
*/
private function loginPrintLogin()
{
@@ -958,7 +1001,7 @@ class Login extends \CoreLibs\DB\IO
$LOGOUT_TARGET = "";
}
$html_string = $this->login_template['template'];
$html_string = (string)$this->login_template['template'];
// if password change is okay
if ($this->password_change) {
@@ -1099,6 +1142,8 @@ class Login extends \CoreLibs\DB\IO
$error_msgs = [
// actually obsolete
'100' => $this->l->__('Fatal Error: <b>[EUID] came in as GET/POST!</b>'),
// query errors
'1009' => $this->l->__('Fatal Error: <b>Login query reading failed<b>'),
// user not found
'1010' => $this->l->__('Fatal Error: <b>Login Failed - Wrong Username or Password</b>'),
// blowfish password wrong
@@ -1111,6 +1156,7 @@ class Login extends \CoreLibs\DB\IO
'103' => $this->l->__('Fatal Error: <b>You do not have the rights to access this Page</b>'),
'104' => $this->l->__('Fatal Error: <b>Login Failed - User not enabled</b>'),
'105' => $this->l->__('Fatal Error: <b>Login Failed - User is locked</b>'),
'109' => $this->l->__('Fatal Error: <b>Check permission query reading failed</b>'),
// actually this is an illegal user, but I mask it
'220' => $this->l->__('Fatal Error: <b>Password change - The user could not be found</b>'),
'200' => $this->l->__('Fatal Error: <b>Password change - Please enter username and old password</b>'),
@@ -1123,7 +1169,8 @@ class Login extends \CoreLibs\DB\IO
// for OK password change
'300' => $this->l->__('Success: <b>Password change successful</b>'),
// this is bad bad error
'9999' => $this->l->__('Fatal Error: <b>necessary crypt engine could not be found</b>. Login is impossible')
'9999' => $this->l->__('Fatal Error: <b>necessary crypt engine could not be found</b>. '
. 'Login is impossible'),
];
// if password change is okay
@@ -1280,7 +1327,7 @@ EOM;
'_FILES' => $_FILES,
'error' => $this->login_error
];
$data_binary = $this->dbEscapeBytea(bzcompress(serialize($_data_binary)));
$data_binary = $this->dbEscapeBytea((string)bzcompress(serialize($_data_binary)));
// SQL querie for log entry
$q = "INSERT INTO edit_log "
. "(username, password, euid, event_date, event, error, data, data_binary, page, "
@@ -1327,6 +1374,7 @@ EOM;
public function loginCheckEditAccessId(?int $edit_access_id): ?int
{
if (
$edit_access_id !== null &&
isset($_SESSION['UNIT']) &&
is_array($_SESSION['UNIT']) &&
!array_key_exists($edit_access_id, $_SESSION['UNIT'])