220 lines
6.4 KiB
PHP
Executable File
220 lines
6.4 KiB
PHP
Executable File
<?php
|
|
namespace JR\NetSuite\Lib\Restful;
|
|
|
|
use JR\NetSuite\Logger\Logger;
|
|
use Magento\Framework\App\Config\ScopeConfigInterface;
|
|
use Magento\Framework\App\ObjectManager;
|
|
use Magento\Framework\Exception\InvalidArgumentException;
|
|
use Magento\Store\Model\ScopeInterface;
|
|
use Magento\Store\Model\StoreManagerInterface;
|
|
|
|
class Oauth
|
|
{
|
|
const SIGNATURE_METHOD_HMACSHA256 = 'HMAC-SHA256';
|
|
const OAUTH_VERSION = '1.0';
|
|
const NONCE_STRING = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
|
const XML_PATH_RESTFUL_ENDPOINT = 'jr_netsuite/restful/service_endpoint';
|
|
const XML_PATH_ACCOUNT_ID = 'jr_netsuite/restful/account_id';
|
|
const XML_PATH_OAUTH_CONSUMER_KEY = 'jr_netsuite/apidetail/oauth_consumer_key';
|
|
const XML_PATH_OAUTH_CONSUMER_SECRET = 'jr_netsuite/apidetail/oauth_consumer_secret';
|
|
const XML_PATH_OAUTH_TOKEN = 'jr_netsuite/apidetail/oauth_token';
|
|
const XML_PATH_OAUTH_TOKEN_SECRET = 'jr_netsuite/apidetail/oauth_token_secret';
|
|
|
|
/**
|
|
* @var StoreManagerInterface
|
|
*/
|
|
protected $storeManager;
|
|
|
|
/**
|
|
* @var ScopeConfigInterface
|
|
*/
|
|
protected $scopeConfig;
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
protected $script;
|
|
|
|
private Logger $logger;
|
|
|
|
/**
|
|
* @param StoreManagerInterface $storeManager
|
|
* @param ScopeConfigInterface $scopeConfig
|
|
**/
|
|
|
|
public function __construct(
|
|
StoreManagerInterface $storeManager,
|
|
ScopeConfigInterface $scopeConfig,
|
|
Logger $logger
|
|
) {
|
|
$this->scopeConfig = $scopeConfig;
|
|
$this->storeManager = $storeManager;
|
|
$this->logger = $logger;
|
|
}
|
|
|
|
/**
|
|
* consumer key
|
|
* @return string
|
|
*/
|
|
public function getConsumerKey()
|
|
{
|
|
return $this->getConfigValue(self::XML_PATH_OAUTH_CONSUMER_KEY);
|
|
}
|
|
|
|
/**
|
|
* consumer Secret
|
|
* @return string
|
|
*/
|
|
public function getConsumerSecret()
|
|
{
|
|
return $this->getConfigValue(self::XML_PATH_OAUTH_CONSUMER_SECRET);
|
|
}
|
|
|
|
/**
|
|
* Token access key
|
|
* @return string
|
|
*/
|
|
public function getToken()
|
|
{
|
|
return $this->getConfigValue(self::XML_PATH_OAUTH_TOKEN);
|
|
}
|
|
|
|
/**
|
|
* Token Secret
|
|
* @return string
|
|
*/
|
|
public function getTokenSecret()
|
|
{
|
|
return $this->getConfigValue(self::XML_PATH_OAUTH_TOKEN_SECRET);
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function getAccountId(): string
|
|
{
|
|
return $this->getConfigValue(self::XML_PATH_ACCOUNT_ID);
|
|
}
|
|
|
|
/**
|
|
* @param string $service
|
|
* @return string
|
|
*/
|
|
public function getEndpoint(string $service = ''): string
|
|
{
|
|
$endpoint = $this->getConfigValue(self::XML_PATH_RESTFUL_ENDPOINT);
|
|
if ($service) {
|
|
$endpoint = $endpoint .'/'.ltrim($service, '/');
|
|
}
|
|
return $endpoint;
|
|
}
|
|
|
|
/**
|
|
* @param string $service, for example, if you want to sync customer to netsuite, this param is record/v1/customer
|
|
* @param string $method
|
|
* @return string
|
|
* @throws InvalidArgumentException
|
|
*/
|
|
public function getOauthParams(string $service, string $method = 'POST')
|
|
{
|
|
if (!$service) {
|
|
throw new InvalidArgumentException(__('Parameter service name is required.'));
|
|
}
|
|
$time = time();
|
|
$nonce = rawurlencode($this->generateNonceString(11));
|
|
$oauthparams = $this->getParamObject($nonce, $time);
|
|
|
|
$baseString = $this->createBaseString($service, $method, $oauthparams );
|
|
|
|
$signature = $this->getSignature('sha256', $baseString);
|
|
|
|
return $this->buildAuthorizationHeader($nonce, $time, $signature);
|
|
}
|
|
|
|
/**
|
|
* Calculate signature for request
|
|
* @return string
|
|
*/
|
|
public function getSignature($algo, $baseString)
|
|
{
|
|
$key = rawurlencode($this->getConsumerSecret()) . '&' . rawurlencode($this->getTokenSecret());
|
|
return rawurlencode(base64_encode(hash_hmac($algo, $baseString, $key, true)));
|
|
}
|
|
|
|
/**
|
|
* Builds the Authorization header for a request
|
|
* @return string
|
|
*/
|
|
private function buildAuthorizationHeader($nonce, $time, $signature)
|
|
{
|
|
return 'OAuth realm="' . $this->getAccountId() . '",oauth_consumer_key="' . $this->getConsumerKey() .
|
|
'",oauth_token="' . $this->getToken() . '",oauth_signature_method="'.self::SIGNATURE_METHOD_HMACSHA256.
|
|
'",oauth_timestamp="' . $time . '",oauth_nonce="' . $nonce . '",oauth_version="1.0",oauth_signature="'
|
|
. $signature . '"';
|
|
}
|
|
|
|
/**
|
|
* Creates the Signature Base String.
|
|
* The Signature Base String is a consistent reproducible concatenation of
|
|
* the request elements into a single string. The string is used as an
|
|
* input in hashing or signing algorithms.
|
|
* @param string $service
|
|
* @param string $method
|
|
* @param array $params
|
|
* @return string
|
|
*/
|
|
private function createBaseString(string $service, string $method, array $params = [])
|
|
{
|
|
$url = $this->getEndpoint().'/'.$service;
|
|
$rawString = strtoupper($method). '&' . rawurlencode($url);
|
|
if ($params) {
|
|
$rawString .= '&';
|
|
ksort($params);
|
|
$rawString .= rawurlencode(http_build_query($params, '', '&', PHP_QUERY_RFC3986));
|
|
}
|
|
|
|
return $rawString;
|
|
}
|
|
/**
|
|
* generating nonce value
|
|
* @return string
|
|
*/
|
|
public function generateNonceString($length = 11)
|
|
{
|
|
$characters = self::NONCE_STRING;
|
|
$charactersLength = strlen($characters);
|
|
$randomString = '';
|
|
for ($i = 0; $i < $length; $i++) {
|
|
$randomString .= $characters[rand(0, $charactersLength - 1)];
|
|
}
|
|
return $randomString;
|
|
}
|
|
|
|
/**
|
|
* generate param value
|
|
* @param $nonce
|
|
* @param $time
|
|
* @return array
|
|
*/
|
|
public function getParamObject(string $nonce, string $time)
|
|
{
|
|
return [
|
|
"oauth_consumer_key" => $this->getConsumerKey(),
|
|
"oauth_nonce" => $nonce,
|
|
"oauth_signature_method" => self::SIGNATURE_METHOD_HMACSHA256,
|
|
"oauth_timestamp" => $time,
|
|
"oauth_token" => $this->getToken(),
|
|
"oauth_version" => self::OAUTH_VERSION,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* get config value
|
|
* @return string
|
|
*/
|
|
public function getConfigValue($path)
|
|
{
|
|
$store = $this->storeManager->getStore()->getStoreId();
|
|
return $this->scopeConfig->getValue($path, ScopeInterface::SCOPE_STORE, $store);
|
|
}
|
|
} |