Quellcode durchsuchen

Multi-utilisateur fonctionnel en HTTP Auth

+ Possibilité d'ajout / suppression d'utilisateur (seulement par
l'administrateur)
+ Divers changements pour le mode multi-utilisateur
https://github.com/marienfressinaud/FreshRSS/issues/126
+ Minz : Renomme "sel_application" en "salt'
Alexandre Alapetite vor 12 Jahren
Ursprung
Commit
1ac09e7fe4

+ 5 - 36
app/Controllers/configureController.php

@@ -309,41 +309,6 @@ class FreshRSS_configure_Controller extends Minz_ActionController {
 	}
 
 	public function usersAction() {
-		if (Minz_Request::isPost()) {
-			$ok = true;
-			$current_token = $this->view->conf->token;
-
-			$mail = Minz_Request::param('mail_login', false);
-			$token = Minz_Request::param('token', $current_token);
-
-			$this->view->conf->_mail_login($mail);
-			$this->view->conf->_token($token);
-			$ok &= $this->view->conf->save();
-
-			Minz_Session::_param('mail', $this->view->conf->mail_login);
-
-			if (Minz_Configuration::isAdmin(Minz_Session::param('currentUser', '_'))) {
-				$anon = Minz_Request::param('anon_access', false);
-				$anon = ((bool)$anon) && ($anon !== 'no');
-				$auth_type = Minz_Request::param('auth_type', 'none');
-				if ($anon != Minz_Configuration::allowAnonymous() ||
-				    $auth_type != Minz_Configuration::authType()) {
-					Minz_Configuration::_allowAnonymous($anon);
-					Minz_Configuration::_authType($auth_type);
-					$ok &= Minz_Configuration::writeFile();
-				}
-			}
-
-			//TODO: use $ok
-			$notif = array(
-				'type' => 'good',
-				'content' => Minz_Translate::t('configuration_updated')
-			);
-			Minz_Session::_param('notification', $notif);
-
-			Minz_Request::forward(array('c' => 'configure', 'a' => 'users'), true);
-		}
-
 		Minz_View::prependTitle(Minz_Translate::t ('users') . ' - ');
 	}
 
@@ -369,6 +334,10 @@ class FreshRSS_configure_Controller extends Minz_ActionController {
 
 		$entryDAO = new FreshRSS_EntryDAO();
 		$this->view->nb_total = $entryDAO->count();
-		$this->view->size_total = $entryDAO->size();
+		$this->view->size_user = $entryDAO->size();
+
+		if (Minz_Configuration::isAdmin(Minz_Session::param('currentUser', '_'))) {
+			$this->view->size_total = $entryDAO->size(true);
+		}
 	}
 }

+ 15 - 13
app/Controllers/entryController.php

@@ -16,6 +16,7 @@ class FreshRSS_entry_Controller extends Minz_ActionController {
 			$this->view->_useLayout (false);
 		}
 	}
+
 	public function lastAction () {
 		$ajax = Minz_Request::param ('ajax');
 		if (!$ajax && $this->redirect) {
@@ -87,22 +88,23 @@ class FreshRSS_entry_Controller extends Minz_ActionController {
 	}
 
 	public function optimizeAction() {
-		@set_time_limit(300);
-		invalidateHttpCache();
+		if (Minz_Request::isPost()) {
+			@set_time_limit(300);
 
-		// La table des entrées a tendance à grossir énormément
-		// Cette action permet d'optimiser cette table permettant de grapiller un peu de place
-		// Cette fonctionnalité n'est à appeler qu'occasionnellement
-		$entryDAO = new FreshRSS_EntryDAO();
-		$entryDAO->optimizeTable();
+			// La table des entrées a tendance à grossir énormément
+			// Cette action permet d'optimiser cette table permettant de grapiller un peu de place
+			// Cette fonctionnalité n'est à appeler qu'occasionnellement
+			$entryDAO = new FreshRSS_EntryDAO();
+			$entryDAO->optimizeTable();
 
-		invalidateHttpCache();
+			invalidateHttpCache();
 
-		$notif = array (
-			'type' => 'good',
-			'content' => Minz_Translate::t ('optimization_complete')
-		);
-		Minz_Session::_param ('notification', $notif);
+			$notif = array (
+				'type' => 'good',
+				'content' => Minz_Translate::t ('optimization_complete')
+			);
+			Minz_Session::_param ('notification', $notif);
+		}
 
 		Minz_Request::forward(array(
 			'c' => 'configure',

+ 132 - 0
app/Controllers/usersController.php

@@ -0,0 +1,132 @@
+<?php
+
+class FreshRSS_users_Controller extends Minz_ActionController {
+	public function firstAction() {
+		if (!$this->view->loginOk) {
+			Minz_Error::error(
+				403,
+				array('error' => array(Minz_Translate::t('access_denied')))
+			);
+		}
+	}
+
+	public function idAction() {
+		if (Minz_Request::isPost()) {
+			$ok = true;
+			$mail = Minz_Request::param('mail_login', false);
+			$this->view->conf->_mail_login($mail);
+			$ok &= $this->view->conf->save();
+
+			Minz_Session::_param('mail', $this->view->conf->mail_login);
+
+			//TODO: use $ok
+			$notif = array(
+				'type' => 'good',
+				'content' => Minz_Translate::t('configuration_updated')
+			);
+			Minz_Session::_param('notification', $notif);
+
+			Minz_Request::forward(array('c' => 'configure', 'a' => 'users'), true);
+		}
+	}
+
+	public function authAction() {
+		if (Minz_Request::isPost() && Minz_Configuration::isAdmin(Minz_Session::param('currentUser', '_'))) {
+			$ok = true;
+			$current_token = $this->view->conf->token;
+			$token = Minz_Request::param('token', $current_token);
+			$this->view->conf->_token($token);
+			$ok &= $this->view->conf->save();
+
+			Minz_Session::_param('mail', $this->view->conf->mail_login);
+
+			$anon = Minz_Request::param('anon_access', false);
+			$anon = ((bool)$anon) && ($anon !== 'no');
+			$auth_type = Minz_Request::param('auth_type', 'none');
+			if ($anon != Minz_Configuration::allowAnonymous() ||
+				$auth_type != Minz_Configuration::authType()) {
+				Minz_Configuration::_allowAnonymous($anon);
+				Minz_Configuration::_authType($auth_type);
+				$ok &= Minz_Configuration::writeFile();
+			}
+
+			$notif = array(
+				'type' => $ok ? 'good' : 'bad',
+				'content' => Minz_Translate::t($ok ? 'configuration_updated' : 'error_occurred')
+			);
+			Minz_Session::_param('notification', $notif);
+		}
+		Minz_Request::forward(array('c' => 'configure', 'a' => 'users'), true);
+	}
+
+	public function createAction() {
+		if (Minz_Request::isPost() && Minz_Configuration::isAdmin(Minz_Session::param('currentUser', '_'))) {
+			require_once(APP_PATH . '/sql.php');
+
+			$new_user_language = Minz_Request::param('new_user_language', $this->view->conf->language);
+			if (!in_array($new_user_language, $this->view->conf->availableLanguages())) {
+				$new_user_language = $this->view->conf->language;
+			}
+
+			$new_user_name = Minz_Request::param('new_user_name');
+			$ok = ctype_alnum($new_user_name);
+
+			$new_user_email = filter_var($_POST['new_user_email'], FILTER_VALIDATE_EMAIL);
+			if (empty($new_user_email)) {
+				$new_user_email = '';
+				$ok &= Minz_Configuration::authType() !== 'persona';
+			}
+
+			if ($ok) {
+				$configPath = DATA_PATH . '/' . $new_user_name . '_user.php';
+				$ok &= !file_exists($configPath);
+			}
+			if ($ok) {
+				$config_array = array(
+					'language' => $new_user_language,
+					'mail_login' => $new_user_email,
+				);
+				$ok &= (file_put_contents($configPath, "<?php\n return " . var_export($config_array, true) . ';') !== false);
+			}
+			if ($ok) {
+				$userDAO = new FreshRSS_UserDAO();
+				$ok &= $userDAO->createUser($new_user_name);
+			}
+
+			$notif = array(
+				'type' => $ok ? 'good' : 'bad',
+				'content' => Minz_Translate::t($ok ? 'user_created' : 'error_occurred', $new_user_name)
+			);
+			Minz_Session::_param('notification', $notif);
+		}
+		Minz_Request::forward(array('c' => 'configure', 'a' => 'users'), true);
+	}
+
+	public function deleteAction() {
+		if (Minz_Request::isPost() && Minz_Configuration::isAdmin(Minz_Session::param('currentUser', '_'))) {
+			require_once(APP_PATH . '/sql.php');
+
+			$username = Minz_Request::param('username');
+			$ok = ctype_alnum($username);
+
+			if ($ok) {
+				$ok &= ($username !== Minz_Configuration::defaultUser());	//It is forbidden to delete the default user
+			}
+			if ($ok) {
+				$configPath = DATA_PATH . '/' . $username . '_user.php';
+				$ok &= file_exists($configPath);
+			}
+			if ($ok) {
+				$userDAO = new FreshRSS_UserDAO();
+				$ok &= $userDAO->deleteUser($username);
+				$ok &= unlink($configPath);
+			}
+			$notif = array(
+				'type' => $ok ? 'good' : 'bad',
+				'content' => Minz_Translate::t($ok ? 'user_deleted' : 'error_occurred', $username)
+			);
+			Minz_Session::_param('notification', $notif);
+		}
+		Minz_Request::forward(array('c' => 'configure', 'a' => 'users'), true);
+	}
+}

+ 33 - 0
app/Models/UserDAO.php

@@ -0,0 +1,33 @@
+<?php
+
+class FreshRSS_UserDAO extends Minz_ModelPdo {
+	public function createUser($username) {
+		require_once(APP_PATH . '/sql.php');
+		$db = Minz_Configuration::dataBase();
+
+		$sql = sprintf(SQL_CREATE_TABLES, $db['prefix'] . $username . '_');
+		$stm = $this->bd->prepare($sql, array(PDO::ATTR_EMULATE_PREPARES => true));
+		if ($stm && $stm->execute()) {
+			return true;
+		} else {
+			$info = $stm->errorInfo();
+			Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR);
+			return false;
+		}
+	}
+
+	public function deleteUser($username) {
+		require_once(APP_PATH . '/sql.php');
+		$db = Minz_Configuration::dataBase();
+
+		$sql = sprintf(SQL_DROP_TABLES, $db['prefix'] . $username . '_');
+		$stm = $this->bd->prepare($sql);
+		if ($stm && $stm->execute()) {
+			return true;
+		} else {
+			$info = $stm->errorInfo();
+			Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR);
+			return false;
+		}
+	}
+}

+ 6 - 1
app/i18n/en.php

@@ -137,7 +137,7 @@ return array (
 	'articles'			=> 'articles',
 	'number_articles'		=> 'Number of articles',
 	'by_feed'			=> 'by feed',
-	'by_default'		=> 'By default',
+	'by_default'			=> 'By default',
 	'keep_history'			=> 'Minimum number of articles to keep',
 	'categorize'			=> 'Store in a category',
 	'truncate'			=> 'Delete all articles',
@@ -167,6 +167,11 @@ return array (
 	'auth_type'			=> 'Authentication method',
 	'auth_none'			=> 'None (dangerous)',
 	'users_list'			=> 'List of users',
+	'create_user'			=> 'Create new user',
+	'username'			=> 'Username',
+	'create'			=> 'Create',
+	'user_created'			=> 'User %s has been created',
+	'user_deleted'			=> 'User %s has been deleted',
 
 	'language'			=> 'Language',
 	'month'				=> 'months',

+ 6 - 1
app/i18n/fr.php

@@ -137,7 +137,7 @@ return array (
 	'articles'			=> 'articles',
 	'number_articles'		=> 'Nombre d’articles',
 	'by_feed'			=> 'par flux',
-	'by_default'		=> 'Par défaut',
+	'by_default'			=> 'Par défaut',
 	'keep_history'			=> 'Nombre minimum d’articles à conserver',
 	'categorize'			=> 'Ranger dans une catégorie',
 	'truncate'			=> 'Supprimer tous les articles',
@@ -167,6 +167,11 @@ return array (
 	'auth_type'			=> 'Méthode d’authentification',
 	'auth_none'			=> 'Aucune (dangereux)',
 	'users_list'			=> 'Liste des utilisateurs',
+	'create_user'			=> 'Créer un nouvel utilisateur',
+	'username'			=> 'Nom d’utilisateur',
+	'create'			=> 'Créer',
+	'user_created'			=> 'L’utilisateur %s a été créé',
+	'user_deleted'			=> 'L’utilisateur %s a été supprimé',
 
 	'language'			=> 'Langue',
 	'month'				=> 'mois',

+ 11 - 9
app/sql.php

@@ -1,16 +1,15 @@
 <?php
-define ('SQL_CREATE_DB', 'CREATE DATABASE %1$s DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;');
-
-define ('SQL_CAT', 'CREATE TABLE IF NOT EXISTS `%1$scategory` (
+define('SQL_CREATE_TABLES', '
+CREATE TABLE IF NOT EXISTS `%1$scategory` (
 	`id` SMALLINT NOT NULL AUTO_INCREMENT,	-- v0.7
 	`name` varchar(255) NOT NULL,
 	`color` char(7),
 	PRIMARY KEY (`id`),
 	UNIQUE KEY (`name`)	-- v0.7
 ) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci
-ENGINE = INNODB;');
+ENGINE = INNODB;
 
-define ('SQL_FEED', 'CREATE TABLE IF NOT EXISTS `%1$sfeed` (
+CREATE TABLE IF NOT EXISTS `%1$sfeed` (
 	`id` SMALLINT NOT NULL AUTO_INCREMENT,	-- v0.7
 	`url` varchar(511) CHARACTER SET latin1 NOT NULL,
 	`category` SMALLINT DEFAULT 0,	-- v0.7
@@ -22,7 +21,7 @@ define ('SQL_FEED', 'CREATE TABLE IF NOT EXISTS `%1$sfeed` (
 	`pathEntries` varchar(511) DEFAULT NULL,
 	`httpAuth` varchar(511) DEFAULT NULL,
 	`error` boolean DEFAULT 0,
-	`keep_history` MEDIUMINT NOT NULL DEFAULT -2,	-- v0.7, -2 = default
+	`keep_history` MEDIUMINT NOT NULL DEFAULT -2,	-- v0.7
 	`cache_nbEntries` int DEFAULT 0,	-- v0.7
 	`cache_nbUnreads` int DEFAULT 0,	-- v0.7
 	PRIMARY KEY (`id`),
@@ -32,9 +31,9 @@ define ('SQL_FEED', 'CREATE TABLE IF NOT EXISTS `%1$sfeed` (
 	INDEX (`priority`),	-- v0.7
 	INDEX (`keep_history`)	-- v0.7
 ) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci
-ENGINE = INNODB;');
+ENGINE = INNODB;
 
-define ('SQL_ENTRY', 'CREATE TABLE IF NOT EXISTS `%1$sentry` (
+CREATE TABLE IF NOT EXISTS `%1$sentry` (
 	`id` bigint NOT NULL,	-- v0.7
 	`guid` varchar(760) CHARACTER SET latin1 NOT NULL,	-- Maximum for UNIQUE is 767B
 	`title` varchar(255) NOT NULL,
@@ -52,4 +51,7 @@ define ('SQL_ENTRY', 'CREATE TABLE IF NOT EXISTS `%1$sentry` (
 	INDEX (`is_favorite`),	-- v0.7
 	INDEX (`is_read`)	-- v0.7
 ) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci
-ENGINE = INNODB;');
+ENGINE = INNODB;
+');
+
+define('SQL_DROP_TABLES', 'DROP TABLES %1$sentry, %1$sfeed, %1$scategory');

+ 17 - 6
app/views/configure/archiving.phtml

@@ -6,7 +6,7 @@
 	<form method="post" action="<?php echo _url('configure', 'archiving'); ?>">
 		<legend><?php echo Minz_Translate::t('archiving_configuration'); ?></legend>
 		<p><?php echo FreshRSS_Themes::icon('help'); ?> <?php echo Minz_Translate::t('archiving_configuration_help'); ?></p>
-		
+
 		<div class="form-group">
 			<label class="group-name" for="old_entries"><?php echo Minz_Translate::t('delete_articles_every'); ?></label>
 			<div class="group-controls">
@@ -31,17 +31,28 @@
 				<button type="reset" class="btn"><?php echo Minz_Translate::t('cancel'); ?></button>
 			</div>
 		</div>
+	</form>
 
+	<form method="post" action="<?php echo _url('entry', 'optimize'); ?>">
 		<legend><?php echo Minz_Translate::t ('advanced'); ?></legend>
+
 		<div class="form-group">
-			<label class="group-name"></label>
+		<p class="group-name"><?php echo Minz_Translate::t('current_user'); ?></p>
 			<div class="group-controls">
-				<p><?php echo $this->nb_total; ?> <?php echo Minz_Translate::t('articles') ?>, <?php echo formatBytes($this->size_total); ?>.</p>
-				<p><a class="btn" href="<?php echo _url('entry', 'optimize'); ?>">
-					<?php echo Minz_Translate::t('optimize_bdd'); ?>
-				</a></p>
+				<p><?php echo $this->nb_total, ' ', Minz_Translate::t('articles'), ', ', formatBytes($this->size_user); ?></p>
+				<input type="hidden" name="optimiseDatabase" value="1" />
+				<button type="submit" class="btn btn-important"><?php echo Minz_Translate::t('optimize_bdd'); ?></button>
 				<?php echo FreshRSS_Themes::icon('help'); ?> <?php echo Minz_Translate::t('optimize_todo_sometimes'); ?>
 			</div>
 		</div>
+
+		<?php if (Minz_Configuration::isAdmin(Minz_Session::param('currentUser', '_'))) { ?>
+		<div class="form-group">
+			<p class="group-name"><?php echo Minz_Translate::t('users'); ?></p>
+			<div class="group-controls">
+				<p><?php echo formatBytes($this->size_total); ?></p>
+			</div>
+		</div>
+		<?php } ?>
 	</form>
 </div>

+ 74 - 17
app/views/configure/users.phtml

@@ -3,16 +3,15 @@
 <div class="post">
 	<a href="<?php echo _url('index', 'index'); ?>"><?php echo Minz_Translate::t('back_to_rss_feeds'); ?></a>
 
-	<form method="post" action="<?php echo _url('configure', 'users'); ?>">
+	<form method="post" action="<?php echo _url('users', 'id'); ?>">
 		<legend><?php echo Minz_Translate::t('login_configuration'); ?></legend>
 
 		<div class="form-group">
 			<label class="group-name" for="current_user"><?php echo Minz_Translate::t('current_user'); ?></label>
 			<div class="group-controls">
 				<input id="current_user" type="text" disabled="disabled" value="<?php echo Minz_Session::param('currentUser', '_'); ?>" />
-				<code>$_SERVER['REMOTE_USER'] = <?php echo httpAuthUser(); ?></code>
 				<label class="checkbox" for="is_admin">
-					<input type="checkbox" id="is_admin" disabled="disabled"<?php echo Minz_Configuration::isAdmin(Minz_Session::param('currentUser', '_')) ? ' checked="checked"' : ''; ?> />
+					<input type="checkbox" id="is_admin" disabled="disabled" <?php echo Minz_Configuration::isAdmin(Minz_Session::param('currentUser', '_')) ? 'checked="checked" ' : ''; ?>/>
 					<?php echo Minz_Translate::t('is_admin'); ?>
 				</label>
 			</div>
@@ -22,21 +21,25 @@
 			<label class="group-name" for="mail_login"><?php echo Minz_Translate::t('persona_connection_email'); ?></label>
 			<?php $mail = $this->conf->mail_login; ?>
 			<div class="group-controls">
-				<input type="email" id="mail_login" name="mail_login" value="<?php echo $mail ? $mail : ''; ?>" placeholder="alice@example.net" />
+				<input type="email" id="mail_login" name="mail_login" value="<?php echo $mail; ?>" <?php echo Minz_Configuration::isAdmin(Minz_Session::param('currentUser', '_')) ? '' : 'disabled="disabled"'; ?> placeholder="alice@example.net" />
 				<noscript><b><?php echo Minz_Translate::t('javascript_should_be_activated'); ?></b></noscript>
 			</div>
 		</div>
 
+		<?php if (Minz_Configuration::isAdmin(Minz_Session::param('currentUser', '_'))) { ?>
 		<div class="form-group form-actions">
 			<div class="group-controls">
 				<button type="submit" class="btn btn-important"><?php echo Minz_Translate::t('save'); ?></button>
 				<button type="reset" class="btn"><?php echo Minz_Translate::t('cancel'); ?></button>
 			</div>
 		</div>
+		<?php } ?>
+	</form>
 
-		<?php if (Minz_Configuration::isAdmin(Minz_Session::param('currentUser', '_'))) { ?>
+	<?php if (Minz_Configuration::isAdmin(Minz_Session::param('currentUser', '_'))) { ?>
 
-		<legend><?php echo Minz_Translate::t('users'); ?></legend>
+	<form method="post" action="<?php echo _url('users', 'auth'); ?>">
+		<legend><?php echo Minz_Translate::t('auth_type'); ?></legend>
 
 		<div class="form-group">
 			<label class="group-name" for="auth_type"><?php echo Minz_Translate::t('auth_type'); ?></label>
@@ -46,17 +49,7 @@
 					<option value="http_auth"<?php echo Minz_Configuration::authType() === 'http_auth' ? ' selected="selected"' : '', httpAuthUser() == '' ? ' disabled="disabled"' : ''; ?>>HTTP Auth</option>
 					<option value="persona"<?php echo Minz_Configuration::authType() === 'persona' ? ' selected="selected"' : ''; ?>>Mozilla Persona</option>
 				</select>
-			</div>
-		</div>
-
-		<div class="form-group">
-			<label class="group-name" for="users_list"><?php echo Minz_Translate::t('users_list'); ?></label>
-			<div class="group-controls">
-				<select id="users_list" name="users_list"><?php
-					foreach (listUsers() as $user) {
-						echo '<option>', $user, '</option>';
-					}
-				?></select>
+				<code>$_SERVER['REMOTE_USER'] = `<?php echo httpAuthUser(); ?>`</code>
 			</div>
 		</div>
 
@@ -67,6 +60,8 @@
 			</div>
 		</div>
 
+		<?php if (Minz_Configuration::authType() === 'persona') { ?>
+
 		<legend>Mozilla Persona</legend>
 		<div class="form-group">
 			<div class="group-controls">
@@ -95,4 +90,66 @@
 
 		<?php } ?>
 	</form>
+
+	<form method="post" action="<?php echo _url('users', 'delete'); ?>">
+		<legend><?php echo Minz_Translate::t('users'); ?></legend>
+
+		<div class="form-group">
+			<label class="group-name" for="users_list"><?php echo Minz_Translate::t('users_list'); ?></label>
+			<div class="group-controls">
+				<select id="users_list" name="username"><?php
+					foreach (listUsers() as $user) {
+						echo '<option>', $user, '</option>';
+					}
+				?></select>
+			</div>
+		</div>
+	
+		<div class="form-group form-actions">
+			<div class="group-controls">
+				<button type="submit" class="btn btn-attention confirm"><?php echo Minz_Translate::t('delete'); ?></button>
+			</div>
+		</div>
+	</form>
+
+	<form method="post" action="<?php echo _url('users', 'create'); ?>">
+		<legend><?php echo Minz_Translate::t('create_user'); ?></legend>
+
+		<div class="form-group">
+			<label class="group-name" for="new_user_language"><?php echo Minz_Translate::t ('language'); ?></label>
+			<div class="group-controls">
+				<select name="new_user_language" id="new_user_language">
+				<?php $languages = $this->conf->availableLanguages (); ?>
+				<?php foreach ($languages as $short => $lib) { ?>
+				<option value="<?php echo $short; ?>"<?php echo $this->conf->language === $short ? ' selected="selected"' : ''; ?>><?php echo $lib; ?></option>
+				<?php } ?>
+				</select>
+			</div>
+		</div>
+
+		<div class="form-group">
+			<label class="group-name" for="new_user_name"><?php echo Minz_Translate::t('username'); ?></label>
+			<div class="group-controls">
+				<input id="new_user_name" name="new_user_name" type="text" size="16" required="required" maxlength="16" pattern="[0-9a-zA-Z]{1,16}" placeholder="demo" />
+			</div>
+		</div>
+
+		<div class="form-group">
+			<label class="group-name" for="new_user_email"><?php echo Minz_Translate::t('persona_connection_email'); ?></label>
+			<?php $mail = $this->conf->mail_login; ?>
+			<div class="group-controls">
+				<input type="email" id="new_user_email" name="new_user_email" placeholder="alice@example.net" />
+			</div>
+		</div>
+
+		<div class="form-group form-actions">
+			<div class="group-controls">
+				<button type="submit" class="btn btn-important"><?php echo Minz_Translate::t('create'); ?></button>
+				<button type="reset" class="btn"><?php echo Minz_Translate::t('cancel'); ?></button>
+			</div>
+		</div>
+
+	</form>
+
+	<?php } ?>
 </div>

+ 30 - 23
lib/Minz/Configuration.php

@@ -28,7 +28,7 @@ class Minz_Configuration {
 
 	/**
 	 * définition des variables de configuration
-	 * $sel_application une chaîne de caractères aléatoires (obligatoire)
+	 * $salt une chaîne de caractères aléatoires (obligatoire)
 	 * $environment gère le niveau d'affichage pour log et erreurs
 	 * $use_url_rewriting indique si on utilise l'url_rewriting
 	 * $base_url le chemin de base pour accéder à l'application
@@ -42,7 +42,7 @@ class Minz_Configuration {
 	 *     - password mot de passe de l'utilisateur
 	 *     - base le nom de la base de données
 	 */
-	private static $sel_application = '';
+	private static $salt = '';
 	private static $environment = Minz_Configuration::PRODUCTION;
 	private static $base_url = '';
 	private static $use_url_rewriting = false;
@@ -55,17 +55,19 @@ class Minz_Configuration {
 	private static $auth_type = 'none';
 
 	private static $db = array (
-		'host' => false,
-		'user' => false,
-		'password' => false,
-		'base' => false
+		'type' => 'mysql',
+		'host' => '',
+		'user' => '',
+		'password' => '',
+		'base' => '',
+		'prefix' => '',
 	);
 
 	/*
 	 * Getteurs
 	 */
 	public static function salt () {
-		return self::$sel_application;
+		return self::$salt;
 	}
 	public static function environment () {
 		return self::$environment;
@@ -145,7 +147,7 @@ class Minz_Configuration {
 			'general' => array(
 				'environment' => self::$environment,
 				'use_url_rewriting' => self::$use_url_rewriting,
-				'sel_application' => self::$sel_application,
+				'salt' => self::$salt,
 				'base_url' => self::$base_url,
 				'title' => self::$title,
 				'default_user' => self::$default_user,
@@ -189,14 +191,18 @@ class Minz_Configuration {
 		}
 		$general = $ini_array['general'];
 
-		// sel_application est obligatoire
-		if (!isset ($general['sel_application'])) {
-			throw new Minz_BadConfigurationException (
-				'sel_application',
-				Minz_Exception::ERROR
-			);
+		// salt est obligatoire
+		if (!isset ($general['salt'])) {
+			if (isset($general['sel_application'])) {	//v0.6
+				$general['salt'] = $general['sel_application'];
+			} else {
+				throw new Minz_BadConfigurationException (
+					'salt',
+					Minz_Exception::ERROR
+				);
+			}
 		}
-		self::$sel_application = $general['sel_application'];
+		self::$salt = $general['salt'];
 
 		if (isset ($general['environment'])) {
 			switch ($general['environment']) {
@@ -256,18 +262,15 @@ class Minz_Configuration {
 		}
 
 		// Base de données
-		$db = false;
 		if (isset ($ini_array['db'])) {
 			$db = $ini_array['db'];
-		}
-		if ($db) {
-			if (!isset ($db['host'])) {
+			if (empty($db['host'])) {
 				throw new Minz_BadConfigurationException (
 					'host',
 					Minz_Exception::ERROR
 				);
 			}
-			if (!isset ($db['user'])) {
+			if (empty($db['user'])) {
 				throw new Minz_BadConfigurationException (
 					'user',
 					Minz_Exception::ERROR
@@ -279,19 +282,23 @@ class Minz_Configuration {
 					Minz_Exception::ERROR
 				);
 			}
-			if (!isset ($db['base'])) {
+			if (empty($db['base'])) {
 				throw new Minz_BadConfigurationException (
 					'base',
 					Minz_Exception::ERROR
 				);
 			}
 
-			self::$db['type'] = isset ($db['type']) ? $db['type'] : 'mysql';
+			if (!empty($db['type'])) {
+				self::$db['type'] = $db['type'];
+			}
 			self::$db['host'] = $db['host'];
 			self::$db['user'] = $db['user'];
 			self::$db['password'] = $db['password'];
 			self::$db['base'] = $db['base'];
-			self::$db['prefix'] = isset ($db['prefix']) ? $db['prefix'] : '';
+			if (isset($db['prefix'])) {
+				self::$db['prefix'] = $db['prefix'];
+			}
 		}
 	}
 

+ 1 - 1
lib/Minz/FileNotExistException.php

@@ -1,7 +1,7 @@
 <?php
 class Minz_FileNotExistException extends Minz_Exception {
 	public function __construct ($file_name, $code = self::ERROR) {
-		$message = 'File doesn\'t exist : `' . $file_name.'`';
+		$message = 'File not found: `' . $file_name.'`';
 		
 		parent::__construct ($message, $code);
 	}

+ 8 - 4
lib/Minz/ModelPdo.php

@@ -1,5 +1,5 @@
 <?php
-/** 
+/**
  * MINZ - Copyright 2011 Marien Fressinaud
  * Sous licence AGPL3 <http://www.gnu.org/licenses/>
 */
@@ -23,7 +23,7 @@ class Minz_ModelPdo {
 	protected $bd;
 
 	protected $prefix;
-	
+
 	/**
 	 * Créé la connexion à la base de données à l'aide des variables
 	 * HOST, BASE, USER et PASS définies dans le fichier de configuration
@@ -80,11 +80,15 @@ class Minz_ModelPdo {
 		$this->bd->rollBack();
 	}
 
-	public function size() {
+	public function size($all = false) {
 		$db = Minz_Configuration::dataBase ();
 		$sql = 'SELECT SUM(data_length + index_length) FROM information_schema.TABLES WHERE table_schema = ?';
-		$stm = $this->bd->prepare ($sql);
 		$values = array ($db['base']);
+		if (!$all) {
+			$sql .= ' AND table_name LIKE ?';
+			$values[] = $this->prefix . '%';
+		}
+		$stm = $this->bd->prepare ($sql);
 		$stm->execute ($values);
 		$res = $stm->fetchAll(PDO::FETCH_COLUMN, 0);
 		return $res[0];

+ 15 - 33
p/i/install.php

@@ -12,6 +12,8 @@ if (isset ($_GET['step'])) {
 	define ('STEP', 1);
 }
 
+define('SQL_CREATE_DB', 'CREATE DATABASE %1$s DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;');
+
 include(APP_PATH . '/sql.php');
 
 //<updates>
@@ -151,7 +153,7 @@ function saveStep2 () {
 			return false;
 		}
 
-		$_SESSION['sel_application'] = sha1(uniqid(mt_rand(), true).implode('', stat(__FILE__)));
+		$_SESSION['salt'] = sha1(uniqid(mt_rand(), true).implode('', stat(__FILE__)));
 		$_SESSION['title'] = substr(trim($_POST['title']), 0, 25);
 		$_SESSION['old_entries'] = $_POST['old_entries'];
 		if ((!ctype_digit($_SESSION['old_entries'])) || ($_SESSION['old_entries'] < 1)) {
@@ -162,7 +164,7 @@ function saveStep2 () {
 
 		$token = '';
 		if ($_SESSION['mail_login']) {
-			$token = sha1($_SESSION['sel_application'] . $_SESSION['mail_login']);
+			$token = sha1($_SESSION['salt'] . $_SESSION['mail_login']);
 		}
 
 		$config_array = array (
@@ -173,7 +175,7 @@ function saveStep2 () {
 		);
 
 		$configPath = DATA_PATH . '/' . $_SESSION['default_user'] . '_user.php';
-		@unlink(configPath);	//To avoid access-rights problems
+		@unlink($configPath);	//To avoid access-rights problems
 		file_put_contents($configPath, "<?php\n return " . var_export($config_array, true) . ';');
 
 		header ('Location: index.php?step=3');
@@ -201,7 +203,7 @@ function saveStep3 () {
 			'general' => array(
 				'environment' => empty($_SESSION['environment']) ? 'production' : $_SESSION['environment'],
 				'use_url_rewriting' => false,
-				'sel_application' => $_SESSION['sel_application'],
+				'salt' => $_SESSION['salt'],
 				'base_url' => '',
 				'title' => $_SESSION['title'],
 				'default_user' => $_SESSION['default_user'],
@@ -424,7 +426,7 @@ function checkStep0 () {
 	if ($ini_array) {
 		$ini_general = isset($ini_array['general']) ? $ini_array['general'] : null;
 		if ($ini_general) {
-			$keys = array('environment', 'sel_application', 'title', 'default_user');
+			$keys = array('environment', 'salt', 'title', 'default_user');
 			foreach ($keys as $key) {
 				if ((empty($_SESSION[$key])) && isset($ini_general[$key])) {
 					$_SESSION[$key] = $ini_general[$key];
@@ -496,7 +498,7 @@ function checkStep1 () {
 }
 
 function checkStep2 () {
-	$conf = !empty($_SESSION['sel_application']) &&
+	$conf = !empty($_SESSION['salt']) &&
 	        !empty($_SESSION['title']) &&
 	        !empty($_SESSION['old_entries']) &&
 	        isset($_SESSION['mail_login']) &&
@@ -537,7 +539,7 @@ function checkStep3 () {
 }
 
 function checkBD () {
-	$error = false;
+	$ok = false;
 
 	try {
 		$str = '';
@@ -575,35 +577,18 @@ function checkBD () {
 			$res = $c->query($sql);	//Backup tables
 		}
 
-		$sql = sprintf (SQL_CAT, $_SESSION['bd_prefix_user']);
-		$res = $c->query ($sql);
-
-		if (!$res) {
-			$error = true;
-		}
-
-		$sql = sprintf (SQL_FEED, $_SESSION['bd_prefix_user']);
-		$res = $c->query ($sql);
-
-		if (!$res) {
-			$error = true;
-		}
-
-		$sql = sprintf (SQL_ENTRY, $_SESSION['bd_prefix_user']);
-		$res = $c->query ($sql);
-
-		if (!$res) {
-			$error = true;
-		}
+		$sql = sprintf(SQL_CREATE_TABLES, $_SESSION['bd_prefix_user']);
+		$stm = $c->prepare($sql, array(PDO::ATTR_EMULATE_PREPARES => true));
+		$ok = $stm->execute();
 	} catch (PDOException $e) {
 		$error = true;
 	}
 
-	if ($error && file_exists (DATA_PATH . '/config.php')) {
-		unlink (DATA_PATH . '/config.php');
+	if (!$ok) {
+		@unlink(DATA_PATH . '/config.php');
 	}
 
-	return !$error;
+	return $ok;
 }
 
 /*** AFFICHAGE ***/
@@ -729,9 +714,6 @@ function printStep2 () {
 
 	<form action="index.php?step=2" method="post">
 		<legend><?php echo _t ('general_configuration'); ?></legend>
-		<?php
-			$url = substr ($_SERVER['PHP_SELF'], 0, -10);
-		?>
 
 		<div class="form-group">
 			<label class="group-name" for="title"><?php echo _t ('title'); ?></label>