From f796e0a4f4e8e7c0c93b497e32868299870e4a99 Mon Sep 17 00:00:00 2001 From: tuutti Date: Mon, 7 Nov 2022 12:56:31 +0200 Subject: [PATCH] UHF-4826: Automatically detect Tunnistamo return URL --- .github/workflows/ci.yml | 3 + composer.json | 4 +- helfi_proxy.services.yml | 6 - .../TunnistamoRedirectUrlSubscriber.php | 37 ++++-- src/HelfiProxyServiceProvider.php | 34 +++++ src/ProxyManagerInterface.php | 7 -- .../TunnistamoRedirectUrlSubscriberTest.php | 116 ++++++++++++++++++ .../Unit/RedirectResponseSubscriberTest.php | 2 +- 8 files changed, 182 insertions(+), 27 deletions(-) create mode 100644 src/HelfiProxyServiceProvider.php create mode 100644 tests/src/Kernel/TunnistamoRedirectUrlSubscriberTest.php diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bf055a6..d5d27f1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,6 +6,7 @@ env: DRUPAL_CORE_VERSION: 9.3.x SYMFONY_DEPRECATIONS_HELPER: disabled BROWSERTEST_OUTPUT_DIRECTORY: 'sites/simpletest' + OPTIONAL_DEPENDENCIES: drupal/helfi_tunnistamo drupal/redirect jobs: tests: runs-on: ubuntu-latest @@ -52,6 +53,8 @@ jobs: composer config --no-plugins allow-plugins.dealerdirect/phpcodesniffer-composer-installer true composer require --dev donatj/mock-webserver composer require --dev "drupal/coder" + # Install defined optional dependencies. + composer require $OPTIONAL_DEPENDENCIES -W - name: Install Drupal run: | diff --git a/composer.json b/composer.json index c61aede..2395575 100644 --- a/composer.json +++ b/composer.json @@ -9,10 +9,12 @@ "drupal/purge": "^3.0", "drupal/varnish_purge": "^2.1", "drupal/helfi_api_base": "*", - "drupal/redirect": "^1.0", "ext-libxml": "*", "ext-dom": "*" }, + "conflict": { + "drupal/helfi_tunnistamo": "<=2.2.1" + }, "require-dev": { "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", "drupal/coder": "^8.3", diff --git a/helfi_proxy.services.yml b/helfi_proxy.services.yml index c0c04d8..29722f3 100644 --- a/helfi_proxy.services.yml +++ b/helfi_proxy.services.yml @@ -39,12 +39,6 @@ services: tags: - { name: cache.context } - helfi_proxy.tunnistamo_redirect_subscriber: - class: Drupal\helfi_proxy\EventSubscriber\TunnistamoRedirectUrlSubscriber - arguments: ['@helfi_proxy.proxy_manager'] - tags: - - { name: event_subscriber } - helfi_proxy.proxy_manager: class: Drupal\helfi_proxy\ProxyManager arguments: ['@config.factory'] diff --git a/src/EventSubscriber/TunnistamoRedirectUrlSubscriber.php b/src/EventSubscriber/TunnistamoRedirectUrlSubscriber.php index 714261a..59745a3 100644 --- a/src/EventSubscriber/TunnistamoRedirectUrlSubscriber.php +++ b/src/EventSubscriber/TunnistamoRedirectUrlSubscriber.php @@ -4,43 +4,59 @@ namespace Drupal\helfi_proxy\EventSubscriber; +use Drupal\Core\Language\LanguageManagerInterface; use Drupal\Core\Url; +use Drupal\helfi_proxy\ActiveSitePrefix; use Drupal\helfi_proxy\ProxyManagerInterface; use Drupal\helfi_tunnistamo\Event\RedirectUrlEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** - * Tunnistamo redirect url subscriber. - * - * @phpcs:ignore - * @deprecated in helfi_proxy:2.1.2 and is removed from helfi_proxy:3.0.0. + * Tunnistamo return url subscriber. */ final class TunnistamoRedirectUrlSubscriber implements EventSubscriberInterface { /** * Constructs a new instance. * + * @param \Drupal\Core\Language\LanguageManagerInterface $languageManager + * The language manager. * @param \Drupal\helfi_proxy\ProxyManagerInterface $proxyManager * The proxy manager. + * @param \Drupal\helfi_proxy\ActiveSitePrefix $prefix + * The active site prefix service. */ public function __construct( - private ProxyManagerInterface $proxyManager + private LanguageManagerInterface $languageManager, + private ProxyManagerInterface $proxyManager, + private ActiveSitePrefix $prefix, ) { } /** - * Responds to tunnistamo redirect url event. + * Responds to Tunnistamo redirect url event. * * @param \Drupal\helfi_tunnistamo\Event\RedirectUrlEvent $event * Response event. */ public function onRedirectUrlEvent(RedirectUrlEvent $event) : void { - if (!$url = $this->proxyManager->getConfig(ProxyManagerInterface::TUNNISTAMO_RETURN_URL)) { + $returnUrl = $this->proxyManager->getConfig(ProxyManagerInterface::TUNNISTAMO_RETURN_URL); + + $uriOptions = []; + // Fallback to automatically constructed return url if return url is not + // defined. + if (!$returnUrl && $activePrefix = $this->prefix->getPrefix('fi')) { + $uriOptions['language'] = $this->languageManager->getLanguage('fi'); + // Tunnistamo return URL is always configured to use /fi prefix. + $returnUrl = sprintf('/fi/%s/openid-connect/%s', $activePrefix, $event->getClient()->getPluginId()); + } + + if (!$returnUrl) { return; } try { - $event->setRedirectUrl(Url::fromUserInput($url)->setAbsolute()); + $event->setRedirectUrl(Url::fromUserInput($returnUrl, $uriOptions)->setAbsolute()); } catch (\InvalidArgumentException $e) { } @@ -50,11 +66,8 @@ public function onRedirectUrlEvent(RedirectUrlEvent $event) : void { * {@inheritdoc} */ public static function getSubscribedEvents() : array { - if (!class_exists('\Drupal\helfi_tunnistamo\Event\RedirectUrlEvent')) { - return []; - } return [ - 'Drupal\helfi_tunnistamo\Event\RedirectUrlEvent' => ['onRedirectUrlEvent'], + RedirectUrlEvent::class => ['onRedirectUrlEvent'], ]; } diff --git a/src/HelfiProxyServiceProvider.php b/src/HelfiProxyServiceProvider.php new file mode 100644 index 0000000..dc7a147 --- /dev/null +++ b/src/HelfiProxyServiceProvider.php @@ -0,0 +1,34 @@ +getParameter('container.modules'); + + if (isset($modules['helfi_tunnistamo'])) { + $container->register('helfi_proxy.tunnistamo_redirect_subscriber', TunnistamoRedirectUrlSubscriber::class) + ->addTag('event_subscriber') + ->addArgument(new Reference('language_manager')) + ->addArgument(new Reference('helfi_proxy.proxy_manager')) + ->addArgument(new Reference('helfi_proxy.active_prefix')); + } + } + +} diff --git a/src/ProxyManagerInterface.php b/src/ProxyManagerInterface.php index 34255a2..e04229c 100644 --- a/src/ProxyManagerInterface.php +++ b/src/ProxyManagerInterface.php @@ -18,13 +18,6 @@ interface ProxyManagerInterface { public const DEFAULT_PROXY_DOMAIN = 'default_proxy_domain'; public const SESSION_SUFFIX = 'session_suffix'; public const ROBOTS_HEADER_ENABLED = 'robots_header_enabled'; - - /** - * The tunnistamo return url config name. - * - * @phpcs:ignore - * @deprecated in helfi_proxy:2.1.2 and is removed from helfi_proxy:3.0.0. - */ public const TUNNISTAMO_RETURN_URL = 'tunnistamo_return_url'; /** diff --git a/tests/src/Kernel/TunnistamoRedirectUrlSubscriberTest.php b/tests/src/Kernel/TunnistamoRedirectUrlSubscriberTest.php new file mode 100644 index 0000000..f252a65 --- /dev/null +++ b/tests/src/Kernel/TunnistamoRedirectUrlSubscriberTest.php @@ -0,0 +1,116 @@ +getDefinition('path_alias.path_processor') + ->addTag('path_processor_inbound') + ->addTag('path_processor_outbound'); + } + + /** + * {@inheritdoc} + */ + public function setUp() : void { + parent::setUp(); + + $this->installEntitySchema('user'); + $this->installEntitySchema('path_alias'); + User::create([ + 'name' => '', + 'uid' => 0, + ])->save(); + $this->installConfig(['language', 'helfi_tunnistamo']); + + foreach (['fi', 'sv'] as $langcode) { + ConfigurableLanguage::createFromLangcode($langcode)->save(); + } + $this->config('helfi_proxy.settings') + ->set('prefixes', [ + 'sv' => 'prefix-sv', + 'en' => 'prefix-en', + 'fi' => 'prefix-fi', + ]) + ->save(); + + $this->config('language.negotiation') + ->set('url.prefixes', ['en' => 'en', 'fi' => 'fi', 'sv' => 'sv']) + ->save(); + + \Drupal::service('kernel')->rebuildContainer(); + } + + /** + * Gets the Tunnistamo redirect url. + * + * @return string + * The redirect url. + */ + private function getRedirectUri() : string { + $client = OpenIDConnectClientEntity::load('tunnistamo')->getPlugin(); + $url = $client->authorize()->getTargetUrl(); + parse_str(parse_url($url, PHP_URL_QUERY), $query); + + return $query['redirect_uri']; + } + + /** + * Make sure manually configured URL is preferred over automatic detection. + */ + public function testReturnUrl() : void { + $this->config('helfi_proxy.settings') + ->set(ProxyManagerInterface::TUNNISTAMO_RETURN_URL, '/fi/jotain/openid-connect/tunnistamo') + ->save(); + $this->assertEquals('http://localhost/fi/jotain/openid-connect/tunnistamo', $this->getRedirectUri()); + } + + /** + * Make sure automatically determine return URL is used as fallback. + */ + public function testFallbackReturnUrl() : void { + $this->assertEquals('http://localhost/fi/prefix-fi/openid-connect/tunnistamo', $this->getRedirectUri()); + } + +} diff --git a/tests/src/Unit/RedirectResponseSubscriberTest.php b/tests/src/Unit/RedirectResponseSubscriberTest.php index adf59f0..b1cfd5d 100644 --- a/tests/src/Unit/RedirectResponseSubscriberTest.php +++ b/tests/src/Unit/RedirectResponseSubscriberTest.php @@ -15,7 +15,7 @@ use Symfony\Component\HttpKernel\HttpKernelInterface; /** - * Tests asset middleware. + * Tests redirect response subscriber. * * @coversDefaultClass \Drupal\helfi_proxy\EventSubscriber\RedirectResponseSubscriber * @group helfi_proxy