Baïkal can be configured to use MySQL right at initialization.

This commit is contained in:
Jérôme Schneider 2012-11-07 14:47:50 +01:00
parent c9cfebf6d8
commit 57a7987932
16 changed files with 503 additions and 207 deletions

View file

@ -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);

View file

@ -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() {
}
}

View 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");
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View 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>&nbsp;</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");
}
}
}

View file

@ -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;
}
}

View file

@ -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&iuml;kal Install Tool";
$sFileName = "ENABLE_INSTALL";
} else {
if(!defined("BAIKAL_ADMIN_AUTOLOCKENABLED") || BAIKAL_ADMIN_AUTOLOCKENABLED === FALSE) {
return TRUE;
}
$sToolName = "Ba&iuml;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&iuml;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&iuml;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");
}
}

View file

@ -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>

View file

@ -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 %}

View 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 {
}

View file

@ -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

View file

@ -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
View file