From 3058ed4cbe24b2d263773fbade42dc39c319fdfa Mon Sep 17 00:00:00 2001 From: Benjamin Sonntag Date: Sun, 21 Sep 2014 13:27:51 +0200 Subject: [PATCH 1/3] [fix] __autoload for api from alban + fixing variables & bad preg --- api/panel/bootstrap.php | 2 +- api/panel/index.php | 71 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 69 insertions(+), 4 deletions(-) diff --git a/api/panel/bootstrap.php b/api/panel/bootstrap.php index 4c374fc8..30c7b25a 100644 --- a/api/panel/bootstrap.php +++ b/api/panel/bootstrap.php @@ -21,7 +21,6 @@ $root=ALTERNC_PANEL."/"; require_once($root."class/db_mysql.php"); require_once($root."class/functions.php"); -require_once($root."class/variables.php"); global $L_MYSQL_HOST,$L_MYSQL_DATABASE,$L_MYSQL_LOGIN,$L_MYSQL_PWD; @@ -71,6 +70,7 @@ closedir($c); /* Language */ //include_once("../../class/lang_env.php"); +$variables=new m_variables(); $mem=new m_mem(); $err=new m_err(); $authip=new m_authip(); diff --git a/api/panel/index.php b/api/panel/index.php index 1f33884f..f8e89685 100644 --- a/api/panel/index.php +++ b/api/panel/index.php @@ -30,7 +30,72 @@ define("API_CALL_POST", 2 ); define("API_CALL_POST_REST", 3 ); define("API_CALL_GET_REST", 4 ); -// TODO : __autoload of classes ? +/** + * Attempts to load a class in multiple path, the PSR-0 or old style way + * + * @staticvar array $srcPathList + * @staticvar boolean $init + * @param string $class_name + * @return boolean + */ + +function __autoload($class_name) +{ + // Contains (Namespace) => directory + static $srcPathList = array(); + static $init=null; + + // Attempts to set include path and directories once + if( is_null( $init )){ + + // Sets init flag + $init = true; + + // Sets a contextual directory + $srcPathList["standard"] = "/usr/share/php"; + + // Updates include_path according to this list + $includePathList = explode(PATH_SEPARATOR, get_include_path()); + + foreach($srcPathList as $path){ + if ( !in_array($path, $includePathList)){ + $includePathList[] = $path; + } + } + // Reverses the path for search efficiency + $finalIncludePathList = array_reverse($includePathList); + + // Sets the updated include_path + set_include_path(implode(PATH_SEPARATOR, $finalIncludePathList)); + + } + + // Accepts old Foo_Bar namespacing + if(preg_match("/_/", $class_name)){ + $file_name = str_replace('_', DIRECTORY_SEPARATOR, $class_name) . '.php'; + + // Accepts 5.3 Foo\Bar PSR-0 namespacing + } else if(preg_match("/\\/", $class_name)){ + $file_name = str_replace('\\', DIRECTORY_SEPARATOR, ltrim($class_name,'\\')) . '.php'; + + // Accepts non namespaced classes + } else { + $file_name = $class_name . '.php'; + } + + // Attempts to find file in namespace + foreach($srcPathList as $namespace => $path ){ + $file_path = $path.DIRECTORY_SEPARATOR.$file_name; + if(is_file($file_path) && is_readable($file_path)){ + require $file_path; + return true; + } + } + + // Failed to find file + return false; +} + function apicall($data,$token,$mode) { global $dbh; @@ -85,7 +150,7 @@ function apiauth($data,$mode) { // Authentication -if (preg_match("#^/api/auth/([^/]*)/?#$",$_SERVER["REQUEST_URI"],$mat)) { +if (preg_match("#^/api/auth/([^/\?]*)[/\?]?#",$_SERVER["REQUEST_URI"],$mat)) { if ($_SERVER["REQUEST_METHOD"]=="POST") { $data=array("options" => $_POST, "method" => $mat[1]); @@ -121,7 +186,7 @@ if ($_SERVER["REQUEST_URI"]=="/api/post") { } } -if (preg_match("#^/api/rest/([^/]*)/([^/]*)/?#$",$_SERVER["REQUEST_URI"],$mat)) { +if (preg_match("#^/api/rest/([^/]*)/([^/\?]*)[/\?]?$#",$_SERVER["REQUEST_URI"],$mat)) { if ($_SERVER["REQUEST_METHOD"]=="POST") { $data=array("options" => $_POST, "object" => $mat[1], From 924b36ee191d41c79595af7ea29142fcfadb8a89 Mon Sep 17 00:00:00 2001 From: Benjamin Sonntag Date: Sun, 21 Sep 2014 15:26:25 +0200 Subject: [PATCH 2/3] Auth() for Sharedsecret is now working, Token Object too. --- api/panel/bootstrap.php | 4 ++-- lib/Alternc/Api/Auth/Interface.php | 2 +- lib/Alternc/Api/Auth/Sharedsecret.php | 12 ++++++------ lib/Alternc/Api/Service.php | 3 ++- lib/Alternc/Api/Token.php | 13 +++++++------ 5 files changed, 18 insertions(+), 16 deletions(-) diff --git a/api/panel/bootstrap.php b/api/panel/bootstrap.php index 30c7b25a..52b8e808 100644 --- a/api/panel/bootstrap.php +++ b/api/panel/bootstrap.php @@ -2,7 +2,7 @@ /* Global variables (AlternC configuration) */ -require_once(__DIR__."/../../class/local.php"); +require_once("/usr/share/alternc/panel/class/local.php"); // Define constants from vars of /etc/alternc/local.sh // The you can't choose where is the AlternC Panel @@ -23,7 +23,7 @@ require_once($root."class/db_mysql.php"); require_once($root."class/functions.php"); -global $L_MYSQL_HOST,$L_MYSQL_DATABASE,$L_MYSQL_LOGIN,$L_MYSQL_PWD; +global $L_MYSQL_HOST,$L_MYSQL_DATABASE,$L_MYSQL_LOGIN,$L_MYSQL_PWD,$db,$dbh; class DB_system extends DB_Sql { var $Host,$Database,$User,$Password; diff --git a/lib/Alternc/Api/Auth/Interface.php b/lib/Alternc/Api/Auth/Interface.php index 626027e3..6e324e44 100644 --- a/lib/Alternc/Api/Auth/Interface.php +++ b/lib/Alternc/Api/Auth/Interface.php @@ -10,7 +10,7 @@ interface Alternc_Api_Auth_Interface { * contructor : * $service is an Alternc_Api_Service object having a getDb() method */ - function __constructor($service); + function __construct($service); /** diff --git a/lib/Alternc/Api/Auth/Sharedsecret.php b/lib/Alternc/Api/Auth/Sharedsecret.php index 26d1ec56..57e973bf 100644 --- a/lib/Alternc/Api/Auth/Sharedsecret.php +++ b/lib/Alternc/Api/Auth/Sharedsecret.php @@ -12,8 +12,7 @@ class Alternc_Api_Auth_Sharedsecret implements Alternc_Api_Auth_Interface { const ERR_INVALID_ARGUMENT = 1111801; const ERR_INVALID_SECRET = 1111802; const ERR_INVALID_LOGIN = 1111803; - const ERR_INVALID_LOGIN = 1111804; - const ERR_DISABLED_ACCOUNT = 1111805; + const ERR_DISABLED_ACCOUNT = 1111804; /** @@ -22,7 +21,7 @@ class Alternc_Api_Auth_Sharedsecret implements Alternc_Api_Auth_Interface { * @param $service an Alternc_Api_Service object * @return create the object */ - function __constructor($service) { + function __construct($service) { if (!($service instanceof Alternc_Api_Service)) throw new \Exception("Invalid argument (service)",ERR_INVALID_ARGUMENT); @@ -55,15 +54,16 @@ class Alternc_Api_Auth_Sharedsecret implements Alternc_Api_Auth_Interface { return new Alternc_Api_Response( array("code" => self::ERR_INVALID_LOGIN, "message" => "Invalid login") ); } - $stmt = $db->query("SELECT m.enabled,m.uid,m.login,m.su FROM membres m, sharedsecret s WHERE s.uid=m.uid AND m.login=? AND s.secret=?;",array($options["login"],$options["secret"]),PDO::FETCH_CLASS); - $me=$stmt->fetch(); + $stmt = $this->db->prepare("SELECT m.enabled,m.uid,m.login,m.su FROM membres m, sharedsecret s WHERE s.uid=m.uid AND m.login=? AND s.secret=?;"); + $stmt->execute(array($options["login"],$options["secret"]) ); + $me=$stmt->fetch(PDO::FETCH_OBJ); if (!$me) return new Alternc_Api_Response( array("code" => self::ERR_INVALID_AUTH, "message" => "Invalid shared secret") ); if (!$me->enabled) return new Alternc_Api_Response( array("code" => self::ERR_DISABLED_ACCOUNT, "message" => "Account is disabled") ); return Alternc_Api_Token::tokenGenerate( - array("uid"=>$me->uid, "isAdmin"=>($me->su!=0) ), + array("uid"=>(int)$me->uid, "isAdmin"=>($me->su!=0) ), $this->db ); } diff --git a/lib/Alternc/Api/Service.php b/lib/Alternc/Api/Service.php index 6a771649..1353c1f4 100644 --- a/lib/Alternc/Api/Service.php +++ b/lib/Alternc/Api/Service.php @@ -37,7 +37,7 @@ class Alternc_Api_Service { */ function __construct($options) { - + // What DB shall we connect to? // Note: it MUST be in this mode : $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); if (isset($options["databaseAdapter"]) && $options["databaseAdapter"] instanceof PDO) { @@ -91,6 +91,7 @@ class Alternc_Api_Service { } $adapterName = "Alternc_Api_Auth_".ucfirst(strtolower($auth["method"])); + $authAdapter = new $adapterName($this); $token = $authAdapter->auth($auth["options"]); diff --git a/lib/Alternc/Api/Token.php b/lib/Alternc/Api/Token.php index 79f29220..8607e6e6 100644 --- a/lib/Alternc/Api/Token.php +++ b/lib/Alternc/Api/Token.php @@ -39,7 +39,7 @@ class Alternc_Api_Token { * * @var int */ - public static $tokenDuration = 2678400; // default is a month + public $tokenDuration = 2678400; // default is a month /** @@ -47,7 +47,7 @@ class Alternc_Api_Token { * @param options any of the public above * may contain a dbAdapter, in that case create() will be available */ - public function __constructor($options=array()) { + public function __construct($options=array()) { if (isset($options["uid"]) && is_int($options["uid"])) $this->uid=$options["uid"]; @@ -84,14 +84,15 @@ class Alternc_Api_Token { if (!isset($options["uid"]) || !isset($options["isAdmin"])) { throw new \Exception("Missing Arguments (uid,isAdmin)",self::ERR_MISSING_ARGUMENT); } - + $token=new Alternc_Api_Token($options); do { $token->token = $token->tokenRandom(); - $rows = $db->exec("INSERT IGNORE INTO token SET token=?, expire=DATE_ADD(NOW(), INTERVAL ? SECONDS), data=?", - array($token,$token->tokenDuration, $token->toJson()) - ); + $stmt=$db->prepare("INSERT IGNORE INTO token SET token=?, expire=DATE_ADD(NOW(), INTERVAL ? SECOND), data=?"); + $stmt->execute(array($token->token,$token->tokenDuration, $token->toJson())); + $rows = $stmt->rowCount(); + } while ($rows==0); // prevent collisions return $token; From eaa3f52364397ba2817d4ffe699dbd4bbd5086b1 Mon Sep 17 00:00:00 2001 From: Benjamin Sonntag Date: Sun, 21 Sep 2014 16:44:06 +0200 Subject: [PATCH 3/3] [fix] Auth OK, Call OK --- api/panel/index.php | 9 +++++---- lib/Alternc/Api/Response.php | 2 +- lib/Alternc/Api/Service.php | 11 ++++++----- lib/Alternc/Api/Token.php | 5 +++-- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/api/panel/index.php b/api/panel/index.php index f8e89685..cba32848 100644 --- a/api/panel/index.php +++ b/api/panel/index.php @@ -103,7 +103,7 @@ function apicall($data,$token,$mode) { $options["loginAdapterList"]=array("sharedsecret","login"); // TODO (no loggerAdapter PSR3-Interface-compliant class as of now) try { - + $data["token_hash"]=$token; $service=new Alternc_Api_Service($options); $response = $service->call( @@ -118,7 +118,7 @@ function apicall($data,$token,$mode) { // something went wrong, we spit out the exception as an Api_Response // TODO : Don't do that on production! spit out a generic "fatal error" code and LOG the exception ! header("Content-Type: application/json"); - $response=new Alternc_Api_Response(array("code" => $e->code, "message" => $e->message)); + $response=new Alternc_Api_Response(array("code" => $e->getCode(), "message" => $e->getMessage() )); echo $response->toJson(); exit(); } @@ -185,8 +185,7 @@ if ($_SERVER["REQUEST_URI"]=="/api/post") { exit(); } } - -if (preg_match("#^/api/rest/([^/]*)/([^/\?]*)[/\?]?$#",$_SERVER["REQUEST_URI"],$mat)) { +if (preg_match("#^/api/rest/([^/]*)/([^/\?]*)[/\?]?#",$_SERVER["REQUEST_URI"],$mat)) { if ($_SERVER["REQUEST_METHOD"]=="POST") { $data=array("options" => $_POST, "object" => $mat[1], @@ -205,3 +204,5 @@ if (preg_match("#^/api/rest/([^/]*)/([^/\?]*)[/\?]?$#",$_SERVER["REQUEST_URI"],$ exit(); } } + +echo "I did nothing. Did you call the api properly?"; \ No newline at end of file diff --git a/lib/Alternc/Api/Response.php b/lib/Alternc/Api/Response.php index fe6debe1..ac54ec84 100644 --- a/lib/Alternc/Api/Response.php +++ b/lib/Alternc/Api/Response.php @@ -46,7 +46,7 @@ class Alternc_Api_Response { * initialize a response object * @param options any of the public above */ - public function __constructor($options=array()) { + public function __construct($options=array()) { $os=array("code","message","content","metadata"); foreach ($os as $o) { if (isset($options[$o])) $this->$o=$options[$o]; diff --git a/lib/Alternc/Api/Service.php b/lib/Alternc/Api/Service.php index 1353c1f4..9bd06240 100644 --- a/lib/Alternc/Api/Service.php +++ b/lib/Alternc/Api/Service.php @@ -86,7 +86,7 @@ class Alternc_Api_Service { if (count($this->allowedAuth) && !in_array($auth["method"],$this->allowedAuth)) { throw new \Exception("Method not allowed", self::ERR_METHOD_DENIED); } - if (isset($auth["options"]["uid"]) && !is_int($auth["options"]["uid"])) { + if (isset($auth["options"]["uid"]) && !intval($auth["options"]["uid"])) { throw new \Exception("Invalid UID", self::ERR_INVALID_ARGUMENT); } @@ -109,9 +109,10 @@ class Alternc_Api_Service { return new Alternc_Api_Response( array("code" => self::ERR_SETUID_FORBIDDEN, "message" => "This user is not allowed to set his uid") ); } // Search for the requested user. We allow using *disabled* account here since we are admin - foreach($db->query("SELECT uid FROM membres WHERE uid=?",array($auth["options"]["uid"])) as $setuid) { - $token->uid=$setuid; - $db->exec("UPDATE token SET uid=? WHERE token=?",array( $token->uid, $token->token) ); + foreach($this->db->query("SELECT uid FROM membres WHERE uid=".intval($auth["options"]["uid"])) as $setuid) { + $token->uid=intval($setuid['uid']); + $stmt=$this->db->prepare("UPDATE token SET data=? WHERE token=?"); + $stmt->execute(array( $token->toJson(), $token->token)); return $token; } return new Alternc_Api_Response( array("code" => self::ERR_SETUID_USER_NOT_FOUND, "message" => "Can't find the user you want to setuid to") ); @@ -149,7 +150,7 @@ class Alternc_Api_Service { $request->token=$this->token; // we receive $request->token_hash as a STRING, but we transmit its object as an Alternc_Api_Token. // TODO: log this Api Call - return $object->$action($request); + return $object->$action($request->options); } diff --git a/lib/Alternc/Api/Token.php b/lib/Alternc/Api/Token.php index 8607e6e6..5c07d577 100644 --- a/lib/Alternc/Api/Token.php +++ b/lib/Alternc/Api/Token.php @@ -114,8 +114,9 @@ class Alternc_Api_Token { if (!is_string($token) || !preg_match("#^[a-zA-Z0-9]{32}$#",$token)) { return new Alternc_Api_Response( array("code" => self::ERR_INVALID_TOKEN, "message" => "Invalid token") ); } - - foreach($db->query("SELECT * FROM token WHERE token=?", array($token)) as $tok) { + $stmt=$db->prepare("SELECT * FROM token WHERE token=?"); + $stmt->execute(array($token)); + while ($tok=$stmt->fetch(PDO::FETCH_OBJ)) { return new Alternc_Api_Token( json_decode($tok->data,true) ); }