Skip to content

Commit

Permalink
Merge pull request sebsauvage#255 from ArthurHoaro/config
Browse files Browse the repository at this point in the history
All settings are now stored in config.php
  • Loading branch information
virtualtam committed Jul 9, 2015
2 parents 7f1dfd1 + dd484b9 commit e92f1ba
Show file tree
Hide file tree
Showing 3 changed files with 358 additions and 34 deletions.
129 changes: 129 additions & 0 deletions application/Config.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
<?php
/**
* Functions related to configuration management.
*/

/**
* Re-write configuration file according to given array.
* Requires mandatory fields listed in $MANDATORY_FIELDS.
*
* @param array $config contains all configuration fields.
* @param bool $isLoggedIn true if user is logged in.
*
* @return void
*
* @throws MissingFieldConfigException: a mandatory field has not been provided in $config.
* @throws UnauthorizedConfigException: user is not authorize to change configuration.
* @throws Exception: an error occured while writing the new config file.
*/
function writeConfig($config, $isLoggedIn)
{
// These fields are required in configuration.
$MANDATORY_FIELDS = [
'login', 'hash', 'salt', 'timezone', 'title', 'titleLink',
'redirector', 'disablesessionprotection', 'privateLinkByDefault'
];

if (!isset($config['config']['CONFIG_FILE'])) {
throw new MissingFieldConfigException('CONFIG_FILE');
}

// Only logged in user can alter config.
if (is_file($config['config']['CONFIG_FILE']) && !$isLoggedIn) {
throw new UnauthorizedConfigException();
}

// Check that all mandatory fields are provided in $config.
foreach ($MANDATORY_FIELDS as $field) {
if (!isset($config[$field])) {
throw new MissingFieldConfigException($field);
}
}

$configStr = '<?php '. PHP_EOL;
$configStr .= '$GLOBALS[\'login\'] = '.var_export($config['login'], true).';'. PHP_EOL;
$configStr .= '$GLOBALS[\'hash\'] = '.var_export($config['hash'], true).';'. PHP_EOL;
$configStr .= '$GLOBALS[\'salt\'] = '.var_export($config['salt'], true).'; '. PHP_EOL;
$configStr .= '$GLOBALS[\'timezone\'] = '.var_export($config['timezone'], true).';'. PHP_EOL;
$configStr .= 'date_default_timezone_set('.var_export($config['timezone'], true).');'. PHP_EOL;
$configStr .= '$GLOBALS[\'title\'] = '.var_export($config['title'], true).';'. PHP_EOL;
$configStr .= '$GLOBALS[\'titleLink\'] = '.var_export($config['titleLink'], true).'; '. PHP_EOL;
$configStr .= '$GLOBALS[\'redirector\'] = '.var_export($config['redirector'], true).'; '. PHP_EOL;
$configStr .= '$GLOBALS[\'disablesessionprotection\'] = '.var_export($config['disablesessionprotection'], true).'; '. PHP_EOL;
$configStr .= '$GLOBALS[\'privateLinkByDefault\'] = '.var_export($config['privateLinkByDefault'], true).'; '. PHP_EOL;

// Store all $config['config']
foreach ($config['config'] as $key => $value) {
$configStr .= '$GLOBALS[\'config\'][\''. $key .'\'] = '.var_export($config['config'][$key], true).';'. PHP_EOL;
}
$configStr .= '?>';

if (!file_put_contents($config['config']['CONFIG_FILE'], $configStr)
|| strcmp(file_get_contents($config['config']['CONFIG_FILE']), $configStr) != 0
) {
throw new Exception(
'Shaarli could not create the config file.
Please make sure Shaarli has the right to write in the folder is it installed in.'
);
}
}

/**
* Milestone 0.9 - shaarli/Shaarli#41: options.php is not supported anymore.
* ==> if user is loggedIn, merge its content with config.php, then delete options.php.
*
* @param array $config contains all configuration fields.
* @param bool $isLoggedIn true if user is logged in.
*
* @return void
*/
function mergeDeprecatedConfig($config, $isLoggedIn)
{
$config_file = $config['config']['CONFIG_FILE'];

if (is_file($config['config']['DATADIR'].'/options.php') && $isLoggedIn) {
include $config['config']['DATADIR'].'/options.php';

// Load GLOBALS into config
foreach ($GLOBALS as $key => $value) {
$config[$key] = $value;
}
$config['config']['CONFIG_FILE'] = $config_file;
writeConfig($config, $isLoggedIn);

unlink($config['config']['DATADIR'].'/options.php');
}
}

/**
* Exception used if a mandatory field is missing in given configuration.
*/
class MissingFieldConfigException extends Exception
{
public $field;

/**
* Construct exception.
*
* @param string $field field name missing.
*/
public function __construct($field)
{
$this->field = $field;
$this->message = 'Configuration value is required for '. $this->field;
}
}

/**
* Exception used if an unauthorized attempt to edit configuration has been made.
*/
class UnauthorizedConfigException extends Exception
{
/**
* Construct exception.
*/
public function __construct()
{
$this->message = 'You are not authorized to alter config.';
}
}
86 changes: 52 additions & 34 deletions index.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
date_default_timezone_set('UTC');

// -----------------------------------------------------------------------------------------------
// Hardcoded parameter (These parameters can be overwritten by creating the file /data/options.php)
// Hardcoded parameter (These parameters can be overwritten by editing the file /data/config.php)
// You should not touch any code below (or at your own risks!)
$GLOBALS['config']['DATADIR'] = 'data'; // Data subdirectory
$GLOBALS['config']['CONFIG_FILE'] = $GLOBALS['config']['DATADIR'].'/config.php'; // Configuration file (user login/password)
$GLOBALS['config']['DATASTORE'] = $GLOBALS['config']['DATADIR'].'/datastore.php'; // Data storage file.
Expand All @@ -36,10 +37,6 @@
$GLOBALS['config']['ENABLE_RSS_PERMALINKS'] = true; // Enable RSS permalinks by default. This corresponds to the default behavior of shaarli before this was added as an option.
$GLOBALS['config']['HIDE_PUBLIC_LINKS'] = false;
// -----------------------------------------------------------------------------------------------
// You should not touch below (or at your own risks!)
// Optional config file.
if (is_file($GLOBALS['config']['DATADIR'].'/options.php')) require($GLOBALS['config']['DATADIR'].'/options.php');

define('shaarli_version','0.0.45beta');
// http://server.com/x/shaarli --> /shaarli/
define('WEB_PATH', substr($_SERVER["REQUEST_URI"], 0, 1+strrpos($_SERVER["REQUEST_URI"], '/', 0)));
Expand Down Expand Up @@ -69,6 +66,7 @@
// Shaarli library
require_once 'application/LinkDB.php';
require_once 'application/Utils.php';
require_once 'application/Config.php';

include "inc/rain.tpl.class.php"; //include Rain TPL
raintpl::$tpl_dir = $GLOBALS['config']['RAINTPL_TPL']; // template directory
Expand Down Expand Up @@ -100,7 +98,6 @@ function stripslashes_deep($value) { $value = is_array($value) ? array_map('stri
if (empty($GLOBALS['timezone'])) $GLOBALS['timezone']=date_default_timezone_get();
if (empty($GLOBALS['redirector'])) $GLOBALS['redirector']='';
if (empty($GLOBALS['disablesessionprotection'])) $GLOBALS['disablesessionprotection']=false;
if (empty($GLOBALS['disablejquery'])) $GLOBALS['disablejquery']=false;
if (empty($GLOBALS['privateLinkByDefault'])) $GLOBALS['privateLinkByDefault']=false;
if (empty($GLOBALS['titleLink'])) $GLOBALS['titleLink']='?';
// I really need to rewrite Shaarli with a proper configuation manager.
Expand Down Expand Up @@ -1220,7 +1217,19 @@ function renderPage()
// Save new password
$GLOBALS['salt'] = sha1(uniqid('',true).'_'.mt_rand()); // Salt renders rainbow-tables attacks useless.
$GLOBALS['hash'] = sha1($_POST['setpassword'].$GLOBALS['login'].$GLOBALS['salt']);
writeConfig();
try {
writeConfig($GLOBALS, isLoggedIn());
}
catch(Exception $e) {
error_log(
'ERROR while writing config file after changing password.' . PHP_EOL .
$e->getMessage()
);

// TODO: do not handle exceptions/errors in JS.
echo '<script>alert("'. $e->getMessage() .'");document.location=\'?do=tools\';</script>';
exit;
}
echo '<script>alert("Your password has been changed.");document.location=\'?do=tools\';</script>';
exit;
}
Expand Down Expand Up @@ -1249,12 +1258,23 @@ function renderPage()
$GLOBALS['titleLink']=$_POST['titleLink'];
$GLOBALS['redirector']=$_POST['redirector'];
$GLOBALS['disablesessionprotection']=!empty($_POST['disablesessionprotection']);
$GLOBALS['disablejquery']=!empty($_POST['disablejquery']);
$GLOBALS['privateLinkByDefault']=!empty($_POST['privateLinkByDefault']);
$GLOBALS['config']['ENABLE_RSS_PERMALINKS']= !empty($_POST['enableRssPermalinks']);
$GLOBALS['config']['ENABLE_UPDATECHECK'] = !empty($_POST['updateCheck']);
$GLOBALS['config']['HIDE_PUBLIC_LINKS'] = !empty($_POST['hidePublicLinks']);
writeConfig();
try {
writeConfig($GLOBALS, isLoggedIn());
}
catch(Exception $e) {
error_log(
'ERROR while writing config file after configuration update.' . PHP_EOL .
$e->getMessage()
);

// TODO: do not handle exceptions/errors in JS.
echo '<script>alert("'. $e->getMessage() .'");document.location=\'?do=tools\';</script>';
exit;
}
echo '<script>alert("Configuration was saved.");document.location=\'?do=tools\';</script>';
exit;
}
Expand Down Expand Up @@ -2013,7 +2033,19 @@ function install()
$GLOBALS['hash'] = sha1($_POST['setpassword'].$GLOBALS['login'].$GLOBALS['salt']);
$GLOBALS['title'] = (empty($_POST['title']) ? 'Shared links on '.escape(indexUrl()) : $_POST['title'] );
$GLOBALS['config']['ENABLE_UPDATECHECK'] = !empty($_POST['updateCheck']);
writeConfig();
try {
writeConfig($GLOBALS, isLoggedIn());
}
catch(Exception $e) {
error_log(
'ERROR while writing config file after installation.' . PHP_EOL .
$e->getMessage()
);

// TODO: do not handle exceptions/errors in JS.
echo '<script>alert("'. $e->getMessage() .'");document.location=\'?\';</script>';
exit;
}
echo '<script>alert("Shaarli is now configured. Please enter your login/password and start shaaring your links!");document.location=\'?do=login\';</script>';
exit;
}
Expand Down Expand Up @@ -2127,30 +2159,7 @@ function json_encode($data) {
}
}

// Re-write configuration file according to globals.
// Requires some $GLOBALS to be set (login,hash,salt,title).
// If the config file cannot be saved, an error message is displayed and the user is redirected to "Tools" menu.
// (otherwise, the function simply returns.)
function writeConfig()
{
if (is_file($GLOBALS['config']['CONFIG_FILE']) && !isLoggedIn()) die('You are not authorized to alter config.'); // Only logged in user can alter config.
$config='<?php $GLOBALS[\'login\']='.var_export($GLOBALS['login'],true).'; $GLOBALS[\'hash\']='.var_export($GLOBALS['hash'],true).'; $GLOBALS[\'salt\']='.var_export($GLOBALS['salt'],true).'; ';
$config .='$GLOBALS[\'timezone\']='.var_export($GLOBALS['timezone'],true).'; date_default_timezone_set('.var_export($GLOBALS['timezone'],true).'); $GLOBALS[\'title\']='.var_export($GLOBALS['title'],true).';';
$config .= '$GLOBALS[\'titleLink\']='.var_export($GLOBALS['titleLink'],true).'; ';
$config .= '$GLOBALS[\'redirector\']='.var_export($GLOBALS['redirector'],true).'; ';
$config .= '$GLOBALS[\'disablesessionprotection\']='.var_export($GLOBALS['disablesessionprotection'],true).'; ';
$config .= '$GLOBALS[\'disablejquery\']='.var_export($GLOBALS['disablejquery'],true).'; ';
$config .= '$GLOBALS[\'privateLinkByDefault\']='.var_export($GLOBALS['privateLinkByDefault'],true).'; ';
$config .= '$GLOBALS[\'config\'][\'ENABLE_RSS_PERMALINKS\']='.var_export($GLOBALS['config']['ENABLE_RSS_PERMALINKS'], true).'; ';
$config .= '$GLOBALS[\'config\'][\'ENABLE_UPDATECHECK\']='.var_export($GLOBALS['config']['ENABLE_UPDATECHECK'], true).'; ';
$config .= '$GLOBALS[\'config\'][\'HIDE_PUBLIC_LINKS\']='.var_export($GLOBALS['config']['HIDE_PUBLIC_LINKS'], true).'; ';
$config .= ' ?>';
if (!file_put_contents($GLOBALS['config']['CONFIG_FILE'],$config) || strcmp(file_get_contents($GLOBALS['config']['CONFIG_FILE']),$config)!=0)
{
echo '<script>alert("Shaarli could not create the config file. Please make sure Shaarli has the right to write in the folder is it installed in.");document.location=\'?\';</script>';
exit;
}
}


/* Because some f*cking services like flickr require an extra HTTP request to get the thumbnail URL,
I have deported the thumbnail URL code generation here, otherwise this would slow down page generation.
Expand Down Expand Up @@ -2379,6 +2388,15 @@ function invalidateCaches()
pageCache::purgeCache(); // Purge page cache shared by sessions.
}

try {
mergeDeprecatedConfig($GLOBALS, isLoggedIn());
} catch(Exception $e) {
error_log(
'ERROR while merging deprecated options.php file.' . PHP_EOL .
$e->getMessage()
);
}

if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=genthumbnail')) { genThumbnail(); exit; } // Thumbnail generation/cache does not need the link database.
if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=rss')) { showRSS(); exit; }
if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=atom')) { showATOM(); exit; }
Expand Down
Loading

0 comments on commit e92f1ba

Please sign in to comment.