diff --git a/proxy/proxy.php b/proxy/proxy.php index f0138ed..5deebcf 100644 --- a/proxy/proxy.php +++ b/proxy/proxy.php @@ -197,7 +197,6 @@ function civiproxy_get_parameters($valid_parameters, $request = NULL) { $result[$name] = civiproxy_sanitise($request[$name], $type); } } - // process wildcard elements if ($default_sanitation !== NULL) { // i.e. we want the others too @@ -336,7 +335,7 @@ function civiproxy_get_valid_allowed_actions_key($action, $rest_allowed_actions) $remote_addr = $_SERVER['REMOTE_ADDR']; // check IP specific whitelisting if specified for this address if (isset($rest_allowed_actions[$remote_addr])) { - if (isset($rest_allowed_actions[$remote_addr][$action['entity']]) && isset($rest_allowed_actions[$remote_addr][$action['entity']][$action['action']])) { + if (civiproxy_validate_api_entity_and_action($remote_addr, $action['entity'], $action['action'], $rest_allowed_actions)) { $valid_key = $remote_addr; } else { $valid_key = 'all'; @@ -347,3 +346,81 @@ function civiproxy_get_valid_allowed_actions_key($action, $rest_allowed_actions) return $valid_key; } +/** + * Function to check whether the api entity and api action are valid for the remote address. + * This function does a case insensitive comparison. + * + * @param $remote_addr + * 'all', or the remote address. + * @param $api_entity + * The api entity. + * @param $api_action + * The api action. + * @param $rest_allowed_actions + * The array with the allowed actions. + * @return bool + */ +function civiproxy_validate_api_entity_and_action($remote_addr, $api_entity, $api_action, $rest_allowed_actions) { + if (!isset($rest_allowed_actions[$remote_addr])) { + return false; + } + + $api_entity = strtolower($api_entity); + $api_action = strtolower($api_action); + if (isset($rest_allowed_actions[$remote_addr][$api_entity]) && isset($rest_allowed_actions[$remote_addr][$api_entity][$api_action])) { + return true; + } + + // Did not find the lower case variant. + // loop through the array + foreach($rest_allowed_actions[$remote_addr] as $allowed_entity => $allowed_actions) { + if (strtolower($allowed_entity) == $api_entity) { + foreach($allowed_actions as $allowed_action => $fields) { + if (strtolower($allowed_action) == $api_action) { + return true; + } + } + } + } + return false; +} + +/** + * Function to retrieve the valid parameters of an api call + * This function does a case insensitive comparison. + * + * @param $remote_addr + * 'all', or the remote address. + * @param $api_entity + * The api entity. + * @param $api_action + * The api action. + * @param $rest_allowed_actions + * The array with the allowed actions. + * @return array()|null + **/ +function civiproxy_retrieve_api_parameters($remote_addr, $api_entity, $api_action, $rest_allowed_actions) { + if (!isset($rest_allowed_actions[$remote_addr])) { + return null; + } + + $api_entity = strtolower($api_entity); + $api_action = strtolower($api_action); + if (isset($rest_allowed_actions[$remote_addr][$api_entity]) && isset($rest_allowed_actions[$remote_addr][$api_entity][$api_action])) { + return $rest_allowed_actions[$remote_addr][$api_entity][$api_action]; + } + + // Did not find the lower case variant. + // loop through the array + foreach($rest_allowed_actions[$remote_addr] as $allowed_entity => $allowed_actions) { + if (strtolower($allowed_entity) == $api_entity) { + foreach($allowed_actions as $allowed_action => $parameters) { + if (strtolower($allowed_action) == $api_action) { + return $parameters; + } + } + } + } + return null; +} + diff --git a/proxy/rest.php b/proxy/rest.php index a8848d4..c465b88 100644 --- a/proxy/rest.php +++ b/proxy/rest.php @@ -52,10 +52,8 @@ if (!isset($action['version']) || $action['version'] != 3) { if (isset($rest_allowed_actions['all'])) { // get valid key for the rest_allowed_actions $valid_allowed_key = civiproxy_get_valid_allowed_actions_key($action, $rest_allowed_actions); - - if (isset($rest_allowed_actions[$valid_allowed_key][$action['entity']]) && isset($rest_allowed_actions[$valid_allowed_key][$action['entity']][$action['action']])) { - $valid_parameters = $rest_allowed_actions[$valid_allowed_key][$action['entity']][$action['action']]; - } else { + $valid_parameters = civiproxy_retrieve_api_parameters($valid_allowed_key, $action['entity'], $action['action'], $rest_allowed_actions); + if (!$valid_parameters) { civiproxy_rest_error("Invalid entity/action."); } } else { @@ -80,7 +78,7 @@ global $rest_evaluate_json_parameter; if ($rest_evaluate_json_parameter) { if (isset($_REQUEST['json'])) { $json_data = json_decode($_REQUEST['json'], true); - if (!empty($json_data)) { + if (!empty($json_data) && is_array($json_data)) { $json_parameters = civiproxy_get_parameters($valid_parameters, $json_data); $parameters['json'] = json_encode($json_parameters); }