From c302397093872463ca31fd926b6d4ee5459dbc3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Malte=20Schlu=CC=88ter?= Date: Thu, 19 Oct 2023 10:03:16 +0200 Subject: [PATCH] Add new provider Passage --- README.md | 18 +++++ phpstan.neon.dist | 6 ++ src/Client/Provider/PassageClient.php | 48 ++++++++++++++ .../KnpUOAuth2ClientExtension.php | 2 + src/DependencyInjection/ProviderFactory.php | 1 - .../PassageProviderConfiguration.php | 66 +++++++++++++++++++ .../Exception/FinishRegistrationException.php | 7 +- 7 files changed, 143 insertions(+), 5 deletions(-) create mode 100644 src/Client/Provider/PassageClient.php create mode 100644 src/DependencyInjection/Providers/PassageProviderConfiguration.php diff --git a/README.md b/README.md index caa61025..1e04d9ab 100644 --- a/README.md +++ b/README.md @@ -91,6 +91,7 @@ via Composer: | [Mollie](https://github.com/mollie/oauth2-mollie-php) | composer require mollie/oauth2-mollie-php | | [Odnoklassniki](https://github.com/rakeev/oauth2-odnoklassniki) | composer require aego/oauth2-odnoklassniki | | [Okta](https://github.com/foxworth42/oauth2-okta) | composer require foxworth42/oauth2-okta | +| [Passage](https://github.com/malteschlueter/oauth2-passage) | composer require malteschlueter/oauth2-passage | | [Paypal](https://github.com/stevenmaguire/oauth2-paypal) | composer require stevenmaguire/oauth2-paypal | | [PSN](https://github.com/larabros/oauth2-psn) | composer require larabros/oauth2-psn | | [Salesforce](https://github.com/stevenmaguire/oauth2-salesforce) | composer require stevenmaguire/oauth2-salesforce | @@ -1313,6 +1314,23 @@ knpu_oauth2_client: # whether to check OAuth2 "state": defaults to true # use_state: true + # will create service: "knpu.oauth2.client.passage" + # an instance of: KnpU\OAuth2ClientBundle\Client\Provider\PassageClient + # composer require malteschlueter/oauth2-passage + passage: + # must be "passage" - it activates that type! + type: passage + # add and set these environment variables in your .env files + client_id: '%env(OAUTH_PASSAGE_CLIENT_ID)%' + client_secret: '%env(OAUTH_PASSAGE_CLIENT_SECRET)%' + # a route name you'll create + redirect_route: connect_passage_check + redirect_params: {} + # Passage sub domain. For example, from passage url "https://example.withpassage.com" only "example" is required. + sub_domain: 'example' + # whether to check OAuth2 "state": defaults to true + # use_state: true + # will create service: "knpu.oauth2.client.paypal" # an instance of: KnpU\OAuth2ClientBundle\Client\Provider\PaypalClient # composer require stevenmaguire/oauth2-paypal diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 9b6ad247..f09298c5 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -13,6 +13,12 @@ parameters: - message: '#Return typehint of method KnpU\\OAuth2ClientBundle\\Client\\Provider\\[a-zA-Z0-9\\_]+::fetchUser\(\) has invalid type [a-zA-Z0-9\\_]#' path: ./src/Client/Provider + - + message: '#Class League\\OAuth2\\Client\\Provider\\[a-zA-Z0-9\\_]+ not found\.#' + path: ./src/Client/Provider + - + message: '#Call to method [a-zA-Z0-9\\_]+\(\) on an unknown class League\\OAuth2\\Client\\Provider\\[a-zA-Z0-9\\_]+\.#' + path: ./src/Client/Provider # False positive: using `::class` is not an error for those providers `::getProviderClass()` method. - message: '#Class [a-zA-Z0-9\\_]+ not found#' diff --git a/src/Client/Provider/PassageClient.php b/src/Client/Provider/PassageClient.php new file mode 100644 index 00000000..7e3aaa2e --- /dev/null +++ b/src/Client/Provider/PassageClient.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace KnpU\OAuth2ClientBundle\Client\Provider; + +use KnpU\OAuth2ClientBundle\Client\OAuth2Client; +use League\OAuth2\Client\Provider\Passage; +use League\OAuth2\Client\Provider\PassageUser; +use League\OAuth2\Client\Provider\ResourceOwnerInterface; +use League\OAuth2\Client\Token\AccessToken; +use Symfony\Component\HttpFoundation\RedirectResponse; + +class PassageClient extends OAuth2Client +{ + /** + * @return PassageUser|ResourceOwnerInterface + */ + public function fetchUserFromToken(AccessToken $accessToken) + { + return parent::fetchUserFromToken($accessToken); + } + + /** + * @return PassageUser|ResourceOwnerInterface + */ + public function fetchUser() + { + return parent::fetchUser(); + } + + public function logout(): RedirectResponse + { + $provider = $this->getOAuth2Provider(); + + if (!($provider instanceof Passage)) { + throw new \RuntimeException('Invalid provider "'.\get_class($provider).'", expected provider "'.Passage::class.'"'); + } + + return new RedirectResponse($provider->getLogoutUrl()); + } +} diff --git a/src/DependencyInjection/KnpUOAuth2ClientExtension.php b/src/DependencyInjection/KnpUOAuth2ClientExtension.php index daa5bcdb..7d3f988a 100644 --- a/src/DependencyInjection/KnpUOAuth2ClientExtension.php +++ b/src/DependencyInjection/KnpUOAuth2ClientExtension.php @@ -51,6 +51,7 @@ use KnpU\OAuth2ClientBundle\DependencyInjection\Providers\MollieProviderConfigurator; use KnpU\OAuth2ClientBundle\DependencyInjection\Providers\OdnoklassnikiProviderConfigurator; use KnpU\OAuth2ClientBundle\DependencyInjection\Providers\OktaProviderConfigurator; +use KnpU\OAuth2ClientBundle\DependencyInjection\Providers\PassageProviderConfiguration; use KnpU\OAuth2ClientBundle\DependencyInjection\Providers\PaypalProviderConfigurator; use KnpU\OAuth2ClientBundle\DependencyInjection\Providers\ProviderConfiguratorInterface; use KnpU\OAuth2ClientBundle\DependencyInjection\Providers\ProviderWithoutClientSecretConfiguratorInterface; @@ -133,6 +134,7 @@ class KnpUOAuth2ClientExtension extends Extension 'mollie' => MollieProviderConfigurator::class, 'odnoklassniki' => OdnoklassnikiProviderConfigurator::class, 'okta' => OktaProviderConfigurator::class, + 'passage' => PassageProviderConfiguration::class, 'paypal' => PaypalProviderConfigurator::class, 'psn' => PsnProviderConfigurator::class, 'salesforce' => SalesforceProviderConfigurator::class, diff --git a/src/DependencyInjection/ProviderFactory.php b/src/DependencyInjection/ProviderFactory.php index 95aa24d8..69e802ab 100644 --- a/src/DependencyInjection/ProviderFactory.php +++ b/src/DependencyInjection/ProviderFactory.php @@ -33,7 +33,6 @@ public function __construct(UrlGeneratorInterface $generator) * Creates a provider of the given class. * * @param string $class - * @param string $redirectUri */ public function createProvider($class, array $options, string $redirectUri = null, array $redirectParams = [], array $collaborators = []) { diff --git a/src/DependencyInjection/Providers/PassageProviderConfiguration.php b/src/DependencyInjection/Providers/PassageProviderConfiguration.php new file mode 100644 index 00000000..5df44cfb --- /dev/null +++ b/src/DependencyInjection/Providers/PassageProviderConfiguration.php @@ -0,0 +1,66 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace KnpU\OAuth2ClientBundle\DependencyInjection\Providers; + +use KnpU\OAuth2ClientBundle\Client\Provider\PassageClient; +use League\OAuth2\Client\Provider\Passage; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; + +class PassageProviderConfiguration implements ProviderConfiguratorInterface +{ + public function buildConfiguration(NodeBuilder $node): void + { + $node + ->scalarNode('sub_domain') + ->isRequired() + ->info('Passage sub domain. For example, from passage url "https://example.withpassage.com" only "example" is required.') + ->example('sub_domain: \'%env(OAUTH_PASSAGE_SUB_DOMAIN)%\'') + ->example('sub_domain: \'example\'') + ->end() + ; + } + + public function getProviderClass(array $configuration): string + { + return Passage::class; + } + + public function getClientClass(array $config): string + { + return PassageClient::class; + } + + public function getProviderOptions(array $configuration): array + { + return [ + 'clientId' => $configuration['client_id'], + 'clientSecret' => $configuration['client_secret'], + 'subDomain' => $configuration['sub_domain'], + ]; + } + + public function getPackagistName(): string + { + return 'malteschlueter/oauth2-passage'; + } + + public function getLibraryHomepage(): string + { + return 'https://github.com/malteschlueter/oauth2-passage'; + } + + public function getProviderDisplayName(): string + { + return 'Passage'; + } +} diff --git a/src/Security/Exception/FinishRegistrationException.php b/src/Security/Exception/FinishRegistrationException.php index 0ed6a5ea..fa718ee5 100644 --- a/src/Security/Exception/FinishRegistrationException.php +++ b/src/Security/Exception/FinishRegistrationException.php @@ -20,10 +20,9 @@ class FinishRegistrationException extends AuthenticationException private $userInformation; /** - * @param mixed $userInfo Any info to be used to help registration - * @param string $message - * @param int $code - * @param \Exception $previous + * @param mixed $userInfo Any info to be used to help registration + * @param string $message + * @param int $code */ public function __construct($userInfo, $message = '', $code = 0, \Exception $previous = null) {