diff --git a/.gitignore b/.gitignore index 8adf1ca..0897e1f 100755 --- a/.gitignore +++ b/.gitignore @@ -2,8 +2,7 @@ logs # Specific -Specific/config.php -Specific/config.system.php +config/baikal.yaml Specific/INSTALL_DISABLED # Composer stuff @@ -15,3 +14,9 @@ vendor # Vim .*.swp + +# Others +.DS_Store + +# IDE +nbproject diff --git a/CHANGELOG.md b/CHANGELOG.md index 49a44d5..6500a53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ ChangeLog ========= +0.7.0 (2019-10-14) +------------------ + +* Changed to YAML configuration files +* Minor configuration improvements + 0.6.1 (2019-11-13) ------------------ diff --git a/Core/Distrib.php b/Core/Distrib.php index 3b49278..125aeff 100644 --- a/Core/Distrib.php +++ b/Core/Distrib.php @@ -24,5 +24,5 @@ # This copyright notice MUST APPEAR in all copies of the script! ################################################################# -define("BAIKAL_VERSION", "0.6.1"); +define("BAIKAL_VERSION", "0.7.0"); define("BAIKAL_HOMEPAGE", "http://sabre.io/baikal/"); diff --git a/Core/Frameworks/Baikal/Core/Server.php b/Core/Frameworks/Baikal/Core/Server.php index 09aaee5..46a8f0c 100644 --- a/Core/Frameworks/Baikal/Core/Server.php +++ b/Core/Frameworks/Baikal/Core/Server.php @@ -28,6 +28,7 @@ namespace Baikal\Core; use PDO; +use Symfony\Component\Yaml\Yaml; /** * The Baikal Server @@ -131,6 +132,12 @@ class Server { */ protected function initServer() { + try { + $config = Yaml::parseFile(PROJECT_PATH_CONFIG . "baikal.yaml"); + } catch (\Exception $e) { + error_log('Error reading baikal.yaml file : ' . $e->getMessage()); + } + if ($this->authType === 'Basic') { $authBackend = new \Baikal\Core\PDOBasicAuth($this->pdo, $this->authRealm); } else { @@ -171,8 +178,8 @@ class Server { $this->server->addPlugin(new \Sabre\CalDAV\Schedule\Plugin()); $this->server->addPlugin(new \Sabre\DAV\Sharing\Plugin()); $this->server->addPlugin(new \Sabre\CalDAV\SharingPlugin()); - if (defined("BAIKAL_INVITE_FROM") && BAIKAL_INVITE_FROM !== "") { - $this->server->addPlugin(new \Sabre\CalDAV\Schedule\IMipPlugin(BAIKAL_INVITE_FROM)); + if (isset($config['system']["invite_from"]) && $config['system']["invite_from"] !== "") { + $this->server->addPlugin(new \Sabre\CalDAV\Schedule\IMipPlugin($config['system']["invite_from"])); } } if ($this->enableCardDAV) { diff --git a/Core/Frameworks/Baikal/Core/Tools.php b/Core/Frameworks/Baikal/Core/Tools.php index 9c1caae..cc4a610 100644 --- a/Core/Frameworks/Baikal/Core/Tools.php +++ b/Core/Frameworks/Baikal/Core/Tools.php @@ -73,33 +73,18 @@ class Tools { #} # Asserting config file exists - if (!file_exists(PROJECT_PATH_SPECIFIC . "config.php")) { - throw new \Exception("Specific/config.php does not exist. Please use the Install tool to create it."); + if (!file_exists(PROJECT_PATH_CONFIG . "baikal.yaml")) { + throw new \Exception("config/baikal.yaml does not exist. Please use the Install tool to create it or duplicate baikal.yaml.dist."); } # Asserting config file is readable - if (!is_readable(PROJECT_PATH_SPECIFIC . "config.php")) { - throw new \Exception("Specific/config.php is not readable. Please give read permissions to httpd user on file 'Specific/config.php'."); + if (!is_readable(PROJECT_PATH_CONFIG . "baikal.yaml")) { + throw new \Exception("config/baikal.yaml is not readable. Please give read permissions to httpd user on file 'config/baikal.yaml'."); } # Asserting config file is writable - if (!is_writable(PROJECT_PATH_SPECIFIC . "config.php")) { - throw new \Exception("Specific/config.php is not writable. Please give write permissions to httpd user on file 'Specific/config.php'."); - } - - # Asserting system config file exists - if (!file_exists(PROJECT_PATH_SPECIFIC . "config.system.php")) { - throw new \Exception("Specific/config.system.php does not exist. Please use the Install tool to create it."); - } - - # Asserting system config file is readable - if (!is_readable(PROJECT_PATH_SPECIFIC . "config.system.php")) { - throw new \Exception("Specific/config.system.php is not readable. Please give read permissions to httpd user on file 'Specific/config.system.php'."); - } - - # Asserting system config file is writable - if (!is_writable(PROJECT_PATH_SPECIFIC . "config.system.php")) { - throw new \Exception("Specific/config.system.php is not writable. Please give write permissions to httpd user on file 'Specific/config.system.php'."); + if (!is_writable(PROJECT_PATH_CONFIG . "baikal.yaml")) { + throw new \Exception("config/baikal.yaml is not writable. Please give write permissions to httpd user on file 'config/baikal.yaml'."); } } diff --git a/Core/Frameworks/Baikal/Framework.php b/Core/Frameworks/Baikal/Framework.php index c1622be..5fd7ca3 100644 --- a/Core/Frameworks/Baikal/Framework.php +++ b/Core/Frameworks/Baikal/Framework.php @@ -27,6 +27,8 @@ namespace Baikal; +use Symfony\Component\Yaml\Yaml; + class Framework extends \Flake\Core\Framework { static function installTool() { @@ -50,30 +52,24 @@ class Framework extends \Flake\Core\Framework { \Baikal\Core\Tools::configureEnvironment(); # Check that a config file exists - if ( - !file_exists(PROJECT_PATH_SPECIFIC . "config.php") || - !file_exists(PROJECT_PATH_SPECIFIC . "config.system.php") - ) { + if (!file_exists(PROJECT_PATH_CONFIG . "baikal.yaml")) { self::installTool(); } else { - require_once(PROJECT_PATH_SPECIFIC . "config.php"); - require_once(PROJECT_PATH_SPECIFIC . "config.system.php"); - date_default_timezone_set(PROJECT_TIMEZONE); + $config = Yaml::parseFile(PROJECT_PATH_CONFIG . "baikal.yaml"); + date_default_timezone_set($config['system']['timezone']); # Check that Baïkal is already configured - if (!defined("BAIKAL_CONFIGURED_VERSION")) { + if (!isset($config['system']['configured_version'])) { self::installTool(); - } else { # Check that running version matches configured version - if (version_compare(BAIKAL_VERSION, BAIKAL_CONFIGURED_VERSION) > 0) { + if (version_compare(BAIKAL_VERSION, $config['system']['configured_version']) > 0) { self::installTool(); - } else { # Check that admin password is set - if (!defined("BAIKAL_ADMIN_PASSWORDHASH")) { + if (!$config['system']['admin_passwordhash']) { self::installTool(); } diff --git a/Core/Frameworks/Baikal/Model/Calendar.php b/Core/Frameworks/Baikal/Model/Calendar.php index 064c062..8ddca09 100644 --- a/Core/Frameworks/Baikal/Model/Calendar.php +++ b/Core/Frameworks/Baikal/Model/Calendar.php @@ -27,6 +27,8 @@ namespace Baikal\Model; +use Symfony\Component\Yaml\Yaml; + class Calendar extends \Flake\Core\Model\Db { const DATATABLE = "calendarinstances"; const PRIMARYKEY = "id"; @@ -39,11 +41,21 @@ class Calendar extends \Flake\Core\Model\Db { "description" => "", "calendarorder" => 0, "calendarcolor" => "", - "timezone" => PROJECT_TIMEZONE, + "timezone" => null, "calendarid" => 0 ]; protected $oCalendar; # Baikal\Model\Calendar\Calendar + function __construct($sPrimary = false) { + parent::__construct($sPrimary); + try { + $config = Yaml::parseFile(PROJECT_PATH_CONFIG . "baikal.yaml"); + $this->set("timezone", $config['system']["timezone"]); + } catch (\Exception $e) { + error_log('Error reading baikal.yaml file : ' . $e->getMessage()); + } + } + protected function initFloating() { parent::initFloating(); $this->oCalendar = new Calendar\Calendar(); diff --git a/Core/Frameworks/Baikal/Model/Config.php b/Core/Frameworks/Baikal/Model/Config.php index 483f9e9..978ee9a 100644 --- a/Core/Frameworks/Baikal/Model/Config.php +++ b/Core/Frameworks/Baikal/Model/Config.php @@ -27,106 +27,44 @@ namespace Baikal\Model; +use Symfony\Component\Yaml\Yaml; + abstract class Config extends \Flake\Core\Model\NoDb { - protected $sConfigFilePath = ""; - protected $aConstants = []; + protected $sConfigFileSection = ""; protected $aData = []; - function __construct($sConfigFilePath) { + function __construct($sConfigFileSection) { # Note: no call to parent::__construct() to avoid erasing $this->aData - $this->sConfigFilePath = $sConfigFilePath; - $aConfig = $this->parseConfig( - $this->getConfigAsString() - ); + $this->sConfigFileSection = $sConfigFileSection; - foreach (array_keys($this->aData) as $sProp) { - if (array_key_exists($sProp, $aConfig)) { - $this->aData[$sProp] = $aConfig[$sProp]; + try { + $config = Yaml::parseFile(PROJECT_PATH_CONFIG . "baikal.yaml"); + $aConfig = $config[$sConfigFileSection]; + foreach (array_keys($this->aData) as $sProp) { + if (array_key_exists($sProp, $aConfig)) { + $this->aData[$sProp] = $aConfig[$sProp]; + } } + } catch (\Exception $e) { + error_log('Error reading baikal.yaml file : ' . $e->getMessage()); + // Keep default values in $aData } } protected function getConfigAsString() { - if (file_exists($this->sConfigFilePath)) { - $sContent = file_get_contents($this->sConfigFilePath); - return str_replace(LF . CR, LF, $sContent); + if (file_exists(PROJECT_PATH_CONFIG . "baikal.yaml")) { + return Yaml::parseFile(PROJECT_PATH_CONFIG . "baikal.yaml")[$this->sConfigFileSection]; } else { - - $sConfig = "aData; } } - protected function parseConfig($sString) { - - $aRes = []; - - foreach (array_keys($this->aConstants) as $sConstant) { - $aConstant = $this->aConstants[$sConstant]; - - $aMatches = []; - $sPattern = '/\s*define\(\s*["|\']' . $sConstant . '["|\']\s*\,\s*(.*?)\s*\);\s*/ix'; - - $iNbRes = preg_match_all( - $sPattern, - $sString, - $aMatches - ); - - if ($iNbRes === 1) { - # Exactly one match - # O would be not enough, and > 1, to much to handle properly - - $sValue = $aMatches[1][0]; # first capture (.*?), first occurence (anyway, we asserted that there's only one) - switch ($aConstant["type"]) { - case "string": { - $sValue = substr($sValue, 1, -1); # Strip quotes - break; - } - case "integer": { - $sValue = intval($sValue); # Integer - break; - } - case "boolean": { - if (in_array(strtoupper(trim($sValue)), ["1", "TRUE"])) { - $sValue = true; - } else { - $sValue = false; - } - break; - } - case "litteral": { - $sValue = trim($sValue); - break; - } - default: { - # nothing - break; - } - } - - $aRes[$sConstant] = $sValue; - - } elseif ($iNbRes > 1) { - throw new \Exception("Baikal\Model\Config->parseConfig(): constant '" . $sConstant . "' has been found multiple times in the config file; stopping execution"); - } else { - # $iNbRes === 0 - # We do nothing, to keep the default value (the one already set in $aData) - } - } - - reset($aRes); - return $aRes; - } - function writable() { return ( - @file_exists($this->sConfigFilePath) && - @is_file($this->sConfigFilePath) && - @is_writable($this->sConfigFilePath) + @file_exists(PROJECT_PATH_CONFIG . "baikal.yaml") && + @is_file(PROJECT_PATH_CONFIG . "baikal.yaml") && + @is_writable(PROJECT_PATH_CONFIG . "baikal.yaml") ); } @@ -147,95 +85,18 @@ abstract class Config extends \Flake\Core\Model\NoDb { } function persist() { - $aLines = explode(LF, $this->getConfigAsString()); - $iLines = count($aLines); - - foreach (array_keys($this->aData) as $prop) { - $sPattern = '/\s*define\(\s*["|\']' . $prop . '["|\']\s*\,\s*(.*?)\s*\);\s*/ix'; - $sValue = $this->aData[$prop]; - - - # We replace value by it's native PHP notation - switch ($this->aConstants[$prop]["type"]) { - case "string": { - $sValue = var_export($sValue, true); # Add quotes, and escape " and all string-termination chars - break; - } - case "integer": { - $sValue = intval($sValue); # Cast as integer - break; - } - case "boolean": { - - if (intval($sValue) === 1) { # Note as a BOOLEAN PHP constant - $sValue = "TRUE"; - } else { - $sValue = "FALSE"; - } - - break; - } - case "litteral": { - $sValue = trim($sValue); - break; - } - default: { - $sValue = "''"; - break; - } - } - - $mFound = false; - for ($k = ($iLines - 1); $k >= 0; $k--) { - if (preg_match($sPattern, $aLines[$k])) { - - # Found the last matching line - $mFound = $k; - break; - } - } - - if ($mFound === false) { - # Adding line at the end of the file - $aLines[] = "\n" . "# " . $this->aConstants[$prop]["comment"] . "\ndefine(\"" . $prop . "\", " . $sValue . ");"; - } else { - $aLines[$mFound] = "define(\"" . $prop . "\", " . $sValue . ");"; - } + if (file_exists(PROJECT_PATH_CONFIG . "baikal.yaml")) { + $config = Yaml::parseFile(PROJECT_PATH_CONFIG . "baikal.yaml"); + } else { + $config = []; + } - - $sLines = implode("\n", $aLines); - $sSandboxedCode = str_replace([""], "", $sLines); - $sRand = (string)rand(); - $sCode = "if(0) {" . $sSandboxedCode . "\n}; echo '" . $sRand . "';"; - ob_start(); - eval($sCode); - $sRes = ob_get_contents(); - ob_end_clean(); - - if ($sRes !== $sRand) { - echo "
" . htmlspecialchars($sLines) . ""; - throw new \Exception("Parse error in new config file. Aborting, nothing has been changed."); - } - - # We asserted that the syntax is OK; - # We now check that all the constants are present, and with the right value - $aNewConfig = $this->parseConfig($sLines); - $aWrittenConfig = $this->aData; - - asort($aNewConfig); - asort($aWrittenConfig); - - if ($aNewConfig != $aWrittenConfig) { - throw new \Exception("New config does not correspond to expected config. Aborting, nothing has been changed."); - } - - file_put_contents($this->sConfigFilePath, $sLines); + $config[$this->sConfigFileSection] = $this->aData; + $yaml = Yaml::dump($config); + file_put_contents(PROJECT_PATH_CONFIG . "baikal.yaml", $yaml); } function destroy() { } - - protected static function getDefaultConfig() { - } } diff --git a/Core/Frameworks/Baikal/Model/Config/Database.php b/Core/Frameworks/Baikal/Model/Config/Database.php index 8a9bb47..0eb0404 100644 --- a/Core/Frameworks/Baikal/Model/Config/Database.php +++ b/Core/Frameworks/Baikal/Model/Config/Database.php @@ -30,27 +30,27 @@ namespace Baikal\Model\Config; class Database extends \Baikal\Model\Config { protected $aConstants = [ - "PROJECT_SQLITE_FILE" => [ + "sqlite_file" => [ "type" => "litteral", "comment" => "Define path to Baïkal Database SQLite file", ], - "PROJECT_DB_MYSQL" => [ + "mysql" => [ "type" => "boolean", "comment" => "MySQL > Use MySQL instead of SQLite ?", ], - "PROJECT_DB_MYSQL_HOST" => [ + "mysql_host" => [ "type" => "string", "comment" => "MySQL > Host, including ':portnumber' if port is not the default one (3306)", ], - "PROJECT_DB_MYSQL_DBNAME" => [ + "mysql_dbname" => [ "type" => "string", "comment" => "MySQL > Database name", ], - "PROJECT_DB_MYSQL_USERNAME" => [ + "mysql_username" => [ "type" => "string", "comment" => "MySQL > Username", ], - "PROJECT_DB_MYSQL_PASSWORD" => [ + "mysql_password" => [ "type" => "string", "comment" => "MySQL > Password", ], @@ -58,19 +58,23 @@ class Database extends \Baikal\Model\Config { # Default values protected $aData = [ - "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" => "", + "sqlite_file" => PROJECT_PATH_SPECIFIC . "db/db.sqlite", + "mysql" => false, + "mysql_host" => "", + "mysql_dbname" => "", + "mysql_username" => "", + "mysql_password" => "", ]; + function __construct() { + parent::__construct("database"); + } + function formMorphologyForThisModelInstance() { $oMorpho = new \Formal\Form\Morphology(); $oMorpho->add(new \Formal\Element\Text([ - "prop" => "PROJECT_SQLITE_FILE", + "prop" => "sqlite_file", "label" => "SQLite file path", "validation" => "required", "inputclass" => "input-xxlarge", @@ -78,30 +82,30 @@ class Database extends \Baikal\Model\Config { ])); $oMorpho->add(new \Formal\Element\Checkbox([ - "prop" => "PROJECT_DB_MYSQL", + "prop" => "mysql", "label" => "Use MySQL", "help" => "If checked, Baïkal will use MySQL instead of SQLite.", "refreshonchange" => true, ])); $oMorpho->add(new \Formal\Element\Text([ - "prop" => "PROJECT_DB_MYSQL_HOST", + "prop" => "mysql_host", "label" => "MySQL host", "help" => "Host ip or name, including ':portnumber' if port is not the default one (3306)" ])); $oMorpho->add(new \Formal\Element\Text([ - "prop" => "PROJECT_DB_MYSQL_DBNAME", + "prop" => "mysql_dbname", "label" => "MySQL database name", ])); $oMorpho->add(new \Formal\Element\Text([ - "prop" => "PROJECT_DB_MYSQL_USERNAME", + "prop" => "mysql_username", "label" => "MySQL username", ])); $oMorpho->add(new \Formal\Element\Password([ - "prop" => "PROJECT_DB_MYSQL_PASSWORD", + "prop" => "mysql_password", "label" => "MySQL password", ])); @@ -111,8 +115,4 @@ class Database extends \Baikal\Model\Config { function label() { return "Baïkal Database Settings"; } - - protected static function getDefaultConfig() { - throw new \Exception("Should never reach getDefaultConfig() on \Baikal\Model\Config\Database"); - } } diff --git a/Core/Frameworks/Baikal/Model/Config/Standard.php b/Core/Frameworks/Baikal/Model/Config/Standard.php index daab958..5507870 100644 --- a/Core/Frameworks/Baikal/Model/Config/Standard.php +++ b/Core/Frameworks/Baikal/Model/Config/Standard.php @@ -27,30 +27,32 @@ namespace Baikal\Model\Config; +use Symfony\Component\Yaml\Yaml; + class Standard extends \Baikal\Model\Config { protected $aConstants = [ - "PROJECT_TIMEZONE" => [ + "timezone" => [ "type" => "string", "comment" => "Timezone of the server; if unsure, check http://en.wikipedia.org/wiki/List_of_tz_database_time_zones", ], - "BAIKAL_CARD_ENABLED" => [ + "card_enabled" => [ "type" => "boolean", "comment" => "CardDAV ON/OFF switch; default TRUE", ], - "BAIKAL_CAL_ENABLED" => [ + "cal_enabled" => [ "type" => "boolean", "comment" => "CalDAV ON/OFF switch; default TRUE", ], - "BAIKAL_INVITE_FROM" => [ + "invite_from" => [ "type" => "string", "comment" => "CalDAV invite From: mail address (comment or leave blank to disable notifications)", ], - "BAIKAL_DAV_AUTH_TYPE" => [ + "dav_auth_type" => [ "type" => "string", "comment" => "HTTP authentication type for WebDAV; default Digest" ], - "BAIKAL_ADMIN_PASSWORDHASH" => [ + "admin_passwordhash" => [ "type" => "string", "comment" => "Baïkal Web admin password hash; Set via Baïkal Web Admin", ] @@ -58,19 +60,25 @@ class Standard extends \Baikal\Model\Config { # Default values protected $aData = [ - "PROJECT_TIMEZONE" => "Europe/Paris", - "BAIKAL_CARD_ENABLED" => true, - "BAIKAL_CAL_ENABLED" => true, - "BAIKAL_INVITE_FROM" => "", - "BAIKAL_DAV_AUTH_TYPE" => "Digest", - "BAIKAL_ADMIN_PASSWORDHASH" => "" - ]; + "configured_version" => BAIKAL_VERSION, + "timezone" => "Europe/Paris", + "card_enabled" => true, + "cal_enabled" => true, + "dav_auth_type" => "Digest", + "admin_passwordhash" => "", + "auth_realm" => "BaikalDAV" +]; + + function __construct() { + $this->aData["invite_from"] = "noreply@" . $_SERVER['SERVER_NAME']; // Default value + parent::__construct("system"); + } function formMorphologyForThisModelInstance() { $oMorpho = new \Formal\Form\Morphology(); $oMorpho->add(new \Formal\Element\Listbox([ - "prop" => "PROJECT_TIMEZONE", + "prop" => "timezone", "label" => "Server Time zone", "validation" => "required", "options" => \Baikal\Core\Tools::timezones(), @@ -78,46 +86,52 @@ class Standard extends \Baikal\Model\Config { $oMorpho->add(new \Formal\Element\Checkbox([ - "prop" => "BAIKAL_CARD_ENABLED", + "prop" => "card_enabled", "label" => "Enable CardDAV" ])); $oMorpho->add(new \Formal\Element\Checkbox([ - "prop" => "BAIKAL_CAL_ENABLED", + "prop" => "cal_enabled", "label" => "Enable CalDAV" ])); $oMorpho->add(new \Formal\Element\Text([ - "prop" => "BAIKAL_INVITE_FROM", + "prop" => "invite_from", "label" => "Email invite sender address", "help" => "Leave empty to disable sending invite emails" ])); $oMorpho->add(new \Formal\Element\Listbox([ - "prop" => "BAIKAL_DAV_AUTH_TYPE", + "prop" => "dav_auth_type", "label" => "WebDAV authentication type", "options" => ["Digest", "Basic"] ])); $oMorpho->add(new \Formal\Element\Password([ - "prop" => "BAIKAL_ADMIN_PASSWORDHASH", + "prop" => "admin_passwordhash", "label" => "Admin password", ])); $oMorpho->add(new \Formal\Element\Password([ - "prop" => "BAIKAL_ADMIN_PASSWORDHASH_CONFIRM", + "prop" => "admin_passwordhash_confirm", "label" => "Admin password, confirmation", - "validation" => "sameas:BAIKAL_ADMIN_PASSWORDHASH", + "validation" => "sameas:admin_passwordhash", ])); - if (!defined("BAIKAL_ADMIN_PASSWORDHASH") || trim(BAIKAL_ADMIN_PASSWORDHASH) === "") { + try { + $config = Yaml::parseFile(PROJECT_PATH_CONFIG . "baikal.yaml"); + } catch (\Exception $e) { + error_log('Error reading baikal.yaml file : ' . $e->getMessage()); + } + + if (!isset($config['system']["admin_passwordhash"]) || trim($config['system']["admin_passwordhash"]) === "") { # No password set (Form is used in install tool), so password is required as it has to be defined - $oMorpho->element("BAIKAL_ADMIN_PASSWORDHASH")->setOption("validation", "required"); + $oMorpho->element("admin_passwordhash")->setOption("validation", "required"); } else { $sNotice = "-- Leave empty to keep current password --"; - $oMorpho->element("BAIKAL_ADMIN_PASSWORDHASH")->setOption("placeholder", $sNotice); - $oMorpho->element("BAIKAL_ADMIN_PASSWORDHASH_CONFIRM")->setOption("placeholder", $sNotice); + $oMorpho->element("admin_passwordhash")->setOption("placeholder", $sNotice); + $oMorpho->element("admin_passwordhash_confirm")->setOption("placeholder", $sNotice); } return $oMorpho; @@ -128,12 +142,12 @@ class Standard extends \Baikal\Model\Config { } function set($sProp, $sValue) { - if ($sProp === "BAIKAL_ADMIN_PASSWORDHASH" || $sProp === "BAIKAL_ADMIN_PASSWORDHASH_CONFIRM") { + if ($sProp === "admin_passwordhash" || $sProp === "admin_passwordhash_confirm") { # Special handling for password and passwordconfirm - if ($sProp === "BAIKAL_ADMIN_PASSWORDHASH" && $sValue !== "") { + if ($sProp === "admin_passwordhash" && $sValue !== "") { parent::set( - "BAIKAL_ADMIN_PASSWORDHASH", + "admin_passwordhash", \BaikalAdmin\Core\Auth::hashAdminPassword($sValue) ); } @@ -145,59 +159,10 @@ class Standard extends \Baikal\Model\Config { } function get($sProp) { - if ($sProp === "BAIKAL_ADMIN_PASSWORDHASH" || $sProp === "BAIKAL_ADMIN_PASSWORDHASH_CONFIRM") { + if ($sProp === "admin_passwordhash" || $sProp === "admin_passwordhash_confirm") { return ""; } 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 = "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 = "getDefaultSystemConfig(); - file_put_contents(PROJECT_PATH_SPECIFIC . "config.system.php", $sContent); - } - } - - protected static function getDefaultConfig() { - - $sCode = <<
[
- "type" => "string",
- "comment" => "If you change this value, you'll have to re-generate passwords for all your users",
- ],
- "BAIKAL_CARD_BASEURI" => [
- "type" => "litteral",
- "comment" => 'Should begin and end with a "/"',
- ],
- "BAIKAL_CAL_BASEURI" => [
- "type" => "litteral",
- "comment" => 'Should begin and end with a "/"',
- ],
- "BAIKAL_DAV_BASEURI" => [
- "type" => "litteral",
- "comment" => 'Should begin and end with a "/"',
- ],
- "PROJECT_SQLITE_FILE" => [
+ "sqlite_file" => [
"type" => "litteral",
"comment" => "Define path to Baïkal Database SQLite file",
],
- "PROJECT_DB_MYSQL" => [
+ "mysql" => [
"type" => "boolean",
"comment" => "MySQL > Use MySQL instead of SQLite ?",
],
- "PROJECT_DB_MYSQL_HOST" => [
+ "mysql_host" => [
"type" => "string",
"comment" => "MySQL > Host, including ':portnumber' if port is not the default one (3306)",
],
- "PROJECT_DB_MYSQL_DBNAME" => [
+ "mysql_dbname" => [
"type" => "string",
"comment" => "MySQL > Database name",
],
- "PROJECT_DB_MYSQL_USERNAME" => [
+ "mysql_username" => [
"type" => "string",
"comment" => "MySQL > Username",
],
- "PROJECT_DB_MYSQL_PASSWORD" => [
+ "mysql_password" => [
"type" => "string",
"comment" => "MySQL > Password",
],
- "BAIKAL_ENCRYPTION_KEY" => [
+ "baikal_encryption_key" => [
"type" => "string",
"comment" => "A random 32 bytes key that will be used to encrypt data",
],
- "BAIKAL_CONFIGURED_VERSION" => [
+ "baikal_configured_version" => [
"type" => "string",
"comment" => "The currently configured Baïkal version",
],
@@ -82,68 +66,25 @@ class System extends \Baikal\Model\Config {
# Default values
protected $aData = [
- "BAIKAL_AUTH_REALM" => "BaikalDAV",
- "BAIKAL_CARD_BASEURI" => 'PROJECT_BASEURI . "card.php/"',
- "BAIKAL_CAL_BASEURI" => 'PROJECT_BASEURI . "cal.php/"',
- "BAIKAL_DAV_BASEURI" => 'PROJECT_BASEURI . "dav.php/"',
- "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" => "",
- "BAIKAL_ENCRYPTION_KEY" => "",
- "BAIKAL_CONFIGURED_VERSION" => "",
+ "sqlite_file" => PROJECT_PATH_SPECIFIC . "db/db.sqlite",
+ "mysql" => false,
+ "mysql_host" => "",
+ "mysql_dbname" => "",
+ "mysql_username" => "",
+ "mysql_password" => "",
+ "encryption_key" => "",
+ "configured_version" => "",
];
+ function __construct() {
+ parent::__construct("database");
+ }
+
function formMorphologyForThisModelInstance() {
$oMorpho = new \Formal\Form\Morphology();
$oMorpho->add(new \Formal\Element\Text([
- "prop" => "BAIKAL_CAL_BASEURI",
- "label" => "CalDAV base URI",
- "validation" => "required",
- "help" => "The absolute web path to cal.php",
- "popover" => [
- "title" => "CalDAV base URI",
- "content" => "If Baïkal is hosted in a subfolder, this path should reflect it.
Whatever happens, it should begin and end with a slash.",
- ]
- ]));
-
- $oMorpho->add(new \Formal\Element\Text([
- "prop" => "BAIKAL_CARD_BASEURI",
- "label" => "CardDAV base URI",
- "validation" => "required",
- "help" => "The absolute web path to card.php",
- "popover" => [
- "title" => "CardDAV base URI",
- "content" => "If Baïkal is hosted in a subfolder, this path should reflect it.
Whatever happens, it should begin and end with a slash."
- ]
- ]));
- $oMorpho->add(new \Formal\Element\Text([
- "prop" => "BAIKAL_DAV_BASEURI",
- "label" => "CalDAV/CardDAV base URI",
- "validation" => "required",
- "help" => "The absolute web path to dav.php",
- "popover" => [
- "title" => "DAV base URI",
- "content" => "If Baïkal is hosted in a subfolder, this path should reflect it.
Whatever happens, it should begin and end with a slash."
- ]
- ]));
-
- $oMorpho->add(new \Formal\Element\Text([
- "prop" => "BAIKAL_AUTH_REALM",
- "label" => "Auth realm",
- "validation" => "required",
- "help" => "Token used in authentication process.
If you change this, you'll have to reset all your users passwords.
You'll also loose access to this admin interface.",
- "popover" => [
- "title" => "Auth realm",
- "content" => "If you change this, you'll loose your access to this interface.
In other words: you should not change this, unless YKWYD."
- ]
- ]));
-
- $oMorpho->add(new \Formal\Element\Text([
- "prop" => "PROJECT_SQLITE_FILE",
+ "prop" => "sqlite_file",
"label" => "SQLite file path",
"validation" => "required",
"inputclass" => "input-xxlarge",
@@ -151,30 +92,30 @@ class System extends \Baikal\Model\Config {
]));
$oMorpho->add(new \Formal\Element\Checkbox([
- "prop" => "PROJECT_DB_MYSQL",
+ "prop" => "mysql",
"label" => "Use MySQL",
"help" => "If checked, Baïkal will use MySQL instead of SQLite.",
"refreshonchange" => true,
]));
$oMorpho->add(new \Formal\Element\Text([
- "prop" => "PROJECT_DB_MYSQL_HOST",
+ "prop" => "mysql_host",
"label" => "MySQL host",
"help" => "Host ip or name, including ':portnumber' if port is not the default one (3306)"
]));
$oMorpho->add(new \Formal\Element\Text([
- "prop" => "PROJECT_DB_MYSQL_DBNAME",
+ "prop" => "mysql_dbname",
"label" => "MySQL database name",
]));
$oMorpho->add(new \Formal\Element\Text([
- "prop" => "PROJECT_DB_MYSQL_USERNAME",
+ "prop" => "mysql_username",
"label" => "MySQL username",
]));
$oMorpho->add(new \Formal\Element\Password([
- "prop" => "PROJECT_DB_MYSQL_PASSWORD",
+ "prop" => "mysql_password",
"label" => "MySQL password",
]));
@@ -184,59 +125,4 @@ class System extends \Baikal\Model\Config {
function label() {
return "Baïkal Settings";
}
-
- protected static function getDefaultConfig() {
-
- $sBaikalVersion = BAIKAL_VERSION;
-
- $sCode = << 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;
- }
}
diff --git a/Core/Frameworks/Baikal/Model/User.php b/Core/Frameworks/Baikal/Model/User.php
index f744f99..9a63898 100644
--- a/Core/Frameworks/Baikal/Model/User.php
+++ b/Core/Frameworks/Baikal/Model/User.php
@@ -27,6 +27,8 @@
namespace Baikal\Model;
+use Symfony\Component\Yaml\Yaml;
+
class User extends \Flake\Core\Model\Db {
const DATATABLE = "users";
const PRIMARYKEY = "id";
@@ -279,6 +281,13 @@ class User extends \Flake\Core\Model\Db {
}
function getPasswordHashForPassword($sPassword) {
- return md5($this->get("username") . ':' . BAIKAL_AUTH_REALM . ':' . $sPassword);
+
+ try {
+ $config = Yaml::parseFile(PROJECT_PATH_CONFIG . "baikal.yaml");
+ } catch (\Exception $e) {
+ error_log('Error reading baikal.yaml file : ' . $e->getMessage());
+ }
+
+ return md5($this->get("username") . ':' . $config['system']['auth_realm'] . ':' . $sPassword);
}
}
diff --git a/Core/Frameworks/BaikalAdmin/Controller/Dashboard.php b/Core/Frameworks/BaikalAdmin/Controller/Dashboard.php
index 9e59da4..0988f22 100644
--- a/Core/Frameworks/BaikalAdmin/Controller/Dashboard.php
+++ b/Core/Frameworks/BaikalAdmin/Controller/Dashboard.php
@@ -27,18 +27,23 @@
namespace BaikalAdmin\Controller;
+use Symfony\Component\Yaml\Yaml;
+
class Dashboard extends \Flake\Core\Controller {
function execute() {
}
function render() {
+
+ $config = Yaml::parseFile(PROJECT_PATH_CONFIG . "baikal.yaml");
+
$oView = new \BaikalAdmin\View\Dashboard();
$oView->setData("BAIKAL_VERSION", BAIKAL_VERSION);
# Services status
- $oView->setData("BAIKAL_CAL_ENABLED", BAIKAL_CAL_ENABLED);
- $oView->setData("BAIKAL_CARD_ENABLED", BAIKAL_CARD_ENABLED);
+ $oView->setData("baikal_cal_enabled", $config['system']['cal_enabled']);
+ $oView->setData("baikal_card_enabled", $config['system']['card_enabled']);
# Statistics: Users
$iNbUsers = \Baikal\Model\User::getBaseRequester()->count();
diff --git a/Core/Frameworks/BaikalAdmin/Controller/Install/Database.php b/Core/Frameworks/BaikalAdmin/Controller/Install/Database.php
index d16a8fa..76a4800 100644
--- a/Core/Frameworks/BaikalAdmin/Controller/Install/Database.php
+++ b/Core/Frameworks/BaikalAdmin/Controller/Install/Database.php
@@ -27,6 +27,8 @@
namespace BaikalAdmin\Controller\Install;
+use Symfony\Component\Yaml\Yaml;
+
class Database extends \Flake\Core\Controller {
protected $aMessages = [];
@@ -34,7 +36,18 @@ class Database extends \Flake\Core\Controller {
protected $oForm; # \Formal\Form
function execute() {
- $this->oModel = new \Baikal\Model\Config\Database(PROJECT_PATH_SPECIFIC . "config.system.php");
+ $this->oModel = new \Baikal\Model\Config\System();
+
+ if (file_exists(PROJECT_PATH_SPECIFIC . "config.system.php")) {
+ require_once(PROJECT_PATH_SPECIFIC . "config.system.php");
+ $this->oModel->set('sqlite_file', PROJECT_SQLITE_FILE);
+ $this->oModel->set('mysql', PROJECT_DB_MYSQL);
+ $this->oModel->set('mysql_host', PROJECT_DB_MYSQL_HOST);
+ $this->oModel->set('mysql_dbname', PROJECT_DB_MYSQL_DBNAME);
+ $this->oModel->set('mysql_username', PROJECT_DB_MYSQL_USERNAME);
+ $this->oModel->set('mysql_password', PROJECT_DB_MYSQL_PASSWORD);
+ $this->oModel->set('encryption_key', BAIKAL_ENCRYPTION_KEY);
+ }
$this->oForm = $this->oModel->formForThisModelInstance([
"close" => false,
@@ -46,6 +59,9 @@ class Database extends \Flake\Core\Controller {
$this->oForm->execute();
if ($this->oForm->persisted()) {
+ if (file_exists(PROJECT_PATH_SPECIFIC . "config.system.php")) {
+ @unlink(PROJECT_PATH_SPECIFIC . "config.system.php");
+ }
touch(PROJECT_PATH_SPECIFIC . '/INSTALL_DISABLED');
}
}
@@ -60,7 +76,7 @@ class Database extends \Flake\Core\Controller {
if ($this->oForm->persisted()) {
- $sMessage = "Baïkal is now installed, and it's database properly configured. For security reasons, this installation wizard is now disabled.
";
+ $sMessage = "Baïkal is now installed, and its database properly configured. For security reasons, this installation wizard is now disabled.
";
$sMessage . "
";
$sMessage .= "";
$sForm = "";
@@ -79,14 +95,14 @@ class Database extends \Flake\Core\Controller {
if ($oForm->refreshed()){
return true;
}
- $bMySQLEnabled = $oMorpho->element("PROJECT_DB_MYSQL")->value();
+ $bMySQLEnabled = $oMorpho->element("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();
+ $sHost = $oMorpho->element("mysql_host")->value();
+ $sDbname = $oMorpho->element("mysql_dbname")->value();
+ $sUsername = $oMorpho->element("mysql_username")->value();
+ $sPassword = $oMorpho->element("mysql_password")->value();
try {
$oDb = new \Flake\Core\Database\Mysql(
@@ -107,7 +123,7 @@ class Database extends \Flake\Core\Controller {
$sMessage .= "
Nothing has been saved. Please, add these tables to the database before pursuing Baïkal initialization.
";
$oForm->declareError(
- $oMorpho->element("PROJECT_DB_MYSQL"),
+ $oMorpho->element("mysql"),
$sMessage
);
} else {
@@ -120,35 +136,29 @@ class Database extends \Flake\Core\Controller {
return true;
} catch (\Exception $e) {
- $oForm->declareError($oMorpho->element("PROJECT_DB_MYSQL"),
+ $oForm->declareError($oMorpho->element("mysql"),
"Baïkal was not able to establish a connexion to the MySQL database as configured.
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"));
+ $oForm->declareError($oMorpho->element("mysql_host"));
+ $oForm->declareError($oMorpho->element("mysql_dbname"));
+ $oForm->declareError($oMorpho->element("mysql_username"));
+ $oForm->declareError($oMorpho->element("mysql_password"));
}
} else {
- $sFile = $oMorpho->element("PROJECT_SQLITE_FILE")->value();
+ $sFile = $oMorpho->element("sqlite_file")->value();
try {
- // not sure yet how to better address this
- // yup! this is mental, but even if we don't use eval, effectively these
- // config settings are eval'ed because they are written as raw php files.
- // We'll have to clean this up later.
- $sFile = eval('return ' . $sFile . ';');
-
# Asserting DB file is writable
if (file_exists($sFile) && !is_writable($sFile)) {
$sMessage = "DB file is not writable. Please give write permissions on file " . $sFile . "";
- $oForm->declareError($oMorpho->element("PROJECT_SQLITE_FILE"), $sMessage);
+ $oForm->declareError($oMorpho->element("sqlite_file"), $sMessage);
return false;
}
# Asserting DB directory is writable
if (!is_writable(dirname($sFile))) {
$sMessage = "The FOLDER containing the DB file is not writable, and it has to.
Please give write permissions on folder " . dirname($sFile) . "";
- $oForm->declareError($oMorpho->element("PROJECT_SQLITE_FILE"), $sMessage);
+ $oForm->declareError($oMorpho->element("sqlite_file"), $sMessage);
return false;
}
@@ -168,7 +178,7 @@ class Database extends \Flake\Core\Controller {
$sMessage .= "
Nothing has been saved. Please, add these tables to the database before pursuing Baïkal initialization.
";
$oForm->declareError(
- $oMorpho->element("PROJECT_SQLITE_FILE"),
+ $oMorpho->element("sqlite_file"),
$sMessage
);
} else {
@@ -185,7 +195,7 @@ class Database extends \Flake\Core\Controller {
return true;
} catch (\Exception $e) {
$oForm->declareError(
- $oMorpho->element("PROJECT_SQLITE_FILE"),
+ $oMorpho->element("sqlite_file"),
"Baïkal was not able to establish a connexion to the SQLite database as configured.
SQLite says: " . $e->getMessage() . (string)$e
);
}
@@ -196,19 +206,24 @@ class Database extends \Flake\Core\Controller {
function hideMySQLFieldWhenNeeded(\Formal\Form $oForm, \Formal\Form\Morphology $oMorpho) {
if ($oForm->submitted()) {
- $bMySQL = (intval($oForm->postValue("PROJECT_DB_MYSQL")) === 1);
+ $bMySQL = (intval($oForm->postValue("mysql")) === 1);
} else {
- $bMySQL = PROJECT_DB_MYSQL;
+ try {
+ $configSystem = Yaml::parseFile(PROJECT_PATH_CONFIG . "baikal.yaml");
+ } catch (\Exception $e) {
+ error_log('Error reading baikal.yaml file : ' . $e->getMessage());
+ }
+ $bMySQL = $configSystem['database']['mysql'] ?? true;
}
if ($bMySQL === true) {
- $oMorpho->remove("PROJECT_SQLITE_FILE");
+ $oMorpho->remove("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");
+ $oMorpho->remove("mysql_host");
+ $oMorpho->remove("mysql_dbname");
+ $oMorpho->remove("mysql_username");
+ $oMorpho->remove("mysql_password");
}
}
}
diff --git a/Core/Frameworks/BaikalAdmin/Controller/Install/Initialize.php b/Core/Frameworks/BaikalAdmin/Controller/Install/Initialize.php
index 04ec977..47c1c79 100644
--- a/Core/Frameworks/BaikalAdmin/Controller/Install/Initialize.php
+++ b/Core/Frameworks/BaikalAdmin/Controller/Install/Initialize.php
@@ -36,16 +36,26 @@ class Initialize extends \Flake\Core\Controller {
function execute() {
# Assert that /Specific is writable
- if (!file_exists(PROJECT_PATH_SPECIFIC) || !is_dir(PROJECT_PATH_SPECIFIC) || !is_writable(PROJECT_PATH_SPECIFIC)) {
- $message = "Error - Insufficient permissions on the Specific/ folder
";
- $message .= "
In order to work properly, Baïkal needs to have write permissions in the Specific/ folder.
";
+ if (!file_exists(PROJECT_PATH_SPECIFIC) || !is_dir(PROJECT_PATH_SPECIFIC) || !is_writable(PROJECT_PATH_SPECIFIC) || !file_exists(PROJECT_PATH_CONFIG) || !is_dir(PROJECT_PATH_CONFIG) || !is_writable(PROJECT_PATH_CONFIG)) {
+ $message = "Error - Insufficient permissions on the configuration folders
";
+ $message .= "
In order to work properly, Baïkal needs to have write permissions in the Specific/ and config/ folder.
";
die($message);
}
$this->createHtaccessFilesIfNeeded();
- $this->oModel = new \Baikal\Model\Config\Standard(PROJECT_PATH_SPECIFIC . "config.php");
+ $this->oModel = new \Baikal\Model\Config\Standard();
+
+ // If we come from pre-0.7.0, we need to get the values from the config.php and config.system.php files
+ if (file_exists(PROJECT_PATH_SPECIFIC . "config.php")) {
+ require_once(PROJECT_PATH_SPECIFIC . "config.php");
+ $this->oModel->set('timezone', PROJECT_TIMEZONE);
+ $this->oModel->set('card_enabled', BAIKAL_CARD_ENABLED);
+ $this->oModel->set('cal_enabled', BAIKAL_CAL_ENABLED);
+ $this->oModel->set('invite_from', BAIKAL_INVITE_FROM);
+ $this->oModel->set('dav_auth_type', BAIKAL_DAV_AUTH_TYPE);
+ }
$this->oForm = $this->oModel->formForThisModelInstance([
"close" => false
@@ -56,14 +66,22 @@ class Initialize extends \Flake\Core\Controller {
if ($this->oForm->persisted()) {
+ // If we come from pre-0.7.0, we need to remove the INSTALL_DISABLED file so we go to the next step
+ if (file_exists(PROJECT_PATH_SPECIFIC . '/INSTALL_DISABLED')) {
+ @unlink(PROJECT_PATH_SPECIFIC . '/INSTALL_DISABLED');
+ }
+ if (file_exists(PROJECT_PATH_SPECIFIC . "config.php")) {
+ @unlink(PROJECT_PATH_SPECIFIC . "config.php");
+ }
+
# 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 = new \Baikal\Model\Config\System("system");
+ $oSystemConfig->set("encryption_key", md5(microtime() . rand()));
# Default: PDO::SQLite or PDO::MySQL ?
$aPDODrivers = \PDO::getAvailableDrivers();
if (!in_array('sqlite', $aPDODrivers)) { # PDO::MySQL is already asserted in \Baikal\Core\Tools::assertEnvironmentIsOk()
- $oSystemConfig->set("PROJECT_DB_MYSQL", true);
+ $oSystemConfig->set("mysql", true);
}
$oSystemConfig->persist();
@@ -79,6 +97,11 @@ class Initialize extends \Flake\Core\Controller {
$oView = new \BaikalAdmin\View\Install\Initialize();
$oView->setData("baikalversion", BAIKAL_VERSION);
+ // If we come from pre-0.7.0 (old config files are still present),
+ // we need to tell the installer page to show a warning message.
+ $oView->setData("oldConfigSystem", file_exists(PROJECT_PATH_SPECIFIC . "config.system.php"));
+
+
if ($this->oForm->persisted()) {
$sLink = PROJECT_URI . "admin/install/?/database";
\Flake\Util\Tools::redirect($sLink);
diff --git a/Core/Frameworks/BaikalAdmin/Controller/Install/UpgradeConfirmation.php b/Core/Frameworks/BaikalAdmin/Controller/Install/UpgradeConfirmation.php
index d4ce825..822df29 100644
--- a/Core/Frameworks/BaikalAdmin/Controller/Install/UpgradeConfirmation.php
+++ b/Core/Frameworks/BaikalAdmin/Controller/Install/UpgradeConfirmation.php
@@ -27,6 +27,8 @@
namespace BaikalAdmin\Controller\Install;
+use Symfony\Component\Yaml\Yaml;
+
class UpgradeConfirmation extends \Flake\Core\Controller {
function execute() {
@@ -35,10 +37,16 @@ class UpgradeConfirmation extends \Flake\Core\Controller {
function render() {
$oView = new \BaikalAdmin\View\Install\UpgradeConfirmation();
- if (BAIKAL_CONFIGURED_VERSION === BAIKAL_VERSION) {
- $sMessage = "Your system is configured to use version " . BAIKAL_CONFIGURED_VERSION . ".
There's no upgrade to be done.";
+ try {
+ $config = Yaml::parseFile(PROJECT_PATH_CONFIG . "baikal.yaml");
+ } catch (\Exception $e) {
+ error_log('Error reading baikal.yaml file : ' . $e->getMessage());
+ }
+
+ if (isset($config['system']['configured_version']) && $config['system']['configured_version'] === BAIKAL_VERSION) {
+ $sMessage = "Your system is configured to use version " . $config['system']['configured_version'] . ".
There's no upgrade to be done.";
} else {
- $sMessage = "Upgrading Baïkal from version " . BAIKAL_CONFIGURED_VERSION . " to version " . BAIKAL_VERSION . "";
+ $sMessage = "Upgrading Baïkal from version " . "Unknown" . " to version " . BAIKAL_VERSION . "";
}
$oView->setData("message", $sMessage);
diff --git a/Core/Frameworks/BaikalAdmin/Controller/Install/VersionUpgrade.php b/Core/Frameworks/BaikalAdmin/Controller/Install/VersionUpgrade.php
index 79d350f..2083615 100644
--- a/Core/Frameworks/BaikalAdmin/Controller/Install/VersionUpgrade.php
+++ b/Core/Frameworks/BaikalAdmin/Controller/Install/VersionUpgrade.php
@@ -27,6 +27,8 @@
namespace BaikalAdmin\Controller\Install;
+use Symfony\Component\Yaml\Yaml;
+
class VersionUpgrade extends \Flake\Core\Controller {
protected $aMessages = [];
@@ -40,11 +42,18 @@ class VersionUpgrade extends \Flake\Core\Controller {
}
function render() {
+
+ try {
+ $config = Yaml::parseFile(PROJECT_PATH_CONFIG . "baikal.yaml");
+ } catch (\Exception $e) {
+ error_log('Error reading baikal.yaml file : ' . $e->getMessage());
+ }
+
$sBigIcon = "glyph2x-magic";
$sBaikalVersion = BAIKAL_VERSION;
- $sBaikalConfiguredVersion = BAIKAL_CONFIGURED_VERSION;
+ $sBaikalConfiguredVersion = $config['system']['configured_version'];
- if (BAIKAL_CONFIGURED_VERSION === BAIKAL_VERSION) {
+ if ($config['system']['configured_version'] === BAIKAL_VERSION) {
$sMessage = "Your system is configured to use version " . $sBaikalConfiguredVersion . ".
There's no upgrade to be done.";
} else {
$sMessage = "Upgrading Baïkal from version " . $sBaikalConfiguredVersion . " to version " . $sBaikalVersion . "";
@@ -58,7 +67,7 @@ class VersionUpgrade extends \Flake\Core\Controller {
HTML;
try {
- $bSuccess = $this->upgrade(BAIKAL_CONFIGURED_VERSION, BAIKAL_VERSION);
+ $bSuccess = $this->upgrade($config['system']['configured_version'], BAIKAL_VERSION);
} catch (\Exception $e) {
$bSuccess = false;
$this->aErrors[] = 'Uncaught exception during upgrade: ' . (string)$e;
@@ -521,26 +530,17 @@ SQL
}
protected function updateConfiguredVersion($sVersionTo) {
-
- # Create new settings
- $oConfig = new \Baikal\Model\Config\Standard(PROJECT_PATH_SPECIFIC . "config.php");
- $oConfig->persist();
-
# Update BAIKAL_CONFIGURED_VERSION
- $oConfig = new \Baikal\Model\Config\System(PROJECT_PATH_SPECIFIC . "config.system.php");
- $oConfig->set("BAIKAL_CONFIGURED_VERSION", $sVersionTo);
+ $oConfig = new \Baikal\Model\Config\System();
+ $oConfig->set("baikal_configured_version", $sVersionTo);
$oConfig->persist();
}
protected function assertConfigWritable() {
# Parsing the config also makes sure that it is not malformed
- $oConfig = new \Baikal\Model\Config\Standard(PROJECT_PATH_SPECIFIC . "config.php");
+ $oConfig = new \Baikal\Model\Config\System();
if ($oConfig->writable() === false) {
- throw new \Exception(PROJECT_PATH_SPECIFIC . "config.php is not writable");
- }
- $oConfig = new \Baikal\Model\Config\System(PROJECT_PATH_SPECIFIC . "config.system.php");
- if ($oConfig->writable() === false) {
- throw new \Exception(PROJECT_PATH_SPECIFIC . "config.system.php is not writable");
+ throw new \Exception(PROJECT_PATH_CONFIG . "baikal.yaml is not writable");
}
}
}
diff --git a/Core/Frameworks/BaikalAdmin/Controller/Settings/Standard.php b/Core/Frameworks/BaikalAdmin/Controller/Settings/Standard.php
index 19e4f27..8782a5a 100644
--- a/Core/Frameworks/BaikalAdmin/Controller/Settings/Standard.php
+++ b/Core/Frameworks/BaikalAdmin/Controller/Settings/Standard.php
@@ -40,7 +40,7 @@ class Standard extends \Flake\Core\Controller {
private $oForm;
function execute() {
- $this->oModel = new \Baikal\Model\Config\Standard(PROJECT_PATH_SPECIFIC . "config.php");
+ $this->oModel = new \Baikal\Model\Config\Standard();
# Assert that config file is writable
if (!$this->oModel->writable()) {
diff --git a/Core/Frameworks/BaikalAdmin/Controller/Settings/System.php b/Core/Frameworks/BaikalAdmin/Controller/Settings/System.php
index 120f74e..9f2c4a3 100644
--- a/Core/Frameworks/BaikalAdmin/Controller/Settings/System.php
+++ b/Core/Frameworks/BaikalAdmin/Controller/Settings/System.php
@@ -27,6 +27,8 @@
namespace BaikalAdmin\Controller\Settings;
+use Symfony\Component\Yaml\Yaml;
+
class System extends \Flake\Core\Controller {
/**
@@ -40,11 +42,11 @@ class System extends \Flake\Core\Controller {
private $oForm;
function execute() {
- $this->oModel = new \Baikal\Model\Config\System(PROJECT_PATH_SPECIFIC . "config.system.php");
+ $this->oModel = new \Baikal\Model\Config\System();
# Assert that config file is writable
if (!$this->oModel->writable()) {
- throw new \Exception("System config file is not writable;" . __FILE__ . " > " . __LINE__);
+ throw new \Exception("Config file is not writable;" . __FILE__ . " > " . __LINE__);
}
$this->oForm = $this->oModel->formForThisModelInstance([
@@ -74,19 +76,24 @@ class System extends \Flake\Core\Controller {
function morphologyHook(\Formal\Form $oForm, \Formal\Form\Morphology $oMorpho) {
if ($oForm->submitted()) {
- $bMySQL = (intval($oForm->postValue("PROJECT_DB_MYSQL")) === 1);
+ $bMySQL = (intval($oForm->postValue("mysql")) === 1);
} else {
- $bMySQL = PROJECT_DB_MYSQL;
+ try {
+ $config = Yaml::parseFile(PROJECT_PATH_CONFIG . "baikal.yaml");
+ } catch (\Exception $e) {
+ error_log('Error reading baikal.yaml file : ' . $e->getMessage());
+ }
+ $bMySQL = $config['database']['mysql'] ?? true;
}
if ($bMySQL === true) {
- $oMorpho->remove("PROJECT_SQLITE_FILE");
+ $oMorpho->remove("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");
+ $oMorpho->remove("mysql_host");
+ $oMorpho->remove("mysql_dbname");
+ $oMorpho->remove("mysql_username");
+ $oMorpho->remove("mysql_password");
}
}
@@ -94,13 +101,13 @@ class System extends \Flake\Core\Controller {
if ($oForm->refreshed()){
return true;
}
- if (intval($oForm->modelInstance()->get("PROJECT_DB_MYSQL")) === 1) {
+ if (intval($oForm->modelInstance()->get("mysql")) === 1) {
# We have to check the MySQL connection
- $sHost = $oForm->modelInstance()->get("PROJECT_DB_MYSQL_HOST");
- $sDbName = $oForm->modelInstance()->get("PROJECT_DB_MYSQL_DBNAME");
- $sUsername = $oForm->modelInstance()->get("PROJECT_DB_MYSQL_USERNAME");
- $sPassword = $oForm->modelInstance()->get("PROJECT_DB_MYSQL_PASSWORD");
+ $sHost = $oForm->modelInstance()->get("mysql_host");
+ $sDbName = $oForm->modelInstance()->get("mysql_dbname");
+ $sUsername = $oForm->modelInstance()->get("mysql_username");
+ $sPassword = $oForm->modelInstance()->get("mysql_password");
try {
$oDB = new \Flake\Core\Database\Mysql(
@@ -112,10 +119,10 @@ class System extends \Flake\Core\Controller {
} catch (\Exception $e) {
$sMessage = "MySQL error: " . $e->getMessage();
$sMessage .= "
Nothing has been saved";
- $oForm->declareError($oMorpho->element("PROJECT_DB_MYSQL_HOST"), $sMessage);
- $oForm->declareError($oMorpho->element("PROJECT_DB_MYSQL_DBNAME"));
- $oForm->declareError($oMorpho->element("PROJECT_DB_MYSQL_USERNAME"));
- $oForm->declareError($oMorpho->element("PROJECT_DB_MYSQL_PASSWORD"));
+ $oForm->declareError($oMorpho->element("mysql_host"), $sMessage);
+ $oForm->declareError($oMorpho->element("mysql_dbname"));
+ $oForm->declareError($oMorpho->element("mysql_username"));
+ $oForm->declareError($oMorpho->element("mysql_password"));
return;
}
@@ -124,31 +131,24 @@ class System extends \Flake\Core\Controller {
$sMessage .= "You may want create these tables using the file Core/Resources/Db/MySQL/db.sql";
$sMessage .= "
Nothing has been saved";
- $oForm->declareError($oMorpho->element("PROJECT_DB_MYSQL"), $sMessage);
+ $oForm->declareError($oMorpho->element("mysql"), $sMessage);
return;
}
} else {
- $sFile = $oMorpho->element("PROJECT_SQLITE_FILE")->value();
+ $sFile = $oMorpho->element("sqlite_file")->value();
try {
-
- // not sure yet how to better address this
- // yup! this is mental, but even if we don't use eval, effectively these
- // config settings are eval'ed because they are written as raw php files.
- // We'll have to clean this up later.
- $sFile = eval('return ' . $sFile . ';');
-
# Asserting DB file is writable
if (file_exists($sFile) && !is_writable($sFile)) {
$sMessage = "DB file is not writable. Please give write permissions on file " . $sFile . "";
- $oForm->declareError($oMorpho->element("PROJECT_SQLITE_FILE"), $sMessage);
+ $oForm->declareError($oMorpho->element("sqlite_file"), $sMessage);
return;
}
# Asserting DB directory is writable
if (!is_writable(dirname($sFile))) {
$sMessage = "The FOLDER containing the DB file is not writable, and it has to.
Please give write permissions on folder " . dirname($sFile) . "";
- $oForm->declareError($oMorpho->element("PROJECT_SQLITE_FILE"), $sMessage);
+ $oForm->declareError($oMorpho->element("sqlite_file"), $sMessage);
return;
}
@@ -164,14 +164,14 @@ class System extends \Flake\Core\Controller {
$sMessage .= "
Nothing has been saved. Please, add these tables to the database before pursuing Baïkal initialization.
";
$oForm->declareError(
- $oMorpho->element("PROJECT_SQLITE_FILE"),
+ $oMorpho->element("sqlite_file"),
$sMessage
);
}
return;
} catch (\Exception $e) {
$oForm->declareError(
- $oMorpho->element("PROJECT_SQLITE_FILE"),
+ $oMorpho->element("sqlite_file"),
"Baïkal was not able to establish a connexion to the SQLite database as configured.
SQLite says: " . $e->getMessage() . (string)$e
);
}
diff --git a/Core/Frameworks/BaikalAdmin/Core/Auth.php b/Core/Frameworks/BaikalAdmin/Core/Auth.php
index 5f4e81c..78b303f 100644
--- a/Core/Frameworks/BaikalAdmin/Core/Auth.php
+++ b/Core/Frameworks/BaikalAdmin/Core/Auth.php
@@ -27,9 +27,14 @@
namespace BaikalAdmin\Core;
+use Symfony\Component\Yaml\Yaml;
+
class Auth {
static function isAuthenticated() {
- if (isset($_SESSION["baikaladminauth"]) && $_SESSION["baikaladminauth"] === md5(BAIKAL_ADMIN_PASSWORDHASH)) {
+
+ $config = Yaml::parseFile(PROJECT_PATH_CONFIG . "baikal.yaml");
+
+ if (isset($_SESSION["baikaladminauth"]) && $_SESSION["baikaladminauth"] === md5($config['system']['admin_passwordhash'])) {
return true;
}
@@ -46,9 +51,13 @@ class Auth {
$sPass = \Flake\Util\Tools::POST("password");
$sPassHash = self::hashAdminPassword($sPass);
-
- if ($sUser === "admin" && $sPassHash === BAIKAL_ADMIN_PASSWORDHASH) {
- $_SESSION["baikaladminauth"] = md5(BAIKAL_ADMIN_PASSWORDHASH);
+ try {
+ $config = Yaml::parseFile(PROJECT_PATH_CONFIG . "baikal.yaml");
+ } catch (\Exception $e) {
+ error_log('Error reading baikal.yaml file : ' . $e->getMessage());
+ }
+ if ($sUser === "admin" && $sPassHash === $config['system']['admin_passwordhash']) {
+ $_SESSION["baikaladminauth"] = md5($config['system']['admin_passwordhash']);
return true;
}
@@ -61,13 +70,17 @@ class Auth {
}
static function hashAdminPassword($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
+
+ try {
+ $config = Yaml::parseFile(PROJECT_PATH_CONFIG . "baikal.yaml");
+ } catch (\Exception $e) {
+ error_log('Error reading baikal.yaml file : ' . $e->getMessage());
}
- return md5('admin:' . $sAuthRealm . ':' . $sPassword);
+ # Fallback to default value; useful when initializing App, as all constants are not set yet
+ $sAuthRealm = $config['system']['auth_realm'] ?? "BaikalDAV";
+
+ return hash('sha256', 'admin:' . $sAuthRealm . ':' . $sPassword);
}
}
diff --git a/Core/Frameworks/BaikalAdmin/Resources/Templates/Dashboard.html b/Core/Frameworks/BaikalAdmin/Resources/Templates/Dashboard.html
index c8ccbda..a426df4 100644
--- a/Core/Frameworks/BaikalAdmin/Resources/Templates/Dashboard.html
+++ b/Core/Frameworks/BaikalAdmin/Resources/Templates/Dashboard.html
@@ -38,7 +38,7 @@
Services
- {% if BAIKAL_CAL_ENABLED %}
+ {% if cal_enabled %}
{% set caldavclass = 'label-success' %}
{% set caldavtext = 'On' %}
{% else %}
@@ -46,7 +46,7 @@
{% set caldavtext = 'Off' %}
{% endif %}
- {% if BAIKAL_CARD_ENABLED %}
+ {% if card_enabled %}
{% set carddavclass = 'label-success' %}
{% set carddavtext = 'On' %}
{% else %}
diff --git a/Core/Frameworks/BaikalAdmin/Resources/Templates/Install/Initialize.html b/Core/Frameworks/BaikalAdmin/Resources/Templates/Install/Initialize.html
index 72791e3..38369d2 100644
--- a/Core/Frameworks/BaikalAdmin/Resources/Templates/Install/Initialize.html
+++ b/Core/Frameworks/BaikalAdmin/Resources/Templates/Install/Initialize.html
@@ -2,6 +2,15 @@
Baïkal initialization wizard
Configure your new Baïkal {{ baikalversion }} installation.
+
+ {% if oldConfigSystem %}
+
+ With the 0.7.0 release, our configuration format was updated to use YAML files.
+ You need to go through this installer again but we pre-filled most values with the ones from your old installation.
+ As we updated our hashing algorithm for the admin interface password, you need to enter it again.
+ The database with your contacts and events stays untouched. We still recommend that you make a full backup of your data before proceeding, as a safety measure.
+
+ {% endif %}
diff --git a/Core/Frameworks/BaikalAdmin/WWWRoot/install/index.php b/Core/Frameworks/BaikalAdmin/WWWRoot/install/index.php
index 547214f..e1dab04 100644
--- a/Core/Frameworks/BaikalAdmin/WWWRoot/install/index.php
+++ b/Core/Frameworks/BaikalAdmin/WWWRoot/install/index.php
@@ -24,6 +24,8 @@
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
+use Symfony\Component\Yaml\Yaml;
+
ini_set("session.cookie_httponly", 1);
ini_set("log_errors", 1);
$maxtime = ini_get('max_execution_time');
@@ -65,15 +67,22 @@ $oPage->setBaseUrl(PROJECT_URI);
$oPage->zone("navbar")->addBlock(new \BaikalAdmin\Controller\Navigation\Topbar\Install());
-if (!defined("BAIKAL_CONFIGURED_VERSION")) {
+try {
+ $config = Yaml::parseFile(PROJECT_PATH_CONFIG . "baikal.yaml");
+} catch (\Exception $e) {
+ $config = null;
+ error_log('Error reading baikal.yaml file : ' . $e->getMessage());
+}
+
+if (!$config || !isset($config['system']["configured_version"])) {
# we have to upgrade Baïkal (existing installation)
$oPage->zone("Payload")->addBlock(new \BaikalAdmin\Controller\Install\Initialize());
-} elseif (!defined("BAIKAL_ADMIN_PASSWORDHASH")) {
+} elseif (!isset($config['system']["admin_passwordhash"])) {
# we have to set an admin password
$oPage->zone("Payload")->addBlock(new \BaikalAdmin\Controller\Install\Initialize());
} else {
- if (BAIKAL_CONFIGURED_VERSION !== BAIKAL_VERSION) {
+ if ($config['system']["configured_version"] !== BAIKAL_VERSION) {
# we have to upgrade Baïkal
if (\Flake\Util\Tools::GET("upgradeConfirmed")) {
$oPage->zone("Payload")->addBlock(new \BaikalAdmin\Controller\Install\VersionUpgrade());
diff --git a/Core/Frameworks/Flake/Framework.php b/Core/Frameworks/Flake/Framework.php
index 50b9c12..4b9ca24 100644
--- a/Core/Frameworks/Flake/Framework.php
+++ b/Core/Frameworks/Flake/Framework.php
@@ -27,6 +27,8 @@
namespace Flake;
+use Symfony\Component\Yaml\Yaml;
+
class Framework extends \Flake\Core\Framework {
static function rmBeginSlash($sString) {
@@ -150,6 +152,7 @@ class Framework extends \Flake\Core\Framework {
define("PROJECT_PATH_CORE", PROJECT_PATH_ROOT . "Core/");
define("PROJECT_PATH_CORERESOURCES", PROJECT_PATH_CORE . "Resources/");
define("PROJECT_PATH_SPECIFIC", PROJECT_PATH_ROOT . "Specific/");
+ define("PROJECT_PATH_CONFIG", PROJECT_PATH_ROOT . "config/");
define("PROJECT_PATH_FRAMEWORKS", PROJECT_PATH_CORE . "Frameworks/");
define("PROJECT_PATH_WWWROOT", PROJECT_PATH_CORE . "WWWRoot/");
@@ -206,94 +209,82 @@ class Framework extends \Flake\Core\Framework {
define("FLAKE_URIPATH", \Flake\Util\Tools::stripBeginSlash($aUrlInfo["path"]));
unset($aUrlInfo);
-
- # Include Project config
- # NOTE: DB initialization and App config files inclusion
- # do not break execution if not properly executed, as
- # these errors will have to be caught later in the process
- # notably by the App install tool, if available; breaking right now
- # would forbid such install tool forwarding, for instance
-
- $sConfigPath = PROJECT_PATH_SPECIFIC . "config.php";
- $sConfigSystemPath = PROJECT_PATH_SPECIFIC . "config.system.php";
-
- if (file_exists($sConfigPath)) {
- require_once($sConfigPath);
- }
-
- if (file_exists($sConfigSystemPath)) {
- require_once($sConfigSystemPath);
- }
-
self::initDb();
}
protected static function initDb() {
- # Dont init db on install, but in normal mode and when upgrading
- if (defined("BAIKAL_CONTEXT_INSTALL") && (!defined('BAIKAL_CONFIGURED_VERSION') || BAIKAL_CONFIGURED_VERSION === BAIKAL_VERSION)) {
+
+ try {
+ $config = Yaml::parseFile(PROJECT_PATH_CONFIG . "baikal.yaml");
+ } catch (\Exception $e) {
+ error_log('Error reading baikal.yaml file : ' . $e->getMessage());
return true;
}
- if (defined("PROJECT_DB_MYSQL") && PROJECT_DB_MYSQL === true) {
- self::initDbMysql();
+ # Dont init db on install, but in normal mode and when upgrading
+ if (defined("BAIKAL_CONTEXT_INSTALL") && (!isset($config['system']['configured_version']) || $config['system']['configured_version'] === BAIKAL_VERSION)) {
+ return true;
+ }
+ if ($config['database']['mysql'] === true) {
+ self::initDbMysql($config);
} else {
- self::initDbSqlite();
+ self::initDbSqlite($config);
}
}
- protected static function initDbSqlite() {
+ protected static function initDbSqlite(array $config) {
# Asserting DB filepath is set
- if (!defined("PROJECT_SQLITE_FILE")) {
+ if (!$config['database']['sqlite_file']) {
return false;
}
# Asserting DB file is writable
- if (file_exists(PROJECT_SQLITE_FILE) && !is_writable(PROJECT_SQLITE_FILE)) {
- die("DB file is not writable. Please give write permissions on file '" . PROJECT_SQLITE_FILE . "'
");
+ if (file_exists($config['database']['sqlite_file']) && !is_writable($config['database']['sqlite_file'])) {
+ die("DB file is not writable. Please give write permissions on file '" . $config['database']['sqlite_file'] . "'
");
}
# Asserting DB directory is writable
- if (!is_writable(dirname(PROJECT_SQLITE_FILE))) {
- die("The FOLDER containing the DB file is not writable, and it has to.
Please give write permissions on folder '" . dirname(PROJECT_SQLITE_FILE) . "'
");
+ if (!is_writable(dirname($config['database']['sqlite_file']))) {
+ die("The FOLDER containing the DB file is not writable, and it has to.
Please give write permissions on folder '" . dirname($config['database']['sqlite_file']) . "'
");
}
- if (file_exists(PROJECT_SQLITE_FILE) && is_readable(PROJECT_SQLITE_FILE) && !isset($GLOBALS["DB"])) {
- $GLOBALS["DB"] = new \Flake\Core\Database\Sqlite(PROJECT_SQLITE_FILE);
+ if (file_exists($config['database']['sqlite_file']) && is_readable($config['database']['sqlite_file']) && !isset($GLOBALS["DB"])) {
+ $GLOBALS["DB"] = new \Flake\Core\Database\Sqlite($config['database']['sqlite_file']);
return true;
}
return false;
}
- protected static function initDbMysql() {
+ protected static function initDbMysql(array $config) {
- if (!defined("PROJECT_DB_MYSQL_HOST")) {
- die("The constant PROJECT_DB_MYSQL_HOST, containing the MySQL host name, is not set.
You should set it in Specific/config.system.php
");
+ if (!$config['database']['mysql_host']) {
+ die("The constant PROJECT_DB_MYSQL_HOST, containing the MySQL host name, is not set.
You should set it in config/baikal.yaml
");
}
- if (!defined("PROJECT_DB_MYSQL_DBNAME")) {
- die("The constant PROJECT_DB_MYSQL_DBNAME, containing the MySQL database name, is not set.
You should set it in Specific/config.system.php
");
+ if (!$config['database']['mysql_dbname']) {
+ die("The constant PROJECT_DB_MYSQL_DBNAME, containing the MySQL database name, is not set.
You should set it in config/baikal.yaml
");
}
- if (!defined("PROJECT_DB_MYSQL_USERNAME")) {
- die("The constant PROJECT_DB_MYSQL_USERNAME, containing the MySQL database username, is not set.
You should set it in Specific/config.system.php
");
+ if (!$config['database']['mysql_username']) {
+ die("The constant PROJECT_DB_MYSQL_USERNAME, containing the MySQL database username, is not set.
You should set it in config/baikal.yaml
");
}
- if (!defined("PROJECT_DB_MYSQL_PASSWORD")) {
- die("The constant PROJECT_DB_MYSQL_PASSWORD, containing the MySQL database password, is not set.
You should set it in Specific/config.system.php
");
+ if (!$config['database']['mysql_password']) {
+ die("The constant PROJECT_DB_MYSQL_PASSWORD, containing the MySQL database password, is not set.
You should set it in config/baikal.yaml
");
}
try {
$GLOBALS["DB"] = new \Flake\Core\Database\Mysql(
- PROJECT_DB_MYSQL_HOST,
- PROJECT_DB_MYSQL_DBNAME,
- PROJECT_DB_MYSQL_USERNAME,
- PROJECT_DB_MYSQL_PASSWORD
+ $config['database']['mysql_host'],
+ $config['database']['mysql_dbname'],
+ $config['database']['mysql_username'],
+ $config['database']['mysql_password']
);
# We now setup t6he connexion to use UTF8
$GLOBALS["DB"]->query("SET NAMES UTF8");
} catch (\Exception $e) {
- die("Baïkal was not able to establish a connexion to the configured MySQL database (as configured in Specific/config.system.php).
");
+ die("Baïkal was not able to establish a connexion to the configured MySQL database (as configured in config/baikal.yaml).
");
}
return true;
diff --git a/Makefile b/Makefile
index 2332554..ba08717 100644
--- a/Makefile
+++ b/Makefile
@@ -9,8 +9,9 @@ VERSION=$(shell php -r "include 'Core/Distrib.php'; echo BAIKAL_VERSION;")
dist: vendor/autoload.php
# Building Baikal $(VERSION)
rm -r $(BUILD_DIR); true
- mkdir -p $(BUILD_DIR) $(BUILD_DIR)/Specific $(BUILD_DIR)/Specific/db
+ mkdir -p $(BUILD_DIR) $(BUILD_DIR)/Specific $(BUILD_DIR)/Specific/db $(BUILD_DIR)/config
touch $(BUILD_DIR)/Specific/db/.empty
+ touch $(BUILD_DIR)/config/.empty
rsync -av \
$(BUILD_FILES) \
--exclude="*.swp" \
@@ -31,4 +32,4 @@ composer.lock: composer.json
clean:
# Wipe out all local data, and go back to a clean install
- rm Specific/config.php Specific/config.system.php Specific/db/db.sqlite; true
+ rm config/baikal.yaml Specific/db/db.sqlite; true
diff --git a/composer.json b/composer.json
index a61c267..1f1a12c 100644
--- a/composer.json
+++ b/composer.json
@@ -1,6 +1,6 @@
{
"name": "fruux/baikal",
- "description": "Baïkal is a lightweight CalDAV + CardDAV server based on PHP, SQLite and SabreDAV",
+ "description": "Baïkal is a lightweight CalDAV + CardDAV server based on PHP, SQLite or MySQL, and SabreDAV",
"keywords": ["Framework", "WebDAV", "CalDAV", "CardDAV", "iCalendar"],
"homepage": "http://sabre.io/baikal/",
"license" : "GPL-3.0",
@@ -15,7 +15,8 @@
"require": {
"php" : "^7.1",
"sabre/dav" : "~4.1.0",
- "twig/twig" : "~1.8.0"
+ "twig/twig" : "~1.8.0",
+ "symfony/yaml" : "^3.4"
},
"require-dev" : {
"sabre/cs" : "~0.0.6"
@@ -31,6 +32,6 @@
}
},
"support" : {
- "source" : "https://github.com/fruux/Baikal"
+ "source" : "https://github.com/sabre-io/Baikal"
}
}
diff --git a/config/baikal.yaml.dist b/config/baikal.yaml.dist
new file mode 100644
index 0000000..cc2c01b
--- /dev/null
+++ b/config/baikal.yaml.dist
@@ -0,0 +1,17 @@
+system:
+ configured_version: '0.7.0'
+ timezone: 'Europe/Paris'
+ card_enabled: true
+ cal_enabled: true
+ invite_from: 'noreply@localhost'
+ dav_auth_type: 'Digest'
+ admin_passwordhash: 5fe794627e1f841f8debba065e2c807a
+ auth_realm: BaikalDAV
+database:
+ encryption_key: 5d3f0fa0192e3058ea70f1bb20924add
+ sqlite_file: "absolute/path/to/Specific/db/db.sqlite"
+ mysql: true
+ mysql_host: 'localhost'
+ mysql_dbname: 'baikal'
+ mysql_username: 'baikal'
+ mysql_password: 'baikal'
diff --git a/html/cal.php b/html/cal.php
index 7242048..3a52cc2 100644
--- a/html/cal.php
+++ b/html/cal.php
@@ -24,6 +24,8 @@
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
+use Symfony\Component\Yaml\Yaml;
+
ini_set("session.cookie_httponly", 1);
ini_set("display_errors", 0);
ini_set("log_errors", 1);
@@ -47,19 +49,26 @@ require PROJECT_PATH_ROOT . 'vendor/autoload.php';
# Bootstraping Flake
\Flake\Framework::bootstrap();
+
# Bootstrapping Baïkal
\Baikal\Framework::bootstrap();
-if (!defined("BAIKAL_CAL_ENABLED") || BAIKAL_CAL_ENABLED !== true) {
+try {
+ $config = Yaml::parseFile(PROJECT_PATH_CONFIG . "baikal.yaml");
+} catch (\Exception $e) {
+ die('Incomplete installation
Baïkal is missing its configuration file, or its configuration file is unreadable.');
+}
+
+if (!isset($config['system']["cal_enabled"]) || $config['system']["cal_enabled"] !== true) {
throw new ErrorException("Baikal CalDAV is disabled.", 0, 255, __FILE__, __LINE__);
}
$server = new \Baikal\Core\Server(
- BAIKAL_CAL_ENABLED,
- BAIKAL_CARD_ENABLED,
- BAIKAL_DAV_AUTH_TYPE,
- BAIKAL_AUTH_REALM,
+ $config['system']["cal_enabled"],
+ $config['system']["card_enabled"],
+ $config['system']["dav_auth_type"],
+ $config['system']["auth_realm"],
$GLOBALS['DB']->getPDO(),
- BAIKAL_CAL_BASEURI
+ PROJECT_BASEURI . 'cal.php/'
);
$server->start();
diff --git a/html/card.php b/html/card.php
index 1ee24a0..a617214 100644
--- a/html/card.php
+++ b/html/card.php
@@ -24,6 +24,8 @@
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
+use Symfony\Component\Yaml\Yaml;
+
ini_set("session.cookie_httponly", 1);
ini_set("display_errors", 0);
ini_set("log_errors", 1);
@@ -51,16 +53,23 @@ require PROJECT_PATH_ROOT . 'vendor/autoload.php';
# Bootstrapping Baïkal
\Baikal\Framework::bootstrap();
-if (!defined("BAIKAL_CARD_ENABLED") || BAIKAL_CARD_ENABLED !== true) {
+
+try {
+ $config = Yaml::parseFile(PROJECT_PATH_CONFIG . "baikal.yaml");
+} catch (\Exception $e) {
+ die('
Incomplete installation
Baïkal is missing its configuration file, or its configuration file is unreadable.');
+}
+
+if (!isset($config['system']["card_enabled"]) || $config['system']["card_enabled"] !== true) {
throw new ErrorException("Baikal CardDAV is disabled.", 0, 255, __FILE__, __LINE__);
}
$server = new \Baikal\Core\Server(
- BAIKAL_CAL_ENABLED,
- BAIKAL_CARD_ENABLED,
- BAIKAL_DAV_AUTH_TYPE,
- BAIKAL_AUTH_REALM,
+ $config['system']["cal_enabled"],
+ $config['system']["card_enabled"],
+ $config['system']["dav_auth_type"],
+ $config['system']["auth_realm"],
$GLOBALS['DB']->getPDO(),
- BAIKAL_CARD_BASEURI
+ PROJECT_BASEURI . 'card.php/'
);
$server->start();
diff --git a/html/dav.php b/html/dav.php
index d068b54..be51362 100644
--- a/html/dav.php
+++ b/html/dav.php
@@ -24,6 +24,8 @@
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
+use Symfony\Component\Yaml\Yaml;
+
ini_set("session.cookie_httponly", 1);
ini_set("display_errors", 0);
ini_set("log_errors", 1);
@@ -50,12 +52,18 @@ require PROJECT_PATH_ROOT . 'vendor/autoload.php';
# Bootstrapping Baïkal
\Baikal\Framework::bootstrap();
+try {
+ $config = Yaml::parseFile(PROJECT_PATH_CONFIG . "baikal.yaml");
+} catch (\Exception $e) {
+ die('
Incomplete installation
Baïkal is missing its configuration file, or its configuration file is unreadable.');
+}
+
$server = new \Baikal\Core\Server(
- BAIKAL_CAL_ENABLED,
- BAIKAL_CARD_ENABLED,
- BAIKAL_DAV_AUTH_TYPE,
- BAIKAL_AUTH_REALM,
+ $config['system']["cal_enabled"],
+ $config['system']["card_enabled"],
+ $config['system']["dav_auth_type"],
+ $config['system']["auth_realm"],
$GLOBALS['DB']->getPDO(),
- BAIKAL_DAV_BASEURI
+ PROJECT_BASEURI . 'dav.php/'
);
$server->start();
diff --git a/phpstan.neon b/phpstan.neon
index 14a75c4..8adde37 100644
--- a/phpstan.neon
+++ b/phpstan.neon
@@ -8,9 +8,6 @@ parameters:
-
message: '#Instantiated class Flake\\Core\\Exception not found.#'
path: Core/Frameworks/Flake/Util/Frameworks.php
- -
- message: '#Call to an undefined method Baikal\\Model\\Config\\Standard::getDefaultSystemConfig\(\).#'
- path: Core/Frameworks/Baikal/Model/Config/Standard.php
-
message: '#Call to static method compileCss\(\) on an unknown class Frameworks\\LessPHP\\Delegate.#'
path: Core/Frameworks/Flake/Controller/Page.php