From 3f59b3bc1470a1f4096e9065d6164c52da8b9649 Mon Sep 17 00:00:00 2001 From: Nick Liu Date: Tue, 28 Dec 2021 11:51:20 +0100 Subject: [PATCH] Suppress uncaught Hybridauth exceptions in `e_user_provider` And add a check for those exceptions in `social_ui::generateSocialLoginSection()` Fixes: #4192 --- e107_handlers/user_handler.php | 29 ++++++++++++++----- e107_plugins/social/admin_config.php | 13 +++++++++ e107_tests/tests/unit/e_user_providerTest.php | 28 ++++++++++++++++++ 3 files changed, 63 insertions(+), 7 deletions(-) diff --git a/e107_handlers/user_handler.php b/e107_handlers/user_handler.php index daf1add085..5e0d637e41 100644 --- a/e107_handlers/user_handler.php +++ b/e107_handlers/user_handler.php @@ -1171,16 +1171,30 @@ public function __construct($provider = null, $config = array(), $suppress_excep } - $this->respawnHybridauth(); - $this->setProvider($provider); + try + { + $this->respawnHybridauth(); + $this->setProvider($provider); - $providerId = $this->getProvider(); - if ($providerId && $this->hybridauth->isConnectedWith($providerId)) + $providerId = $this->getProvider(); + if ($providerId && $this->hybridauth->isConnectedWith($providerId)) + { + $this->adapter = $this->hybridauth->getAdapter($providerId); + } + } + catch (\Hybridauth\Exception\InvalidArgumentException $e) + { + if (!$suppress_exceptions) throw $e; + } + catch (\Hybridauth\Exception\UnexpectedValueException $e) { - $this->adapter = $this->hybridauth->getAdapter($providerId); + if (!$suppress_exceptions) throw $e; } } + /** + * @throws \Hybridauth\Exception\InvalidArgumentException + */ private function respawnHybridauth() { $this->hybridauth = new Hybridauth\Hybridauth($this->_config); @@ -1237,9 +1251,10 @@ public function userId() /** * Get the social login providers for which we have adapters * - * This function is slow! Please cache the output instead of calling it multiple times. + * Despite this being a static method, it memoizes (caches) the slow reflection code in the {@link e107} registry + * after the first run, so subsequent calls to this method are fast. * - * @return array String list of supported providers. Empty if Hybridauth is broken. + * @return string[] String list of supported providers. Empty if Hybridauth is broken. */ public static function getSupportedProviders() { diff --git a/e107_plugins/social/admin_config.php b/e107_plugins/social/admin_config.php index 79bcb28859..6edefdffe6 100644 --- a/e107_plugins/social/admin_config.php +++ b/e107_plugins/social/admin_config.php @@ -606,6 +606,19 @@ private function generateSocialLoginSection($provider_names, $readonly=false) foreach ($provider_names as $provider_name) { + // Check if the current configuration for the provider is valid + try + { + new e_user_provider($provider_name, [], false); + } + catch (\Hybridauth\Exception\InvalidArgumentException $e) + { + e107::getMessage()->addError("[{$e->getCode()}] {$e->getMessage()}"); + } + catch (\Hybridauth\Exception\UnexpectedValueException $ignored) + { + } + $text .= $this->generateSocialLoginRow($provider_name, $readonly); } diff --git a/e107_tests/tests/unit/e_user_providerTest.php b/e107_tests/tests/unit/e_user_providerTest.php index c09ad08685..8350f763a8 100644 --- a/e107_tests/tests/unit/e_user_providerTest.php +++ b/e107_tests/tests/unit/e_user_providerTest.php @@ -115,4 +115,32 @@ public function testGetSupplementalFieldsOf() $result = e_user_provider::getSupplementalFieldsOf("Vkontakte"); $this->assertTrue(array_key_exists('photo_size', $result)); } + + public function testNewSuppressExceptions() + { + $this->assertInstanceOf( + e_user_provider::class, + new e_user_provider("Facebook", ["providers" => ["Facebook", ["enabled" => true]]]) + ); + } + + public function testNewNoSuppressConfigurationException() + { + $this->expectException(\Hybridauth\Exception\InvalidArgumentException::class); + new e_user_provider( + "Facebook", + ["providers" => ["Facebook" => ["enabled" => true]]], + false + ); + } + + public function testNewNoSuppressDisabledException() + { + $this->expectException(\Hybridauth\Exception\UnexpectedValueException::class); + new e_user_provider( + "Facebook", + ["providers" => ["Facebook" => ["enabled" => false]]], + false + ); + } }