From 7d2bec622b9c67a2d1902eefeae985ba14c8b565 Mon Sep 17 00:00:00 2001 From: Anubhav Chaturvedi Date: Tue, 31 Oct 2017 12:51:27 +0530 Subject: [PATCH 1/2] Added feature to create third party access tokens --- lib/PayPal/Auth/OAuthTokenCredential.php | 26 ++++++++++++++++++- .../Test/Auth/OAuthTokenCredentialTest.php | 21 +++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/lib/PayPal/Auth/OAuthTokenCredential.php b/lib/PayPal/Auth/OAuthTokenCredential.php index d142aa0c..3ea29320 100644 --- a/lib/PayPal/Auth/OAuthTokenCredential.php +++ b/lib/PayPal/Auth/OAuthTokenCredential.php @@ -75,17 +75,26 @@ class OAuthTokenCredential extends PayPalResourceModel */ private $cipher; + /** + * The encryted account number of the merchant on whose behalf the transaction is being done + * + * @var Subject + */ + private $subject; + /** * Construct * * @param string $clientId client id obtained from the developer portal * @param string $clientSecret client secret obtained from the developer portal + * @param null|string $subject subject used to create Third Party Token */ - public function __construct($clientId, $clientSecret) + public function __construct($clientId, $clientSecret, $subject = null) { $this->clientId = $clientId; $this->clientSecret = $clientSecret; $this->cipher = new Cipher($this->clientSecret); + $this->subject = $subject; } /** @@ -108,6 +117,16 @@ public function getClientSecret() return $this->clientSecret; } + /** + * Get the subject used to create Third Party Access Token + * + * @return string + */ + public function getSubject() + { + return $this->subject; + } + /** * Get AccessToken * @@ -267,6 +286,11 @@ private function generateAccessToken($config, $refreshToken = null) $params['grant_type'] = 'refresh_token'; $params['refresh_token'] = $refreshToken; } + + if ($this->subject != null && $refreshToken != null) { + $params['target_subject'] = $this->subject; + } + $payload = http_build_query($params); $response = $this->getToken($config, $this->clientId, $this->clientSecret, $payload); diff --git a/tests/PayPal/Test/Auth/OAuthTokenCredentialTest.php b/tests/PayPal/Test/Auth/OAuthTokenCredentialTest.php index 9317228a..ee0b0f88 100644 --- a/tests/PayPal/Test/Auth/OAuthTokenCredentialTest.php +++ b/tests/PayPal/Test/Auth/OAuthTokenCredentialTest.php @@ -60,6 +60,27 @@ public function testGetAccessTokenUnit() $this->assertNotNull($result); } + public function testGetAccessTokenWithSubjectUnit() + { + $config = array( + 'mode' => 'sandbox', + 'cache.enabled' => true, + 'cache.FileName' => AuthorizationCacheTest::CACHE_FILE + ); + $cred = new OAuthTokenCredential('clientId', 'clientSecret', 'subject'); + + //{"clientId":{"clientId":"clientId","accessToken":"accessToken","tokenCreateTime":1421204091,"tokenExpiresIn":288000000}} + AuthorizationCache::push($config, 'clientId', $cred->encrypt('accessTokenWithSubject'), 1421204091, 288000000); + + $apiContext = new ApiContext($cred); + $apiContext->setConfig($config); + $this->assertEquals('clientId', $cred->getClientId()); + $this->assertEquals('clientSecret', $cred->getClientSecret()); + $this->assertEquals('subject', $cred->getSubject()); + $result = $cred->getAccessToken($config); + $this->assertNotNull($result); + } + public function testGetAccessTokenUnitMock() { $config = array( From 31f600115974a4a40bcaf307d07f079184c47ebd Mon Sep 17 00:00:00 2001 From: Anubhav Chaturvedi Date: Mon, 13 Nov 2017 16:43:35 +0530 Subject: [PATCH 2/2] fixed caching issue --- lib/PayPal/Auth/OAuthTokenCredential.php | 13 +++++++------ lib/PayPal/Cache/AuthorizationCache.php | 12 +++++++----- .../Test/Auth/OAuthTokenCredentialTest.php | 16 +++++++++++++--- 3 files changed, 27 insertions(+), 14 deletions(-) diff --git a/lib/PayPal/Auth/OAuthTokenCredential.php b/lib/PayPal/Auth/OAuthTokenCredential.php index 3ea29320..43f0c438 100644 --- a/lib/PayPal/Auth/OAuthTokenCredential.php +++ b/lib/PayPal/Auth/OAuthTokenCredential.php @@ -38,7 +38,7 @@ class OAuthTokenCredential extends PayPalResourceModel * * @var string $clientId */ - private $clientId; + private $clientId; /** * Client secret as obtained from the developer portal @@ -76,7 +76,7 @@ class OAuthTokenCredential extends PayPalResourceModel private $cipher; /** - * The encryted account number of the merchant on whose behalf the transaction is being done + * The encrypted account number of the merchant on whose behalf the transaction is being done * * @var Subject */ @@ -140,8 +140,9 @@ public function getAccessToken($config) if ($this->accessToken && (time() - $this->tokenCreateTime) < ($this->tokenExpiresIn - self::$expiryBufferTime)) { return $this->accessToken; } + // Check for persisted data first - $token = AuthorizationCache::pull($config, $this->clientId); + $token = AuthorizationCache::pull($config, $this->clientId, $this->subject); if ($token) { // We found it // This code block is for backward compatibility only. @@ -154,7 +155,7 @@ public function getAccessToken($config) // Case where we have an old unencrypted cache file if (!array_key_exists('accessTokenEncrypted', $token)) { - AuthorizationCache::push($config, $this->clientId, $this->encrypt($this->accessToken), $this->tokenCreateTime, $this->tokenExpiresIn); + AuthorizationCache::push($config, $this->clientId, $this->encrypt($this->accessToken), $this->tokenCreateTime, $this->tokenExpiresIn, $this->subject); } else { $this->accessToken = $this->decrypt($token['accessTokenEncrypted']); } @@ -177,7 +178,7 @@ public function getAccessToken($config) if ($this->accessToken == null) { // Get a new one by making calls to API $this->updateAccessToken($config); - AuthorizationCache::push($config, $this->clientId, $this->encrypt($this->accessToken), $this->tokenCreateTime, $this->tokenExpiresIn); + AuthorizationCache::push($config, $this->clientId, $this->encrypt($this->accessToken), $this->tokenCreateTime, $this->tokenExpiresIn, $this->subject); } return $this->accessToken; @@ -287,7 +288,7 @@ private function generateAccessToken($config, $refreshToken = null) $params['refresh_token'] = $refreshToken; } - if ($this->subject != null && $refreshToken != null) { + if ($this->subject != null && $refreshToken == null) { $params['target_subject'] = $this->subject; } diff --git a/lib/PayPal/Cache/AuthorizationCache.php b/lib/PayPal/Cache/AuthorizationCache.php index 83910d3b..eea3facd 100644 --- a/lib/PayPal/Cache/AuthorizationCache.php +++ b/lib/PayPal/Cache/AuthorizationCache.php @@ -17,7 +17,7 @@ abstract class AuthorizationCache * @param string $clientId * @return mixed|null */ - public static function pull($config = null, $clientId = null) + public static function pull($config = null, $clientId = null, $subject = null) { // Return if not enabled if (!self::isEnabled($config)) { @@ -26,14 +26,15 @@ public static function pull($config = null, $clientId = null) $tokens = null; $cachePath = self::cachePath($config); + $cacheKey = $subject == null ? $clientId : $clientId . "." . $subject; if (file_exists($cachePath)) { // Read from the file $cachedToken = file_get_contents($cachePath); if ($cachedToken && JsonValidator::validate($cachedToken, true)) { $tokens = json_decode($cachedToken, true); - if ($clientId && is_array($tokens) && array_key_exists($clientId, $tokens)) { + if ($cacheKey && is_array($tokens) && array_key_exists($cacheKey, $tokens)) { // If client Id is found, just send in that data only - return $tokens[$clientId]; + return $tokens[$cacheKey]; } elseif ($clientId) { // If client Id is provided, but no key in persisted data found matching it. return null; @@ -53,7 +54,7 @@ public static function pull($config = null, $clientId = null) * @param $tokenExpiresIn * @throws \Exception */ - public static function push($config = null, $clientId, $accessToken, $tokenCreateTime, $tokenExpiresIn) + public static function push($config = null, $clientId, $accessToken, $tokenCreateTime, $tokenExpiresIn, $subject=null) { // Return if not enabled if (!self::isEnabled($config)) { @@ -70,8 +71,9 @@ public static function push($config = null, $clientId, $accessToken, $tokenCreat // Reads all the existing persisted data $tokens = self::pull(); $tokens = $tokens ? $tokens : array(); + $cacheKey = $subject == null ? $clientId : $clientId . "." . $subject; if (is_array($tokens)) { - $tokens[$clientId] = array( + $tokens[$cacheKey] = array( 'clientId' => $clientId, 'accessTokenEncrypted' => $accessToken, 'tokenCreateTime' => $tokenCreateTime, diff --git a/tests/PayPal/Test/Auth/OAuthTokenCredentialTest.php b/tests/PayPal/Test/Auth/OAuthTokenCredentialTest.php index ee0b0f88..e6b53ad3 100644 --- a/tests/PayPal/Test/Auth/OAuthTokenCredentialTest.php +++ b/tests/PayPal/Test/Auth/OAuthTokenCredentialTest.php @@ -70,15 +70,25 @@ public function testGetAccessTokenWithSubjectUnit() $cred = new OAuthTokenCredential('clientId', 'clientSecret', 'subject'); //{"clientId":{"clientId":"clientId","accessToken":"accessToken","tokenCreateTime":1421204091,"tokenExpiresIn":288000000}} - AuthorizationCache::push($config, 'clientId', $cred->encrypt('accessTokenWithSubject'), 1421204091, 288000000); + AuthorizationCache::push($config, 'clientId', $cred->encrypt('accessTokenWithSubject'), 1421204091, 288000000, 'subject'); + AuthorizationCache::push($config, 'clientId', $cred->encrypt('accessToken1'), 1421204091, 288000000); $apiContext = new ApiContext($cred); $apiContext->setConfig($config); $this->assertEquals('clientId', $cred->getClientId()); $this->assertEquals('clientSecret', $cred->getClientSecret()); $this->assertEquals('subject', $cred->getSubject()); - $result = $cred->getAccessToken($config); - $this->assertNotNull($result); + $result = $cred->getAccessToken($config); + $this->assertEquals('accessTokenWithSubject', $result); + + $cred = new OAuthTokenCredential('clientId', 'clientSecret'); + $apiContext = new ApiContext($cred); + $apiContext->setConfig($config); + $this->assertEquals('clientId', $cred->getClientId()); + $this->assertEquals('clientSecret', $cred->getClientSecret()); + $this->assertNull($cred->getSubject()); + $result = $cred->getAccessToken($config); + $this->assertEquals('accessToken1', $result); } public function testGetAccessTokenUnitMock()