Merge branch 'feature-api' of alternc.org:alternc into feature-ssl
This commit is contained in:
commit
a3e2257b50
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
|
|
||||||
/* Global variables (AlternC configuration) */
|
/* 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
|
// Define constants from vars of /etc/alternc/local.sh
|
||||||
// The you can't choose where is the AlternC Panel
|
// The you can't choose where is the AlternC Panel
|
||||||
|
@ -21,10 +21,9 @@ $root=ALTERNC_PANEL."/";
|
||||||
|
|
||||||
require_once($root."class/db_mysql.php");
|
require_once($root."class/db_mysql.php");
|
||||||
require_once($root."class/functions.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;
|
global $L_MYSQL_HOST,$L_MYSQL_DATABASE,$L_MYSQL_LOGIN,$L_MYSQL_PWD,$db,$dbh;
|
||||||
|
|
||||||
class DB_system extends DB_Sql {
|
class DB_system extends DB_Sql {
|
||||||
var $Host,$Database,$User,$Password;
|
var $Host,$Database,$User,$Password;
|
||||||
|
@ -71,6 +70,7 @@ closedir($c);
|
||||||
/* Language */
|
/* Language */
|
||||||
//include_once("../../class/lang_env.php");
|
//include_once("../../class/lang_env.php");
|
||||||
|
|
||||||
|
$variables=new m_variables();
|
||||||
$mem=new m_mem();
|
$mem=new m_mem();
|
||||||
$err=new m_err();
|
$err=new m_err();
|
||||||
$authip=new m_authip();
|
$authip=new m_authip();
|
||||||
|
|
|
@ -30,7 +30,72 @@ define("API_CALL_POST", 2 );
|
||||||
define("API_CALL_POST_REST", 3 );
|
define("API_CALL_POST_REST", 3 );
|
||||||
define("API_CALL_GET_REST", 4 );
|
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) {
|
function apicall($data,$token,$mode) {
|
||||||
global $dbh;
|
global $dbh;
|
||||||
|
@ -38,7 +103,7 @@ function apicall($data,$token,$mode) {
|
||||||
$options["loginAdapterList"]=array("sharedsecret","login");
|
$options["loginAdapterList"]=array("sharedsecret","login");
|
||||||
// TODO (no loggerAdapter PSR3-Interface-compliant class as of now)
|
// TODO (no loggerAdapter PSR3-Interface-compliant class as of now)
|
||||||
try {
|
try {
|
||||||
|
$data["token_hash"]=$token;
|
||||||
$service=new Alternc_Api_Service($options);
|
$service=new Alternc_Api_Service($options);
|
||||||
|
|
||||||
$response = $service->call(
|
$response = $service->call(
|
||||||
|
@ -53,7 +118,7 @@ function apicall($data,$token,$mode) {
|
||||||
// something went wrong, we spit out the exception as an Api_Response
|
// 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 !
|
// TODO : Don't do that on production! spit out a generic "fatal error" code and LOG the exception !
|
||||||
header("Content-Type: application/json");
|
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();
|
echo $response->toJson();
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
@ -85,7 +150,7 @@ function apiauth($data,$mode) {
|
||||||
|
|
||||||
|
|
||||||
// Authentication
|
// Authentication
|
||||||
if (preg_match("#^/api/auth/([^/]*)/?#$",$_SERVER["REQUEST_URI"],$mat)) {
|
if (preg_match("#^/api/auth/([^/\?]*)[/\?]?#",$_SERVER["REQUEST_URI"],$mat)) {
|
||||||
if ($_SERVER["REQUEST_METHOD"]=="POST") {
|
if ($_SERVER["REQUEST_METHOD"]=="POST") {
|
||||||
$data=array("options" => $_POST,
|
$data=array("options" => $_POST,
|
||||||
"method" => $mat[1]);
|
"method" => $mat[1]);
|
||||||
|
@ -120,8 +185,7 @@ if ($_SERVER["REQUEST_URI"]=="/api/post") {
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (preg_match("#^/api/rest/([^/]*)/([^/\?]*)[/\?]?#",$_SERVER["REQUEST_URI"],$mat)) {
|
||||||
if (preg_match("#^/api/rest/([^/]*)/([^/]*)/?#$",$_SERVER["REQUEST_URI"],$mat)) {
|
|
||||||
if ($_SERVER["REQUEST_METHOD"]=="POST") {
|
if ($_SERVER["REQUEST_METHOD"]=="POST") {
|
||||||
$data=array("options" => $_POST,
|
$data=array("options" => $_POST,
|
||||||
"object" => $mat[1],
|
"object" => $mat[1],
|
||||||
|
@ -140,3 +204,5 @@ if (preg_match("#^/api/rest/([^/]*)/([^/]*)/?#$",$_SERVER["REQUEST_URI"],$mat))
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
echo "I did nothing. Did you call the api properly?";
|
|
@ -10,7 +10,7 @@ interface Alternc_Api_Auth_Interface {
|
||||||
* contructor :
|
* contructor :
|
||||||
* $service is an Alternc_Api_Service object having a getDb() method
|
* $service is an Alternc_Api_Service object having a getDb() method
|
||||||
*/
|
*/
|
||||||
function __constructor($service);
|
function __construct($service);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -12,8 +12,7 @@ class Alternc_Api_Auth_Sharedsecret implements Alternc_Api_Auth_Interface {
|
||||||
const ERR_INVALID_ARGUMENT = 1111801;
|
const ERR_INVALID_ARGUMENT = 1111801;
|
||||||
const ERR_INVALID_SECRET = 1111802;
|
const ERR_INVALID_SECRET = 1111802;
|
||||||
const ERR_INVALID_LOGIN = 1111803;
|
const ERR_INVALID_LOGIN = 1111803;
|
||||||
const ERR_INVALID_LOGIN = 1111804;
|
const ERR_DISABLED_ACCOUNT = 1111804;
|
||||||
const ERR_DISABLED_ACCOUNT = 1111805;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -22,7 +21,7 @@ class Alternc_Api_Auth_Sharedsecret implements Alternc_Api_Auth_Interface {
|
||||||
* @param $service an Alternc_Api_Service object
|
* @param $service an Alternc_Api_Service object
|
||||||
* @return create the object
|
* @return create the object
|
||||||
*/
|
*/
|
||||||
function __constructor($service) {
|
function __construct($service) {
|
||||||
|
|
||||||
if (!($service instanceof Alternc_Api_Service))
|
if (!($service instanceof Alternc_Api_Service))
|
||||||
throw new \Exception("Invalid argument (service)",ERR_INVALID_ARGUMENT);
|
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") );
|
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);
|
$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=?;");
|
||||||
$me=$stmt->fetch();
|
$stmt->execute(array($options["login"],$options["secret"]) );
|
||||||
|
$me=$stmt->fetch(PDO::FETCH_OBJ);
|
||||||
if (!$me)
|
if (!$me)
|
||||||
return new Alternc_Api_Response( array("code" => self::ERR_INVALID_AUTH, "message" => "Invalid shared secret") );
|
return new Alternc_Api_Response( array("code" => self::ERR_INVALID_AUTH, "message" => "Invalid shared secret") );
|
||||||
if (!$me->enabled)
|
if (!$me->enabled)
|
||||||
return new Alternc_Api_Response( array("code" => self::ERR_DISABLED_ACCOUNT, "message" => "Account is disabled") );
|
return new Alternc_Api_Response( array("code" => self::ERR_DISABLED_ACCOUNT, "message" => "Account is disabled") );
|
||||||
|
|
||||||
return Alternc_Api_Token::tokenGenerate(
|
return Alternc_Api_Token::tokenGenerate(
|
||||||
array("uid"=>$me->uid, "isAdmin"=>($me->su!=0) ),
|
array("uid"=>(int)$me->uid, "isAdmin"=>($me->su!=0) ),
|
||||||
$this->db
|
$this->db
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ class Alternc_Api_Response {
|
||||||
* initialize a response object
|
* initialize a response object
|
||||||
* @param options any of the public above
|
* @param options any of the public above
|
||||||
*/
|
*/
|
||||||
public function __constructor($options=array()) {
|
public function __construct($options=array()) {
|
||||||
$os=array("code","message","content","metadata");
|
$os=array("code","message","content","metadata");
|
||||||
foreach ($os as $o) {
|
foreach ($os as $o) {
|
||||||
if (isset($options[$o])) $this->$o=$options[$o];
|
if (isset($options[$o])) $this->$o=$options[$o];
|
||||||
|
|
|
@ -86,11 +86,12 @@ class Alternc_Api_Service {
|
||||||
if (count($this->allowedAuth) && !in_array($auth["method"],$this->allowedAuth)) {
|
if (count($this->allowedAuth) && !in_array($auth["method"],$this->allowedAuth)) {
|
||||||
throw new \Exception("Method not allowed", self::ERR_METHOD_DENIED);
|
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);
|
throw new \Exception("Invalid UID", self::ERR_INVALID_ARGUMENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
$adapterName = "Alternc_Api_Auth_".ucfirst(strtolower($auth["method"]));
|
$adapterName = "Alternc_Api_Auth_".ucfirst(strtolower($auth["method"]));
|
||||||
|
|
||||||
$authAdapter = new $adapterName($this);
|
$authAdapter = new $adapterName($this);
|
||||||
|
|
||||||
$token = $authAdapter->auth($auth["options"]);
|
$token = $authAdapter->auth($auth["options"]);
|
||||||
|
@ -108,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") );
|
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
|
// 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) {
|
foreach($this->db->query("SELECT uid FROM membres WHERE uid=".intval($auth["options"]["uid"])) as $setuid) {
|
||||||
$token->uid=$setuid;
|
$token->uid=intval($setuid['uid']);
|
||||||
$db->exec("UPDATE token SET uid=? WHERE token=?",array( $token->uid, $token->token) );
|
$stmt=$this->db->prepare("UPDATE token SET data=? WHERE token=?");
|
||||||
|
$stmt->execute(array( $token->toJson(), $token->token));
|
||||||
return $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") );
|
return new Alternc_Api_Response( array("code" => self::ERR_SETUID_USER_NOT_FOUND, "message" => "Can't find the user you want to setuid to") );
|
||||||
|
@ -148,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.
|
$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
|
// TODO: log this Api Call
|
||||||
return $object->$action($request);
|
return $object->$action($request->options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ class Alternc_Api_Token {
|
||||||
*
|
*
|
||||||
* @var int
|
* @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
|
* @param options any of the public above
|
||||||
* may contain a dbAdapter, in that case create() will be available
|
* 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"]))
|
if (isset($options["uid"]) && is_int($options["uid"]))
|
||||||
$this->uid=$options["uid"];
|
$this->uid=$options["uid"];
|
||||||
|
@ -89,9 +89,10 @@ class Alternc_Api_Token {
|
||||||
|
|
||||||
do {
|
do {
|
||||||
$token->token = $token->tokenRandom();
|
$token->token = $token->tokenRandom();
|
||||||
$rows = $db->exec("INSERT IGNORE INTO token SET token=?, expire=DATE_ADD(NOW(), INTERVAL ? SECONDS), data=?",
|
$stmt=$db->prepare("INSERT IGNORE INTO token SET token=?, expire=DATE_ADD(NOW(), INTERVAL ? SECOND), data=?");
|
||||||
array($token,$token->tokenDuration, $token->toJson())
|
$stmt->execute(array($token->token,$token->tokenDuration, $token->toJson()));
|
||||||
);
|
$rows = $stmt->rowCount();
|
||||||
|
|
||||||
} while ($rows==0); // prevent collisions
|
} while ($rows==0); // prevent collisions
|
||||||
|
|
||||||
return $token;
|
return $token;
|
||||||
|
@ -113,8 +114,9 @@ class Alternc_Api_Token {
|
||||||
if (!is_string($token) || !preg_match("#^[a-zA-Z0-9]{32}$#",$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") );
|
return new Alternc_Api_Response( array("code" => self::ERR_INVALID_TOKEN, "message" => "Invalid token") );
|
||||||
}
|
}
|
||||||
|
$stmt=$db->prepare("SELECT * FROM token WHERE token=?");
|
||||||
foreach($db->query("SELECT * FROM token WHERE token=?", array($token)) as $tok) {
|
$stmt->execute(array($token));
|
||||||
|
while ($tok=$stmt->fetch(PDO::FETCH_OBJ)) {
|
||||||
return new Alternc_Api_Token( json_decode($tok->data,true) );
|
return new Alternc_Api_Token( json_decode($tok->data,true) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue