From ff59d97ac334583614b97d9415b7838faa05c161 Mon Sep 17 00:00:00 2001 From: Roland Gruber Date: Sun, 27 Jul 2025 20:46:41 +0200 Subject: [PATCH] refactoring --- composer.json | 3 +- lam/lib/2factor.inc | 20 ++++--- lam/lib/account.inc | 135 ++++++++++++++----------------------------- lam/lib/baseType.inc | 15 ++--- lam/lib/export.inc | 4 +- lam/lib/modules.inc | 4 +- 6 files changed, 68 insertions(+), 113 deletions(-) diff --git a/composer.json b/composer.json index 9c1393f06..54eb755a5 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,8 @@ "ext-gettext": "*", "ext-curl": "*", "ext-openssl": "*", - "ext-xmlwriter": "*" + "ext-xmlwriter": "*", + "ext-iconv": "*" }, "scripts": { "test": "vendor/bin/phpunit" diff --git a/lam/lib/2factor.inc b/lam/lib/2factor.inc index 415792f08..9967ceb09 100644 --- a/lam/lib/2factor.inc +++ b/lam/lib/2factor.inc @@ -7,6 +7,11 @@ use DateTime; use Duo\DuoUniversal\Client; use Duo\DuoUniversal\DuoException; use Exception; +use Facile\OpenIDClient\Client\ClientBuilder; +use Facile\OpenIDClient\Client\ClientInterface; +use Facile\OpenIDClient\Client\Metadata\ClientMetadata; +use Facile\OpenIDClient\Issuer\IssuerBuilder; +use GuzzleHttp\Psr7\ServerRequest; use htmlResponsiveRow; use LAM\LOGIN\WEBAUTHN\WebauthnManager; use SelfServiceLoginHandler; @@ -130,7 +135,7 @@ abstract class BaseProvider implements TwoFactorProvider { * Returns the value of the user attribute in LDAP. * * @param string $userDn user DN - * @return string user name + * @return string|null user name */ protected function getLoginAttributeValue($userDn) { $attrName = $this->config->twoFactorAuthenticationSerialAttributeName; @@ -831,10 +836,10 @@ class OpenIdProvider extends BaseProvider { /** * Returns the client object. * - * @return \Facile\OpenIDClient\Client\Client client + * @return ClientInterface client */ - private function getOpenIdClient(): \Facile\OpenIDClient\Client\Client { - $issuer = (new \Facile\OpenIDClient\Issuer\IssuerBuilder())->build($this->config->twoFactorAuthenticationURL . '/.well-known/openid-configuration'); + private function getOpenIdClient(): ClientInterface { + $issuer = (new IssuerBuilder())->build($this->config->twoFactorAuthenticationURL . '/.well-known/openid-configuration'); $meta = [ 'client_id' => $this->config->twoFactorAuthenticationClientId, 'client_secret' => $this->config->twoFactorAuthenticationSecretKey, @@ -843,8 +848,8 @@ class OpenIdProvider extends BaseProvider { if (!empty($_GET['redirect_uri'])) { $meta['redirect_uri'] = $_GET['redirect_uri']; } - $clientMetadata = \Facile\OpenIDClient\Client\Metadata\ClientMetadata::fromArray($meta); - return (new \Facile\OpenIDClient\Client\ClientBuilder()) + $clientMetadata = ClientMetadata::fromArray($meta); + return (new ClientBuilder()) ->setIssuer($issuer) ->setClientMetadata($clientMetadata) ->build(); @@ -874,7 +879,7 @@ class OpenIdProvider extends BaseProvider { include_once __DIR__ . '/3rdParty/composer/autoload.php'; $client = $this->getOpenIdClient(); $authorizationService = $this->getAuthorizationService(); - $serverRequest = \GuzzleHttp\Psr7\ServerRequest::fromGlobals(); + $serverRequest = ServerRequest::fromGlobals(); try { $callbackParams = $authorizationService->getCallbackParams($serverRequest, $client); $tokenSet = $authorizationService->callback($client, $callbackParams, $_GET['redirect_uri']); @@ -1093,7 +1098,6 @@ class TwoFactorProviderService { /** * Returns the provider for the given type. * - * @param string $type authentication type * @return TwoFactorProvider provider * @throws Exception unable to get provider */ diff --git a/lam/lib/account.inc b/lam/lib/account.inc index 8270254b4..14dcc7ac6 100644 --- a/lam/lib/account.inc +++ b/lam/lib/account.inc @@ -41,7 +41,7 @@ use LDAP\Connection; * * @template T * @param T[] $values list of values which should be removed - * @param T[] $array list of original values + * @param T[]|null $array list of original values * @return T[] list of remaining values */ function array_delete($values, $array) { @@ -62,8 +62,8 @@ function array_delete($values, $array) { /** * Checks if a string exists in an array, ignoring case. * - * @param String $needle search string - * @param array $haystack array + * @param string|null $needle search string + * @param array|null $haystack array */ function in_array_ignore_case($needle, $haystack) { if (!is_array($haystack)) { @@ -108,57 +108,10 @@ function natCaseKeySort(array $toSort): array { return $newElements; } -/** - * This function will return the days from 1.1.1970 until now. - * - * @return number of days - */ -function getdays() { - $days = time() / 86400; - return (int) $days; -} - -/** - * Takes a list of Samba flags and creates the corresponding flag string. - * - * @param array $input is an array of Samba flags (e.g. X or D) - * @return string Samba flag string - */ -function smbflag($input) { - // Start character - $flag = "["; - // Add Options - if ($input['W']) { - $flag .= "W"; - } - else { - $flag .= "U"; - } - if ($input['D']) { - $flag .= "D"; - } - if ($input['X']) { - $flag .= "X"; - } - if ($input['N']) { - $flag .= "N"; - } - if ($input['S']) { - $flag .= "S"; - } - if ($input['H']) { - $flag .= "H"; - } - // Expand string to fixed length - $flag = str_pad($flag, 12); - // End character - return $flag . "]"; -} - /** * Generates the NT hash of a password. * - * @param string password original password + * @param string $password password original password * @return string password hash */ function ntPassword($password) { @@ -167,16 +120,17 @@ function ntPassword($password) { /** * Returns the hash value of a plain text password. - * @param string $password the password string + * + * @param string|null $password the password string * @param boolean $enabled marks the hash as enabled/disabled (e.g. by prefixing "!") * @param string $hashType password hash type (CRYPT, CRYPT-SHA512, SHA, SSHA, MD5, SMD5, PLAIN, K5KEY) * @return string the password hash - * @see getSupportedHashTypes() * + * @see getSupportedHashTypes() */ function pwd_hash($password, $enabled = true, $hashType = 'SSHA') { // check for empty password - if (!$password || ($password == "")) { + if (($password === null) || ($password === "")) { return ""; } switch ($hashType) { @@ -412,7 +366,7 @@ function generateRandomText($length = 20): string { /** * Checks if the given password matches the crypto hash. * - * @param String type hash type (must be one of getSupportedHashTypes()) + * @param string $type type hash type (must be one of getSupportedHashTypes()) * @param string $hash password hash value * @param string $password plain text password to check * @return bool hash matches @@ -467,7 +421,7 @@ function checkPasswordHash($type, $hash, $password) { /** * Returns the number of character classes in a password. * - * @param string $password password + * @param string|null $password password * @return int number of classes */ function getNumberOfCharacterClasses($password): int { @@ -1039,13 +993,13 @@ function ldapListDN($dn, $filter = '(objectclass=*)', $attributes = ['dn'], $han /** * Deletes a DN and all child entries. * - * @param string $dn DN to delete + * @param string|null $dn DN to delete * @param boolean $recursive recursive delete also child entries * @return array error messages */ function deleteDN($dn, $recursive) { $errors = []; - if (($dn == null) || ($dn == '')) { + if (($dn === null) || ($dn === '')) { $errors[] = ['ERROR', _('Entry does not exist')]; return $errors; } @@ -1146,7 +1100,7 @@ function moveDn(string $oldDn, string $targetDn): void { /** * Returns the parameters for a StatusMessage of the last LDAP search. * - * @return array parameters for StatusMessage or null if all was ok + * @return array|null parameters for StatusMessage or null if all was ok */ function getLastLDAPError() { $errorNumber = ldap_errno($_SESSION["ldap"]->server()); @@ -1351,10 +1305,11 @@ function parseLDAPTimestamp($time) { /** * Simple function to obfuscate strings. * - * @param String $text text to obfuscate + * @param string|null $text text to obfuscate + * @return string|null obfuscated text */ function obfuscateText($text) { - if (($text == null) || ($text == '')) { + if (($text === null) || ($text === '')) { return $text; } return str_rot13(base64_encode('LAM_OBFUSCATE:' . $text)); @@ -1363,10 +1318,11 @@ function obfuscateText($text) { /** * Simple function to deobfuscate strings. * - * @param String $text text to deobfuscate + * @param string|null $text text to deobfuscate + * @return string|null deobfuscated text */ function deobfuscateText($text) { - if (($text == null) || ($text == '')) { + if (($text === null) || ($text === '')) { return $text; } if (!isObfuscatedText($text)) { @@ -1378,11 +1334,11 @@ function deobfuscateText($text) { /** * Checks if the given text is obfuscated. * - * @param String $text text to check - * @return boolean obfuscated or not + * @param string|null $text text to check + * @return bool obfuscated or not */ -function isObfuscatedText($text) { - if (($text == null) || ($text == '')) { +function isObfuscatedText($text): bool { + if (($text === null) || ($text === '')) { return false; } $deob = base64_decode(str_rot13($text)); @@ -1392,8 +1348,8 @@ function isObfuscatedText($text) { /** * Extracts the RDN attribute name from a given DN. * - * @param String $dn DN - * @return String RDN attribute name + * @param string $dn DN + * @return string|null RDN attribute name */ function extractRDNAttribute($dn) { $rdn = extractRDN($dn); @@ -1407,8 +1363,8 @@ function extractRDNAttribute($dn) { /** * Extracts the RDN attribute value from a given DN. * - * @param String $dn DN - * @return String RDN attribute value + * @param string $dn DN + * @return string|null RDN attribute value */ function extractRDNValue($dn) { $rdn = extractRDN($dn); @@ -1442,11 +1398,11 @@ function extractRDN(?string $dn): ?string { * Extracts the DN suffix from a given DN. * E.g. ou=people,dc=test,dc=com will result in dc=test,dc=com. * - * @param String $dn DN - * @return String DN suffix + * @param string|null $dn DN + * @return string|null DN suffix */ function extractDNSuffix($dn) { - if ($dn == null) { + if ($dn === null) { return null; } $dn = convertCommaEscaping($dn); @@ -1479,7 +1435,7 @@ function testSmtpConnection(string $server, string $user, string $password, stri $mailer->isSMTP(); $serverParts = explode(':', $server); $mailer->Host = $serverParts[0]; - $mailer->Port = $serverParts[1]; + $mailer->Port = (int) $serverParts[1]; if (!empty($user)) { $mailer->SMTPAuth = true; $mailer->Username = $user; @@ -1587,7 +1543,7 @@ function sendEMail($to, $subject, $text, $from, $isHTML, $replyTo = null, $cc = $mailer->isSMTP(); $serverParts = explode(':', $cfgMain->mailServer); $mailer->Host = $serverParts[0]; - $mailer->Port = $serverParts[1]; + $mailer->Port = (int) $serverParts[1]; if (!empty($cfgMain->mailUser)) { $mailer->SMTPAuth = true; $mailer->Username = $cfgMain->mailUser; @@ -1787,10 +1743,7 @@ function getRandomNumber() { * @return mixed false on error and certificate if extracted successfully */ function getLDAPSSLCertificate($server, $port) { - $stream = @stream_context_create(["ssl" => ["capture_peer_cert_chain" => true, "verify_peer" => false, "allow_self_signed" => true]]); - if (!$stream) { - return false; - } + $stream = stream_context_create(["ssl" => ["capture_peer_cert_chain" => true, "verify_peer" => false, "allow_self_signed" => true]]); $client = @stream_socket_client('ssl://' . $server . ':' . $port, $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $stream); if (!$client) { return false; @@ -1817,7 +1770,7 @@ function getLDAPSSLCertificate($server, $port) { /** * Returns the extended LDAP error message if any. * - * @param handle $server LDAP server handle + * @param Connection $server LDAP server handle * @return String error message */ function getExtendedLDAPErrorMessage($server) { @@ -1833,7 +1786,7 @@ function getExtendedLDAPErrorMessage($server) { * Returns the default error message to display on the web page. * HTML special characters are already escaped. * - * @param LDAP\Connection $server LDAP server handle + * @param Connection $server LDAP server handle * @return String error message */ function getDefaultLDAPErrorString($server) { @@ -1937,7 +1890,7 @@ function getCallingURL($baseUrl = ''): ?string { /** * Returns the offset in hours from configured time zone to GMT. * - * @return int offset + * @return float offset */ function getTimeZoneOffsetHours() { $dtz = getTimeZone(); @@ -1963,7 +1916,7 @@ function getTimeZone() { /** * Returns the current time in formatted form. * - * @param unknown $format format to use (e.g. 'Y-m-d H:i:s') + * @param string $format format to use (e.g. 'Y-m-d H:i:s') */ function getFormattedTime($format) { $time = new DateTime('now', getTimeZone()); @@ -1974,8 +1927,8 @@ function getFormattedTime($format) { * Formats a number of seconds to a more human readable format with minutes, hours, etc. * E.g. 70 seconds will return 1m10s. * - * @param int $numSeconds number of seconds - * @return String formatted number + * @param int|string $numSeconds number of seconds + * @return string formatted number */ function formatSecondsToShortFormat($numSeconds) { if (($numSeconds === '0') || ($numSeconds === 0)) { @@ -2111,12 +2064,12 @@ function printJsIncludes($prefix) { } /** - * Converts an UTF-8 string to UTF16LE. + * Converts a UTF-8 string to UTF16LE. * - * @param string $input UTF-8 value + * @param string|null $input UTF-8 value */ function convertUtf8ToUtf16Le($input) { - if (($input == null) || (strlen($input) == 0)) { + if (($input === null) || (strlen($input) === 0)) { return $input; } $output = iconv('UTF-8', 'UTF-16LE', $input); @@ -2142,10 +2095,10 @@ function getLAMVersionText() { /** * Returns if the given release is a developer version. * - * @param string version + * @param string $version version * @return bool is developer version */ -function isDeveloperVersion($version) { +function isDeveloperVersion($version): bool { return str_contains($version, 'DEV'); } diff --git a/lam/lib/baseType.inc b/lam/lib/baseType.inc index 211f36ece..612cfd9b0 100644 --- a/lam/lib/baseType.inc +++ b/lam/lib/baseType.inc @@ -5,7 +5,7 @@ use LAM\TYPES\ConfiguredType; /* This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) - Copyright (C) 2005 - 2024 Roland Gruber + Copyright (C) 2005 - 2025 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 @@ -123,10 +123,10 @@ class baseType { } /** - * Returns the the title text for the title bar on the new/edit page. + * Returns the title text for the title bar on the new/edit page. * * @param accountContainer $container account container - * @return String title text + * @return string|null title text */ public function getTitleBarTitle($container) { if ($container->dn_orig == null) { @@ -157,8 +157,7 @@ class baseType { $lockableOptions = []; $statusSupported = false; foreach ($container->getAccountModules() as $module) { - $interfaces = class_implements($module); - if (!in_array('AccountStatusProvider', $interfaces)) { + if (!($module instanceof AccountStatusProvider)) { continue; } $statusSupported = true; @@ -354,8 +353,7 @@ class baseType { } } foreach ($container->getAccountModules() as $module) { - $interfaces = class_implements($module); - if (!in_array('AccountStatusProvider', $interfaces)) { + if (!($module instanceof AccountStatusProvider)) { continue; } $dummyAttributes = null; @@ -371,8 +369,7 @@ class baseType { } } foreach ($container->getAccountModules() as $module) { - $interfaces = class_implements($module); - if (!in_array('AccountStatusProvider', $interfaces)) { + if (!($module instanceof AccountStatusProvider)) { continue; } $dummyAttributes = null; diff --git a/lam/lib/export.inc b/lam/lib/export.inc index 62ce93d04..981d659e7 100644 --- a/lam/lib/export.inc +++ b/lam/lib/export.inc @@ -9,7 +9,7 @@ use LamTemporaryFilesManager; /* This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) - Copyright (C) 2018 - 2024 Roland Gruber + Copyright (C) 2018 - 2025 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 @@ -197,7 +197,7 @@ class Exporter { /** * Converts the given LDAP entries to CSV format. * - * @param string $entries entries + * @param array $entries entries * @param string $lineEnding line ending */ private function getCsvOutput(&$entries, $lineEnding) { diff --git a/lam/lib/modules.inc b/lam/lib/modules.inc index 8b92c123e..9eb8ed2f0 100644 --- a/lam/lib/modules.inc +++ b/lam/lib/modules.inc @@ -2357,7 +2357,7 @@ class accountContainer { * * @return array list of attributes which are serialized */ - function __sleep() { + public function __sleep() { // encrypt data $this->attributes = lamEncrypt(json_encode($this->attributes, JSON_INVALID_UTF8_IGNORE)); $this->attributes_orig = lamEncrypt(json_encode($this->attributes_orig, JSON_INVALID_UTF8_IGNORE)); @@ -2369,7 +2369,7 @@ class accountContainer { /** * Decrypts sensitive data after accountContainer was loaded from session. */ - function __wakeup() { + public function __wakeup() { // decrypt data $this->attributes = json_decode(lamDecrypt($this->attributes), true, 512, JSON_INVALID_UTF8_IGNORE); $this->attributes_orig = json_decode(lamDecrypt($this->attributes_orig), true, 512, JSON_INVALID_UTF8_IGNORE);