From 72016a5735e77634522e53975f3b2b63ba1f8a2d Mon Sep 17 00:00:00 2001 From: Michael Kaufmann Date: Tue, 7 May 2019 14:03:37 +0200 Subject: [PATCH 001/159] fix integrity-check language-file entries Signed-off-by: Michael Kaufmann --- lng/english.lng.php | 12 ++++++------ lng/german.lng.php | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lng/english.lng.php b/lng/english.lng.php index 45bced52..bf55b07b 100644 --- a/lng/english.lng.php +++ b/lng/english.lng.php @@ -1743,12 +1743,12 @@ $lng['admin']['configfiles']['commands'] = 'Commands: T $lng['admin']['configfiles']['files'] = 'Config files: The commands before the textfields should open an editor with the target file. Just copy and paste the contents into the editor and save the file.
Please note: The MySQL-password has not been replaced for security reasons. Please replace "FROXLOR_MYSQL_PASSWORD" on your own or use the javascript form below to replace it on-site. If you forgot your MySQL-password you\'ll find it in "lib/userdata.inc.php"'; $lng['serversettings']['apache_itksupport']['title'] = 'Use modifications for Apache ITK-MPM'; $lng['serversettings']['apache_itksupport']['description'] = 'ATTENTION: use only if you actually have apache itk-mpm enabled
otherwise your webserver will not be able to start'; -$lng['integrity_check']['DatabaseCharset'] = 'Character set of database (should be UTF-8)'; -$lng['integrity_check']['DomainIpTable'] = 'IP <‐> domain references'; -$lng['integrity_check']['SubdomainSslRedirect'] = 'False SSL-redirect flag for non-ssl domains'; -$lng['integrity_check']['FroxlorLocalGroupMemberForFcgidPhpFpm'] = 'froxlor-user in the customer groups (for FCGID/php-fpm)'; -$lng['integrity_check']['WebserverGroupMemberForFcgidPhpFpm'] = 'Webserver-user in the customer groups (for FCGID/php-fpm)'; -$lng['integrity_check']['SubdomainLetsencrypt'] = 'Main domains with no SSL-Port assigned don\'t have any subdomains with active SSL redirect'; +$lng['integrity_check']['databaseCharset'] = 'Character set of database (should be UTF-8)'; +$lng['integrity_check']['domainIpTable'] = 'IP <‐> domain references'; +$lng['integrity_check']['subdomainSslRedirect'] = 'False SSL-redirect flag for non-ssl domains'; +$lng['integrity_check']['froxlorLocalGroupMemberForFcgidPhpFpm'] = 'froxlor-user in the customer groups (for FCGID/php-fpm)'; +$lng['integrity_check']['webserverGroupMemberForFcgidPhpFpm'] = 'Webserver-user in the customer groups (for FCGID/php-fpm)'; +$lng['integrity_check']['subdomainLetsencrypt'] = 'Main domains with no SSL-Port assigned don\'t have any subdomains with active SSL redirect'; $lng['admin']['mod_fcgid_umask']['title'] = 'Umask (default: 022)'; // Added for apcuinfo diff --git a/lng/german.lng.php b/lng/german.lng.php index 551ff001..4e150a75 100644 --- a/lng/german.lng.php +++ b/lng/german.lng.php @@ -1467,12 +1467,12 @@ $lng['admin']['configfiles']['commands'] = 'Kommandos: $lng['admin']['configfiles']['files'] = 'Konfigurationsdateien: Der Befehl direkt vor dem Textfeld sollte einen Editor mit der Zieldatei öffnen. Der Inhalt kann nun einfach kopiert und in den Editor eingefügt und die Datei gespeichert werden.
Bitte beachten: Das MySQL-Passwort wurde aus Sicherheitsgründen nicht ersetzt. Bitte ersetzen Sie "FROXLOR_MYSQL_PASSWORD" manuell oder nutzen Sie das folgende Formular, um es temporär auf dieser Seite zu setzen. Falls das Passwort vergessen wurde, findet es sich in der Datei "lib/userdata.inc.php".'; $lng['serversettings']['apache_itksupport']['title'] = 'Anpassungen für Apache ITK-MPM verwenden'; $lng['serversettings']['apache_itksupport']['description'] = '
Achtung: Bitte nur verwenden, wenn wirklich Apache itk-mpm verwendet wird, ansonsten wird der Webserver nicht starten.
'; -$lng['integrity_check']['DatabaseCharset'] = 'Characterset der Datenbank (sollte UTF-8 sein)'; -$lng['integrity_check']['DomainIpTable'] = 'IP <‐> Domain Verknüpfung'; -$lng['integrity_check']['SubdomainSslRedirect'] = 'Falsches SSL-redirect Flag bei nicht-SSL Domains'; -$lng['integrity_check']['FroxlorLocalGroupMemberForFcgidPhpFpm'] = 'froxlor-Benutzer in Kunden-Gruppen (für FCGID/php-fpm)'; -$lng['integrity_check']['WebserverGroupMemberForFcgidPhpFpm'] = 'Webserver-Benutzer in Kunden-Gruppen (für FCGID/php-fpm)'; -$lng['integrity_check']['SubdomainLetsencrypt'] = 'Hauptdomains ohne zugewiesenen SSL-Port haben keine Subdomain mit aktiviertem SSL-Redirect'; +$lng['integrity_check']['databaseCharset'] = 'Characterset der Datenbank (sollte UTF-8 sein)'; +$lng['integrity_check']['domainIpTable'] = 'IP <‐> Domain Verknüpfung'; +$lng['integrity_check']['subdomainSslRedirect'] = 'Falsches SSL-redirect Flag bei nicht-SSL Domains'; +$lng['integrity_check']['froxlorLocalGroupMemberForFcgidPhpFpm'] = 'froxlor-Benutzer in Kunden-Gruppen (für FCGID/php-fpm)'; +$lng['integrity_check']['webserverGroupMemberForFcgidPhpFpm'] = 'Webserver-Benutzer in Kunden-Gruppen (für FCGID/php-fpm)'; +$lng['integrity_check']['subdomainLetsencrypt'] = 'Hauptdomains ohne zugewiesenen SSL-Port haben keine Subdomain mit aktiviertem SSL-Redirect'; $lng['admin']['mod_fcgid_umask']['title'] = 'Umask (Standard: 022)'; // Added for let's encrypt From e2d69c664a92b05e580e10c111a1712b6861f9d5 Mon Sep 17 00:00:00 2001 From: Christian Schiffler Date: Mon, 13 May 2019 19:53:55 +0200 Subject: [PATCH 002/159] Fixes #682 - mail log parsing regex character group The mail log parsing regex was incorrectly using a character group of `\A` --- lib/Froxlor/MailLogParser.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Froxlor/MailLogParser.php b/lib/Froxlor/MailLogParser.php index 1463da2f..f8800e89 100644 --- a/lib/Froxlor/MailLogParser.php +++ b/lib/Froxlor/MailLogParser.php @@ -101,13 +101,13 @@ class MailLogParser $timestamp = $this->getLogTimestamp($line); if ($this->startTime < $timestamp) { - if (preg_match("/postfix\/qmgr.*(?::|\])\s([A-Z\d]+).*from=?, size=(\d+),/", $line, $matches)) { + if (preg_match("/postfix\/qmgr.*(?::|\])\s([A-Z\d]+).*from=?, size=(\d+),/", $line, $matches)) { // Postfix from $this->mails[$matches[1]] = array( "domainFrom" => strtolower($matches[2]), "size" => $matches[3] ); - } elseif (preg_match("/postfix\/(?:pipe|smtp).*(?::|\])\s([A-Z\d]+).*to=?,/", $line, $matches)) { + } elseif (preg_match("/postfix\/(?:pipe|smtp).*(?::|\])\s([A-Z\d]+).*to=?,/", $line, $matches)) { // Postfix to if (array_key_exists($matches[1], $this->mails)) { $this->mails[$matches[1]]["domainTo"] = strtolower($matches[2]); From 68f55f95968f9108c12e24ad3149800b8790cc07 Mon Sep 17 00:00:00 2001 From: Michael Kaufmann Date: Mon, 27 May 2019 08:33:36 +0200 Subject: [PATCH 003/159] dont allow bootstrap.php file from tests/ to be called via browser Signed-off-by: Michael Kaufmann --- tests/bootstrap.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/bootstrap.php b/tests/bootstrap.php index a4e59d86..87344530 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -11,6 +11,11 @@ if (file_exists('/etc/froxlor-test.pwd') && file_exists('/etc/froxlor-test.rpwd' define('TRAVIS_CI', 1); } +if (@php_sapi_name() !== 'cli') { + // not to be called via browser + die; +} + $userdata_content = " Date: Mon, 27 May 2019 11:47:58 +0200 Subject: [PATCH 004/159] set version to 0.10.0-rc2 for second release candidate Signed-off-by: Michael Kaufmann --- install/froxlor.sql | 2 +- install/updates/froxlor/0.10/update_0.10.inc.php | 4 ++++ lib/Froxlor/Froxlor.php | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/install/froxlor.sql b/install/froxlor.sql index 127fa073..ec917791 100644 --- a/install/froxlor.sql +++ b/install/froxlor.sql @@ -680,7 +680,7 @@ opcache.interned_strings_buffer'), ('panel', 'password_special_char', '!?<>§$%+#=@'), ('panel', 'customer_hide_options', ''), ('panel', 'is_configured', '0'), - ('panel', 'version', '0.10.0-rc1'), + ('panel', 'version', '0.10.0-rc2'), ('panel', 'db_version', '201904250'); diff --git a/install/updates/froxlor/0.10/update_0.10.inc.php b/install/updates/froxlor/0.10/update_0.10.inc.php index c4796636..d79ceb9e 100644 --- a/install/updates/froxlor/0.10/update_0.10.inc.php +++ b/install/updates/froxlor/0.10/update_0.10.inc.php @@ -255,3 +255,7 @@ if (\Froxlor\Froxlor::isDatabaseVersion('201904100')) { \Froxlor\Froxlor::updateToDbVersion('201904250'); } + +if (\Froxlor\Froxlor::isFroxlorVersion('0.10.0-rc1')) { + \Froxlor\Froxlor::updateToVersion('0.10.0-rc2'); +} diff --git a/lib/Froxlor/Froxlor.php b/lib/Froxlor/Froxlor.php index 99934a6d..53e32359 100644 --- a/lib/Froxlor/Froxlor.php +++ b/lib/Froxlor/Froxlor.php @@ -7,7 +7,7 @@ final class Froxlor { // Main version variable - const VERSION = '0.10.0-rc1'; + const VERSION = '0.10.0-rc2'; // Database version (YYYYMMDDC where C is a daily counter) const DBVERSION = '201904250'; From b75c9ddff63b6be19d0de8bb6257428471f5dacf Mon Sep 17 00:00:00 2001 From: Daniel Drexlmaier Date: Mon, 27 May 2019 15:27:28 +0200 Subject: [PATCH 005/159] Update install.php --- install/install.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/install/install.php b/install/install.php index 1e06c9d1..3a93b420 100644 --- a/install/install.php +++ b/install/install.php @@ -15,6 +15,9 @@ * @package Install * */ +if(!file_exists(dirname(__DIR__) . '/vendor/autoload.php')){ + die('Vendor does not exist. Please run "Composer install". For more informationen https://github.com/Froxlor/Froxlor/wiki'); +} require dirname(__DIR__) . '/vendor/autoload.php'; require __DIR__ . '/lib/class.FroxlorInstall.php'; From 79e5113e1298a21bb30035f710d8e00a765ba3e7 Mon Sep 17 00:00:00 2001 From: Daniel Drexlmaier Date: Mon, 27 May 2019 15:28:08 +0200 Subject: [PATCH 006/159] Update init.php --- lib/init.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/init.php b/lib/init.php index 2e57aa1c..7d474ad4 100644 --- a/lib/init.php +++ b/lib/init.php @@ -16,6 +16,10 @@ * @package System * */ +if(!file_exists(dirname(__DIR__) . '/vendor/autoload.php')){ + die('Vendor does not exist. Please run "Composer install". For more informationen https://github.com/Froxlor/Froxlor/wiki'); +} + require dirname(__DIR__) . '/vendor/autoload.php'; use Froxlor\Database\Database; From fb87129e294d510538e67bb5e7a995b3c773505f Mon Sep 17 00:00:00 2001 From: Daniel Drexlmaier Date: Mon, 27 May 2019 15:46:39 +0200 Subject: [PATCH 007/159] Update init.php --- lib/init.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/init.php b/lib/init.php index 7d474ad4..bec161f6 100644 --- a/lib/init.php +++ b/lib/init.php @@ -17,7 +17,7 @@ * */ if(!file_exists(dirname(__DIR__) . '/vendor/autoload.php')){ - die('Vendor does not exist. Please run "Composer install". For more informationen https://github.com/Froxlor/Froxlor/wiki'); + die('Vendor does not exist. Please run "composer install". For more informationen https://github.com/Froxlor/Froxlor/wiki'); } require dirname(__DIR__) . '/vendor/autoload.php'; From 6ea91f55e5052df86e6d1e90dbbc03073b0e7d7e Mon Sep 17 00:00:00 2001 From: Daniel Drexlmaier Date: Mon, 27 May 2019 15:47:30 +0200 Subject: [PATCH 008/159] Update install.php --- install/install.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/install.php b/install/install.php index 3a93b420..76723290 100644 --- a/install/install.php +++ b/install/install.php @@ -16,7 +16,7 @@ * */ if(!file_exists(dirname(__DIR__) . '/vendor/autoload.php')){ - die('Vendor does not exist. Please run "Composer install". For more informationen https://github.com/Froxlor/Froxlor/wiki'); + die('Vendor does not exist. Please run "composer install". For more informationen https://github.com/Froxlor/Froxlor/wiki'); } require dirname(__DIR__) . '/vendor/autoload.php'; require __DIR__ . '/lib/class.FroxlorInstall.php'; From a647d48fbed68a1f6646490ef9a1ed6bc12e9a39 Mon Sep 17 00:00:00 2001 From: Michael Kaufmann Date: Mon, 27 May 2019 17:48:33 +0200 Subject: [PATCH 009/159] fix up testing/production switch and challengepath for lets encrypt, fixes #696 Signed-off-by: Michael Kaufmann --- lib/Froxlor/Cron/Http/LetsEncrypt/AcmeSh.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/Froxlor/Cron/Http/LetsEncrypt/AcmeSh.php b/lib/Froxlor/Cron/Http/LetsEncrypt/AcmeSh.php index 07e1ec27..70b398fc 100644 --- a/lib/Froxlor/Cron/Http/LetsEncrypt/AcmeSh.php +++ b/lib/Froxlor/Cron/Http/LetsEncrypt/AcmeSh.php @@ -272,7 +272,7 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron $acmesh_cmd = self::$acmesh . " --auto-upgrade 0 --server " . self::$apiserver . " --" . $cert_mode . " -d " . implode(" -d ", $domains); if ($cert_mode == 'issue') { - $acmesh_cmd .= " -w " . \Froxlor\Froxlor::getInstallDir(); + $acmesh_cmd .= " -w " . Settings::Get('system.letsencryptchallengepath'); } if (Settings::Get('system.leecc') > 0) { $acmesh_cmd .= " --keylength ec-" . Settings::Get('system.leecc'); @@ -282,6 +282,9 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron if (Settings::Get('system.letsencryptreuseold') != '1') { $acmesh_cmd .= " --always-force-new-domain-key"; } + if (Settings::Get('system.letsencryptca') == 'testing') { + $acmesh_cmd .= " --staging"; + } $acme_result = \Froxlor\FileDir::safe_exec($acmesh_cmd); From 87a2f86365aeac3764e7ff705b2e3a5977582fb3 Mon Sep 17 00:00:00 2001 From: Michael Kaufmann Date: Thu, 30 May 2019 17:44:08 +0200 Subject: [PATCH 010/159] do not set default ssl-ips if the frontend values are left empty; if default ssl-ips are specified, preset them in the form when adding a domain, fixes #697 Signed-off-by: Michael Kaufmann --- lib/Froxlor/Api/Commands/Domains.php | 9 ++++++--- lib/formfields/admin/domains/formfield.domains_add.php | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/Froxlor/Api/Commands/Domains.php b/lib/Froxlor/Api/Commands/Domains.php index 05104b25..79009efd 100644 --- a/lib/Froxlor/Api/Commands/Domains.php +++ b/lib/Froxlor/Api/Commands/Domains.php @@ -170,7 +170,9 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn * @param bool $letsencrypt * optional, whether to generate a Let's Encrypt certificate for this domain, default false; requires SSL to be enabled * @param array $ssl_ipandport - * optional, list of ssl-enabled ip/port id's to assign to this domain + * optional, list of ssl-enabled ip/port id's to assign to this domain, default empty + * @param bool $use_default_ssl_ipandport_if_empty + * optional, set the systems default ssl ip addresses if none are given via $ssl_ipandport parameter * @param bool $http2 * optional, whether to enable http/2 for this domain (requires to be enabled in the settings), default 0 (false) * @param int $hsts_maxage @@ -223,7 +225,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn $mod_fcgid_maxrequests = $this->getParam('mod_fcgid_maxrequests', true, - 1); $ssl_redirect = $this->getBoolParam('ssl_redirect', true, 0); $letsencrypt = $this->getBoolParam('letsencrypt', true, 0); - $p_ssl_ipandports = $this->getParam('ssl_ipandport', true, explode(',', Settings::Get('system.defaultsslip'))); + $use_default_ssl_ipandport_if_empty = $this->getBoolParam('use_default_ssl_ipandport_if_empty', true, 0); + $p_ssl_ipandports = $this->getParam('ssl_ipandport', true, $use_default_ssl_ipandport_if_empty ? explode(',', Settings::Get('system.defaultsslip')) : array()); $http2 = $this->getBoolParam('http2', true, 0); $hsts_maxage = $this->getParam('hsts_maxage', true, 0); $hsts_sub = $this->getBoolParam('hsts_sub', true, 0); @@ -1633,7 +1636,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn * @param boolean $ssl * default false * @param int $edit_id - * default 0 + * default 0 * * @throws \Exception * @return array diff --git a/lib/formfields/admin/domains/formfield.domains_add.php b/lib/formfields/admin/domains/formfield.domains_add.php index 48b7b243..ddbb6266 100644 --- a/lib/formfields/admin/domains/formfield.domains_add.php +++ b/lib/formfields/admin/domains/formfield.domains_add.php @@ -185,7 +185,7 @@ return array( 'desc' => $lng['domains']['ipandport_ssl_multi']['description'], 'type' => 'checkbox', 'values' => $ssl_ipsandports, - 'value' => '', + 'value' => explode(',', \Froxlor\Settings::Get('system.defaultsslip')), 'is_array' => 1 ), 'ssl_redirect' => array( From 6806f896d62c0bc065d36b6885d5e77dba3c6b83 Mon Sep 17 00:00:00 2001 From: Michael Kaufmann Date: Fri, 31 May 2019 08:02:03 +0200 Subject: [PATCH 011/159] fix proftp path of rhel/centos config template, fixes #636 Signed-off-by: Michael Kaufmann --- lib/configfiles/rhel_centos.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/configfiles/rhel_centos.xml b/lib/configfiles/rhel_centos.xml index 68f9e544..0e3682f9 100644 --- a/lib/configfiles/rhel_centos.xml +++ b/lib/configfiles/rhel_centos.xml @@ -1826,7 +1826,7 @@ iterate_query = SELECT username AS user FROM mail_users - Date: Mon, 3 Jun 2019 11:59:56 +0200 Subject: [PATCH 012/159] fix vhost(parts)-merging in nginx cron, fixes #669 Signed-off-by: Michael Kaufmann --- lib/Froxlor/Cron/Http/Nginx.php | 46 +++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/lib/Froxlor/Cron/Http/Nginx.php b/lib/Froxlor/Cron/Http/Nginx.php index ff6f3669..e38c9a6f 100644 --- a/lib/Froxlor/Cron/Http/Nginx.php +++ b/lib/Froxlor/Cron/Http/Nginx.php @@ -250,7 +250,7 @@ class Nginx extends HttpConfigBase $aliases = ""; $froxlor_aliases = Settings::Get('system.froxloraliases'); - if (!empty($froxlor_aliases)) { + if (! empty($froxlor_aliases)) { $froxlor_aliases = explode(",", $froxlor_aliases); foreach ($froxlor_aliases as $falias) { if (\Froxlor\Validate\Validate::validateDomain(trim($falias))) { @@ -574,26 +574,38 @@ class Nginx extends HttpConfigBase return $vhost_content; } + private function cleanVhostStruct($vhost = null) + { + // Remove windows linebreaks + $vhost = str_replace("\r", "\n", $vhost); + // Break blocks into lines + $vhost = str_replace(array( + "{", + "}" + ), array( + " {\n", + "\n}" + ), $vhost); + // Break into array items + $vhost = explode("\n", preg_replace('/[ \t]+/', ' ', trim(preg_replace('/\t+/', '', $vhost)))); + // Remove empty lines + $vhost = array_filter($vhost, function ($a) { + return preg_match("#\S#", $a); + }); + + // remove unnecessary whitespaces + $vhost = array_map("trim", $vhost); + // re-number array keys + $vhost = array_values($vhost); + return $vhost; + } + protected function mergeVhostCustom($vhost_frx, $vhost_usr) { // Clean froxlor defined settings - $vhost_frx = explode("\n", preg_replace('/[ \t]+/', ' ', trim(preg_replace('/\t+/', '', $vhost_frx)))); // Break into array items - $vhost_frx = array_map("trim", $vhost_frx); // remove unnecessary whitespaces - + $vhost_frx = $this->cleanVhostStruct($vhost_frx); // Clean user defined settings - $vhost_usr = str_replace("\r", "\n", $vhost_usr); // Remove windows linebreaks - $vhost_usr = str_replace(array( - "{ ", - " }" - ), array( - "{\n", - "\n}" - ), $vhost_usr); // Break blocks into lines - $vhost_usr = explode("\n", preg_replace('/[ \t]+/', ' ', trim(preg_replace('/\t+/', '', $vhost_usr)))); // Break into array items - // Remove empty lines - $vhost_usr = array_filter($vhost_usr, function ($a) { - return preg_match("#\S#", $a); - }); + $vhost_usr = $this->cleanVhostStruct($vhost_usr); // Cycle through the user defined settings $currentBlock = array(); From 13086d91d85862b676321667024ce47aabbef73b Mon Sep 17 00:00:00 2001 From: Michael Kaufmann Date: Tue, 4 Jun 2019 15:14:51 +0200 Subject: [PATCH 013/159] only validate and process ip-list if given at all Signed-off-by: Michael Kaufmann --- api_keys.php | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/api_keys.php b/api_keys.php index fec078e7..0c3126e5 100644 --- a/api_keys.php +++ b/api_keys.php @@ -88,15 +88,17 @@ if ($action == 'delete') { $valid_until = isset($_POST['valid_until']) ? (int) $_POST['valid_until'] : - 1; // validate allowed_from - $ip_list = array_map('trim', explode(",", $allowed_from)); - $_check_list = $ip_list; - foreach ($_check_list as $idx => $ip) { - if (\Froxlor\Validate\Validate::validate_ip2($ip, true, 'invalidip', true, true) == false) { - unset($ip_list[$idx]); + if (! empty($allowed_from)) { + $ip_list = array_map('trim', explode(",", $allowed_from)); + $_check_list = $ip_list; + foreach ($_check_list as $idx => $ip) { + if (\Froxlor\Validate\Validate::validate_ip2($ip, true, 'invalidip', true, true) == false) { + unset($ip_list[$idx]); + } } + $ip_list = array_map('inet_ntop', array_map('inet_pton', $ip_list)); + $allowed_from = implode(",", array_unique($ip_list)); } - $ip_list = array_map('inet_ntop', array_map('inet_pton', $ip_list)); - $allowed_from = implode(",", array_unique($ip_list)); if ($valid_until <= 0 || ! is_numeric($valid_until)) { $valid_until = - 1; From 97703e7a0cd1c74e79b60d41e9a739d7cc10f164 Mon Sep 17 00:00:00 2001 From: Michael Kaufmann Date: Wed, 5 Jun 2019 06:39:44 +0200 Subject: [PATCH 014/159] add a few tests for Settings Signed-off-by: Michael Kaufmann --- lib/Froxlor/Settings.php | 2 + tests/Froxlor/SettingsTest.php | 94 ++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 tests/Froxlor/SettingsTest.php diff --git a/lib/Froxlor/Settings.php b/lib/Froxlor/Settings.php index 88edf132..17dd0c43 100644 --- a/lib/Froxlor/Settings.php +++ b/lib/Froxlor/Settings.php @@ -263,6 +263,8 @@ class Settings self::init(); // empty update array self::$updatedata = array(); + // re-read in all settings + return self::readSettings(); } public static function loadSettingsInto(&$settings_data) diff --git a/tests/Froxlor/SettingsTest.php b/tests/Froxlor/SettingsTest.php new file mode 100644 index 00000000..b0f9922d --- /dev/null +++ b/tests/Froxlor/SettingsTest.php @@ -0,0 +1,94 @@ +assertEquals("dev.froxlor.org", $syshostname); + } + + public function testSettingGetNoSeparator() + { + $nullval = \Froxlor\Settings::Get('system'); + $this->assertNull($nullval); + } + + public function testSettingGetUnknown() + { + $nullval = \Froxlor\Settings::Get('thissetting.doesnotexist'); + $this->assertNull($nullval); + } + + public function testSettingsAddNew() + { + \Froxlor\Settings::AddNew('temp.setting', 'empty'); + $actval = \Froxlor\Settings::Get('temp.setting'); + $this->assertEquals("empty", $actval); + } + + public function testSettingsAddNewSettingExists() + { + $result = \Froxlor\Settings::AddNew('system.ipaddress', '127.0.0.1'); + $this->assertFalse($result); + } + + /** + * + * @depends testSettingsAddNew + */ + public function testSettingSetNoSave() + { + $actval = \Froxlor\Settings::Get('temp.setting'); + $this->assertEquals("empty", $actval); + \Froxlor\Settings::Set('temp.setting', 'temp-value', false); + $tmpval = \Froxlor\Settings::Get('temp.setting'); + $this->assertEquals("temp-value", $tmpval); + \Froxlor\Settings::Stash(); + $actval = \Froxlor\Settings::Get('temp.setting'); + $this->assertEquals("empty", $actval); + } + + /** + * + * @depends testSettingsAddNew + */ + public function testSettingsSetInstantSave() + { + \Froxlor\Settings::Set('temp.setting', 'temp-value'); + \Froxlor\Settings::Stash(); + $tmpval = \Froxlor\Settings::Get('temp.setting'); + $this->assertEquals("temp-value", $tmpval); + } + + /** + * + * @depends testSettingsAddNew + */ + public function testSettingsSetFlushSave() + { + \Froxlor\Settings::Set('temp.setting', 'another-temp-value', false); + \Froxlor\Settings::Flush(); + $actval = \Froxlor\Settings::Get('temp.setting'); + $this->assertEquals("another-temp-value", $actval); + } + + public function testSettingsIsInList() + { + $result = \Froxlor\Settings::IsInList("system.mysql_access_host", "localhost"); + $this->assertTrue($result); + $result = \Froxlor\Settings::IsInList("system.mysql_access_host", "my-super-domain.de"); + $this->assertFalse($result); + } +} From 13bfd62ac5132c972c11f25f8fce41c0e6a6c6d0 Mon Sep 17 00:00:00 2001 From: Michael Kaufmann Date: Wed, 5 Jun 2019 06:50:06 +0200 Subject: [PATCH 015/159] move validateUrl function to correct file Signed-off-by: Michael Kaufmann --- customer_domains.php | 2 +- lib/Froxlor/Api/Commands/DirOptions.php | 2 +- lib/Froxlor/Api/Commands/SubDomains.php | 4 +- lib/Froxlor/Cron/Http/Apache.php | 4 +- lib/Froxlor/Cron/Http/Lighttpd.php | 4 +- lib/Froxlor/Cron/Http/Nginx.php | 8 ++-- lib/Froxlor/Validate/Form/Data.php | 60 +------------------------ lib/Froxlor/Validate/Validate.php | 56 +++++++++++++++++++++++ 8 files changed, 70 insertions(+), 70 deletions(-) diff --git a/customer_domains.php b/customer_domains.php index 0e44156f..50681cf2 100644 --- a/customer_domains.php +++ b/customer_domains.php @@ -369,7 +369,7 @@ if ($page == 'overview') { $domains .= \Froxlor\UI\HTML::makeoption($idna_convert->decode($row_domain['domain']), $row_domain['id'], $result['aliasdomain']); } - if (preg_match('/^https?\:\/\//', $result['documentroot']) && \Froxlor\Validate\Form\Data::validateUrl($result['documentroot'])) { + if (preg_match('/^https?\:\/\//', $result['documentroot']) && \Froxlor\Validate\Validate::validateUrl($result['documentroot'])) { if (Settings::Get('panel.pathedit') == 'Dropdown') { $urlvalue = $result['documentroot']; $pathSelect = \Froxlor\FileDir::makePathfield($userinfo['documentroot'], $userinfo['guid'], $userinfo['guid']); diff --git a/lib/Froxlor/Api/Commands/DirOptions.php b/lib/Froxlor/Api/Commands/DirOptions.php index b2ec7fb4..ad5116b9 100644 --- a/lib/Froxlor/Api/Commands/DirOptions.php +++ b/lib/Froxlor/Api/Commands/DirOptions.php @@ -394,7 +394,7 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc { if ($errdoc !== null && $errdoc != '') { // not a URL - if ((strtoupper(substr($errdoc, 0, 5)) != 'HTTP:' && strtoupper(substr($errdoc, 0, 6)) != 'HTTPS:') || ! \Froxlor\Validate\Form\Data::validateUrl($errdoc)) { + if ((strtoupper(substr($errdoc, 0, 5)) != 'HTTP:' && strtoupper(substr($errdoc, 0, 6)) != 'HTTPS:') || ! \Froxlor\Validate\Validate::validateUrl($errdoc)) { // a file if (substr($errdoc, 0, 1) != '"') { $errdoc = \Froxlor\FileDir::makeCorrectFile($errdoc); diff --git a/lib/Froxlor/Api/Commands/SubDomains.php b/lib/Froxlor/Api/Commands/SubDomains.php index dbe329e5..4588a73d 100644 --- a/lib/Froxlor/Api/Commands/SubDomains.php +++ b/lib/Froxlor/Api/Commands/SubDomains.php @@ -852,7 +852,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc { // check whether an URL was specified $_doredirect = false; - if (! empty($url) && \Froxlor\Validate\Form\Data::validateUrl($url)) { + if (! empty($url) && \Froxlor\Validate\Validate::validateUrl($url)) { $path = $url; $_doredirect = true; } else { @@ -860,7 +860,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc } // check whether path is a real path - if (! preg_match('/^https?\:\/\//', $path) || ! \Froxlor\Validate\Form\Data::validateUrl($path)) { + if (! preg_match('/^https?\:\/\//', $path) || ! \Froxlor\Validate\Validate::validateUrl($path)) { if (strstr($path, ":") !== false) { \Froxlor\UI\Response::standard_error('pathmaynotcontaincolon', '', true); } diff --git a/lib/Froxlor/Cron/Http/Apache.php b/lib/Froxlor/Cron/Http/Apache.php index 2a6a9058..6b7d762b 100644 --- a/lib/Froxlor/Cron/Http/Apache.php +++ b/lib/Froxlor/Cron/Http/Apache.php @@ -144,7 +144,7 @@ class Apache extends HttpConfigBase foreach ($statusCodes as $statusCode) { if (Settings::Get('defaultwebsrverrhandler.err' . $statusCode) != '') { $defhandler = Settings::Get('defaultwebsrverrhandler.err' . $statusCode); - if (! \Froxlor\Validate\Form\Data::validateUrl($defhandler)) { + if (! \Froxlor\Validate\Validate::validateUrl($defhandler)) { if (substr($defhandler, 0, 1) != '"' && substr($defhandler, - 1, 1) != '"') { $defhandler = '"' . \Froxlor\FileDir::makeCorrectFile($defhandler) . '"'; } @@ -1209,7 +1209,7 @@ class Apache extends HttpConfigBase foreach ($statusCodes as $statusCode) { if (isset($row_diroptions['error' . $statusCode . 'path']) && $row_diroptions['error' . $statusCode . 'path'] != '') { $defhandler = $row_diroptions['error' . $statusCode . 'path']; - if (! \Froxlor\Validate\Form\Data::validateUrl($defhandler)) { + if (! \Froxlor\Validate\Validate::validateUrl($defhandler)) { if (substr($defhandler, 0, 1) != '"' && substr($defhandler, - 1, 1) != '"') { $defhandler = '"' . \Froxlor\FileDir::makeCorrectFile($defhandler) . '"'; } diff --git a/lib/Froxlor/Cron/Http/Lighttpd.php b/lib/Froxlor/Cron/Http/Lighttpd.php index 25dd6d95..fd15c2b1 100644 --- a/lib/Froxlor/Cron/Http/Lighttpd.php +++ b/lib/Froxlor/Cron/Http/Lighttpd.php @@ -316,7 +316,7 @@ class Lighttpd extends HttpConfigBase } $defhandler = Settings::Get('defaultwebsrverrhandler.err404'); - if (! \Froxlor\Validate\Form\Data::validateUrl($defhandler)) { + if (! \Froxlor\Validate\Validate::validateUrl($defhandler)) { $defhandler = \Froxlor\FileDir::makeCorrectFile($defhandler); } $this->lighttpd_data[$vhost_filename] = 'server.error-handler-404 = "' . $defhandler . '"'; @@ -707,7 +707,7 @@ class Lighttpd extends HttpConfigBase if (! empty($row['error404path'])) { $defhandler = $row['error404path']; - if (! \Froxlor\Validate\Form\Data::validateUrl($defhandler)) { + if (! \Froxlor\Validate\Validate::validateUrl($defhandler)) { $defhandler = \Froxlor\FileDir::makeCorrectFile($domain['documentroot'] . '/' . $defhandler); } $error_string .= ' server.error-handler-404 = "' . $defhandler . '"' . "\n\n"; diff --git a/lib/Froxlor/Cron/Http/Nginx.php b/lib/Froxlor/Cron/Http/Nginx.php index e38c9a6f..c42f8775 100644 --- a/lib/Froxlor/Cron/Http/Nginx.php +++ b/lib/Froxlor/Cron/Http/Nginx.php @@ -137,7 +137,7 @@ class Nginx extends HttpConfigBase foreach ($statusCodes as $statusCode) { if (Settings::Get('defaultwebsrverrhandler.err' . $statusCode) != '') { $defhandler = Settings::Get('defaultwebsrverrhandler.err' . $statusCode); - if (! \Froxlor\Validate\Form\Data::validateUrl($defhandler)) { + if (! \Froxlor\Validate\Validate::validateUrl($defhandler)) { $defhandler = \Froxlor\FileDir::makeCorrectFile($defhandler); } $this->nginx_data[$vhosts_filename] .= 'error_page ' . $statusCode . ' ' . $defhandler . ';' . "\n"; @@ -757,7 +757,7 @@ class Nginx extends HttpConfigBase while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) { if (! empty($row['error404path'])) { $defhandler = $row['error404path']; - if (! \Froxlor\Validate\Form\Data::validateUrl($defhandler)) { + if (! \Froxlor\Validate\Validate::validateUrl($defhandler)) { $defhandler = \Froxlor\FileDir::makeCorrectFile($defhandler); } $path_options .= "\t" . 'error_page 404 ' . $defhandler . ';' . "\n"; @@ -765,7 +765,7 @@ class Nginx extends HttpConfigBase if (! empty($row['error403path'])) { $defhandler = $row['error403path']; - if (! \Froxlor\Validate\Form\Data::validateUrl($defhandler)) { + if (! \Froxlor\Validate\Validate::validateUrl($defhandler)) { $defhandler = \Froxlor\FileDir::makeCorrectFile($defhandler); } $path_options .= "\t" . 'error_page 403 ' . $defhandler . ';' . "\n"; @@ -773,7 +773,7 @@ class Nginx extends HttpConfigBase if (! empty($row['error500path'])) { $defhandler = $row['error500path']; - if (! \Froxlor\Validate\Form\Data::validateUrl($defhandler)) { + if (! \Froxlor\Validate\Validate::validateUrl($defhandler)) { $defhandler = \Froxlor\FileDir::makeCorrectFile($defhandler); } $path_options .= "\t" . 'error_page 500 502 503 504 ' . $defhandler . ';' . "\n"; diff --git a/lib/Froxlor/Validate/Form/Data.php b/lib/Froxlor/Validate/Form/Data.php index a746ed17..713266b3 100644 --- a/lib/Froxlor/Validate/Form/Data.php +++ b/lib/Froxlor/Validate/Form/Data.php @@ -33,7 +33,7 @@ class Data if (isset($fielddata['string_type']) && $fielddata['string_type'] == 'mail') { $returnvalue = (filter_var($newfieldvalue, FILTER_VALIDATE_EMAIL) == $newfieldvalue); } elseif (isset($fielddata['string_type']) && $fielddata['string_type'] == 'url') { - $returnvalue = self::validateUrl($newfieldvalue); + $returnvalue = \Froxlor\Validate\Validate::validateUrl($newfieldvalue); } elseif (isset($fielddata['string_type']) && $fielddata['string_type'] == 'dir') { // check for empty value (it might be allowed) if (trim($newfieldvalue) == '') { @@ -128,62 +128,6 @@ class Data } } - /** - * Returns whether a URL is in a correct format or not - * - * @param string $url - * URL to be tested - * @return bool - * @author Christian Hoffmann - * @author Froxlor team (2010-) - * - */ - public static function validateUrl($url) - { - if (strtolower(substr($url, 0, 7)) != "http://" && strtolower(substr($url, 0, 8)) != "https://") { - $url = 'http://' . $url; - } - - // needs converting - try { - $idna_convert = new \Froxlor\Idna\IdnaWrapper(); - $url = $idna_convert->encode($url); - } catch (\Exception $e) { - return false; - } - - $pattern = '%^(?:(?:https?)://)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)*(?:\.(?:[a-z\x{00a1}-\x{ffff}]{2,})))(?::\d{2,5})?(?:/[^\s]*)?$%iuS'; - if (preg_match($pattern, $url)) { - return true; - } - - // not an fqdn - if (strtolower(substr($url, 0, 7)) == "http://" || strtolower(substr($url, 0, 8)) == "https://") { - if (strtolower(substr($url, 0, 7)) == "http://") { - $ip = strtolower(substr($url, 7)); - } - - if (strtolower(substr($url, 0, 8)) == "https://") { - $ip = strtolower(substr($url, 8)); - } - - $ip = substr($ip, 0, strpos($ip, '/')); - // possible : in IP (when a port is given), #1173 - // but only if there actually IS ONE - if (strpos($ip, ':') !== false) { - $ip = substr($ip, 0, strpos($ip, ':')); - } - - if (\Froxlor\Validate\Validate::validate_ip2($ip, true) !== false) { - return true; - } else { - return false; - } - } else { - return false; - } - } - public static function validateFormFieldBool($fieldname, $fielddata, $newfieldvalue) { if ($newfieldvalue === '1' || $newfieldvalue === 1 || $newfieldvalue === true || strtolower($newfieldvalue) === 'yes' || strtolower($newfieldvalue) === 'ja' || $newfieldvalue === '0' || $newfieldvalue === 0 || $newfieldvalue === false || strtolower($newfieldvalue) === 'no' || strtolower($newfieldvalue) === 'nein' || strtolower($newfieldvalue) === '') { @@ -252,7 +196,7 @@ class Data if (isset($fielddata['string_type']) && $fielddata['string_type'] == 'mail') { $returnvalue = (filter_var($newfieldvalue, FILTER_VALIDATE_EMAIL) == $newfieldvalue); } elseif (isset($fielddata['string_type']) && $fielddata['string_type'] == 'url') { - $returnvalue = \Froxlor\Validate\Form\Data::validateUrl($newfieldvalue); + $returnvalue = \Froxlor\Validate\Validate::validateUrl($newfieldvalue); } elseif (isset($fielddata['string_type']) && $fielddata['string_type'] == 'dir') { // add trailing slash to validate path if needed // refs #331 diff --git a/lib/Froxlor/Validate/Validate.php b/lib/Froxlor/Validate/Validate.php index 150bf44a..c6989cd7 100644 --- a/lib/Froxlor/Validate/Validate.php +++ b/lib/Froxlor/Validate/Validate.php @@ -122,6 +122,62 @@ class Validate } } + /** + * Returns whether a URL is in a correct format or not + * + * @param string $url + * URL to be tested + * @return bool + * @author Christian Hoffmann + * @author Froxlor team (2010-) + * + */ + public static function validateUrl($url) + { + if (strtolower(substr($url, 0, 7)) != "http://" && strtolower(substr($url, 0, 8)) != "https://") { + $url = 'http://' . $url; + } + + // needs converting + try { + $idna_convert = new \Froxlor\Idna\IdnaWrapper(); + $url = $idna_convert->encode($url); + } catch (\Exception $e) { + return false; + } + + $pattern = '%^(?:(?:https?)://)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)*(?:\.(?:[a-z\x{00a1}-\x{ffff}]{2,})))(?::\d{2,5})?(?:/[^\s]*)?$%iuS'; + if (preg_match($pattern, $url)) { + return true; + } + + // not an fqdn + if (strtolower(substr($url, 0, 7)) == "http://" || strtolower(substr($url, 0, 8)) == "https://") { + if (strtolower(substr($url, 0, 7)) == "http://") { + $ip = strtolower(substr($url, 7)); + } + + if (strtolower(substr($url, 0, 8)) == "https://") { + $ip = strtolower(substr($url, 8)); + } + + $ip = substr($ip, 0, strpos($ip, '/')); + // possible : in IP (when a port is given), #1173 + // but only if there actually IS ONE + if (strpos($ip, ':') !== false) { + $ip = substr($ip, 0, strpos($ip, ':')); + } + + if (\Froxlor\Validate\Validate::validate_ip2($ip, true) !== false) { + return true; + } else { + return false; + } + } else { + return false; + } + } + /** * Check if the submitted string is a valid domainname * From 4917b9c057928716b534030547f85b64b051128a Mon Sep 17 00:00:00 2001 From: Michael Kaufmann Date: Wed, 5 Jun 2019 09:07:21 +0200 Subject: [PATCH 016/159] added first validation tests Signed-off-by: Michael Kaufmann --- lib/Froxlor/Validate/Validate.php | 7 +-- tests/Froxlor/ValidateTest.php | 100 ++++++++++++++++++++++++++++++ tests/bootstrap.php | 2 + 3 files changed, 104 insertions(+), 5 deletions(-) create mode 100644 tests/Froxlor/ValidateTest.php diff --git a/lib/Froxlor/Validate/Validate.php b/lib/Froxlor/Validate/Validate.php index c6989cd7..2a767fe6 100644 --- a/lib/Froxlor/Validate/Validate.php +++ b/lib/Froxlor/Validate/Validate.php @@ -35,8 +35,8 @@ class Validate } // Check if the $str is one of the values which represent the default for an 'empty' value - if (is_array($emptydefault) && ! empty($emptydefault) && in_array($str, $emptydefault) && isset($emptydefault[0])) { - return $emptydefault[0]; + if (is_array($emptydefault) && ! empty($emptydefault) && in_array($str, $emptydefault)) { + return $str; } if ($pattern == '') { @@ -61,7 +61,6 @@ class Validate } \Froxlor\UI\Response::standard_error($lng, $fieldname, $throw_exception); - exit(); } /** @@ -99,7 +98,6 @@ class Validate return false; } else { \Froxlor\UI\Response::standard_error($lng, $ip, $throw_exception); - exit(); } } @@ -118,7 +116,6 @@ class Validate return false; } else { \Froxlor\UI\Response::standard_error($lng, $ip, $throw_exception); - exit(); } } diff --git a/tests/Froxlor/ValidateTest.php b/tests/Froxlor/ValidateTest.php new file mode 100644 index 00000000..0c7edb15 --- /dev/null +++ b/tests/Froxlor/ValidateTest.php @@ -0,0 +1,100 @@ +assertEquals("user input", $teststr); + } + + public function testValidateStrInEmptyDefault() + { + $teststr = Validate::validate("user input", "test-field", '', '', [ + "user test", + "user input", + "user bla" + ], true); + $this->assertEquals("user input", $teststr); + } + + public function testValidateEmptyDefaultNoArray() + { + $teststr = Validate::validate("user input", "test-field", '', '', "user input", true); + $this->assertEquals("user input", $teststr); + } + + public function testValidateRemoveNotAllowedChar() + { + $teststr = Validate::validate("user " . PHP_EOL . "input", "test-field", '', '', [], true); + $this->assertEquals("user input", $teststr); + } + + public function testValidateStringFormatError() + { + $this->expectException("Exception"); + $this->expectExceptionCode(400); + Validate::validate("user input", "test-field", '/^[A-Z]+$/i', '', [], true); + } + + public function testValidateIp() + { + $result = Validate::validate_ip2("12.34.56.78", false, 'invalidip', false, false, false, true); + $this->assertEquals("12.34.56.78", $result); + } + + public function testValidateIpPrivNotAllowed() + { + $this->expectException("Exception"); + $this->expectExceptionCode(400); + Validate::validate_ip2("10.0.0.1", false, 'invalidip', false, false, false, true); + } + + public function testValidateIpPrivNotAllowedBool() + { + $result = Validate::validate_ip2("10.0.0.1", true, 'invalidip', false, false, false, true); + $this->assertFalse($result); + } + + public function testValidateIpCidrNotAllowed() + { + $this->expectException("Exception"); + $this->expectExceptionCode(400); + Validate::validate_ip2("12.34.56.78/24", false, 'invalidip', false, false, false, true); + } + + public function testValidateIpCidrNotAllowedBool() + { + $result = Validate::validate_ip2("12.34.56.78/24", true, 'invalidip', false, false, false, true); + $this->assertFalse($result); + } + + public function testValidateIpCidr() + { + $result = Validate::validate_ip2("12.34.56.78/24", false, 'invalidip', false, false, true, true); + $this->assertEquals("12.34.56.78/24", $result); + } + + public function testValidateIpLocalhostAllowed() + { + $result = Validate::validate_ip2("127.0.0.1/32", false, 'invalidip', true, false, true, true); + $this->assertEquals("127.0.0.1/32", $result); + } + + public function testValidateIpLocalhostAllowedWrongIp() + { + $this->expectException("Exception"); + $this->expectExceptionCode(400); + Validate::validate_ip2("127.0.0.2", false, 'invalidip', true, false, false, true); + } +} diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 87344530..5b2f1210 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -148,6 +148,8 @@ $sel_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_ADMINS . "` WHERE $admin_userdata = Database::pexecute_first($sel_stmt); $admin_userdata['adminsession'] = 1; +$log = \Froxlor\FroxlorLogger::getInstanceOf($admin_userdata); + Settings::Set('panel.standardlanguage', 'English', true); Settings::Set('panel.adminmail', 'admin@dev.froxlor.org', true); Settings::Set('panel.allow_domain_change_admin', '1', true); From 0afbe3d13b67d439177ae23a4f60028b91cc7687 Mon Sep 17 00:00:00 2001 From: Michael Kaufmann Date: Wed, 5 Jun 2019 20:52:37 +0200 Subject: [PATCH 017/159] add validation tests Signed-off-by: Michael Kaufmann --- lib/Froxlor/Database/Database.php | 15 +++++ lib/Froxlor/Validate/Validate.php | 105 ++++++++++++------------------ tests/Froxlor/ValidateTest.php | 99 ++++++++++++++++++++++++++++ 3 files changed, 157 insertions(+), 62 deletions(-) diff --git a/lib/Froxlor/Database/Database.php b/lib/Froxlor/Database/Database.php index 466a948e..ccf5ad3b 100644 --- a/lib/Froxlor/Database/Database.php +++ b/lib/Froxlor/Database/Database.php @@ -183,6 +183,21 @@ class Database return $return; } + /** + * return number of characters that are allowed to use as username + * + * @return int + */ + public static function getSqlUsernameLength() + { + // MySQL user names can be up to 32 characters long (16 characters before MySQL 5.7.8). + $mysql_max = 32; + if (version_compare(Database::getAttribute(\PDO::ATTR_SERVER_VERSION), '5.7.8', '<')) { + $mysql_max -= 16; + } + return $mysql_max; + } + /** * let's us interact with the PDO-Object by using static * call like "Database::function()" diff --git a/lib/Froxlor/Validate/Validate.php b/lib/Froxlor/Validate/Validate.php index 2a767fe6..3e77b595 100644 --- a/lib/Froxlor/Validate/Validate.php +++ b/lib/Froxlor/Validate/Validate.php @@ -124,10 +124,8 @@ class Validate * * @param string $url * URL to be tested + * * @return bool - * @author Christian Hoffmann - * @author Froxlor team (2010-) - * */ public static function validateUrl($url) { @@ -148,31 +146,7 @@ class Validate return true; } - // not an fqdn - if (strtolower(substr($url, 0, 7)) == "http://" || strtolower(substr($url, 0, 8)) == "https://") { - if (strtolower(substr($url, 0, 7)) == "http://") { - $ip = strtolower(substr($url, 7)); - } - - if (strtolower(substr($url, 0, 8)) == "https://") { - $ip = strtolower(substr($url, 8)); - } - - $ip = substr($ip, 0, strpos($ip, '/')); - // possible : in IP (when a port is given), #1173 - // but only if there actually IS ONE - if (strpos($ip, ':') !== false) { - $ip = substr($ip, 0, strpos($ip, ':')); - } - - if (\Froxlor\Validate\Validate::validate_ip2($ip, true) !== false) { - return true; - } else { - return false; - } - } else { - return false; - } + return false; } /** @@ -210,7 +184,7 @@ class Validate */ public static function validateLocalHostname($hostname) { - $pattern = '/^([a-zA-Z0-9\-])+$/i'; + $pattern = '/^[a-z0-9][a-z0-9\-]{0,62}$/i'; if (preg_match($pattern, $hostname)) { return $hostname; } @@ -233,52 +207,59 @@ class Validate /** * Returns if an username is in correct format or not. * - * @param - * string The username to check - * @return bool Correct or not - * @author Michael Duergner - * + * @param string $username + * The username to check + * @param bool $unix_names + * optional, default true, checks whether it must be UNIX compatible + * @param int $mysql_max + * optional, number of max mysql username characters, default empty + * + * @return bool */ public static function validateUsername($username, $unix_names = 1, $mysql_max = '') { + if (empty($mysql_max) || ! is_numeric($mysql_max) || $mysql_max <= 0) { + $mysql_max = \Froxlor\Database\Database::getSqlUsernameLength() - 1; + } else { + $mysql_max --; + } if ($unix_names == 0) { if (strpos($username, '--') === false) { - return (preg_match('/^[a-z][a-z0-9\-_]{0,' . (int) ($mysql_max - 1) . '}[a-z0-9]{1}$/Di', $username) != false); - } else { - return false; + return (preg_match('/^[a-z][a-z0-9\-_]{0,' . $mysql_max . '}[a-z0-9]{1}$/Di', $username) != false); } - } else { - return (preg_match('/^[a-z][a-z0-9]{0,' . $mysql_max . '}$/Di', $username) != false); + return false; } + return (preg_match('/^[a-z][a-z0-9]{0,' . $mysql_max . '}$/Di', $username) != false); } + /** + * validate sql interval string + * + * @param string $interval + * + * @return boolean + */ public static function validateSqlInterval($interval = null) { - if (! $interval === null || $interval != '') { - if (strstr($interval, ' ') !== false) { - /* - * [0] = ([0-9]+) - * [1] = valid SQL-Interval expression - */ - $valid_expr = array( - 'SECOND', - 'MINUTE', - 'HOUR', - 'DAY', - 'WEEK', - 'MONTH', - 'YEAR' - ); + if (! empty($interval) && strstr($interval, ' ') !== false) { + /* + * [0] = ([0-9]+) + * [1] = valid SQL-Interval expression + */ + $valid_expr = array( + 'SECOND', + 'MINUTE', + 'HOUR', + 'DAY', + 'WEEK', + 'MONTH', + 'YEAR' + ); - $interval_parts = explode(' ', $interval); + $interval_parts = explode(' ', $interval); - if (is_array($interval_parts) && isset($interval_parts[0]) && isset($interval_parts[1])) { - if (preg_match('/([0-9]+)/i', $interval_parts[0])) { - if (in_array(strtoupper($interval_parts[1]), $valid_expr)) { - return true; - } - } - } + if (count($interval_parts) == 2 && preg_match('/[0-9]+/', $interval_parts[0]) && in_array(strtoupper($interval_parts[1]), $valid_expr)) { + return true; } } return false; diff --git a/tests/Froxlor/ValidateTest.php b/tests/Froxlor/ValidateTest.php index 0c7edb15..a47dba82 100644 --- a/tests/Froxlor/ValidateTest.php +++ b/tests/Froxlor/ValidateTest.php @@ -8,6 +8,7 @@ use Froxlor\Validate\Validate; * @covers \Froxlor\Validate\Validate * @covers \Froxlor\UI\Response * @covers \Froxlor\FroxlorLogger + * @covers \Froxlor\Idna\IdnaWrapper */ class ValidateTest extends TestCase { @@ -97,4 +98,102 @@ class ValidateTest extends TestCase $this->expectExceptionCode(400); Validate::validate_ip2("127.0.0.2", false, 'invalidip', true, false, false, true); } + + public function testValidateUrl() + { + $result = Validate::validateUrl("https://froxlor.org/"); + $this->assertTrue($result); + $result = Validate::validateUrl("http://forum.froxlor.org/"); + $this->assertTrue($result); + $result = Validate::validateUrl("https://api.froxlor.org/doc/0.10.0/index.php"); + $this->assertTrue($result); + $result = Validate::validateUrl("#froxlor"); + $this->assertFalse($result); + $result = Validate::validateUrl("https://82.149.225.211/"); + $this->assertTrue($result); + $result = Validate::validateUrl("https://82.149.225.300"); + $this->assertFalse($result); + $result = Validate::validateUrl("82.149.225.211:443"); + $this->assertTrue($result); + } + + public function testValidateDomain() + { + $result = Validate::validateDomain('froxlor.org'); + $this->assertEquals('froxlor.org', $result); + $result = Validate::validateDomain('_dmarc.froxlor.org'); + $this->assertFalse($result); + $result = Validate::validateDomain('_dmarc.froxlor.org', true); + $this->assertEquals('_dmarc.froxlor.org', $result); + $result = Validate::validateDomain('test._dmarc.froxlor.org', true); + $this->assertEquals('test._dmarc.froxlor.org', $result); + $result = Validate::validateDomain('0815'); + $this->assertFalse($result); + $result = Validate::validateDomain('abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz'); + $this->assertFalse($result); + } + + public function testValidateHostname() + { + $result = Validate::validateLocalHostname('localhost'); + $this->assertEquals('localhost', $result); + $result = Validate::validateLocalHostname('froxlor-srv02'); + $this->assertEquals('froxlor-srv02', $result); + $result = Validate::validateLocalHostname('froxlor_org'); + $this->assertFalse($result); + $result = Validate::validateLocalHostname('froxlor.org'); + $this->assertFalse($result); + $result = Validate::validateLocalHostname('a--------------------------------------------------------------'); + $this->assertEquals('a--------------------------------------------------------------', $result); + $result = Validate::validateLocalHostname('-hostname'); + $this->assertFalse($result); + $result = Validate::validateLocalHostname('a-----------------------------------------------------------------'); + $this->assertFalse($result); + } + + public function testValidateEmail() + { + $result = Validate::validateEmail('team@froxlor.org'); + $this->assertEquals('team@froxlor.org', $result); + $result = Validate::validateEmail('team.froxlor.org'); + $this->assertFalse($result); + } + + public function testValidateUsername() + { + $result = Validate::validateUsername('web123sql2'); + $this->assertTrue($result); + $mysql_max = \Froxlor\Database\Database::getSqlUsernameLength() - strlen(\Froxlor\Settings::Get('customer.mysqlprefix')); + $result = Validate::validateUsername('web123sql2', true, $mysql_max); + $this->assertTrue($result); + // too long + $result = Validate::validateUsername('myperfectsuperduperwebuser123sql2', true, $mysql_max); + $this->assertFalse($result); + // not unix-conform + $result = Validate::validateUsername('web123-sql2', true, $mysql_max); + $this->assertFalse($result); + // non-unix-conform + $result = Validate::validateUsername('web123-sql2', false, $mysql_max); + $this->assertTrue($result); + $result = Validate::validateUsername('web123--sql2', false, $mysql_max); + $this->assertFalse($result); + $result = Validate::validateUsername('-web123sql2', false, $mysql_max); + $this->assertFalse($result); + $result = Validate::validateUsername('web123sql2-', false, $mysql_max); + $this->assertFalse($result); + } + + public function testValidateSqlInterval() + { + $result = Validate::validateSqlInterval('60 HOUR'); + $this->assertTrue($result); + $result = Validate::validateSqlInterval('2 MONTH'); + $this->assertTrue($result); + $result = Validate::validateSqlInterval(); + $this->assertFalse($result); + $result = Validate::validateSqlInterval('2 QUARTER'); + $this->assertFalse($result); + $result = Validate::validateSqlInterval('1DAY'); + $this->assertFalse($result); + } } From d8a8f76dc95866decedc8851f9690ce1fc4b5752 Mon Sep 17 00:00:00 2001 From: Michael Kaufmann Date: Thu, 6 Jun 2019 10:18:03 +0200 Subject: [PATCH 018/159] update dev-environment to use more recent versions, requries php-7.3 now (dev-only) Signed-off-by: Michael Kaufmann --- .travis.yml | 6 +- build.xml | 17 +- composer.json | 19 +- composer.lock | 871 +++++++++++-------------- lib/Froxlor/Api/Commands/Customers.php | 7 +- lib/Froxlor/Database/Database.php | 2 +- lib/Froxlor/Validate/Check.php | 2 +- phpunit.xml | 10 +- tests/Customers/CustomersTest.php | 2 +- tests/Froxlor/SettingsTest.php | 3 +- tests/Traffic/TrafficTest.php | 2 +- 11 files changed, 439 insertions(+), 502 deletions(-) diff --git a/.travis.yml b/.travis.yml index b751d37c..5014b70f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,8 +4,8 @@ php: # - "5.4" # - "5.6" # - "7.0" - - "7.1" -# - "7.2" +# - "7.1" + - "7.3" branches: only: @@ -18,7 +18,7 @@ matrix: # env: deps=highest # - php: 5.4 # env: deps=lowest - - php: 7.1 + - php: 7.3 env: deps=highest mysql: diff --git a/build.xml b/build.xml index 291013db..150eebdc 100644 --- a/build.xml +++ b/build.xml @@ -226,7 +226,20 @@ - + + + + + + + + + + + @@ -234,6 +247,8 @@ + + diff --git a/composer.json b/composer.json index 4299118e..2b715393 100644 --- a/composer.json +++ b/composer.json @@ -49,17 +49,16 @@ "algo26-matthias/idna-convert": "^2.1" }, "require-dev": { - "phpunit/phpunit": "6.5.13", - "pdepend/pdepend": "2.5.0", - "phpmd/phpmd": "2.6.0", - "sebastian/phpcpd": "3.0.1", - "squizlabs/php_codesniffer": "3.3.2", - "phploc/phploc": "3.0.1", - "theseer/phpdox": "0.11.2", - "phpunit/php-invoker": "1.1.4", - "php": ">=7.1", + "phpunit/phpunit": "^8", + "php": ">=7.3", "ext-pcntl": "*", - "phpcompatibility/php-compatibility": "*" + "phpcompatibility/php-compatibility": "*", + "squizlabs/php_codesniffer": "*", + "pdepend/pdepend": "^2.5", + "sebastian/phpcpd": "^4.1", + "theseer/phpdox": "^0.12.0", + "phploc/phploc": "^5.0", + "phpmd/phpmd": "^2.6" }, "suggest": { "ext-bcmath": "*", diff --git a/composer.lock b/composer.lock index bbfe2827..21eb30fb 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5a09e82c87504e904337a4fc8a80e3a8", + "content-hash": "5be3ef1341b33f64d1eab9a4afa10f20", "packages": [ { "name": "algo26-matthias/idna-convert", @@ -247,16 +247,16 @@ }, { "name": "robthree/twofactorauth", - "version": "1.6.5", + "version": "1.6.6", "source": { "type": "git", "url": "https://github.com/RobThree/TwoFactorAuth.git", - "reference": "f5f58a4c62d0336a0e6175856894a51f3565dad2" + "reference": "7477d5d65625b7fe33cb338b98e419d394e9e9fd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/RobThree/TwoFactorAuth/zipball/f5f58a4c62d0336a0e6175856894a51f3565dad2", - "reference": "f5f58a4c62d0336a0e6175856894a51f3565dad2", + "url": "https://api.github.com/repos/RobThree/TwoFactorAuth/zipball/7477d5d65625b7fe33cb338b98e419d394e9e9fd", + "reference": "7477d5d65625b7fe33cb338b98e419d394e9e9fd", "shasum": "" }, "require": { @@ -294,33 +294,35 @@ "php", "tfa" ], - "time": "2018-06-09T10:09:59+00:00" + "time": "2019-03-19T21:51:19+00:00" } ], "packages-dev": [ { "name": "doctrine/instantiator", - "version": "1.1.0", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda" + "reference": "a2c590166b2133a4633738648b6b064edae0814a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", - "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/a2c590166b2133a4633738648b6b064edae0814a", + "reference": "a2c590166b2133a4633738648b6b064edae0814a", "shasum": "" }, "require": { "php": "^7.1" }, "require-dev": { - "athletic/athletic": "~0.1.8", + "doctrine/coding-standard": "^6.0", "ext-pdo": "*", "ext-phar": "*", - "phpunit/phpunit": "^6.2.3", - "squizlabs/php_codesniffer": "^3.0.2" + "phpbench/phpbench": "^0.13", + "phpstan/phpstan-phpunit": "^0.11", + "phpstan/phpstan-shim": "^0.11", + "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { @@ -345,25 +347,25 @@ } ], "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://github.com/doctrine/instantiator", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", "keywords": [ "constructor", "instantiate" ], - "time": "2017-07-22T11:58:36+00:00" + "time": "2019-03-17T17:37:11+00:00" }, { "name": "myclabs/deep-copy", - "version": "1.8.1", + "version": "1.9.1", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8" + "reference": "e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8", - "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72", + "reference": "e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72", "shasum": "" }, "require": { @@ -398,28 +400,28 @@ "object", "object graph" ], - "time": "2018-06-11T23:09:50+00:00" + "time": "2019-04-07T13:18:21+00:00" }, { "name": "nikic/php-parser", - "version": "v3.1.5", + "version": "v4.2.2", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "bb87e28e7d7b8d9a7fda231d37457c9210faf6ce" + "reference": "1bd73cc04c3843ad8d6b0bfc0956026a151fc420" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/bb87e28e7d7b8d9a7fda231d37457c9210faf6ce", - "reference": "bb87e28e7d7b8d9a7fda231d37457c9210faf6ce", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/1bd73cc04c3843ad8d6b0bfc0956026a151fc420", + "reference": "1bd73cc04c3843ad8d6b0bfc0956026a151fc420", "shasum": "" }, "require": { "ext-tokenizer": "*", - "php": ">=5.5" + "php": ">=7.0" }, "require-dev": { - "phpunit/phpunit": "~4.0|~5.0" + "phpunit/phpunit": "^6.5 || ^7.0" }, "bin": [ "bin/php-parse" @@ -427,7 +429,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -449,30 +451,30 @@ "parser", "php" ], - "time": "2018-02-28T20:30:58+00:00" + "time": "2019-05-25T20:07:01+00:00" }, { "name": "pdepend/pdepend", - "version": "2.5.0", + "version": "2.5.2", "source": { "type": "git", "url": "https://github.com/pdepend/pdepend.git", - "reference": "0c50874333149c0dad5a2877801aed148f2767ff" + "reference": "9daf26d0368d4a12bed1cacae1a9f3a6f0adf239" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pdepend/pdepend/zipball/0c50874333149c0dad5a2877801aed148f2767ff", - "reference": "0c50874333149c0dad5a2877801aed148f2767ff", + "url": "https://api.github.com/repos/pdepend/pdepend/zipball/9daf26d0368d4a12bed1cacae1a9f3a6f0adf239", + "reference": "9daf26d0368d4a12bed1cacae1a9f3a6f0adf239", "shasum": "" }, "require": { "php": ">=5.3.7", - "symfony/config": "^2.3.0|^3", - "symfony/dependency-injection": "^2.3.0|^3", - "symfony/filesystem": "^2.3.0|^3" + "symfony/config": "^2.3.0|^3|^4", + "symfony/dependency-injection": "^2.3.0|^3|^4", + "symfony/filesystem": "^2.3.0|^3|^4" }, "require-dev": { - "phpunit/phpunit": "^4.4.0,<4.8", + "phpunit/phpunit": "^4.8|^5.7", "squizlabs/php_codesniffer": "^2.0.0" }, "bin": [ @@ -489,26 +491,26 @@ "BSD-3-Clause" ], "description": "Official version of pdepend to be handled with Composer", - "time": "2017-01-19T14:23:36+00:00" + "time": "2017-12-13T13:21:38+00:00" }, { "name": "phar-io/manifest", - "version": "1.0.1", + "version": "1.0.3", "source": { "type": "git", "url": "https://github.com/phar-io/manifest.git", - "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0" + "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0", - "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", + "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", "shasum": "" }, "require": { "ext-dom": "*", "ext-phar": "*", - "phar-io/version": "^1.0.1", + "phar-io/version": "^2.0", "php": "^5.6 || ^7.0" }, "type": "library", @@ -544,20 +546,20 @@ } ], "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "time": "2017-03-05T18:14:27+00:00" + "time": "2018-07-08T19:23:20+00:00" }, { "name": "phar-io/version", - "version": "1.0.1", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/phar-io/version.git", - "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" + "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", - "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", + "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6", + "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6", "shasum": "" }, "require": { @@ -591,7 +593,7 @@ } ], "description": "Library for handling version information and constraints", - "time": "2017-03-05T17:38:23+00:00" + "time": "2018-07-08T19:19:57+00:00" }, { "name": "phpcompatibility/php-compatibility", @@ -707,16 +709,16 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "4.3.0", + "version": "4.3.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "94fd0001232e47129dd3504189fa1c7225010d08" + "reference": "bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94fd0001232e47129dd3504189fa1c7225010d08", - "reference": "94fd0001232e47129dd3504189fa1c7225010d08", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c", + "reference": "bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c", "shasum": "" }, "require": { @@ -754,7 +756,7 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2017-11-30T07:14:17+00:00" + "time": "2019-04-30T17:48:53+00:00" }, { "name": "phpdocumentor/type-resolver", @@ -805,27 +807,23 @@ }, { "name": "phploc/phploc", - "version": "3.0.1", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phploc.git", - "reference": "74f917e6f80f291856989960d31afa44a4196859" + "reference": "5b714ccb7cb8ca29ccf9caf6eb1aed0131d3a884" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phploc/zipball/74f917e6f80f291856989960d31afa44a4196859", - "reference": "74f917e6f80f291856989960d31afa44a4196859", + "url": "https://api.github.com/repos/sebastianbergmann/phploc/zipball/5b714ccb7cb8ca29ccf9caf6eb1aed0131d3a884", + "reference": "5b714ccb7cb8ca29ccf9caf6eb1aed0131d3a884", "shasum": "" }, "require": { - "php": ">=5.6", - "sebastian/finder-facade": "~1.1", - "sebastian/git": "~2.1", - "sebastian/version": "~1.0.3|~2.0", - "symfony/console": "~2.5|~3.0" - }, - "require-dev": { - "phpunit/phpunit": "~5" + "php": "^7.2", + "sebastian/finder-facade": "^1.1", + "sebastian/version": "^2.0", + "symfony/console": "^4.0" }, "bin": [ "phploc" @@ -833,7 +831,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "5.0-dev" } }, "autoload": { @@ -854,7 +852,7 @@ ], "description": "A tool for quickly measuring the size of a PHP project.", "homepage": "https://github.com/sebastianbergmann/phploc", - "time": "2016-04-25T08:11:21+00:00" + "time": "2019-03-16T10:41:19+00:00" }, { "name": "phpmd/phpmd", @@ -987,40 +985,40 @@ }, { "name": "phpunit/php-code-coverage", - "version": "5.3.2", + "version": "7.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "c89677919c5dd6d3b3852f230a663118762218ac" + "reference": "6024c8a6cb962d496b7bd049ed8f48473824176d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c89677919c5dd6d3b3852f230a663118762218ac", - "reference": "c89677919c5dd6d3b3852f230a663118762218ac", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6024c8a6cb962d496b7bd049ed8f48473824176d", + "reference": "6024c8a6cb962d496b7bd049ed8f48473824176d", "shasum": "" }, "require": { "ext-dom": "*", "ext-xmlwriter": "*", - "php": "^7.0", - "phpunit/php-file-iterator": "^1.4.2", + "php": "^7.2", + "phpunit/php-file-iterator": "^2.0.2", "phpunit/php-text-template": "^1.2.1", - "phpunit/php-token-stream": "^2.0.1", + "phpunit/php-token-stream": "^3.0.1", "sebastian/code-unit-reverse-lookup": "^1.0.1", - "sebastian/environment": "^3.0", + "sebastian/environment": "^4.1", "sebastian/version": "^2.0.1", "theseer/tokenizer": "^1.1" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "phpunit/phpunit": "^8.0" }, "suggest": { - "ext-xdebug": "^2.5.5" + "ext-xdebug": "^2.6.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.3.x-dev" + "dev-master": "7.0-dev" } }, "autoload": { @@ -1046,29 +1044,32 @@ "testing", "xunit" ], - "time": "2018-04-06T15:36:58+00:00" + "time": "2019-05-29T09:59:31+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "1.4.5", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" + "reference": "050bedf145a257b1ff02746c31894800e5122946" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", - "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/050bedf145a257b1ff02746c31894800e5122946", + "reference": "050bedf145a257b1ff02746c31894800e5122946", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -1080,53 +1081,6 @@ "license": [ "BSD-3-Clause" ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", - "keywords": [ - "filesystem", - "iterator" - ], - "time": "2017-11-27T13:52:08+00:00" - }, - { - "name": "phpunit/php-invoker", - "version": "1.1.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "86074bf0fc2caf02ec8819a93f65a37cd0b44c8e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/86074bf0fc2caf02ec8819a93f65a37cd0b44c8e", - "reference": "86074bf0fc2caf02ec8819a93f65a37cd0b44c8e", - "shasum": "" - }, - "require": { - "ext-pcntl": "*", - "php": ">=5.3.3", - "phpunit/php-timer": ">=1.0.6" - }, - "require-dev": { - "phpunit/phpunit": "~4" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], "authors": [ { "name": "Sebastian Bergmann", @@ -1134,12 +1088,13 @@ "role": "lead" } ], - "description": "Utility class for invoking callables with a timeout.", - "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", "keywords": [ - "process" + "filesystem", + "iterator" ], - "time": "2015-06-21T13:32:55+00:00" + "time": "2018-09-13T20:33:42+00:00" }, { "name": "phpunit/php-text-template", @@ -1184,28 +1139,28 @@ }, { "name": "phpunit/php-timer", - "version": "1.0.9", + "version": "2.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" + "reference": "8b389aebe1b8b0578430bda0c7c95a829608e059" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/8b389aebe1b8b0578430bda0c7c95a829608e059", + "reference": "8b389aebe1b8b0578430bda0c7c95a829608e059", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0" + "php": "^7.1" }, "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "2.1-dev" } }, "autoload": { @@ -1220,7 +1175,7 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", + "email": "sebastian@phpunit.de", "role": "lead" } ], @@ -1229,33 +1184,33 @@ "keywords": [ "timer" ], - "time": "2017-02-26T11:10:40+00:00" + "time": "2019-02-20T10:12:59+00:00" }, { "name": "phpunit/php-token-stream", - "version": "2.0.2", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "791198a2c6254db10131eecfe8c06670700904db" + "reference": "c99e3be9d3e85f60646f152f9002d46ed7770d18" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/791198a2c6254db10131eecfe8c06670700904db", - "reference": "791198a2c6254db10131eecfe8c06670700904db", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/c99e3be9d3e85f60646f152f9002d46ed7770d18", + "reference": "c99e3be9d3e85f60646f152f9002d46ed7770d18", "shasum": "" }, "require": { "ext-tokenizer": "*", - "php": "^7.0" + "php": "^7.1" }, "require-dev": { - "phpunit/phpunit": "^6.2.4" + "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -1278,57 +1233,55 @@ "keywords": [ "tokenizer" ], - "time": "2017-11-27T05:48:46+00:00" + "time": "2018-10-30T05:52:18+00:00" }, { "name": "phpunit/phpunit", - "version": "6.5.13", + "version": "8.1.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "0973426fb012359b2f18d3bd1e90ef1172839693" + "reference": "e3c9da6e645492c461e0a11eca117f83f4f4c840" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/0973426fb012359b2f18d3bd1e90ef1172839693", - "reference": "0973426fb012359b2f18d3bd1e90ef1172839693", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/e3c9da6e645492c461e0a11eca117f83f4f4c840", + "reference": "e3c9da6e645492c461e0a11eca117f83f4f4c840", "shasum": "" }, "require": { + "doctrine/instantiator": "^1.1", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", "ext-mbstring": "*", "ext-xml": "*", - "myclabs/deep-copy": "^1.6.1", - "phar-io/manifest": "^1.0.1", - "phar-io/version": "^1.0", - "php": "^7.0", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.7", + "phar-io/manifest": "^1.0.2", + "phar-io/version": "^2.0", + "php": "^7.2", "phpspec/prophecy": "^1.7", - "phpunit/php-code-coverage": "^5.3", - "phpunit/php-file-iterator": "^1.4.3", + "phpunit/php-code-coverage": "^7.0", + "phpunit/php-file-iterator": "^2.0.1", "phpunit/php-text-template": "^1.2.1", - "phpunit/php-timer": "^1.0.9", - "phpunit/phpunit-mock-objects": "^5.0.9", - "sebastian/comparator": "^2.1", - "sebastian/diff": "^2.0", - "sebastian/environment": "^3.1", + "phpunit/php-timer": "^2.1", + "sebastian/comparator": "^3.0", + "sebastian/diff": "^3.0", + "sebastian/environment": "^4.1", "sebastian/exporter": "^3.1", - "sebastian/global-state": "^2.0", + "sebastian/global-state": "^3.0", "sebastian/object-enumerator": "^3.0.3", - "sebastian/resource-operations": "^1.0", + "sebastian/resource-operations": "^2.0", "sebastian/version": "^2.0.1" }, - "conflict": { - "phpdocumentor/reflection-docblock": "3.0.2", - "phpunit/dbunit": "<3.0" - }, "require-dev": { "ext-pdo": "*" }, "suggest": { + "ext-soap": "*", "ext-xdebug": "*", - "phpunit/php-invoker": "^1.1" + "phpunit/php-invoker": "^2.0" }, "bin": [ "phpunit" @@ -1336,7 +1289,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "6.5.x-dev" + "dev-master": "8.1-dev" } }, "autoload": { @@ -1362,67 +1315,7 @@ "testing", "xunit" ], - "time": "2018-09-08T15:10:43+00:00" - }, - { - "name": "phpunit/phpunit-mock-objects", - "version": "5.0.10", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "cd1cf05c553ecfec36b170070573e540b67d3f1f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/cd1cf05c553ecfec36b170070573e540b67d3f1f", - "reference": "cd1cf05c553ecfec36b170070573e540b67d3f1f", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.0.5", - "php": "^7.0", - "phpunit/php-text-template": "^1.2.1", - "sebastian/exporter": "^3.1" - }, - "conflict": { - "phpunit/phpunit": "<6.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.5.11" - }, - "suggest": { - "ext-soap": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Mock Object library for PHPUnit", - "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", - "keywords": [ - "mock", - "xunit" - ], - "abandoned": true, - "time": "2018-08-09T05:50:03+00:00" + "time": "2019-05-28T11:53:42+00:00" }, { "name": "psr/container", @@ -1520,30 +1413,30 @@ }, { "name": "sebastian/comparator", - "version": "2.1.3", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9" + "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/34369daee48eafb2651bea869b4b15d75ccc35f9", - "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/5de4fc177adf9bce8df98d8d141a7559d7ccf6da", + "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da", "shasum": "" }, "require": { - "php": "^7.0", - "sebastian/diff": "^2.0 || ^3.0", + "php": "^7.1", + "sebastian/diff": "^3.0", "sebastian/exporter": "^3.1" }, "require-dev": { - "phpunit/phpunit": "^6.4" + "phpunit/phpunit": "^7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.1.x-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -1580,32 +1473,33 @@ "compare", "equality" ], - "time": "2018-02-01T13:46:46+00:00" + "time": "2018-07-12T15:12:46+00:00" }, { "name": "sebastian/diff", - "version": "2.0.1", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd" + "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", - "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/720fcc7e9b5cf384ea68d9d930d480907a0c1a29", + "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29", "shasum": "" }, "require": { - "php": "^7.0" + "php": "^7.1" }, "require-dev": { - "phpunit/phpunit": "^6.2" + "phpunit/phpunit": "^7.5 || ^8.0", + "symfony/process": "^2 || ^3.3 || ^4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -1630,34 +1524,40 @@ "description": "Diff implementation", "homepage": "https://github.com/sebastianbergmann/diff", "keywords": [ - "diff" + "diff", + "udiff", + "unidiff", + "unified diff" ], - "time": "2017-08-03T08:09:46+00:00" + "time": "2019-02-04T06:01:07+00:00" }, { "name": "sebastian/environment", - "version": "3.1.0", + "version": "4.2.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" + "reference": "f2a2c8e1c97c11ace607a7a667d73d47c19fe404" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", - "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/f2a2c8e1c97c11ace607a7a667d73d47c19fe404", + "reference": "f2a2c8e1c97c11ace607a7a667d73d47c19fe404", "shasum": "" }, "require": { - "php": "^7.0" + "php": "^7.1" }, "require-dev": { - "phpunit/phpunit": "^6.1" + "phpunit/phpunit": "^7.5" + }, + "suggest": { + "ext-posix": "*" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1.x-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -1682,7 +1582,7 @@ "environment", "hhvm" ], - "time": "2017-07-01T08:51:00+00:00" + "time": "2019-05-05T09:05:15+00:00" }, { "name": "sebastian/exporter", @@ -1790,71 +1690,28 @@ "homepage": "https://github.com/sebastianbergmann/finder-facade", "time": "2017-11-18T17:31:49+00:00" }, - { - "name": "sebastian/git", - "version": "2.1.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/git.git", - "reference": "815bbbc963cf35e5413df195aa29df58243ecd24" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/git/zipball/815bbbc963cf35e5413df195aa29df58243ecd24", - "reference": "815bbbc963cf35e5413df195aa29df58243ecd24", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Simple wrapper for Git", - "homepage": "http://www.github.com/sebastianbergmann/git", - "keywords": [ - "git" - ], - "abandoned": true, - "time": "2017-01-23T20:57:12+00:00" - }, { "name": "sebastian/global-state", - "version": "2.0.0", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" + "reference": "edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4", + "reference": "edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4", "shasum": "" }, "require": { - "php": "^7.0" + "php": "^7.2", + "sebastian/object-reflector": "^1.1.1", + "sebastian/recursion-context": "^3.0" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "ext-dom": "*", + "phpunit/phpunit": "^8.0" }, "suggest": { "ext-uopz": "*" @@ -1862,7 +1719,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -1885,7 +1742,7 @@ "keywords": [ "global state" ], - "time": "2017-04-27T15:39:26+00:00" + "time": "2019-02-01T05:30:01+00:00" }, { "name": "sebastian/object-enumerator", @@ -1981,21 +1838,22 @@ }, { "name": "sebastian/phpcpd", - "version": "3.0.1", + "version": "4.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpcpd.git", - "reference": "dfed51c1288790fc957c9433e2f49ab152e8a564" + "reference": "0d9afa762f2400de077b2192f4a9d127de0bb78e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpcpd/zipball/dfed51c1288790fc957c9433e2f49ab152e8a564", - "reference": "dfed51c1288790fc957c9433e2f49ab152e8a564", + "url": "https://api.github.com/repos/sebastianbergmann/phpcpd/zipball/0d9afa762f2400de077b2192f4a9d127de0bb78e", + "reference": "0d9afa762f2400de077b2192f4a9d127de0bb78e", "shasum": "" }, "require": { - "php": "^5.6|^7.0", - "phpunit/php-timer": "^1.0.6", + "ext-dom": "*", + "php": "^7.1", + "phpunit/php-timer": "^2.0", "sebastian/finder-facade": "^1.1", "sebastian/version": "^1.0|^2.0", "symfony/console": "^2.7|^3.0|^4.0" @@ -2006,7 +1864,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -2027,7 +1885,7 @@ ], "description": "Copy/Paste Detector (CPD) for PHP code.", "homepage": "https://github.com/sebastianbergmann/phpcpd", - "time": "2017-11-16T08:49:28+00:00" + "time": "2018-09-17T17:17:27+00:00" }, { "name": "sebastian/recursion-context", @@ -2084,25 +1942,25 @@ }, { "name": "sebastian/resource-operations", - "version": "1.0.0", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" + "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", - "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/4d7a795d35b889bf80a0cc04e08d77cedfa917a9", + "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9", "shasum": "" }, "require": { - "php": ">=5.6.0" + "php": "^7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.0-dev" } }, "autoload": { @@ -2122,7 +1980,7 @@ ], "description": "Provides a list of PHP built-in functions that operate on resources", "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "time": "2015-07-28T20:34:47+00:00" + "time": "2018-10-04T04:07:39+00:00" }, { "name": "sebastian/version", @@ -2169,16 +2027,16 @@ }, { "name": "squizlabs/php_codesniffer", - "version": "3.3.2", + "version": "3.4.2", "source": { "type": "git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "6ad28354c04b364c3c71a34e4a18b629cc3b231e" + "reference": "b8a7362af1cc1aadb5bd36c3defc4dda2cf5f0a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/6ad28354c04b364c3c71a34e4a18b629cc3b231e", - "reference": "6ad28354c04b364c3c71a34e4a18b629cc3b231e", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/b8a7362af1cc1aadb5bd36c3defc4dda2cf5f0a8", + "reference": "b8a7362af1cc1aadb5bd36c3defc4dda2cf5f0a8", "shasum": "" }, "require": { @@ -2211,41 +2069,41 @@ } ], "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "http://www.squizlabs.com/php-codesniffer", + "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", "keywords": [ "phpcs", "standards" ], - "time": "2018-09-23T23:08:17+00:00" + "time": "2019-04-10T23:49:02+00:00" }, { "name": "symfony/config", - "version": "v3.4.23", + "version": "v4.3.0", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "177a276c01575253c95cefe0866e3d1b57637fe0" + "reference": "5455fc0ae8b46269b83a22949429ea878496408c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/177a276c01575253c95cefe0866e3d1b57637fe0", - "reference": "177a276c01575253c95cefe0866e3d1b57637fe0", + "url": "https://api.github.com/repos/symfony/config/zipball/5455fc0ae8b46269b83a22949429ea878496408c", + "reference": "5455fc0ae8b46269b83a22949429ea878496408c", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8", - "symfony/filesystem": "~2.8|~3.0|~4.0", + "php": "^7.1.3", + "symfony/filesystem": "~3.4|~4.0", "symfony/polyfill-ctype": "~1.8" }, "conflict": { - "symfony/dependency-injection": "<3.3", - "symfony/finder": "<3.3" + "symfony/finder": "<3.4" }, "require-dev": { - "symfony/dependency-injection": "~3.3|~4.0", - "symfony/event-dispatcher": "~3.3|~4.0", - "symfony/finder": "~3.3|~4.0", - "symfony/yaml": "~3.0|~4.0" + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/event-dispatcher": "~3.4|~4.0", + "symfony/finder": "~3.4|~4.0", + "symfony/messenger": "~4.1", + "symfony/yaml": "~3.4|~4.0" }, "suggest": { "symfony/yaml": "To use the yaml reference dumper" @@ -2253,7 +2111,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.4-dev" + "dev-master": "4.3-dev" } }, "autoload": { @@ -2280,29 +2138,31 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2019-02-23T15:06:07+00:00" + "time": "2019-05-20T16:16:12+00:00" }, { "name": "symfony/console", - "version": "v3.4.23", + "version": "v4.3.0", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "71ce77f37af0c5ffb9590e43cc4f70e426945c5e" + "reference": "707b619d2c3bedf0224d56f95f77dabc60102305" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/71ce77f37af0c5ffb9590e43cc4f70e426945c5e", - "reference": "71ce77f37af0c5ffb9590e43cc4f70e426945c5e", + "url": "https://api.github.com/repos/symfony/console/zipball/707b619d2c3bedf0224d56f95f77dabc60102305", + "reference": "707b619d2c3bedf0224d56f95f77dabc60102305", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8", - "symfony/debug": "~2.8|~3.0|~4.0", - "symfony/polyfill-mbstring": "~1.0" + "php": "^7.1.3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php73": "^1.8", + "symfony/service-contracts": "^1.1" }, "conflict": { "symfony/dependency-injection": "<3.4", + "symfony/event-dispatcher": "<4.3", "symfony/process": "<3.3" }, "provide": { @@ -2310,11 +2170,12 @@ }, "require-dev": { "psr/log": "~1.0", - "symfony/config": "~3.3|~4.0", + "symfony/config": "~3.4|~4.0", "symfony/dependency-injection": "~3.4|~4.0", - "symfony/event-dispatcher": "~2.8|~3.0|~4.0", + "symfony/event-dispatcher": "^4.3", "symfony/lock": "~3.4|~4.0", - "symfony/process": "~3.3|~4.0" + "symfony/process": "~3.4|~4.0", + "symfony/var-dumper": "^4.3" }, "suggest": { "psr/log": "For using the console logger", @@ -2325,7 +2186,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.4-dev" + "dev-master": "4.3-dev" } }, "autoload": { @@ -2352,94 +2213,40 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2019-02-23T15:06:07+00:00" + "time": "2019-05-27T08:16:38+00:00" }, { - "name": "symfony/debug", - "version": "v4.2.4", + "name": "symfony/dependency-injection", + "version": "v4.3.0", "source": { "type": "git", - "url": "https://github.com/symfony/debug.git", - "reference": "de73f48977b8eaf7ce22814d66e43a1662cc864f" + "url": "https://github.com/symfony/dependency-injection.git", + "reference": "aa6fe799fa5adc938fc55aeccd2f5fb0aa0b8eac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/de73f48977b8eaf7ce22814d66e43a1662cc864f", - "reference": "de73f48977b8eaf7ce22814d66e43a1662cc864f", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/aa6fe799fa5adc938fc55aeccd2f5fb0aa0b8eac", + "reference": "aa6fe799fa5adc938fc55aeccd2f5fb0aa0b8eac", "shasum": "" }, "require": { "php": "^7.1.3", - "psr/log": "~1.0" + "psr/container": "^1.0", + "symfony/service-contracts": "^1.1.2" }, "conflict": { - "symfony/http-kernel": "<3.4" - }, - "require-dev": { - "symfony/http-kernel": "~3.4|~4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.2-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Debug\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Debug Component", - "homepage": "https://symfony.com", - "time": "2019-03-03T18:11:24+00:00" - }, - { - "name": "symfony/dependency-injection", - "version": "v3.4.23", - "source": { - "type": "git", - "url": "https://github.com/symfony/dependency-injection.git", - "reference": "c3dd7b7ea8cd8ec12304a5e222d7dc01cac8fa11" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/c3dd7b7ea8cd8ec12304a5e222d7dc01cac8fa11", - "reference": "c3dd7b7ea8cd8ec12304a5e222d7dc01cac8fa11", - "shasum": "" - }, - "require": { - "php": "^5.5.9|>=7.0.8", - "psr/container": "^1.0" - }, - "conflict": { - "symfony/config": "<3.3.7", - "symfony/finder": "<3.3", + "symfony/config": "<4.3", + "symfony/finder": "<3.4", "symfony/proxy-manager-bridge": "<3.4", "symfony/yaml": "<3.4" }, "provide": { - "psr/container-implementation": "1.0" + "psr/container-implementation": "1.0", + "symfony/service-implementation": "1.0" }, "require-dev": { - "symfony/config": "~3.3|~4.0", - "symfony/expression-language": "~2.8|~3.0|~4.0", + "symfony/config": "^4.3", + "symfony/expression-language": "~3.4|~4.0", "symfony/yaml": "~3.4|~4.0" }, "suggest": { @@ -2452,7 +2259,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.4-dev" + "dev-master": "4.3-dev" } }, "autoload": { @@ -2479,30 +2286,30 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2019-02-23T15:06:07+00:00" + "time": "2019-05-28T07:50:59+00:00" }, { "name": "symfony/filesystem", - "version": "v3.4.23", + "version": "v4.3.0", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "acf99758b1df8e9295e6b85aa69f294565c9fedb" + "reference": "988ab7d70c267c34efa85772ca20de3fad11c74b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/acf99758b1df8e9295e6b85aa69f294565c9fedb", - "reference": "acf99758b1df8e9295e6b85aa69f294565c9fedb", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/988ab7d70c267c34efa85772ca20de3fad11c74b", + "reference": "988ab7d70c267c34efa85772ca20de3fad11c74b", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8", + "php": "^7.1.3", "symfony/polyfill-ctype": "~1.8" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.4-dev" + "dev-master": "4.3-dev" } }, "autoload": { @@ -2529,20 +2336,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2019-02-04T21:34:32+00:00" + "time": "2019-05-24T12:50:04+00:00" }, { "name": "symfony/finder", - "version": "v4.2.4", + "version": "v4.3.0", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "267b7002c1b70ea80db0833c3afe05f0fbde580a" + "reference": "b3d4f4c0e4eadfdd8b296af9ca637cfbf51d8176" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/267b7002c1b70ea80db0833c3afe05f0fbde580a", - "reference": "267b7002c1b70ea80db0833c3afe05f0fbde580a", + "url": "https://api.github.com/repos/symfony/finder/zipball/b3d4f4c0e4eadfdd8b296af9ca637cfbf51d8176", + "reference": "b3d4f4c0e4eadfdd8b296af9ca637cfbf51d8176", "shasum": "" }, "require": { @@ -2551,7 +2358,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.2-dev" + "dev-master": "4.3-dev" } }, "autoload": { @@ -2578,20 +2385,20 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2019-02-23T15:42:05+00:00" + "time": "2019-05-26T20:47:49+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.10.0", + "version": "v1.11.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "e3d826245268269cd66f8326bd8bc066687b4a19" + "reference": "82ebae02209c21113908c229e9883c419720738a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e3d826245268269cd66f8326bd8bc066687b4a19", - "reference": "e3d826245268269cd66f8326bd8bc066687b4a19", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/82ebae02209c21113908c229e9883c419720738a", + "reference": "82ebae02209c21113908c229e9883c419720738a", "shasum": "" }, "require": { @@ -2603,7 +2410,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.9-dev" + "dev-master": "1.11-dev" } }, "autoload": { @@ -2625,7 +2432,7 @@ }, { "name": "Gert de Pagter", - "email": "backendtea@gmail.com" + "email": "BackEndTea@gmail.com" } ], "description": "Symfony polyfill for ctype functions", @@ -2636,20 +2443,20 @@ "polyfill", "portable" ], - "time": "2018-08-06T14:22:27+00:00" + "time": "2019-02-06T07:57:58+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.10.0", + "version": "v1.11.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "c79c051f5b3a46be09205c73b80b346e4153e494" + "reference": "fe5e94c604826c35a32fa832f35bd036b6799609" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/c79c051f5b3a46be09205c73b80b346e4153e494", - "reference": "c79c051f5b3a46be09205c73b80b346e4153e494", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fe5e94c604826c35a32fa832f35bd036b6799609", + "reference": "fe5e94c604826c35a32fa832f35bd036b6799609", "shasum": "" }, "require": { @@ -2661,7 +2468,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.9-dev" + "dev-master": "1.11-dev" } }, "autoload": { @@ -2695,7 +2502,123 @@ "portable", "shim" ], - "time": "2018-09-21T13:07:52+00:00" + "time": "2019-02-06T07:57:58+00:00" + }, + { + "name": "symfony/polyfill-php73", + "version": "v1.11.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php73.git", + "reference": "d1fb4abcc0c47be136208ad9d68bf59f1ee17abd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/d1fb4abcc0c47be136208ad9d68bf59f1ee17abd", + "reference": "d1fb4abcc0c47be136208ad9d68bf59f1ee17abd", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.11-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php73\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2019-02-06T07:57:58+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v1.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "191afdcb5804db960d26d8566b7e9a2843cab3a0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/191afdcb5804db960d26d8566b7e9a2843cab3a0", + "reference": "191afdcb5804db960d26d8566b7e9a2843cab3a0", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "suggest": { + "psr/container": "", + "symfony/service-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "time": "2019-05-28T07:50:59+00:00" }, { "name": "theseer/directoryscanner", @@ -2826,16 +2749,16 @@ }, { "name": "theseer/phpdox", - "version": "0.11.2", + "version": "0.12.0", "source": { "type": "git", "url": "https://github.com/theseer/phpdox.git", - "reference": "0e1dbf4bd862ed0cf87797409407973b2c228958" + "reference": "a46438e723a2b5bfd6ea4f299ecc0c7a1db1112c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/phpdox/zipball/0e1dbf4bd862ed0cf87797409407973b2c228958", - "reference": "0e1dbf4bd862ed0cf87797409407973b2c228958", + "url": "https://api.github.com/repos/theseer/phpdox/zipball/a46438e723a2b5bfd6ea4f299ecc0c7a1db1112c", + "reference": "a46438e723a2b5bfd6ea4f299ecc0c7a1db1112c", "shasum": "" }, "require": { @@ -2845,9 +2768,9 @@ "ext-mbstring": "*", "ext-tokenizer": "*", "ext-xsl": "*", - "nikic/php-parser": "^3.1", - "php": ">=5.5", - "phpunit/php-timer": "^1.0", + "nikic/php-parser": "^4.2", + "php": ">=7.1", + "phpunit/php-timer": "^2.0", "theseer/directoryscanner": "^1.3.0", "theseer/fdomdocument": "^1.6", "theseer/fxsl": "^1.1" @@ -2873,20 +2796,20 @@ } ], "description": "A fast Documentation generator for PHP Code using standard technology (SRC, DOCBLOCK, XML and XSLT) with event based processing", - "time": "2018-05-22T16:43:30+00:00" + "time": "2019-03-13T09:34:17+00:00" }, { "name": "theseer/tokenizer", - "version": "1.1.0", + "version": "1.1.2", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b" + "reference": "1c42705be2b6c1de5904f8afacef5895cab44bf8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/cb2f008f3f05af2893a87208fe6a6c4985483f8b", - "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/1c42705be2b6c1de5904f8afacef5895cab44bf8", + "reference": "1c42705be2b6c1de5904f8afacef5895cab44bf8", "shasum": "" }, "require": { @@ -2913,7 +2836,7 @@ } ], "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", - "time": "2017-04-07T12:08:54+00:00" + "time": "2019-04-04T09:56:43+00:00" }, { "name": "webmozart/assert", @@ -2988,7 +2911,7 @@ "ext-openssl": "*" }, "platform-dev": { - "php": ">=7.1", + "php": ">=7.3", "ext-pcntl": "*" } } diff --git a/lib/Froxlor/Api/Commands/Customers.php b/lib/Froxlor/Api/Commands/Customers.php index 271e1f6d..273ecd10 100644 --- a/lib/Froxlor/Api/Commands/Customers.php +++ b/lib/Froxlor/Api/Commands/Customers.php @@ -340,11 +340,12 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource 'login' => $loginname ), true, true); + $mysql_maxlen = \Froxlor\Database\Database::getSqlUsernameLength() - strlen(Settings::Get('customer.mysqlprefix')); if (strtolower($loginname_check['loginname']) == strtolower($loginname) || strtolower($loginname_check_admin['loginname']) == strtolower($loginname)) { \Froxlor\UI\Response::standard_error('loginnameexists', $loginname, true); - } elseif (! \Froxlor\Validate\Validate::validateUsername($loginname, Settings::Get('panel.unix_names'), 14 - strlen(Settings::Get('customer.mysqlprefix')))) { - if (strlen($loginname) > 14 - strlen(Settings::Get('customer.mysqlprefix'))) { - \Froxlor\UI\Response::standard_error('loginnameiswrong2', 14 - strlen(Settings::Get('customer.mysqlprefix')), true); + } elseif (! \Froxlor\Validate\Validate::validateUsername($loginname, Settings::Get('panel.unix_names'), $mysql_maxlen)) { + if (strlen($loginname) > $mysql_maxlen) { + \Froxlor\UI\Response::standard_error('loginnameiswrong2', $mysql_maxlen, true); } else { \Froxlor\UI\Response::standard_error('loginnameiswrong', $loginname, true); } diff --git a/lib/Froxlor/Database/Database.php b/lib/Froxlor/Database/Database.php index ccf5ad3b..d0791148 100644 --- a/lib/Froxlor/Database/Database.php +++ b/lib/Froxlor/Database/Database.php @@ -193,7 +193,7 @@ class Database // MySQL user names can be up to 32 characters long (16 characters before MySQL 5.7.8). $mysql_max = 32; if (version_compare(Database::getAttribute(\PDO::ATTR_SERVER_VERSION), '5.7.8', '<')) { - $mysql_max -= 16; + $mysql_max = 16; } return $mysql_max; } diff --git a/lib/Froxlor/Validate/Check.php b/lib/Froxlor/Validate/Check.php index 41901d31..d436616e 100644 --- a/lib/Froxlor/Validate/Check.php +++ b/lib/Froxlor/Validate/Check.php @@ -192,7 +192,7 @@ class Check } $returnvalue = array(); - if (Validate::validateUsername($newfieldvalue, Settings::Get('panel.unix_names'), 14 - strlen($allnewfieldvalues['customer_mysqlprefix'])) === true) { + if (Validate::validateUsername($newfieldvalue, Settings::Get('panel.unix_names'), \Froxlor\Database\Database::getSqlUsernameLength() - strlen($allnewfieldvalues['customer_mysqlprefix'])) === true) { $returnvalue = array( self::FORMFIELDS_PLAUSIBILITY_CHECK_OK ); diff --git a/phpunit.xml b/phpunit.xml index 4a31f67b..3ec18fd3 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -2,7 +2,7 @@ @@ -29,13 +29,11 @@ - + - + diff --git a/tests/Customers/CustomersTest.php b/tests/Customers/CustomersTest.php index 3735d244..2fb75d71 100644 --- a/tests/Customers/CustomersTest.php +++ b/tests/Customers/CustomersTest.php @@ -545,7 +545,7 @@ class CustomersTest extends TestCase 'customernumber' => 1339 ]; - $this->expectExceptionMessage('Loginname contains too many characters. Only ' . (14 - strlen(Settings::Get('customer.mysqlprefix'))) . ' characters are allowed.'); + $this->expectExceptionMessage('Loginname contains too many characters. Only ' . (\Froxlor\Database\Database::getSqlUsernameLength() - strlen(Settings::Get('customer.mysqlprefix'))) . ' characters are allowed.'); Customers::getLocal($admin_userdata, $data)->add(); } } diff --git a/tests/Froxlor/SettingsTest.php b/tests/Froxlor/SettingsTest.php index b0f9922d..c4afbb31 100644 --- a/tests/Froxlor/SettingsTest.php +++ b/tests/Froxlor/SettingsTest.php @@ -8,7 +8,8 @@ use PHPUnit\Framework\TestCase; class SettingsTest extends TestCase { - protected function setUp() { + protected function setUp(): void + { // start fresh \Froxlor\Settings::Stash(); } diff --git a/tests/Traffic/TrafficTest.php b/tests/Traffic/TrafficTest.php index 24a737fd..3383dd61 100644 --- a/tests/Traffic/TrafficTest.php +++ b/tests/Traffic/TrafficTest.php @@ -16,7 +16,7 @@ use Froxlor\Api\Commands\Traffic; class TrafficTest extends TestCase { - public static function setUpBeforeClass() + public static function setUpBeforeClass(): void { $ins_stmt = Database::prepare(" INSERT INTO `" . TABLE_PANEL_TRAFFIC . "` SET From f266bb05c99c29b37a0a05491e9ed1aa9b7a459e Mon Sep 17 00:00:00 2001 From: Michael Kaufmann Date: Thu, 6 Jun 2019 13:04:43 +0200 Subject: [PATCH 019/159] testing \Froxlor\Settings\FroxlorVhostSettings Signed-off-by: Michael Kaufmann --- tests/Froxlor/SettingsTest.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/Froxlor/SettingsTest.php b/tests/Froxlor/SettingsTest.php index c4afbb31..343eadf7 100644 --- a/tests/Froxlor/SettingsTest.php +++ b/tests/Froxlor/SettingsTest.php @@ -4,6 +4,7 @@ use PHPUnit\Framework\TestCase; /** * * @covers \Froxlor\Settings + * @covers \Froxlor\Settings\FroxlorVhostSettings */ class SettingsTest extends TestCase { @@ -92,4 +93,21 @@ class SettingsTest extends TestCase $result = \Froxlor\Settings::IsInList("system.mysql_access_host", "my-super-domain.de"); $this->assertFalse($result); } + + public function testFroxlorVhostSettings() + { + // bootstrap.php adds two IPs, one ssl one non-ssl both with vhostcontainer = 1 + $result = \Froxlor\Settings\FroxlorVhostSettings::hasVhostContainerEnabled(false); + $this->assertTrue($result); + $result = \Froxlor\Settings\FroxlorVhostSettings::hasVhostContainerEnabled(true); + $this->assertTrue($result); + // now disable both + \Froxlor\Database\Database::query("UPDATE `". TABLE_PANEL_IPSANDPORTS . "` SET `vhostcontainer` = '0'"); + $result = \Froxlor\Settings\FroxlorVhostSettings::hasVhostContainerEnabled(false); + $this->assertFalse($result); + $result = \Froxlor\Settings\FroxlorVhostSettings::hasVhostContainerEnabled(true); + $this->assertFalse($result); + // and change back + \Froxlor\Database\Database::query("UPDATE `". TABLE_PANEL_IPSANDPORTS . "` SET `vhostcontainer` = '1'"); + } } From 1ac304e5ac6b0450e5432262af795462dc06ac9d Mon Sep 17 00:00:00 2001 From: Michael Kaufmann Date: Mon, 10 Jun 2019 11:36:05 +0200 Subject: [PATCH 020/159] fix missing domainname parameter when manually adding ssl-certificates for a domain, fixes #700 Signed-off-by: Michael Kaufmann --- customer_domains.php | 11 +++++++++++ .../customer/domains/formfield.domain_ssleditor.php | 6 ++++++ 2 files changed, 17 insertions(+) diff --git a/customer_domains.php b/customer_domains.php index 50681cf2..e50173e1 100644 --- a/customer_domains.php +++ b/customer_domains.php @@ -480,6 +480,17 @@ if ($page == 'overview') { } elseif ($page == 'domainssleditor') { if ($action == '' || $action == 'view') { + + // get domain + try { + $json_result = SubDomains::getLocal($userinfo, array( + 'id' => $id + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result_domain = json_decode($json_result, true)['data']; + if (isset($_POST['send']) && $_POST['send'] == 'send') { $do_insert = isset($_POST['do_insert']) ? (($_POST['do_insert'] == 1) ? true : false) : false; try { diff --git a/lib/formfields/customer/domains/formfield.domain_ssleditor.php b/lib/formfields/customer/domains/formfield.domain_ssleditor.php index e6a14faa..3518ef39 100644 --- a/lib/formfields/customer/domains/formfield.domain_ssleditor.php +++ b/lib/formfields/customer/domains/formfield.domain_ssleditor.php @@ -23,6 +23,12 @@ return array( 'title' => 'SSL certificates', 'image' => 'icons/ssl.png', 'fields' => array( + 'domainname' => array( + 'label' => $lng['domains']['domainname'], + 'type' => 'hidden', + 'value' => $result_domain['domain'], + 'display' => $result_domain['domain'] + ), 'ssl_cert_file' => array( 'style' => 'align-top', 'label' => $lng['admin']['ipsandports']['ssl_cert_file_content'], From 028524291eff4979df25b6e16aabf4567b6db414 Mon Sep 17 00:00:00 2001 From: Michael Kaufmann Date: Mon, 10 Jun 2019 11:38:47 +0200 Subject: [PATCH 021/159] test improvements and preparation for more tests later Signed-off-by: Michael Kaufmann --- phpunit.xml | 2 +- tests/Customers/CustomersTest.php | 8 +++++++- tests/Domains/DomainsTest.php | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/phpunit.xml b/phpunit.xml index 3ec18fd3..b0ff49e7 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -9,7 +9,6 @@ tests/Global - tests/Froxlor tests/Admins tests/Customers tests/IpsAndPorts @@ -25,6 +24,7 @@ tests/Mysqls tests/PhpAndFpm tests/Traffic + tests/Froxlor diff --git a/tests/Customers/CustomersTest.php b/tests/Customers/CustomersTest.php index 2fb75d71..3c0a913a 100644 --- a/tests/Customers/CustomersTest.php +++ b/tests/Customers/CustomersTest.php @@ -5,6 +5,7 @@ use Froxlor\Settings; use Froxlor\Database\Database; use Froxlor\Api\Commands\Admins; use Froxlor\Api\Commands\Customers; +use Froxlor\Api\Commands\SubDomains; /** * @@ -58,6 +59,11 @@ class CustomersTest extends TestCase $this->assertEquals(1337, $result['customernumber']); $this->assertEquals(15, $result['subdomains']); $this->assertEquals('secret', $result['custom_notes']); + + // validate that the std-subdomain has been added + $json_result = SubDomains::getLocal($admin_userdata, array('id' => $result['standardsubdomain']))->get(); + $result = json_decode($json_result, true)['data']; + $this->assertEquals('test1.dev.froxlor.org', $result['domain']); } public function testAdminCustomersAddEmptyMail() @@ -447,7 +453,7 @@ class CustomersTest extends TestCase 'mysqls' => 15, 'createstdsubdomain' => 1, 'new_customer_password' => 'h0lYmo1y', - 'sendpassword' => 1, + 'sendpassword' => TRAVIS_CI == 1 ? 0 : 1, 'phpenabled' => 1, 'store_defaultindex' => 1, 'custom_notes' => 'secret', diff --git a/tests/Domains/DomainsTest.php b/tests/Domains/DomainsTest.php index b89f4eba..ead35c02 100644 --- a/tests/Domains/DomainsTest.php +++ b/tests/Domains/DomainsTest.php @@ -119,7 +119,7 @@ class DomainsTest extends TestCase 'customerid' => 1 ]; $this->expectExceptionMessage('The server-hostname cannot be used as customer-domain.'); - $json_result = Domains::getLocal($admin_userdata, $data)->add(); + Domains::getLocal($admin_userdata, $data)->add(); } public function testAdminDomainsAddNoPunycode() From 7a94a430536b0e93c5cfa4f7aa7c89a016693662 Mon Sep 17 00:00:00 2001 From: Michael Kaufmann Date: Mon, 10 Jun 2019 13:37:22 +0200 Subject: [PATCH 022/159] started \Settings\Store unit tests Signed-off-by: Michael Kaufmann --- lib/Froxlor/Settings/Store.php | 125 +++++++++++------------------- tests/Customers/CustomersTest.php | 4 +- tests/Froxlor/StoreTest.php | 97 +++++++++++++++++++++++ 3 files changed, 145 insertions(+), 81 deletions(-) create mode 100644 tests/Froxlor/StoreTest.php diff --git a/lib/Froxlor/Settings/Store.php b/lib/Froxlor/Settings/Store.php index 5c567d31..d9e33144 100644 --- a/lib/Froxlor/Settings/Store.php +++ b/lib/Froxlor/Settings/Store.php @@ -27,29 +27,58 @@ class Store $returnvalue = self::storeSettingField($fieldname, $fielddata, $newfieldvalue); if ($returnvalue !== false && is_array($fielddata) && isset($fielddata['settinggroup']) && $fielddata['settinggroup'] == 'system' && isset($fielddata['varname']) && $fielddata['varname'] == 'defaultip') { + self::updateStdSubdomainDefaultIp($newfieldvalue, $defaultips_old); + } - $customerstddomains_result_stmt = Database::prepare(" - SELECT `standardsubdomain` FROM `" . TABLE_PANEL_CUSTOMERS . "` WHERE `standardsubdomain` <> '0' - "); - Database::pexecute($customerstddomains_result_stmt); + return $returnvalue; + } - $ids = array(); + public static function storeSettingDefaultSslIp($fieldname, $fielddata, $newfieldvalue) + { + $defaultips_old = Settings::Get('system.defaultsslip'); - while ($customerstddomains_row = $customerstddomains_result_stmt->fetch(\PDO::FETCH_ASSOC)) { - $ids[] = (int) $customerstddomains_row['standardsubdomain']; + $returnvalue = self::storeSettingField($fieldname, $fielddata, $newfieldvalue); + + if ($returnvalue !== false && is_array($fielddata) && isset($fielddata['settinggroup']) && $fielddata['settinggroup'] == 'system' && isset($fielddata['varname']) && $fielddata['varname'] == 'defaultsslip') { + self::updateStdSubdomainDefaultIp($newfieldvalue, $defaultips_old); + } + + return $returnvalue; + } + + private static function updateStdSubdomainDefaultIp($newfieldvalue, $defaultips_old) + { + // update standard-subdomain of customer if exists + $customerstddomains_result_stmt = Database::prepare(" + SELECT `standardsubdomain` FROM `" . TABLE_PANEL_CUSTOMERS . "` WHERE `standardsubdomain` <> '0' + "); + Database::pexecute($customerstddomains_result_stmt); + + $ids = array(); + while ($customerstddomains_row = $customerstddomains_result_stmt->fetch(\PDO::FETCH_ASSOC)) { + $ids[] = (int) $customerstddomains_row['standardsubdomain']; + } + + if (count($ids) > 0) { + $defaultips_new = explode(',', $newfieldvalue); + + if (! empty($defaultips_old) && ! empty($newfieldvalue)) { + $in_value = $defaultips_old . ", " . $newfieldvalue; + } elseif (! empty($defaultips_old) && empty($newfieldvalue)) { + $in_value = $defaultips_old; + } else { + $in_value = $newfieldvalue; } - if (count($ids) > 0) { - $defaultips_new = explode(',', $newfieldvalue); - - // Delete the existing mappings linking to default IPs - $del_stmt = Database::prepare(" - DELETE FROM `" . TABLE_DOMAINTOIP . "` - WHERE `id_domain` IN (" . implode(', ', $ids) . ") - AND `id_ipandports` IN (" . $defaultips_old . ", " . $newfieldvalue . ") - "); - Database::pexecute($del_stmt); + // Delete the existing mappings linking to default IPs + $del_stmt = Database::prepare(" + DELETE FROM `" . TABLE_DOMAINTOIP . "` + WHERE `id_domain` IN (" . implode(', ', $ids) . ") + AND `id_ipandports` IN (" . $in_value . ") + "); + Database::pexecute($del_stmt); + if (count($defaultips_new) > 0) { // Insert the new mappings $ins_stmt = Database::prepare(" INSERT INTO `" . TABLE_DOMAINTOIP . "` @@ -66,68 +95,6 @@ class Store } } } - - return $returnvalue; - } - - public static function storeSettingDefaultSslIp($fieldname, $fielddata, $newfieldvalue) - { - $defaultips_old = Settings::Get('system.defaultsslip'); - - $returnvalue = self::storeSettingField($fieldname, $fielddata, $newfieldvalue); - - if ($returnvalue !== false && is_array($fielddata) && isset($fielddata['settinggroup']) && $fielddata['settinggroup'] == 'system' && isset($fielddata['varname']) && $fielddata['varname'] == 'defaultsslip') { - - $customerstddomains_result_stmt = Database::prepare(" - SELECT `standardsubdomain` FROM `" . TABLE_PANEL_CUSTOMERS . "` WHERE `standardsubdomain` <> '0' - "); - Database::pexecute($customerstddomains_result_stmt); - - $ids = array(); - - while ($customerstddomains_row = $customerstddomains_result_stmt->fetch(\PDO::FETCH_ASSOC)) { - $ids[] = (int) $customerstddomains_row['standardsubdomain']; - } - - if (count($ids) > 0) { - $defaultips_new = explode(',', $newfieldvalue); - - if (! empty($defaultips_old) && ! empty($newfieldvalue)) { - $in_value = $defaultips_old . ", " . $newfieldvalue; - } elseif (! empty($defaultips_old) && empty($newfieldvalue)) { - $in_value = $defaultips_old; - } else { - $in_value = $newfieldvalue; - } - - // Delete the existing mappings linking to default IPs - $del_stmt = Database::prepare(" - DELETE FROM `" . TABLE_DOMAINTOIP . "` - WHERE `id_domain` IN (" . implode(', ', $ids) . ") - AND `id_ipandports` IN (" . $in_value . ") - "); - Database::pexecute($del_stmt); - - if (count($defaultips_new) > 0) { - // Insert the new mappings - $ins_stmt = Database::prepare(" - INSERT INTO `" . TABLE_DOMAINTOIP . "` - SET `id_domain` = :domainid, `id_ipandports` = :ipandportid - "); - - foreach ($ids as $id) { - foreach ($defaultips_new as $defaultip_new) { - Database::pexecute($ins_stmt, array( - 'domainid' => $id, - 'ipandportid' => $defaultip_new - )); - } - } - } - } - } - - return $returnvalue; } /** diff --git a/tests/Customers/CustomersTest.php b/tests/Customers/CustomersTest.php index 3c0a913a..4de3fc0d 100644 --- a/tests/Customers/CustomersTest.php +++ b/tests/Customers/CustomersTest.php @@ -230,7 +230,7 @@ class CustomersTest extends TestCase /** * - * @depends testAdminCustomersAdd + * @depends testAdminCustomerUpdateDeactivate */ public function testCustomerCustomersGetWhenDeactivated() { @@ -252,7 +252,7 @@ class CustomersTest extends TestCase /** * - * @depends testAdminCustomersAdd + * @depends testCustomerCustomersGetWhenDeactivated */ public function testCustomerCustomersUpdate() { diff --git a/tests/Froxlor/StoreTest.php b/tests/Froxlor/StoreTest.php new file mode 100644 index 00000000..f5a46f18 --- /dev/null +++ b/tests/Froxlor/StoreTest.php @@ -0,0 +1,97 @@ + 'le_froxlor_enabled', + 'settinggroup' => 'system', + 'varname' => 'le_froxlor_enabled' + ); + Store::storeSettingClearCertificates('system_le_froxlor_enabled', $fielddata, 0); + + // there should be no entry in domain_ssl_settings now + $result = Database::query("SELECT COUNT(*) as entries FROM `domain_ssl_settings` WHERE `domainid` = '0'"); + $result = $result->fetch(\PDO::FETCH_ASSOC); + $this->assertEquals(0, (int) $result['entries']); + + // truncate the table for other tests + Database::query("TRUNCATE TABLE `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "`;"); + } + + public function testStoreSettingDefaultIp() + { + global $admin_userdata; + + // the customer should have a std-subdomin + Customers::getLocal($admin_userdata, array( + 'id' => 1, + 'createstdsubdomain' => 1 + ))->update(); + + // we need a second non-ssl IP + Database::query("INSERT INTO `panel_ipsandports` SET `ip` = '82.149.225.47', `port` = '80'"); + $ip_id = Database::lastInsertId(); + $default_ip = Settings::Get('system.defaultip'); + + // get all std-subdomains + $customerstddomains_result_stmt = Database::prepare(" + SELECT `standardsubdomain` FROM `" . TABLE_PANEL_CUSTOMERS . "` WHERE `standardsubdomain` <> '0' + "); + Database::pexecute($customerstddomains_result_stmt); + + $ids = array(); + while ($customerstddomains_row = $customerstddomains_result_stmt->fetch(\PDO::FETCH_ASSOC)) { + $ids[] = (int) $customerstddomains_row['standardsubdomain']; + } + + if (count($ids) <= 0) { + $this->fail("There should be customer std-subdomains for this test to make sense"); + } + + // check that they have the current default IP set + $sel_stmt = Database::prepare(" + SELECT * FROM `" . TABLE_DOMAINTOIP . "` + WHERE `id_domain` IN (" . implode(', ', $ids) . ") AND `id_ipandports` = :ipid + "); + Database::pexecute($sel_stmt, array('ipid' => $default_ip)); + $current_result = $sel_stmt->fetchAll(\PDO::FETCH_ASSOC); + // we assume there are entries + $this->assertTrue(count($current_result) > 0); + + $fielddata = array( + 'label' => 'serversettingsipaddress', + 'settinggroup' => 'system', + 'varname' => 'defaultip' + ); + Store::storeSettingDefaultIp('serversettings_ipaddress', $fielddata, $ip_id); + + // check that they do not have the current default IP set anymore + Database::pexecute($sel_stmt, array('ipid' => $default_ip)); + $current_result = $sel_stmt->fetchAll(\PDO::FETCH_ASSOC); + // we assume there are entries + $this->assertTrue(count($current_result) == 0); + + // check that they have the new default IP set + Database::pexecute($sel_stmt, array('ipid' => $ip_id)); + $current_result = $sel_stmt->fetchAll(\PDO::FETCH_ASSOC); + // we assume there are entries + $this->assertTrue(count($current_result) > 0); + } +} From a07a9e6a88a9eb13c21dc85f17453d46b3b121f8 Mon Sep 17 00:00:00 2001 From: Michael Kaufmann Date: Tue, 11 Jun 2019 12:10:56 +0200 Subject: [PATCH 023/159] more unit-testing, enhancements in Store-functions Signed-off-by: Michael Kaufmann --- lib/Froxlor/Settings/Store.php | 46 ++++++++------------------- tests/Froxlor/StoreTest.php | 57 ++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 33 deletions(-) diff --git a/lib/Froxlor/Settings/Store.php b/lib/Froxlor/Settings/Store.php index d9e33144..5a506e87 100644 --- a/lib/Froxlor/Settings/Store.php +++ b/lib/Froxlor/Settings/Store.php @@ -115,20 +115,20 @@ class Store $returnvalue = self::storeSettingField($fieldname, $fielddata, $newfieldvalue); if ($returnvalue !== false && is_array($fielddata) && isset($fielddata['settinggroup']) && $fielddata['settinggroup'] == 'panel' && isset($fielddata['varname']) && $fielddata['varname'] == 'default_theme') { - // now, if changing themes is disabled we recursivly set + // now, if changing themes is disabled we manually set // the new theme (customers and admin, depending on settings) if (Settings::Get('panel.allow_theme_change_customer') == '0') { $upd_stmt = Database::prepare(" - UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET `theme` = :theme - "); + UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET `theme` = :theme + "); Database::pexecute($upd_stmt, array( 'theme' => $newfieldvalue )); } if (Settings::Get('panel.allow_theme_change_admin') == '0') { $upd_stmt = Database::prepare(" - UPDATE `" . TABLE_PANEL_ADMINS . "` SET `theme` = :theme - "); + UPDATE `" . TABLE_PANEL_ADMINS . "` SET `theme` = :theme + "); Database::pexecute($upd_stmt, array( 'theme' => $newfieldvalue )); @@ -171,17 +171,13 @@ class Store public static function storeSettingFieldInsertBindTask($fieldname, $fielddata, $newfieldvalue) { - if (is_array($fielddata) && isset($fielddata['settinggroup']) && $fielddata['settinggroup'] != '' && isset($fielddata['varname']) && $fielddata['varname'] != '') { - if (Settings::Set($fielddata['settinggroup'] . '.' . $fielddata['varname'], $newfieldvalue) !== false) { - return array( - $fielddata['settinggroup'] . '.' . $fielddata['varname'] => $newfieldvalue - ); - } else { - return false; - } - } else { - return false; + // first save the setting itself + $returnvalue = self::storeSettingField($fieldname, $fielddata, $newfieldvalue); + + if ($returnvalue !== false) { + \Froxlor\System\Cronjob::inserttask('4'); } + return false; } public static function storeSettingHostname($fieldname, $fielddata, $newfieldvalue) @@ -297,25 +293,9 @@ class Store $returnvalue = self::storeSettingField($fieldname, $fielddata, $newfieldvalue); if ($returnvalue !== false && is_array($fielddata) && isset($fielddata['settinggroup']) && $fielddata['settinggroup'] == 'catchall' && isset($fielddata['varname']) && $fielddata['varname'] == 'catchall_enabled' && $newfieldvalue == '0') { - - $result_stmt = Database::query(" - SELECT `id`, `email`, `email_full`, `iscatchall` FROM `" . TABLE_MAIL_VIRTUAL . "` - WHERE `iscatchall` = '1' + Database::query(" + UPDATE `" . TABLE_MAIL_VIRTUAL . "` SET `iscatchall` = '0' WHERE `iscatchall` = '1' "); - - if (Database::num_rows() > 0) { - - $upd_stmt = Database::prepare(" - UPDATE `" . TABLE_MAIL_VIRTUAL . "` SET `email` = :email, `iscatchall` = '0' WHERE `id` = :id - "); - - while ($result_row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) { - Database::pexecute($upd_stmt, array( - 'email' => $result_row['email_full'], - 'id' => $result_row['id'] - )); - } - } } return $returnvalue; diff --git a/tests/Froxlor/StoreTest.php b/tests/Froxlor/StoreTest.php index f5a46f18..1316d3b4 100644 --- a/tests/Froxlor/StoreTest.php +++ b/tests/Froxlor/StoreTest.php @@ -94,4 +94,61 @@ class StoreTest extends TestCase // we assume there are entries $this->assertTrue(count($current_result) > 0); } + + public function testStoreSettingDefaultTheme() + { + $current_theme = Settings::Get('panel.default_theme'); + // allow theme changing for admins/customers so a new default won't overwrite + Settings::Set('panel.allow_theme_change_customer', 1); + Settings::Set('panel.allow_theme_change_admin', 1); + $fielddata = array( + 'label' => 'panel_default_theme', + 'settinggroup' => 'panel', + 'varname' => 'default_theme' + ); + Store::storeSettingDefaultTheme('panel_default_theme', $fielddata, "newTheme"); + $this->assertTrue($current_theme != Settings::Get('panel.default_theme')); + $this->assertEquals("newTheme", Settings::Get('panel.default_theme')); + // validate admin/customer field did not change + $sel_stmt = Database::prepare(" + SELECT * FROM `" . TABLE_PANEL_ADMINS . "` + WHERE `theme` = :newtheme + "); + Database::pexecute($sel_stmt, array('newtheme' => "newTheme")); + $current_result = $sel_stmt->fetchAll(\PDO::FETCH_ASSOC); + // we assume there are entries + $this->assertTrue(count($current_result) == 0); + $sel_stmt = Database::prepare(" + SELECT * FROM `" . TABLE_PANEL_CUSTOMERS . "` + WHERE `theme` = :newtheme + "); + Database::pexecute($sel_stmt, array('newtheme' => "newTheme")); + $current_result = $sel_stmt->fetchAll(\PDO::FETCH_ASSOC); + // we assume there are entries + $this->assertTrue(count($current_result) == 0); + // now do not allow changing of themes so the theme should get updated for all admins/customers + // allow theme changing for admins/customers so a new default won't overwrite + Settings::Set('panel.allow_theme_change_customer', 0); + Settings::Set('panel.allow_theme_change_admin', 0); + Store::storeSettingDefaultTheme('panel_default_theme', $fielddata, "newTheme"); + // validate admin/customer field did change + $sel_stmt = Database::prepare(" + SELECT * FROM `" . TABLE_PANEL_ADMINS . "` + WHERE `theme` = :newtheme + "); + Database::pexecute($sel_stmt, array('newtheme' => "newTheme")); + $current_result = $sel_stmt->fetchAll(\PDO::FETCH_ASSOC); + // we assume there are entries + $this->assertTrue(count($current_result) > 0); + $sel_stmt = Database::prepare(" + SELECT * FROM `" . TABLE_PANEL_CUSTOMERS . "` + WHERE `theme` = :newtheme + "); + Database::pexecute($sel_stmt, array('newtheme' => "newTheme")); + $current_result = $sel_stmt->fetchAll(\PDO::FETCH_ASSOC); + // we assume there are entries + $this->assertTrue(count($current_result) > 0); + // set back to default + Store::storeSettingDefaultTheme('panel_default_theme', $fielddata, $current_theme); + } } From 6e41c0ad2cc43998c37fbb3e3e079209cabb0b18 Mon Sep 17 00:00:00 2001 From: Michael Kaufmann Date: Mon, 17 Jun 2019 14:11:40 +0200 Subject: [PATCH 024/159] add codecov.io to travis build for code-coverage stats - yay Signed-off-by: Michael Kaufmann --- .travis.yml | 27 +++++---------------------- lib/Froxlor/Settings/Store.php | 1 - 2 files changed, 5 insertions(+), 23 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5014b70f..2a4dd27c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,6 @@ language: php php: -# - "5.4" -# - "5.6" -# - "7.0" -# - "7.1" - "7.3" branches: @@ -14,10 +10,6 @@ branches: matrix: include: - # - php: 5.6 - # env: deps=highest - # - php: 5.4 - # env: deps=lowest - php: 7.3 env: deps=highest @@ -30,10 +22,6 @@ addons: apt: update: true -# build.xml includes that -#install: -# - composer install - service: - mysql @@ -43,18 +31,13 @@ before_script: - mysql -u root -pfr0xl0r.TravisCI froxlor010 < install/froxlor.sql - mysql -u root -pfr0xl0r.TravisCI -e "CREATE USER 'froxlor010'@'localhost' IDENTIFIED BY 'fr0xl0r.TravisCI';" - mysql -u root -pfr0xl0r.TravisCI -e "GRANT ALL ON froxlor010.* TO 'froxlor010'@'localhost';" +# - phpenv config-rm xdebug.ini script: -# sufficient for travis - - ant phpunit-no-coverage -# - ant full-build-parallel -# -Dpdepend=$(pwd)/vendor/bin/pdepend -# -Dphpmd=$(pwd)/vendor/bin/phpmd -# -Dphpcpd=$(pwd)/vendor/bin/phpcpd -# -Dphpcs=$(pwd)/vendor/bin/phpcs -# -Dphploc=$(pwd)/vendor/bin/phploc -# -Dphpdox=$(pwd)/vendor/bin/phpdox -# -Dphpunit=$(pwd)/vendor/bin/phpunit + - ant phpunit + +after_success: + - bash <(curl -s https://codecov.io/bash) -f "build/logs/clover.xml" notifications: irc: "irc.freenode.org#froxlor" diff --git a/lib/Froxlor/Settings/Store.php b/lib/Froxlor/Settings/Store.php index 5a506e87..baaf3a93 100644 --- a/lib/Froxlor/Settings/Store.php +++ b/lib/Froxlor/Settings/Store.php @@ -110,7 +110,6 @@ class Store */ public static function storeSettingDefaultTheme($fieldname, $fielddata, $newfieldvalue) { - // first save the setting itself $returnvalue = self::storeSettingField($fieldname, $fielddata, $newfieldvalue); From 5dfb74701c2b4e15afcb0b492907defd505140b7 Mon Sep 17 00:00:00 2001 From: Michael Kaufmann Date: Tue, 25 Jun 2019 11:10:32 +0200 Subject: [PATCH 025/159] improve error message display on missing vendor-folder Signed-off-by: Michael Kaufmann --- install/install.php | 9 +++- lib/init.php | 18 +++++--- templates/Sparkle/misc/ownershiphint.tpl | 2 +- templates/Sparkle/misc/vendormissinghint.tpl | 45 ++++++++++++++++++++ 4 files changed, 65 insertions(+), 9 deletions(-) create mode 100644 templates/Sparkle/misc/vendormissinghint.tpl diff --git a/install/install.php b/install/install.php index 76723290..7a258149 100644 --- a/install/install.php +++ b/install/install.php @@ -15,8 +15,13 @@ * @package Install * */ -if(!file_exists(dirname(__DIR__) . '/vendor/autoload.php')){ - die('Vendor does not exist. Please run "composer install". For more informationen https://github.com/Froxlor/Froxlor/wiki'); +if (! file_exists(dirname(__DIR__) . '/vendor/autoload.php')) { + // get hint-template + $vendor_hint = file_get_contents(dirname(__DIR__) . '/templates/Sparkle/misc/vendormissinghint.tpl'); + // replace values + $vendor_hint = str_replace("", dirname(__DIR__), $vendor_hint); + $vendor_hint = str_replace("", date('Y', time()), $vendor_hint); + die($vendor_hint); } require dirname(__DIR__) . '/vendor/autoload.php'; require __DIR__ . '/lib/class.FroxlorInstall.php'; diff --git a/lib/init.php b/lib/init.php index bec161f6..e3a050b5 100644 --- a/lib/init.php +++ b/lib/init.php @@ -16,8 +16,17 @@ * @package System * */ -if(!file_exists(dirname(__DIR__) . '/vendor/autoload.php')){ - die('Vendor does not exist. Please run "composer install". For more informationen https://github.com/Froxlor/Froxlor/wiki'); + +// define default theme for configurehint, etc. +$_deftheme = 'Sparkle'; + +if (! file_exists(dirname(__DIR__) . '/vendor/autoload.php')) { + // get hint-template + $vendor_hint = file_get_contents(dirname(__DIR__) . '/templates/' . $_deftheme . '/misc/vendormissinghint.tpl'); + // replace values + $vendor_hint = str_replace("", dirname(__DIR__), $vendor_hint); + $vendor_hint = str_replace("", date('Y', time()), $vendor_hint); + die($vendor_hint); } require dirname(__DIR__) . '/vendor/autoload.php'; @@ -72,9 +81,6 @@ unset($key); $filename = htmlentities(basename($_SERVER['PHP_SELF'])); -// define default theme for configurehint, etc. -$_deftheme = 'Sparkle'; - // check whether the userdata file exists if (! file_exists(\Froxlor\Froxlor::getInstallDir() . '/lib/userdata.inc.php')) { $config_hint = file_get_contents(\Froxlor\Froxlor::getInstallDir() . '/templates/' . $_deftheme . '/misc/configurehint.tpl'); @@ -92,7 +98,7 @@ if (! is_readable(\Froxlor\Froxlor::getInstallDir() . '/lib/userdata.inc.php')) // replace values $owner_hint = str_replace("", $posixusername['name'], $owner_hint); $owner_hint = str_replace("", $posixgroup['name'], $owner_hint); - $owner_hint = str_replace("<\Froxlor\Froxlor::getInstallDir()>", \Froxlor\Froxlor::getInstallDir(), $owner_hint); + $owner_hint = str_replace("", \Froxlor\Froxlor::getInstallDir(), $owner_hint); $owner_hint = str_replace("", date('Y', time()), $owner_hint); // show die($owner_hint); diff --git a/templates/Sparkle/misc/ownershiphint.tpl b/templates/Sparkle/misc/ownershiphint.tpl index 9ab32641..ec510e87 100644 --- a/templates/Sparkle/misc/ownershiphint.tpl +++ b/templates/Sparkle/misc/ownershiphint.tpl @@ -25,7 +25,7 @@

 

This mostly happens due to wrong ownership.
Try the following command to correct the ownership:

 

-

chown -R : <\Froxlor\Froxlor::getInstallDir()>

+

chown -R :