From 467d77a217e8e7ba2b33336f3cbab349218e709a Mon Sep 17 00:00:00 2001 From: Aaron Leitner Date: Fri, 2 Jul 2021 12:39:41 -0400 Subject: [PATCH 1/8] getreWWTH-5837 update access/refresh token URL and overwrite AbstractProvider::prepareAccessTokenResponse() to handle new response format --- src/Provider/Withings.php | 40 +++++++++++++++++++++++++++++- test/src/Provider/WithingsTest.php | 6 ++--- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/src/Provider/Withings.php b/src/Provider/Withings.php index 0548607..3f08cec 100644 --- a/src/Provider/Withings.php +++ b/src/Provider/Withings.php @@ -65,7 +65,7 @@ public function getBaseAuthorizationUrl() */ public function getBaseAccessTokenUrl(array $params) { - return static::BASE_WITHINGS_URL.'/oauth2/token'; + return static::BASE_WITHINGS_API_URL.'/v2/oauth2'; } /** @@ -113,6 +113,44 @@ protected function checkResponse(ResponseInterface $response, $data) } } + /** + * Prepares an parsed access token response for a grant. + * + * Custom mapping of expiration, etc should be done here. Always call the + * parent method when overloading this method. + * + * @param mixed $result + * @return array + */ + protected function prepareAccessTokenResponse(array $result) + { + if (!array_key_exists('status', $result)) { + throw new IdentityProviderException( + 'Invalid response received from Authorization Server. Missing status.', + 0, + null + ); + } + + if ($result['status'] !== 0) { + throw new IdentityProviderException( + sprintf('Invalid response received from Authorization Server. Status code %d.', $result['status']), + 0, + null + ); + } + + if (!array_key_exists('body', $result)) { + throw new IdentityProviderException( + 'Invalid response received from Authorization Server. Missing body.', + 0, + null + ); + } + + return parent::getAuthorizationParameters($result['body']); + } + /** * Returns authorization parameters based on provided options. * Withings does not use the 'approval_prompt' param and here we remove it. diff --git a/test/src/Provider/WithingsTest.php b/test/src/Provider/WithingsTest.php index 5e1ce3c..b9d45ac 100644 --- a/test/src/Provider/WithingsTest.php +++ b/test/src/Provider/WithingsTest.php @@ -77,7 +77,7 @@ public function testGetBaseAccessTokenUrl() $params = []; $url = $this->provider->getBaseAccessTokenUrl($params); $uri = parse_url($url); - $this->assertEquals('/oauth2/token', $uri['path']); + $this->assertEquals('/v2/oauth2', $uri['path']); } public function testGetResourceOwnerDetailsUrl() @@ -91,7 +91,7 @@ public function testGetResourceOwnerDetailsUrl() public function testGetAccessToken() { $response = Mockery::mock('Psr\Http\Message\ResponseInterface'); - $response->shouldReceive('getBody')->andReturn('{"access_token":"mock_access_token", "token_type":"Bearer", "scope": "identify"}'); + $response->shouldReceive('getBody')->andReturn('{"status":0, "body":{"access_token":"mock_access_token", "token_type":"Bearer", "scope":"identify", "refresh_token":"mock_refresh_token", "user_id":"mock_user_id"}}'); $response->shouldReceive('getHeader')->andReturn(['content-type' => 'json']); $response->shouldReceive('getStatusCode')->andReturn(200); $client = Mockery::mock('GuzzleHttp\ClientInterface'); @@ -99,8 +99,8 @@ public function testGetAccessToken() $this->provider->setHttpClient($client); $token = $this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']); $this->assertEquals('mock_access_token', $token->getToken()); + $this->assertEquals('mock_refresh_token', $token->getRefreshToken()); $this->assertNull($token->getExpires()); - $this->assertNull($token->getRefreshToken()); $this->assertNull($token->getResourceOwnerId()); } From a78897d44e8558622ce8f939aef585f0fdbaef21 Mon Sep 17 00:00:00 2001 From: Aaron Leitner Date: Fri, 2 Jul 2021 12:46:47 -0400 Subject: [PATCH 2/8] WTH-5837 include response when throwing IdentityProviderException --- src/Provider/Withings.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Provider/Withings.php b/src/Provider/Withings.php index 3f08cec..4aeb979 100644 --- a/src/Provider/Withings.php +++ b/src/Provider/Withings.php @@ -128,7 +128,7 @@ protected function prepareAccessTokenResponse(array $result) throw new IdentityProviderException( 'Invalid response received from Authorization Server. Missing status.', 0, - null + $result ); } @@ -136,7 +136,7 @@ protected function prepareAccessTokenResponse(array $result) throw new IdentityProviderException( sprintf('Invalid response received from Authorization Server. Status code %d.', $result['status']), 0, - null + $result ); } @@ -144,7 +144,7 @@ protected function prepareAccessTokenResponse(array $result) throw new IdentityProviderException( 'Invalid response received from Authorization Server. Missing body.', 0, - null + $result ); } From 36d7a20e117eb6d42dcb88528832d2e252745c4d Mon Sep 17 00:00:00 2001 From: Aaron Leitner Date: Fri, 2 Jul 2021 12:49:04 -0400 Subject: [PATCH 3/8] WTH-5837 update doc to reflect that $result should be an array --- src/Provider/Withings.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Provider/Withings.php b/src/Provider/Withings.php index 4aeb979..811ed25 100644 --- a/src/Provider/Withings.php +++ b/src/Provider/Withings.php @@ -119,7 +119,7 @@ protected function checkResponse(ResponseInterface $response, $data) * Custom mapping of expiration, etc should be done here. Always call the * parent method when overloading this method. * - * @param mixed $result + * @param array $result * @return array */ protected function prepareAccessTokenResponse(array $result) From 0d494e4a72dcc0ffee9553985c571738729f627c Mon Sep 17 00:00:00 2001 From: Aaron Leitner Date: Mon, 19 Jul 2021 13:00:41 -0400 Subject: [PATCH 4/8] WTH-5837 add action to access token request params --- src/Provider/Withings.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/Provider/Withings.php b/src/Provider/Withings.php index 811ed25..68a1b8c 100644 --- a/src/Provider/Withings.php +++ b/src/Provider/Withings.php @@ -68,6 +68,22 @@ public function getBaseAccessTokenUrl(array $params) return static::BASE_WITHINGS_API_URL.'/v2/oauth2'; } + /** + * Builds the access token URL's query string. + * + * @param array $params Query parameters + * @return string Query string + */ + protected function getAccessTokenQuery(array $params) + { + // withings requires the action to be 'requesttoken' when getting an access token + if (empty($params['action'])) { + $params['action'] = 'requesttoken'; + } + + return parent::getAccessTokenQuery($params); + } + /** * Returns the url to retrieve the resource owners's profile/details. * From 67fe63cea8211e72b0410ed931a6536c8e704a0b Mon Sep 17 00:00:00 2001 From: Aaron Leitner Date: Mon, 19 Jul 2021 13:13:27 -0400 Subject: [PATCH 5/8] WTH-5837 call correct parent method --- src/Provider/Withings.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Provider/Withings.php b/src/Provider/Withings.php index 68a1b8c..426e427 100644 --- a/src/Provider/Withings.php +++ b/src/Provider/Withings.php @@ -164,7 +164,7 @@ protected function prepareAccessTokenResponse(array $result) ); } - return parent::getAuthorizationParameters($result['body']); + return parent::prepareAccessTokenResponse($result['body']); } /** From 03ee8ab7d12f8dd634030670cac27170b976e945 Mon Sep 17 00:00:00 2001 From: Aaron Leitner Date: Mon, 19 Jul 2021 13:56:37 -0400 Subject: [PATCH 6/8] WTH-5837 had better luck overriding this function --- src/Provider/Withings.php | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/Provider/Withings.php b/src/Provider/Withings.php index 426e427..95dba6b 100644 --- a/src/Provider/Withings.php +++ b/src/Provider/Withings.php @@ -69,19 +69,21 @@ public function getBaseAccessTokenUrl(array $params) } /** - * Builds the access token URL's query string. + * Requests an access token using a specified grant and option set. * - * @param array $params Query parameters - * @return string Query string + * @param mixed $grant + * @param array $options + * @throws IdentityProviderException + * @return AccessTokenInterface */ - protected function getAccessTokenQuery(array $params) + public function getAccessToken($grant, array $options = []) { // withings requires the action to be 'requesttoken' when getting an access token - if (empty($params['action'])) { - $params['action'] = 'requesttoken'; + if (empty($options['action'])) { + $options['action'] = 'requesttoken'; } - return parent::getAccessTokenQuery($params); + return parent::getAccessToken($options); } /** From f192c47a28e06057afb349ef698c6e3bfb6e74c9 Mon Sep 17 00:00:00 2001 From: Aaron Leitner Date: Mon, 19 Jul 2021 14:01:17 -0400 Subject: [PATCH 7/8] WTH-5837 add missing param --- src/Provider/Withings.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Provider/Withings.php b/src/Provider/Withings.php index 95dba6b..27b44a0 100644 --- a/src/Provider/Withings.php +++ b/src/Provider/Withings.php @@ -83,7 +83,7 @@ public function getAccessToken($grant, array $options = []) $options['action'] = 'requesttoken'; } - return parent::getAccessToken($options); + return parent::getAccessToken($grant, $options); } /** From b4b90998eb75ee2e975111b53fd4bd8ab589d427 Mon Sep 17 00:00:00 2001 From: Aaron Leitner Date: Mon, 19 Jul 2021 14:05:22 -0400 Subject: [PATCH 8/8] WTH-5837 resolve picky error --- src/Provider/Withings.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Provider/Withings.php b/src/Provider/Withings.php index 27b44a0..bc36bbb 100644 --- a/src/Provider/Withings.php +++ b/src/Provider/Withings.php @@ -6,6 +6,7 @@ use League\OAuth2\Client\Provider\GenericResourceOwner; use League\OAuth2\Client\Provider\Exception\IdentityProviderException; use League\OAuth2\Client\Token\AccessToken; +use League\OAuth2\Client\Token\AccessTokenInterface; use League\OAuth2\Client\Tool\BearerAuthorizationTrait; use Psr\Http\Message\ResponseInterface;