Beispiel #1
0
/**
 * Executes a method.
 * A method is a function which you have previously exposed using expose_function.
 *
 * @param string $method Method, e.g. "foo.bar"
 *
 * @return GenericResult The result of the execution.
 * @throws APIException|CallException
 * @access private
 */
function execute_method($method)
{
    global $API_METHODS;
    // method must be exposed
    if (!isset($API_METHODS[$method])) {
        $msg = elgg_echo('APIException:MethodCallNotImplemented', array($method));
        throw new APIException($msg);
    }
    // function must be callable
    $function = elgg_extract('function', $API_METHODS[$method]);
    if (!$function || !is_callable($function)) {
        $msg = elgg_echo('APIException:FunctionDoesNotExist', array($method));
        throw new APIException($msg);
    }
    // check http call method
    if (strcmp(get_call_method(), $API_METHODS[$method]["call_method"]) != 0) {
        $msg = elgg_echo('CallException:InvalidCallMethod', array($method, $API_METHODS[$method]["call_method"]));
        throw new CallException($msg);
    }
    $parameters = get_parameters_for_method($method);
    // may throw exception, which is not caught here
    verify_parameters($method, $parameters);
    $serialised_parameters = serialise_parameters($method, $parameters);
    // Execute function: Construct function and calling parameters
    $serialised_parameters = trim($serialised_parameters, ", ");
    // Sadly we probably can't get rid of this eval() in 2.x. Doing so would involve
    // replacing serialise_parameters(), which does a bunch of weird stuff we need to
    // stay BC with 2.x. There are tests for a lot of these quirks in ElggCoreWebServicesApiTest
    // particularly in testSerialiseParametersCasting().
    $arguments = eval("return [{$serialised_parameters}];");
    if ($API_METHODS[$method]['assoc']) {
        $argument = array_combine(_elgg_ws_get_parameter_names($method), $arguments);
        $result = call_user_func($function, $argument);
    } else {
        $result = call_user_func_array($function, $arguments);
    }
    $result = elgg_trigger_plugin_hook('rest:output', $method, $parameters, $result);
    // Sanity check result
    // If this function returns an api result itself, just return it
    if ($result instanceof GenericResult) {
        return $result;
    }
    if ($result === false) {
        $msg = elgg_echo('APIException:FunctionParseError', array($function, $serialised_parameters));
        throw new APIException($msg);
    }
    if ($result === NULL) {
        // If no value
        $msg = elgg_echo('APIException:FunctionNoReturn', array($function, $serialised_parameters));
        throw new APIException($msg);
    }
    // Otherwise assume that the call was successful and return it as a success object.
    return SuccessResult::getInstance($result);
}
/**
 * Executes a method.
 * A method is a function which you have previously exposed using expose_function.
 *
 * @param string $method Method, e.g. "foo.bar"
 *
 * @return GenericResult The result of the execution.
 * @throws APIException|CallException
 * @access private
 */
function execute_method($method)
{
    global $API_METHODS;
    // method must be exposed
    if (!isset($API_METHODS[$method])) {
        $msg = elgg_echo('APIException:MethodCallNotImplemented', array($method));
        throw new APIException($msg);
    }
    // function must be callable
    $function = null;
    if (isset($API_METHODS[$method]["function"])) {
        $function = $API_METHODS[$method]["function"];
        // allow array version of static callback
        if (is_array($function) && isset($function[0], $function[1]) && is_string($function[0]) && is_string($function[1])) {
            $function = "{$function[0]}::{$function[1]}";
        }
    }
    if (!is_string($function) || !is_callable($function)) {
        $msg = elgg_echo('APIException:FunctionDoesNotExist', array($method));
        throw new APIException($msg);
    }
    // check http call method
    if (strcmp(get_call_method(), $API_METHODS[$method]["call_method"]) != 0) {
        $msg = elgg_echo('CallException:InvalidCallMethod', array($method, $API_METHODS[$method]["call_method"]));
        throw new CallException($msg);
    }
    $parameters = get_parameters_for_method($method);
    // may throw exception, which is not caught here
    verify_parameters($method, $parameters);
    $serialised_parameters = serialise_parameters($method, $parameters);
    // Execute function: Construct function and calling parameters
    $serialised_parameters = trim($serialised_parameters, ", ");
    // @todo remove the need for eval()
    $result = eval("return {$function}({$serialised_parameters});");
    $result = elgg_trigger_plugin_hook('rest:output', $method, $parameters, $result);
    // Sanity check result
    // If this function returns an api result itself, just return it
    if ($result instanceof GenericResult) {
        return $result;
    }
    if ($result === false) {
        $msg = elgg_echo('APIException:FunctionParseError', array($function, $serialised_parameters));
        throw new APIException($msg);
    }
    if ($result === NULL) {
        // If no value
        $msg = elgg_echo('APIException:FunctionNoReturn', array($function, $serialised_parameters));
        throw new APIException($msg);
    }
    // Otherwise assume that the call was successful and return it as a success object.
    return SuccessResult::getInstance($result);
}
Beispiel #3
0
/**
 * Executes a method.
 * A method is a function which you have previously exposed using expose_function.
 *
 * @param string $method Method, e.g. "foo.bar"
 *
 * @return GenericResult The result of the execution.
 * @throws APIException, CallException
 * @access private
 */
function execute_method($method)
{
    global $API_METHODS, $CONFIG;
    // method must be exposed
    if (!isset($API_METHODS[$method])) {
        $msg = elgg_echo('APIException:MethodCallNotImplemented', array($method));
        throw new APIException($msg);
    }
    // function must be callable
    if (!isset($API_METHODS[$method]["function"]) || !is_callable($API_METHODS[$method]["function"])) {
        $msg = elgg_echo('APIException:FunctionDoesNotExist', array($method));
        throw new APIException($msg);
    }
    // check http call method
    if (strcmp(get_call_method(), $API_METHODS[$method]["call_method"]) != 0) {
        $msg = elgg_echo('CallException:InvalidCallMethod', array($method, $API_METHODS[$method]["call_method"]));
        throw new CallException($msg);
    }
    $parameters = get_parameters_for_method($method);
    if (verify_parameters($method, $parameters) == false) {
        // if verify_parameters fails, it throws exception which is not caught here
    }
    $serialised_parameters = serialise_parameters($method, $parameters);
    // Execute function: Construct function and calling parameters
    $function = $API_METHODS[$method]["function"];
    $serialised_parameters = trim($serialised_parameters, ", ");
    // @todo document why we cannot use call_user_func_array here
    $result = eval("return {$function}({$serialised_parameters});");
    // Sanity check result
    // If this function returns an api result itself, just return it
    if ($result instanceof GenericResult) {
        return $result;
    }
    if ($result === false) {
        $msg = elgg_echo('APIException:FunctionParseError', array($function, $serialised_parameters));
        throw new APIException($msg);
    }
    if ($result === NULL) {
        // If no value
        $msg = elgg_echo('APIException:FunctionNoReturn', array($function, $serialised_parameters));
        throw new APIException($msg);
    }
    // Otherwise assume that the call was successful and return it as a success object.
    return SuccessResult::getInstance($result);
}
Beispiel #4
0
    throw new SecurityException(elgg_echo('SecurityException:APIAccessDenied'));
}
// Register some default PAM methods, plugins can add their own
register_pam_handler('pam_auth_session_or_hmac');
// Command must either be authenticated by a hmac or the user is already logged in
register_pam_handler('pam_auth_usertoken', 'required');
// Either token present and valid OR method doesn't require one.
register_pam_handler('pam_auth_anonymous_method');
// Support anonymous functions
// Get parameter variables
$method = get_input('method');
$result = null;
// Authenticate session
if (pam_authenticate()) {
    // Authenticated somehow, now execute.
    $token = "";
    $params = get_parameters_for_method($method);
    // Use $CONFIG->input instead of $_REQUEST since this is called by the pagehandler
    if (isset($params['auth_token'])) {
        $token = $params['auth_token'];
    }
    $result = execute_method($method, $params, $token);
} else {
    throw new SecurityException(elgg_echo('SecurityException:NoAuthMethods'));
}
// Finally output
if (!$result instanceof GenericResult) {
    throw new APIException(elgg_echo('APIException:ApiResultUnknown'));
}
// Output the result
page_draw($method, elgg_view("api/output", array("result" => $result)));
Beispiel #5
0
/**
 * This function looks at the super-global variable $_SERVER and extracts the various
 * header variables needed to pass to the validation functions after performing basic validation.
 *
 * @return stdClass Containing all the values.
 * @throws APIException Detailing any error.
 */
function get_and_validate_api_headers()
{
    $result = new stdClass();
    $result->method = get_call_method();
    if ($result->method != "GET" && $result->method != "POST") {
        // Only allow these methods
        throw new APIException(elgg_echo('APIException:NotGetOrPost'));
    }
    $result->api_key = $_SERVER['HTTP_X_ELGG_APIKEY'];
    if ($result->api_key == "") {
        throw new APIException(elgg_echo('APIException:MissingAPIKey'));
    }
    $result->hmac = $_SERVER['HTTP_X_ELGG_HMAC'];
    if ($result->hmac == "") {
        throw new APIException(elgg_echo('APIException:MissingHmac'));
    }
    $result->hmac_algo = $_SERVER['HTTP_X_ELGG_HMAC_ALGO'];
    if ($result->hmac_algo == "") {
        throw new APIException(elgg_echo('APIException:MissingHmacAlgo'));
    }
    $result->time = $_SERVER['HTTP_X_ELGG_TIME'];
    if ($result->time == "") {
        throw new APIException(elgg_echo('APIException:MissingTime'));
    }
    if ($result->time < microtime(true) - 86400.0 || $result->time > microtime(true) + 86400.0) {
        // Basic timecheck, think about making this smaller if we get loads of users and the cache gets really big.
        throw new APIException(elgg_echo('APIException:TemporalDrift'));
    }
    $result->get_variables = get_parameters_for_method(get_input('method'));
    //$_SERVER['QUERY_STRING'];
    if ($result->get_variables == "") {
        throw new APIException(elgg_echo('APIException:NoQueryString'));
    }
    if ($result->method == "POST") {
        $result->posthash = $_SERVER['HTTP_X_ELGG_POSTHASH'];
        if ($result->posthash == "") {
            throw new APIException(elgg_echo('APIException:MissingPOSTHash'));
        }
        $result->posthash_algo = $_SERVER['HTTP_X_ELGG_POSTHASH_ALGO'];
        if ($result->posthash_algo == "") {
            throw new APIException(elgg_echo('APIException:MissingPOSTAlgo'));
        }
        $result->content_type = $_SERVER['CONTENT_TYPE'];
        if ($result->content_type == "") {
            throw new APIException(elgg_echo('APIException:MissingContentType'));
        }
    }
    return $result;
}