cleanup function/parameters and add type declarations where possible
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
This commit is contained in:
@@ -63,9 +63,10 @@ class CurrentUser
|
||||
/**
|
||||
* re-read in the user data if a valid session exists
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function reReadUserData()
|
||||
public static function reReadUserData(): bool
|
||||
{
|
||||
$table = self::isAdmin() ? TABLE_PANEL_ADMINS : TABLE_PANEL_CUSTOMERS;
|
||||
$userinfo_stmt = Database::prepare("
|
||||
@@ -75,7 +76,7 @@ class CurrentUser
|
||||
"loginname" => self::getField('loginname')
|
||||
]);
|
||||
if ($userinfo) {
|
||||
// dont just set the data, we need to merge with current data
|
||||
// don't just set the data, we need to merge with current data
|
||||
// array_merge is a right-reduction - value existing in getData() will be overwritten with $userinfo,
|
||||
// other than the union-operator (+) which would keep the values already existing from getData()
|
||||
$newuserinfo = array_merge(self::getData(), $userinfo);
|
||||
@@ -107,7 +108,7 @@ class CurrentUser
|
||||
*/
|
||||
public static function getField(string $index)
|
||||
{
|
||||
return isset($_SESSION['userinfo'][$index]) ? $_SESSION['userinfo'][$index] : "";
|
||||
return $_SESSION['userinfo'][$index] ?? "";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -130,6 +131,11 @@ class CurrentUser
|
||||
$_SESSION['userinfo'] = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $resource
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function canAddResource(string $resource): bool
|
||||
{
|
||||
$addition = true;
|
||||
@@ -145,14 +151,15 @@ class CurrentUser
|
||||
]);
|
||||
$addition = $result['emaildomains'] != 0;
|
||||
} elseif ($resource == 'subdomains') {
|
||||
$parentDomainCollection = (new Collection(SubDomains::class, $_SESSION['userinfo'], ['sql_search' => ['d.parentdomainid' => 0]]));
|
||||
$parentDomainCollection = (new Collection(SubDomains::class, $_SESSION['userinfo'],
|
||||
['sql_search' => ['d.parentdomainid' => 0]]));
|
||||
$addition = $parentDomainCollection != 0;
|
||||
} elseif ($resource == 'domains') {
|
||||
$customerCollection = (new Collection(Customers::class, $_SESSION['userinfo']));
|
||||
$addition = $customerCollection != 0;
|
||||
}
|
||||
|
||||
return ($_SESSION['userinfo'][$resource.'_used'] < $_SESSION['userinfo'][$resource] || $_SESSION['userinfo'][$resource] == '-1') && $addition;
|
||||
return ($_SESSION['userinfo'][$resource . '_used'] < $_SESSION['userinfo'][$resource] || $_SESSION['userinfo'][$resource] == '-1') && $addition;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,7 +31,15 @@ use PDO;
|
||||
class Customer
|
||||
{
|
||||
|
||||
public static function getCustomerDetail($customerid, $varname)
|
||||
/**
|
||||
* Get value of a a specific field from a given customer
|
||||
*
|
||||
* @param int $customerid
|
||||
* @param string $varname
|
||||
* @return false|mixed
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function getCustomerDetail(int $customerid, string $varname)
|
||||
{
|
||||
$customer_stmt = Database::prepare("
|
||||
SELECT `" . $varname . "` FROM `" . TABLE_PANEL_CUSTOMERS . "` WHERE `customerid` = :customerid
|
||||
@@ -42,20 +50,19 @@ class Customer
|
||||
|
||||
if (isset($customer[$varname])) {
|
||||
return $customer[$varname];
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the loginname of a customer by given uid
|
||||
*
|
||||
* @param int $uid
|
||||
* uid of customer
|
||||
* @param int $uid uid of customer
|
||||
*
|
||||
* @return string customers loginname
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function getLoginNameByUid($uid = null)
|
||||
public static function getLoginNameByUid(int $uid)
|
||||
{
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT `loginname` FROM `" . TABLE_PANEL_CUSTOMERS . "` WHERE `guid` = :guid
|
||||
@@ -64,7 +71,7 @@ class Customer
|
||||
'guid' => $uid
|
||||
]);
|
||||
|
||||
if (is_array($result) && isset($result['loginname'])) {
|
||||
if ($result && isset($result['loginname'])) {
|
||||
return $result['loginname'];
|
||||
}
|
||||
return false;
|
||||
@@ -76,23 +83,22 @@ class Customer
|
||||
* returns true or false whether perl is
|
||||
* enabled for the given customer
|
||||
*
|
||||
* @param
|
||||
* int customer-id
|
||||
* @param int $cid customer-id
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function customerHasPerlEnabled($cid = 0)
|
||||
public static function customerHasPerlEnabled(int $cid = 0)
|
||||
{
|
||||
if ($cid > 0) {
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT `perlenabled` FROM `" . TABLE_PANEL_CUSTOMERS . "` WHERE `customerid` = :cid");
|
||||
Database::pexecute($result_stmt, [
|
||||
$result = Database::pexecute_first($result_stmt, [
|
||||
'cid' => $cid
|
||||
]);
|
||||
$result = $result_stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (is_array($result) && isset($result['perlenabled'])) {
|
||||
return $result['perlenabled'] == '1';
|
||||
if ($result && isset($result['perlenabled'])) {
|
||||
return (bool)$result['perlenabled'];
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -83,19 +83,21 @@ class Database
|
||||
private static $need_dbname = true;
|
||||
|
||||
/**
|
||||
* Wrapper for PDOStatement::execute so we can catch the PDOException
|
||||
* Wrapper for PDOStatement::execute, so we can catch the PDOException
|
||||
* and display the error nicely on the panel - also fetches the
|
||||
* result from the statement and returns the resulting array
|
||||
*
|
||||
* @param PDOStatement $stmt
|
||||
* @param array $params
|
||||
* @param array|null $params
|
||||
* (optional)
|
||||
* @param bool $showerror
|
||||
* suppress errordisplay (default true)
|
||||
* suppress error display (default true)
|
||||
* @param bool $json_response
|
||||
*
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function pexecute_first(&$stmt, $params = null, $showerror = true, $json_response = false)
|
||||
public static function pexecute_first(PDOStatement &$stmt, $params = null, bool $showerror = true, bool $json_response = false): array
|
||||
{
|
||||
self::pexecute($stmt, $params, $showerror, $json_response);
|
||||
return $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
@@ -106,12 +108,15 @@ class Database
|
||||
* and display the error nicely on the panel
|
||||
*
|
||||
* @param PDOStatement $stmt
|
||||
* @param array $params
|
||||
* @param array|null $params
|
||||
* (optional)
|
||||
* @param bool $showerror
|
||||
* suppress errordisplay (default true)
|
||||
* suppress error display (default true)
|
||||
* @param bool $json_response
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function pexecute(&$stmt, $params = null, $showerror = true, $json_response = false)
|
||||
public static function pexecute(PDOStatement &$stmt, $params = null, bool $showerror = true, bool $json_response = false)
|
||||
{
|
||||
try {
|
||||
$stmt->execute($params);
|
||||
@@ -125,9 +130,10 @@ class Database
|
||||
*
|
||||
* @param PDOException $error
|
||||
* @param bool $showerror
|
||||
* if set to false, the error will be logged but we go on
|
||||
* if set to false, the error will be logged, but we go on
|
||||
* @throws Exception
|
||||
*/
|
||||
private static function showerror($error, $showerror = true, $json_response = false, PDOStatement $stmt = null)
|
||||
private static function showerror(Exception $error, bool $showerror = true, bool $json_response = false, PDOStatement $stmt = null)
|
||||
{
|
||||
global $userinfo, $theme, $linker;
|
||||
|
||||
@@ -143,7 +149,7 @@ class Database
|
||||
0 => [
|
||||
'caption' => 'Default',
|
||||
'host' => $sql['host'],
|
||||
'socket' => (isset($sql['socket']) ? $sql['socket'] : null),
|
||||
'socket' => ($sql['socket'] ?? null),
|
||||
'user' => $sql['root_user'],
|
||||
'password' => $sql['root_password']
|
||||
]
|
||||
@@ -159,8 +165,8 @@ class Database
|
||||
$substitutions = [
|
||||
$sql['password'] => 'DB_UNPRIV_PWD',
|
||||
];
|
||||
foreach ($sql_root as $dbserver => $sql_root_data) {
|
||||
$substitutions[$sql_root_data[$dbserver]]['password'] = 'DB_ROOT_PWD';
|
||||
foreach ($sql_root as $sql_root_data) {
|
||||
$substitutions[$sql_root_data['password']] = 'DB_ROOT_PWD';
|
||||
}
|
||||
|
||||
// hide username/password in messages
|
||||
@@ -254,7 +260,7 @@ class Database
|
||||
* @param int $minLength
|
||||
* @return string
|
||||
*/
|
||||
private static function substitute($content, array $substitutions, $minLength = 6)
|
||||
private static function substitute(string $content, array $substitutions, int $minLength = 6): string
|
||||
{
|
||||
$replacements = [];
|
||||
|
||||
@@ -262,9 +268,7 @@ class Database
|
||||
$replacements += self::createShiftedSubstitutions($search, $replace, $minLength);
|
||||
}
|
||||
|
||||
$content = str_replace(array_keys($replacements), array_values($replacements), $content);
|
||||
|
||||
return $content;
|
||||
return str_replace(array_keys($replacements), array_values($replacements), $content);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -284,7 +288,7 @@ class Database
|
||||
* @param int $minLength
|
||||
* @return array
|
||||
*/
|
||||
private static function createShiftedSubstitutions($search, $replace, $minLength)
|
||||
private static function createShiftedSubstitutions(string $search, string $replace, int $minLength): array
|
||||
{
|
||||
$substitutions = [];
|
||||
$length = strlen($search);
|
||||
@@ -303,8 +307,9 @@ class Database
|
||||
*
|
||||
* @param int $length
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
private static function genUniqueToken(int $length = 16)
|
||||
private static function genUniqueToken(int $length = 16): string
|
||||
{
|
||||
if (intval($length) <= 8) {
|
||||
$length = 16;
|
||||
@@ -327,7 +332,7 @@ class Database
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function num_rows()
|
||||
public static function num_rows(): int
|
||||
{
|
||||
return Database::query("SELECT FOUND_ROWS()")->fetchColumn();
|
||||
}
|
||||
@@ -337,7 +342,7 @@ class Database
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getDbName()
|
||||
public static function getDbName(): ?string
|
||||
{
|
||||
return self::$dbname;
|
||||
}
|
||||
@@ -349,8 +354,8 @@ class Database
|
||||
* the 'normal' database-connection
|
||||
*
|
||||
* @param bool $needroot
|
||||
* @param int $dbserver
|
||||
* optional
|
||||
* @param int $dbserver optional
|
||||
* @param bool $need_db
|
||||
*/
|
||||
public static function needRoot(bool $needroot = false, int $dbserver = 0, bool $need_db = true)
|
||||
{
|
||||
@@ -366,7 +371,7 @@ class Database
|
||||
*
|
||||
* @param int $dbserver
|
||||
*/
|
||||
private static function setServer($dbserver = 0)
|
||||
private static function setServer(int $dbserver = 0)
|
||||
{
|
||||
self::$dbserver = $dbserver;
|
||||
self::$link = null;
|
||||
@@ -397,17 +402,16 @@ class Database
|
||||
* function that will be called on every static call
|
||||
* which connects to the database if necessary
|
||||
*
|
||||
* @param bool $root
|
||||
*
|
||||
* @return object
|
||||
* @throws Exception
|
||||
*/
|
||||
private static function getDB()
|
||||
{
|
||||
if (!extension_loaded('pdo') || in_array("mysql", PDO::getAvailableDrivers()) == false) {
|
||||
if (!extension_loaded('pdo') || !in_array("mysql", PDO::getAvailableDrivers())) {
|
||||
self::showerror(new Exception("The php PDO extension or PDO-MySQL driver is not available"));
|
||||
}
|
||||
|
||||
// do we got a connection already?
|
||||
// do we have a connection already?
|
||||
if (self::$link) {
|
||||
// return it
|
||||
return self::$link;
|
||||
@@ -422,7 +426,7 @@ class Database
|
||||
0 => [
|
||||
'caption' => 'Default',
|
||||
'host' => $sql['host'],
|
||||
'socket' => (isset($sql['socket']) ? $sql['socket'] : null),
|
||||
'socket' => ($sql['socket'] ?? null),
|
||||
'user' => $sql['root_user'],
|
||||
'password' => $sql['root_password']
|
||||
]
|
||||
@@ -441,8 +445,8 @@ class Database
|
||||
$user = $sql_root[self::$dbserver]['user'];
|
||||
$password = $sql_root[self::$dbserver]['password'];
|
||||
$host = $sql_root[self::$dbserver]['host'];
|
||||
$socket = isset($sql_root[self::$dbserver]['socket']) ? $sql_root[self::$dbserver]['socket'] : null;
|
||||
$port = isset($sql_root[self::$dbserver]['port']) ? $sql_root[self::$dbserver]['port'] : '3306';
|
||||
$socket = $sql_root[self::$dbserver]['socket'] ?? null;
|
||||
$port = $sql_root[self::$dbserver]['port'] ?? '3306';
|
||||
$sslCAFile = $sql_root[self::$dbserver]['ssl']['caFile'] ?? "";
|
||||
$sslVerifyServerCertificate = $sql_root[self::$dbserver]['ssl']['verifyServerCertificate'] ?? false;
|
||||
} else {
|
||||
@@ -450,8 +454,8 @@ class Database
|
||||
$user = $sql["user"];
|
||||
$password = $sql["password"];
|
||||
$host = $sql["host"];
|
||||
$socket = isset($sql['socket']) ? $sql['socket'] : null;
|
||||
$port = isset($sql['port']) ? $sql['port'] : '3306';
|
||||
$socket = $sql['socket'] ?? null;
|
||||
$port = $sql['port'] ?? '3306';
|
||||
$sslCAFile = $sql['ssl']['caFile'] ?? "";
|
||||
$sslVerifyServerCertificate = $sql['ssl']['verifyServerCertificate'] ?? false;
|
||||
}
|
||||
@@ -556,14 +560,14 @@ class Database
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function getSqlUsernameLength()
|
||||
public static function getSqlUsernameLength(): int
|
||||
{
|
||||
// MariaDB supports up to 80 characters but only 64 for databases and as we use the loginname also for
|
||||
// MariaDB supports up to 80 characters but only 64 for databases and as we use the login-name also for
|
||||
// database names, we set the limit to 64 here
|
||||
if (strpos(strtolower(Database::getAttribute(\PDO::ATTR_SERVER_VERSION)), "mariadb") !== false) {
|
||||
$mysql_max = 64;
|
||||
} else {
|
||||
// MySQL user names can be up to 32 characters long (16 characters before MySQL 5.7.8).
|
||||
// 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;
|
||||
@@ -573,15 +577,16 @@ class Database
|
||||
}
|
||||
|
||||
/**
|
||||
* let's us interact with the PDO-Object by using static
|
||||
* Lets us interact with the PDO-Object by using static
|
||||
* call like "Database::function()"
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $args
|
||||
*
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function __callStatic($name, $args)
|
||||
public static function __callStatic(string $name, $args)
|
||||
{
|
||||
$callback = [
|
||||
self::getDB(),
|
||||
|
||||
@@ -77,7 +77,15 @@ class DbManager
|
||||
$this->manager = new DbManagerMySQL($this->log);
|
||||
}
|
||||
|
||||
public static function correctMysqlUsers($mysql_access_host_array)
|
||||
/**
|
||||
* function called when the mysql-access-host setting changes
|
||||
*
|
||||
* @param array $mysql_access_host_array
|
||||
*
|
||||
* @return void
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function correctMysqlUsers(array $mysql_access_host_array)
|
||||
{
|
||||
// get all databases for all dbservers
|
||||
$databases = [];
|
||||
@@ -136,13 +144,14 @@ class DbManager
|
||||
* DB-name and user-name are being generated and
|
||||
* the password for the user will be set
|
||||
*
|
||||
* @param string $loginname
|
||||
* @param string $password
|
||||
* @param ?string $loginname
|
||||
* @param ?string $password
|
||||
* @param int $dbserver
|
||||
* @param int $last_accnumber
|
||||
*
|
||||
* @return string|bool $username if successful or false of username is equal to the password
|
||||
*/
|
||||
public function createDatabase($loginname = null, $password = null, int $dbserver = 0, $last_accnumber = 0)
|
||||
public function createDatabase(string $loginname = null, string $password = null, int $dbserver = 0, int $last_accnumber = 0)
|
||||
{
|
||||
Database::needRoot(true, $dbserver, false);
|
||||
|
||||
|
||||
@@ -85,21 +85,22 @@ class IntegrityCheck
|
||||
/**
|
||||
* check whether the froxlor database and its tables are in utf-8 character-set
|
||||
*
|
||||
* @param bool $fix
|
||||
* fix db charset/collation if not utf8
|
||||
* @param bool $fix fix db charset/collation if not utf8
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function databaseCharset($fix = false)
|
||||
public function databaseCharset(bool $fix = false): bool
|
||||
{
|
||||
// get characterset
|
||||
// get character-set
|
||||
$cs_stmt = Database::prepare('SELECT default_character_set_name FROM information_schema.SCHEMATA WHERE schema_name = :dbname');
|
||||
$resp = Database::pexecute_first($cs_stmt, [
|
||||
'dbname' => Database::getDbName()
|
||||
]);
|
||||
$charset = isset($resp['default_character_set_name']) ? $resp['default_character_set_name'] : null;
|
||||
$charset = $resp['default_character_set_name'] ?? null;
|
||||
if (!empty($charset) && substr(strtolower($charset), 0, 4) != 'utf8') {
|
||||
$this->log->logAction(FroxlorLogger::ADM_ACTION, LOG_NOTICE, "database charset seems to be different from UTF-8, integrity-check can fix that");
|
||||
$this->log->logAction(FroxlorLogger::ADM_ACTION, LOG_NOTICE,
|
||||
"database charset seems to be different from UTF-8, integrity-check can fix that");
|
||||
if ($fix) {
|
||||
// fix database
|
||||
Database::query('ALTER DATABASE `' . Database::getDbName() . '` CHARACTER SET utf8 COLLATE utf8_general_ci');
|
||||
@@ -109,7 +110,8 @@ class IntegrityCheck
|
||||
$table = $row[0];
|
||||
Database::query('ALTER TABLE `' . $table . '` CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;');
|
||||
}
|
||||
$this->log->logAction(FroxlorLogger::ADM_ACTION, LOG_WARNING, "database charset was different from UTF-8, integrity-check fixed that");
|
||||
$this->log->logAction(FroxlorLogger::ADM_ACTION, LOG_WARNING,
|
||||
"database charset was different from UTF-8, integrity-check fixed that");
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@@ -124,10 +126,12 @@ class IntegrityCheck
|
||||
/**
|
||||
* Check the integrity of the domain to ip/port - association
|
||||
*
|
||||
* @param bool $fix
|
||||
* Fix everything found directly
|
||||
* @param bool $fix fix everything found directly
|
||||
*
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function domainIpTable($fix = false)
|
||||
public function domainIpTable(bool $fix = false): bool
|
||||
{
|
||||
$ips = [];
|
||||
$domains = [];
|
||||
@@ -184,9 +188,11 @@ class IntegrityCheck
|
||||
'domainid' => $row['id_domain'],
|
||||
'ipandportid' => $row['id_ipandports']
|
||||
]);
|
||||
$this->log->logAction(FroxlorLogger::ADM_ACTION, LOG_WARNING, "found an ip/port-id in domain <> ip table which does not exist, integrity check fixed this");
|
||||
$this->log->logAction(FroxlorLogger::ADM_ACTION, LOG_WARNING,
|
||||
"found an ip/port-id in domain <> ip table which does not exist, integrity check fixed this");
|
||||
} else {
|
||||
$this->log->logAction(FroxlorLogger::ADM_ACTION, LOG_NOTICE, "found an ip/port-id in domain <> ip table which does not exist, integrity check can fix this");
|
||||
$this->log->logAction(FroxlorLogger::ADM_ACTION, LOG_NOTICE,
|
||||
"found an ip/port-id in domain <> ip table which does not exist, integrity check can fix this");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -196,9 +202,11 @@ class IntegrityCheck
|
||||
'domainid' => $row['id_domain'],
|
||||
'ipandportid' => $row['id_ipandports']
|
||||
]);
|
||||
$this->log->logAction(FroxlorLogger::ADM_ACTION, LOG_WARNING, "found a domain-id in domain <> ip table which does not exist, integrity check fixed this");
|
||||
$this->log->logAction(FroxlorLogger::ADM_ACTION, LOG_WARNING,
|
||||
"found a domain-id in domain <> ip table which does not exist, integrity check fixed this");
|
||||
} else {
|
||||
$this->log->logAction(FroxlorLogger::ADM_ACTION, LOG_NOTICE, "found a domain-id in domain <> ip table which does not exist, integrity check can fix this");
|
||||
$this->log->logAction(FroxlorLogger::ADM_ACTION, LOG_NOTICE,
|
||||
"found a domain-id in domain <> ip table which does not exist, integrity check can fix this");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -216,9 +224,11 @@ class IntegrityCheck
|
||||
'ipandportid' => $defaultip
|
||||
]);
|
||||
}
|
||||
$this->log->logAction(FroxlorLogger::ADM_ACTION, LOG_WARNING, "found a domain-id with no entry in domain <> ip table, integrity check fixed this");
|
||||
$this->log->logAction(FroxlorLogger::ADM_ACTION, LOG_WARNING,
|
||||
"found a domain-id with no entry in domain <> ip table, integrity check fixed this");
|
||||
} else {
|
||||
$this->log->logAction(FroxlorLogger::ADM_ACTION, LOG_NOTICE, "found a domain-id with no entry in domain <> ip table, integrity check can fix this");
|
||||
$this->log->logAction(FroxlorLogger::ADM_ACTION, LOG_NOTICE,
|
||||
"found a domain-id with no entry in domain <> ip table, integrity check can fix this");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -226,18 +236,19 @@ class IntegrityCheck
|
||||
|
||||
if ($fix) {
|
||||
return $this->domainIpTable();
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if all subdomains have ssl-redirect = 0 if domain has no ssl-port
|
||||
*
|
||||
* @param bool $fix
|
||||
* Fix everything found directly
|
||||
* @param bool $fix fix everything found directly
|
||||
*
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function subdomainSslRedirect($fix = false)
|
||||
public function subdomainSslRedirect(bool $fix = false): bool
|
||||
{
|
||||
$ips = [];
|
||||
$parentdomains = [];
|
||||
@@ -300,28 +311,31 @@ class IntegrityCheck
|
||||
Database::pexecute($upd_stmt, [
|
||||
'domainid' => $id
|
||||
]);
|
||||
$this->log->logAction(FroxlorLogger::ADM_ACTION, LOG_WARNING, "found a subdomain with ssl_redirect=1 but parent-domain has ssl=0, integrity check fixed this");
|
||||
$this->log->logAction(FroxlorLogger::ADM_ACTION, LOG_WARNING,
|
||||
"found a subdomain with ssl_redirect=1 but parent-domain has ssl=0, integrity check fixed this");
|
||||
} else {
|
||||
// It's just the check, let the function fail
|
||||
$this->log->logAction(FroxlorLogger::ADM_ACTION, LOG_NOTICE, "found a subdomain with ssl_redirect=1 but parent-domain has ssl=0, integrity check can fix this");
|
||||
$this->log->logAction(FroxlorLogger::ADM_ACTION, LOG_NOTICE,
|
||||
"found a subdomain with ssl_redirect=1 but parent-domain has ssl=0, integrity check can fix this");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($fix) {
|
||||
return $this->subdomainSslRedirect();
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if all subdomain have letsencrypt = 0 if domain has no ssl-port
|
||||
*
|
||||
* @param bool $fix
|
||||
* Fix everything found directly
|
||||
* @param bool $fix fix everything found directly
|
||||
*
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function subdomainLetsencrypt($fix = false)
|
||||
public function subdomainLetsencrypt(bool $fix = false): bool
|
||||
{
|
||||
$ips = [];
|
||||
$parentdomains = [];
|
||||
@@ -384,31 +398,32 @@ class IntegrityCheck
|
||||
Database::pexecute($upd_stmt, [
|
||||
'domainid' => $id
|
||||
]);
|
||||
$this->log->logAction(FroxlorLogger::ADM_ACTION, LOG_WARNING, "found a subdomain with letsencrypt=1 but parent-domain has ssl=0, integrity check fixed this");
|
||||
$this->log->logAction(FroxlorLogger::ADM_ACTION, LOG_WARNING,
|
||||
"found a subdomain with letsencrypt=1 but parent-domain has ssl=0, integrity check fixed this");
|
||||
} else {
|
||||
// It's just the check, let the function fail
|
||||
$this->log->logAction(FroxlorLogger::ADM_ACTION, LOG_NOTICE, "found a subdomain with letsencrypt=1 but parent-domain has ssl=0, integrity check can fix this");
|
||||
$this->log->logAction(FroxlorLogger::ADM_ACTION, LOG_NOTICE,
|
||||
"found a subdomain with letsencrypt=1 but parent-domain has ssl=0, integrity check can fix this");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($fix) {
|
||||
return $this->subdomainLetsencrypt();
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* check whether the webserveruser is in
|
||||
* the customers groups when fcgid / php-fpm is used
|
||||
*
|
||||
* @param bool $fix
|
||||
* fix member/groups
|
||||
* @param bool $fix fix member/groups
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function webserverGroupMemberForFcgidPhpFpm($fix = false)
|
||||
public function webserverGroupMemberForFcgidPhpFpm(bool $fix = false): bool
|
||||
{
|
||||
if (Settings::Get('system.mod_fcgid') == 0 && Settings::Get('phpfpm.enabled') == 0) {
|
||||
return true;
|
||||
@@ -423,7 +438,8 @@ class IntegrityCheck
|
||||
]);
|
||||
|
||||
if ($cwg_stmt->rowCount() > 0) {
|
||||
$this->log->logAction(FroxlorLogger::ADM_ACTION, LOG_NOTICE, "Customers are missing the webserver-user as group-member, integrity-check can fix that");
|
||||
$this->log->logAction(FroxlorLogger::ADM_ACTION, LOG_NOTICE,
|
||||
"Customers are missing the webserver-user as group-member, integrity-check can fix that");
|
||||
if ($fix) {
|
||||
// prepare update statement
|
||||
$upd_stmt = Database::prepare("
|
||||
@@ -438,7 +454,8 @@ class IntegrityCheck
|
||||
$upd_data['id'] = $cwg_row['id'];
|
||||
Database::pexecute($upd_stmt, $upd_data);
|
||||
}
|
||||
$this->log->logAction(FroxlorLogger::ADM_ACTION, LOG_NOTICE, "Customers were missing the webserver-user as group-member, integrity-check fixed that");
|
||||
$this->log->logAction(FroxlorLogger::ADM_ACTION, LOG_NOTICE,
|
||||
"Customers were missing the webserver-user as group-member, integrity-check fixed that");
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@@ -455,12 +472,12 @@ class IntegrityCheck
|
||||
* the customers groups when fcgid / php-fpm and
|
||||
* fcgid/fpm in froxlor vhost is used
|
||||
*
|
||||
* @param bool $fix
|
||||
* fix member/groups
|
||||
* @param bool $fix fix member/groups
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function froxlorLocalGroupMemberForFcgidPhpFpm($fix = false)
|
||||
public function froxlorLocalGroupMemberForFcgidPhpFpm(bool $fix = false): bool
|
||||
{
|
||||
if (Settings::Get('system.mod_fcgid') == 0 && Settings::Get('phpfpm.enabled') == 0) {
|
||||
return true;
|
||||
@@ -491,7 +508,8 @@ class IntegrityCheck
|
||||
]);
|
||||
|
||||
if ($cwg_stmt->rowCount() > 0) {
|
||||
$this->log->logAction(FroxlorLogger::ADM_ACTION, LOG_NOTICE, "Customers are missing the local froxlor-user as group-member, integrity-check can fix that");
|
||||
$this->log->logAction(FroxlorLogger::ADM_ACTION, LOG_NOTICE,
|
||||
"Customers are missing the local froxlor-user as group-member, integrity-check can fix that");
|
||||
if ($fix) {
|
||||
// prepare update statement
|
||||
$upd_stmt = Database::prepare("
|
||||
@@ -506,7 +524,8 @@ class IntegrityCheck
|
||||
$upd_data['id'] = $cwg_row['id'];
|
||||
Database::pexecute($upd_stmt, $upd_data);
|
||||
}
|
||||
$this->log->logAction(FroxlorLogger::ADM_ACTION, LOG_NOTICE, "Customers were missing the local froxlor-user as group-member, integrity-check fixed that");
|
||||
$this->log->logAction(FroxlorLogger::ADM_ACTION, LOG_NOTICE,
|
||||
"Customers were missing the local froxlor-user as group-member, integrity-check fixed that");
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ class DbManagerMySQL
|
||||
/**
|
||||
* main constructor
|
||||
*
|
||||
* @param FroxlorLogger $log
|
||||
* @param FroxlorLogger|null $log
|
||||
*/
|
||||
public function __construct(&$log = null)
|
||||
{
|
||||
@@ -58,9 +58,9 @@ class DbManagerMySQL
|
||||
/**
|
||||
* creates a database
|
||||
*
|
||||
* @param string $dbname
|
||||
* @param string|null $dbname
|
||||
*/
|
||||
public function createDatabase($dbname = null)
|
||||
public function createDatabase(string $dbname = null)
|
||||
{
|
||||
Database::query("CREATE DATABASE `" . $dbname . "`");
|
||||
}
|
||||
@@ -71,13 +71,14 @@ class DbManagerMySQL
|
||||
*
|
||||
* @param string $username
|
||||
* @param string|array $password
|
||||
* @param string $access_host
|
||||
* @param ?string $access_host
|
||||
* @param bool $p_encrypted
|
||||
* optional, whether the password is encrypted or not, default false
|
||||
* @param bool $update
|
||||
* optional, whether to update the password only (not create user)
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function grantPrivilegesTo($username = null, $password = null, $access_host = null, $p_encrypted = false, $update = false)
|
||||
public function grantPrivilegesTo(string $username, $password, string $access_host = null, bool $p_encrypted = false, bool $update = false)
|
||||
{
|
||||
$pwd_plugin = 'mysql_native_password';
|
||||
if (is_array($password) && count($password) == 2) {
|
||||
@@ -141,8 +142,9 @@ class DbManagerMySQL
|
||||
* takes away any privileges from a user to that db
|
||||
*
|
||||
* @param string $dbname
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function deleteDatabase($dbname = null)
|
||||
public function deleteDatabase(string $dbname)
|
||||
{
|
||||
if (version_compare(Database::getAttribute(PDO::ATTR_SERVER_VERSION), '5.0.2', '<')) {
|
||||
// failsafe if user has been deleted manually (requires MySQL 4.1.2+)
|
||||
@@ -178,8 +180,9 @@ class DbManagerMySQL
|
||||
*
|
||||
* @param string $username
|
||||
* @param string $host
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function deleteUser($username = null, $host = null)
|
||||
public function deleteUser(string $username, string $host)
|
||||
{
|
||||
if (Database::getAttribute(PDO::ATTR_SERVER_VERSION) < '5.0.2') {
|
||||
// Revoke privileges (only required for MySQL 4.1.2 - 5.0.1)
|
||||
@@ -203,9 +206,9 @@ class DbManagerMySQL
|
||||
*
|
||||
* @param string $username
|
||||
* @param string $host
|
||||
* (unused in mysql)
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function disableUser($username = null, $host = null)
|
||||
public function disableUser(string $username, string $host)
|
||||
{
|
||||
$stmt = Database::prepare('REVOKE ALL PRIVILEGES, GRANT OPTION FROM `' . $username . '`@`' . $host . '`');
|
||||
Database::pexecute($stmt, [], false);
|
||||
@@ -216,8 +219,9 @@ class DbManagerMySQL
|
||||
*
|
||||
* @param string $username
|
||||
* @param string $host
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function enableUser($username = null, $host = null)
|
||||
public function enableUser(string $username, string $host)
|
||||
{
|
||||
// check whether user exists to avoid errors
|
||||
$exist_check_stmt = Database::prepare("SELECT EXISTS(SELECT 1 FROM mysql.user WHERE user = '" . $username . "' AND host = '" . $host . "')");
|
||||
@@ -239,14 +243,14 @@ class DbManagerMySQL
|
||||
/**
|
||||
* return an array of all usernames used in that DBMS
|
||||
*
|
||||
* @param bool $user_only
|
||||
* if false, * will be selected from mysql.user and slightly different array will be generated
|
||||
* @param bool $user_only if false, will be selected from mysql.user and slightly different array will be generated
|
||||
*
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getAllSqlUsers($user_only = true)
|
||||
public function getAllSqlUsers(bool $user_only = true): array
|
||||
{
|
||||
if ($user_only == false) {
|
||||
if (!$user_only) {
|
||||
$result_stmt = Database::prepare('SELECT * FROM mysql.user');
|
||||
} else {
|
||||
$result_stmt = Database::prepare('SELECT `User` FROM mysql.user');
|
||||
|
||||
@@ -33,7 +33,15 @@ use PDO;
|
||||
|
||||
class Dns
|
||||
{
|
||||
public static function getAllowedDomainEntry($domain_id, $area = 'customer', $userinfo = [])
|
||||
/**
|
||||
* @param int $domain_id
|
||||
* @param string $area
|
||||
* @param array $userinfo
|
||||
*
|
||||
* @return string|void
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function getAllowedDomainEntry(int $domain_id, string $area = 'customer', array $userinfo = [])
|
||||
{
|
||||
$dom_data = [
|
||||
'did' => $domain_id
|
||||
@@ -67,7 +75,15 @@ class Dns
|
||||
Response::standardError('dns_notfoundorallowed');
|
||||
}
|
||||
|
||||
public static function createDomainZone($domain_id, $froxlorhostname = false, $isMainButSubTo = false)
|
||||
/**
|
||||
* @param int|array $domain_id id of domain or in case of froxlorhostname, a domain-array with the needed data
|
||||
* @param bool $froxlorhostname
|
||||
* @param bool $isMainButSubTo
|
||||
*
|
||||
* @return DnsZone|void
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function createDomainZone($domain_id, bool $froxlorhostname = false, bool $isMainButSubTo = false)
|
||||
{
|
||||
if (!$froxlorhostname) {
|
||||
// get domain-name
|
||||
@@ -146,16 +162,22 @@ class Dns
|
||||
while ($subdomain = $subdomains_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
// Listing domains is enough as there currently is no support for choosing
|
||||
// different ips for a subdomain => use same IPs as toplevel
|
||||
self::addRequiredEntry(str_replace('.' . $domain['domain'], '', $subdomain['domain']), 'A', $required_entries);
|
||||
self::addRequiredEntry(str_replace('.' . $domain['domain'], '', $subdomain['domain']), 'AAAA', $required_entries);
|
||||
self::addRequiredEntry(str_replace('.' . $domain['domain'], '', $subdomain['domain']), 'A',
|
||||
$required_entries);
|
||||
self::addRequiredEntry(str_replace('.' . $domain['domain'], '', $subdomain['domain']), 'AAAA',
|
||||
$required_entries);
|
||||
|
||||
// Check whether to add a www.-prefix
|
||||
if ($subdomain['iswildcarddomain'] == '1') {
|
||||
self::addRequiredEntry('*.' . str_replace('.' . $domain['domain'], '', $subdomain['domain']), 'A', $required_entries);
|
||||
self::addRequiredEntry('*.' . str_replace('.' . $domain['domain'], '', $subdomain['domain']), 'AAAA', $required_entries);
|
||||
self::addRequiredEntry('*.' . str_replace('.' . $domain['domain'], '', $subdomain['domain']), 'A',
|
||||
$required_entries);
|
||||
self::addRequiredEntry('*.' . str_replace('.' . $domain['domain'], '', $subdomain['domain']),
|
||||
'AAAA', $required_entries);
|
||||
} elseif ($subdomain['wwwserveralias'] == '1') {
|
||||
self::addRequiredEntry('www.' . str_replace('.' . $domain['domain'], '', $subdomain['domain']), 'A', $required_entries);
|
||||
self::addRequiredEntry('www.' . str_replace('.' . $domain['domain'], '', $subdomain['domain']), 'AAAA', $required_entries);
|
||||
self::addRequiredEntry('www.' . str_replace('.' . $domain['domain'], '', $subdomain['domain']), 'A',
|
||||
$required_entries);
|
||||
self::addRequiredEntry('www.' . str_replace('.' . $domain['domain'], '', $subdomain['domain']),
|
||||
'AAAA', $required_entries);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -200,14 +222,17 @@ class Dns
|
||||
|
||||
// now generate all records and unset the required entries we have
|
||||
foreach ($dom_entries as $entry) {
|
||||
if (array_key_exists($entry['type'], $required_entries) && array_key_exists(md5($entry['record']), $required_entries[$entry['type']])) {
|
||||
if (array_key_exists($entry['type'], $required_entries) && array_key_exists(md5($entry['record']),
|
||||
$required_entries[$entry['type']])) {
|
||||
unset($required_entries[$entry['type']][md5($entry['record'])]);
|
||||
}
|
||||
if (Settings::Get('system.dns_createcaaentry') == '1' && $entry['type'] == 'CAA' && strtolower(substr($entry['content'], 0, 7)) == '"v=caa1') {
|
||||
if (Settings::Get('system.dns_createcaaentry') == '1' && $entry['type'] == 'CAA' && strtolower(substr($entry['content'],
|
||||
0, 7)) == '"v=caa1') {
|
||||
// unset special CAA required-entry
|
||||
unset($required_entries[$entry['type']][md5("@CAA@")]);
|
||||
}
|
||||
if (Settings::Get('spf.use_spf') == '1' && $entry['type'] == 'TXT' && $entry['record'] == '@' && (strtolower(substr($entry['content'], 0, 7)) == '"v=spf1' || strtolower(substr($entry['content'], 0, 6)) == 'v=spf1')) {
|
||||
if (Settings::Get('spf.use_spf') == '1' && $entry['type'] == 'TXT' && $entry['record'] == '@' && (strtolower(substr($entry['content'],
|
||||
0, 7)) == '"v=spf1' || strtolower(substr($entry['content'], 0, 6)) == 'v=spf1')) {
|
||||
// unset special spf required-entry
|
||||
unset($required_entries[$entry['type']][md5("@SPF@")]);
|
||||
}
|
||||
@@ -223,7 +248,8 @@ class Dns
|
||||
'*'
|
||||
] as $crecord
|
||||
) {
|
||||
if ($entry['type'] == 'CNAME' && $entry['record'] == '@' && (array_key_exists(md5($crecord), $required_entries['A']) || array_key_exists(md5($crecord), $required_entries['AAAA']))) {
|
||||
if ($entry['type'] == 'CNAME' && $entry['record'] == '@' && (array_key_exists(md5($crecord),
|
||||
$required_entries['A']) || array_key_exists(md5($crecord), $required_entries['AAAA']))) {
|
||||
unset($required_entries['A'][md5($crecord)]);
|
||||
unset($required_entries['AAAA'][md5($crecord)]);
|
||||
}
|
||||
@@ -238,13 +264,16 @@ class Dns
|
||||
'smtp'
|
||||
] as $crecord
|
||||
) {
|
||||
if ($entry['type'] == 'CNAME' && $entry['record'] == $crecord && (array_key_exists(md5($crecord), $required_entries['A']) || array_key_exists(md5($crecord), $required_entries['AAAA']))) {
|
||||
if ($entry['type'] == 'CNAME' && $entry['record'] == $crecord && (array_key_exists(md5($crecord),
|
||||
$required_entries['A']) || array_key_exists(md5($crecord),
|
||||
$required_entries['AAAA']))) {
|
||||
unset($required_entries['A'][md5($crecord)]);
|
||||
unset($required_entries['AAAA'][md5($crecord)]);
|
||||
}
|
||||
}
|
||||
}
|
||||
$zonerecords[] = new DnsEntry($entry['record'], $entry['type'], $entry['content'], $entry['prio'], $entry['ttl']);
|
||||
$zonerecords[] = new DnsEntry($entry['record'], $entry['type'], $entry['content'], $entry['prio'],
|
||||
$entry['ttl']);
|
||||
}
|
||||
|
||||
// add missing required entries
|
||||
@@ -275,7 +304,8 @@ class Dns
|
||||
foreach ($records as $record) {
|
||||
if ($type == 'A' && filter_var($ip['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false) {
|
||||
$zonerecords[] = new DnsEntry($record, 'A', $ip['ip']);
|
||||
} elseif ($type == 'AAAA' && filter_var($ip['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false) {
|
||||
} elseif ($type == 'AAAA' && filter_var($ip['ip'], FILTER_VALIDATE_IP,
|
||||
FILTER_FLAG_IPV6) !== false) {
|
||||
$zonerecords[] = new DnsEntry($record, 'AAAA', $ip['ip']);
|
||||
}
|
||||
}
|
||||
@@ -356,7 +386,8 @@ class Dns
|
||||
if (substr($dkim_entries[0], 0, 1) == '(') {
|
||||
$multiline = true;
|
||||
}
|
||||
$zonerecords[] = new DnsEntry($record, 'TXT', self::encloseTXTContent($dkim_entries[0], $multiline));
|
||||
$zonerecords[] = new DnsEntry($record, 'TXT',
|
||||
self::encloseTXTContent($dkim_entries[0], $multiline));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -416,7 +447,8 @@ class Dns
|
||||
|
||||
if (!$isMainButSubTo) {
|
||||
$date = date('Ymd');
|
||||
$domain['bindserial'] = (preg_match('/^' . $date . '/', $domain['bindserial']) ? $domain['bindserial'] + 1 : $date . '00');
|
||||
$domain['bindserial'] = (preg_match('/^' . $date . '/',
|
||||
$domain['bindserial']) ? $domain['bindserial'] + 1 : $date . '00');
|
||||
if (!$froxlorhostname) {
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_DOMAINS . "` SET
|
||||
@@ -443,12 +475,19 @@ class Dns
|
||||
array_unshift($zonerecords, $soa_record);
|
||||
}
|
||||
|
||||
$zone = new DnsZone((int)Settings::Get('system.defaultttl'), $domain['domain'], $domain['bindserial'], $zonerecords);
|
||||
$zone = new DnsZone((int)Settings::Get('system.defaultttl'), $domain['domain'], $domain['bindserial'],
|
||||
$zonerecords);
|
||||
|
||||
return $zone;
|
||||
}
|
||||
|
||||
private static function addRequiredEntry($record = '@', $type = 'A', &$required = [])
|
||||
/**
|
||||
* @param string $record
|
||||
* @param string $type
|
||||
* @param array $required
|
||||
* @return void
|
||||
*/
|
||||
private static function addRequiredEntry(string $record = '@', string $type = 'A', array &$required = [])
|
||||
{
|
||||
if (!isset($required[$type])) {
|
||||
$required[$type] = [];
|
||||
@@ -456,7 +495,11 @@ class Dns
|
||||
$required[$type][md5($record)] = $record;
|
||||
}
|
||||
|
||||
private static function generateDkimEntries($domain)
|
||||
/**
|
||||
* @param array $domain
|
||||
* @return array
|
||||
*/
|
||||
private static function generateDkimEntries(array $domain): array
|
||||
{
|
||||
$zone_dkim = [];
|
||||
|
||||
@@ -486,7 +529,8 @@ class Dns
|
||||
}
|
||||
|
||||
// key
|
||||
$dkim_txt .= 'k=rsa;p=' . trim(preg_replace('/-----BEGIN PUBLIC KEY-----(.+)-----END PUBLIC KEY-----/s', '$1', str_replace("\n", '', $domain['dkim_pubkey']))) . ';';
|
||||
$dkim_txt .= 'k=rsa;p=' . trim(preg_replace('/-----BEGIN PUBLIC KEY-----(.+)-----END PUBLIC KEY-----/s',
|
||||
'$1', str_replace("\n", '', $domain['dkim_pubkey']))) . ';';
|
||||
|
||||
// service-type
|
||||
if (Settings::Get('dkim.dkim_servicetype') == '1') {
|
||||
@@ -503,10 +547,15 @@ class Dns
|
||||
return $zone_dkim;
|
||||
}
|
||||
|
||||
public static function encloseTXTContent($txt_content, $isMultiLine = false)
|
||||
/**
|
||||
* @param string $txt_content
|
||||
* @param bool $isMultiLine
|
||||
* @return string
|
||||
*/
|
||||
public static function encloseTXTContent(string $txt_content, bool $isMultiLine = false): string
|
||||
{
|
||||
// check that TXT content is enclosed in " "
|
||||
if ($isMultiLine == false && Settings::Get('system.dns_server') != 'PowerDNS') {
|
||||
if (!$isMultiLine && Settings::Get('system.dns_server') != 'PowerDNS') {
|
||||
if (substr($txt_content, 0, 1) != '"') {
|
||||
$txt_content = '"' . $txt_content;
|
||||
}
|
||||
@@ -526,10 +575,13 @@ class Dns
|
||||
return $txt_content;
|
||||
}
|
||||
|
||||
private static function escapeSoaAdminMail($email)
|
||||
/**
|
||||
* @param string $email
|
||||
* @return string
|
||||
*/
|
||||
private static function escapeSoaAdminMail(string $email): string
|
||||
{
|
||||
$mail_parts = explode("@", $email);
|
||||
$escpd_mail = str_replace(".", "\.", $mail_parts[0]) . "." . $mail_parts[1] . ".";
|
||||
return $escpd_mail;
|
||||
return str_replace(".", "\.", $mail_parts[0]) . "." . $mail_parts[1] . ".";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,14 +29,22 @@ use Froxlor\Settings;
|
||||
|
||||
class DnsEntry
|
||||
{
|
||||
public $record;
|
||||
public $ttl;
|
||||
public $class = 'IN';
|
||||
public $type;
|
||||
public $priority;
|
||||
public $content;
|
||||
public string $record;
|
||||
public int $ttl;
|
||||
public string $class = 'IN';
|
||||
public string $type;
|
||||
public int $priority;
|
||||
public ?string $content;
|
||||
|
||||
public function __construct($record = '', $type = 'A', $content = null, $prio = 0, $ttl = 0, $class = 'IN')
|
||||
/**
|
||||
* @param string $record
|
||||
* @param string $type
|
||||
* @param string|null $content
|
||||
* @param int $prio
|
||||
* @param int $ttl
|
||||
* @param string $class
|
||||
*/
|
||||
public function __construct(string $record = '', string $type = 'A', string $content = null, int $prio = 0, int $ttl = 0, string $class = 'IN')
|
||||
{
|
||||
$this->record = $record;
|
||||
$this->type = $type;
|
||||
@@ -72,7 +80,6 @@ class DnsEntry
|
||||
// last line
|
||||
$_content .= "\t\t\t\t" . '"' . $_l . '")';
|
||||
}
|
||||
$result = $this->record . "\t" . $this->ttl . "\t" . $this->class . "\t" . $this->type . "\t" . (($this->priority >= 0 && ($this->type == 'MX' || $this->type == 'SRV')) ? $this->priority . "\t" : "") . $_content . PHP_EOL;
|
||||
return $result;
|
||||
return $this->record . "\t" . $this->ttl . "\t" . $this->class . "\t" . $this->type . "\t" . (($this->priority >= 0 && ($this->type == 'MX' || $this->type == 'SRV')) ? $this->priority . "\t" : "") . $_content . PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,12 +29,18 @@ use Froxlor\Settings;
|
||||
|
||||
class DnsZone
|
||||
{
|
||||
public $ttl;
|
||||
public $origin;
|
||||
public $serial;
|
||||
public $records;
|
||||
public int $ttl;
|
||||
public string $origin;
|
||||
public string $serial;
|
||||
public ?array $records;
|
||||
|
||||
public function __construct($ttl = 0, $origin = '', $serial = '', $records = null)
|
||||
/**
|
||||
* @param int $ttl
|
||||
* @param string $origin
|
||||
* @param string $serial
|
||||
* @param array|null $records
|
||||
*/
|
||||
public function __construct(int $ttl = 0, string $origin = '', string $serial = '', array $records = null)
|
||||
{
|
||||
$this->ttl = ($ttl <= 0 ? Settings::Get('system.defaultttl') : $ttl);
|
||||
$this->origin = $origin;
|
||||
@@ -44,13 +50,13 @@ class DnsZone
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
$_zonefile = "\$TTL " . $this->ttl . PHP_EOL;
|
||||
$_zonefile .= "\$ORIGIN " . $this->origin . "." . PHP_EOL;
|
||||
$zone_file = "\$TTL " . $this->ttl . PHP_EOL;
|
||||
$zone_file .= "\$ORIGIN " . $this->origin . "." . PHP_EOL;
|
||||
if (!empty($this->records)) {
|
||||
foreach ($this->records as $record) {
|
||||
$_zonefile .= (string)$record;
|
||||
$zone_file .= (string)$record;
|
||||
}
|
||||
}
|
||||
return $_zonefile;
|
||||
return $zone_file;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,9 +37,9 @@ class PowerDNS
|
||||
/**
|
||||
* remove all records and entries of a given domain
|
||||
*
|
||||
* @param array $domain
|
||||
* @param array|null $domain
|
||||
*/
|
||||
public static function cleanDomainZone($domain = null)
|
||||
public static function cleanDomainZone(array $domain = null)
|
||||
{
|
||||
if (is_array($domain) && isset($domain['domain'])) {
|
||||
$pdns_domains_stmt = self::getDB()->prepare("SELECT `id`, `name` FROM `domains` WHERE `name` = :domain");
|
||||
@@ -67,16 +67,19 @@ class PowerDNS
|
||||
/**
|
||||
* get pdo database connection to powerdns database
|
||||
*
|
||||
* @return PDO
|
||||
* @return \PDO
|
||||
*/
|
||||
public static function getDB()
|
||||
public static function getDB(): \PDO
|
||||
{
|
||||
if (!isset(self::$pdns_db) || (self::$pdns_db instanceof PDO) == false) {
|
||||
if (!isset(self::$pdns_db) || !(self::$pdns_db instanceof PDO)) {
|
||||
self::connectToPdnsDb();
|
||||
}
|
||||
return self::$pdns_db;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private static function connectToPdnsDb()
|
||||
{
|
||||
// get froxlor pdns config
|
||||
|
||||
@@ -41,8 +41,9 @@ class Domain
|
||||
*
|
||||
* @param int $domain_id
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function getIpsOfDomain($domain_id)
|
||||
public static function getIpsOfDomain(int $domain_id = 0): array
|
||||
{
|
||||
if ($domain_id > 0) {
|
||||
$sel_stmt = Database::prepare("
|
||||
@@ -75,7 +76,7 @@ class Domain
|
||||
*
|
||||
* @return array array of enabled redirect-codes
|
||||
*/
|
||||
public static function getRedirectCodesArray()
|
||||
public static function getRedirectCodesArray(): array
|
||||
{
|
||||
$sql = "SELECT * FROM `" . TABLE_PANEL_REDIRECTCODES . "` WHERE `enabled` = '1' ORDER BY `id` ASC";
|
||||
$result_stmt = Database::query($sql);
|
||||
@@ -92,12 +93,12 @@ class Domain
|
||||
* returns the redirect-code for a given
|
||||
* domain-id
|
||||
*
|
||||
* @param integer $domainid
|
||||
* id of the domain
|
||||
* @param int $domainid id of the domain
|
||||
*
|
||||
* @return string redirect-code
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function getDomainRedirectCode($domainid = 0)
|
||||
public static function getDomainRedirectCode(int $domainid = 0): string
|
||||
{
|
||||
// get system default
|
||||
$default = '301';
|
||||
@@ -128,12 +129,11 @@ class Domain
|
||||
* return an array of all enabled redirect-codes
|
||||
* for the settings form
|
||||
*
|
||||
* @param bool $add_desc
|
||||
* optional, default true, add the code-description
|
||||
* @param bool $add_desc optional, default true, add the code-description
|
||||
*
|
||||
* @return array array of enabled redirect-codes
|
||||
*/
|
||||
public static function getRedirectCodes($add_desc = true)
|
||||
public static function getRedirectCodes(bool $add_desc = true): array
|
||||
{
|
||||
$sql = "SELECT * FROM `" . TABLE_PANEL_REDIRECTCODES . "` WHERE `enabled` = '1' ORDER BY `id` ASC";
|
||||
$result_stmt = Database::query($sql);
|
||||
@@ -153,12 +153,12 @@ class Domain
|
||||
* returns the redirect-id for a given
|
||||
* domain-id
|
||||
*
|
||||
* @param integer $domainid
|
||||
* id of the domain
|
||||
* @param int $domainid id of the domain
|
||||
*
|
||||
* @return integer redirect-code-id
|
||||
* @return int redirect-code-id
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function getDomainRedirectId($domainid = 0)
|
||||
public static function getDomainRedirectId(int $domainid = 0): int
|
||||
{
|
||||
$code = 1;
|
||||
if ($domainid > 0) {
|
||||
@@ -171,7 +171,7 @@ class Domain
|
||||
'domainid' => $domainid
|
||||
]);
|
||||
|
||||
if (is_array($result) && isset($result['redirect'])) {
|
||||
if ($result && isset($result['redirect'])) {
|
||||
$code = (int)$result['redirect'];
|
||||
}
|
||||
}
|
||||
@@ -179,16 +179,15 @@ class Domain
|
||||
}
|
||||
|
||||
/**
|
||||
* adds a redirectcode for a domain
|
||||
* adds a redirect-code for a domain
|
||||
*
|
||||
* @param integer $domainid
|
||||
* id of the domain to add the code for
|
||||
* @param integer $redirect
|
||||
* selected redirect-id
|
||||
* @param int $domainid id of the domain to add the code for
|
||||
* @param int $redirect selected redirect-id
|
||||
*
|
||||
* @return null
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function addRedirectToDomain($domainid = 0, $redirect = 1)
|
||||
public static function addRedirectToDomain(int $domainid = 0, int $redirect = 1)
|
||||
{
|
||||
if ($domainid > 0) {
|
||||
$ins_stmt = Database::prepare("
|
||||
@@ -202,19 +201,18 @@ class Domain
|
||||
}
|
||||
|
||||
/**
|
||||
* updates the redirectcode of a domain
|
||||
* updates the redirect-code of a domain
|
||||
* if redirect-code is false, nothing happens
|
||||
*
|
||||
* @param integer $domainid
|
||||
* id of the domain to update
|
||||
* @param integer $redirect
|
||||
* selected redirect-id or false
|
||||
* @param int $domainid id of the domain to update
|
||||
* @param int $redirect selected redirect-id
|
||||
*
|
||||
* @return null
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function updateRedirectOfDomain($domainid = 0, $redirect = false)
|
||||
public static function updateRedirectOfDomain(int $domainid = 0, int $redirect = 0)
|
||||
{
|
||||
if ($redirect == false) {
|
||||
if (!$redirect) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -240,12 +238,12 @@ class Domain
|
||||
* check whether a domain has subdomains added as full-domains
|
||||
* #329
|
||||
*
|
||||
* @param int $id
|
||||
* domain-id
|
||||
* @param int $id domain-id
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function domainHasMainSubDomains($id = 0)
|
||||
public static function domainHasMainSubDomains(int $id): bool
|
||||
{
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT COUNT(`id`) as `mainsubs` FROM `" . TABLE_PANEL_DOMAINS . "`
|
||||
@@ -254,8 +252,8 @@ class Domain
|
||||
'id' => $id
|
||||
]);
|
||||
|
||||
if (isset($result['mainsubs']) && $result['mainsubs'] > 0) {
|
||||
return true;
|
||||
if ($result && isset($result['mainsubs'])) {
|
||||
return $result['mainsubs'] > 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -264,12 +262,12 @@ class Domain
|
||||
* check whether a subof-domain exists
|
||||
* #329
|
||||
*
|
||||
* @param int $id
|
||||
* subof-domain-id
|
||||
* @param int $id subof-domain-id
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function domainMainToSubExists($id = 0)
|
||||
public static function domainMainToSubExists(int $id): bool
|
||||
{
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT `id` FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `id` = :id");
|
||||
@@ -278,8 +276,8 @@ class Domain
|
||||
]);
|
||||
$result = $result_stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (isset($result['id']) && $result['id'] > 0) {
|
||||
return true;
|
||||
if ($result && isset($result['id'])) {
|
||||
return $result['id'] > 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -289,9 +287,10 @@ class Domain
|
||||
*
|
||||
* @param int $domainid
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function domainHasSslIpPort($domainid = 0)
|
||||
public static function domainHasSslIpPort(int $domainid): bool
|
||||
{
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT `dt`.* FROM `" . TABLE_DOMAINTOIP . "` `dt`, `" . TABLE_PANEL_IPSANDPORTS . "` `iap`
|
||||
@@ -301,7 +300,7 @@ class Domain
|
||||
]);
|
||||
$result = $result_stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (is_array($result) && isset($result['id_ipandports'])) {
|
||||
if ($result && isset($result['id_ipandports'])) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -311,12 +310,12 @@ class Domain
|
||||
* returns true or false whether a given domain id
|
||||
* is the std-subdomain of a customer
|
||||
*
|
||||
* @param
|
||||
* int domain-id
|
||||
* @param int $did domain-id
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function isCustomerStdSubdomain($did = 0)
|
||||
public static function isCustomerStdSubdomain(int $did): bool
|
||||
{
|
||||
if ($did > 0) {
|
||||
$result_stmt = Database::prepare("
|
||||
@@ -327,17 +326,27 @@ class Domain
|
||||
'did' => $did
|
||||
]);
|
||||
|
||||
if (is_array($result) && isset($result['customerid']) && $result['customerid'] > 0) {
|
||||
return true;
|
||||
if ($result && isset($result['customerid'])) {
|
||||
return $result['customerid'] > 0;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function triggerLetsEncryptCSRForAliasDestinationDomain($aliasDestinationDomainID, $log)
|
||||
{
|
||||
if (isset($aliasDestinationDomainID) && $aliasDestinationDomainID > 0) {
|
||||
$log->logAction(FroxlorLogger::ADM_ACTION, LOG_INFO, "LetsEncrypt CSR triggered for domain ID " . $aliasDestinationDomainID);
|
||||
/**
|
||||
* @param int $aliasDestinationDomainID
|
||||
* @param FroxlorLogger $log
|
||||
*
|
||||
* @return void
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function triggerLetsEncryptCSRForAliasDestinationDomain(
|
||||
int $aliasDestinationDomainID,
|
||||
FroxlorLogger $log
|
||||
) {
|
||||
if ($aliasDestinationDomainID > 0) {
|
||||
$log->logAction(FroxlorLogger::ADM_ACTION, LOG_INFO,
|
||||
"LetsEncrypt CSR triggered for domain ID " . $aliasDestinationDomainID);
|
||||
$upd_stmt = Database::prepare("UPDATE
|
||||
`" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "`
|
||||
SET
|
||||
@@ -351,7 +360,11 @@ class Domain
|
||||
}
|
||||
}
|
||||
|
||||
public static function doLetsEncryptCleanUp($domainname = null)
|
||||
/**
|
||||
* @param string $domainname
|
||||
* @return true
|
||||
*/
|
||||
public static function doLetsEncryptCleanUp(string $domainname): bool
|
||||
{
|
||||
// @ see \Froxlor\Cron\Http\LetsEncrypt\AcmeSh.php
|
||||
$acmesh = AcmeSh::getAcmeSh();
|
||||
@@ -374,18 +387,19 @@ class Domain
|
||||
/**
|
||||
* checks give path for security issues
|
||||
* and returns a string that can be appended
|
||||
* to a line for a open_basedir directive
|
||||
* to a line for an open_basedir directive
|
||||
*
|
||||
* @param string $path
|
||||
* the path to check and append
|
||||
* @param boolean $first
|
||||
* if true, no ':' will be prefixed to the path
|
||||
* @param string $path the path to check and append
|
||||
* @param bool $first if true, no ':' will be prefixed to the path
|
||||
*
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function appendOpenBasedirPath($path = '', $first = false)
|
||||
public static function appendOpenBasedirPath(string $path = '', bool $first = false): string
|
||||
{
|
||||
if ($path != '' && $path != '/' && (!preg_match("#^/dev#i", $path) || preg_match("#^/dev/urandom#i", $path)) && !preg_match("#^/proc#i", $path) && !preg_match("#^/etc#i", $path) && !preg_match("#^/sys#i", $path) && !preg_match("#:#", $path)) {
|
||||
if ($path != '' && $path != '/' && (!preg_match("#^/dev#i", $path) || preg_match("#^/dev/urandom#i",
|
||||
$path)) && !preg_match("#^/proc#i", $path) && !preg_match("#^/etc#i",
|
||||
$path) && !preg_match("#^/sys#i", $path) && !preg_match("#:#", $path)) {
|
||||
if (preg_match("#^/dev/urandom#i", $path)) {
|
||||
$path = FileDir::makeCorrectFile($path);
|
||||
} else {
|
||||
@@ -394,7 +408,7 @@ class Domain
|
||||
|
||||
// check for php-version that requires the trailing
|
||||
// slash to be removed as it does not allow the usage
|
||||
// of the subfolders within the given folder, fixes #797
|
||||
// of the sub-folders within the given folder, fixes #797
|
||||
if ((PHP_MINOR_VERSION == 2 && PHP_VERSION_ID >= 50216) || PHP_VERSION_ID >= 50304) {
|
||||
// check trailing slash
|
||||
if (substr($path, -1, 1) == '/') {
|
||||
|
||||
@@ -30,8 +30,10 @@ use PDO;
|
||||
|
||||
class IpAddr
|
||||
{
|
||||
|
||||
public static function getIpAddresses()
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function getIpAddresses(): array
|
||||
{
|
||||
$result_stmt = Database::query("
|
||||
SELECT `id`, `ip`, `port` FROM `" . TABLE_PANEL_IPSANDPORTS . "` ORDER BY `ip` ASC, `port` ASC
|
||||
@@ -51,14 +53,22 @@ class IpAddr
|
||||
return $system_ipaddress_array;
|
||||
}
|
||||
|
||||
public static function getSslIpPortCombinations()
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function getSslIpPortCombinations(): array
|
||||
{
|
||||
return [
|
||||
'' => lng('panel.none_value')
|
||||
] + self::getIpPortCombinations(true);
|
||||
}
|
||||
|
||||
public static function getIpPortCombinations($ssl = false)
|
||||
/**
|
||||
* @param bool $ssl
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function getIpPortCombinations(bool $ssl = false): array
|
||||
{
|
||||
global $userinfo;
|
||||
|
||||
|
||||
@@ -38,30 +38,24 @@ class FileDir
|
||||
* which had to be created below with correct Owner/Group
|
||||
* (Copied from cron_tasks.php:rev1189 as we'll need this more often in future)
|
||||
*
|
||||
* @param string $homeDir
|
||||
* The homedir of the user
|
||||
* @param string $dirToCreate
|
||||
* The dir which should be created
|
||||
* @param int $uid
|
||||
* The uid of the user
|
||||
* @param int $gid
|
||||
* The gid of the user
|
||||
* @param bool $placeindex
|
||||
* Place standard-index.html into the new folder
|
||||
* @param bool $allow_notwithinhomedir
|
||||
* Allow creating a directory out of the customers docroot
|
||||
* @param string $homeDir The homedir of the user
|
||||
* @param string $dirToCreate The dir which should be created
|
||||
* @param int $uid The uid of the user
|
||||
* @param int $gid The gid of the user
|
||||
* @param bool $placeindex Place standard-index.html into the new folder
|
||||
* @param bool $allow_notwithinhomedir Allow creating a directory out of the customers docroot
|
||||
*
|
||||
* @return bool true if everything went okay, false if something went wrong
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function mkDirWithCorrectOwnership(
|
||||
$homeDir,
|
||||
$dirToCreate,
|
||||
$uid,
|
||||
$gid,
|
||||
$placeindex = false,
|
||||
$allow_notwithinhomedir = false
|
||||
) {
|
||||
string $homeDir,
|
||||
string $dirToCreate,
|
||||
int $uid,
|
||||
int $gid,
|
||||
bool $placeindex = false,
|
||||
bool $allow_notwithinhomedir = false
|
||||
): bool {
|
||||
if ($homeDir != '' && $dirToCreate != '') {
|
||||
$homeDir = self::makeCorrectDir($homeDir);
|
||||
$dirToCreate = self::makeCorrectDir($dirToCreate);
|
||||
@@ -116,15 +110,14 @@ class FileDir
|
||||
* Function which returns a correct dirname, means to add slashes at the beginning and at the end if there weren't
|
||||
* some
|
||||
*
|
||||
* @param string $path
|
||||
* the path to correct
|
||||
* @param string $dir the path to correct
|
||||
*
|
||||
* @return string the corrected path
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function makeCorrectDir($dir)
|
||||
public static function makeCorrectDir(string $dir): string
|
||||
{
|
||||
if (is_string($dir) && strlen($dir) > 0) {
|
||||
if (strlen($dir) > 0) {
|
||||
$dir = trim($dir);
|
||||
if (substr($dir, -1, 1) != '/') {
|
||||
$dir .= '/';
|
||||
@@ -140,12 +133,11 @@ class FileDir
|
||||
/**
|
||||
* Function which returns a secure path, means to remove all multiple dots and slashes
|
||||
*
|
||||
* @param string $path
|
||||
* the path to secure
|
||||
* @param string $path the path to secure
|
||||
*
|
||||
* @return string the corrected path
|
||||
*/
|
||||
public static function makeSecurePath($path)
|
||||
public static function makeSecurePath(string $path): string
|
||||
{
|
||||
// check for bad characters, some are allowed with escaping,
|
||||
// but we generally don't want them in our directory-names,
|
||||
@@ -191,16 +183,13 @@ class FileDir
|
||||
/**
|
||||
* Wrapper around the exec command.
|
||||
*
|
||||
* @param string $exec_string
|
||||
* command to be executed
|
||||
* @param string $return_value
|
||||
* referenced variable where the output is stored
|
||||
* @param array $allowedChars
|
||||
* optional array of allowed characters in path/command
|
||||
* @param string $exec_string command to be executed
|
||||
* @param mixed $return_value referenced variable where the output is stored
|
||||
* @param ?array $allowedChars optional array of allowed characters in path/command
|
||||
*
|
||||
* @return array result of exec()
|
||||
*/
|
||||
public static function safe_exec($exec_string, &$return_value = false, $allowedChars = null)
|
||||
public static function safe_exec(string $exec_string, &$return_value = false, $allowedChars = null)
|
||||
{
|
||||
$disallowed = [
|
||||
';',
|
||||
@@ -245,19 +234,20 @@ class FileDir
|
||||
/**
|
||||
* store the default index-file in a given destination folder
|
||||
*
|
||||
* @param string $loginname
|
||||
* customers loginname
|
||||
* @param string $destination
|
||||
* path where to create the file
|
||||
* @param object $logger
|
||||
* FroxlorLogger object
|
||||
* @param boolean $force
|
||||
* force creation whatever the settings say (needed for task #2, create new user)
|
||||
* @param string $loginname customers loginname
|
||||
* @param string $destination path where to create the file
|
||||
* @param object $logger FroxlorLogger object
|
||||
* @param bool $force force creation whatever the settings say (needed for task #2, create new user)
|
||||
*
|
||||
* @return null
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function storeDefaultIndex($loginname = null, $destination = null, $logger = null, $force = false)
|
||||
{
|
||||
public static function storeDefaultIndex(
|
||||
string $loginname,
|
||||
string $destination,
|
||||
$logger = null,
|
||||
bool $force = false
|
||||
) {
|
||||
if ($force || (int)Settings::Get('system.store_index_file_subs') == 1) {
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT `t`.`value`, `c`.`email` AS `customer_email`, `a`.`email` AS `admin_email`, `c`.`loginname` AS `customer_login`, `a`.`loginname` AS `admin_login`
|
||||
@@ -306,18 +296,16 @@ class FileDir
|
||||
self::safe_exec('cp -a ' . Froxlor::getInstallDir() . '/templates/misc/standardcustomer/* ' . escapeshellarg($destination));
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function which returns a correct filename, means to add a slash at the beginning if there wasn't one
|
||||
*
|
||||
* @param string $filename
|
||||
* the filename
|
||||
* @param string $filename the filename
|
||||
*
|
||||
* @return string the corrected filename
|
||||
*/
|
||||
public static function makeCorrectFile(string $filename)
|
||||
public static function makeCorrectFile(string $filename): string
|
||||
{
|
||||
if (trim($filename) == '') {
|
||||
$error = 'Given filename for function ' . __FUNCTION__ . ' is empty.' . "\n";
|
||||
@@ -333,21 +321,19 @@ class FileDir
|
||||
$filename = '/' . $filename;
|
||||
}
|
||||
|
||||
$filename = self::makeSecurePath($filename);
|
||||
return $filename;
|
||||
return self::makeSecurePath($filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* checks a directory against disallowed paths which could
|
||||
* lead to a damaged system if you use them
|
||||
*
|
||||
* @param string $fieldname
|
||||
* @param array $fielddata
|
||||
* @param mixed $newfieldvalue
|
||||
* @param string|null $path
|
||||
*
|
||||
* @return boolean|array
|
||||
* @return bool
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function checkDisallowedPaths($path = null)
|
||||
public static function checkDisallowedPaths(string $path): bool
|
||||
{
|
||||
/*
|
||||
* disallow base-directories and /
|
||||
@@ -385,12 +371,11 @@ class FileDir
|
||||
/**
|
||||
* Function which returns a correct destination for Postfix Virtual Table
|
||||
*
|
||||
* @param
|
||||
* string The destinations
|
||||
* @param string $destination The destinations
|
||||
*
|
||||
* @return string the corrected destinations
|
||||
* @author Florian Lippert <flo@syscp.org> (2003-2009)
|
||||
*/
|
||||
public static function makeCorrectDestination($destination)
|
||||
public static function makeCorrectDestination(string $destination): string
|
||||
{
|
||||
$search = '/ +/';
|
||||
$replace = ' ';
|
||||
@@ -410,27 +395,25 @@ class FileDir
|
||||
/**
|
||||
* Returns a valid html tag for the chosen $fieldType for paths
|
||||
*
|
||||
* @param
|
||||
* string path The path to start searching in
|
||||
* @param
|
||||
* integer uid The uid which must match the found directories
|
||||
* @param
|
||||
* integer gid The gid which must match the found directories
|
||||
* @param
|
||||
* string value the value for the input-field
|
||||
* @param string $path The path to start searching in
|
||||
* @param int $uid The uid which must match the found directories
|
||||
* @param int $gid The gid which must match the found directories
|
||||
* @param string $value the value for the input-field
|
||||
* @param bool $dom
|
||||
*
|
||||
* @return string The html tag for the chosen $fieldType
|
||||
* @return array
|
||||
*
|
||||
* @author Martin Burchert <martin.burchert@syscp.de>
|
||||
* @throws Exception
|
||||
* @author Manuel Bernhardt <manuel.bernhardt@syscp.de>
|
||||
* @author Martin Burchert <martin.burchert@syscp.de>
|
||||
*/
|
||||
public static function makePathfield($path, $uid, $gid, $value = '', $dom = false)
|
||||
public static function makePathfield(string $path, int $uid, int $gid, string $value = '', bool $dom = false): array
|
||||
{
|
||||
$value = str_replace($path, '', $value);
|
||||
$field = [];
|
||||
|
||||
// path is given without starting slash
|
||||
// but dirList holds the paths with starting slash
|
||||
// but dirList holds the paths with starting slash,
|
||||
// so we just add one here to get the correct
|
||||
// default path selected, #225
|
||||
if (substr($value, 0, 1) != '/' && !$dom) {
|
||||
@@ -484,16 +467,14 @@ class FileDir
|
||||
* This function checks every found directory if they match either $uid or $gid, if they do
|
||||
* the found directory is valid. It uses recursive-iterators to find subdirectories.
|
||||
*
|
||||
* @param string $path
|
||||
* the path to start searching in
|
||||
* @param int $uid
|
||||
* the uid which must match the found directories
|
||||
* @param int $gid
|
||||
* the gid which must match the found directories
|
||||
* @param string $path the path to start searching in
|
||||
* @param int $uid the uid which must match the found directories
|
||||
* @param int $gid the gid which must match the found directories
|
||||
*
|
||||
* @return array Array of found valid paths
|
||||
* @throws Exception
|
||||
*/
|
||||
private static function findDirs($path, $uid, $gid)
|
||||
private static function findDirs(string $path, int $uid, int $gid): array
|
||||
{
|
||||
$_fileList = [];
|
||||
$path = self::makeCorrectDir($path);
|
||||
@@ -503,7 +484,8 @@ class FileDir
|
||||
// Will exclude everything under these directories
|
||||
$exclude = [
|
||||
'awstats',
|
||||
'webalizer'
|
||||
'webalizer',
|
||||
'goaccess'
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -569,7 +551,7 @@ class FileDir
|
||||
*
|
||||
* @return string functionname + parameter (not the file)
|
||||
*/
|
||||
private static function getImmutableFunction(bool $remove = false)
|
||||
private static function getImmutableFunction(bool $remove = false): string
|
||||
{
|
||||
if (self::isFreeBSD()) {
|
||||
// FreeBSD style
|
||||
@@ -589,7 +571,7 @@ class FileDir
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isFreeBSD(bool $exact = false)
|
||||
public static function isFreeBSD(bool $exact = false): bool
|
||||
{
|
||||
if (($exact && PHP_OS == 'FreeBSD') || (!$exact && stristr(PHP_OS, 'BSD'))) {
|
||||
return true;
|
||||
|
||||
@@ -45,7 +45,7 @@ final class Froxlor
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getInstallDir()
|
||||
public static function getInstallDir(): string
|
||||
{
|
||||
return dirname(__DIR__, 2) . '/';
|
||||
}
|
||||
@@ -55,7 +55,7 @@ final class Froxlor
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getVersion()
|
||||
public static function getVersion(): string
|
||||
{
|
||||
return self::VERSION;
|
||||
}
|
||||
@@ -65,7 +65,7 @@ final class Froxlor
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getVersionString()
|
||||
public static function getVersionString(): string
|
||||
{
|
||||
return self::getFullVersion() . ' (' . self::DBVERSION . ')';
|
||||
}
|
||||
@@ -75,7 +75,7 @@ final class Froxlor
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getFullVersion()
|
||||
public static function getFullVersion(): string
|
||||
{
|
||||
return self::VERSION . self::BRANDING;
|
||||
}
|
||||
@@ -85,12 +85,11 @@ final class Froxlor
|
||||
*
|
||||
* checks if a given version is not equal the current one
|
||||
*
|
||||
* @param string $to_check
|
||||
* version to check, if empty current version is used
|
||||
* @param string $to_check version to check, if empty current version is used
|
||||
*
|
||||
* @return bool true if version to check does not match, else false
|
||||
*/
|
||||
public static function hasUpdates($to_check = null)
|
||||
public static function hasUpdates(string $to_check): bool
|
||||
{
|
||||
if (empty($to_check)) {
|
||||
$to_check = self::VERSION;
|
||||
@@ -102,16 +101,15 @@ final class Froxlor
|
||||
}
|
||||
|
||||
/**
|
||||
* Function hasUpdates
|
||||
* Function hasDbUpdates
|
||||
*
|
||||
* checks if a given database-version is not equal the current one
|
||||
*
|
||||
* @param int $to_check
|
||||
* version to check, if empty current dbversion is used
|
||||
* @param string $to_check version to check, if empty current dbversion is used
|
||||
*
|
||||
* @return bool true if version to check does not match, else false
|
||||
*/
|
||||
public static function hasDbUpdates($to_check = null)
|
||||
public static function hasDbUpdates(string $to_check): bool
|
||||
{
|
||||
if (empty($to_check)) {
|
||||
$to_check = self::DBVERSION;
|
||||
@@ -127,12 +125,11 @@ final class Froxlor
|
||||
*
|
||||
* checks if a given database-version is the current one
|
||||
*
|
||||
* @param int $to_check
|
||||
* version to check
|
||||
* @param string $to_check version to check
|
||||
*
|
||||
* @return bool true if version to check matches, else false
|
||||
*/
|
||||
public static function isDatabaseVersion($to_check = null)
|
||||
public static function isDatabaseVersion(string $to_check): bool
|
||||
{
|
||||
if (Settings::Get('panel.frontend') == 'froxlor' && Settings::Get('panel.db_version') == $to_check) {
|
||||
return true;
|
||||
@@ -146,14 +143,14 @@ final class Froxlor
|
||||
* updates the panel.version field
|
||||
* to the given value (no checks here!)
|
||||
*
|
||||
* @param string $new_version
|
||||
* new-version
|
||||
* @param string $new_version new-version
|
||||
*
|
||||
* @return bool true on success, else false
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function updateToDbVersion($new_version = null)
|
||||
public static function updateToDbVersion(string $new_version): bool
|
||||
{
|
||||
if ($new_version !== null && $new_version != '') {
|
||||
if ($new_version != '') {
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_SETTINGS . "` SET `value` = :newversion
|
||||
WHERE `settinggroup` = 'panel' AND `varname` = 'db_version'");
|
||||
@@ -172,14 +169,14 @@ final class Froxlor
|
||||
* updates the panel.version field
|
||||
* to the given value (no checks here!)
|
||||
*
|
||||
* @param string $new_version
|
||||
* new-version
|
||||
* @param string $new_version new-version
|
||||
*
|
||||
* @return bool true on success, else false
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function updateToVersion($new_version = null)
|
||||
public static function updateToVersion(string $new_version): bool
|
||||
{
|
||||
if ($new_version !== null && $new_version != '') {
|
||||
if ($new_version != '') {
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_SETTINGS . "` SET `value` = :newversion
|
||||
WHERE `settinggroup` = 'panel' AND `varname` = 'version'");
|
||||
@@ -199,7 +196,7 @@ final class Froxlor
|
||||
*
|
||||
* @return bool true if panel is froxlor, else false
|
||||
*/
|
||||
public static function isFroxlor()
|
||||
public static function isFroxlor(): bool
|
||||
{
|
||||
if (Settings::Get('panel.frontend') !== null && Settings::Get('panel.frontend') == 'froxlor') {
|
||||
return true;
|
||||
@@ -213,12 +210,11 @@ final class Froxlor
|
||||
* checks if a given version is the
|
||||
* current one (and panel is froxlor)
|
||||
*
|
||||
* @param string $to_check
|
||||
* version to check
|
||||
* @param string $to_check version to check
|
||||
*
|
||||
* @return bool true if version to check matches, else false
|
||||
*/
|
||||
public static function isFroxlorVersion($to_check = null)
|
||||
public static function isFroxlorVersion(string $to_check): bool
|
||||
{
|
||||
if (Settings::Get('panel.frontend') == 'froxlor' && Settings::Get('panel.version') == $to_check) {
|
||||
return true;
|
||||
@@ -231,10 +227,11 @@ final class Froxlor
|
||||
*
|
||||
* @param int $length
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function genSessionId(int $length = 16)
|
||||
public static function genSessionId(int $length = 16): string
|
||||
{
|
||||
if (intval($length) <= 8) {
|
||||
if ($length <= 8) {
|
||||
$length = 16;
|
||||
}
|
||||
if (function_exists('random_bytes')) {
|
||||
@@ -256,9 +253,9 @@ final class Froxlor
|
||||
* @param string $a
|
||||
* @param string $b
|
||||
*
|
||||
* @return integer 0 if equal, 1 if a>b and -1 if b>a
|
||||
* @return int 0 if equal, 1 if a>b and -1 if b>a
|
||||
*/
|
||||
public static function versionCompare2($a, $b)
|
||||
public static function versionCompare2(string $a, string $b): int
|
||||
{
|
||||
// split version into pieces and remove trailing .0
|
||||
$a = explode(".", $a);
|
||||
@@ -295,7 +292,11 @@ final class Froxlor
|
||||
return (count($a) < count($b)) ? -1 : 0;
|
||||
}
|
||||
|
||||
private static function parseVersionArray(&$arr = null)
|
||||
/**
|
||||
* @param array|null $arr
|
||||
* @return void
|
||||
*/
|
||||
private static function parseVersionArray(array &$arr = null)
|
||||
{
|
||||
// -dev or -beta or -rc ?
|
||||
if (stripos($arr[count($arr) - 1], '-') !== false) {
|
||||
@@ -306,16 +307,20 @@ final class Froxlor
|
||||
$arr[] = '2'; // dev < beta < rc
|
||||
// number of rc
|
||||
$arr[] = substr($x[1], 2);
|
||||
} else if (stripos($x[1], 'beta') !== false) {
|
||||
$arr[] = '-1';
|
||||
$arr[] = '1'; // dev < beta < rc
|
||||
// number of beta
|
||||
$arr[] = substr($x[1], 3);
|
||||
} else if (stripos($x[1], 'dev') !== false) {
|
||||
$arr[] = '-1';
|
||||
$arr[] = '0'; // dev < beta < rc
|
||||
// number of dev
|
||||
$arr[] = substr($x[1], 3);
|
||||
} else {
|
||||
if (stripos($x[1], 'beta') !== false) {
|
||||
$arr[] = '-1';
|
||||
$arr[] = '1'; // dev < beta < rc
|
||||
// number of beta
|
||||
$arr[] = substr($x[1], 3);
|
||||
} else {
|
||||
if (stripos($x[1], 'dev') !== false) {
|
||||
$arr[] = '-1';
|
||||
$arr[] = '0'; // dev < beta < rc
|
||||
// number of dev
|
||||
$arr[] = substr($x[1], 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,38 +45,42 @@ class FroxlorLogger
|
||||
/**
|
||||
* current \Monolog\Logger object
|
||||
*
|
||||
* @var Logger
|
||||
* @var ?Logger
|
||||
*/
|
||||
private static $ml = null;
|
||||
private static ?Logger $ml = null;
|
||||
/**
|
||||
* LogTypes Array
|
||||
*
|
||||
* @var array
|
||||
* @var ?array
|
||||
*/
|
||||
private static $logtypes = null;
|
||||
private static ?array $logtypes = null;
|
||||
/**
|
||||
* whether to output log-messages to STDOUT (cron)
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private static $crondebug_flag = false;
|
||||
private static bool $crondebug_flag = false;
|
||||
/**
|
||||
* user info of logged in user
|
||||
* user info of logged-in user
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $userinfo = [];
|
||||
private static array $userinfo = [];
|
||||
/**
|
||||
* whether the logger object has already been initialized
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private static $is_initialized = false;
|
||||
private static bool $is_initialized = false;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param array $userinfo
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function __construct($userinfo = [])
|
||||
protected function __construct(array $userinfo = [])
|
||||
{
|
||||
$this->initMonolog();
|
||||
self::$userinfo = $userinfo;
|
||||
@@ -143,8 +147,9 @@ class FroxlorLogger
|
||||
* @param array $userinfo
|
||||
*
|
||||
* @return FroxlorLogger
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function getInstanceOf($userinfo = [])
|
||||
public static function getInstanceOf(array $userinfo = [])
|
||||
{
|
||||
if (empty($userinfo)) {
|
||||
$userinfo = [
|
||||
@@ -159,9 +164,9 @@ class FroxlorLogger
|
||||
*
|
||||
* @param int $action
|
||||
* @param int $type
|
||||
* @param string $text
|
||||
* @param ?string $text
|
||||
*/
|
||||
public function logAction($action = FroxlorLogger::USR_ACTION, $type = LOG_NOTICE, $text = null)
|
||||
public function logAction($action = FroxlorLogger::USR_ACTION, int $type = LOG_NOTICE, string $text = null)
|
||||
{
|
||||
// not logging normal stuff if not set to "paranoid" logging
|
||||
if (!self::$crondebug_flag && Settings::Get('logger.severity') == '1' && $type > LOG_NOTICE) {
|
||||
@@ -208,7 +213,11 @@ class FroxlorLogger
|
||||
}
|
||||
}
|
||||
|
||||
public function getLogLevelDesc($type)
|
||||
/**
|
||||
* @param int $type
|
||||
* @return string
|
||||
*/
|
||||
public function getLogLevelDesc(int $type): string
|
||||
{
|
||||
switch ($type) {
|
||||
case LOG_INFO:
|
||||
@@ -236,7 +245,11 @@ class FroxlorLogger
|
||||
return $_type;
|
||||
}
|
||||
|
||||
private function getActionTypeDesc($action)
|
||||
/**
|
||||
* @param $action
|
||||
* @return string
|
||||
*/
|
||||
private function getActionTypeDesc($action): string
|
||||
{
|
||||
switch ($action) {
|
||||
case FroxlorLogger::USR_ACTION:
|
||||
@@ -268,7 +281,7 @@ class FroxlorLogger
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function setCronLog(int $cronlog = 0)
|
||||
public function setCronLog(int $cronlog = 0): int
|
||||
{
|
||||
if ($cronlog < 0 || $cronlog > 2) {
|
||||
$cronlog = 0;
|
||||
|
||||
@@ -47,15 +47,17 @@ class Directory
|
||||
*
|
||||
* @param string $dir
|
||||
*/
|
||||
public function __construct($dir = null)
|
||||
public function __construct(string $dir = null)
|
||||
{
|
||||
$this->dir = $dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* check whether the directory has options set in panel_htaccess
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasUserOptions()
|
||||
public function hasUserOptions(): bool
|
||||
{
|
||||
$uo_stmt = Database::prepare("
|
||||
SELECT COUNT(`id`) as `usropts` FROM `" . TABLE_PANEL_HTACCESS . "` WHERE `path` = :dir
|
||||
@@ -63,7 +65,7 @@ class Directory
|
||||
$uo_res = Database::pexecute_first($uo_stmt, [
|
||||
'dir' => FileDir::makeCorrectDir($this->dir)
|
||||
]);
|
||||
if ($uo_res != false && isset($uo_res['usropts'])) {
|
||||
if ($uo_res && isset($uo_res['usropts'])) {
|
||||
return $uo_res['usropts'] > 0;
|
||||
}
|
||||
return false;
|
||||
@@ -71,8 +73,10 @@ class Directory
|
||||
|
||||
/**
|
||||
* check whether the directory is protected using panel_htpasswd
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isUserProtected()
|
||||
public function isUserProtected(): bool
|
||||
{
|
||||
$up_stmt = Database::prepare("
|
||||
SELECT COUNT(`id`) as `usrprot` FROM `" . TABLE_PANEL_HTPASSWDS . "` WHERE `path` = :dir
|
||||
@@ -80,7 +84,7 @@ class Directory
|
||||
$up_res = Database::pexecute_first($up_stmt, [
|
||||
'dir' => FileDir::makeCorrectDir($this->dir)
|
||||
]);
|
||||
if ($up_res != false && isset($up_res['usrprot'])) {
|
||||
if ($up_res && isset($up_res['usrprot'])) {
|
||||
return $up_res['usrprot'] > 0;
|
||||
}
|
||||
return false;
|
||||
@@ -90,12 +94,11 @@ class Directory
|
||||
* Checks if a given directory is valid for multiple configurations
|
||||
* or should rather be used as a single file
|
||||
*
|
||||
* @param bool $ifexists
|
||||
* also check whether file/dir exists
|
||||
* @param bool $ifexists also check whether file/dir exists
|
||||
*
|
||||
* @return bool true if usable as dir, false otherwise
|
||||
*/
|
||||
public function isConfigDir($ifexists = false)
|
||||
public function isConfigDir(bool $ifexists = false): bool
|
||||
{
|
||||
if (is_null($this->dir)) {
|
||||
trigger_error(__CLASS__ . '::' . __FUNCTION__ . ' has been called with a null value', E_USER_WARNING);
|
||||
|
||||
@@ -33,6 +33,10 @@ class HttpClient
|
||||
/**
|
||||
* Executes simple GET request
|
||||
*
|
||||
* @param string $url
|
||||
* @param bool $follow_location
|
||||
* @param int $timeout
|
||||
*
|
||||
* @return bool|string
|
||||
* @throws Exception
|
||||
*/
|
||||
@@ -59,6 +63,10 @@ class HttpClient
|
||||
/**
|
||||
* Downloads and stores a file from an url
|
||||
*
|
||||
* @param string $url
|
||||
* @param string $target
|
||||
*
|
||||
* @return bool|string
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function fileGet(string $url, string $target)
|
||||
|
||||
@@ -37,7 +37,7 @@ class PhpConfig
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getPhpConfigs()
|
||||
public static function getPhpConfigs(): array
|
||||
{
|
||||
$configs_array = [];
|
||||
|
||||
|
||||
@@ -36,16 +36,22 @@ class Statistics
|
||||
* Create or modify the AWStats configuration file for the given domain.
|
||||
* Modified by Berend Dekens to allow custom configurations.
|
||||
*
|
||||
* @param
|
||||
* logFile
|
||||
* @param
|
||||
* siteDomain
|
||||
* @param
|
||||
* hostAliases
|
||||
* @param string $logFile
|
||||
* @param string $siteDomain
|
||||
* @param string $hostAliases
|
||||
* @param string $customerDocroot
|
||||
* @param array $domain_data
|
||||
*
|
||||
* @return null
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function createAWStatsConf($logFile, $siteDomain, $hostAliases, $customerDocroot, $awstats_params = [])
|
||||
{
|
||||
public static function createAWStatsConf(
|
||||
string $logFile,
|
||||
string $siteDomain,
|
||||
string $hostAliases,
|
||||
string $customerDocroot,
|
||||
array $domain_data = []
|
||||
) {
|
||||
// Generation header
|
||||
$header = "## GENERATED BY FROXLOR\n";
|
||||
$header2 = "## Do not remove the line above! This tells Froxlor to update this configuration\n## If you wish to manually change this configuration file, remove the first line to make sure Froxlor won't rebuild this file\n## Generated for domain {SITE_DOMAIN} on " . date('l dS \of F Y h:i:s A') . "\n";
|
||||
@@ -55,7 +61,7 @@ class Statistics
|
||||
FileDir::safe_exec('mkdir -p ' . escapeshellarg($awstats_dir));
|
||||
}
|
||||
// chown created folder, #258
|
||||
self::makeChownWithNewStats($awstats_params);
|
||||
self::makeChownWithNewStats($domain_data);
|
||||
|
||||
// weird but could happen...
|
||||
if (!is_dir(Settings::Get('system.awstats_conf'))) {
|
||||
@@ -127,16 +133,15 @@ class Statistics
|
||||
}
|
||||
|
||||
/**
|
||||
* chowns either awstats or webalizer folder,
|
||||
* either with webserver-user or - if fcgid
|
||||
* is used - the customers name, #258
|
||||
* chowns stats-tools folder, either with webserver-user or
|
||||
* if fcgid/php-fpm is used, the customers name, #258
|
||||
*
|
||||
* @param array $row
|
||||
* array if panel_customers
|
||||
* @param array $row array of panel_customers
|
||||
*
|
||||
* @return void
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function makeChownWithNewStats($row)
|
||||
public static function makeChownWithNewStats(array $row)
|
||||
{
|
||||
// get correct user
|
||||
if ((Settings::Get('system.mod_fcgid') == '1' || Settings::Get('phpfpm.enabled') == '1') && isset($row['deactivated']) && $row['deactivated'] == '0') {
|
||||
|
||||
@@ -54,16 +54,15 @@ class IdnaWrapper
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode a domain name, a email address or a list of one of both.
|
||||
* Encode a domain name, an email address or a list of one of both.
|
||||
*
|
||||
* @param
|
||||
* string May be either a single domain name, e single email address or a list of one
|
||||
* @param string $to_encode May be either a single domain name, e single email address or a list of one
|
||||
* separated either by ',', ';' or ' '.
|
||||
*
|
||||
* @return string Returns either a single domain name, a single email address or a list of one of
|
||||
* both separated by the same string as the input.
|
||||
*/
|
||||
public function encode($to_encode)
|
||||
public function encode(string $to_encode): string
|
||||
{
|
||||
$to_encode = $this->isUtf8($to_encode) ? $to_encode : utf8_encode($to_encode);
|
||||
try {
|
||||
@@ -83,7 +82,7 @@ class IdnaWrapper
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
private function isUtf8($string = null)
|
||||
private function isUtf8(string $string)
|
||||
{
|
||||
if (function_exists("mb_detect_encoding")) {
|
||||
if (mb_detect_encoding($string, 'UTF-8, ISO-8859-1') === 'UTF-8') {
|
||||
@@ -119,16 +118,15 @@ class IdnaWrapper
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a domain name, a email address or a list of one of both.
|
||||
* Decode a domain name, an email address or a list of one of both.
|
||||
*
|
||||
* @param
|
||||
* string May be either a single domain name, e single email address or a list of one
|
||||
* @param string $to_decode May be either a single domain name, e single email address or a list of one
|
||||
* separated either by ',', ';' or ' '.
|
||||
*
|
||||
* @return string Returns either a single domain name, a single email address or a list of one of
|
||||
* both separated by the same string as the input.
|
||||
*/
|
||||
public function decode($to_decode)
|
||||
public function decode(string $to_decode): string
|
||||
{
|
||||
return $this->idna_converter->decode($to_decode);
|
||||
}
|
||||
|
||||
@@ -43,9 +43,9 @@ class PhpHelper
|
||||
* @param array $list
|
||||
* @param string $key
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public static function sortListBy(&$list, $key = 'id')
|
||||
public static function sortListBy(array &$list, string $key = 'id'): bool
|
||||
{
|
||||
self::$sort_type = Settings::Get('panel.natsorting') == 1 ? SORT_NATURAL : SORT_STRING;
|
||||
self::$sort_key = $key;
|
||||
@@ -59,14 +59,10 @@ class PhpHelper
|
||||
* Wrapper around htmlentities to handle arrays, with the advantage that you
|
||||
* can select which fields should be handled by htmlentities
|
||||
*
|
||||
* @param array|string $subject
|
||||
* The subject array
|
||||
* @param string $fields
|
||||
* The fields which should be checked for, separated by spaces
|
||||
* @param int $quote_style
|
||||
* See php documentation about this
|
||||
* @param string $charset
|
||||
* See php documentation about this
|
||||
* @param array|string $subject The subject array
|
||||
* @param array|string $fields The fields which should be checked for, separated by spaces
|
||||
* @param int $quote_style See php documentation about this
|
||||
* @param string $charset See php documentation about this
|
||||
*
|
||||
* @return array|string The string or an array with htmlentities converted strings
|
||||
* @author Florian Lippert <flo@syscp.org> (2003-2009)
|
||||
@@ -79,7 +75,7 @@ class PhpHelper
|
||||
}
|
||||
|
||||
foreach ($subject as $field => $value) {
|
||||
if ((!is_array($fields) || empty($fields)) || (is_array($fields) && !empty($fields) && in_array($field, $fields))) {
|
||||
if ((!is_array($fields) || empty($fields)) || (in_array($field, $fields))) {
|
||||
// Just call ourselve to manage multi-dimensional arrays
|
||||
$subject[$field] = self::htmlentitiesArray($value, $fields, $quote_style, $charset);
|
||||
}
|
||||
@@ -94,45 +90,36 @@ class PhpHelper
|
||||
/**
|
||||
* Returns array with all empty-values removed
|
||||
*
|
||||
* @param array $source
|
||||
* The array to trim
|
||||
* @param array $source The array to trim
|
||||
* @return array The trim'med array
|
||||
*/
|
||||
public static function arrayTrim($source)
|
||||
public static function arrayTrim(array $source): array
|
||||
{
|
||||
$returnval = [];
|
||||
if (is_array($source)) {
|
||||
$source = array_map('trim', $source);
|
||||
$returnval = array_filter($source, function ($value) {
|
||||
return $value !== '';
|
||||
});
|
||||
} else {
|
||||
$returnval = $source;
|
||||
}
|
||||
return $returnval;
|
||||
$source = array_map('trim', $source);
|
||||
return array_filter($source, function ($value) {
|
||||
return $value !== '';
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces Strings in an array, with the advantage that you
|
||||
* can select which fields should be str_replace'd
|
||||
*
|
||||
* @param string|array $search
|
||||
* String or array of strings to search for
|
||||
* @param string|array $reaplce
|
||||
* String or array to replace with
|
||||
* @param string|array $subject
|
||||
* String or array The subject array
|
||||
* @param string $fields
|
||||
* string The fields which should be checked for, separated by spaces
|
||||
* @param string|array $search String or array of strings to search for
|
||||
* @param string|array $replace String or array to replace with
|
||||
* @param string|array $subject String or array The subject array
|
||||
* @param string|array $fields string The fields which should be checked for, separated by spaces
|
||||
*
|
||||
* @return string|array The str_replace'd array
|
||||
* @author Florian Lippert <flo@syscp.org> (2003-2009)
|
||||
*/
|
||||
public static function strReplaceArray($search, $replace, $subject, $fields = '')
|
||||
{
|
||||
if (is_array($subject)) {
|
||||
$fields = self::arrayTrim(explode(' ', $fields));
|
||||
if (!is_array($fields)) {
|
||||
$fields = self::arrayTrim(explode(' ', $fields));
|
||||
}
|
||||
foreach ($subject as $field => $value) {
|
||||
if ((!is_array($fields) || empty($fields)) || (is_array($fields) && !empty($fields) && in_array($field, $fields))) {
|
||||
if ((!is_array($fields) || empty($fields)) || (in_array($field, $fields))) {
|
||||
$subject[$field] = str_replace($search, $replace, $value);
|
||||
}
|
||||
}
|
||||
@@ -177,7 +164,8 @@ class PhpHelper
|
||||
$err_display .= '<br><p><pre>';
|
||||
$debug = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
|
||||
foreach ($debug as $dline) {
|
||||
$err_display .= $dline['function'] . '() called at [' . str_replace(Froxlor::getInstallDir(), '', ($dline['file'] ?? 'unknown')) . ':' . ($dline['line'] ?? 0) . ']<br>';
|
||||
$err_display .= $dline['function'] . '() called at [' . str_replace(Froxlor::getInstallDir(), '',
|
||||
($dline['file'] ?? 'unknown')) . ':' . ($dline['line'] ?? 0) . ']<br>';
|
||||
}
|
||||
$err_display .= '</pre></p>';
|
||||
// end later
|
||||
@@ -193,9 +181,13 @@ class PhpHelper
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Throwable $exception
|
||||
* @return void
|
||||
*/
|
||||
public static function phpExceptionHandler(Throwable $exception)
|
||||
{
|
||||
if (!isset($_SERVER['SHELL']) || (isset($_SERVER['SHELL']) && $_SERVER['SHELL'] == '')) {
|
||||
if (!isset($_SERVER['SHELL']) || $_SERVER['SHELL'] == '') {
|
||||
// show
|
||||
UI::initTwig(true);
|
||||
UI::twig()->addGlobal('install_mode', '1');
|
||||
@@ -210,6 +202,10 @@ class PhpHelper
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ...$configdirs
|
||||
* @return array|null
|
||||
*/
|
||||
public static function loadConfigArrayDir(...$configdirs)
|
||||
{
|
||||
if (count($configdirs) <= 0) {
|
||||
@@ -224,7 +220,8 @@ class PhpHelper
|
||||
if (is_dir($data_dirname)) {
|
||||
$data_dirhandle = opendir($data_dirname);
|
||||
while (false !== ($data_filename = readdir($data_dirhandle))) {
|
||||
if ($data_filename != '.' && $data_filename != '..' && $data_filename != '' && substr($data_filename, -4) == '.php') {
|
||||
if ($data_filename != '.' && $data_filename != '..' && $data_filename != '' && substr($data_filename,
|
||||
-4) == '.php') {
|
||||
$data_files[] = $data_dirname . $data_filename;
|
||||
}
|
||||
}
|
||||
@@ -248,7 +245,7 @@ class PhpHelper
|
||||
* @param string $host
|
||||
* @param boolean $try_a default true
|
||||
* @param string|null $nameserver set additional resolver nameserver to use (e.g. 1.1.1.1)
|
||||
* @return boolean|array
|
||||
* @return bool|array
|
||||
*/
|
||||
public static function gethostbynamel6(string $host, bool $try_a = true, string $nameserver = null)
|
||||
{
|
||||
@@ -315,7 +312,7 @@ class PhpHelper
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function randomStr($length)
|
||||
public static function randomStr(int $length): string
|
||||
{
|
||||
if (function_exists('openssl_random_pseudo_bytes')) {
|
||||
return openssl_random_pseudo_bytes($length);
|
||||
@@ -324,20 +321,21 @@ class PhpHelper
|
||||
}
|
||||
|
||||
/**
|
||||
* Return human readable sizes
|
||||
* Return human-readable sizes
|
||||
*
|
||||
* @param int $size
|
||||
* size in bytes
|
||||
* @param string $max
|
||||
* maximum unit
|
||||
* @param string $system
|
||||
* 'si' for SI, 'bi' for binary prefixes
|
||||
* @param int $size size in bytes
|
||||
* @param string $max maximum unit
|
||||
* @param string $system 'si' for SI, 'bi' for binary prefixes
|
||||
* @param string $retstring string-format
|
||||
*
|
||||
* @param string $retstring
|
||||
* string
|
||||
* @return string
|
||||
*/
|
||||
public static function sizeReadable($size, $max = null, $system = 'si', $retstring = '%01.2f %s')
|
||||
{
|
||||
public static function sizeReadable(
|
||||
int $size,
|
||||
string $max = '',
|
||||
string $system = 'si',
|
||||
string $retstring = '%01.2f %s'
|
||||
): string {
|
||||
// Pick units
|
||||
$systems = [
|
||||
'si' => [
|
||||
@@ -363,7 +361,7 @@ class PhpHelper
|
||||
'size' => 1024
|
||||
]
|
||||
];
|
||||
$sys = isset($systems[$system]) ? $systems[$system] : $systems['si'];
|
||||
$sys = $systems[$system] ?? $systems['si'];
|
||||
|
||||
// Max unit to display
|
||||
$depth = count($sys['prefix']) - 1;
|
||||
@@ -384,14 +382,12 @@ class PhpHelper
|
||||
* Replaces all occurrences of variables defined in the second argument
|
||||
* in the first argument with their values.
|
||||
*
|
||||
* @param string $text
|
||||
* The string that should be searched for variables
|
||||
* @param array $vars
|
||||
* The array containing the variables with their values
|
||||
* @param string $text The string that should be searched for variables
|
||||
* @param array $vars The array containing the variables with their values
|
||||
*
|
||||
* @return string The submitted string with the variables replaced.
|
||||
*/
|
||||
public static function replaceVariables($text, $vars)
|
||||
public static function replaceVariables(string $text, array $vars): string
|
||||
{
|
||||
$pattern = "/\{([a-zA-Z0-9\-_]+)\}/";
|
||||
$matches = [];
|
||||
@@ -407,12 +403,22 @@ class PhpHelper
|
||||
}
|
||||
}
|
||||
|
||||
$text = str_replace('\n', "\n", $text);
|
||||
return $text;
|
||||
return str_replace('\n', "\n", $text);
|
||||
}
|
||||
|
||||
public static function recursive_array_search($needle, $haystack, &$keys = [], $currentKey = '')
|
||||
{
|
||||
/**
|
||||
* @param string $needle
|
||||
* @param array $haystack
|
||||
* @param array $keys
|
||||
* @param string $currentKey
|
||||
* @return true
|
||||
*/
|
||||
public static function recursive_array_search(
|
||||
string $needle,
|
||||
array $haystack,
|
||||
array &$keys = [],
|
||||
string $currentKey = ''
|
||||
): bool {
|
||||
foreach ($haystack as $key => $value) {
|
||||
$pathkey = empty($currentKey) ? $key : $currentKey . '.' . $key;
|
||||
if (is_array($value)) {
|
||||
@@ -427,13 +433,13 @@ class PhpHelper
|
||||
}
|
||||
|
||||
/**
|
||||
* function to check a super-global passed by reference
|
||||
* function to check a super-global passed by reference,
|
||||
* so it gets automatically updated
|
||||
*
|
||||
* @param array $global
|
||||
* @param AntiXSS $antiXss
|
||||
*/
|
||||
public static function cleanGlobal(&$global, &$antiXss)
|
||||
public static function cleanGlobal(array &$global, AntiXSS &$antiXss)
|
||||
{
|
||||
$ignored_fields = [
|
||||
'system_default_vhostconf',
|
||||
@@ -455,7 +461,12 @@ class PhpHelper
|
||||
}
|
||||
}
|
||||
|
||||
private static function sortListByGivenKey($a, $b): int
|
||||
/**
|
||||
* @param array $a
|
||||
* @param array $b
|
||||
* @return int
|
||||
*/
|
||||
private static function sortListByGivenKey(array $a, array $b): int
|
||||
{
|
||||
if (self::$sort_type == SORT_NATURAL) {
|
||||
return strnatcasecmp($a[self::$sort_key], $b[self::$sort_key]);
|
||||
@@ -488,35 +499,33 @@ class PhpHelper
|
||||
/**
|
||||
* Parse array to array string.
|
||||
*
|
||||
* @param $array
|
||||
* @param $key
|
||||
* @param array $array
|
||||
* @param ?string $key
|
||||
* @param int $depth
|
||||
* @return string
|
||||
*/
|
||||
public static function parseArrayToString($array, $key = null, int $depth = 1): string
|
||||
public static function parseArrayToString(array $array, string $key = null, int $depth = 1): string
|
||||
{
|
||||
$str = '';
|
||||
if (is_array($array)) {
|
||||
if (!is_null($key)) {
|
||||
$str .= self::tabPrefix(($depth-1), "'{$key}' => [\n");
|
||||
} else {
|
||||
$str .= self::tabPrefix(($depth-1), "[\n");
|
||||
}
|
||||
foreach ($array as $key => $value) {
|
||||
if (!is_array($value)) {
|
||||
if (is_bool($value)) {
|
||||
$str .= self::tabPrefix($depth, sprintf("'%s' => %s,\n", $key, $value ? 'true' : 'false'));
|
||||
} elseif (is_int($value)) {
|
||||
$str .= self::tabPrefix($depth, "'{$key}' => $value,\n");
|
||||
} else {
|
||||
$str .= self::tabPrefix($depth, "'{$key}' => '{$value}',\n");
|
||||
}
|
||||
} elseif (is_array($value)) {
|
||||
$str .= self::parseArrayToString($value, $key, ($depth + 1));
|
||||
}
|
||||
}
|
||||
$str .= self::tabPrefix(($depth-1), "],\n");
|
||||
if (!is_null($key)) {
|
||||
$str .= self::tabPrefix(($depth - 1), "'{$key}' => [\n");
|
||||
} else {
|
||||
$str .= self::tabPrefix(($depth - 1), "[\n");
|
||||
}
|
||||
foreach ($array as $key => $value) {
|
||||
if (!is_array($value)) {
|
||||
if (is_bool($value)) {
|
||||
$str .= self::tabPrefix($depth, sprintf("'%s' => %s,\n", $key, $value ? 'true' : 'false'));
|
||||
} elseif (is_int($value)) {
|
||||
$str .= self::tabPrefix($depth, "'{$key}' => $value,\n");
|
||||
} else {
|
||||
$str .= self::tabPrefix($depth, "'{$key}' => '{$value}',\n");
|
||||
}
|
||||
} else {
|
||||
$str .= self::parseArrayToString($value, $key, ($depth + 1));
|
||||
}
|
||||
}
|
||||
$str .= self::tabPrefix(($depth - 1), "],\n");
|
||||
return $str;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,10 +30,19 @@ use Froxlor\Database\Database;
|
||||
class FroxlorVhostSettings
|
||||
{
|
||||
|
||||
public static function hasVhostContainerEnabled($need_ssl = false)
|
||||
/**
|
||||
* @param bool $need_ssl
|
||||
*
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function hasVhostContainerEnabled(bool $need_ssl = false): bool
|
||||
{
|
||||
$sel_stmt = Database::prepare("SELECT COUNT(*) as vcentries FROM `" . TABLE_PANEL_IPSANDPORTS . "` WHERE `vhostcontainer`= '1'" . ($need_ssl ? " AND `ssl` = '1'" : ""));
|
||||
$result = Database::pexecute_first($sel_stmt);
|
||||
return $result['vcentries'] > 0;
|
||||
if ($result) {
|
||||
return $result['vcentries'] > 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,32 +100,34 @@ class Cronjob
|
||||
|
||||
// now check if it differs from our settings
|
||||
if ($update_to_guid != Settings::Get('system.lastguid')) {
|
||||
$mylog->logAction(FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Updating froxlor last guid to ' . $update_to_guid);
|
||||
$mylog->logAction(FroxlorLogger::CRON_ACTION, LOG_NOTICE,
|
||||
'Updating froxlor last guid to ' . $update_to_guid);
|
||||
Settings::Set('system.lastguid', $update_to_guid);
|
||||
}
|
||||
} else {
|
||||
$mylog->logAction(FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'File /etc/group not readable; cannot check for latest guid');
|
||||
$mylog->logAction(FroxlorLogger::CRON_ACTION, LOG_NOTICE,
|
||||
'File /etc/group not readable; cannot check for latest guid');
|
||||
}
|
||||
} else {
|
||||
$mylog->logAction(FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'File /etc/group not readable; cannot check for latest guid');
|
||||
$mylog->logAction(FroxlorLogger::CRON_ACTION, LOG_NOTICE,
|
||||
'File /etc/group not readable; cannot check for latest guid');
|
||||
}
|
||||
} else {
|
||||
$mylog->logAction(FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'File /etc/group does not exist; cannot check for latest guid');
|
||||
$mylog->logAction(FroxlorLogger::CRON_ACTION, LOG_NOTICE,
|
||||
'File /etc/group does not exist; cannot check for latest guid');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a task into the PANEL_TASKS-Table
|
||||
*
|
||||
* @param
|
||||
* int Type of task
|
||||
* @param
|
||||
* string Parameter (possible to pass multiple times)
|
||||
* @param int $type Type of task
|
||||
* @param string $params Parameter (possible to pass multiple times)
|
||||
*
|
||||
* @author Florian Lippert <flo@syscp.org> (2003-2009)
|
||||
* @throws Exception
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
*/
|
||||
public static function inserttask($type, ...$params)
|
||||
public static function inserttask(int $type, ...$params)
|
||||
{
|
||||
// prepare the insert-statement
|
||||
$ins_stmt = Database::prepare("
|
||||
@@ -223,7 +225,7 @@ class Cronjob
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getCronjobsLastRun()
|
||||
public static function getCronjobsLastRun(): array
|
||||
{
|
||||
$query = "SELECT `lastrun`, `desc_lng_key` FROM `" . TABLE_PANEL_CRONRUNS . "` WHERE `isactive` = '1' ORDER BY `cronfile` ASC";
|
||||
$result = Database::query($query);
|
||||
@@ -238,14 +240,21 @@ class Cronjob
|
||||
return $cronjobs_last_run;
|
||||
}
|
||||
|
||||
public static function toggleCronStatus($module = null, $isactive = 0)
|
||||
/**
|
||||
* @param string $module
|
||||
* @param int $isactive
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function toggleCronStatus(string $module, int $isactive = 0)
|
||||
{
|
||||
if ($isactive != 1) {
|
||||
$isactive = 0;
|
||||
}
|
||||
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_CRONRUNS . "` SET `isactive` = :active WHERE `module` = :module");
|
||||
UPDATE `" . TABLE_PANEL_CRONRUNS . "` SET `isactive` = :active WHERE `module` = :module
|
||||
");
|
||||
Database::pexecute($upd_stmt, [
|
||||
'active' => $isactive,
|
||||
'module' => $module
|
||||
@@ -257,7 +266,7 @@ class Cronjob
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getOutstandingTasks()
|
||||
public static function getOutstandingTasks(): array
|
||||
{
|
||||
$query = "SELECT * FROM `" . TABLE_PANEL_TASKS . "` ORDER BY `type` ASC";
|
||||
$result = Database::query($query);
|
||||
@@ -309,7 +318,7 @@ class Cronjob
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function dieWithMail($message, $subject = "[froxlor] Cronjob error")
|
||||
public static function dieWithMail(string $message, string $subject = "[froxlor] Cronjob error")
|
||||
{
|
||||
if (Settings::Get('system.send_cron_errors') == '1') {
|
||||
$_mail = new Mailer(true);
|
||||
@@ -339,7 +348,12 @@ class Cronjob
|
||||
die($message);
|
||||
}
|
||||
|
||||
public static function updateLastRunOfCron($cronname)
|
||||
/**
|
||||
* @param string $cronname
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function updateLastRunOfCron(string $cronname)
|
||||
{
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_CRONRUNS . "` SET `lastrun` = UNIX_TIMESTAMP() WHERE `cronfile` = :cron;
|
||||
|
||||
@@ -41,7 +41,7 @@ class Crypt
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function generatePassword(int $length = 0, bool $isSalt = false)
|
||||
public static function generatePassword(int $length = 0, bool $isSalt = false): string
|
||||
{
|
||||
$alpha_lower = 'abcdefghijklmnopqrstuvwxyz';
|
||||
$alpha_upper = strtoupper($alpha_lower);
|
||||
@@ -78,7 +78,7 @@ class Crypt
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function specialShuffle($str = null)
|
||||
private static function specialShuffle(string $str): string
|
||||
{
|
||||
$len = mb_strlen($str);
|
||||
$sploded = [];
|
||||
@@ -94,7 +94,7 @@ class Crypt
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getAvailablePasswordHashes()
|
||||
public static function getAvailablePasswordHashes(): array
|
||||
{
|
||||
// get available pwd-hases
|
||||
$available_pwdhashes = [
|
||||
@@ -120,31 +120,40 @@ class Crypt
|
||||
* we check against the length, if not matched
|
||||
* an error message will be output and 'exit' is called
|
||||
*
|
||||
* @param string $password
|
||||
* the password to validate
|
||||
* @param string $password the password to validate
|
||||
* @param bool $json_response
|
||||
*
|
||||
* @return string either the password or an errormessage+exit
|
||||
*/
|
||||
public static function validatePassword($password = null, $json_response = false)
|
||||
public static function validatePassword(string $password, bool $json_response = false): string
|
||||
{
|
||||
if (Settings::Get('panel.password_min_length') > 0) {
|
||||
$password = Validate::validate($password, Settings::Get('panel.password_min_length'), '/^.{' . (int)Settings::Get('panel.password_min_length') . ',}$/D', 'notrequiredpasswordlength', [], $json_response);
|
||||
$password = Validate::validate($password, Settings::Get('panel.password_min_length'),
|
||||
'/^.{' . (int)Settings::Get('panel.password_min_length') . ',}$/D', 'notrequiredpasswordlength', [],
|
||||
$json_response);
|
||||
}
|
||||
|
||||
if (Settings::Get('panel.password_regex') != '') {
|
||||
$password = Validate::validate($password, Settings::Get('panel.password_regex'), Settings::Get('panel.password_regex'), 'notrequiredpasswordcomplexity', [], $json_response);
|
||||
$password = Validate::validate($password, Settings::Get('panel.password_regex'),
|
||||
Settings::Get('panel.password_regex'), 'notrequiredpasswordcomplexity', [], $json_response);
|
||||
} else {
|
||||
if (Settings::Get('panel.password_alpha_lower')) {
|
||||
$password = Validate::validate($password, '/.*[a-z]+.*/', '/.*[a-z]+.*/', 'notrequiredpasswordcomplexity', [], $json_response);
|
||||
$password = Validate::validate($password, '/.*[a-z]+.*/', '/.*[a-z]+.*/',
|
||||
'notrequiredpasswordcomplexity', [], $json_response);
|
||||
}
|
||||
if (Settings::Get('panel.password_alpha_upper')) {
|
||||
$password = Validate::validate($password, '/.*[A-Z]+.*/', '/.*[A-Z]+.*/', 'notrequiredpasswordcomplexity', [], $json_response);
|
||||
$password = Validate::validate($password, '/.*[A-Z]+.*/', '/.*[A-Z]+.*/',
|
||||
'notrequiredpasswordcomplexity', [], $json_response);
|
||||
}
|
||||
if (Settings::Get('panel.password_numeric')) {
|
||||
$password = Validate::validate($password, '/.*[0-9]+.*/', '/.*[0-9]+.*/', 'notrequiredpasswordcomplexity', [], $json_response);
|
||||
$password = Validate::validate($password, '/.*[0-9]+.*/', '/.*[0-9]+.*/',
|
||||
'notrequiredpasswordcomplexity', [], $json_response);
|
||||
}
|
||||
if (Settings::Get('panel.password_special_char_required')) {
|
||||
$password = Validate::validate($password, '/.*[' . preg_quote(Settings::Get('panel.password_special_char'), '/') . ']+.*/', '/.*[' . preg_quote(Settings::Get('panel.password_special_char'), '/') . ']+.*/', 'notrequiredpasswordcomplexity', [], $json_response);
|
||||
$password = Validate::validate($password,
|
||||
'/.*[' . preg_quote(Settings::Get('panel.password_special_char'), '/') . ']+.*/',
|
||||
'/.*[' . preg_quote(Settings::Get('panel.password_special_char'), '/') . ']+.*/',
|
||||
'notrequiredpasswordcomplexity', [], $json_response);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,19 +168,20 @@ class Crypt
|
||||
* additionally it updates the hash if the system settings changed
|
||||
* or if the very old md5() sum is used
|
||||
*
|
||||
* @param array $userinfo
|
||||
* user-data from table
|
||||
* @param string $password
|
||||
* the password to validate
|
||||
* @param string $table
|
||||
* either panel_customers or panel_admins
|
||||
* @param string $uid
|
||||
* user-id-field in $table
|
||||
* @param array $userinfo user-data from table
|
||||
* @param string $password the password to validate
|
||||
* @param string $table either panel_customers or panel_admins
|
||||
* @param string $uid user-id-field in $table
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function validatePasswordLogin($userinfo = null, $password = null, $table = 'panel_customers', $uid = 'customerid')
|
||||
{
|
||||
public static function validatePasswordLogin(
|
||||
array $userinfo,
|
||||
string $password,
|
||||
string $table = 'panel_customers',
|
||||
string $uid = 'customerid'
|
||||
): bool {
|
||||
$algo = Settings::Get('system.passwordcryptfunc') !== null ? Settings::Get('system.passwordcryptfunc') : PASSWORD_DEFAULT;
|
||||
if (is_numeric($algo)) {
|
||||
// old setting format
|
||||
@@ -209,16 +219,13 @@ class Crypt
|
||||
/**
|
||||
* Make encrypted password from clear text password
|
||||
*
|
||||
* @param string $password
|
||||
* Password to be encrypted
|
||||
* @param bool $htpasswd
|
||||
* optional whether to generate a SHA1 password for directory protection
|
||||
* @param bool $ftpd
|
||||
* optional generates sha256 password strings for proftpd/pureftpd
|
||||
* @param string $password Password to be encrypted
|
||||
* @param bool $htpasswd optional whether to generate a SHA1 password for directory protection
|
||||
* @param bool $ftpd optional generates sha256 password strings for proftpd/pureftpd
|
||||
*
|
||||
* @return string encrypted password
|
||||
*/
|
||||
public static function makeCryptPassword(string $password, bool $htpasswd = false, bool $ftpd = false)
|
||||
public static function makeCryptPassword(string $password, bool $htpasswd = false, bool $ftpd = false): string
|
||||
{
|
||||
if ($htpasswd || $ftpd) {
|
||||
if ($ftpd) {
|
||||
|
||||
@@ -36,7 +36,7 @@ class IPTools
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function cidr2NetmaskAddr($cidr)
|
||||
public static function cidr2NetmaskAddr(string $cidr): string
|
||||
{
|
||||
$ta = substr($cidr, strpos($cidr, '/') + 1) * 1;
|
||||
$netmask = str_split(str_pad(str_pad('', $ta, '1'), 32, '0'), 8);
|
||||
@@ -52,7 +52,7 @@ class IPTools
|
||||
* Checks whether the given $ip is in range of given ip/cidr range
|
||||
*
|
||||
* @param array $ip_cidr 0 => ip, 1 => netmask in decimal, e.g. [0 => '123.123.123.123', 1 => 24]
|
||||
* @param string $ip ip-address to check
|
||||
* @param string $ip ip-address to check
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
@@ -77,7 +77,7 @@ class IPTools
|
||||
*
|
||||
* @return string|bool ip address on success, false on failure
|
||||
*/
|
||||
public static function is_ipv6($address)
|
||||
public static function is_ipv6(string $address)
|
||||
{
|
||||
return filter_var($address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6);
|
||||
}
|
||||
@@ -86,7 +86,7 @@ class IPTools
|
||||
* Checks whether the given ipv6 $ip is in range of given ip/cidr range
|
||||
*
|
||||
* @param array $ip_cidr 0 => ip, 1 => netmask in decimal, e.g. [0 => '123:123::1', 1 => 64]
|
||||
* @param string $ip ip-address to check
|
||||
* @param string $ip ip-address to check
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
@@ -130,6 +130,10 @@ class IPTools
|
||||
return $in_range;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $addr
|
||||
* @return false|string
|
||||
*/
|
||||
private static function inet6_expand(string $addr)
|
||||
{
|
||||
// Check if there are segments missing, insert if necessary
|
||||
@@ -139,7 +143,7 @@ class IPTools
|
||||
$part[1] = explode(':', $part[1]);
|
||||
$missing = [];
|
||||
for ($i = 0; $i < (8 - (count($part[0]) + count($part[1]))); $i++) {
|
||||
array_push($missing, '0000');
|
||||
$missing[] = '0000';
|
||||
}
|
||||
$missing = array_merge($part[0], $missing);
|
||||
$part = array_merge($missing, $part[1]);
|
||||
@@ -163,17 +167,18 @@ class IPTools
|
||||
}
|
||||
}
|
||||
|
||||
private static function inet6_prefix_to_mask($prefix)
|
||||
/**
|
||||
* @param int $prefix
|
||||
* @return false|string
|
||||
*/
|
||||
private static function inet6_prefix_to_mask(int $prefix)
|
||||
{
|
||||
/* Make sure the prefix is a number between 1 and 127 (inclusive) */
|
||||
$prefix = intval($prefix);
|
||||
if ($prefix < 0 || $prefix > 128) {
|
||||
return false;
|
||||
}
|
||||
$mask = '0b';
|
||||
for ($i = 0; $i < $prefix; $i++) {
|
||||
$mask .= '1';
|
||||
}
|
||||
$mask .= str_repeat('1', $prefix);
|
||||
for ($i = strlen($mask) - 2; $i < 128; $i++) {
|
||||
$mask .= '0';
|
||||
}
|
||||
@@ -188,7 +193,11 @@ class IPTools
|
||||
return inet_ntop(inet_pton($result));
|
||||
}
|
||||
|
||||
private static function ip2long6($ip)
|
||||
/**
|
||||
* @param string $ip
|
||||
* @return string
|
||||
*/
|
||||
private static function ip2long6(string $ip): string
|
||||
{
|
||||
$ip_n = inet_pton($ip);
|
||||
$bits = 15; // 16 x 8 bit = 128bit
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
namespace Froxlor\System;
|
||||
|
||||
use Froxlor\Settings;
|
||||
use PHPMailer\PHPMailer\Exception;
|
||||
use PHPMailer\PHPMailer\PHPMailer;
|
||||
|
||||
class Mailer extends PHPMailer
|
||||
@@ -34,9 +35,9 @@ class Mailer extends PHPMailer
|
||||
/**
|
||||
* class constructor
|
||||
*
|
||||
* @param bool $exceptions
|
||||
* whether to throw exceptions or not
|
||||
* @param bool $exceptions whether to throw exceptions or not
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __construct(bool $exceptions = false)
|
||||
{
|
||||
|
||||
@@ -32,7 +32,7 @@ use Monolog\Logger;
|
||||
class MysqlHandler extends AbstractProcessingHandler
|
||||
{
|
||||
|
||||
protected static $froxlorLevels = [
|
||||
protected static array $froxlorLevels = [
|
||||
Logger::DEBUG => LOG_DEBUG,
|
||||
Logger::INFO => LOG_INFO,
|
||||
Logger::NOTICE => LOG_NOTICE,
|
||||
@@ -47,11 +47,10 @@ class MysqlHandler extends AbstractProcessingHandler
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param bool|int $level
|
||||
* Debug level which this handler should store
|
||||
* @param bool|int $level Debug level which this handler should store
|
||||
* @param bool $bubble
|
||||
*/
|
||||
public function __construct($level = Logger::DEBUG, $bubble = true)
|
||||
public function __construct($level = Logger::DEBUG, bool $bubble = true)
|
||||
{
|
||||
parent::__construct($level, $bubble);
|
||||
}
|
||||
@@ -66,8 +65,8 @@ class MysqlHandler extends AbstractProcessingHandler
|
||||
{
|
||||
$this->insert([
|
||||
':message' => $record['message'],
|
||||
':contextUser' => (isset($record['context']['user']) ? $record['context']['user'] : 'unknown'),
|
||||
':contextAction' => (isset($record['context']['action']) ? $record['context']['action'] : '0'),
|
||||
':contextUser' => ($record['context']['user'] ?? 'unknown'),
|
||||
':contextAction' => ($record['context']['action'] ?? '0'),
|
||||
':level' => self::$froxlorLevels[$record['level']],
|
||||
':datetime' => $record['datetime']->format('U')
|
||||
]);
|
||||
@@ -79,7 +78,7 @@ class MysqlHandler extends AbstractProcessingHandler
|
||||
* @param array $data
|
||||
* @return bool
|
||||
*/
|
||||
protected function insert(array $data)
|
||||
protected function insert(array $data): bool
|
||||
{
|
||||
if ($this->pdoStatement === null) {
|
||||
$sql = "INSERT INTO `panel_syslog` SET `text` = :message, `user` = :contextUser, `action` = :contextAction, `type` = :level, `date` = :datetime";
|
||||
|
||||
@@ -32,9 +32,16 @@ use Froxlor\Api\Commands\Traffic as TrafficAPI;
|
||||
|
||||
class Traffic
|
||||
{
|
||||
public static function getCustomerStats($userinfo, $range = null): array
|
||||
/**
|
||||
* @param array $userinfo
|
||||
* @param ?string $range
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function getCustomerStats(array $userinfo, string $range = null): array
|
||||
{
|
||||
$trafficCollectionObj = (new Collection(TrafficAPI::class, $userinfo, self::getParamsByRange($range, ['customer_traffic' => true,])));
|
||||
$trafficCollectionObj = (new Collection(TrafficAPI::class, $userinfo,
|
||||
self::getParamsByRange($range, ['customer_traffic' => true,])));
|
||||
if ($userinfo['adminsession'] == 1) {
|
||||
$trafficCollectionObj->has('customer', Customers::class, 'customerid', 'customerid');
|
||||
}
|
||||
@@ -58,15 +65,15 @@ class Traffic
|
||||
$years[$item['year']]['ftp'] += ($item['ftp_up'] + $item['ftp_down']);
|
||||
$years[$item['year']]['mail'] += $item['mail'];
|
||||
// per month
|
||||
$months[$item['month'].'/'.$item['year']]['total'] += ($item['http'] + $item['ftp_up'] + $item['ftp_down'] + $item['mail']);
|
||||
$months[$item['month'].'/'.$item['year']]['http'] += $item['http'];
|
||||
$months[$item['month'].'/'.$item['year']]['ftp'] += ($item['ftp_up'] + $item['ftp_down']);
|
||||
$months[$item['month'].'/'.$item['year']]['mail'] += $item['mail'];
|
||||
$months[$item['month'] . '/' . $item['year']]['total'] += ($item['http'] + $item['ftp_up'] + $item['ftp_down'] + $item['mail']);
|
||||
$months[$item['month'] . '/' . $item['year']]['http'] += $item['http'];
|
||||
$months[$item['month'] . '/' . $item['year']]['ftp'] += ($item['ftp_up'] + $item['ftp_down']);
|
||||
$months[$item['month'] . '/' . $item['year']]['mail'] += $item['mail'];
|
||||
// per day
|
||||
$days[$item['day'].'.'.$item['month'].'.'.$item['year']]['total'] += ($item['http'] + $item['ftp_up'] + $item['ftp_down'] + $item['mail']);
|
||||
$days[$item['day'].'.'.$item['month'].'.'.$item['year']]['http'] += $item['http'];
|
||||
$days[$item['day'].'.'.$item['month'].'.'.$item['year']]['ftp'] += ($item['ftp_up'] + $item['ftp_down']);
|
||||
$days[$item['day'].'.'.$item['month'].'.'.$item['year']]['mail'] += $item['mail'];
|
||||
$days[$item['day'] . '.' . $item['month'] . '.' . $item['year']]['total'] += ($item['http'] + $item['ftp_up'] + $item['ftp_down'] + $item['mail']);
|
||||
$days[$item['day'] . '.' . $item['month'] . '.' . $item['year']]['http'] += $item['http'];
|
||||
$days[$item['day'] . '.' . $item['month'] . '.' . $item['year']]['ftp'] += ($item['ftp_up'] + $item['ftp_down']);
|
||||
$days[$item['day'] . '.' . $item['month'] . '.' . $item['year']]['mail'] += $item['mail'];
|
||||
}
|
||||
|
||||
// calculate overview for given range from users
|
||||
@@ -94,7 +101,13 @@ class Traffic
|
||||
];
|
||||
}
|
||||
|
||||
private static function getParamsByRange($range = null, array $params = [])
|
||||
/**
|
||||
* @param ?string $range
|
||||
* @param array $params
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
private static function getParamsByRange(string $range = null, array $params = []): array
|
||||
{
|
||||
$dateParams = [];
|
||||
|
||||
|
||||
@@ -38,6 +38,13 @@ class Check
|
||||
|
||||
const FORMFIELDS_PLAUSIBILITY_CHECK_QUESTION = 2;
|
||||
|
||||
/**
|
||||
* @param $fieldname
|
||||
* @param $fielddata
|
||||
* @param $newfieldvalue
|
||||
* @param $allnewfieldvalues
|
||||
* @return array|int[]
|
||||
*/
|
||||
public static function checkFcgidPhpFpm($fieldname, $fielddata, $newfieldvalue, $allnewfieldvalues)
|
||||
{
|
||||
$returnvalue = [
|
||||
@@ -76,7 +83,8 @@ class Check
|
||||
} else {
|
||||
// fcgid is being validated before fpm -> "ask" fpm about its state
|
||||
if ($fieldname == 'system_mod_fcgid_enabled') {
|
||||
$returnvalue = self::checkFcgidPhpFpm('system_phpfpm_enabled', null, $check_array[$fieldname]['other_post_field'], null);
|
||||
$returnvalue = self::checkFcgidPhpFpm('system_phpfpm_enabled', null,
|
||||
$check_array[$fieldname]['other_post_field'], null);
|
||||
} else {
|
||||
// not, bot are nogo
|
||||
$returnvalue = $returnvalue = [
|
||||
@@ -109,7 +117,8 @@ class Check
|
||||
$mysql_access_host_array = array_unique(array_map('trim', explode(',', $newfieldvalue)));
|
||||
|
||||
foreach ($mysql_access_host_array as $host_entry) {
|
||||
if (Validate::validate_ip2($host_entry, true, 'invalidip', true, true, true, true, false) == false && Validate::validateDomain($host_entry) == false && Validate::validateLocalHostname($host_entry) == false && $host_entry != '%') {
|
||||
if (Validate::validate_ip2($host_entry, true, 'invalidip', true, true, true, true,
|
||||
false) == false && Validate::validateDomain($host_entry) == false && Validate::validateLocalHostname($host_entry) == false && $host_entry != '%') {
|
||||
return [
|
||||
self::FORMFIELDS_PLAUSIBILITY_CHECK_ERROR,
|
||||
'invalidmysqlhost',
|
||||
@@ -123,6 +132,13 @@ class Check
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $fieldname
|
||||
* @param $fielddata
|
||||
* @param $newfieldvalue
|
||||
* @param $allnewfieldvalues
|
||||
* @return array|int[]
|
||||
*/
|
||||
public static function checkHostname($fieldname, $fielddata, $newfieldvalue, $allnewfieldvalues)
|
||||
{
|
||||
if (0 == strlen(trim($newfieldvalue)) || Validate::validateDomain($newfieldvalue) === false) {
|
||||
@@ -141,10 +157,12 @@ class Check
|
||||
* check whether an email account is to be deleted
|
||||
* reference: #1519
|
||||
*
|
||||
* @return bool true if the domain is to be deleted, false otherwise
|
||||
* @param string $email_addr
|
||||
*
|
||||
* @return bool true if the domain is to be deleted, false otherwise
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function checkMailAccDeletionState($email_addr = null)
|
||||
public static function checkMailAccDeletionState(string $email_addr): bool
|
||||
{
|
||||
// example data of task 7: a:2:{s:9:"loginname";s:4:"webX";s:5:"email";s:20:"deleteme@example.tld";}
|
||||
|
||||
@@ -164,6 +182,14 @@ class Check
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $fieldname
|
||||
* @param $fielddata
|
||||
* @param $newfieldvalue
|
||||
* @param $allnewfieldvalues
|
||||
* @return array|int[]
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function checkPathConflicts($fieldname, $fielddata, $newfieldvalue, $allnewfieldvalues)
|
||||
{
|
||||
if ((int)Settings::Get('system.mod_fcgid') == 1) {
|
||||
@@ -178,7 +204,8 @@ class Check
|
||||
}
|
||||
|
||||
// neither dir can be within the other nor can they be equal
|
||||
if (substr($newdir, 0, strlen($cdir)) == $cdir || substr($cdir, 0, strlen($newdir)) == $newdir || $newdir == $cdir) {
|
||||
if (substr($newdir, 0, strlen($cdir)) == $cdir || substr($cdir, 0,
|
||||
strlen($newdir)) == $newdir || $newdir == $cdir) {
|
||||
$returnvalue = [
|
||||
self::FORMFIELDS_PLAUSIBILITY_CHECK_ERROR,
|
||||
'fcgidpathcannotbeincustomerdoc'
|
||||
@@ -197,6 +224,13 @@ class Check
|
||||
return $returnvalue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $fieldname
|
||||
* @param $fielddata
|
||||
* @param $newfieldvalue
|
||||
* @param $allnewfieldvalues
|
||||
* @return array|int[]
|
||||
*/
|
||||
public static function checkPhpInterfaceSetting($fieldname, $fielddata, $newfieldvalue, $allnewfieldvalues)
|
||||
{
|
||||
$returnvalue = [
|
||||
@@ -216,6 +250,13 @@ class Check
|
||||
return $returnvalue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $fieldname
|
||||
* @param $fielddata
|
||||
* @param $newfieldvalue
|
||||
* @param $allnewfieldvalues
|
||||
* @return array|int[]
|
||||
*/
|
||||
public static function checkUsername($fieldname, $fielddata, $newfieldvalue, $allnewfieldvalues)
|
||||
{
|
||||
if (!isset($allnewfieldvalues['customer_mysqlprefix'])) {
|
||||
@@ -223,7 +264,8 @@ class Check
|
||||
}
|
||||
|
||||
$returnvalue = [];
|
||||
if (Validate::validateUsername($newfieldvalue, Settings::Get('panel.unix_names'), Database::getSqlUsernameLength() - strlen($allnewfieldvalues['customer_mysqlprefix'])) === true) {
|
||||
if (Validate::validateUsername($newfieldvalue, Settings::Get('panel.unix_names'),
|
||||
Database::getSqlUsernameLength() - strlen($allnewfieldvalues['customer_mysqlprefix'])) === true) {
|
||||
$returnvalue = [
|
||||
self::FORMFIELDS_PLAUSIBILITY_CHECK_OK
|
||||
];
|
||||
@@ -240,6 +282,13 @@ class Check
|
||||
return $returnvalue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $fieldname
|
||||
* @param $fielddata
|
||||
* @param $newfieldvalue
|
||||
* @param $allnewfieldvalues
|
||||
* @return array|int[]
|
||||
*/
|
||||
public static function checkLocalGroup($fieldname, $fielddata, $newfieldvalue, $allnewfieldvalues)
|
||||
{
|
||||
if (empty($newfieldvalue) || $fielddata == $newfieldvalue) {
|
||||
|
||||
@@ -28,32 +28,40 @@ namespace Froxlor\Validate;
|
||||
class Form
|
||||
{
|
||||
|
||||
public static function validateFormDefinition($form)
|
||||
/**
|
||||
* @param array $form
|
||||
* @return bool
|
||||
*/
|
||||
public static function validateFormDefinition(array $form): bool
|
||||
{
|
||||
$returnvalue = false;
|
||||
|
||||
if (is_array($form) && !empty($form) && isset($form['groups']) && is_array($form['groups']) && !empty($form['groups'])) {
|
||||
$returnvalue = true;
|
||||
if (!empty($form) && isset($form['groups']) && is_array($form['groups']) && !empty($form['groups'])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $returnvalue;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function validateFieldDefinition($field)
|
||||
/**
|
||||
* @param array $field
|
||||
* @return bool
|
||||
*/
|
||||
public static function validateFieldDefinition(array $field): bool
|
||||
{
|
||||
$returnvalue = false;
|
||||
|
||||
if (is_array($field) && !empty($field) && isset($field['fields']) && is_array($field['fields']) && !empty($field['fields'])) {
|
||||
$returnvalue = true;
|
||||
if (!empty($field) && isset($field['fields']) && is_array($field['fields']) && !empty($field['fields'])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $returnvalue;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function validateFormField($fieldname, $fielddata, $newfieldvalue)
|
||||
/**
|
||||
* @param $fieldname
|
||||
* @param array $fielddata
|
||||
* @param $newfieldvalue
|
||||
* @return mixed|string
|
||||
*/
|
||||
public static function validateFormField($fieldname, array $fielddata, $newfieldvalue)
|
||||
{
|
||||
$returnvalue = '';
|
||||
if (is_array($fielddata) && isset($fielddata['type']) && $fielddata['type'] != '' && method_exists('\\Froxlor\\Validate\\Form\\Data', 'validateFormField' . ucfirst($fielddata['type']))) {
|
||||
if (isset($fielddata['type']) && $fielddata['type'] != '' && method_exists('\\Froxlor\\Validate\\Form\\Data', 'validateFormField' . ucfirst($fielddata['type']))) {
|
||||
$returnvalue = call_user_func([
|
||||
'\\Froxlor\\Validate\\Form\\Data',
|
||||
'validateFormField' . ucfirst($fielddata['type'])
|
||||
|
||||
@@ -57,9 +57,16 @@ class Validate
|
||||
* @param bool $throw_exception whether to display error or throw an exception, default false
|
||||
*
|
||||
* @return string|void the clean string or error
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function validate($str, string $fieldname, string $pattern = '', $lng = '', $emptydefault = [], bool $throw_exception = false)
|
||||
{
|
||||
public static function validate(
|
||||
string $str,
|
||||
string $fieldname,
|
||||
string $pattern = '',
|
||||
$lng = '',
|
||||
$emptydefault = [],
|
||||
bool $throw_exception = false
|
||||
) {
|
||||
if (!is_array($emptydefault)) {
|
||||
$emptydefault_array = [
|
||||
$emptydefault
|
||||
@@ -101,27 +108,28 @@ class Validate
|
||||
/**
|
||||
* Checks whether it is a valid ip
|
||||
*
|
||||
* @param string $ip
|
||||
* ip-address to check
|
||||
* @param bool $return_bool
|
||||
* whether to return bool or call \Froxlor\UI\Response::standard_error()
|
||||
* @param string $lng
|
||||
* index for error-message (if $return_bool is false)
|
||||
* @param bool $allow_localhost
|
||||
* whether to allow 127.0.0.1
|
||||
* @param bool $allow_priv
|
||||
* whether to allow private network addresses
|
||||
* @param bool $allow_cidr
|
||||
* whether to allow CIDR values e.g. 10.10.10.10/16
|
||||
* @param bool $cidr_as_netmask
|
||||
* whether to format CIDR nodation to netmask notation
|
||||
* @param bool $throw_exception
|
||||
* whether to throw an exception on failure
|
||||
* @param string $ip ip-address to check
|
||||
* @param bool $return_bool whether to return bool or call \Froxlor\UI\Response::standard_error()
|
||||
* @param string $lng index for error-message (if $return_bool is false)
|
||||
* @param bool $allow_localhost whether to allow 127.0.0.1
|
||||
* @param bool $allow_priv whether to allow private network addresses
|
||||
* @param bool $allow_cidr whether to allow CIDR values e.g. 10.10.10.10/16
|
||||
* @param bool $cidr_as_netmask whether to format CIDR notation to netmask notation
|
||||
* @param bool $throw_exception whether to throw an exception on failure
|
||||
*
|
||||
* @return string|bool|void ip address on success, false on failure (or nothing if error is displayed)
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function validate_ip2($ip, bool $return_bool = false, string $lng = 'invalidip', bool $allow_localhost = false, bool $allow_priv = false, bool $allow_cidr = false, bool $cidr_as_netmask = false, bool $throw_exception = false)
|
||||
{
|
||||
public static function validate_ip2(
|
||||
string $ip,
|
||||
bool $return_bool = false,
|
||||
string $lng = 'invalidip',
|
||||
bool $allow_localhost = false,
|
||||
bool $allow_priv = false,
|
||||
bool $allow_cidr = false,
|
||||
bool $cidr_as_netmask = false,
|
||||
bool $throw_exception = false
|
||||
) {
|
||||
$cidr = "";
|
||||
if ($allow_cidr) {
|
||||
$org_ip = $ip;
|
||||
@@ -131,7 +139,8 @@ class Validate
|
||||
if (IPTools::is_ipv6($ip_cidr[0])) {
|
||||
$cidr_range_max = 128;
|
||||
}
|
||||
if (strlen($ip_cidr[1]) <= 3 && in_array((int)$ip_cidr[1], array_values(range(1, $cidr_range_max)), true) === false) {
|
||||
if (strlen($ip_cidr[1]) <= 3 && in_array((int)$ip_cidr[1], array_values(range(1, $cidr_range_max)),
|
||||
true) === false) {
|
||||
if ($return_bool) {
|
||||
return false;
|
||||
}
|
||||
@@ -161,7 +170,8 @@ class Validate
|
||||
|
||||
$filter_lan = $allow_priv ? FILTER_FLAG_NO_RES_RANGE : (FILTER_FLAG_NO_RES_RANGE | FILTER_FLAG_NO_PRIV_RANGE);
|
||||
|
||||
if ((filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) || filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) && filter_var($ip, FILTER_VALIDATE_IP, $filter_lan)) {
|
||||
if ((filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) || filter_var($ip, FILTER_VALIDATE_IP,
|
||||
FILTER_FLAG_IPV4)) && filter_var($ip, FILTER_VALIDATE_IP, $filter_lan)) {
|
||||
return $ip . $cidr;
|
||||
}
|
||||
|
||||
@@ -179,14 +189,12 @@ class Validate
|
||||
/**
|
||||
* Returns whether a URL is in a correct format or not
|
||||
*
|
||||
* @param string $url
|
||||
* URL to be tested
|
||||
* @param bool $allow_private_ip
|
||||
* optional, default is false
|
||||
* @param string $url URL to be tested
|
||||
* @param bool $allow_private_ip optional, default is false
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function validateUrl(string $url, bool $allow_private_ip = false)
|
||||
public static function validateUrl(string $url, bool $allow_private_ip = false): bool
|
||||
{
|
||||
if (strtolower(substr($url, 0, 7)) != "http://" && strtolower(substr($url, 0, 8)) != "https://") {
|
||||
$url = 'http://' . $url;
|
||||
@@ -215,25 +223,22 @@ class Validate
|
||||
/**
|
||||
* Check if the submitted string is a valid domainname
|
||||
*
|
||||
* @param string $domainname
|
||||
* The domainname which should be checked.
|
||||
* @param bool $allow_underscore
|
||||
* optional if true, allowes the underscore character in a domain label (DKIM etc.)
|
||||
* @param string $domainname The domainname which should be checked.
|
||||
* @param bool $allow_underscore optional if true, allowes the underscore character in a domain label (DKIM etc.)
|
||||
*
|
||||
* @return string|boolean the domain-name if the domain is valid, false otherwise
|
||||
*/
|
||||
public static function validateDomain($domainname, $allow_underscore = false)
|
||||
public static function validateDomain(string $domainname, bool $allow_underscore = false)
|
||||
{
|
||||
if (is_string($domainname)) {
|
||||
$char_validation = '([a-z\d](-*[a-z\d])*)(\.?([a-z\d](-*[a-z\d])*))*\.(xn\-\-)?([a-z\d])+';
|
||||
if ($allow_underscore) {
|
||||
$char_validation = '([a-z\d\_](-*[a-z\d\_])*)(\.([a-z\d\_](-*[a-z\d])*))*(\.?([a-z\d](-*[a-z\d])*))+\.(xn\-\-)?([a-z\d])+';
|
||||
}
|
||||
$char_validation = '([a-z\d](-*[a-z\d])*)(\.?([a-z\d](-*[a-z\d])*))*\.(xn\-\-)?([a-z\d])+';
|
||||
if ($allow_underscore) {
|
||||
$char_validation = '([a-z\d\_](-*[a-z\d\_])*)(\.([a-z\d\_](-*[a-z\d])*))*(\.?([a-z\d](-*[a-z\d])*))+\.(xn\-\-)?([a-z\d])+';
|
||||
}
|
||||
|
||||
// valid chars check && overall length check && length of each label
|
||||
if (preg_match("/^" . $char_validation . "$/i", $domainname) && preg_match("/^.{1,253}$/", $domainname) && preg_match("/^[^\.]{1,63}(\.[^\.]{1,63})*$/", $domainname)) {
|
||||
return $domainname;
|
||||
}
|
||||
// valid chars check && overall length check && length of each label
|
||||
if (preg_match("/^" . $char_validation . "$/i", $domainname) && preg_match("/^.{1,253}$/",
|
||||
$domainname) && preg_match("/^[^\.]{1,63}(\.[^\.]{1,63})*$/", $domainname)) {
|
||||
return $domainname;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -245,7 +250,7 @@ class Validate
|
||||
*
|
||||
* @return string|boolean hostname on success, else false
|
||||
*/
|
||||
public static function validateLocalHostname($hostname)
|
||||
public static function validateLocalHostname(string $hostname)
|
||||
{
|
||||
$pattern = '/^[a-z0-9][a-z0-9\-]{0,62}$/i';
|
||||
if (preg_match($pattern, $hostname)) {
|
||||
@@ -257,11 +262,11 @@ class Validate
|
||||
/**
|
||||
* Returns if an emailaddress is in correct format or not
|
||||
*
|
||||
* @param string $email
|
||||
* The email address to check
|
||||
* @return bool Correct or not
|
||||
* @param string $email The email address to check
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function validateEmail($email)
|
||||
public static function validateEmail(string $email)
|
||||
{
|
||||
$email = strtolower($email);
|
||||
// as of php-7.1
|
||||
@@ -272,25 +277,22 @@ class Validate
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if an username is in correct format or not.
|
||||
* Returns if a username is in correct format or not.
|
||||
*
|
||||
* @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
|
||||
* @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 = '')
|
||||
public static function validateUsername(string $username, bool $unix_names = true, int $mysql_max = 0): bool
|
||||
{
|
||||
if (empty($mysql_max) || !is_numeric($mysql_max) || $mysql_max <= 0) {
|
||||
if (empty($mysql_max) || $mysql_max <= 0) {
|
||||
$mysql_max = Database::getSqlUsernameLength() - 1;
|
||||
} else {
|
||||
$mysql_max--;
|
||||
}
|
||||
if ($unix_names == 0) {
|
||||
if (!$unix_names) {
|
||||
if (strpos($username, '--') === false) {
|
||||
return (preg_match('/^[a-z][a-z0-9\-_]{0,' . $mysql_max . '}[a-z0-9]{1}$/Di', $username) != false);
|
||||
}
|
||||
@@ -304,9 +306,9 @@ class Validate
|
||||
*
|
||||
* @param string $interval
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public static function validateSqlInterval($interval = null)
|
||||
public static function validateSqlInterval(string $interval): bool
|
||||
{
|
||||
if (!empty($interval) && strstr($interval, ' ') !== false) {
|
||||
/*
|
||||
@@ -325,7 +327,8 @@ class Validate
|
||||
|
||||
$interval_parts = explode(' ', $interval);
|
||||
|
||||
if (count($interval_parts) == 2 && preg_match('/[0-9]+/', $interval_parts[0]) && in_array(strtoupper($interval_parts[1]), $valid_expr)) {
|
||||
if (count($interval_parts) == 2 && preg_match('/[0-9]+/',
|
||||
$interval_parts[0]) && in_array(strtoupper($interval_parts[1]), $valid_expr)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user