refactoring

This commit is contained in:
Roland Gruber 2025-07-27 20:46:41 +02:00
parent 5b636dea8b
commit ff59d97ac3
6 changed files with 68 additions and 113 deletions

View file

@ -18,7 +18,8 @@
"ext-gettext": "*", "ext-gettext": "*",
"ext-curl": "*", "ext-curl": "*",
"ext-openssl": "*", "ext-openssl": "*",
"ext-xmlwriter": "*" "ext-xmlwriter": "*",
"ext-iconv": "*"
}, },
"scripts": { "scripts": {
"test": "vendor/bin/phpunit" "test": "vendor/bin/phpunit"

View file

@ -7,6 +7,11 @@ use DateTime;
use Duo\DuoUniversal\Client; use Duo\DuoUniversal\Client;
use Duo\DuoUniversal\DuoException; use Duo\DuoUniversal\DuoException;
use Exception; 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 htmlResponsiveRow;
use LAM\LOGIN\WEBAUTHN\WebauthnManager; use LAM\LOGIN\WEBAUTHN\WebauthnManager;
use SelfServiceLoginHandler; use SelfServiceLoginHandler;
@ -130,7 +135,7 @@ abstract class BaseProvider implements TwoFactorProvider {
* Returns the value of the user attribute in LDAP. * Returns the value of the user attribute in LDAP.
* *
* @param string $userDn user DN * @param string $userDn user DN
* @return string user name * @return string|null user name
*/ */
protected function getLoginAttributeValue($userDn) { protected function getLoginAttributeValue($userDn) {
$attrName = $this->config->twoFactorAuthenticationSerialAttributeName; $attrName = $this->config->twoFactorAuthenticationSerialAttributeName;
@ -831,10 +836,10 @@ class OpenIdProvider extends BaseProvider {
/** /**
* Returns the client object. * Returns the client object.
* *
* @return \Facile\OpenIDClient\Client\Client client * @return ClientInterface client
*/ */
private function getOpenIdClient(): \Facile\OpenIDClient\Client\Client { private function getOpenIdClient(): ClientInterface {
$issuer = (new \Facile\OpenIDClient\Issuer\IssuerBuilder())->build($this->config->twoFactorAuthenticationURL . '/.well-known/openid-configuration'); $issuer = (new IssuerBuilder())->build($this->config->twoFactorAuthenticationURL . '/.well-known/openid-configuration');
$meta = [ $meta = [
'client_id' => $this->config->twoFactorAuthenticationClientId, 'client_id' => $this->config->twoFactorAuthenticationClientId,
'client_secret' => $this->config->twoFactorAuthenticationSecretKey, 'client_secret' => $this->config->twoFactorAuthenticationSecretKey,
@ -843,8 +848,8 @@ class OpenIdProvider extends BaseProvider {
if (!empty($_GET['redirect_uri'])) { if (!empty($_GET['redirect_uri'])) {
$meta['redirect_uri'] = $_GET['redirect_uri']; $meta['redirect_uri'] = $_GET['redirect_uri'];
} }
$clientMetadata = \Facile\OpenIDClient\Client\Metadata\ClientMetadata::fromArray($meta); $clientMetadata = ClientMetadata::fromArray($meta);
return (new \Facile\OpenIDClient\Client\ClientBuilder()) return (new ClientBuilder())
->setIssuer($issuer) ->setIssuer($issuer)
->setClientMetadata($clientMetadata) ->setClientMetadata($clientMetadata)
->build(); ->build();
@ -874,7 +879,7 @@ class OpenIdProvider extends BaseProvider {
include_once __DIR__ . '/3rdParty/composer/autoload.php'; include_once __DIR__ . '/3rdParty/composer/autoload.php';
$client = $this->getOpenIdClient(); $client = $this->getOpenIdClient();
$authorizationService = $this->getAuthorizationService(); $authorizationService = $this->getAuthorizationService();
$serverRequest = \GuzzleHttp\Psr7\ServerRequest::fromGlobals(); $serverRequest = ServerRequest::fromGlobals();
try { try {
$callbackParams = $authorizationService->getCallbackParams($serverRequest, $client); $callbackParams = $authorizationService->getCallbackParams($serverRequest, $client);
$tokenSet = $authorizationService->callback($client, $callbackParams, $_GET['redirect_uri']); $tokenSet = $authorizationService->callback($client, $callbackParams, $_GET['redirect_uri']);
@ -1093,7 +1098,6 @@ class TwoFactorProviderService {
/** /**
* Returns the provider for the given type. * Returns the provider for the given type.
* *
* @param string $type authentication type
* @return TwoFactorProvider provider * @return TwoFactorProvider provider
* @throws Exception unable to get provider * @throws Exception unable to get provider
*/ */

View file

@ -41,7 +41,7 @@ use LDAP\Connection;
* *
* @template T * @template T
* @param T[] $values list of values which should be removed * @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 * @return T[] list of remaining values
*/ */
function array_delete($values, $array) { function array_delete($values, $array) {
@ -62,8 +62,8 @@ function array_delete($values, $array) {
/** /**
* Checks if a string exists in an array, ignoring case. * Checks if a string exists in an array, ignoring case.
* *
* @param String $needle search string * @param string|null $needle search string
* @param array $haystack array * @param array|null $haystack array
*/ */
function in_array_ignore_case($needle, $haystack) { function in_array_ignore_case($needle, $haystack) {
if (!is_array($haystack)) { if (!is_array($haystack)) {
@ -108,57 +108,10 @@ function natCaseKeySort(array $toSort): array {
return $newElements; 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. * Generates the NT hash of a password.
* *
* @param string password original password * @param string $password password original password
* @return string password hash * @return string password hash
*/ */
function ntPassword($password) { function ntPassword($password) {
@ -167,16 +120,17 @@ function ntPassword($password) {
/** /**
* Returns the hash value of a plain text 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 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) * @param string $hashType password hash type (CRYPT, CRYPT-SHA512, SHA, SSHA, MD5, SMD5, PLAIN, K5KEY)
* @return string the password hash * @return string the password hash
* @see getSupportedHashTypes()
* *
* @see getSupportedHashTypes()
*/ */
function pwd_hash($password, $enabled = true, $hashType = 'SSHA') { function pwd_hash($password, $enabled = true, $hashType = 'SSHA') {
// check for empty password // check for empty password
if (!$password || ($password == "")) { if (($password === null) || ($password === "")) {
return ""; return "";
} }
switch ($hashType) { switch ($hashType) {
@ -412,7 +366,7 @@ function generateRandomText($length = 20): string {
/** /**
* Checks if the given password matches the crypto hash. * 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 $hash password hash value
* @param string $password plain text password to check * @param string $password plain text password to check
* @return bool hash matches * @return bool hash matches
@ -467,7 +421,7 @@ function checkPasswordHash($type, $hash, $password) {
/** /**
* Returns the number of character classes in a password. * Returns the number of character classes in a password.
* *
* @param string $password password * @param string|null $password password
* @return int number of classes * @return int number of classes
*/ */
function getNumberOfCharacterClasses($password): int { function getNumberOfCharacterClasses($password): int {
@ -1039,13 +993,13 @@ function ldapListDN($dn, $filter = '(objectclass=*)', $attributes = ['dn'], $han
/** /**
* Deletes a DN and all child entries. * 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 * @param boolean $recursive recursive delete also child entries
* @return array error messages * @return array error messages
*/ */
function deleteDN($dn, $recursive) { function deleteDN($dn, $recursive) {
$errors = []; $errors = [];
if (($dn == null) || ($dn == '')) { if (($dn === null) || ($dn === '')) {
$errors[] = ['ERROR', _('Entry does not exist')]; $errors[] = ['ERROR', _('Entry does not exist')];
return $errors; return $errors;
} }
@ -1146,7 +1100,7 @@ function moveDn(string $oldDn, string $targetDn): void {
/** /**
* Returns the parameters for a StatusMessage of the last LDAP search. * 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() { function getLastLDAPError() {
$errorNumber = ldap_errno($_SESSION["ldap"]->server()); $errorNumber = ldap_errno($_SESSION["ldap"]->server());
@ -1351,10 +1305,11 @@ function parseLDAPTimestamp($time) {
/** /**
* Simple function to obfuscate strings. * 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) { function obfuscateText($text) {
if (($text == null) || ($text == '')) { if (($text === null) || ($text === '')) {
return $text; return $text;
} }
return str_rot13(base64_encode('LAM_OBFUSCATE:' . $text)); return str_rot13(base64_encode('LAM_OBFUSCATE:' . $text));
@ -1363,10 +1318,11 @@ function obfuscateText($text) {
/** /**
* Simple function to deobfuscate strings. * 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) { function deobfuscateText($text) {
if (($text == null) || ($text == '')) { if (($text === null) || ($text === '')) {
return $text; return $text;
} }
if (!isObfuscatedText($text)) { if (!isObfuscatedText($text)) {
@ -1378,11 +1334,11 @@ function deobfuscateText($text) {
/** /**
* Checks if the given text is obfuscated. * Checks if the given text is obfuscated.
* *
* @param String $text text to check * @param string|null $text text to check
* @return boolean obfuscated or not * @return bool obfuscated or not
*/ */
function isObfuscatedText($text) { function isObfuscatedText($text): bool {
if (($text == null) || ($text == '')) { if (($text === null) || ($text === '')) {
return false; return false;
} }
$deob = base64_decode(str_rot13($text)); $deob = base64_decode(str_rot13($text));
@ -1392,8 +1348,8 @@ function isObfuscatedText($text) {
/** /**
* Extracts the RDN attribute name from a given DN. * Extracts the RDN attribute name from a given DN.
* *
* @param String $dn DN * @param string $dn DN
* @return String RDN attribute name * @return string|null RDN attribute name
*/ */
function extractRDNAttribute($dn) { function extractRDNAttribute($dn) {
$rdn = extractRDN($dn); $rdn = extractRDN($dn);
@ -1407,8 +1363,8 @@ function extractRDNAttribute($dn) {
/** /**
* Extracts the RDN attribute value from a given DN. * Extracts the RDN attribute value from a given DN.
* *
* @param String $dn DN * @param string $dn DN
* @return String RDN attribute value * @return string|null RDN attribute value
*/ */
function extractRDNValue($dn) { function extractRDNValue($dn) {
$rdn = extractRDN($dn); $rdn = extractRDN($dn);
@ -1442,11 +1398,11 @@ function extractRDN(?string $dn): ?string {
* Extracts the DN suffix from a given DN. * Extracts the DN suffix from a given DN.
* E.g. ou=people,dc=test,dc=com will result in dc=test,dc=com. * E.g. ou=people,dc=test,dc=com will result in dc=test,dc=com.
* *
* @param String $dn DN * @param string|null $dn DN
* @return String DN suffix * @return string|null DN suffix
*/ */
function extractDNSuffix($dn) { function extractDNSuffix($dn) {
if ($dn == null) { if ($dn === null) {
return null; return null;
} }
$dn = convertCommaEscaping($dn); $dn = convertCommaEscaping($dn);
@ -1479,7 +1435,7 @@ function testSmtpConnection(string $server, string $user, string $password, stri
$mailer->isSMTP(); $mailer->isSMTP();
$serverParts = explode(':', $server); $serverParts = explode(':', $server);
$mailer->Host = $serverParts[0]; $mailer->Host = $serverParts[0];
$mailer->Port = $serverParts[1]; $mailer->Port = (int) $serverParts[1];
if (!empty($user)) { if (!empty($user)) {
$mailer->SMTPAuth = true; $mailer->SMTPAuth = true;
$mailer->Username = $user; $mailer->Username = $user;
@ -1587,7 +1543,7 @@ function sendEMail($to, $subject, $text, $from, $isHTML, $replyTo = null, $cc =
$mailer->isSMTP(); $mailer->isSMTP();
$serverParts = explode(':', $cfgMain->mailServer); $serverParts = explode(':', $cfgMain->mailServer);
$mailer->Host = $serverParts[0]; $mailer->Host = $serverParts[0];
$mailer->Port = $serverParts[1]; $mailer->Port = (int) $serverParts[1];
if (!empty($cfgMain->mailUser)) { if (!empty($cfgMain->mailUser)) {
$mailer->SMTPAuth = true; $mailer->SMTPAuth = true;
$mailer->Username = $cfgMain->mailUser; $mailer->Username = $cfgMain->mailUser;
@ -1787,10 +1743,7 @@ function getRandomNumber() {
* @return mixed false on error and certificate if extracted successfully * @return mixed false on error and certificate if extracted successfully
*/ */
function getLDAPSSLCertificate($server, $port) { function getLDAPSSLCertificate($server, $port) {
$stream = @stream_context_create(["ssl" => ["capture_peer_cert_chain" => true, "verify_peer" => false, "allow_self_signed" => true]]); $stream = stream_context_create(["ssl" => ["capture_peer_cert_chain" => true, "verify_peer" => false, "allow_self_signed" => true]]);
if (!$stream) {
return false;
}
$client = @stream_socket_client('ssl://' . $server . ':' . $port, $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $stream); $client = @stream_socket_client('ssl://' . $server . ':' . $port, $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $stream);
if (!$client) { if (!$client) {
return false; return false;
@ -1817,7 +1770,7 @@ function getLDAPSSLCertificate($server, $port) {
/** /**
* Returns the extended LDAP error message if any. * Returns the extended LDAP error message if any.
* *
* @param handle $server LDAP server handle * @param Connection $server LDAP server handle
* @return String error message * @return String error message
*/ */
function getExtendedLDAPErrorMessage($server) { function getExtendedLDAPErrorMessage($server) {
@ -1833,7 +1786,7 @@ function getExtendedLDAPErrorMessage($server) {
* Returns the default error message to display on the web page. * Returns the default error message to display on the web page.
* HTML special characters are already escaped. * HTML special characters are already escaped.
* *
* @param LDAP\Connection $server LDAP server handle * @param Connection $server LDAP server handle
* @return String error message * @return String error message
*/ */
function getDefaultLDAPErrorString($server) { function getDefaultLDAPErrorString($server) {
@ -1937,7 +1890,7 @@ function getCallingURL($baseUrl = ''): ?string {
/** /**
* Returns the offset in hours from configured time zone to GMT. * Returns the offset in hours from configured time zone to GMT.
* *
* @return int offset * @return float offset
*/ */
function getTimeZoneOffsetHours() { function getTimeZoneOffsetHours() {
$dtz = getTimeZone(); $dtz = getTimeZone();
@ -1963,7 +1916,7 @@ function getTimeZone() {
/** /**
* Returns the current time in formatted form. * 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) { function getFormattedTime($format) {
$time = new DateTime('now', getTimeZone()); $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. * Formats a number of seconds to a more human readable format with minutes, hours, etc.
* E.g. 70 seconds will return 1m10s. * E.g. 70 seconds will return 1m10s.
* *
* @param int $numSeconds number of seconds * @param int|string $numSeconds number of seconds
* @return String formatted number * @return string formatted number
*/ */
function formatSecondsToShortFormat($numSeconds) { function formatSecondsToShortFormat($numSeconds) {
if (($numSeconds === '0') || ($numSeconds === 0)) { 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) { function convertUtf8ToUtf16Le($input) {
if (($input == null) || (strlen($input) == 0)) { if (($input === null) || (strlen($input) === 0)) {
return $input; return $input;
} }
$output = iconv('UTF-8', 'UTF-16LE', $input); $output = iconv('UTF-8', 'UTF-16LE', $input);
@ -2142,10 +2095,10 @@ function getLAMVersionText() {
/** /**
* Returns if the given release is a developer version. * Returns if the given release is a developer version.
* *
* @param string version * @param string $version version
* @return bool is developer version * @return bool is developer version
*/ */
function isDeveloperVersion($version) { function isDeveloperVersion($version): bool {
return str_contains($version, 'DEV'); return str_contains($version, 'DEV');
} }

View file

@ -5,7 +5,7 @@ use LAM\TYPES\ConfiguredType;
/* /*
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) 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 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 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 * @param accountContainer $container account container
* @return String title text * @return string|null title text
*/ */
public function getTitleBarTitle($container) { public function getTitleBarTitle($container) {
if ($container->dn_orig == null) { if ($container->dn_orig == null) {
@ -157,8 +157,7 @@ class baseType {
$lockableOptions = []; $lockableOptions = [];
$statusSupported = false; $statusSupported = false;
foreach ($container->getAccountModules() as $module) { foreach ($container->getAccountModules() as $module) {
$interfaces = class_implements($module); if (!($module instanceof AccountStatusProvider)) {
if (!in_array('AccountStatusProvider', $interfaces)) {
continue; continue;
} }
$statusSupported = true; $statusSupported = true;
@ -354,8 +353,7 @@ class baseType {
} }
} }
foreach ($container->getAccountModules() as $module) { foreach ($container->getAccountModules() as $module) {
$interfaces = class_implements($module); if (!($module instanceof AccountStatusProvider)) {
if (!in_array('AccountStatusProvider', $interfaces)) {
continue; continue;
} }
$dummyAttributes = null; $dummyAttributes = null;
@ -371,8 +369,7 @@ class baseType {
} }
} }
foreach ($container->getAccountModules() as $module) { foreach ($container->getAccountModules() as $module) {
$interfaces = class_implements($module); if (!($module instanceof AccountStatusProvider)) {
if (!in_array('AccountStatusProvider', $interfaces)) {
continue; continue;
} }
$dummyAttributes = null; $dummyAttributes = null;

View file

@ -9,7 +9,7 @@ use LamTemporaryFilesManager;
/* /*
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) 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 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 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. * Converts the given LDAP entries to CSV format.
* *
* @param string $entries entries * @param array $entries entries
* @param string $lineEnding line ending * @param string $lineEnding line ending
*/ */
private function getCsvOutput(&$entries, $lineEnding) { private function getCsvOutput(&$entries, $lineEnding) {

View file

@ -2357,7 +2357,7 @@ class accountContainer {
* *
* @return array list of attributes which are serialized * @return array list of attributes which are serialized
*/ */
function __sleep() { public function __sleep() {
// encrypt data // encrypt data
$this->attributes = lamEncrypt(json_encode($this->attributes, JSON_INVALID_UTF8_IGNORE)); $this->attributes = lamEncrypt(json_encode($this->attributes, JSON_INVALID_UTF8_IGNORE));
$this->attributes_orig = lamEncrypt(json_encode($this->attributes_orig, 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. * Decrypts sensitive data after accountContainer was loaded from session.
*/ */
function __wakeup() { public function __wakeup() {
// decrypt data // decrypt data
$this->attributes = json_decode(lamDecrypt($this->attributes), true, 512, JSON_INVALID_UTF8_IGNORE); $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); $this->attributes_orig = json_decode(lamDecrypt($this->attributes_orig), true, 512, JSON_INVALID_UTF8_IGNORE);