summaryrefslogtreecommitdiff
path: root/app/Controllers
diff options
context:
space:
mode:
authorGravatar Alexandre Alapetite <alexandre@alapetite.fr> 2014-01-12 03:10:31 +0100
committerGravatar Alexandre Alapetite <alexandre@alapetite.fr> 2014-01-12 03:10:31 +0100
commitd58886a937cbe425163526fc2ba3d2a118602035 (patch)
tree4769024f513d927c45fe3a6475e8dcdf92f01d0f /app/Controllers
parent43f1b227b459f8edade9d551164c18f56cfa1925 (diff)
Implémentation de l'indentification par mot de passe
Implémentation de https://github.com/marienfressinaud/FreshRSS/issues/104
Diffstat (limited to 'app/Controllers')
-rwxr-xr-xapp/Controllers/indexController.php52
-rwxr-xr-xapp/Controllers/javascriptController.php12
-rw-r--r--app/Controllers/usersController.php26
3 files changed, 77 insertions, 13 deletions
diff --git a/app/Controllers/indexController.php b/app/Controllers/indexController.php
index 81dfefabb..772a08f30 100755
--- a/app/Controllers/indexController.php
+++ b/app/Controllers/indexController.php
@@ -47,8 +47,6 @@ class FreshRSS_index_Controller extends Minz_ActionController {
$this->view->_useLayout (false);
header('Content-Type: application/rss+xml; charset=utf-8');
} else {
- Minz_View::appendScript (Minz_Url::display ('/scripts/shortcut.js?' . @filemtime(PUBLIC_PATH . '/scripts/shortcut.js')));
-
if ($output === 'global') {
Minz_View::appendScript (Minz_Url::display ('/scripts/global_view.js?' . @filemtime(PUBLIC_PATH . '/scripts/global_view.js')));
}
@@ -290,8 +288,56 @@ class FreshRSS_index_Controller extends Minz_ActionController {
}
public function logoutAction () {
+ $this->view->_useLayout(false);
+ invalidateHttpCache();
+ Minz_Session::_param('currentUser');
+ Minz_Session::_param('mail');
+ Minz_Session::_param('passwordHash');
+ }
+
+ public function formLoginAction () {
$this->view->_useLayout (false);
- Minz_Session::_param ('mail');
+ if (Minz_Request::isPost()) {
+ $ok = false;
+ $nonce = Minz_Session::param('nonce');
+ $username = Minz_Request::param('username', '');
+ $c = Minz_Request::param('challenge', '');
+ if (ctype_alnum($username) && ctype_graph($c) && ctype_alnum($nonce)) {
+ if (!function_exists('password_verify')) {
+ include_once(LIB_PATH . '/password_compat.php');
+ }
+ try {
+ $conf = new FreshRSS_Configuration($username);
+ $s = $conf->passwordHash;
+ $ok = password_verify($nonce . $s, $c);
+ if ($ok) {
+ Minz_Session::_param('currentUser', $username);
+ Minz_Session::_param('passwordHash', $s);
+ } else {
+ Minz_Log::record('Password mismatch for user ' . $username . ', nonce=' . $nonce . ', c=' . $c, Minz_Log::WARNING);
+ }
+ } catch (Minz_Exception $me) {
+ Minz_Log::record('Login failure: ' . $me->getMessage(), Minz_Log::WARNING);
+ }
+ }
+ if (!$ok) {
+ $notif = array(
+ 'type' => 'bad',
+ 'content' => Minz_Translate::t('invalid_login')
+ );
+ Minz_Session::_param('notification', $notif);
+ }
+ }
+ invalidateHttpCache();
+ Minz_Request::forward(array('c' => 'index', 'a' => 'index'), true);
+ }
+
+ public function formLogoutAction () {
+ $this->view->_useLayout(false);
invalidateHttpCache();
+ Minz_Session::_param('currentUser');
+ Minz_Session::_param('mail');
+ Minz_Session::_param('passwordHash');
+ Minz_Request::forward(array('c' => 'index', 'a' => 'index'), true);
}
}
diff --git a/app/Controllers/javascriptController.php b/app/Controllers/javascriptController.php
index e29f439d8..02e424437 100755
--- a/app/Controllers/javascriptController.php
+++ b/app/Controllers/javascriptController.php
@@ -17,7 +17,7 @@ class FreshRSS_javascript_Controller extends Minz_ActionController {
$this->view->categories = $catDAO->listCategories(true, false);
}
- // For Web-form login
+ //For Web-form login
public function nonceAction() {
header('Content-Type: application/json; charset=UTF-8');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s \G\M\T'));
@@ -29,15 +29,15 @@ class FreshRSS_javascript_Controller extends Minz_ActionController {
if (ctype_alnum($user)) {
try {
$conf = new FreshRSS_Configuration($user);
- $hash = $conf->passwordHash; //CRYPT_BLOWFISH - Blowfish hashing with a salt as follows: "$2a$", "$2x$" or "$2y$", a two digit cost parameter, "$", and 22 characters from the alphabet "./0-9A-Za-z".
- if (strlen($hash) >= 60) {
- $this->view->salt1 = substr($hash, 0, 29);
+ $s = $conf->passwordHash;
+ if (strlen($s) >= 60) {
+ $this->view->salt1 = substr($s, 0, 29); //CRYPT_BLOWFISH Salt: "$2a$", a two digit cost parameter, "$", and 22 characters from the alphabet "./0-9A-Za-z".
$this->view->nonce = sha1(Minz_Configuration::salt() . uniqid(mt_rand(), true));
- Minz_Session::_param ('nonce', $this->view->nonce);
+ Minz_Session::_param('nonce', $this->view->nonce);
return; //Success
}
} catch (Minz_Exception $me) {
- Minz_Log::record ('Login failure: ' . $me->getMessage(), Minz_Log::WARNING);
+ Minz_Log::record('Login failure: ' . $me->getMessage(), Minz_Log::WARNING);
}
}
$this->view->nonce = ''; //Failure
diff --git a/app/Controllers/usersController.php b/app/Controllers/usersController.php
index 8954c845d..cb5ebd209 100644
--- a/app/Controllers/usersController.php
+++ b/app/Controllers/usersController.php
@@ -21,18 +21,20 @@ class FreshRSS_users_Controller extends Minz_ActionController {
if (!function_exists('password_hash')) {
include_once(LIB_PATH . '/password_compat.php');
}
- $passwordHash = password_hash($passwordPlain, PASSWORD_BCRYPT); //A bit expensive, on purpose
+ $passwordHash = password_hash($passwordPlain, PASSWORD_BCRYPT, array('cost' => 8)); //This will also have to be computed client side on mobile devices, so do not use a too high cost
$passwordPlain = '';
+ $passwordHash = preg_replace('/^\$2[xy]\$/', '\$2a\$', $passwordHash); //Compatibility with bcrypt.js
$this->view->conf->_passwordHash($passwordHash);
}
- $mail = Minz_Request::param('mail_login', false);
- $this->view->conf->_mail_login($mail);
+ $email = Minz_Request::param('mail_login', false);
+ $this->view->conf->_mail_login($email);
$ok &= $this->view->conf->save();
$email = $this->view->conf->mail_login;
Minz_Session::_param('mail', $email);
+ Minz_Session::_param('passwordHash', $this->view->conf->passwordHash);
if ($email != '') {
$personaFile = DATA_PATH . '/persona/' . $email . '.txt';
@@ -89,10 +91,25 @@ class FreshRSS_users_Controller extends Minz_ActionController {
$ok &= !file_exists($configPath);
}
if ($ok) {
+
+ $passwordPlain = Minz_Request::param('new_user_passwordPlain', false);
+ $passwordHash = '';
+ if ($passwordPlain != '') {
+ Minz_Request::_param('new_user_passwordPlain'); //Discard plain-text password ASAP
+ $_POST['new_user_passwordPlain'] = '';
+ if (!function_exists('password_hash')) {
+ include_once(LIB_PATH . '/password_compat.php');
+ }
+ $passwordHash = password_hash($passwordPlain, PASSWORD_BCRYPT, array('cost' => 8));
+ $passwordPlain = '';
+ }
+ if (empty($passwordHash)) {
+ $passwordHash = '';
+ }
+
$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';
} else {
$personaFile = DATA_PATH . '/persona/' . $new_user_email . '.txt';
@unlink($personaFile);
@@ -102,6 +119,7 @@ class FreshRSS_users_Controller extends Minz_ActionController {
if ($ok) {
$config_array = array(
'language' => $new_user_language,
+ 'passwordHash' => $passwordHash,
'mail_login' => $new_user_email,
);
$ok &= (file_put_contents($configPath, "<?php\n return " . var_export($config_array, true) . ';') !== false);