From 2cc6b9dae554f1188598b3613d3dc0460d9ab94a Mon Sep 17 00:00:00 2001 From: IanM Date: Mon, 27 Nov 2023 12:07:59 +0000 Subject: [PATCH] feat: oauth debug toggle --- extend.php | 3 +- js/src/admin/components/AuthSettingsPage.js | 12 ++++++ resources/locale/en.yml | 4 ++ src/Controller.php | 43 ++++++++++++++++++++- 4 files changed, 59 insertions(+), 3 deletions(-) diff --git a/extend.php b/extend.php index 52e853e..3e35059 100644 --- a/extend.php +++ b/extend.php @@ -67,7 +67,8 @@ ->default('fof-oauth.fullscreenPopup', true) ->serializeToForum('fof-oauth.popupWidth', 'fof-oauth.popupWidth', 'intval') ->serializeToForum('fof-oauth.popupHeight', 'fof-oauth.popupHeight', 'intval') - ->serializeToForum('fof-oauth.fullscreenPopup', 'fof-oauth.fullscreenPopup', 'boolVal'), + ->serializeToForum('fof-oauth.fullscreenPopup', 'fof-oauth.fullscreenPopup', 'boolVal') + ->default('fof-oauth.log-oauth-errors', false), (new Extend\Event()) ->listen(OAuthLoginSuccessful::class, Listeners\UpdateEmailFromProvider::class) diff --git a/js/src/admin/components/AuthSettingsPage.js b/js/src/admin/components/AuthSettingsPage.js index 01bb0d9..c5d3487 100644 --- a/js/src/admin/components/AuthSettingsPage.js +++ b/js/src/admin/components/AuthSettingsPage.js @@ -54,6 +54,18 @@ export default class AuthSettingsPage extends ExtensionPage { {this.providerSettingsItems().toArray()} +
+ +
+

{app.translator.trans('fof-oauth.admin.settings.advanced.heading')}

+ {this.buildSettingComponent({ + type: 'boolean', + setting: 'fof-oauth.log-oauth-errors', + label: app.translator.trans('fof-oauth.admin.settings.advanced.log-oauth-errors-label'), + help: app.translator.trans('fof-oauth.admin.settings.advanced.log-oauth-errors-help'), + })} +
+ {this.submitButton()} diff --git a/resources/locale/en.yml b/resources/locale/en.yml index 75c56ff..89126d3 100644 --- a/resources/locale/en.yml +++ b/resources/locale/en.yml @@ -5,6 +5,10 @@ fof-oauth: settings_accessibility_label: "{name} settings" settings: + advanced: + heading: Advanced + log-oauth-errors-label: Log OAuth errors + log-oauth-errors-help: If enabled, OAuth errors will be logged to the Flarum log. This may help with debugging OAuth issues, but may also contain sensitive information. only_icons_label: Only show the Log In Button icons (alternative layout) update_email_from_provider_label: Update email address from provider update_email_from_provider_help: If enabled, the user's email address will be updated to match the one provided by the OAuth provider on each login to the forum. Not all providers provide the updated email, in which case this setting will not have any effect with those providers. diff --git a/src/Controller.php b/src/Controller.php index 5eb6372..1546efe 100644 --- a/src/Controller.php +++ b/src/Controller.php @@ -12,18 +12,41 @@ namespace FoF\OAuth; use Exception; +use Flarum\Forum\Auth\ResponseFactory; use Flarum\Http\Exception\RouteNotFoundException; +use Flarum\Http\UrlGenerator; +use Flarum\Settings\SettingsRepositoryInterface; use FoF\Extend\Controllers\AbstractOAuthController; use FoF\OAuth\Errors\AuthenticationException; +use Illuminate\Contracts\Cache\Store as CacheStore; +use Illuminate\Contracts\Events\Dispatcher; use League\OAuth2\Client\Provider\Exception\IdentityProviderException; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; +use Psr\Log\LoggerInterface; abstract class Controller extends AbstractOAuthController { + /** + * @var SettingsRepositoryInterface + */ + protected $settings; + + public function __construct( + ResponseFactory $response, + SettingsRepositoryInterface $settings, + UrlGenerator $url, + Dispatcher $events, + CacheStore $cache, + ) { + parent::__construct($response, $settings, $url, $events, $cache); + + $this->settings = $settings; + } + protected function getRouteName(): string { - return 'auth.'.$this->getProviderName(); + return 'auth.' . $this->getProviderName(); } protected function getIdentifier($user): string @@ -40,13 +63,29 @@ protected function getIdentifier($user): string */ public function handle(ServerRequestInterface $request): ResponseInterface { - if (!(bool) (int) $this->settings->get('fof-oauth.'.$this->getProviderName())) { + if (!(bool) (int) $this->settings->get('fof-oauth.' . $this->getProviderName())) { throw new RouteNotFoundException(); } try { return parent::handle($request); } catch (Exception $e) { + if ((bool) $this->settings->get('fof-oauth.log-oauth-errors')) { + /** @var LoggerInterface $logger */ + $logger = resolve('log'); + $detail = json_encode([ + 'server_params' => $request->getServerParams(), + 'request_attrs' => $request->getAttributes(), + 'cookie_params' => $request->getCookieParams(), + 'query_params' => $request->getQueryParams(), + 'parsed_body' => $request->getParsedBody(), + 'code' => $e->getCode(), + 'trace' => $e->getTraceAsString(), + ], JSON_PRETTY_PRINT); + + $logger->error("[OAuth][{$this->getProviderName()}] {$e->getMessage()}: {$detail}"); + } + if ($e->getMessage() === 'Invalid state' || $e instanceof IdentityProviderException) { throw new AuthenticationException($e->getMessage()); }