aboutsummaryrefslogtreecommitdiff
path: root/p/api
diff options
context:
space:
mode:
authorGravatar Alexandre Alapetite <alexandre@alapetite.fr> 2014-03-01 14:45:58 +0100
committerGravatar Alexandre Alapetite <alexandre@alapetite.fr> 2014-03-01 14:45:58 +0100
commit29b3bbfe284a6e56413a2e89b740ffc4172c6847 (patch)
tree5e1b74f889f071e3e45beca09673304629e79f74 /p/api
parentf44683b5671b323ba96f0c4cd47ba9458e934679 (diff)
API: Real password system
https://github.com/marienfressinaud/FreshRSS/issues/13 Expiring token not implemented yet
Diffstat (limited to 'p/api')
-rw-r--r--p/api/greader.php89
1 files changed, 54 insertions, 35 deletions
diff --git a/p/api/greader.php b/p/api/greader.php
index e99e1c0c8..035a031dd 100644
--- a/p/api/greader.php
+++ b/p/api/greader.php
@@ -20,9 +20,6 @@ Server-side API compatible with Google Reader API layer 2
* https://github.com/theoldreader/api
*/
-define('TEMP_PASSWORD', 'temp123'); //Change to another ASCII password
-define('TEMP_AUTH', 'XtofqkkOkCULRLH8'); //Change to another random ASCII auth
-
require('../../constants.php');
require(LIB_PATH . '/lib_rss.php'); //Includes class autoloader
@@ -119,14 +116,28 @@ function checkCompatibility() {
exit();
}
-function authorizationToUser() {
+function authorizationToUserConf() {
$headerAuth = headerVariable('Authorization', 'GoogleLogin_auth'); //Input is 'GoogleLogin auth', but PHP replaces spaces by '_' http://php.net/language.variables.external
if ($headerAuth != '') {
$headerAuthX = explode('/', $headerAuth, 2);
- if ((count($headerAuthX) === 2) && ($headerAuthX[1] === TEMP_AUTH)) {
+ if (count($headerAuthX) === 2) {
$user = $headerAuthX[0];
if (ctype_alnum($user)) {
- return $user;
+ try {
+ $conf = new FreshRSS_Configuration($user);
+ } catch (Exception $e) {
+ logMe($e->getMessage() . "\n");
+ unauthorized();
+ }
+ if ($headerAuthX[1] === sha1(Minz_Configuration::salt() . $conf->user . $conf->apiPasswordHash)) {
+ return $conf;
+ } else {
+ logMe('Invalid API authorisation for user ' . $user . ': ' . $headerAuthX[1] . "\n");
+ Minz_Log::record('Invalid API authorisation for user ' . $user . ': ' . $headerAuthX[1], Minz_Log::WARNING);
+ unauthorized();
+ }
+ } else {
+ badRequest();
}
}
}
@@ -135,28 +146,45 @@ function authorizationToUser() {
function clientLogin($email, $pass) { //http://web.archive.org/web/20130604091042/http://undoc.in/clientLogin.html
logMe('clientLogin(' . $email . ")\n");
- if ($pass !== TEMP_PASSWORD) {
- unauthorized();
+ if (ctype_alnum($email)) {
+ if (!function_exists('password_verify')) {
+ include_once(LIB_PATH . '/password_compat.php');
+ }
+ try {
+ $conf = new FreshRSS_Configuration($email);
+ } catch (Exception $e) {
+ logMe($e->getMessage() . "\n");
+ Minz_Log::record('Invalid API user ' . $email, Minz_Log::WARNING);
+ unauthorized();
+ }
+ if ($conf->apiPasswordHash != '' && password_verify($pass, $conf->apiPasswordHash)) {
+ header('Content-Type: text/plain; charset=UTF-8');
+ $auth = $email . '/' . sha1(Minz_Configuration::salt() . $conf->user . $conf->apiPasswordHash);
+ echo 'SID=', $auth, "\n",
+ 'Auth=', $auth, "\n";
+ exit();
+ } else {
+ Minz_Log::record('Password API mismatch for user ' . $email, Minz_Log::WARNING);
+ unauthorized();
+ }
+ } else {
+ badRequest();
}
- header('Content-Type: text/plain; charset=UTF-8');
- $auth = $email . '/' . TEMP_AUTH;
- echo 'SID=', $auth, "\n",
- 'Auth=', $auth, "\n";
- exit();
+ die();
}
-function token($user) {
+function token($conf) {
//http://blog.martindoms.com/2009/08/15/using-the-google-reader-api-part-1/ https://github.com/ericmann/gReader-Library/blob/master/greader.class.php
- logMe('token('. $user . ")\n");
- $token = 'ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ01234'; //Must have 57 characters...
+ logMe('token('. $conf->user . ")\n"); //TODO: Implement real token that expires
+ $token = str_pad(sha1(Minz_Configuration::salt() . $conf->user . $conf->apiPasswordHash), 57, 'Z'); //Must have 57 characters
echo $token, "\n";
exit();
}
-function checkToken($user, $token) {
+function checkToken($conf, $token) {
//http://code.google.com/p/google-reader-api/wiki/ActionToken
logMe('checkToken(' . $token . ")\n");
- if ($token === 'ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ01234') {
+ if ($token === str_pad(sha1(Minz_Configuration::salt() . $conf->user . $conf->apiPasswordHash), 57, 'Z')) {
return true;
}
unauthorized();
@@ -462,32 +490,23 @@ if (!Minz_Configuration::apiEnabled()) {
Minz_Session::init('FreshRSS');
-$user = authorizationToUser();
-$conf = null;
+$conf = authorizationToUserConf();
+$user = $conf == null ? '' : $conf->user;
logMe('User => ' . $user . "\n");
-if ($user != null) {
- try {
- $conf = new FreshRSS_Configuration($user);
- } catch (Exception $e) {
- logMe($e->getMessage());
- $user = null;
- badRequest();
- }
-}
-
Minz_Session::_param('currentUser', $user);
if (count($pathInfos) < 3) {
badRequest();
}
elseif ($pathInfos[1] === 'accounts') {
- if (($pathInfos[2] === 'ClientLogin') && isset($_REQUEST['Email']) && isset($_REQUEST['Passwd']))
+ if (($pathInfos[2] === 'ClientLogin') && isset($_REQUEST['Email']) && isset($_REQUEST['Passwd'])) {
clientLogin($_REQUEST['Email'], $_REQUEST['Passwd']);
+ }
}
elseif ($pathInfos[1] === 'reader' && $pathInfos[2] === 'api' && isset($pathInfos[3]) && $pathInfos[3] === '0' && isset($pathInfos[4])) {
- if ($user == null) {
+ if ($user == '') {
unauthorized();
}
$timestamp = isset($_GET['ck']) ? intval($_GET['ck']) : 0; //ck=[unix timestamp] : Use the current Unix time here, helps Google with caching.
@@ -543,7 +562,7 @@ elseif ($pathInfos[1] === 'reader' && $pathInfos[2] === 'api' && isset($pathInfo
break;
case 'edit-tag': //http://blog.martindoms.com/2010/01/20/using-the-google-reader-api-part-3/
$token = isset($_POST['T']) ? trim($_POST['T']) : '';
- checkToken($user, $token);
+ checkToken($conf, $token);
$a = isset($_POST['a']) ? $_POST['a'] : ''; //Add: user/-/state/com.google/read user/-/state/com.google/starred
$r = isset($_POST['r']) ? $_POST['r'] : ''; //Remove: user/-/state/com.google/read user/-/state/com.google/starred
$e_ids = multiplePosts('i'); //item IDs
@@ -551,7 +570,7 @@ elseif ($pathInfos[1] === 'reader' && $pathInfos[2] === 'api' && isset($pathInfo
break;
case 'mark-all-as-read':
$token = isset($_POST['T']) ? trim($_POST['T']) : '';
- checkToken($user, $token);
+ checkToken($conf, $token);
$streamId = $_POST['s']; //StreamId
$ts = isset($_POST['ts']) ? $_POST['ts'] : '0'; //Older than timestamp in nanoseconds
if (!ctype_digit($ts)) {
@@ -560,7 +579,7 @@ elseif ($pathInfos[1] === 'reader' && $pathInfos[2] === 'api' && isset($pathInfo
markAllAsRead($streamId, $ts);
break;
case 'token':
- Token($user);
+ Token($conf);
break;
}
} elseif ($pathInfos[1] === 'check' && $pathInfos[2] === 'compatibility') {