diff options
-rw-r--r-- | endpoints/rest.php | 11 | ||||
-rw-r--r-- | engine/lib/api.php | 129 | ||||
-rw-r--r-- | engine/lib/users.php | 3 | ||||
-rw-r--r-- | engine/schema/mysql.sql | 19 | ||||
-rw-r--r-- | index.php | 5 |
5 files changed, 153 insertions, 14 deletions
diff --git a/endpoints/rest.php b/endpoints/rest.php index 483971eb4..cb47804ed 100644 --- a/endpoints/rest.php +++ b/endpoints/rest.php @@ -17,10 +17,10 @@ // Register the error handler error_reporting(E_ALL); - set_error_handler('__php_error_handler'); + set_error_handler('__php_api_error_handler'); // Register a default exception handler - set_exception_handler('__php_exception_handler'); + set_exception_handler('__php_api_exception_handler'); // Get parameter variables $format = get_input('format', 'php'); @@ -40,6 +40,11 @@ // Get api header $api_header = get_and_validate_api_headers(); $ApiEnvironment->api_header = $api_header; + + // Get site + + + // Pull API user details $ApiEnvironment->api_user = get_api_user($api_header->api_key); @@ -94,6 +99,8 @@ } else { + // TODO: set site environment + // User is logged in, just execute if (isset($params['auth_token'])) $token = $params['auth_token']; $result = execute_method($method, $params, $token); diff --git a/engine/lib/api.php b/engine/lib/api.php index b446c5d63..0e9260629 100644 --- a/engine/lib/api.php +++ b/engine/lib/api.php @@ -162,8 +162,7 @@ /** Create the environment for API Calls */ $ApiEnvironment = new stdClass; - - + /** * An array holding methods. * The structure of this is @@ -182,8 +181,22 @@ */ $METHODS = array(); + /** + * Validate a token against a given site. + * + * A token registered with one site can not be used from a different apikey(site), so be aware of this + * during development. + * + * @param int $site The ID of the site + * @param string $token The Token. + * @return mixed The user id attached to the token or false. + */ + function validate_user_token($site, $token) + { + $u = new User(); - // export function + return $u->getUserIDFromAuthToken($site, $token); + } /** * Expose an arbitrary function as an api call. @@ -198,6 +211,26 @@ */ function expose_function($method, $function, array $parameters = NULL, $require_auth = true) { + global $METHODS; + + if ( + ($method!="") && + ($function!="") + ) + { + $METHODS[$method] = array(); + + $METHODS[$method]["function"] = $function; + + if ($parameters!=NULL) + $METHODS[$method]["parameters"] = $parameters; + + $METHODS[$method]["require_auth"] = $require_auth; + + return true; + } + + return false; } /** @@ -212,9 +245,91 @@ */ function execute_method($method, array $parameters, $token = "") { - - // TODO: If auth token, validate user and set session + global $METHODS, $ApiEnvironment; + // Sanity check + $method = trim($method); + $token = trim($token); + + // See if we can find the method handler + if (is_callable($METHODS[$method]["function"])) + { + $serialised_parameters = ""; + + $validated_userid = validate_user_token($ApiEnvironment->site_id, $token); + + if ((!$METHODS[$method]["require_auth"]) || ($validated_userid) || (isloggedin())) + { + // If we have parameters then we need to sanitise the parameters. + if ((isset($METHODS[$method]["parameters"])) && (is_array($METHODS[$method]["parameters"]))) + { + foreach ($METHODS[$method]["parameters"] as $key => $value) + { + if ( + (is_array($value)) // Check that this is an array + && (isset($value['type'])) // Check we have a type defined + ) + { + // Check that the variable is present in the request + + if ( + (!isset($parameters[$key])) && // No parameter + ((!isset($value['required'])) || ($value['required']!=true)) // and not optional + ) + throw new APIException("Missing parameter $key in method $method"); + else + { + // Avoid debug error + if (isset($parameters[$key])) + { + // Set variables casting to type. + switch (strtolower($value['type'])) + { + case 'int': + case 'integer' : $serialised_parameters .= "," . (int)trim($parameters[$key]); break; + case 'bool': + case 'boolean': + if (strcasecmp(trim($parameters[$key]), "false")==0) + $parameters[$key]=''; + + $serialised_parameters .= "," . (bool)trim($parameters[$key]); + break; + case 'string': $serialised_parameters .= ",'" . (string)mysql_real_escape_string(trim($parameters[$key])) . "'"; + break; + case 'float': $serialised_parameters .= "," . (float)trim($parameters[$key]); + break; + + default : throw new APIException("Unrecognised type in cast {$value['type']} for variable '$key' in method '$method'"); + } + } + } + } + else + throw new APIException("Invalid parameter found for '$key' in method '$method'."); + } + } + + // Execute function: Construct function and calling parameters + $function = $METHODS[$method]["function"]; + $serialised_parameters = trim($serialised_parameters, ", "); + + $result = eval("return $function($serialised_parameters);"); + + // Sanity check result + if ($result instanceof GenericResult) // If this function returns an api result itself, just return it + return $result; + + if ($result === FALSE) + throw new APIException("$function($serialised_parameters) has a parsing error."); + + if ($result === NULL) + throw new APIException("$function($serialised_parameters) returned no value."); // If no value + + return SuccessResult::getInstance($result); // Otherwise assume that the call was successful and return it as a success object. + } + else + throw new SecurityException("Authentication token either missing, invalid or expired.", GenericResult::$RESULT_FAIL_AUTHTOKEN); + } // Return an error if not found throw new APIException("Method call '$method' has not been implemented."); @@ -227,7 +342,7 @@ * @return stdClass Containing all the values. * @throws APIException Detailing the error. */ - function get_and_validate_api_headers() + function get_and_validate_api_headers() { $result = new stdClass; @@ -351,8 +466,6 @@ return true; } - - // XML functions ////////////////////////////////////////////////////////////////////////// /** diff --git a/engine/lib/users.php b/engine/lib/users.php index 6003be706..24ded8ce5 100644 --- a/engine/lib/users.php +++ b/engine/lib/users.php @@ -708,7 +708,8 @@ setcookie("elggperm", $code, (time()+(86400 * 30)),"/");
//}
- // set_login_fields($user->id);
+ // set_login_fields($user->id); +
}
diff --git a/engine/schema/mysql.sql b/engine/schema/mysql.sql index 8563eed7e..dff19be35 100644 --- a/engine/schema/mysql.sql +++ b/engine/schema/mysql.sql @@ -119,6 +119,23 @@ CREATE TABLE `prefix_users` ( ) ENGINE=MyISAM ;
+--
+-- User sessions
+--
+
+CREATE TABLE `prefix_users_apisessions` (
+ `id` int(11) NOT NULL auto_increment,
+ `user_id` int(11) NOT NULL,
+ `site_id` int(11) NOT NULL,
+
+ `token` varchar(40),
+
+ `expires` int(11) NOT NULL,
+
+ PRIMARY KEY (`id`),
+ UNIQUE KEY (`user_id`,`site_id`)
+) ENGINE=MyISAM;
+
-- --------------------------------------------------------
--
@@ -215,7 +232,7 @@ CREATE TABLE `prefix_api_users` ( id int(11) auto_increment,
email_address varchar(128),
-
+ site_id int(11),
api_key varchar(40),
secret varchar(40) NOT NULL,
active int default 1,
@@ -87,7 +87,8 @@ error_log("GETTIGN SITE ".$_SESSION['id']. " " . print_r($site, true)); // get site metadata
- error_log("SITE Metadata : " . print_r($site->getMetadata("Metaname"), true));
+ error_log("SITE Metadata : " . print_r($site->getMetadata("Metaname"), true)); + +
*/
-
?>
\ No newline at end of file |