diff --git a/lam/HISTORY b/lam/HISTORY index b23072f01..56de6b0ea 100644 --- a/lam/HISTORY +++ b/lam/HISTORY @@ -1,3 +1,8 @@ +December 2024 9.0 + - Fixed bugs: + -> Windows: show more than 1000 LDAP entries when paged results is activated in server profile + + 24.09.2024 8.9 - Windows user: support for room number and personal title (needs to be activated in module settings) (343, 344) - Usability improvements (354) diff --git a/lam/lib/2factor.inc b/lam/lib/2factor.inc index fd032f116..2c14fec1a 100644 --- a/lam/lib/2factor.inc +++ b/lam/lib/2factor.inc @@ -7,25 +7,23 @@ use DateTime; use Duo\DuoUniversal\Client; use Duo\DuoUniversal\DuoException; use Exception; -use \htmlResponsiveRow; -use \LAM\LOGIN\WEBAUTHN\WebauthnManager; +use htmlResponsiveRow; +use LAM\LOGIN\WEBAUTHN\WebauthnManager; use SelfServiceLoginHandler; -use \selfServiceProfile; -use \LAMConfig; -use \htmlScript; -use \htmlIframe; -use \htmlImage; -use \htmlButton; -use \htmlJavaScript; -use \htmlStatusMessage; -use \htmlOutputText; -use \htmlDiv; -use \LAMException; -use \Webauthn\PublicKeyCredentialCreationOptions; +use selfServiceProfile; +use LAMConfig; +use htmlImage; +use htmlButton; +use htmlJavaScript; +use htmlStatusMessage; +use htmlOutputText; +use htmlDiv; +use LAMException; +use Webauthn\PublicKeyCredentialCreationOptions; /* This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) - Copyright (C) 2017 - 2023 Roland Gruber + Copyright (C) 2017 - 2024 Roland Gruber 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 @@ -114,7 +112,7 @@ abstract class BaseProvider implements TwoFactorProvider { /** * {@inheritDoc} - * @see \LAM\LIB\TWO_FACTOR\TwoFactorProvider::hasCustomInputForm() + * @see TwoFactorProvider::hasCustomInputForm */ public function hasCustomInputForm() { return false; @@ -122,7 +120,7 @@ abstract class BaseProvider implements TwoFactorProvider { /** * {@inheritDoc} - * @see \LAM\LIB\TWO_FACTOR\TwoFactorProvider::addCustomInput() + * @see TwoFactorProvider::addCustomInput */ public function addCustomInput(&$row, $userDn) { // must be filled by subclass if used @@ -150,7 +148,7 @@ abstract class BaseProvider implements TwoFactorProvider { /** * {@inheritDoc} - * @see \LAM\LIB\TWO_FACTOR\TwoFactorProvider::isShowSubmitButton() + * @see TwoFactorProvider::isShowSubmitButton */ public function isShowSubmitButton() { return true; @@ -174,7 +172,7 @@ class PrivacyIDEAProvider extends BaseProvider { /** * {@inheritDoc} - * @see \LAM\LIB\TWO_FACTOR\TwoFactorProvider::getSerials() + * @see TwoFactorProvider::getSerials */ public function getSerials($user, $password) { logNewMessage(LOG_DEBUG, 'PrivacyIDEAProvider: Getting serials for ' . $user); @@ -185,7 +183,7 @@ class PrivacyIDEAProvider extends BaseProvider { /** * {@inheritDoc} - * @see \LAM\LIB\TWO_FACTOR\TwoFactorProvider::verify2ndFactor() + * @see TwoFactorProvider::verify2ndFactor */ public function verify2ndFactor($user, $password, $serial, $twoFactorInput) { logNewMessage(LOG_DEBUG, 'PrivacyIDEAProvider: Checking 2nd factor for ' . $user); @@ -200,7 +198,7 @@ class PrivacyIDEAProvider extends BaseProvider { * @param string $user user name * @param string $password password * @return string token - * @throws \Exception error during authentication + * @throws Exception error during authentication */ private function authenticate($user, $password) { $curl = $this->getCurl(); @@ -224,8 +222,8 @@ class PrivacyIDEAProvider extends BaseProvider { } $status = $output->result->status; if ($status != 1) { - $errCode = isset($output->result->error) && isset($output->result->error->code) ? $output->result->error->code : ''; - $errMessage = isset($output->result->error) && isset($output->result->error->message) ? $output->result->error->message : ''; + $errCode = $output->result->error->code ?? ''; + $errMessage = $output->result->error->message ?? ''; throw new Exception("Unable to login: " . $errCode . ' ' . $errMessage); } if (!isset($output->result->value) || !isset($output->result->value->token)) { @@ -238,7 +236,7 @@ class PrivacyIDEAProvider extends BaseProvider { * Returns the curl object. * * @return object curl handle - * @throws \Exception error during curl creation + * @throws Exception error during curl creation */ private function getCurl() { $curl = curl_init(); @@ -275,8 +273,8 @@ class PrivacyIDEAProvider extends BaseProvider { } $status = $output->result->status; if (($status != 1) || !isset($output->result->value) || !isset($output->result->value->tokens)) { - $errCode = isset($output->result->error) && isset($output->result->error->code) ? $output->result->error->code : ''; - $errMessage = isset($output->result->error) && isset($output->result->error->message) ? $output->result->error->message : ''; + $errCode = $output->result->error->code ?? ''; + $errMessage = $output->result->error->message ?? ''; throw new Exception("Unable to get serials: " . $errCode . ' ' . $errMessage); } $serials = []; @@ -311,7 +309,7 @@ class PrivacyIDEAProvider extends BaseProvider { curl_close($curl); $output = json_decode($json); if (empty($output) || !isset($output->result) || !isset($output->result->status) || !isset($output->result->value)) { - throw new \Exception("Unable to get json from $url."); + throw new Exception("Unable to get json from $url."); } $status = $output->result->status; $value = $output->result->value; @@ -349,7 +347,7 @@ class YubicoProvider extends BaseProvider { /** * {@inheritDoc} - * @see \LAM\LIB\TWO_FACTOR\TwoFactorProvider::getSerials() + * @see TwoFactorProvider::getSerials */ public function getSerials($user, $password) { $keyAttributeName = strtolower($this->config->twoFactorAuthenticationSerialAttributeName); @@ -369,7 +367,7 @@ class YubicoProvider extends BaseProvider { /** * {@inheritDoc} - * @see \LAM\LIB\TWO_FACTOR\TwoFactorProvider::verify2ndFactor() + * @see TwoFactorProvider::verify2ndFactor */ public function verify2ndFactor($user, $password, $serial, $twoFactorInput) { include_once(__DIR__ . "/3rdParty/yubico/Yubico.php"); @@ -380,13 +378,13 @@ class YubicoProvider extends BaseProvider { $serials = explode(', ', $serialData[0]); $serialMatched = false; foreach ($serials as $serial) { - if (strpos($twoFactorInput, $serial) === 0) { + if (str_starts_with($twoFactorInput, $serial)) { $serialMatched = true; break; } } if (!$serialMatched) { - throw new \Exception(_('YubiKey id does not match allowed list of key ids.')); + throw new Exception(_('YubiKey id does not match allowed list of key ids.')); } $urls = $this->config->twoFactorAuthenticationURL; shuffle($urls); @@ -431,7 +429,7 @@ class DuoProvider extends BaseProvider { /** * {@inheritDoc} - * @see \LAM\LIB\TWO_FACTOR\TwoFactorProvider::getSerials() + * @see TwoFactorProvider::getSerials */ public function getSerials($user, $password) { return ['DUO']; @@ -439,7 +437,7 @@ class DuoProvider extends BaseProvider { /** * {@inheritDoc} - * @see \LAM\LIB\TWO_FACTOR\TwoFactorProvider::isShowSubmitButton() + * @see TwoFactorProvider::isShowSubmitButton */ public function isShowSubmitButton() { return false; @@ -447,7 +445,7 @@ class DuoProvider extends BaseProvider { /** * {@inheritDoc} - * @see \LAM\LIB\TWO_FACTOR\TwoFactorProvider::hasCustomInputForm() + * @see TwoFactorProvider::hasCustomInputForm */ public function hasCustomInputForm() { return true; @@ -455,7 +453,7 @@ class DuoProvider extends BaseProvider { /** * {@inheritDoc} - * @see \LAM\LIB\TWO_FACTOR\BaseProvider::addCustomInput() + * @see BaseProvider::addCustomInput */ public function addCustomInput(&$row, $userDn) { $pathPrefix = $this->config->isSelfService ? '../' : ''; @@ -482,7 +480,7 @@ class DuoProvider extends BaseProvider { $row->add(new htmlJavaScript($jsBlock)); } // start authentication - elseif (!empty($_GET['duoRedirect'])) { + else { include_once __DIR__ . '/3rdParty/composer/autoload.php'; try { $duoClient = new Client( @@ -512,7 +510,7 @@ class DuoProvider extends BaseProvider { /** * {@inheritDoc} - * @see \LAM\LIB\TWO_FACTOR\TwoFactorProvider::verify2ndFactor() + * @see TwoFactorProvider::verify2ndFactor */ public function verify2ndFactor($user, $password, $serial, $twoFactorInput) { logNewMessage(LOG_DEBUG, 'DuoProvider: Checking 2nd factor for ' . $user); @@ -571,7 +569,7 @@ class OktaProvider extends BaseProvider { /** * {@inheritDoc} - * @see \LAM\LIB\TWO_FACTOR\TwoFactorProvider::getSerials() + * @see TwoFactorProvider::getSerials */ public function getSerials($user, $password) { return ['OKTA']; @@ -579,7 +577,7 @@ class OktaProvider extends BaseProvider { /** * {@inheritDoc} - * @see \LAM\LIB\TWO_FACTOR\TwoFactorProvider::isShowSubmitButton() + * @see TwoFactorProvider::isShowSubmitButton */ public function isShowSubmitButton() { return false; @@ -587,7 +585,7 @@ class OktaProvider extends BaseProvider { /** * {@inheritDoc} - * @see \LAM\LIB\TWO_FACTOR\TwoFactorProvider::hasCustomInputForm() + * @see TwoFactorProvider::hasCustomInputForm */ public function hasCustomInputForm() { return true; @@ -596,7 +594,7 @@ class OktaProvider extends BaseProvider { /** * {@inheritDoc} * @throws LAMException error building custom input - * @see \LAM\LIB\TWO_FACTOR\BaseProvider::addCustomInput() + * @see BaseProvider::addCustomInput */ public function addCustomInput(&$row, $userDn) { if (($this->config->loginHandler === null) || !$this->config->loginHandler->managesAuthentication()) { @@ -636,7 +634,7 @@ class OktaProvider extends BaseProvider { /** * {@inheritDoc} - * @see \LAM\LIB\TWO_FACTOR\TwoFactorProvider::verify2ndFactor() + * @see TwoFactorProvider::verify2ndFactor */ public function verify2ndFactor($user, $password, $serial, $twoFactorInput) { $this->verificationFailed = true; @@ -755,7 +753,7 @@ class OpenIdProvider extends BaseProvider { /** * {@inheritDoc} - * @see \LAM\LIB\TWO_FACTOR\TwoFactorProvider::getSerials() + * @see TwoFactorProvider::getSerials */ public function getSerials($user, $password) { return ['OpenID']; @@ -763,7 +761,7 @@ class OpenIdProvider extends BaseProvider { /** * {@inheritDoc} - * @see \LAM\LIB\TWO_FACTOR\TwoFactorProvider::isShowSubmitButton() + * @see TwoFactorProvider::isShowSubmitButton */ public function isShowSubmitButton() { return false; @@ -771,7 +769,7 @@ class OpenIdProvider extends BaseProvider { /** * {@inheritDoc} - * @see \LAM\LIB\TWO_FACTOR\TwoFactorProvider::hasCustomInputForm() + * @see TwoFactorProvider::hasCustomInputForm */ public function hasCustomInputForm() { return true; @@ -780,7 +778,7 @@ class OpenIdProvider extends BaseProvider { /** * {@inheritDoc} * @throws LAMException error building custom input - * @see \LAM\LIB\TWO_FACTOR\BaseProvider::addCustomInput() + * @see BaseProvider::addCustomInput */ public function addCustomInput(&$row, $userDn) { $loginAttribute = ''; @@ -795,7 +793,7 @@ class OpenIdProvider extends BaseProvider { } $content = new htmlResponsiveRow(); $pathPrefix = $this->config->isSelfService ? '../' : ''; - $row->add(new htmlImage($pathPrefix . '../graphics/openid.png'), 12); + $row->add(new htmlImage($pathPrefix . '../graphics/openid.png')); include_once __DIR__ . '/3rdParty/composer/autoload.php'; try { $client = $this->getOpenIdClient(); @@ -863,7 +861,7 @@ class OpenIdProvider extends BaseProvider { /** * {@inheritDoc} - * @see \LAM\LIB\TWO_FACTOR\TwoFactorProvider::verify2ndFactor() + * @see TwoFactorProvider::verify2ndFactor */ public function verify2ndFactor($user, $password, $serial, $twoFactorInput) { $this->verificationFailed = true; @@ -927,7 +925,7 @@ class WebauthnProvider extends BaseProvider { /** * {@inheritDoc} - * @see \LAM\LIB\TWO_FACTOR\TwoFactorProvider::getSerials() + * @see TwoFactorProvider::getSerials */ public function getSerials($user, $password) { return ['WEBAUTHN']; @@ -935,7 +933,7 @@ class WebauthnProvider extends BaseProvider { /** * {@inheritDoc} - * @see \LAM\LIB\TWO_FACTOR\TwoFactorProvider::isShowSubmitButton() + * @see TwoFactorProvider::isShowSubmitButton */ public function isShowSubmitButton() { return false; @@ -943,7 +941,7 @@ class WebauthnProvider extends BaseProvider { /** * {@inheritDoc} - * @see \LAM\LIB\TWO_FACTOR\TwoFactorProvider::hasCustomInputForm() + * @see TwoFactorProvider::hasCustomInputForm */ public function hasCustomInputForm() { return true; @@ -951,26 +949,26 @@ class WebauthnProvider extends BaseProvider { /** * {@inheritDoc} - * @see \LAM\LIB\TWO_FACTOR\BaseProvider::addCustomInput() + * @see BaseProvider::addCustomInput */ public function addCustomInput(&$row, $userDn) { if (!extension_loaded('PDO')) { - $row->add(new htmlStatusMessage('ERROR', 'WebAuthn requires the PDO extension for PHP.'), 12); + $row->add(new htmlStatusMessage('ERROR', 'WebAuthn requires the PDO extension for PHP.')); return; } $pdoDrivers = \PDO::getAvailableDrivers(); if (!in_array('sqlite', $pdoDrivers)) { - $row->add(new htmlStatusMessage('ERROR', 'WebAuthn requires the sqlite PDO driver for PHP.'), 12); + $row->add(new htmlStatusMessage('ERROR', 'WebAuthn requires the sqlite PDO driver for PHP.')); return; } include_once __DIR__ . '/webauthn.inc'; $webauthnManager = $this->getWebauthnManager(); $hasTokens = $webauthnManager->isRegistered($userDn); if ($hasTokens) { - $row->add(new htmlStatusMessage('INFO', _('Please authenticate with your security device.')), 12); + $row->add(new htmlStatusMessage('INFO', _('Please authenticate with your security device.'))); } else { - $row->add(new htmlStatusMessage('INFO', _('Please register a security device.')), 12); + $row->add(new htmlStatusMessage('INFO', _('Please register a security device.'))); } $row->addVerticalSpacer('2rem'); $pathPrefix = $this->config->isSelfService ? '../' : ''; @@ -1006,7 +1004,7 @@ class WebauthnProvider extends BaseProvider { /** * {@inheritDoc} - * @see \LAM\LIB\TWO_FACTOR\TwoFactorProvider::verify2ndFactor() + * @see TwoFactorProvider::verify2ndFactor */ public function verify2ndFactor($user, $password, $serial, $twoFactorInput) { logNewMessage(LOG_DEBUG, 'WebauthnProvider: Checking 2nd factor for ' . $user); @@ -1050,22 +1048,22 @@ class WebauthnProvider extends BaseProvider { class TwoFactorProviderService { /** 2factor authentication disabled */ - const TWO_FACTOR_NONE = 'none'; + public const TWO_FACTOR_NONE = 'none'; /** 2factor authentication via privacyIDEA */ - const TWO_FACTOR_PRIVACYIDEA = 'privacyidea'; + public const TWO_FACTOR_PRIVACYIDEA = 'privacyidea'; /** 2factor authentication via YubiKey */ - const TWO_FACTOR_YUBICO = 'yubico'; + public const TWO_FACTOR_YUBICO = 'yubico'; /** 2factor authentication via DUO */ - const TWO_FACTOR_DUO = 'duo'; + public const TWO_FACTOR_DUO = 'duo'; /** 2factor authentication via webauthn */ - const TWO_FACTOR_WEBAUTHN = 'webauthn'; + public const TWO_FACTOR_WEBAUTHN = 'webauthn'; /** 2factor authentication via Okta */ - const TWO_FACTOR_OKTA = 'okta'; + public const TWO_FACTOR_OKTA = 'okta'; /** 2factor authentication via OpenId */ - const TWO_FACTOR_OPENID = 'openid'; + public const TWO_FACTOR_OPENID = 'openid'; /** date format when remembering devices */ - const DEVICE_REMEMBER_DATE_FORMAT = 'Y-m-d H:i:s'; + private const DEVICE_REMEMBER_DATE_FORMAT = 'Y-m-d H:i:s'; private TwoFactorConfiguration $config; diff --git a/lam/lib/account.inc b/lam/lib/account.inc index 9a961f67e..b2784a513 100644 --- a/lam/lib/account.inc +++ b/lam/lib/account.inc @@ -31,6 +31,7 @@ */ use LAM\PLUGINS\EXTRA_INVALID_CREDENTIALS\ExtraInvalidCredentials; +use LAM\TYPES\TypeManager; /** @@ -253,12 +254,12 @@ function generateSalt($len) { */ function pwd_enable($hash) { // check if password is disabled (old wrong LAM method) - if ((substr($hash, 0, 2) == "!{") || (substr($hash, 0, 2) == "*{")) { + if ((str_starts_with($hash, "!{")) || (str_starts_with($hash, "*{"))) { return substr($hash, 1, strlen($hash)); } // check for "!" or "*" at beginning of password hash else { - if (substr($hash, 0, 1) == "{") { + if (str_starts_with($hash, "{")) { $pos = strpos($hash, "}"); if ((substr($hash, $pos + 1, 1) == "!") || (substr($hash, $pos + 1, 1) == "*")) { // enable hash @@ -282,12 +283,12 @@ function pwd_enable($hash) { */ function pwd_disable($hash) { // check if password is disabled (old wrong LAM method) - if ((substr($hash, 0, 2) == "!{") || (substr($hash, 0, 2) == "*{")) { + if ((str_starts_with($hash, "!{")) || (str_starts_with($hash, "*{"))) { return $hash; } // check for "!" or "*" at beginning of password hash else { - if (substr($hash, 0, 1) == "{") { + if (str_starts_with($hash, "{")) { $pos = strpos($hash, "}"); if ((substr($hash, $pos + 1, 1) == "!") || (substr($hash, $pos + 1, 1) == "*")) { // hash already disabled @@ -315,10 +316,10 @@ function pwd_is_lockable($password) { return false; } // SASL is not lockable - if (strpos($password, '{SASL}') === 0) { + if (str_starts_with($password, '{SASL}')) { return false; } - return ((substr($password, 0, 1) == "{") || (substr($password, 1, 1) == "{")) && (strpos($password, "}") > 3); + return ((str_starts_with($password, "{")) || (substr($password, 1, 1) == "{")) && (strpos($password, "}") > 3); } /** @@ -329,10 +330,10 @@ function pwd_is_lockable($password) { */ function pwd_is_enabled($hash) { // disabled passwords have a "!" or "*" at the beginning (old wrong LAM method) - if ((substr($hash, 0, 2) == "!{") || (substr($hash, 0, 2) == "*{")) { + if ((str_starts_with($hash, "!{")) || (str_starts_with($hash, "*{"))) { return false; } - if (substr($hash, 0, 1) == "{") { + if (str_starts_with($hash, "{")) { $pos = strrpos($hash, "}"); // check if hash starts with "!" or "*" return ((substr($hash, $pos + 1, 1) !== "!") && (substr($hash, $pos + 1, 1) !== "*")); @@ -798,7 +799,7 @@ function searchLDAPByAttribute($name, $value, $objectClass, $attributes, $scopes elseif (sizeof($filterParts) > 1) { $filter = '(& ' . implode(' ', $filterParts) . ')'; } - $typeManager = new \LAM\TYPES\TypeManager(); + $typeManager = new TypeManager(); $activeTypes = $typeManager->getConfiguredTypes(); foreach ($activeTypes as $type) { if (!in_array($type->getScope(), $scopes)) { @@ -830,15 +831,15 @@ function searchLDAPByFilter($filter, $attributes, $scopes, $attrsOnly = false) { if ($attrsOnly) { $readAttributesOnly = 1; } - $typeManager = new \LAM\TYPES\TypeManager(); + $typeManager = new TypeManager(); $types = $typeManager->getConfiguredTypesForScopes($scopes); foreach ($types as $type) { $additionalFilter = $type->getAdditionalLdapFilter(); if (!empty($additionalFilter)) { - if (strpos($additionalFilter, '(') !== 0) { + if (!str_starts_with($additionalFilter, '(')) { $additionalFilter = '(' . $additionalFilter . ')'; } - if (strpos($filter, '(') !== 0) { + if (!str_starts_with($filter, '(')) { $filter = '(' . $filter . ')'; } $filter = '(&' . $additionalFilter . $filter . ')'; @@ -919,26 +920,35 @@ function searchLDAPPaged($server, $dn, $filter, $attributes, $attrsOnly, $limit) } $pageSize = 999; $cookie = ''; - $controls = [ - [ - 'oid' => LDAP_CONTROL_PAGEDRESULTS, - 'size' => $pageSize, - 'cookie' => $cookie] - ]; $return = []; do { + $controls = [ + [ + 'oid' => LDAP_CONTROL_PAGEDRESULTS, + 'value' => [ + 'size' => $pageSize, + 'cookie' => $cookie] + ] + ]; $sr = @ldap_search($server, $dn, $filter, $attributes, $attrsOnly, $limit, 0, LDAP_DEREF_NEVER, $controls); if (!$sr) { break; } + $errorCode = 0; + $matchedDn = ''; + $errorMessage = ''; + $referrals = []; + $resultControls = []; + ldap_parse_result($server, $sr, $errorCode , $matchedDn , $errorMessage , $referrals, $resultControls); $entries = ldap_get_entries($server, $sr); if (!$entries) { break; } $return = array_merge($return, $entries); + $cookie = $resultControls[LDAP_CONTROL_PAGEDRESULTS]['value']['cookie'] ?? ''; } - while ($cookie !== null && $cookie != ''); + while ($cookie != ''); cleanLDAPResult($return); return $return; } @@ -1215,10 +1225,10 @@ function compareDN($a, $b): int { // get parts to compare $part_a = $array_a[$len_a - $i - 1]; $part_a = explode('=', $part_a); - $part_a = isset($part_a[1]) ? $part_a[1] : $part_a[0]; + $part_a = $part_a[1] ?? $part_a[0]; $part_b = $array_b[$len_b - $i - 1]; $part_b = explode('=', $part_b); - $part_b = isset($part_b[1]) ? $part_b[1] : $part_b[0]; + $part_b = $part_b[1] ?? $part_b[0]; // compare parts if ($part_a == $part_b) { // part is identical if ($i == ($len - 1)) { @@ -1315,7 +1325,7 @@ function isObfuscatedText($text) { return false; } $deob = base64_decode(str_rot13($text)); - return (strpos($deob, 'LAM_OBFUSCATE:') === 0); + return (str_starts_with($deob, 'LAM_OBFUSCATE:')); } /** @@ -1442,7 +1452,7 @@ function testSmtpConnection(string $server, string $user, string $password, stri * @return array list of arrays that can be used to create status messages */ function sendPasswordMail($pwd, $user, $recipient = null) { - $user = array_change_key_case($user, CASE_LOWER); + $user = array_change_key_case($user); // read mail data $cfgMain = $_SESSION['cfgMain']; $mailTo = null; @@ -1627,16 +1637,13 @@ class moduleCache { || (!empty($scope) && !ScopeAndModuleValidation::isValidScopeName($scope))) { return null; } - if (isset(self::$cache[$name . ':' . $scope])) { - return self::$cache[$name . ':' . $scope]; - } - else { + if (!isset(self::$cache[$name . ':' . $scope])) { if (!class_exists($name)) { return null; } self::$cache[$name . ':' . $scope] = new $name($scope); - return self::$cache[$name . ':' . $scope]; } + return self::$cache[$name . ':' . $scope]; } } @@ -1710,32 +1717,32 @@ function getExtendedLDAPErrorMessage($server) { function getDefaultLDAPErrorString($server) { $extError = htmlspecialchars(getExtendedLDAPErrorMessage($server)); // Active Directory message translations - if (strpos($extError, 'DSID') !== false) { - if (strpos($extError, '5003') !== false) { + if (str_contains($extError, 'DSID')) { + if (str_contains($extError, '5003')) { logNewMessage(LOG_DEBUG, 'Password change failed because of ' . $extError); $extError = _('Your password does not meet the password strength qualifications. Please retry with another one.'); } - elseif (strpos($extError, 'data 530,') !== false) { + elseif (str_contains($extError, 'data 530,')) { logNewMessage(LOG_DEBUG, 'Login failed because of ' . $extError); $extError = _('Logon not permitted at this time'); } - elseif (strpos($extError, 'data 532,') !== false) { + elseif (str_contains($extError, 'data 532,')) { logNewMessage(LOG_DEBUG, 'Login failed because of ' . $extError); $extError = _('Password expired'); } - elseif (strpos($extError, 'data 533,') !== false) { + elseif (str_contains($extError, 'data 533,')) { logNewMessage(LOG_DEBUG, 'Login failed because of ' . $extError); $extError = _('Account is deactivated'); } - elseif (strpos($extError, 'data 701,') !== false) { + elseif (str_contains($extError, 'data 701,')) { logNewMessage(LOG_DEBUG, 'Login failed because of ' . $extError); $extError = _('Account is expired'); } - elseif (strpos($extError, 'data 773,') !== false) { + elseif (str_contains($extError, 'data 773,')) { logNewMessage(LOG_DEBUG, 'Login failed because of ' . $extError); $extError = _('Password change required'); } - elseif (strpos($extError, 'data 775,') !== false) { + elseif (str_contains($extError, 'data 775,')) { logNewMessage(LOG_DEBUG, 'Login failed because of ' . $extError); $extError = _('Account is locked'); } @@ -1756,11 +1763,11 @@ function getDefaultLDAPErrorString($server) { */ function ldapIsPasswordExpired($server): bool { $extError = htmlspecialchars(getExtendedLDAPErrorMessage($server)); - if (strpos($extError, 'data 532,') !== false) { + if (str_contains($extError, 'data 532,')) { // password expired return true; } - elseif (strpos($extError, 'data 773,') !== false) { + elseif (str_contains($extError, 'data 773,')) { // password change required return true; } @@ -1946,7 +1953,7 @@ function printHeaderContents($title, $prefix) { $cssFiles = []; $cssEntry = $cssDir->read(); while ($cssEntry !== false) { - if (substr($cssEntry, strlen($cssEntry) - 4, 4) == '.css') { + if (str_ends_with($cssEntry, '.css')) { $cssFiles[] = $cssEntry; } $cssEntry = $cssDir->read(); @@ -1970,7 +1977,7 @@ function printJsIncludes($prefix) { $jsFiles = []; $jsEntry = $jsDir->read(); while ($jsEntry !== false) { - if ((substr($jsEntry, strlen($jsEntry) - 3, 3) == '.js') || (substr($jsEntry, strlen($jsEntry) - 4, 4) == '.php')) { + if ((str_ends_with($jsEntry, '.js')) || (str_ends_with($jsEntry, '.php'))) { $jsFiles[] = $jsEntry; } $jsEntry = $jsDir->read(); @@ -1991,7 +1998,7 @@ function convertUtf8ToUtf16Le($input) { return $input; } $output = iconv('UTF-8', 'UTF-16LE', $input); - if (($output === false) || ($output == '')) { + if (($output == '')) { $output = mb_convert_encoding($input, 'UTF-8', 'UTF-16LE'); } return $output; @@ -2017,7 +2024,7 @@ function getLAMVersionText() { * @return bool is developer version */ function isDeveloperVersion($version) { - return strpos($version, 'DEV') !== false; + return str_contains($version, 'DEV'); } /** diff --git a/lam/lib/adminHeader.inc b/lam/lib/adminHeader.inc index 2d67eea30..83833a06c 100644 --- a/lam/lib/adminHeader.inc +++ b/lam/lib/adminHeader.inc @@ -30,6 +30,7 @@ use htmlLink; use htmlOutputText; use htmlResponsiveRow; use htmlSpan; +use LAM\TYPES\TypeManager; use LAMException; use ServerProfilePersistenceManager; @@ -87,7 +88,7 @@ function printHeader(string $headerPrefix): void { continue; } // check if hidden by config - $toolClass = get_class($myTool); + $toolClass = $myTool::class; $toolName = substr($toolClass, strrpos($toolClass, '\\') + 1); if (!$_SESSION['config']->isToolActive($toolName)) { continue; @@ -140,7 +141,7 @@ function printHeader(string $headerPrefix): void {