Baïkal can be configured to use MySQL right at initialization.
This commit is contained in:
parent
c9cfebf6d8
commit
57a7987932
16 changed files with 503 additions and 207 deletions
|
@ -67,9 +67,9 @@ class Tools {
|
|||
}
|
||||
|
||||
# Asserting that the database is structurally complete
|
||||
if(($aMissingTables = self::isDBStructurallyComplete($GLOBALS["DB"])) !== TRUE) {
|
||||
throw new \Exception("<strong>Fatal error</strong>: Database is not structurally complete; missing tables are: <strong>" . implode("</strong>, <strong>", $aMissingTables) . "</strong>");
|
||||
}
|
||||
#if(($aMissingTables = self::isDBStructurallyComplete($GLOBALS["DB"])) !== TRUE) {
|
||||
# throw new \Exception("<strong>Fatal error</strong>: Database is not structurally complete; missing tables are: <strong>" . implode("</strong>, <strong>", $aMissingTables) . "</strong>");
|
||||
#}
|
||||
|
||||
# Asserting config file exists
|
||||
if(!file_exists(PROJECT_PATH_SPECIFIC . "config.php")) {
|
||||
|
@ -101,10 +101,9 @@ class Tools {
|
|||
throw new \Exception("Specific/config.system.php is not writable. Please give write permissions to httpd user on file 'Specific/config.system.php'.");
|
||||
}
|
||||
}
|
||||
|
||||
public static function isDBStructurallyComplete(\Flake\Core\Database $oDB) {
|
||||
|
||||
$aRequiredTables = array(
|
||||
|
||||
public static function getRequiredTablesList() {
|
||||
return array(
|
||||
"addressbooks",
|
||||
"calendarobjects",
|
||||
"calendars",
|
||||
|
@ -114,8 +113,13 @@ class Tools {
|
|||
"principals",
|
||||
"users",
|
||||
);
|
||||
}
|
||||
|
||||
public static function isDBStructurallyComplete(\Flake\Core\Database $oDB) {
|
||||
|
||||
$aRequiredTables = self::getRequiredTablesList();
|
||||
$aPresentTables = $oDB->tables();
|
||||
|
||||
$aIntersect = array_intersect($aRequiredTables, $aPresentTables);
|
||||
if(count($aIntersect) !== count($aRequiredTables)) {
|
||||
return array_diff($aRequiredTables, $aIntersect);
|
||||
|
|
|
@ -47,8 +47,16 @@ abstract class Config extends \Flake\Core\Model\NoDb {
|
|||
}
|
||||
|
||||
protected function getConfigAsString() {
|
||||
$sContent = file_get_contents($this->sConfigFilePath);
|
||||
return str_replace(LF . CR, LF, $sContent);
|
||||
if(file_exists($this->sConfigFilePath)) {
|
||||
$sContent = file_get_contents($this->sConfigFilePath);
|
||||
return str_replace(LF . CR, LF, $sContent);
|
||||
} else {
|
||||
|
||||
$sConfig = "<?php\n" . \Baikal\Core\Tools::getCopyrightNotice() . "\n\n";
|
||||
$sConfig .= static::getDefaultConfig();
|
||||
|
||||
return $sConfig;
|
||||
}
|
||||
}
|
||||
|
||||
protected function parseConfig($sString) {
|
||||
|
@ -222,8 +230,11 @@ abstract class Config extends \Flake\Core\Model\NoDb {
|
|||
|
||||
file_put_contents($this->sConfigFilePath, $sLines);
|
||||
}
|
||||
|
||||
|
||||
public function destroy() {
|
||||
|
||||
}
|
||||
|
||||
protected static function getDefaultConfig() {
|
||||
}
|
||||
}
|
117
Core/Frameworks/Baikal/Model/Config/Database.php
Normal file
117
Core/Frameworks/Baikal/Model/Config/Database.php
Normal file
|
@ -0,0 +1,117 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://baikal.codr.fr
|
||||
#
|
||||
# This script is part of the Baïkal Server project. The Baïkal
|
||||
# Server project 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.
|
||||
#
|
||||
# The GNU General Public License can be found at
|
||||
# http://www.gnu.org/copyleft/gpl.html.
|
||||
#
|
||||
# This script 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.
|
||||
#
|
||||
# This copyright notice MUST APPEAR in all copies of the script!
|
||||
#################################################################
|
||||
|
||||
namespace Baikal\Model\Config;
|
||||
|
||||
class Database extends \Baikal\Model\Config {
|
||||
|
||||
protected $aConstants = array(
|
||||
"PROJECT_SQLITE_FILE" => array(
|
||||
"type" => "litteral",
|
||||
"comment" => "Define path to Baïkal Database SQLite file",
|
||||
),
|
||||
"PROJECT_DB_MYSQL" => array(
|
||||
"type" => "boolean",
|
||||
"comment" => "MySQL > Use MySQL instead of SQLite ?",
|
||||
),
|
||||
"PROJECT_DB_MYSQL_HOST" => array(
|
||||
"type" => "string",
|
||||
"comment" => "MySQL > Host, including ':portnumber' if port is not the default one (3306)",
|
||||
),
|
||||
"PROJECT_DB_MYSQL_DBNAME" => array(
|
||||
"type" => "string",
|
||||
"comment" => "MySQL > Database name",
|
||||
),
|
||||
"PROJECT_DB_MYSQL_USERNAME" => array(
|
||||
"type" => "string",
|
||||
"comment" => "MySQL > Username",
|
||||
),
|
||||
"PROJECT_DB_MYSQL_PASSWORD" => array(
|
||||
"type" => "string",
|
||||
"comment" => "MySQL > Password",
|
||||
),
|
||||
);
|
||||
|
||||
# Default values
|
||||
protected $aData = array(
|
||||
"PROJECT_SQLITE_FILE" => 'PROJECT_PATH_SPECIFIC . "db/db.sqlite"',
|
||||
"PROJECT_DB_MYSQL" => FALSE,
|
||||
"PROJECT_DB_MYSQL_HOST" => "",
|
||||
"PROJECT_DB_MYSQL_DBNAME" => "",
|
||||
"PROJECT_DB_MYSQL_USERNAME" => "",
|
||||
"PROJECT_DB_MYSQL_PASSWORD" => "",
|
||||
);
|
||||
|
||||
public function formMorphologyForThisModelInstance() {
|
||||
$oMorpho = new \Formal\Form\Morphology();
|
||||
|
||||
$oMorpho->add(new \Formal\Element\Text(array(
|
||||
"prop" => "PROJECT_SQLITE_FILE",
|
||||
"label" => "SQLite file path",
|
||||
"validation" => "required",
|
||||
"inputclass" => "input-xxlarge",
|
||||
"help" => "The absolute server path to the SQLite file",
|
||||
)));
|
||||
|
||||
$oMorpho->add(new \Formal\Element\Checkbox(array(
|
||||
"prop" => "PROJECT_DB_MYSQL",
|
||||
"label" => "Use MySQL",
|
||||
"help" => "If checked, Baïkal will use MySQL instead of SQLite.",
|
||||
"refreshonchange" => TRUE,
|
||||
)));
|
||||
|
||||
$oMorpho->add(new \Formal\Element\Text(array(
|
||||
"prop" => "PROJECT_DB_MYSQL_HOST",
|
||||
"label" => "MySQL host",
|
||||
"help" => "Host ip or name, including <strong>':portnumber'</strong> if port is not the default one (3306)"
|
||||
)));
|
||||
|
||||
$oMorpho->add(new \Formal\Element\Text(array(
|
||||
"prop" => "PROJECT_DB_MYSQL_DBNAME",
|
||||
"label" => "MySQL database name",
|
||||
)));
|
||||
|
||||
$oMorpho->add(new \Formal\Element\Text(array(
|
||||
"prop" => "PROJECT_DB_MYSQL_USERNAME",
|
||||
"label" => "MySQL username",
|
||||
)));
|
||||
|
||||
$oMorpho->add(new \Formal\Element\Password(array(
|
||||
"prop" => "PROJECT_DB_MYSQL_PASSWORD",
|
||||
"label" => "MySQL password",
|
||||
)));
|
||||
|
||||
return $oMorpho;
|
||||
}
|
||||
|
||||
public function label() {
|
||||
return "Baïkal Database Settings";
|
||||
}
|
||||
|
||||
protected static function getDefaultConfig() {
|
||||
throw new \Exception("Should never reach getDefaultConfig() on \Baikal\Model\Config\Database");
|
||||
}
|
||||
}
|
|
@ -31,7 +31,7 @@ class Standard extends \Baikal\Model\Config {
|
|||
protected $aConstants = array(
|
||||
"PROJECT_TIMEZONE" => array(
|
||||
"type" => "string",
|
||||
"comment" => "Timezone of your users, if unsure, check http://en.wikipedia.org/wiki/List_of_tz_database_time_zones",
|
||||
"comment" => "Timezone of the server; if unsure, check http://en.wikipedia.org/wiki/List_of_tz_database_time_zones",
|
||||
),
|
||||
"BAIKAL_CARD_ENABLED" => array(
|
||||
"type" => "boolean",
|
||||
|
@ -70,29 +70,11 @@ class Standard extends \Baikal\Model\Config {
|
|||
|
||||
$oMorpho->add(new \Formal\Element\Listbox(array(
|
||||
"prop" => "PROJECT_TIMEZONE",
|
||||
"label" => "Time zone",
|
||||
"label" => "Server Time zone",
|
||||
"validation" => "required",
|
||||
"options" => \Baikal\Core\Tools::timezones(),
|
||||
"help" => "Time zone of the server"
|
||||
)));
|
||||
|
||||
$oMorpho->add(new \Formal\Element\Checkbox(array(
|
||||
"prop" => "BAIKAL_ADMIN_ENABLED",
|
||||
"label" => "Enable Web Admin",
|
||||
"popover" => array(
|
||||
"title" => "Warning !",
|
||||
"content" => "If disabled, you'll lose access to this very admin interface !",
|
||||
),
|
||||
)));
|
||||
|
||||
$oMorpho->add(new \Formal\Element\Checkbox(array(
|
||||
"prop" => "BAIKAL_ADMIN_AUTOLOCKENABLED",
|
||||
"label" => "Enable Web Admin autolock",
|
||||
"popover" => array(
|
||||
"title" => "Web admin autolock",
|
||||
"content" => "If enabled, you'll have to create a file named ENABLE_ADMIN in Specific/ prior to every admin use."
|
||||
)
|
||||
)));
|
||||
|
||||
$oMorpho->add(new \Formal\Element\Checkbox(array(
|
||||
"prop" => "BAIKAL_CAL_ENABLED",
|
||||
|
@ -106,12 +88,12 @@ class Standard extends \Baikal\Model\Config {
|
|||
|
||||
$oMorpho->add(new \Formal\Element\Password(array(
|
||||
"prop" => "BAIKAL_ADMIN_PASSWORDHASH",
|
||||
"label" => "Web admin password",
|
||||
"label" => "Admin password",
|
||||
)));
|
||||
|
||||
$oMorpho->add(new \Formal\Element\Password(array(
|
||||
"prop" => "BAIKAL_ADMIN_PASSWORDHASH_CONFIRM",
|
||||
"label" => "Web admin password confirmation",
|
||||
"label" => "Admin password, confirmation",
|
||||
"validation" => "sameas:BAIKAL_ADMIN_PASSWORDHASH",
|
||||
)));
|
||||
|
||||
|
@ -124,6 +106,24 @@ class Standard extends \Baikal\Model\Config {
|
|||
$oMorpho->element("BAIKAL_ADMIN_PASSWORDHASH")->setOption("placeholder", $sNotice);
|
||||
$oMorpho->element("BAIKAL_ADMIN_PASSWORDHASH_CONFIRM")->setOption("placeholder", $sNotice);
|
||||
}
|
||||
|
||||
$oMorpho->add(new \Formal\Element\Checkbox(array(
|
||||
"prop" => "BAIKAL_ADMIN_ENABLED",
|
||||
"label" => "Enable Web interface (recommended)",
|
||||
"popover" => array(
|
||||
"title" => "Warning !",
|
||||
"content" => "If disabled, you'll lose access to this very admin interface !",
|
||||
),
|
||||
)));
|
||||
|
||||
$oMorpho->add(new \Formal\Element\Checkbox(array(
|
||||
"prop" => "BAIKAL_ADMIN_AUTOLOCKENABLED",
|
||||
"label" => "Web interface autolock",
|
||||
"popover" => array(
|
||||
"title" => "Web admin autolock",
|
||||
"content" => "If enabled, you'll have to create a file named <strong>ENABLE_ADMIN</strong> in the folder <strong>Specific/</strong> prior to every admin use.<br /><br />This enforces security, but might be uncomfortable if you use the admin frequently."
|
||||
)
|
||||
)));
|
||||
|
||||
return $oMorpho;
|
||||
}
|
||||
|
@ -156,4 +156,53 @@ class Standard extends \Baikal\Model\Config {
|
|||
|
||||
return parent::get($sProp);
|
||||
}
|
||||
|
||||
protected function createDefaultConfigFilesIfNeeded() {
|
||||
|
||||
# Create empty config.php if needed
|
||||
if(!file_exists(PROJECT_PATH_SPECIFIC . "config.php")) {
|
||||
@touch(PROJECT_PATH_SPECIFIC . "config.php");
|
||||
$sContent = "<?php\n" . \Baikal\Core\Tools::getCopyrightNotice() . "\n\n";
|
||||
$sContent .= $this->getDefaultConfig();
|
||||
file_put_contents(PROJECT_PATH_SPECIFIC . "config.php", $sContent);
|
||||
}
|
||||
|
||||
# Create empty config.system.php if needed
|
||||
if(!file_exists(PROJECT_PATH_SPECIFIC . "config.system.php")) {
|
||||
@touch(PROJECT_PATH_SPECIFIC . "config.system.php");
|
||||
$sContent = "<?php\n" . \Baikal\Core\Tools::getCopyrightNotice() . "\n\n";
|
||||
$sContent .= $this->getDefaultSystemConfig();
|
||||
file_put_contents(PROJECT_PATH_SPECIFIC . "config.system.php", $sContent);
|
||||
}
|
||||
}
|
||||
|
||||
protected static function getDefaultConfig() {
|
||||
|
||||
$sCode =<<<CODE
|
||||
##############################################################################
|
||||
# Required configuration
|
||||
# You *have* to review these settings for Baïkal to run properly
|
||||
#
|
||||
|
||||
# Timezone of your users, if unsure, check http://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
||||
define("PROJECT_TIMEZONE", "Europe/Paris");
|
||||
|
||||
# CardDAV ON/OFF switch; default TRUE
|
||||
define("BAIKAL_CARD_ENABLED", TRUE);
|
||||
|
||||
# CalDAV ON/OFF switch; default TRUE
|
||||
define("BAIKAL_CAL_ENABLED", TRUE);
|
||||
|
||||
# Baïkal Web Admin ON/OFF switch; default TRUE
|
||||
define("BAIKAL_ADMIN_ENABLED", TRUE);
|
||||
|
||||
# Baïkal Web Admin autolock ON/OFF switch; default FALSE
|
||||
define("BAIKAL_ADMIN_AUTOLOCKENABLED", FALSE);
|
||||
|
||||
# Baïkal Web admin password hash; Set via Baïkal Web Admin
|
||||
define("BAIKAL_ADMIN_PASSWORDHASH", "");
|
||||
CODE;
|
||||
$sCode = trim($sCode);
|
||||
return $sCode;
|
||||
}
|
||||
}
|
|
@ -29,14 +29,6 @@ namespace Baikal\Model\Config;
|
|||
class System extends \Baikal\Model\Config {
|
||||
|
||||
protected $aConstants = array(
|
||||
"BAIKAL_STANDALONE_ALLOWED" => array(
|
||||
"type" => "boolean",
|
||||
"comment" => "Standalone Server, allowed or not; default FALSE",
|
||||
),
|
||||
"BAIKAL_STANDALONE_PORT" => array(
|
||||
"type" => "integer",
|
||||
"comment" => "Standalone Server, port number; default 8888",
|
||||
),
|
||||
"BAIKAL_PATH_SABREDAV" => array(
|
||||
"type" => "litteral",
|
||||
"comment" => "PATH to SabreDAV",
|
||||
|
@ -59,7 +51,7 @@ class System extends \Baikal\Model\Config {
|
|||
),
|
||||
"PROJECT_DB_MYSQL" => array(
|
||||
"type" => "boolean",
|
||||
"comment" => "MySQL > Use mysql instead of SQLite ?",
|
||||
"comment" => "MySQL > Use MySQL instead of SQLite ?",
|
||||
),
|
||||
"PROJECT_DB_MYSQL_HOST" => array(
|
||||
"type" => "string",
|
||||
|
@ -89,8 +81,6 @@ class System extends \Baikal\Model\Config {
|
|||
|
||||
# Default values
|
||||
protected $aData = array(
|
||||
"BAIKAL_STANDALONE_ALLOWED" => FALSE,
|
||||
"BAIKAL_STANDALONE_PORT" => 8888,
|
||||
"BAIKAL_PATH_SABREDAV" => 'PROJECT_PATH_FRAMEWORKS . "SabreDAV/lib/Sabre/"',
|
||||
"BAIKAL_AUTH_REALM" => "BaikalDAV",
|
||||
"BAIKAL_CARD_BASEURI" => 'PROJECT_BASEURI . "card.php/"',
|
||||
|
@ -141,18 +131,6 @@ class System extends \Baikal\Model\Config {
|
|||
)
|
||||
)));
|
||||
|
||||
if(\Flake\Util\Frameworks::enabled("BaikalStandalone")) {
|
||||
$oMorpho->add(new \Formal\Element\Checkbox(array(
|
||||
"prop" => "BAIKAL_STANDALONE_ALLOWED",
|
||||
"label" => "Allow Standalone Baïkal execution"
|
||||
)));
|
||||
|
||||
$oMorpho->add(new \Formal\Element\Text(array(
|
||||
"prop" => "BAIKAL_STANDALONE_PORT",
|
||||
"label" => "Standalone Baïkal port"
|
||||
)));
|
||||
}
|
||||
|
||||
$oMorpho->add(new \Formal\Element\Text(array(
|
||||
"prop" => "BAIKAL_PATH_SABREDAV",
|
||||
"label" => "Path to SabreDAV",
|
||||
|
@ -208,4 +186,59 @@ class System extends \Baikal\Model\Config {
|
|||
public function label() {
|
||||
return "Baïkal Settings";
|
||||
}
|
||||
|
||||
protected static function getDefaultConfig() {
|
||||
|
||||
$sBaikalVersion = BAIKAL_VERSION;
|
||||
|
||||
$sCode =<<<CODE
|
||||
##############################################################################
|
||||
# System configuration
|
||||
# Should not be changed, unless YNWYD
|
||||
#
|
||||
# RULES
|
||||
# 0. All folder pathes *must* be suffixed by "/"
|
||||
# 1. All URIs *must* be suffixed by "/" if pointing to a folder
|
||||
#
|
||||
|
||||
# PATH to SabreDAV
|
||||
define("BAIKAL_PATH_SABREDAV", PROJECT_PATH_FRAMEWORKS . "SabreDAV/lib/Sabre/");
|
||||
|
||||
# If you change this value, you'll have to re-generate passwords for all your users
|
||||
define("BAIKAL_AUTH_REALM", "BaikalDAV");
|
||||
|
||||
# Should begin and end with a "/"
|
||||
define("BAIKAL_CARD_BASEURI", PROJECT_BASEURI . "card.php/");
|
||||
|
||||
# Should begin and end with a "/"
|
||||
define("BAIKAL_CAL_BASEURI", PROJECT_BASEURI . "cal.php/");
|
||||
|
||||
# Define path to Baïkal Database SQLite file
|
||||
define("PROJECT_SQLITE_FILE", PROJECT_PATH_SPECIFIC . "db/db.sqlite");
|
||||
|
||||
# MySQL > Use MySQL instead of SQLite ?
|
||||
define("PROJECT_DB_MYSQL", FALSE);
|
||||
|
||||
# MySQL > Host, including ':portnumber' if port is not the default one (3306)
|
||||
define("PROJECT_DB_MYSQL_HOST", "");
|
||||
|
||||
# MySQL > Database name
|
||||
define("PROJECT_DB_MYSQL_DBNAME", "");
|
||||
|
||||
# MySQL > Username
|
||||
define("PROJECT_DB_MYSQL_USERNAME", "");
|
||||
|
||||
# MySQL > Password
|
||||
define("PROJECT_DB_MYSQL_PASSWORD", "");
|
||||
|
||||
# A random 32 bytes key that will be used to encrypt data
|
||||
define("BAIKAL_ENCRYPTION_KEY", "");
|
||||
|
||||
# The currently configured Baïkal version
|
||||
define("BAIKAL_CONFIGURED_VERSION", "{$sBaikalVersion}");
|
||||
|
||||
CODE;
|
||||
$sCode = trim($sCode);
|
||||
return $sCode;
|
||||
}
|
||||
}
|
165
Core/Frameworks/BaikalAdmin/Controller/Install/Database.php
Normal file
165
Core/Frameworks/BaikalAdmin/Controller/Install/Database.php
Normal file
|
@ -0,0 +1,165 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://baikal.codr.fr
|
||||
#
|
||||
# This script is part of the Baïkal Server project. The Baïkal
|
||||
# Server project 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.
|
||||
#
|
||||
# The GNU General Public License can be found at
|
||||
# http://www.gnu.org/copyleft/gpl.html.
|
||||
#
|
||||
# This script 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.
|
||||
#
|
||||
# This copyright notice MUST APPEAR in all copies of the script!
|
||||
#################################################################
|
||||
|
||||
namespace BaikalAdmin\Controller\Install;
|
||||
|
||||
class Database extends \Flake\Core\Controller {
|
||||
|
||||
protected $aMessages = array();
|
||||
protected $oModel;
|
||||
protected $oForm; # \Formal\Form
|
||||
|
||||
public function execute() {
|
||||
$this->oModel = new \Baikal\Model\Config\Database(PROJECT_PATH_SPECIFIC . "config.system.php");
|
||||
|
||||
$this->oForm = $this->oModel->formForThisModelInstance(array(
|
||||
"close" => FALSE,
|
||||
"hook.validation" => array($this, "validateMySQLConnection"),
|
||||
"hook.morphology" => array($this, "hideMySQLFieldWhenNeeded"),
|
||||
));
|
||||
|
||||
if($this->oForm->submitted()) {
|
||||
$this->oForm->execute();
|
||||
|
||||
if($this->oForm->persisted()) {
|
||||
|
||||
# nothing here
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function render() {
|
||||
$sBigIcon = "glyph2x-magic";
|
||||
$sBaikalVersion = BAIKAL_VERSION;
|
||||
|
||||
$oView = new \BaikalAdmin\View\Install\Database();
|
||||
$oView->setData("baikalversion", BAIKAL_VERSION);
|
||||
|
||||
if($this->oForm->persisted()) {
|
||||
|
||||
\BaikalAdmin\Core\Auth::lockInstall();
|
||||
|
||||
$sMessage = "<p>Baïkal is now installed, and it's database properly configured. <strong>For security reasons, this installation wizard is now disabled.</strong></p>";
|
||||
$sMessage . "<p> </p>";
|
||||
$sMessage .= "<p><a class='btn btn-success' href='" . PROJECT_URI . "admin/'>Start using Baïkal</a></p>";
|
||||
$sForm = "";
|
||||
} else {
|
||||
$sMessage = "";
|
||||
$sForm = $this->oForm->render();
|
||||
}
|
||||
|
||||
$oView->setData("message", $sMessage);
|
||||
$oView->setData("form", $sForm);
|
||||
|
||||
return $oView->render();
|
||||
}
|
||||
|
||||
public function validateMySQLConnection($oForm, $oMorpho) {
|
||||
|
||||
$bMySQLEnabled = $oMorpho->element("PROJECT_DB_MYSQL")->value();
|
||||
|
||||
if($bMySQLEnabled) {
|
||||
|
||||
$sHost = $oMorpho->element("PROJECT_DB_MYSQL_HOST")->value();
|
||||
$sDbname = $oMorpho->element("PROJECT_DB_MYSQL_DBNAME")->value();
|
||||
$sUsername = $oMorpho->element("PROJECT_DB_MYSQL_USERNAME")->value();
|
||||
$sPassword = $oMorpho->element("PROJECT_DB_MYSQL_PASSWORD")->value();
|
||||
|
||||
try {
|
||||
$oDb = new \Flake\Core\Database\Mysql(
|
||||
$sHost,
|
||||
$sDbname,
|
||||
$sUsername,
|
||||
$sPassword
|
||||
);
|
||||
|
||||
if(($aMissingTables = \Baikal\Core\Tools::isDBStructurallyComplete($oDb)) !== TRUE) {
|
||||
|
||||
# Checking if all tables are missing
|
||||
$aRequiredTables = \Baikal\Core\Tools::getRequiredTablesList();
|
||||
if(count($aRequiredTables) !== count($aMissingTables)) {
|
||||
$sMessage = "<br /><p><strong>Database is not structurally complete.</strong></p>";
|
||||
$sMessage .= "<p>Missing tables are: <strong>" . implode("</strong>, <strong>", $aMissingTables) . "</strong></p>";
|
||||
$sMessage .= "<p>You will find the SQL definition of Baïkal tables in this file: <strong>Core/Resources/Db/MySQL/db.sql</strong></p>";
|
||||
$sMessage .= "<br /><p>Nothing has been saved. <strong>Please, add these tables to the database before pursuing Baïkal initialization.</strong></p>";
|
||||
|
||||
$oForm->declareError(
|
||||
$oMorpho->element("PROJECT_DB_MYSQL"),
|
||||
$sMessage
|
||||
);
|
||||
} else {
|
||||
# All tables are missing
|
||||
# We add these tables ourselves to the database, to initialize Baïkal
|
||||
$sSqlDefinition = file_get_contents(PROJECT_PATH_CORERESOURCES . "Db/MySQL/db.sql");
|
||||
$oDb->query($sSqlDefinition);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
} catch(\Exception $e) {
|
||||
$oForm->declareError(
|
||||
$oMorpho->element("PROJECT_DB_MYSQL"),
|
||||
"Baïkal was not able to establish a connexion to the MySQL database as configured.<br />MySQL says: " . $e->getMessage()
|
||||
);
|
||||
|
||||
$oForm->declareError(
|
||||
$oMorpho->element("PROJECT_DB_MYSQL_HOST")
|
||||
);
|
||||
|
||||
$oForm->declareError(
|
||||
$oMorpho->element("PROJECT_DB_MYSQL_DBNAME")
|
||||
);
|
||||
|
||||
$oForm->declareError(
|
||||
$oMorpho->element("PROJECT_DB_MYSQL_USERNAME")
|
||||
);
|
||||
|
||||
$oForm->declareError(
|
||||
$oMorpho->element("PROJECT_DB_MYSQL_PASSWORD")
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function hideMySQLFieldWhenNeeded(\Formal\Form $oForm, \Formal\Form\Morphology $oMorpho) {
|
||||
|
||||
if($oForm->submitted()) {
|
||||
$bMySQL = (intval($oForm->postValue("PROJECT_DB_MYSQL")) === 1);
|
||||
} else {
|
||||
$bMySQL = PROJECT_DB_MYSQL;
|
||||
}
|
||||
|
||||
if($bMySQL === TRUE) {
|
||||
$oMorpho->remove("PROJECT_SQLITE_FILE");
|
||||
} else {
|
||||
|
||||
$oMorpho->remove("PROJECT_DB_MYSQL_HOST");
|
||||
$oMorpho->remove("PROJECT_DB_MYSQL_DBNAME");
|
||||
$oMorpho->remove("PROJECT_DB_MYSQL_USERNAME");
|
||||
$oMorpho->remove("PROJECT_DB_MYSQL_PASSWORD");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -37,17 +37,11 @@ class Initialize extends \Flake\Core\Controller {
|
|||
if(!file_exists(PROJECT_PATH_SPECIFIC) || !is_dir(PROJECT_PATH_SPECIFIC) || !is_writable(PROJECT_PATH_SPECIFIC)) {
|
||||
throw new \Exception("Specific/ dir is readonly. Baïkal Admin requires write permissions on this dir.");
|
||||
}
|
||||
|
||||
$this->createDefaultConfigFilesIfNeeded();
|
||||
|
||||
$this->createHtaccessFilesIfNeeded();
|
||||
|
||||
$this->oModel = new \Baikal\Model\Config\Standard(PROJECT_PATH_SPECIFIC . "config.php");
|
||||
|
||||
# Assert that config file is writable
|
||||
if(!$this->oModel->writable()) {
|
||||
throw new \Exception("Config file is not writable;" . __FILE__ . " > " . __LINE__);
|
||||
}
|
||||
|
||||
$this->oForm = $this->oModel->formForThisModelInstance(array(
|
||||
"close" => FALSE
|
||||
));
|
||||
|
@ -56,22 +50,19 @@ class Initialize extends \Flake\Core\Controller {
|
|||
$this->oForm->execute();
|
||||
|
||||
if($this->oForm->persisted()) {
|
||||
$sContent = file_get_contents(PROJECT_PATH_SPECIFIC . "config.system.php");
|
||||
|
||||
$sBaikalVersion = BAIKAL_VERSION;
|
||||
$sEncryptionKey = md5(microtime() . rand());
|
||||
|
||||
# Setting "BAIKAL_CONFIGURED_VERSION"
|
||||
$sNewConstants =<<<PHP
|
||||
# A random 32 bytes key that will be used to encrypt data
|
||||
define("BAIKAL_ENCRYPTION_KEY", "{$sEncryptionKey}");
|
||||
|
||||
# The currently configured Baïkal version
|
||||
define("BAIKAL_CONFIGURED_VERSION", "{$sBaikalVersion}");
|
||||
PHP;
|
||||
|
||||
# Writing results to file
|
||||
file_put_contents(PROJECT_PATH_SPECIFIC . "config.system.php", $sContent . "\n\n" . $sNewConstants);
|
||||
# Creating system config, and initializing BAIKAL_ENCRYPTION_KEY
|
||||
$oSystemConfig = new \Baikal\Model\Config\System(PROJECT_PATH_SPECIFIC . "config.system.php");
|
||||
$oSystemConfig->set("BAIKAL_ENCRYPTION_KEY", md5(microtime() . rand()));
|
||||
$oSystemConfig->persist();
|
||||
|
||||
# Using default PROJECT_SQLITE_FILE
|
||||
$PROJECT_SQLITE_FILE = PROJECT_PATH_SPECIFIC . "db/db.sqlite";
|
||||
|
||||
if(!file_exists($PROJECT_SQLITE_FILE)) {
|
||||
# Installing default sqlite database
|
||||
@copy(PROJECT_PATH_CORERESOURCES . "Db/SQLite/db.sqlite", $PROJECT_SQLITE_FILE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -84,8 +75,12 @@ PHP;
|
|||
$oView->setData("baikalversion", BAIKAL_VERSION);
|
||||
|
||||
if($this->oForm->persisted()) {
|
||||
$sMessage = "<p>Baïkal is now configured. You may now <a class='btn btn-success' href='" . PROJECT_URI . "admin/'>Access the Baïkal admin</a></h2>";
|
||||
$sForm = "";
|
||||
$sLink = PROJECT_URI . "admin/install/?/database";
|
||||
\Flake\Util\Tools::redirect($sLink);
|
||||
exit(0);
|
||||
|
||||
#$sMessage = "<p>Baïkal is now configured. You may <a class='btn btn-success' href='" . PROJECT_URI . "admin/'>Access the Baïkal admin</a></p>";
|
||||
#$sForm = "";
|
||||
} else {
|
||||
$sMessage = "";
|
||||
$sForm = $this->oForm->render();
|
||||
|
@ -97,10 +92,6 @@ PHP;
|
|||
return $oView->render();
|
||||
}
|
||||
|
||||
protected function tagConfiguredVersion() {
|
||||
file_put_contents(PROJECT_PATH_SPECIFIC . "config.php", $sContent);
|
||||
}
|
||||
|
||||
protected function createHtaccessFilesIfNeeded() {
|
||||
|
||||
if(!file_exists(PROJECT_PATH_DOCUMENTROOT . ".htaccess")) {
|
||||
|
@ -119,105 +110,4 @@ PHP;
|
|||
throw new \Exception("Unable to create " . PROJECT_PATH_SPECIFIC . ".htaccess; you may try to create it manually by copying " . PROJECT_PATH_CORERESOURCES . "System/htaccess-specific");
|
||||
}
|
||||
}
|
||||
|
||||
protected function createDefaultConfigFilesIfNeeded() {
|
||||
|
||||
# Create empty config.php if needed
|
||||
if(!file_exists(PROJECT_PATH_SPECIFIC . "config.php")) {
|
||||
@touch(PROJECT_PATH_SPECIFIC . "config.php");
|
||||
$sContent = "<?php\n" . \Baikal\Core\Tools::getCopyrightNotice() . "\n\n";
|
||||
$sContent .= $this->getDefaultConfig();
|
||||
file_put_contents(PROJECT_PATH_SPECIFIC . "config.php", $sContent);
|
||||
}
|
||||
|
||||
# Create empty config.system.php if needed
|
||||
if(!file_exists(PROJECT_PATH_SPECIFIC . "config.system.php")) {
|
||||
@touch(PROJECT_PATH_SPECIFIC . "config.system.php");
|
||||
$sContent = "<?php\n" . \Baikal\Core\Tools::getCopyrightNotice() . "\n\n";
|
||||
$sContent .= $this->getDefaultSystemConfig();
|
||||
file_put_contents(PROJECT_PATH_SPECIFIC . "config.system.php", $sContent);
|
||||
}
|
||||
}
|
||||
|
||||
protected function getDefaultConfig() {
|
||||
|
||||
$sCode =<<<CODE
|
||||
##############################################################################
|
||||
# Required configuration
|
||||
# You *have* to review these settings for Baïkal to run properly
|
||||
#
|
||||
|
||||
# Timezone of your users, if unsure, check http://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
||||
define("PROJECT_TIMEZONE", "Europe/Paris");
|
||||
|
||||
# CardDAV ON/OFF switch; default TRUE
|
||||
define("BAIKAL_CARD_ENABLED", TRUE);
|
||||
|
||||
# CalDAV ON/OFF switch; default TRUE
|
||||
define("BAIKAL_CAL_ENABLED", TRUE);
|
||||
|
||||
# Baïkal Web Admin ON/OFF switch; default TRUE
|
||||
define("BAIKAL_ADMIN_ENABLED", TRUE);
|
||||
|
||||
# Baïkal Web Admin autolock ON/OFF switch; default FALSE
|
||||
define("BAIKAL_ADMIN_AUTOLOCKENABLED", FALSE);
|
||||
|
||||
# Baïkal Web admin password hash; Set via Baïkal Web Admin
|
||||
define("BAIKAL_ADMIN_PASSWORDHASH", "");
|
||||
CODE;
|
||||
$sCode = trim($sCode);
|
||||
return $sCode;
|
||||
}
|
||||
|
||||
protected function getDefaultSystemConfig() {
|
||||
$sCode =<<<CODE
|
||||
##############################################################################
|
||||
# System configuration
|
||||
# Should not be changed, unless YNWYD
|
||||
#
|
||||
# RULES
|
||||
# 0. All folder pathes *must* be suffixed by "/"
|
||||
# 1. All URIs *must* be suffixed by "/" if pointing to a folder
|
||||
#
|
||||
|
||||
# Standalone Server, allowed or not; default FALSE
|
||||
define("BAIKAL_STANDALONE_ALLOWED", FALSE);
|
||||
|
||||
# Standalone Server, port number; default 8888
|
||||
define("BAIKAL_STANDALONE_PORT", 8888);
|
||||
|
||||
# PATH to SabreDAV
|
||||
define("BAIKAL_PATH_SABREDAV", PROJECT_PATH_FRAMEWORKS . "SabreDAV/lib/Sabre/");
|
||||
|
||||
# If you change this value, you'll have to re-generate passwords for all your users
|
||||
define("BAIKAL_AUTH_REALM", "BaikalDAV");
|
||||
|
||||
# Should begin and end with a "/"
|
||||
define("BAIKAL_CARD_BASEURI", PROJECT_BASEURI . "card.php/");
|
||||
|
||||
# Should begin and end with a "/"
|
||||
define("BAIKAL_CAL_BASEURI", PROJECT_BASEURI . "cal.php/");
|
||||
|
||||
# Define path to Baïkal Database SQLite file
|
||||
define("PROJECT_SQLITE_FILE", PROJECT_PATH_SPECIFIC . "db/db.sqlite");
|
||||
|
||||
# MySQL > Use mysql instead of SQLite ?
|
||||
define("PROJECT_DB_MYSQL", FALSE);
|
||||
|
||||
# MySQL > Host, including ':portnumber' if port is not the default one (3306)
|
||||
define("PROJECT_DB_MYSQL_HOST", "");
|
||||
|
||||
# MySQL > Database name
|
||||
define("PROJECT_DB_MYSQL_DBNAME", "");
|
||||
|
||||
# MySQL > Username
|
||||
define("PROJECT_DB_MYSQL_USERNAME", "");
|
||||
|
||||
# MySQL > Password
|
||||
define("PROJECT_DB_MYSQL_PASSWORD", "");
|
||||
|
||||
CODE;
|
||||
$sCode = trim($sCode);
|
||||
return $sCode;
|
||||
}
|
||||
}
|
|
@ -36,19 +36,22 @@ class Auth {
|
|||
}
|
||||
|
||||
public static function assertUnlocked() {
|
||||
|
||||
if(!defined("BAIKAL_ADMIN_AUTOLOCKENABLED") || BAIKAL_ADMIN_AUTOLOCKENABLED === FALSE) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
if(defined("BAIKAL_CONTEXT_INSTALL") && BAIKAL_CONTEXT_INSTALL === TRUE) {
|
||||
$sToolName = "Baïkal Install Tool";
|
||||
$sFileName = "ENABLE_INSTALL";
|
||||
} else {
|
||||
if(!defined("BAIKAL_ADMIN_AUTOLOCKENABLED") || BAIKAL_ADMIN_AUTOLOCKENABLED === FALSE) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
$sToolName = "Baïkal Admin";
|
||||
$sFileName = "ENABLE_ADMIN";
|
||||
}
|
||||
|
||||
$sEnableFile = PROJECT_PATH_SPECIFIC . $sFileName;
|
||||
|
||||
$bLocked = TRUE;
|
||||
$sEnableFile = PROJECT_PATH_SPECIFIC . "ENABLE_ADMIN";
|
||||
if(file_exists($sEnableFile)) {
|
||||
|
||||
clearstatcache();
|
||||
|
@ -63,13 +66,13 @@ class Auth {
|
|||
// file has been created more than an hour ago
|
||||
// delete and declare locked
|
||||
if(!@unlink($sEnableFile)) {
|
||||
die("<h1>" . $sToolName . " is locked.</h1>To unlock it, delete and re-create an empty file named ENABLE_ADMIN in <b>Specific/config.php</b>");
|
||||
die("<h1>" . $sToolName . " is locked.</h1>To unlock it, create (or re-create if it exists already) an empty file named <strong>" . $sFileName . "</strong> (uppercase, no file extension) in the <b>Specific/</b> folder of Baïkal.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($bLocked) {
|
||||
die("<h1>" . $sToolName . " is locked.</h1>To unlock it, create an empty file named ENABLE_ADMIN in <b>Specific/</b>");
|
||||
die("<h1>" . $sToolName . " is locked.</h1>To unlock it, create (or re-create if it exists already) an empty file named <strong>" . $sFileName . "</strong> (uppercase, no file extension) in the <b>Specific/</b> folder of Baïkal.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -106,6 +109,20 @@ class Auth {
|
|||
}
|
||||
|
||||
public static function hashAdminPassword($sPassword) {
|
||||
return md5('admin:' . BAIKAL_AUTH_REALM . ':' . $sPassword);
|
||||
if(defined("BAIKAL_AUTH_REALM")) {
|
||||
$sAuthRealm = BAIKAL_AUTH_REALM;
|
||||
} else {
|
||||
$sAuthRealm = "BaikalDAV"; # Fallback to default value; useful when initializing App, as all constants are not set yet
|
||||
}
|
||||
|
||||
return md5('admin:' . $sAuthRealm . ':' . $sPassword);
|
||||
}
|
||||
|
||||
public static function lockAdmin() {
|
||||
@unlink(PROJECT_PATH_SPECIFIC . "ENABLE_ADMIN");
|
||||
}
|
||||
|
||||
public static function lockInstall() {
|
||||
@unlink(PROJECT_PATH_SPECIFIC . "ENABLE_INSTALL");
|
||||
}
|
||||
}
|
|
@ -54,9 +54,9 @@
|
|||
</div>
|
||||
<div class="span6">
|
||||
<h2>License and credits</h2>
|
||||
<p>Baïkal is open source software, and released under the terms of the GNU GPL v3.</p>
|
||||
<p>Baïkal is based upon other open source projects. Read the <a href="https://github.com/jeromeschneider/Baikal/blob/master/README.md" target="_blank">README.md</a> file to learn about that.</p>
|
||||
<p>Baïkal is developed by <a href="http://base8.fr" target="_blank"><img src="res/core/BaikalAdmin/Images/logo-framboise.png" style="height: 32px; vertical-align:text-bottom;" /></a> <a href="http://base8.fr" target="_blank">Base8</a>. We'd love to hear from you at <a href="mailto:contact@base8.fr">contact@base8.fr</a></p>
|
||||
<p>Baïkal is open source software licensed under the terms of the GNU GPL v3.</p>
|
||||
<p>Baïkal is based upon other open source projects.<br />Read the <a href="https://github.com/jeromeschneider/Baikal/blob/master/README.md" target="_blank">README.md</a> file to learn about that.</p>
|
||||
<p>Baïkal is happily developed by <a href="http://base8.fr" target="_blank"><img src="res/core/BaikalAdmin/Images/logo-framboise.png" style="height: 32px; vertical-align:text-bottom;" /></a> <a href="http://base8.fr" target="_blank">Base8</a>.<br />We'd love to hear from you at <a href="mailto:contact@base8.fr">contact@base8.fr</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
{% autoescape false %}
|
||||
<header class="jumbotron subhead" id="overview">
|
||||
<h1><i class="glyph2x-magic"></i>Baïkal Database setup</h1>
|
||||
<p class="lead">Configure Baïkal Database.</p>
|
||||
</header>
|
||||
|
||||
<a id="formid"></a>
|
||||
{{ message }}
|
||||
{{ form }}
|
||||
|
||||
{% endautoescape %}
|
8
Core/Frameworks/BaikalAdmin/Route/Install.php → Core/Frameworks/BaikalAdmin/View/Install/Database.php
Executable file → Normal file
8
Core/Frameworks/BaikalAdmin/Route/Install.php → Core/Frameworks/BaikalAdmin/View/Install/Database.php
Executable file → Normal file
|
@ -24,11 +24,7 @@
|
|||
# This copyright notice MUST APPEAR in all copies of the script!
|
||||
#################################################################
|
||||
|
||||
namespace BaikalAdmin\Route;
|
||||
namespace BaikalAdmin\View\Install;
|
||||
|
||||
class Install extends \Flake\Core\Route {
|
||||
|
||||
public static function layout(\Flake\Core\Render\Container &$oRenderContainer) {
|
||||
$oRenderContainer->zone("Payload")->addBlock(new \BaikalAdmin\Controller\Install());
|
||||
}
|
||||
class Database extends \BaikalAdmin\Core\View {
|
||||
}
|
|
@ -65,8 +65,12 @@ if(!defined("BAIKAL_CONFIGURED_VERSION")) {
|
|||
# we have to set an admin password
|
||||
$oPage->zone("Payload")->addBlock(new \BaikalAdmin\Controller\Install\Initialize());
|
||||
} else {
|
||||
# we have to upgrade Baïkal
|
||||
$oPage->zone("Payload")->addBlock(new \BaikalAdmin\Controller\Install\VersionUpgrade());
|
||||
if(BAIKAL_CONFIGURED_VERSION !== BAIKAL_VERSION) {
|
||||
# we have to upgrade Baïkal
|
||||
$oPage->zone("Payload")->addBlock(new \BaikalAdmin\Controller\Install\VersionUpgrade());
|
||||
} else {
|
||||
$oPage->zone("Payload")->addBlock(new \BaikalAdmin\Controller\Install\Database());
|
||||
}
|
||||
}
|
||||
|
||||
# Render the page
|
||||
|
|
|
@ -31,7 +31,6 @@ $GLOBALS["ROUTES"] = array(
|
|||
"users" => "\BaikalAdmin\Route\Users",
|
||||
"users/calendars" => "\BaikalAdmin\Route\User\Calendars",
|
||||
"users/addressbooks" => "\BaikalAdmin\Route\User\AddressBooks",
|
||||
"install" => "\BaikalAdmin\Route\Install",
|
||||
"settings/standard" => "\BaikalAdmin\Route\Settings\Standard",
|
||||
"settings/system" => "\BaikalAdmin\Route\Settings\System",
|
||||
"logout" => "\BaikalAdmin\Route\Logout"
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 1de6d8dc3d6408619cd23dda28ce7d6284ad63e9
|
||||
Subproject commit 6c97f964f10287c4f6b31f7397947b5152b0e948
|
|
@ -1 +1 @@
|
|||
Subproject commit d83f38d3880a82650ea4f93c815a8211245f58fe
|
||||
Subproject commit 1663200604730cd7bf27795f3d215b226e050431
|
0
Specific/ENABLE_INSTALL
Normal file
0
Specific/ENABLE_INSTALL
Normal file
Loading…
Reference in a new issue