From 0655faf2c7c72a6bd5b15ae3a125730cad8d7da5 Mon Sep 17 00:00:00 2001 From: Fabiana Romagnoli Date: Mon, 1 Feb 2021 13:08:02 +0100 Subject: [PATCH] WIP - Refresh Akeneo oauth token when it is expired --- src/ApiClient.php | 83 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 62 insertions(+), 21 deletions(-) diff --git a/src/ApiClient.php b/src/ApiClient.php index f1f3896c..a8dd0e9b 100644 --- a/src/ApiClient.php +++ b/src/ApiClient.php @@ -14,7 +14,10 @@ final class ApiClient implements ApiClientInterface, AttributeOptionsApiClientInterface { /** @var string */ - private $token; + private $accessToken; + + /** @var string */ + private $refreshToken; /** @var ClientInterface */ private $httpClient; @@ -74,7 +77,7 @@ public function authenticatedRequest(string $uri, string $method, array $headers $uri = $this->baseUrl . $uri; } - if (!(bool) $this->token) { + if (!(bool) $this->accessToken) { $this->login(); } @@ -82,13 +85,22 @@ public function authenticatedRequest(string $uri, string $method, array $headers $headers, [ 'Content-Type' => 'application/json', - 'Authorization' => sprintf('Bearer %s', $this->token), + 'Authorization' => sprintf('Bearer %s', $this->accessToken), ] ); $request = new Request($method, $uri, $headers); $response = $this->httpClient->send($request); $statusClass = (int) ($response->getStatusCode() / 100); $responseResult = json_decode($response->getBody()->getContents(), true); + + $accessTokenHasExpired = $response->getStatusCode() === 401 + && (string) $responseResult['message'] === 'The access token provided has expired.'; + if ($accessTokenHasExpired) { + $this->refreshAccessToken(); + + return $this->authenticatedRequest($uri, $method, $headers); + } + if ($statusClass !== 2) { throw new \HttpException($responseResult['message'], $responseResult['code']); } @@ -132,7 +144,7 @@ public function findAttribute(string $code): ?array public function downloadFile(string $code): \SplFileInfo { $endpoint = sprintf('/api/rest/v1/media-files/%s/download', $code); - $headers = ['Authorization' => sprintf('Bearer %s', $this->token)]; + $headers = ['Authorization' => sprintf('Bearer %s', $this->accessToken)]; $request = new Request('GET', $this->baseUrl . $endpoint, $headers); $response = $this->httpClient->send($request); $statusClass = (int) ($response->getStatusCode() / 100); @@ -202,25 +214,25 @@ private function login(): void ] ); Assert::string($body); - $headers = [ - 'Content-Type' => 'application/json', - ]; - $request = new Request( - 'POST', - $this->baseUrl . '/api/oauth/v1/token', - $headers, - $body + $responseResult = $this->makeOauthRequest($body); + + $this->accessToken = $responseResult['access_token']; + $this->refreshToken = $responseResult['refresh_token']; + } + + private function refreshAccessToken(): void + { + $body = json_encode( + [ + 'grant_type' => 'refresh_token', + 'refresh_token' => $this->refreshToken, + ] ); - $options = [ - 'auth' => [ - $this->clientId, - $this->secret, - ], - ]; - $rawResponse = $this->httpClient->send($request, $options); - $responseResult = json_decode($rawResponse->getBody()->getContents(), true); + Assert::string($body); + $responseResult = $this->makeOauthRequest($body); - $this->token = $responseResult['access_token']; + $this->accessToken = $responseResult['access_token']; + $this->refreshToken = $responseResult['refresh_token']; } /** @@ -268,4 +280,33 @@ private function generateTempFilePath(): string return $this->temporaryFilesManager->generateTemporaryFilePath(); } + + /** + * @param bool $body + * + * @return mixed + * + * @throws GuzzleException + */ + private function makeOauthRequest(string $body) + { + $headers = [ + 'Content-Type' => 'application/json', + ]; + $request = new Request( + 'POST', + $this->baseUrl . '/api/oauth/v1/token', + $headers, + $body + ); + $options = [ + 'auth' => [ + $this->clientId, + $this->secret, + ], + ]; + $rawResponse = $this->httpClient->send($request, $options); + + return json_decode($rawResponse->getBody()->getContents(), true); + } }