Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade Guzzle and Platform.sh client library #1507

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
"require": {
"php": ">=8.2",
"doctrine/cache": "~1.5",
"guzzlehttp/guzzle": "^5.3",
"guzzlehttp/guzzle": "^7",
"guzzlehttp/ringphp": "^1.1",
"platformsh/console-form": ">=0.0.37 <2.0",
"platformsh/client": ">=0.87.0 <2.0",
"platformsh/client": "^3@beta",
"symfony/console": "^3.0 >=3.2",
"symfony/yaml": "^3.0 || ^2.6",
"symfony/finder": "^3.0",
Expand All @@ -26,7 +26,8 @@
"giggsey/libphonenumber-for-php": "^8.13",
"symfony/polyfill-mbstring": "^1.19",
"symfony/polyfill-iconv": "^1.19",
"padraic/humbug_get_contents": "dev-allow-php-8 as 1.1.3"
"padraic/humbug_get_contents": "dev-allow-php-8 as 1.1.3",
"platformsh/oauth2": "^1@beta"
},
"repositories": [
{
Expand Down
6 changes: 4 additions & 2 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 7 additions & 8 deletions src/Command/Auth/ApiTokenLoginCommand.php
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
<?php
namespace Platformsh\Cli\Command\Auth;

use CommerceGuys\Guzzle\Oauth2\AccessToken;
use GuzzleHttp\Exception\BadResponseException;
use GuzzleHttp\Utils;
use League\OAuth2\Client\Token\AccessToken;
use Platformsh\Cli\Command\CommandBase;
use Platformsh\Client\OAuth2\ApiToken;
use Platformsh\OAuth2\Client\Grant\ApiToken;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\Question;
Expand Down Expand Up @@ -59,12 +60,10 @@ protected function execute(InputInterface $input, OutputInterface $output)
}

try {
$token = (new ApiToken($tokenClient, [
'client_id' => $clientId,
'token_url' => $tokenUrl,
'auth_location' => 'headers',
$provider = $this->api()->getClient()->getConnector()->getOAuth2Provider();
$token = $provider->getAccessToken(new ApiToken(), [
'api_token' => $apiToken,
]))->getToken();
]);
} catch (BadResponseException $e) {
if ($this->exceptionMeansInvalidToken($e)) {
throw new \RuntimeException('Invalid API token');
Expand Down Expand Up @@ -121,7 +120,7 @@ private function exceptionMeansInvalidToken(\Exception $e) {
if (!$e instanceof BadResponseException || !$e->getResponse() || !in_array($e->getResponse()->getStatusCode(), [400, 401], true)) {
return false;
}
$json = $e->getResponse()->json();
$json = Utils::jsonDecode($e->getResponse(), true);
// Compatibility with legacy auth provider.
if (isset($json['error'], $json['error_description'])
&& $json['error'] === 'invalid_grant'
Expand Down
48 changes: 22 additions & 26 deletions src/Command/Auth/BrowserLoginCommand.php
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
<?php
namespace Platformsh\Cli\Command\Auth;

use CommerceGuys\Guzzle\Oauth2\AccessToken;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\BadResponseException;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Utils;
use League\OAuth2\Client\Token\AccessToken;
use Platformsh\Cli\Command\CommandBase;
use Platformsh\Cli\Console\ArrayArgument;
use Platformsh\Cli\Service\Filesystem;
Expand Down Expand Up @@ -301,17 +303,11 @@ private function getParentEnv()
*/
private function saveAccessToken(array $tokenData, SessionInterface $session)
{
$token = new AccessToken($tokenData['access_token'], $tokenData['token_type'], $tokenData);
$session->setData([
'accessToken' => $token->getToken(),
'tokenType' => $token->getType(),
]);
if ($token->getExpires()) {
$session->set('expires', $token->getExpires()->getTimestamp());
}
if ($token->getRefreshToken()) {
$session->set('refreshToken', $token->getRefreshToken()->getToken());
}
$token = new AccessToken($tokenData);
$session->set('accessToken', $token->getToken());
$session->set('tokenType', $tokenData['token_type'] ?: null);
$session->set('expires', $token->getExpires());
$session->set('refreshToken', $token->getRefreshToken());
$session->save();
}

Expand Down Expand Up @@ -342,23 +338,23 @@ private function createDocumentRoot($dir)
*/
private function getAccessToken($authCode, $codeVerifier, $redirectUri)
{
$client = new Client();
$request = $client->createRequest('post', $this->config()->get('api.oauth2_token_url'), [
'body' => [
'grant_type' => 'authorization_code',
'code' => $authCode,
'client_id' => $this->config()->get('api.oauth2_client_id'),
'redirect_uri' => $redirectUri,
'code_verifier' => $codeVerifier,
],
'auth' => false,
'verify' => !$this->config()->getWithDefault('api.skip_ssl', false),
]);
$client = new Client(['verify' => !$this->config()->getWithDefault('api.skip_ssl', false)]);
$request = new Request('POST', $this->config()->get('api.oauth2_token_url'), body: http_build_query([
'grant_type' => 'authorization_code',
'code' => $authCode,
'redirect_uri' => $redirectUri,
'code_verifier' => $codeVerifier,
]));

try {
$response = $client->send($request);
$response = $client->send($request, [
'headers' => [
'Content-Type' => 'application/x-www-form-urlencoded',
],
'auth' => [$this->config()->get('api.oauth2_client_id'), ''],
]);

return $response->json();
return Utils::jsonDecode((string) $response->getBody(), true);
} catch (BadResponseException $e) {
throw ApiResponseException::create($request, $e->getResponse(), $e);
}
Expand Down
11 changes: 7 additions & 4 deletions src/Command/Auth/VerifyPhoneNumberCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
namespace Platformsh\Cli\Command\Auth;

use GuzzleHttp\Exception\BadResponseException;
use GuzzleHttp\Utils;
use libphonenumber\NumberParseException;
use libphonenumber\PhoneNumberFormat;
use libphonenumber\PhoneNumberUtil;
Expand Down Expand Up @@ -67,12 +68,13 @@ protected function execute(InputInterface $input, OutputInterface $output)

$httpClient = $this->api()->getHttpClient();

$sid = $httpClient->post('/users/' . rawurlencode($myUser->id) . '/phonenumber', [
$response = $httpClient->post('/users/' . rawurlencode($myUser->id) . '/phonenumber', [
'json' => [
'channel' => $channel,
'phone_number' => $number,
],
])->json()['sid'];
]);
$sid = Utils::jsonDecode((string) $response->getBody(), true)['sid'];

if ($channel === 'call') {
$this->stdErr->writeln('Calling the number <info>' . $number . '</info> with a verification code.');
Expand All @@ -94,15 +96,16 @@ protected function execute(InputInterface $input, OutputInterface $output)
]);
} catch (BadResponseException $e) {
if (($response = $e->getResponse()) && $response->getStatusCode() === 400) {
$detail = $response->json();
$detail = Utils::jsonDecode((string) $response->getBody(), true);
throw new InvalidArgumentException(isset($detail['error']) ? ucfirst($detail['error']) : 'Invalid verification code');
}
throw $e;
}
});

$this->debug('Refreshing phone verification status');
$needsVerify = $httpClient->post( '/me/verification?force_refresh=1')->json();
$response = $httpClient->post( '/me/verification?force_refresh=1');
$needsVerify = Utils::jsonDecode((string) $response->getBody(), true);
$this->stdErr->writeln('');

if ($needsVerify['type'] === 'phone') {
Expand Down
2 changes: 1 addition & 1 deletion src/Command/Backup/BackupListCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
/** @var \Platformsh\Cli\Service\PropertyFormatter $formatter */
$formatter = $this->getService('property_formatter');

$backups = $environment->getBackups($input->getOption('limit'));
$backups = $environment->getBackups((int) $input->getOption('limit'));
if (!$backups) {
$this->stdErr->writeln('No backups found');
return 1;
Expand Down
4 changes: 3 additions & 1 deletion src/Command/BlueGreen/BlueGreenConcludeCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Platformsh\Cli\Command\BlueGreen;

use GuzzleHttp\Utils;
use Platformsh\Cli\Command\CommandBase;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
Expand All @@ -25,7 +26,8 @@ protected function execute(InputInterface $input, OutputInterface $output)
$environment = $this->getSelectedEnvironment();

$httpClient = $this->api()->getHttpClient();
$data = $httpClient->get($environment->getLink('#versions'))->json();
$response = $httpClient->get($environment->getLink('#versions'));
$data = Utils::jsonDecode((string) $response->getBody(), true);
if (count($data) < 2) {
$this->stdErr->writeln(sprintf('Blue/green deployments are not enabled for the environment %s.', $this->api()->getEnvironmentLabel($environment, 'error')));
return 1;
Expand Down
4 changes: 3 additions & 1 deletion src/Command/BlueGreen/BlueGreenDeployCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Platformsh\Cli\Command\BlueGreen;

use GuzzleHttp\Utils;
use Platformsh\Cli\Command\CommandBase;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
Expand All @@ -27,7 +28,8 @@ protected function execute(InputInterface $input, OutputInterface $output)
$environment = $this->getSelectedEnvironment();

$httpClient = $this->api()->getHttpClient();
$data = $httpClient->get($environment->getLink('#versions'))->json();
$response = $httpClient->get($environment->getLink('#versions'));
$data = Utils::jsonDecode((string) $response->getBody(), true);
if (count($data) < 2) {
$this->stdErr->writeln(sprintf('Blue/green deployments are not enabled for the environment %s.', $this->api()->getEnvironmentLabel($environment, 'error')));
$this->stdErr->writeln(sprintf('Enable blue/green first by running: <info>%s blue-green:enable</info>', $this->config()->get('application.executable')));
Expand Down
4 changes: 3 additions & 1 deletion src/Command/BlueGreen/BlueGreenEnableCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Platformsh\Cli\Command\BlueGreen;

use GuzzleHttp\Utils;
use Platformsh\Cli\Command\CommandBase;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
Expand Down Expand Up @@ -32,7 +33,8 @@ protected function execute(InputInterface $input, OutputInterface $output)
$environment = $this->getSelectedEnvironment();

$httpClient = $this->api()->getHttpClient();
$data = $httpClient->get($environment->getLink('#versions'))->json();
$response = $httpClient->get($environment->getLink('#versions'));
$data = Utils::jsonDecode((string) $response->getBody(), true);
if (count($data) > 1) {
$this->stdErr->writeln(sprintf('Blue/green deployments are already enabled for the environment %s.', $this->api()->getEnvironmentLabel($environment)));
$this->stdErr->writeln(sprintf('List versions by running: <info>%s versions</info>', $this->config()->get('application.executable')));
Expand Down
4 changes: 2 additions & 2 deletions src/Command/CommandBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -714,8 +714,8 @@ public function getCurrentProject($suppressErrors = false)
}
if ($this->config()->has('api.base_url')
&& $e->getResponse() && $e->getResponse()->getStatusCode() === 401
&& parse_url($this->config()->get('api.base_url'), PHP_URL_HOST) !== $e->getRequest()->getHost()) {
$this->debug('Ignoring 401 error for unrecognized local project hostname: ' . $e->getRequest()->getHost());
&& parse_url($this->config()->get('api.base_url'), PHP_URL_HOST) !== $e->getRequest()->getUri()->getHost()) {
$this->debug('Ignoring 401 error for unrecognized local project hostname: ' . $e->getRequest()->getUri()->getHost());
return $this->currentProject = false;
}
throw $e;
Expand Down
5 changes: 3 additions & 2 deletions src/Command/Domain/DomainAddCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
namespace Platformsh\Cli\Command\Domain;

use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Utils;
use Platformsh\Cli\Model\EnvironmentDomain;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
Expand Down Expand Up @@ -68,7 +69,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
if ($response) {
$code = $response->getStatusCode();
if ($code === 402) {
$data = $response->json();
$data = Utils::jsonDecode((string) $response->getBody(), true);
if (isset($data['message'], $data['detail']['environments_with_domains_limit'], $data['detail']['environments_with_domains'])) {
$this->stdErr->writeln('');
$this->stdErr->writeln($data['message']);
Expand All @@ -79,7 +80,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
}
}
if ($code === 409) {
$data = $response->json();
$data = Utils::jsonDecode((string) $response->getBody(), true);
if (isset($data['message'], $data['detail']['conflicting_domain']) && strpos($data['message'], 'already has a domain with the same replacement_for') !== false) {
$this->stdErr->writeln('');
$this->stdErr->writeln(sprintf(
Expand Down
3 changes: 2 additions & 1 deletion src/Command/Domain/DomainCommandBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

use GuzzleHttp\Exception\BadResponseException;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Utils;
use Platformsh\Cli\Command\CommandBase;
use Platformsh\Cli\Util\SslUtil;
use Platformsh\Client\Model\Environment;
Expand Down Expand Up @@ -207,7 +208,7 @@ protected function handleApiException(ClientException $e, Project $project)
}
// @todo standardize API error parsing if the format is ever formalized
if ($response->getStatusCode() === 400) {
$data = $response->json();
$data = Utils::jsonDecode((string) $response->getBody(), true);
if (isset($data['detail']['error'])) {
$this->stdErr->writeln($data['detail']['error']);
return;
Expand Down
5 changes: 3 additions & 2 deletions src/Command/Integration/IntegrationCommandBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
namespace Platformsh\Cli\Command\Integration;

use GuzzleHttp\Exception\BadResponseException;
use GuzzleHttp\Utils;
use Platformsh\Cli\Command\CommandBase;
use Platformsh\Client\Model\Integration;
use Platformsh\Client\Model\Project;
Expand Down Expand Up @@ -667,7 +668,7 @@ protected function getBitbucketAccessToken(array $credentials)
if (isset($this->bitbucketAccessTokens[$credentials['key']])) {
return $this->bitbucketAccessTokens[$credentials['key']];
}
$result = $this->api()
$response = $this->api()
->getExternalHttpClient()
->post('https://bitbucket.org/site/oauth2/access_token', [
'auth' => [$credentials['key'], $credentials['secret']],
Expand All @@ -676,7 +677,7 @@ protected function getBitbucketAccessToken(array $credentials)
],
]);

$data = $result->json();
$data = Utils::jsonDecode((string) $response->getBody(), true);
if (!isset($data['access_token'])) {
throw new \RuntimeException('Access token not found in Bitbucket response');
}
Expand Down
5 changes: 4 additions & 1 deletion src/Command/Metrics/MetricsCommandBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Platformsh\Cli\Command\Metrics;

use GuzzleHttp\Exception\BadResponseException;
use GuzzleHttp\Psr7\Request;
use Khill\Duration\Duration;
use Platformsh\Cli\Command\CommandBase;
use Platformsh\Cli\Console\AdaptiveTableCell;
Expand Down Expand Up @@ -256,7 +257,9 @@ protected function fetchMetrics(InputInterface $input, TimeSpec $timeSpec, Envir

// Perform the metrics query.
$client = $this->api()->getHttpClient();
$request = $client->createRequest('POST', $metricsQueryUrl, ['json' => $query->asArray()]);
$request = new Request('POST', $metricsQueryUrl, [
'Content-Type' => 'application/json',
], json_encode($query->asArray()));
try {
$result = $client->send($request);
} catch (BadResponseException $e) {
Expand Down
6 changes: 3 additions & 3 deletions src/Command/Organization/OrganizationCurlCommand.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php
namespace Platformsh\Cli\Command\Organization;

use GuzzleHttp\Url;
use GuzzleHttp\Psr7\Uri;
use Platformsh\Cli\Service\CurlCli;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
Expand All @@ -22,8 +22,8 @@ protected function execute(InputInterface $input, OutputInterface $output)
{
$organization = $this->validateOrganizationInput($input);

$apiUrl = Url::fromString($this->config()->getApiUrl());
$absoluteUrl = $apiUrl->combine($organization->getUri())->__toString();
$apiUri = new Uri($this->config()->getApiUrl());
$absoluteUrl = $apiUri->withPath($organization->getUri());

/** @var CurlCli $curl */
$curl = $this->getService('curl_cli');
Expand Down
3 changes: 2 additions & 1 deletion src/Command/Self/SelfReleaseCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
namespace Platformsh\Cli\Command\Self;

use GuzzleHttp\Client;
use GuzzleHttp\Utils;
use Platformsh\Cli\Command\CommandBase;
use Platformsh\Cli\Util\VersionUtil;
use Symfony\Component\Console\Input\InputArgument;
Expand Down Expand Up @@ -353,7 +354,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
],
'debug' => $output->isDebug(),
]);
$release = $response->json();
$release = Utils::jsonDecode((string) $response->getBody(), true);
$releaseUrl = $repoApiUrl . '/releases/' . $release['id'];
$uploadUrl = preg_replace('/\{.+?\}/', '', $release['upload_url']);

Expand Down
Loading
Loading