Я пытаюсь создать пользовательский API, содержащий метод с именем callToMethod
.Этот метод вызывает другой метод с именем bypassSugarAuthenticationVariables
, который устанавливает 3 переменные для значений, которые я им присвоил:
$_REQUEST['platform']
$_GET['oauth_token']
или $_POST['oauth_token']
$_SESSION['authenticated_user_id']
После вызова этой функции я использую cURL
для установки вызова rest
в callToMethod
на другой API в приложении (SugarCRM RestService
), ожидая, что эти переменные останутся установленными.Однако конечная точка этого вызова не распознает ни одну из этих переменных.
Я не могу изменить конечную точку RestService
, потому что тогда она станет небезопасной для обновления.
Я пытался использовать CURLOPT_POSTFIELDS
, но он не работает, и я не думаю, что смог бы передать ему $_REQUEST['platform']
и $_SESSION['authenticated_user_id']
в любом случае.
Есть ли способ, которым я могу отправить эти переменные в конечную точку rest
из пользовательского API без изменения RestService
?
Вот мой пользовательский API:
<?php
if (!defined('sugarEntry') || !sugarEntry) {
die('Not A Valid Entry Point');
}
class customPortalApi extends SugarApi
{
protected $store;
public function registerApiRest() //register methods here
{
return array(
'customToken' => array(
'reqType' => 'POST',
'path' => array('customPortalApi', 'customToken'),
'pathVars' => array('', ''),
'method' => 'customToken',
'shortHelp' => 'OAuth2 token requests.',
'longHelp' => 'include/api/help/oauth2_token_post_help.html',
'noLoginRequired' => true,
'keepSession' => true,
'ignoreMetaHash' => true,
'ignoreSystemStatusError' => true,
),
'callToMethod' => array(
'reqType' => 'POST',
'path' => array('customPortalApi', 'callToMethod'),
'pathVars' => array('', ''),
'method' => 'callToMethod',
'shortHelp' => 'Method call request.',
'longHelp' => '',
'noLoginRequired' => true,
'keepSession' => true,
'ignoreMetaHash' => true,
'ignoreSystemStatusError' => true,
)
);
}
public function customToken($api, array $args) //generate custom token if unavailable/expired
{
$module = BeanFactory::getBean($args["module"]);
$module->retrieve_by_string_fields(array(
"email" => $args["email"],
"password_c" => $args["user"]
));
if ($module->id) {
$userData = $this->checkTokenValid("id", $module->id);
if ($userData == false) {
$authData = array(
"token" => $this->genAccessToken(),
"expires_on" => date('Y-m-d', strtotime(date("Y/m/d") . ' + 1 days')),
"module" => $args["module"],
"id" => $module->id,
);
$this->saveToken($authData);
return $authData;
} else {
return $userData;
}
} else {
die("Invalid creds");
// tell the credentials are wrong.
}
}
public function checkTokenValid($field, $id) //series of checks to see if the token exists / is valid
{
$sql = sprintf("SELECT * FROM `custom_oauth` WHERE $field LIKE '%s'", $id);
$result = $GLOBALS['db']->query($sql);
$row = $result->fetch_assoc();
$currDate = date('Y-m-d', strtotime(date("Y/m/d")));
//also check if the token has expired
if ($row['expires_on'] <= $currDate) {
$sql = sprintf("DELETE FROM `custom_oauth` WHERE $field LIKE '%s'", $id);
$result = $GLOBALS['db']->query($sql);
return false;
} elseif (empty($row)) {
return false;
} else {
return $row;
}
}
protected function saveToken(array $arr) //save to custom table
{
$sql = sprintf("INSERT INTO `custom_oauth` (`id`, `module`, `token`, `expires_on`) VALUES ('%s', '%s', '%s', '%s')",
$arr["id"], $arr["module"], $arr["token"], $arr["expires_on"]);
$result = $GLOBALS['db']->query($sql);
}
public function callToMethod($api, array $args)
{
if ($this->checkTokenValid("token", $args['token']) !== false) {
$this->bypassSugarAuthenticationVariables($args['platform'], $args['request_type'], $args['token']);
//here
$recent_url = "http://localhost/SugarPro-Full-8.0.0/rest/v11_1/Leads";
$recent_request = curl_init($recent_url);
curl_setopt($recent_request, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_setopt($recent_request, CURLOPT_HEADER, false);
curl_setopt($recent_request, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($recent_request, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($recent_request, CURLOPT_FOLLOWLOCATION, 0);
curl_setopt($recent_request, CURLOPT_HTTPHEADER, array(
"Content-Type: application/json",
"oauth-token: {$args['token']} "
));
//execute request
$recent_response = curl_exec($recent_request);
//decode json
$recent_response_obj = json_decode($recent_response);
//end
}
}
protected function genAccessToken()
{
$tokenLen = 40;
if (file_exists('/dev/urandom')) { // Get 100 bytes of random data
$randomData = file_get_contents('/dev/urandom', false, null, 0, 100) . uniqid(mt_rand(), true);
} else {
$randomData = mt_rand() . mt_rand() . mt_rand() . mt_rand() . microtime(true) . uniqid(mt_rand(), true);
}
return substr(hash('sha512', $randomData), 0, $tokenLen);
}
// pretty functions doing awesome stuff to trick sugar variables
public function initializeSystemUser()
{
$current_user = BeanFactory::retrieveBean('Users');
$GLOBALS['current_user'] = $current_user->getSystemUser();
}
public function setPlatform($platform)
{
$_REQUEST['platform'] = $platform;
}
public function setAuthenticatedUserId()
{
$this->initializeSystemUser();
$_SESSION['authenticated_user_id'] = $GLOBALS['current_user']->id;
}
public function setOauthToken($request_type, $token)
{
if ($request_type == "GET") {
$_GET['oauth_token'] = $token;
} else {
if ($request_type == "POST") {
$_POST['oauth_token'] = $token;
} else {
new SugarApiExceptionInvalidParameter("Invalid Request Type!");
}
}
}
// magic to bundle the awesome functions together
public function bypassSugarAuthenticationVariables($platform, $request_type, $token)
{
$this->setAuthenticatedUserId();
$this->setPlatform($platform);
$this->setOauthToken($request_type, $token);
}
}
SugarCRM RestService
огромен, например, я скопировал методы authenticateUser
и grabToken
, чтобы дать вам представление об использовании переменной:
AuthenticateUser:
protected function authenticateUser()
{
$valid = false;
die(print_r($_POST));
$token = $this->grabToken();
$platform = !empty($_REQUEST['platform']) ? $_REQUEST['platform'] : 'base';
if ( !empty($token) ) {
try {
$oauthServer = \SugarOAuth2Server::getOAuth2Server($platform);
$oauthServer->verifyAccessToken($token);
if (isset($_SESSION['authenticated_user_id'])) {
$authController = AuthenticationController::getInstance();
// This will return false if anything is wrong with the session
// (mismatched IP, mismatched unique_key, etc)
$valid = $authController->apiSessionAuthenticate();
if ($valid) {
$valid = $this->userAfterAuthenticate($_SESSION['authenticated_user_id'], $oauthServer);
}
if (!$valid) {
// Need to populate the exception here so later code
// has it and can send the correct status back to the client
$e = new SugarApiExceptionInvalidGrant();
}
}
} catch ( OAuth2AuthenticateException $e ) {
// This was failing if users were passing an oauth token up to a public url.
$valid = false;
} catch ( SugarApiException $e ) {
// If we get an exception during this we'll assume authentication failed
$valid = false;
}
}
if (!$valid) {
// If token is invalid, clear the session for bwc
// It looks like a big upload can cause no auth error,
// so we do it here instead of the catch block above
$_SESSION = array();
$exception = (isset($e)) ? $e : false;
return array('isLoggedIn' => false, 'exception' => $exception);
}
return array('isLoggedIn' => true, 'exception' => false);
}
grabToken:
protected function grabToken()
{
// Bug 61887 - initial portal load dies with undefined variable error
// Initialize the return var in case all conditionals fail
$sessionId = '';
$allowGet = (bool) SugarConfig::getInstance()->get('allow_oauth_via_get', false);
if ( isset($_SERVER['HTTP_OAUTH_TOKEN']) ) {
// Passing a session id claiming to be an oauth token
$sessionId = $_SERVER['HTTP_OAUTH_TOKEN'];
} elseif ( isset($_POST['oauth_token']) ) {
$sessionId = $_POST['oauth_token'];
} elseif ($allowGet && !empty($_GET['oauth_token'])) {
$sessionId = $_GET['oauth_token'];
} elseif ( isset($_POST['OAuth-Token']) ) {
$sessionId = $_POST['OAuth-Token'];
} elseif ($allowGet && !empty($_GET['OAuth-Token'])) {
$sessionId = $_GET['OAuth-Token'];
} elseif ( function_exists('apache_request_headers') ) {
// Some PHP implementations don't populate custom headers by default
// So we have to go for a hunt
$headers = apache_request_headers();
foreach ($headers as $key => $value) {
// Check for oAuth 2.0 header
if ($token = $this->getOAuth2AccessToken($key, $value)) {
$sessionId = $token;
break;
}
$check = strtolower($key);
if ( $check == 'oauth_token' || $check == 'oauth-token') {
$sessionId = $value;
break;
}
}
}
return $sessionId;
}