From 38cdcf4f6195053c28a88126a636e87fbfbff005 Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Thu, 25 Jan 2024 17:31:40 +0100 Subject: [PATCH] =?UTF-8?q?N=C2=B05809=20Update=20league/oauth2-google=20f?= =?UTF-8?q?rom=203.0.4=20to=204.0.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- composer.json | 2 +- composer.lock | 40 +++---- lib/composer/autoload_classmap.php | 1 - lib/composer/autoload_psr4.php | 2 +- lib/composer/autoload_static.php | 5 +- lib/composer/installed.json | 42 +++---- lib/composer/installed.php | 20 ++-- lib/league/oauth2-client/README.md | 2 +- .../src/Provider/AbstractProvider.php | 106 +++++++++++++++++- .../Exception/IdentityProviderException.php | 4 +- .../src/Provider/GenericProvider.php | 14 +++ lib/league/oauth2-google/CHANGELOG.md | 13 +++ lib/league/oauth2-google/README.md | 21 ++-- lib/league/oauth2-google/composer.json | 15 ++- lib/league/oauth2-google/examples/index.php | 35 ------ .../oauth2-google/examples/provider.php | 24 ---- lib/league/oauth2-google/examples/reset.php | 7 -- lib/league/oauth2-google/examples/server.sh | 3 - lib/league/oauth2-google/examples/user.php | 39 ------- lib/league/oauth2-google/phpunit.xml.dist | 28 ----- .../src/Exception/HostedDomainException.php | 8 +- .../oauth2-google/src/Provider/Google.php | 20 ++-- .../oauth2-google/src/Provider/GoogleUser.php | 21 ++-- 23 files changed, 229 insertions(+), 243 deletions(-) delete mode 100644 lib/league/oauth2-google/examples/index.php delete mode 100644 lib/league/oauth2-google/examples/provider.php delete mode 100644 lib/league/oauth2-google/examples/reset.php delete mode 100644 lib/league/oauth2-google/examples/server.sh delete mode 100644 lib/league/oauth2-google/examples/user.php delete mode 100644 lib/league/oauth2-google/phpunit.xml.dist diff --git a/composer.json b/composer.json index 627df0e7e..145173777 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ "guzzlehttp/guzzle": "^7.5.1", "laminas/laminas-mail": "^2.11", "laminas/laminas-servicemanager": "^3.5", - "league/oauth2-google": "^3.0", + "league/oauth2-google": "^4.0.1", "nikic/php-parser": "~4.14.0", "pear/archive_tar": "~1.4.14", "pelago/emogrifier": "^6.0.0", diff --git a/composer.lock b/composer.lock index 887393de4..ce948b94f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "441491944d0900502340912e2f2e1703", + "content-hash": "8fb5b1ba82a4784cb72cd95e4290c892", "packages": [ { "name": "apereo/phpcas", @@ -973,16 +973,16 @@ }, { "name": "league/oauth2-client", - "version": "2.6.1", + "version": "2.7.0", "source": { "type": "git", "url": "https://github.com/thephpleague/oauth2-client.git", - "reference": "2334c249907190c132364f5dae0287ab8666aa19" + "reference": "160d6274b03562ebeb55ed18399281d8118b76c8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/oauth2-client/zipball/2334c249907190c132364f5dae0287ab8666aa19", - "reference": "2334c249907190c132364f5dae0287ab8666aa19", + "url": "https://api.github.com/repos/thephpleague/oauth2-client/zipball/160d6274b03562ebeb55ed18399281d8118b76c8", + "reference": "160d6274b03562ebeb55ed18399281d8118b76c8", "shasum": "" }, "require": { @@ -1037,32 +1037,32 @@ ], "support": { "issues": "https://github.com/thephpleague/oauth2-client/issues", - "source": "https://github.com/thephpleague/oauth2-client/tree/2.6.1" + "source": "https://github.com/thephpleague/oauth2-client/tree/2.7.0" }, - "time": "2021-12-22T16:42:49+00:00" + "time": "2023-04-16T18:19:15+00:00" }, { "name": "league/oauth2-google", - "version": "3.0.4", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/thephpleague/oauth2-google.git", - "reference": "6b79441f244040760bed5fdcd092a2bda7cf34c6" + "reference": "1b01ba18ba31b29e88771e3e0979e5c91d4afe76" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/oauth2-google/zipball/6b79441f244040760bed5fdcd092a2bda7cf34c6", - "reference": "6b79441f244040760bed5fdcd092a2bda7cf34c6", + "url": "https://api.github.com/repos/thephpleague/oauth2-google/zipball/1b01ba18ba31b29e88771e3e0979e5c91d4afe76", + "reference": "1b01ba18ba31b29e88771e3e0979e5c91d4afe76", "shasum": "" }, "require": { - "league/oauth2-client": "^2.0" + "league/oauth2-client": "^2.0", + "php": "^7.3 || ^8.0" }, "require-dev": { - "eloquent/phony-phpunit": "^2.0", - "php-coveralls/php-coveralls": "^2.1", - "phpunit/phpunit": "^6.0", - "squizlabs/php_codesniffer": "^2.0" + "eloquent/phony-phpunit": "^6.0 || ^7.1", + "phpunit/phpunit": "^8.0 || ^9.0", + "squizlabs/php_codesniffer": "^3.0" }, "type": "library", "autoload": { @@ -1077,8 +1077,8 @@ "authors": [ { "name": "Woody Gilk", - "email": "woody.gilk@gmail.com", - "homepage": "http://shadowhand.me" + "email": "hello@shadowhand.com", + "homepage": "https://shadowhand.com" } ], "description": "Google OAuth 2.0 Client Provider for The PHP League OAuth2-Client", @@ -1092,9 +1092,9 @@ ], "support": { "issues": "https://github.com/thephpleague/oauth2-google/issues", - "source": "https://github.com/thephpleague/oauth2-google/tree/3.0.4" + "source": "https://github.com/thephpleague/oauth2-google/tree/4.0.1" }, - "time": "2021-01-27T16:09:03+00:00" + "time": "2023-03-17T15:20:52+00:00" }, { "name": "nikic/php-parser", diff --git a/lib/composer/autoload_classmap.php b/lib/composer/autoload_classmap.php index 371f2e781..bf35b49f3 100644 --- a/lib/composer/autoload_classmap.php +++ b/lib/composer/autoload_classmap.php @@ -899,7 +899,6 @@ return array( 'Laminas\\ServiceManager\\Proxy\\LazyServiceFactory' => $vendorDir . '/laminas/laminas-servicemanager/src/Proxy/LazyServiceFactory.php', 'Laminas\\ServiceManager\\ServiceLocatorInterface' => $vendorDir . '/laminas/laminas-servicemanager/src/ServiceLocatorInterface.php', 'Laminas\\ServiceManager\\ServiceManager' => $vendorDir . '/laminas/laminas-servicemanager/src/ServiceManager.php', - 'Laminas\\ServiceManager\\Test\\CommonPluginManagerTrait' => $vendorDir . '/laminas/laminas-servicemanager/src/Test/CommonPluginManagerTrait.php', 'Laminas\\ServiceManager\\Tool\\ConfigDumper' => $vendorDir . '/laminas/laminas-servicemanager/src/Tool/ConfigDumper.php', 'Laminas\\ServiceManager\\Tool\\ConfigDumperCommand' => $vendorDir . '/laminas/laminas-servicemanager/src/Tool/ConfigDumperCommand.php', 'Laminas\\ServiceManager\\Tool\\FactoryCreator' => $vendorDir . '/laminas/laminas-servicemanager/src/Tool/FactoryCreator.php', diff --git a/lib/composer/autoload_psr4.php b/lib/composer/autoload_psr4.php index 37e965ba4..acc87aeef 100644 --- a/lib/composer/autoload_psr4.php +++ b/lib/composer/autoload_psr4.php @@ -56,7 +56,7 @@ return array( 'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'), 'PhpParser\\' => array($vendorDir . '/nikic/php-parser/lib/PhpParser'), 'Pelago\\Emogrifier\\' => array($vendorDir . '/pelago/emogrifier/src'), - 'League\\OAuth2\\Client\\' => array($vendorDir . '/league/oauth2-client/src', $vendorDir . '/league/oauth2-google/src'), + 'League\\OAuth2\\Client\\' => array($vendorDir . '/league/oauth2-google/src', $vendorDir . '/league/oauth2-client/src'), 'Laminas\\Validator\\' => array($vendorDir . '/laminas/laminas-validator/src'), 'Laminas\\Stdlib\\' => array($vendorDir . '/laminas/laminas-stdlib/src'), 'Laminas\\ServiceManager\\' => array($vendorDir . '/laminas/laminas-servicemanager/src'), diff --git a/lib/composer/autoload_static.php b/lib/composer/autoload_static.php index f4bcf3175..708fc3d17 100644 --- a/lib/composer/autoload_static.php +++ b/lib/composer/autoload_static.php @@ -314,8 +314,8 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f ), 'League\\OAuth2\\Client\\' => array ( - 0 => __DIR__ . '/..' . '/league/oauth2-client/src', - 1 => __DIR__ . '/..' . '/league/oauth2-google/src', + 0 => __DIR__ . '/..' . '/league/oauth2-google/src', + 1 => __DIR__ . '/..' . '/league/oauth2-client/src', ), 'Laminas\\Validator\\' => array ( @@ -1274,7 +1274,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f 'Laminas\\ServiceManager\\Proxy\\LazyServiceFactory' => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src/Proxy/LazyServiceFactory.php', 'Laminas\\ServiceManager\\ServiceLocatorInterface' => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src/ServiceLocatorInterface.php', 'Laminas\\ServiceManager\\ServiceManager' => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src/ServiceManager.php', - 'Laminas\\ServiceManager\\Test\\CommonPluginManagerTrait' => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src/Test/CommonPluginManagerTrait.php', 'Laminas\\ServiceManager\\Tool\\ConfigDumper' => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src/Tool/ConfigDumper.php', 'Laminas\\ServiceManager\\Tool\\ConfigDumperCommand' => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src/Tool/ConfigDumperCommand.php', 'Laminas\\ServiceManager\\Tool\\FactoryCreator' => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src/Tool/FactoryCreator.php', diff --git a/lib/composer/installed.json b/lib/composer/installed.json index b88dc57b2..5da0810e9 100644 --- a/lib/composer/installed.json +++ b/lib/composer/installed.json @@ -1003,17 +1003,17 @@ }, { "name": "league/oauth2-client", - "version": "2.6.1", - "version_normalized": "2.6.1.0", + "version": "2.7.0", + "version_normalized": "2.7.0.0", "source": { "type": "git", "url": "https://github.com/thephpleague/oauth2-client.git", - "reference": "2334c249907190c132364f5dae0287ab8666aa19" + "reference": "160d6274b03562ebeb55ed18399281d8118b76c8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/oauth2-client/zipball/2334c249907190c132364f5dae0287ab8666aa19", - "reference": "2334c249907190c132364f5dae0287ab8666aa19", + "url": "https://api.github.com/repos/thephpleague/oauth2-client/zipball/160d6274b03562ebeb55ed18399281d8118b76c8", + "reference": "160d6274b03562ebeb55ed18399281d8118b76c8", "shasum": "" }, "require": { @@ -1027,7 +1027,7 @@ "phpunit/phpunit": "^5.7 || ^6.0 || ^9.5", "squizlabs/php_codesniffer": "^2.3 || ^3.0" }, - "time": "2021-12-22T16:42:49+00:00", + "time": "2023-04-16T18:19:15+00:00", "type": "library", "extra": { "branch-alias": { @@ -1070,35 +1070,35 @@ ], "support": { "issues": "https://github.com/thephpleague/oauth2-client/issues", - "source": "https://github.com/thephpleague/oauth2-client/tree/2.6.1" + "source": "https://github.com/thephpleague/oauth2-client/tree/2.7.0" }, "install-path": "../league/oauth2-client" }, { "name": "league/oauth2-google", - "version": "3.0.4", - "version_normalized": "3.0.4.0", + "version": "4.0.1", + "version_normalized": "4.0.1.0", "source": { "type": "git", "url": "https://github.com/thephpleague/oauth2-google.git", - "reference": "6b79441f244040760bed5fdcd092a2bda7cf34c6" + "reference": "1b01ba18ba31b29e88771e3e0979e5c91d4afe76" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/oauth2-google/zipball/6b79441f244040760bed5fdcd092a2bda7cf34c6", - "reference": "6b79441f244040760bed5fdcd092a2bda7cf34c6", + "url": "https://api.github.com/repos/thephpleague/oauth2-google/zipball/1b01ba18ba31b29e88771e3e0979e5c91d4afe76", + "reference": "1b01ba18ba31b29e88771e3e0979e5c91d4afe76", "shasum": "" }, "require": { - "league/oauth2-client": "^2.0" + "league/oauth2-client": "^2.0", + "php": "^7.3 || ^8.0" }, "require-dev": { - "eloquent/phony-phpunit": "^2.0", - "php-coveralls/php-coveralls": "^2.1", - "phpunit/phpunit": "^6.0", - "squizlabs/php_codesniffer": "^2.0" + "eloquent/phony-phpunit": "^6.0 || ^7.1", + "phpunit/phpunit": "^8.0 || ^9.0", + "squizlabs/php_codesniffer": "^3.0" }, - "time": "2021-01-27T16:09:03+00:00", + "time": "2023-03-17T15:20:52+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -1113,8 +1113,8 @@ "authors": [ { "name": "Woody Gilk", - "email": "woody.gilk@gmail.com", - "homepage": "http://shadowhand.me" + "email": "hello@shadowhand.com", + "homepage": "https://shadowhand.com" } ], "description": "Google OAuth 2.0 Client Provider for The PHP League OAuth2-Client", @@ -1128,7 +1128,7 @@ ], "support": { "issues": "https://github.com/thephpleague/oauth2-google/issues", - "source": "https://github.com/thephpleague/oauth2-google/tree/3.0.4" + "source": "https://github.com/thephpleague/oauth2-google/tree/4.0.1" }, "install-path": "../league/oauth2-google" }, diff --git a/lib/composer/installed.php b/lib/composer/installed.php index 647b75df3..6b207e339 100644 --- a/lib/composer/installed.php +++ b/lib/composer/installed.php @@ -3,7 +3,7 @@ 'name' => 'combodo/itop', 'pretty_version' => 'dev-develop', 'version' => 'dev-develop', - 'reference' => '1c7dbcb1e90113dbf3a3f61fdae6519e492f6d4f', + 'reference' => 'b13efeb3a87aebbbd77d8a37f17a1e7514964e3b', 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -22,7 +22,7 @@ 'combodo/itop' => array( 'pretty_version' => 'dev-develop', 'version' => 'dev-develop', - 'reference' => '1c7dbcb1e90113dbf3a3f61fdae6519e492f6d4f', + 'reference' => 'b13efeb3a87aebbbd77d8a37f17a1e7514964e3b', 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -134,18 +134,18 @@ 'dev_requirement' => false, ), 'league/oauth2-client' => array( - 'pretty_version' => '2.6.1', - 'version' => '2.6.1.0', - 'reference' => '2334c249907190c132364f5dae0287ab8666aa19', + 'pretty_version' => '2.7.0', + 'version' => '2.7.0.0', + 'reference' => '160d6274b03562ebeb55ed18399281d8118b76c8', 'type' => 'library', 'install_path' => __DIR__ . '/../league/oauth2-client', 'aliases' => array(), 'dev_requirement' => false, ), 'league/oauth2-google' => array( - 'pretty_version' => '3.0.4', - 'version' => '3.0.4.0', - 'reference' => '6b79441f244040760bed5fdcd092a2bda7cf34c6', + 'pretty_version' => '4.0.1', + 'version' => '4.0.1.0', + 'reference' => '1b01ba18ba31b29e88771e3e0979e5c91d4afe76', 'type' => 'library', 'install_path' => __DIR__ . '/../league/oauth2-google', 'aliases' => array(), @@ -241,8 +241,8 @@ 'psr/container-implementation' => array( 'dev_requirement' => false, 'provided' => array( - 0 => '1.1|2.0', - 1 => '^1.0', + 0 => '^1.0', + 1 => '1.1|2.0', ), ), 'psr/event-dispatcher' => array( diff --git a/lib/league/oauth2-client/README.md b/lib/league/oauth2-client/README.md index f35d53e8a..cbb449d48 100644 --- a/lib/league/oauth2-client/README.md +++ b/lib/league/oauth2-client/README.md @@ -6,7 +6,7 @@ This package provides a base for integrating with [OAuth 2.0](http://oauth.net/2 [![Source Code](https://img.shields.io/badge/source-thephpleague/oauth2--client-blue.svg?style=flat-square)](https://github.com/thephpleague/oauth2-client) [![Latest Version](https://img.shields.io/github/release/thephpleague/oauth2-client.svg?style=flat-square)](https://github.com/thephpleague/oauth2-client/releases) [![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](https://github.com/thephpleague/oauth2-client/blob/master/LICENSE) -[![Build Status](https://img.shields.io/github/workflow/status/thephpleague/oauth2-client/CI?label=CI&logo=github&style=flat-square)](https://github.com/thephpleague/oauth2-client/actions?query=workflow%3ACI) +[![Build Status](https://img.shields.io/github/actions/workflow/status/thephpleague/oauth2-client/continuous-integration.yml?label=CI&logo=github&style=flat-square)](https://github.com/thephpleague/oauth2-client/actions?query=workflow%3ACI) [![Codecov Code Coverage](https://img.shields.io/codecov/c/gh/thephpleague/oauth2-client?label=codecov&logo=codecov&style=flat-square)](https://codecov.io/gh/thephpleague/oauth2-client) [![Total Downloads](https://img.shields.io/packagist/dt/league/oauth2-client.svg?style=flat-square)](https://packagist.org/packages/league/oauth2-client) diff --git a/lib/league/oauth2-client/src/Provider/AbstractProvider.php b/lib/league/oauth2-client/src/Provider/AbstractProvider.php index d1679998c..293a54d6e 100644 --- a/lib/league/oauth2-client/src/Provider/AbstractProvider.php +++ b/lib/league/oauth2-client/src/Provider/AbstractProvider.php @@ -17,6 +17,7 @@ namespace League\OAuth2\Client\Provider; use GuzzleHttp\Client as HttpClient; use GuzzleHttp\ClientInterface as HttpClientInterface; use GuzzleHttp\Exception\BadResponseException; +use InvalidArgumentException; use League\OAuth2\Client\Grant\AbstractGrant; use League\OAuth2\Client\Grant\GrantFactory; use League\OAuth2\Client\OptionProvider\OptionProviderInterface; @@ -44,7 +45,7 @@ abstract class AbstractProvider use QueryBuilderTrait; /** - * @var string Key used in a token response to identify the resource owner. + * @var string|null Key used in a token response to identify the resource owner. */ const ACCESS_TOKEN_RESOURCE_OWNER_ID = null; @@ -58,6 +59,19 @@ abstract class AbstractProvider */ const METHOD_POST = 'POST'; + /** + * @var string PKCE method used to fetch authorization token. + * The PKCE code challenge will be hashed with sha256 (recommended). + */ + const PKCE_METHOD_S256 = 'S256'; + + /** + * @var string PKCE method used to fetch authorization token. + * The PKCE code challenge will be sent as plain text, this is NOT recommended. + * Only use `plain` if no other option is possible. + */ + const PKCE_METHOD_PLAIN = 'plain'; + /** * @var string */ @@ -78,6 +92,11 @@ abstract class AbstractProvider */ protected $state; + /** + * @var string|null + */ + protected $pkceCode = null; + /** * @var GrantFactory */ @@ -264,6 +283,32 @@ abstract class AbstractProvider return $this->state; } + /** + * Set the value of the pkceCode parameter. + * + * When using PKCE this should be set before requesting an access token. + * + * @param string $pkceCode + * @return self + */ + public function setPkceCode($pkceCode) + { + $this->pkceCode = $pkceCode; + return $this; + } + + /** + * Returns the current value of the pkceCode parameter. + * + * This can be accessed by the redirect handler during authorization. + * + * @return string|null + */ + public function getPkceCode() + { + return $this->pkceCode; + } + /** * Returns the base URL for authorizing a client. * @@ -305,6 +350,27 @@ abstract class AbstractProvider return bin2hex(random_bytes($length / 2)); } + /** + * Returns a new random string to use as PKCE code_verifier and + * hashed as code_challenge parameters in an authorization flow. + * Must be between 43 and 128 characters long. + * + * @param int $length Length of the random string to be generated. + * @return string + */ + protected function getRandomPkceCode($length = 64) + { + return substr( + strtr( + base64_encode(random_bytes($length)), + '+/', + '-_' + ), + 0, + $length + ); + } + /** * Returns the default scopes used by this provider. * @@ -326,6 +392,14 @@ abstract class AbstractProvider return ','; } + /** + * @return string|null + */ + protected function getPkceMethod() + { + return null; + } + /** * Returns authorization parameters based on provided options. * @@ -355,6 +429,26 @@ abstract class AbstractProvider // Store the state as it may need to be accessed later on. $this->state = $options['state']; + $pkceMethod = $this->getPkceMethod(); + if (!empty($pkceMethod)) { + $this->pkceCode = $this->getRandomPkceCode(); + if ($pkceMethod === static::PKCE_METHOD_S256) { + $options['code_challenge'] = trim( + strtr( + base64_encode(hash('sha256', $this->pkceCode, true)), + '+/', + '-_' + ), + '=' + ); + } elseif ($pkceMethod === static::PKCE_METHOD_PLAIN) { + $options['code_challenge'] = $this->pkceCode; + } else { + throw new InvalidArgumentException('Unknown PKCE method "' . $pkceMethod . '".'); + } + $options['code_challenge_method'] = $pkceMethod; + } + // Business code layer might set a different redirect_uri parameter // depending on the context, leave it as-is if (!isset($options['redirect_uri'])) { @@ -517,8 +611,8 @@ abstract class AbstractProvider /** * Requests an access token using a specified grant and option set. * - * @param mixed $grant - * @param array $options + * @param mixed $grant + * @param array $options * @throws IdentityProviderException * @return AccessTokenInterface */ @@ -532,6 +626,10 @@ abstract class AbstractProvider 'redirect_uri' => $this->redirectUri, ]; + if (!empty($this->pkceCode)) { + $params['code_verifier'] = $this->pkceCode; + } + $params = $grant->prepareRequestParameters($params, $options); $request = $this->getAccessTokenRequest($params); $response = $this->getParsedResponse($request); @@ -564,7 +662,7 @@ abstract class AbstractProvider * * @param string $method * @param string $url - * @param AccessTokenInterface|string $token + * @param AccessTokenInterface|string|null $token * @param array $options Any of "headers", "body", and "protocolVersion". * @return RequestInterface */ diff --git a/lib/league/oauth2-client/src/Provider/Exception/IdentityProviderException.php b/lib/league/oauth2-client/src/Provider/Exception/IdentityProviderException.php index 52b7e0353..55cb438fb 100644 --- a/lib/league/oauth2-client/src/Provider/Exception/IdentityProviderException.php +++ b/lib/league/oauth2-client/src/Provider/Exception/IdentityProviderException.php @@ -27,7 +27,7 @@ class IdentityProviderException extends \Exception /** * @param string $message * @param int $code - * @param array|string $response The response body + * @param mixed $response The response body */ public function __construct($message, $code, $response) { @@ -39,7 +39,7 @@ class IdentityProviderException extends \Exception /** * Returns the exception's response body. * - * @return array|string + * @return mixed */ public function getResponseBody() { diff --git a/lib/league/oauth2-client/src/Provider/GenericProvider.php b/lib/league/oauth2-client/src/Provider/GenericProvider.php index 74393ffda..0fc95f250 100644 --- a/lib/league/oauth2-client/src/Provider/GenericProvider.php +++ b/lib/league/oauth2-client/src/Provider/GenericProvider.php @@ -78,6 +78,11 @@ class GenericProvider extends AbstractProvider */ private $responseResourceOwnerId = 'id'; + /** + * @var string|null + */ + private $pkceMethod = null; + /** * @param array $options * @param array $collaborators @@ -114,6 +119,7 @@ class GenericProvider extends AbstractProvider 'responseCode', 'responseResourceOwnerId', 'scopes', + 'pkceMethod', ]); } @@ -205,6 +211,14 @@ class GenericProvider extends AbstractProvider return $this->scopeSeparator ?: parent::getScopeSeparator(); } + /** + * @inheritdoc + */ + protected function getPkceMethod() + { + return $this->pkceMethod ?: parent::getPkceMethod(); + } + /** * @inheritdoc */ diff --git a/lib/league/oauth2-google/CHANGELOG.md b/lib/league/oauth2-google/CHANGELOG.md index 18b1a9a6e..d82a2ae17 100644 --- a/lib/league/oauth2-google/CHANGELOG.md +++ b/lib/league/oauth2-google/CHANGELOG.md @@ -1,5 +1,18 @@ OAuth 2.0 Google Provider Changelog +## 4.0.1 - 2022-03-17 + +### Changed + +- Corrected file excludes for dist archive, #120 by @cedric-anne + +## 4.0.0 - 2022-03-04 + +### Changed + +- Adding return type, #98 by @yozhef +- Add PHP 8.0 support, require PHP 7.3 or newer, #102 by @yozhef + ## 3.0.4 - 2021-01-27 ### Fixed diff --git a/lib/league/oauth2-google/README.md b/lib/league/oauth2-google/README.md index df69dcd12..38792d4af 100644 --- a/lib/league/oauth2-google/README.md +++ b/lib/league/oauth2-google/README.md @@ -1,11 +1,9 @@ # Google Provider for OAuth 2.0 Client -[![Join the chat](https://img.shields.io/badge/gitter-join-1DCE73.svg)](https://gitter.im/thephpleague/oauth2-google) -[![Build Status](https://img.shields.io/travis/thephpleague/oauth2-google.svg)](https://travis-ci.org/thephpleague/oauth2-google) -[![Code Coverage](https://img.shields.io/coveralls/thephpleague/oauth2-google.svg)](https://coveralls.io/r/thephpleague/oauth2-google) -[![Code Quality](https://img.shields.io/scrutinizer/g/thephpleague/oauth2-google.svg)](https://scrutinizer-ci.com/g/thephpleague/oauth2-google/) -[![License](https://img.shields.io/packagist/l/league/oauth2-google.svg)](https://github.com/thephpleague/oauth2-google/blob/master/LICENSE) -[![Latest Stable Version](https://img.shields.io/packagist/v/league/oauth2-google.svg)](https://packagist.org/packages/league/oauth2-google) +[![Build Status](https://img.shields.io/github/workflow/status/thephpleague/oauth2-google/test/main)](https://github.com/thephpleague/oauth2-google/actions/workflows/test.yaml) +[![Code Coverage](https://img.shields.io/codecov/c/gh/thephpleague/oauth2-google)](https://app.codecov.io/gh/thephpleague/oauth2-google) +[![License](https://img.shields.io/packagist/l/league/oauth2-google)](https://github.com/thephpleague/oauth2-google/blob/main/LICENSE) +[![Latest Stable Version](https://img.shields.io/packagist/v/league/oauth2-google)](https://packagist.org/packages/league/oauth2-google) This package provides Google OAuth 2.0 support for the PHP League's [OAuth 2.0 Client](https://github.com/thephpleague/oauth2-client). @@ -20,11 +18,10 @@ a patch via pull request. The following versions of PHP are supported. -* PHP 7.0 -* PHP 7.1 -* PHP 7.2 * PHP 7.3 * PHP 7.4 +* PHP 8.0 +* PHP 8.1 This package uses [OpenID Connect][openid-connect] to authenticate users with Google accounts. @@ -178,7 +175,7 @@ $refreshToken = $token->getRefreshToken(); If you ever need to get a new refresh token you can request one by forcing the consent prompt: ```php -$authUrl = $provider->getAuthorizationUrl(['prompt' => 'consent']); +$authUrl = $provider->getAuthorizationUrl(['prompt' => 'consent', 'access_type' => 'offline']); ``` Now you have everything you need to refresh an access token using a refresh token: @@ -228,7 +225,7 @@ composer check ## Contributing -Please see [CONTRIBUTING](https://github.com/thephpleague/oauth2-google/blob/master/CONTRIBUTING.md) for details. +Please see [CONTRIBUTING](https://github.com/thephpleague/oauth2-google/blob/main/CONTRIBUTING.md) for details. ## Credits @@ -239,4 +236,4 @@ Please see [CONTRIBUTING](https://github.com/thephpleague/oauth2-google/blob/mas ## License -The MIT License (MIT). Please see [License File](https://github.com/thephpleague/oauth2-google/blob/master/LICENSE) for more information. +The MIT License (MIT). Please see [License File](https://github.com/thephpleague/oauth2-google/blob/main/LICENSE) for more information. diff --git a/lib/league/oauth2-google/composer.json b/lib/league/oauth2-google/composer.json index f34a1cec9..73ce51ed8 100644 --- a/lib/league/oauth2-google/composer.json +++ b/lib/league/oauth2-google/composer.json @@ -5,8 +5,8 @@ "authors": [ { "name": "Woody Gilk", - "email": "woody.gilk@gmail.com", - "homepage": "http://shadowhand.me" + "email": "hello@shadowhand.com", + "homepage": "https://shadowhand.com" } ], "keywords": [ @@ -19,13 +19,13 @@ ], "minimum-stability": "stable", "require": { + "php": "^7.3 || ^8.0", "league/oauth2-client": "^2.0" }, "require-dev": { - "eloquent/phony-phpunit": "^2.0", - "phpunit/phpunit": "^6.0", - "php-coveralls/php-coveralls": "^2.1", - "squizlabs/php_codesniffer": "^2.0" + "eloquent/phony-phpunit": "^6.0 || ^7.1", + "phpunit/phpunit": "^8.0 || ^9.0", + "squizlabs/php_codesniffer": "^3.0" }, "autoload": { "psr-4": { @@ -38,7 +38,6 @@ } }, "scripts": { - "test": "phpunit", - "check": "phpcs src --standard=psr2 -sp" + "check": "phpcs src test --standard=PSR12 -sp" } } diff --git a/lib/league/oauth2-google/examples/index.php b/lib/league/oauth2-google/examples/index.php deleted file mode 100644 index 913843777..000000000 --- a/lib/league/oauth2-google/examples/index.php +++ /dev/null @@ -1,35 +0,0 @@ -getAuthorizationUrl(); - $_SESSION['oauth2state'] = $provider->getState(); - header('Location: ' . $authUrl); - exit; - -} elseif (empty($_GET['state']) || ($_GET['state'] !== $_SESSION['oauth2state'])) { - - // State is invalid, possible CSRF attack in progress - unset($_SESSION['oauth2state']); - exit('Invalid state'); - -} else { - - // Try to get an access token (using the authorization code grant) - $token = $provider->getAccessToken('authorization_code', [ - 'code' => $_GET['code'] - ]); - - $_SESSION['token'] = serialize($token); - - // Optional: Now you have a token you can look up a users profile data - header('Location: /user.php'); -} diff --git a/lib/league/oauth2-google/examples/provider.php b/lib/league/oauth2-google/examples/provider.php deleted file mode 100644 index 4001f6857..000000000 --- a/lib/league/oauth2-google/examples/provider.php +++ /dev/null @@ -1,24 +0,0 @@ -getResourceOwner($token); - - // Use these details to create a new profile - printf('Hello %s!
', $userDetails->getFirstname()); -} catch (Exception $e) { - // Failed to get user details - exit('Something went wrong: ' . $e->getMessage()); -} - -// Use this to interact with an API on the users behalf -echo "Token is: ", $token->getToken(), "
"; - -// Use this to get a new access token if the old one expires -echo "Refresh token is: ", $token->getRefreshToken(), "
"; - -// Number of seconds until the access token will expire, and need refreshing -echo "Expires at ", date('r', $token->getExpires()), "
"; - -// Allow the user to logout -echo 'Logout
'; diff --git a/lib/league/oauth2-google/phpunit.xml.dist b/lib/league/oauth2-google/phpunit.xml.dist deleted file mode 100644 index 7f37586aa..000000000 --- a/lib/league/oauth2-google/phpunit.xml.dist +++ /dev/null @@ -1,28 +0,0 @@ - - - - - ./test - - - - - src/ - - - - - - - - diff --git a/lib/league/oauth2-google/src/Exception/HostedDomainException.php b/lib/league/oauth2-google/src/Exception/HostedDomainException.php index b38a41580..7f82b5374 100644 --- a/lib/league/oauth2-google/src/Exception/HostedDomainException.php +++ b/lib/league/oauth2-google/src/Exception/HostedDomainException.php @@ -7,8 +7,12 @@ namespace League\OAuth2\Client\Exception; */ class HostedDomainException extends \Exception { - - public static function notMatchingDomain($configuredDomain) + /** + * @param $configuredDomain + * + * @return static + */ + public static function notMatchingDomain($configuredDomain): self { return new static("User is not part of domain '$configuredDomain'"); } diff --git a/lib/league/oauth2-google/src/Provider/Google.php b/lib/league/oauth2-google/src/Provider/Google.php index 43938e0ec..a28add748 100644 --- a/lib/league/oauth2-google/src/Provider/Google.php +++ b/lib/league/oauth2-google/src/Provider/Google.php @@ -36,22 +36,22 @@ class Google extends AbstractProvider */ protected $scopes = []; - public function getBaseAuthorizationUrl() + public function getBaseAuthorizationUrl(): string { return 'https://accounts.google.com/o/oauth2/v2/auth'; } - public function getBaseAccessTokenUrl(array $params) + public function getBaseAccessTokenUrl(array $params): string { return 'https://oauth2.googleapis.com/token'; } - public function getResourceOwnerDetailsUrl(AccessToken $token) + public function getResourceOwnerDetailsUrl(AccessToken $token): string { return 'https://openidconnect.googleapis.com/v1/userinfo'; } - protected function getAuthorizationParameters(array $options) + protected function getAuthorizationParameters(array $options): array { if (empty($options['hd']) && $this->hostedDomain) { $options['hd'] = $this->hostedDomain; @@ -84,7 +84,7 @@ class Google extends AbstractProvider return $options; } - protected function getDefaultScopes() + protected function getDefaultScopes(): array { // "openid" MUST be the first scope in the list. return [ @@ -94,12 +94,12 @@ class Google extends AbstractProvider ]; } - protected function getScopeSeparator() + protected function getScopeSeparator(): string { return ' '; } - protected function checkResponse(ResponseInterface $response, $data) + protected function checkResponse(ResponseInterface $response, $data): void { // @codeCoverageIgnoreStart if (empty($data['error'])) { @@ -118,7 +118,7 @@ class Google extends AbstractProvider throw new IdentityProviderException($error, $code, $data); } - protected function createResourceOwner(array $response, AccessToken $token) + protected function createResourceOwner(array $response, AccessToken $token): GoogleUser { $user = new GoogleUser($response); @@ -128,9 +128,11 @@ class Google extends AbstractProvider } /** + * @param string|null $hostedDomain + * * @throws HostedDomainException If the domain does not match the configured domain. */ - protected function assertMatchingDomain($hostedDomain) + protected function assertMatchingDomain(?string $hostedDomain): void { if ($this->hostedDomain === null) { // No hosted domain configured. diff --git a/lib/league/oauth2-google/src/Provider/GoogleUser.php b/lib/league/oauth2-google/src/Provider/GoogleUser.php index 1100b1dbe..d004e3c6d 100644 --- a/lib/league/oauth2-google/src/Provider/GoogleUser.php +++ b/lib/league/oauth2-google/src/Provider/GoogleUser.php @@ -27,7 +27,7 @@ class GoogleUser implements ResourceOwnerInterface * * @return string */ - public function getName() + public function getName(): string { return $this->response['name']; } @@ -37,7 +37,7 @@ class GoogleUser implements ResourceOwnerInterface * * @return string|null */ - public function getFirstName() + public function getFirstName(): ?string { return $this->getResponseValue('given_name'); } @@ -47,7 +47,7 @@ class GoogleUser implements ResourceOwnerInterface * * @return string|null */ - public function getLastName() + public function getLastName(): ?string { return $this->getResponseValue('family_name'); } @@ -57,7 +57,7 @@ class GoogleUser implements ResourceOwnerInterface * * @return string|null */ - public function getLocale() + public function getLocale(): ?string { return $this->getResponseValue('locale'); } @@ -67,7 +67,7 @@ class GoogleUser implements ResourceOwnerInterface * * @return string|null */ - public function getEmail() + public function getEmail(): ?string { return $this->getResponseValue('email'); } @@ -77,7 +77,7 @@ class GoogleUser implements ResourceOwnerInterface * * @return string|null */ - public function getHostedDomain() + public function getHostedDomain(): ?string { return $this->getResponseValue('hd'); } @@ -87,7 +87,7 @@ class GoogleUser implements ResourceOwnerInterface * * @return string|null */ - public function getAvatar() + public function getAvatar(): ?string { return $this->getResponseValue('picture'); } @@ -97,16 +97,13 @@ class GoogleUser implements ResourceOwnerInterface * * @return array */ - public function toArray() + public function toArray(): array { return $this->response; } private function getResponseValue($key) { - if (array_key_exists($key, $this->response)) { - return $this->response[$key]; - } - return null; + return $this->response[$key] ?? null; } }