Как установить переменные в конечной точке при вызове REST - PullRequest
0 голосов
/ 12 февраля 2019

Я пытаюсь создать пользовательский 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;
    }
...