make a more complete version of the installer

This commit is contained in:
envoyr 2022-05-01 17:26:51 +02:00
parent 1557482d17
commit 86e01191d2
No known key found for this signature in database
GPG Key ID: 5A16F49AF96F462F
7 changed files with 701 additions and 1683 deletions

View File

@ -60,7 +60,6 @@ CREATE TABLE `ftp_users` (
) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
DROP TABLE IF EXISTS `mail_users`;
CREATE TABLE `mail_users` (
`id` int(11) NOT NULL auto_increment,

File diff suppressed because it is too large Load Diff

View File

View File

@ -26,6 +26,7 @@
namespace Froxlor\Install;
use Exception;
use Froxlor\Install\Install\Core;
use Froxlor\UI\Panel\UI;
use Froxlor\UI\Request;
@ -36,8 +37,8 @@ class Install
public $phpVersion;
public $formfield;
public string $requiredVersion = '7.4.0';
public array $requiredExtensions = ['libxml', 'zip'];
public array $suggestedExtensions = ['curl'];
public array $requiredExtensions = ['session', 'ctype', 'xml', 'filter', 'posix', 'mbstring', 'curl', 'gmp', 'json'];
public array $suggestedExtensions = ['bcmath', 'zip'];
public array $suggestions = [];
public array $criticals = [];
public array $loadedExtensions;
@ -123,13 +124,19 @@ class Install
$_SESSION['installation'] = array_merge($_SESSION['installation'] ?? [], $validatedData);
}
// also handle completion of installation if it's the last step
// also handle completion of installation if it's the step before the last step
if ($this->currentStep == ($this->maxSteps -1)) {
$core = new \Froxlor\Install\Install\Core($_SESSION['installation']);
$core->doInstall();
}
// redirect user to home if the installation is done
if ($this->currentStep == $this->maxSteps) {
$this->startInstallation($validatedData);
header('Location: ../');
return;
}
// redirect to next step
header('Location: ?step=' . ($this->currentStep + 1));
}
@ -208,16 +215,16 @@ class Install
*/
private function checkDatabase(array $validatedData): void
{
$dsn = sprintf('mysql:host=%s;charset=utf8mb4', $validatedData['sql_hostname']);
$pdo = new \PDO($dsn, $validatedData['sql_root_username'], $validatedData['sql_root_password']);
$dsn = sprintf('mysql:host=%s;charset=utf8', $validatedData['mysql_host']);
$pdo = new \PDO($dsn, $validatedData['mysql_root_user'], $validatedData['mysql_root_pass']);
// check if the database already exist
$stmt = $pdo->prepare('SHOW DATABASES LIKE ?');
$stmt->execute([
$validatedData['sql_database']
$validatedData['mysql_database']
]);
$hasDatabase = $stmt->fetch();
if ($hasDatabase && !$validatedData['sql_override_database']) {
if ($hasDatabase && !$validatedData['mysql_force_create']) {
throw new Exception('Database already exist, please set override option to rebuild!');
}
@ -230,35 +237,25 @@ class Install
throw new Exception('Cant drop test db');
}
// FIXME: seems not to work
// check if the user already exist
$stmt = $pdo->prepare("SELECT `user` FROM `mysql.user` WHERE `user` = '?'");
if ($stmt->rowCount()) {
throw new Exception('Username already exist, please use another username!');
$stmt = $pdo->prepare("SELECT `User` FROM `mysql`.`user` WHERE `User` = ?");
$stmt->execute([$validatedData['mysql_unprivileged_user']]);
if ($stmt->rowCount() && !$validatedData['mysql_force_create']) {
throw new Exception('Username already exist, please use another username or delete it first!');
}
// check if we can create a new user
$testUser = uniqid('froxlor_tmp_');
$stmt = $pdo->prepare('CREATE USER ?@? IDENTIFIED BY ?');
if ($stmt->execute([$testUser, $validatedData['sql_hostname'], uniqid()]) === false) {
if ($stmt->execute([$testUser, $validatedData['mysql_host'], uniqid()]) === false) {
throw new Exception('cant create test user');
}
$stmt = $pdo->prepare('DROP USER ?@?');
if ($stmt->execute([$testUser, $validatedData['sql_hostname']]) === false) {
if ($stmt->execute([$testUser, $validatedData['mysql_host']]) === false) {
throw new Exception('cant create test user');
}
if ($pdo->prepare('FLUSH PRIVILEGES')->execute() === false) {
throw new Exception('Cant flush privileges');
}
}
/**
* @param array $validatedData
* @return void
* @throws Exception
*/
private function startInstallation(array $validatedData): void
{
// TODO: do the installation (maybe in an own class?)
}
}

View File

@ -0,0 +1,599 @@
<?php
/**
* This file is part of the Froxlor project.
* Copyright (c) 2010 the Froxlor Team (see authors).
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you can also view it online at
* https://files.froxlor.org/misc/COPYING.txt
*
* @copyright the authors
* @author Froxlor team <team@froxlor.org>
* @license https://files.froxlor.org/misc/COPYING.txt GPLv2
*/
namespace Froxlor\Install\Install;
use Exception;
use Froxlor\Config\ConfigParser;
use Froxlor\FileDir;
use Froxlor\Froxlor;
use Froxlor\PhpHelper;
use PDO;
use PDOException;
use PDOStatement;
/**
* Installation of the froxlor core database and set settings.
*/
class Core
{
protected array $validatedData;
public function __construct(array $validatedData)
{
$this->validatedData = $validatedData;
}
/**
* no missing fields or data -> perform actual install
*
* @return void
* @throws Exception
*/
public function doInstall()
{
$options = [
'PDO::MYSQL_ATTR_INIT_COMMAND' => 'SET names utf8'
];
if (!empty($this->validatedData['mysql_ssl_ca_file'])) {
$options[PDO::MYSQL_ATTR_SSL_CA] = $this->validatedData['mysql_ssl_ca_file'];
$options[PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT] = (bool)$this->validatedData['mysql_ssl_verify_server_certificate'];
}
$dsn = "mysql:host=" . $this->validatedData['mysql_host'] . ";";
try {
$db_root = new PDO($dsn, $this->validatedData['mysql_root_user'], $this->validatedData['mysql_root_pass'], $options);
} catch (PDOException $e) {
// possibly without passwd?
try {
$db_root = new PDO($dsn, $this->validatedData['mysql_root_user'], '', $options);
// set the given password
$passwd_stmt = $db_root->prepare("
SET PASSWORD = PASSWORD(:passwd)
");
$passwd_stmt->execute([
'passwd' => $this->validatedData['mysql_root_pass']
]);
} catch (PDOException $e) {
// nope
throw new Exception('', 0, $e);
}
}
$version_server = $db_root->getAttribute(PDO::ATTR_SERVER_VERSION);
$sql_mode = 'NO_ENGINE_SUBSTITUTION';
if (version_compare($version_server, '8.0.11', '<')) {
$sql_mode .= ',NO_AUTO_CREATE_USER';
}
$db_root->exec('SET sql_mode = "' . $sql_mode . '"');
// ok, if we are here, the database connection is up and running
// check for existing pdo and create backup if so
$this->backupExistingDatabase($db_root);
// create unprivileged user and the database itself
$this->createDatabaseAndUser($db_root);
// importing data to new database
$this->importDatabaseData();
// create DB object for new database
$options = [
'PDO::MYSQL_ATTR_INIT_COMMAND' => 'SET names utf8'
];
if (!empty($this->validatedData['mysql_ssl_ca_file']) && isset($this->validatedData['mysql_ssl_verify_server_certificate'])) {
$options[PDO::MYSQL_ATTR_SSL_CA] = $this->validatedData['mysql_ssl_ca_file'];
$options[PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT] = (bool)$this->validatedData['mysql_ssl_verify_server_certificate'];
}
$dsn = "mysql:host=" . $this->validatedData['mysql_host'] . ";dbname=" . $this->validatedData['mysql_database'] . ";";
try {
$pdo = new PDO($dsn, $this->validatedData['mysql_unprivileged_user'], $this->validatedData['mysql_unprivileged_pass'], $options);
$version_server = $pdo->getAttribute(PDO::ATTR_SERVER_VERSION);
$sql_mode = 'NO_ENGINE_SUBSTITUTION';
if (version_compare($version_server, '8.0.11', '<')) {
$sql_mode .= ',NO_AUTO_CREATE_USER';
}
$pdo->exec('SET sql_mode = "' . $sql_mode . '"');
} catch (PDOException $e) {
throw new Exception('Unexpected exception occured', 0, $e);
}
// change settings accordingly
$this->doSettings($pdo);
// create entries
$this->doDataEntries($pdo);
// create config-file
$this->createUserdataConf();
}
/**
* Check if an old database exists and back it up if necessary
*
* @param object $db_root
* @return void
* @throws Exception
*/
private function backupExistingDatabase(object &$db_root)
{
// check for existing of former database
$stmt = $db_root->prepare("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = :database");
$stmt->execute([
'database' => $this->validatedData['mysql_database']
]);
$rows = $db_root->query("SELECT FOUND_ROWS()")->fetchColumn();
// backup tables if exist
if ($rows > 0) {
if (!$this->validatedData['mysql_force_create']) {
throw new Exception('We found a database and were not allow to override it!');
}
// create temporary backup-filename
$filename = "/tmp/froxlor_backup_" . date('YmdHi') . ".sql";
// look for mysqldump
if (file_exists("/usr/bin/mysqldump")) {
$mysql_dump = '/usr/bin/mysqldump';
} elseif (file_exists("/usr/local/bin/mysqldump")) {
$mysql_dump = '/usr/local/bin/mysqldump';
}
// create temporary .cnf file
$cnffilename = "/tmp/froxlor_dump.cnf";
$dumpcnf = "[mysqldump]" . PHP_EOL . "password=\"" . $this->validatedData['mysql_root_pass'] . "\"" . PHP_EOL;
file_put_contents($cnffilename, $dumpcnf);
// make the backup
if (isset($mysql_dump)) {
$command = $mysql_dump . " --defaults-extra-file=" . $cnffilename . " " . escapeshellarg($this->validatedData['mysql_database']) . " -u " . escapeshellarg($this->validatedData['mysql_root_user']) . " --result-file=" . $filename;
$output = [];
exec($command, $output);
@unlink($cnffilename);
if (stristr(implode(" ", $output), "error") || !file_exists($filename)) {
throw new Exception('backup_failed');
}
} else {
throw new Exception('backup_binary_missing');
}
}
}
/**
* Create database and database-user
*
* @todo add exceptions?
* @param object $db_root
* @return void
* @throws Exception
*/
private function createDatabaseAndUser(object &$db_root)
{
// so first we have to delete the database and
// the user given for the unpriv-user if they exit
$del_stmt = $db_root->prepare("DELETE FROM `mysql`.`user` WHERE `User` = :user AND `Host` = :accesshost");
$del_stmt->execute([
'user' => $this->validatedData['mysql_unprivileged_user'],
'accesshost' => $this->validatedData['mysql_access_host']
]);
$del_stmt = $db_root->prepare("DELETE FROM `mysql`.`db` WHERE `User` = :user AND `Host` = :accesshost");
$del_stmt->execute([
'user' => $this->validatedData['mysql_unprivileged_user'],
'accesshost' => $this->validatedData['mysql_access_host']
]);
$del_stmt = $db_root->prepare("DELETE FROM `mysql`.`tables_priv` WHERE `User` = :user AND `Host` =:accesshost");
$del_stmt->execute([
'user' => $this->validatedData['mysql_unprivileged_user'],
'accesshost' => $this->validatedData['mysql_access_host']
]);
$del_stmt = $db_root->prepare("DELETE FROM `mysql`.`columns_priv` WHERE `User` = :user AND `Host` = :accesshost");
$del_stmt->execute([
'user' => $this->validatedData['mysql_unprivileged_user'],
'accesshost' => $this->validatedData['mysql_access_host']
]);
$del_stmt = $db_root->prepare("DROP DATABASE IF EXISTS `" . str_replace('`', '', $this->validatedData['mysql_database']) . "`;");
$del_stmt->execute();
$db_root->query("FLUSH PRIVILEGES;");
// we have to create a new user and database for the froxlor unprivileged mysql access
$ins_stmt = $db_root->prepare("CREATE DATABASE `" . str_replace('`', '', $this->validatedData['mysql_database']) . "` CHARACTER SET=utf8 COLLATE=utf8_general_ci");
$ins_stmt->execute();
$mysql_access_host_array = array_map('trim', explode(',', $this->validatedData['mysql_access_host']));
if (in_array('127.0.0.1', $mysql_access_host_array) && !in_array('localhost', $mysql_access_host_array)) {
$mysql_access_host_array[] = 'localhost';
}
if (!in_array('127.0.0.1', $mysql_access_host_array) && in_array('localhost', $mysql_access_host_array)) {
$mysql_access_host_array[] = '127.0.0.1';
}
if (!in_array($this->validatedData['serverip'], $mysql_access_host_array)) {
$mysql_access_host_array[] = $this->validatedData['serverip'];
}
$mysql_access_host_array = array_unique($mysql_access_host_array);
foreach ($mysql_access_host_array as $mysql_access_host) {
$this->grantDbPrivilegesTo($db_root, $this->validatedData['mysql_database'], $this->validatedData['mysql_unprivileged_user'], $this->validatedData['mysql_unprivileged_pass'], $mysql_access_host);
}
$db_root->query("FLUSH PRIVILEGES;");
$this->validatedData['mysql_access_host'] = implode(',', $mysql_access_host_array);
}
/**
* Grant privileges to given user.
*
* @todo add exceptions?
* @param $db_root
* @param $database
* @param $username
* @param $password
* @param $access_host
* @return void
* @throws Exception
*/
private function grantDbPrivilegesTo(&$db_root, $database, $username, $password, $access_host)
{
if (version_compare($db_root->getAttribute(PDO::ATTR_SERVER_VERSION), '10.0.0', '>=')) {
// mariadb compatibility
// create user
$stmt = $db_root->prepare("CREATE USER '" . $username . "'@'" . $access_host . "' IDENTIFIED BY :password");
$stmt->execute([
"password" => $password
]);
// grant privileges
$stmt = $db_root->prepare("GRANT ALL ON `" . $database . "`.* TO :username@:host");
$stmt->execute([
"username" => $username,
"host" => $access_host
]);
} elseif (version_compare($db_root->getAttribute(PDO::ATTR_SERVER_VERSION), '8.0.11', '>=')) {
// mysql8 compatibility
// create user
$stmt = $db_root->prepare("CREATE USER '" . $username . "'@'" . $access_host . "' IDENTIFIED WITH mysql_native_password BY :password");
$stmt->execute([
"password" => $password
]);
// grant privileges
$stmt = $db_root->prepare("GRANT ALL ON `" . $database . "`.* TO :username@:host");
$stmt->execute([
"username" => $username,
"host" => $access_host
]);
} else {
// grant privileges
$stmt = $db_root->prepare("GRANT ALL PRIVILEGES ON `" . $database . "`.* TO :username@:host IDENTIFIED BY :password");
$stmt->execute([
"username" => $username,
"host" => $access_host,
"password" => $password
]);
}
}
/**
* Import froxlor.sql into database
*
* @return void
* @throws Exception
*/
private function importDatabaseData()
{
$options = [
'PDO::MYSQL_ATTR_INIT_COMMAND' => 'SET names utf8'
];
if (!empty($this->validatedData['mysql_ssl_ca_file'])) {
$options[PDO::MYSQL_ATTR_SSL_CA] = $this->validatedData['mysql_ssl_ca_file'];
$options[PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT] = (bool)$this->validatedData['mysql_ssl_verify_server_certificate'];
}
$dsn = "mysql:host=" . $this->validatedData['mysql_host'] . ";dbname=" . $this->validatedData['mysql_database'] . ";";
try {
$pdo = new PDO($dsn, $this->validatedData['mysql_unprivileged_user'], $this->validatedData['mysql_unprivileged_pass'], $options);
$attributes = [
'ATTR_ERRMODE' => 'ERRMODE_EXCEPTION'
];
// set attributes
foreach ($attributes as $k => $v) {
$pdo->setAttribute(constant("PDO::" . $k), constant("PDO::" . $v));
}
$version_server = $pdo->getAttribute(PDO::ATTR_SERVER_VERSION);
$sql_mode = 'NO_ENGINE_SUBSTITUTION';
if (version_compare($version_server, '8.0.11', '<')) {
$sql_mode .= ',NO_AUTO_CREATE_USER';
}
$pdo->exec('SET sql_mode = "' . $sql_mode . '"');
} catch (PDOException $e) {
throw new Exception('failed to initialize froxlor user connection!');
}
// actually import data
try {
$froxlorSQL = include dirname(__FILE__, 5) . '/install/froxlor.sql.php';
$pdo->query($froxlorSQL);
} catch (PDOException $e) {
throw new Exception('failed to import data!', 0, $e);
}
}
/**
* change settings according to users input
*
* @param object $db_user
* @return void
* @throws Exception
*/
private function doSettings(object &$db_user)
{
$upd_stmt = $db_user->prepare("
UPDATE `" . TABLE_PANEL_SETTINGS . "` SET `value` = :value
WHERE `settinggroup` = :group AND `varname` = :varname
");
$this->updateSetting($upd_stmt, 'admin@' . $this->validatedData['servername'], 'panel', 'adminmail');
$this->updateSetting($upd_stmt, $this->validatedData['serverip'], 'system', 'ipaddress');
if ($this->validatedData['use_ssl']) {
$this->updateSetting($upd_stmt, 1, 'system', 'use_ssl');
}
$this->updateSetting($upd_stmt, $this->validatedData['servername'], 'system', 'hostname');
$this->updateSetting($upd_stmt, 'en', 'panel', 'standardlanguage'); // TODO: set language
$this->updateSetting($upd_stmt, $this->validatedData['mysql_access_host'], 'system', 'mysql_access_host');
$this->updateSetting($upd_stmt, $this->validatedData['webserver'], 'system', 'webserver');
$this->updateSetting($upd_stmt, $this->validatedData['httpuser'], 'system', 'httpuser');
$this->updateSetting($upd_stmt, $this->validatedData['httpgroup'], 'system', 'httpgroup');
// necessary changes for webservers != apache2
if ($this->validatedData['webserver'] == "apache24") {
$this->updateSetting($upd_stmt, 'apache2', 'system', 'webserver');
$this->updateSetting($upd_stmt, '1', 'system', 'apache24');
} elseif ($this->validatedData['webserver'] == "lighttpd") {
$this->updateSetting($upd_stmt, '/etc/lighttpd/conf-enabled/', 'system', 'apacheconf_vhost');
$this->updateSetting($upd_stmt, '/etc/lighttpd/froxlor-diroptions/', 'system', 'apacheconf_diroptions');
$this->updateSetting($upd_stmt, '/etc/lighttpd/froxlor-htpasswd/', 'system', 'apacheconf_htpasswddir');
$this->updateSetting($upd_stmt, 'service lighttpd reload', 'system', 'apachereload_command');
$this->updateSetting($upd_stmt, '/etc/lighttpd/lighttpd.pem', 'system', 'ssl_cert_file');
$this->updateSetting($upd_stmt, '/var/run/lighttpd/', 'phpfpm', 'fastcgi_ipcdir');
} elseif ($this->validatedData['webserver'] == "nginx") {
$this->updateSetting($upd_stmt, '/etc/nginx/sites-enabled/', 'system', 'apacheconf_vhost');
$this->updateSetting($upd_stmt, '/etc/nginx/sites-enabled/', 'system', 'apacheconf_diroptions');
$this->updateSetting($upd_stmt, '/etc/nginx/froxlor-htpasswd/', 'system', 'apacheconf_htpasswddir');
$this->updateSetting($upd_stmt, 'service nginx reload', 'system', 'apachereload_command');
$this->updateSetting($upd_stmt, '/etc/nginx/nginx.pem', 'system', 'ssl_cert_file');
$this->updateSetting($upd_stmt, '/var/run/', 'phpfpm', 'fastcgi_ipcdir');
$this->updateSetting($upd_stmt, 'error', 'system', 'errorlog_level');
}
$distros = glob(FileDir::makeCorrectDir(Froxlor::getInstallDir() . '/lib/configfiles/') . '*.xml');
foreach ($distros as $_distribution) {
if ($this->validatedData['distribution'] == str_replace(".xml", "", strtolower(basename($_distribution)))) {
$dist = new ConfigParser($_distribution);
$defaults = $dist->getDefaults();
if (!empty($defaults)) {
foreach ($defaults as $property) {
$this->updateSetting($upd_stmt, $property->attributes()->value, $property->attributes()->settinggroup, $property->attributes()->varname);
}
}
}
}
$this->updateSetting($upd_stmt, $this->validatedData['activate_newsfeed'], 'admin', 'show_news_feed');
$this->updateSetting($upd_stmt, dirname(__FILE__, 3), 'system', 'letsencryptchallengepath');
// insert the lastcronrun to be the installation date
$this->updateSetting($upd_stmt, time(), 'system', 'lastcronrun');
// check currently used php version and set values of fpm/fcgid accordingly
if (defined('PHP_MAJOR_VERSION') && defined('PHP_MINOR_VERSION')) {
$reload = "service php" . PHP_MAJOR_VERSION . "." . PHP_MINOR_VERSION . "-fpm restart";
$config_dir = "/etc/php/" . PHP_MAJOR_VERSION . "." . PHP_MINOR_VERSION . "/fpm/pool.d/";
$db_user->query("UPDATE `" . TABLE_PANEL_FPMDAEMONS . "` SET `reload_cmd` = '" . $reload . "', `config_dir` = '" . $config_dir . "' WHERE `id` ='1';");
}
// set specific times for some crons (traffic only at night, etc.)
$timestamp = mktime(0, 0, 0, date('m', time()), date('d', time()), date('Y', time()));
$db_user->query("UPDATE `" . TABLE_PANEL_CRONRUNS . "` SET `lastrun` = '" . $timestamp . "' WHERE `cronfile` ='cron_traffic';");
// insert task 99 to generate a correct cron.d-file automatically
$db_user->query("INSERT INTO `" . TABLE_PANEL_TASKS . "` SET `type` = '99';");
}
/**
* execute prepared statement to update settings
*
* @param PDOStatement|null $stmt
* @param string|null $group
* @param string|null $varname
* @param string|null $value
*/
private function updateSetting(PDOStatement &$stmt = null, string $value = null, string $group = null, string $varname = null)
{
$stmt->execute([
'group' => $group,
'varname' => $varname,
'value' => $value
]);
}
/**
* create corresponding entries in froxlor database
*
* @param $db_user
* @return void
*/
private function doDataEntries(&$db_user)
{
// lets insert the default ip and port
$stmt = $db_user->prepare("
INSERT INTO `" . TABLE_PANEL_IPSANDPORTS . "` SET
`ip`= :serverip,
`port` = :serverport,
`namevirtualhost_statement` = :nvh,
`vhostcontainer` = '1',
`vhostcontainer_servername_statement` = '1'
");
$nvh = $this->validatedData['webserver'] == 'apache2' ? '1' : '0';
$stmt->execute([
'nvh' => $nvh,
'serverip' => $this->validatedData['serverip'],
'serverport' => 80
]);
$defaultip = $db_user->lastInsertId();
$defaultsslip = false;
if ($this->validatedData['use_ssl']) {
$stmt->execute([
'nvh' => $this->validatedData['webserver'] == 'apache2' ? '1' : '0',
'serverip' => $this->validatedData['serverip'],
'serverport' => 443
]);
$defaultsslip = $db_user->lastInsertId();
}
// insert the defaultip
$upd_stmt = $db_user->prepare("
UPDATE `" . TABLE_PANEL_SETTINGS . "` SET
`value` = :defaultip
WHERE `settinggroup` = 'system' AND `varname` = :defipfld
");
$upd_stmt->execute([
'defaultip' => $defaultip,
'defipfld' => 'defaultip'
]);
if ($defaultsslip) {
$upd_stmt->execute([
'defaultip' => $defaultsslip,
'defipfld' => 'defaultsslip'
]);
}
// last but not least create the main admin
$ins_data = [
'loginname' => $this->validatedData['admin_user'],
/* use system default crypt */
'password' => password_hash($this->validatedData['admin_pass'], PASSWORD_DEFAULT),
'email' => 'admin@' . $this->validatedData['servername'],
'deflang' => 'en' // TODO: set lanuage
];
$ins_stmt = $db_user->prepare("
INSERT INTO `" . TABLE_PANEL_ADMINS . "` SET
`loginname` = :loginname,
`password` = :password,
`name` = 'Froxlor-Administrator',
`email` = :email,
`def_language` = :deflang,
`api_allowed` = 1,
`customers` = -1,
`customers_see_all` = 1,
`caneditphpsettings` = 1,
`domains` = -1,
`domains_see_all` = 1,
`change_serversettings` = 1,
`diskspace` = -1024,
`mysqls` = -1,
`emails` = -1,
`email_accounts` = -1,
`email_forwarders` = -1,
`email_quota` = -1,
`ftps` = -1,
`subdomains` = -1,
`traffic` = -1048576
");
$ins_stmt->execute($ins_data);
}
/**
* Create userdata.inc.php file
*
* @return void
* @throws Exception
*/
private function createUserdataConf()
{
$userdata = [
'sql' => [
'debug' => false,
'host' => $this->validatedData['mysql_host'],
'user' => $this->validatedData['mysql_unprivileged_user'],
'password' => $this->validatedData['mysql_unprivileged_pass'],
'db' => $this->validatedData['mysql_database'],
],
'sql_root' => [
'0' => [
'caption' => 'Default',
'host' => $this->validatedData['mysql_host'],
'user' => $this->validatedData['mysql_root_user'],
'password' => $this->validatedData['mysql_root_pass'],
]
]
];
// enable sql ssl in userdata for unprivileged and root db user
if (!empty($this->validatedData['mysql_ssl_ca_file']) && isset($this->validatedData['mysql_ssl_verify_server_certificate'])) {
$userdata['sql']['ssl'] = [
'caFile' => $this->validatedData['mysql_ssl_ca_file'],
'verifyServerCertificate' => (bool)$this->validatedData['mysql_ssl_verify_server_certificate'],
];
$userdata['sql_root']['0']['ssl'] = [
'caFile' => $this->validatedData['mysql_ssl_ca_file'],
'verifyServerCertificate' => (bool)$this->validatedData['mysql_ssl_verify_server_certificate'],
];
}
// test if we can store the userdata.inc.php in ../lib
$umask = @umask(077);
$userdata = PhpHelper::parseArrayToPhpFile($userdata);
$userdata_file = dirname(__FILE__, 5) . '/lib/userdata.inc.php';
if (@touch($userdata_file) && @is_writable($userdata_file)) {
$fp = @fopen($userdata_file, 'w');
@fputs($fp, $userdata, strlen($userdata));
@fclose($fp);
} else {
@unlink($userdata_file);
// try creating it in a temporary file
$temp_file = @tempnam(sys_get_temp_dir(), 'fx');
if ($temp_file) {
$fp = @fopen($temp_file, 'w');
@fputs($fp, $userdata, strlen($userdata));
@fclose($fp);
} else {
throw new Exception('creating_configfile_failed');
}
}
@umask($umask);
}
}

View File

@ -490,11 +490,11 @@ class PhpHelper
$str = sprintf("<?php\n// %s\n\n", $comment ?? 'autogenerated froxlor file');
if ($asReturn) {
return $str . sprintf("return %s;\n\n", rtrim(self::parseArrayToString($array), "\n,"));
return $str . sprintf("return %s;\n", rtrim(self::parseArrayToString($array), "\n,"));
}
foreach ($array as $var => $arr) {
$str .= sprintf("\$%s = %s;\n\n", $var, rtrim(self::parseArrayToString($arr), "\n,"));
$str .= sprintf("\$%s = %s;\n", $var, rtrim(self::parseArrayToString($arr), "\n,"));
}
return $str;
}

View File

@ -32,93 +32,135 @@ return [
'step1' => [
'title' => lng('install.database.title'),
'fields' => [
'sql_hostname' => [
'label' => lng('sql_hostname'),
'mysql_host' => [
'label' => lng('mysql_host'),
'type' => 'text',
'mandatory' => true,
'value' => old('sql_hostname', 'localhost', 'installation')
'value' => old('mysql_host', 'localhost', 'installation')
],
'sql_root_username' => [
'label' => lng('sql_root_username'),
'mysql_root_user' => [
'label' => lng('mysql_root_user'),
'type' => 'text',
'mandatory' => true,
'value' => old('sql_root_username', 'froxroot', 'installation'),
'value' => old('mysql_root_user', 'froxroot', 'installation'),
'next_to' => [
'sql_root_password' => [
'label' => lng('sql_root_password'),
'mysql_root_pass' => [
'label' => lng('mysql_root_pass'),
'type' => 'password',
'mandatory' => true,
'value' => old('sql_root_password', null, 'installation'),
'value' => old('mysql_root_pass', null, 'installation'),
],
]
],
'sql_username' => [
'label' => lng('sql_username'),
'mysql_unprivileged_user' => [
'label' => lng('mysql_unprivileged_user'),
'type' => 'text',
'mandatory' => true,
'value' => old('sql_username', 'froxlor', 'installation'),
'value' => old('mysql_unprivileged_user', 'froxlor', 'installation'),
'next_to' => [
'sql_password' => [
'label' => lng('sql_password'),
'mysql_unprivileged_pass' => [
'label' => lng('mysql_unprivileged_pass'),
'type' => 'password',
'mandatory' => true,
'value' => old('sql_password', null, 'installation'),
'value' => old('mysql_unprivileged_pass', null, 'installation'),
],
]
],
'sql_database' => [
'label' => lng('sql_database'),
'mysql_database' => [
'label' => lng('mysql_database'),
'type' => 'text',
'mandatory' => true,
'value' => old('sql_database', 'froxlor', 'installation'),
'value' => old('mysql_database', 'froxlor', 'installation'),
],
'sql_override_database' => [
'label' => lng('sql_override_database'),
'mysql_force_create' => [
'label' => lng('mysql_force_create'),
'type' => 'checkbox',
'value' => '1',
'checked' => old('sql_override_database', '0', 'installation')
'checked' => old('mysql_force_create', '0', 'installation')
],
'mysql_access_host' => [
'label' => lng('mysql_access_host'),
'type' => 'text',
'mandatory' => true,
'value' => old('mysql_access_host', '127.0.0.1,localhost', 'installation'),
],
]
],
'step2' => [
'title' => lng('install.admin.title'),
'fields' => [
'name' => [
'label' => lng('name'),
'admin_name' => [
'label' => lng('admin_name'),
'type' => 'text',
'mandatory' => true,
'value' => old('name', 'Administrator', 'installation'),
'value' => old('admin_name', 'Administrator', 'installation'),
],
'username' => [
'label' => lng('username'),
'admin_user' => [
'label' => lng('admin_user'),
'type' => 'text',
'mandatory' => true,
'value' => old('username', 'admin', 'installation'),
'value' => old('admin_user', 'admin', 'installation'),
],
'password' => [
'label' => lng('password'),
'admin_pass' => [
'label' => lng('admin_pass'),
'type' => 'password',
'mandatory' => true,
'value' => old('password', null, 'installation'),
'value' => old('admin_pass', null, 'installation'),
],
'email' => [
'label' => lng('email'),
'admin_email' => [
'label' => lng('admin_email'),
'type' => 'text',
'mandatory' => true,
'value' => old('email', null, 'installation'),
'value' => old('admin_email', null, 'installation'),
],
]
],
'step3' => [
'title' => lng('install.system.title'),
'fields' => [
'system' => [
'label' => lng('install.system.system'),
'distribution' => [
'label' => lng('distribution'),
'type' => 'select',
'select_var' => $this->supportedOS,
],
'test' => [
'label' => lng('install.system.test'),
'serverip' => [
'label' => lng('serverip'),
'type' => 'text',
'mandatory' => true,
'value' => old('serverip', null, 'installation'),
],
'servername' => [
'label' => lng('servername'),
'type' => 'text',
'mandatory' => true,
'value' => old('servername', null, 'installation'),
],
'use_ssl' => [
'label' => lng('use_ssl'),
'type' => 'checkbox',
'value' => '1',
'checked' => old('use_ssl', '0', 'installation'),
],
'webserver' => [
'label' => lng('webserver'),
'type' => 'text',
'mandatory' => true,
'value' => old('webserver', 'apache24', 'installation'),
],
'httpuser' => [
'label' => lng('httpuser'),
'type' => 'text',
'mandatory' => true,
'value' => old('httpuser', 'www-data', 'installation'),
],
'httpgroup' => [
'label' => lng('httpgroup'),
'type' => 'text',
'mandatory' => true,
'value' => old('httpgroup', 'www-data', 'installation'),
],
'activate_newsfeed' => [
'label' => lng('activate_newsfeed'),
'type' => 'checkbox',
'value' => '1',
'checked' => false