Skip to content

Commit

Permalink
IBX-5293: Added event dispatcher in default success handler (#215)
Browse files Browse the repository at this point in the history
  • Loading branch information
ViniTou committed Mar 27, 2023
1 parent af9fdfa commit 7c0b3d0
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 7 deletions.
4 changes: 4 additions & 0 deletions src/bundle/Core/DependencyInjection/Compiler/SecurityPass.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ public function process(ContainerBuilder $container)
'setConfigResolver',
[$configResolverRef]
);
$successHandlerDef->addMethodCall(
'setEventDispatcher',
[new Reference('event_dispatcher')]
);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,46 @@
namespace Ibexa\Core\MVC\Symfony\Security\Authentication;

use Ibexa\Contracts\Core\SiteAccess\ConfigResolverInterface;
use Psr\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationSuccessHandler as BaseSuccessHandler;

class DefaultAuthenticationSuccessHandler extends BaseSuccessHandler
{
private EventDispatcherInterface $eventDispatcher;

private ConfigResolverInterface $configResolver;

/**
* Injects the ConfigResolver to potentially override default_target_path for redirections after authentication success.
*
* @param \Ibexa\Contracts\Core\SiteAccess\ConfigResolverInterface $configResolver
*/
public function setConfigResolver(ConfigResolverInterface $configResolver)
public function setConfigResolver(ConfigResolverInterface $configResolver): void
{
$this->configResolver = $configResolver;
}

public function setEventDispatcher(EventDispatcherInterface $eventDispatcher): void
{
$this->eventDispatcher = $eventDispatcher;
}

protected function determineTargetUrl(Request $request)
{
$defaultPage = $configResolver->getParameter('default_page');
if ($defaultPage !== null) {
$this->options['default_target_path'] = $defaultPage;
if (isset($this->configResolver)) {
$defaultPage = $this->configResolver->getParameter('default_page');
if ($defaultPage !== null) {
$this->options['default_target_path'] = $defaultPage;
}
}

if (isset($this->eventDispatcher)) {
$event = new DetermineTargetUrlEvent($request, $this->options, $this->getFirewallName());
$this->eventDispatcher->dispatch($event);

$this->options = $event->getOptions();
}

return parent::determineTargetUrl($request);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Core\MVC\Symfony\Security\Authentication;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Contracts\EventDispatcher\Event;

final class DetermineTargetUrlEvent extends Event
{
private Request $request;

private string $firewallName;

/** @var array<string, mixed> */
private array $options;

/**
* @param array<string, mixed> $options
**/
public function __construct(
Request $request,
array $options,
string $firewallName
) {
$this->request = $request;
$this->firewallName = $firewallName;
$this->options = $options;
}

public function getRequest(): Request
{
return $this->request;
}

public function getFirewallName(): string
{
return $this->firewallName;
}

/** @return array<string, mixed> */
public function getOptions(): array
{
return $this->options;
}

/** @param array<string, mixed> $options */
public function setOptions(array $options): void
{
$this->options = $options;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,29 @@
use Ibexa\Contracts\Core\SiteAccess\ConfigResolverInterface;
use Ibexa\Core\MVC\Symfony\Security\Authentication\DefaultAuthenticationSuccessHandler;
use Ibexa\Core\MVC\Symfony\Security\HttpUtils;
use Ibexa\Core\MVC\Symfony\SiteAccess;
use Ibexa\Core\MVC\Symfony\SiteAccess\Matcher;
use PHPUnit\Framework\TestCase;
use ReflectionObject;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;

class DefaultAuthenticationSuccessHandlerTest extends TestCase
{
public function testSetConfigResolver()
{
$successHandler = new DefaultAuthenticationSuccessHandler(new HttpUtils(), []);
$siteAccess = new SiteAccess(
'test',
SiteAccess::DEFAULT_MATCHING_TYPE,
$this->createMock(Matcher::class)
);
$httpUtils = new HttpUtils();
$httpUtils->setSiteAccess($siteAccess);
$successHandler = new DefaultAuthenticationSuccessHandler($httpUtils, []);
$successHandler->setFirewallName('test_firewall');

$refHandler = new ReflectionObject($successHandler);
$refOptions = $refHandler->getProperty('options');
$refOptions->setAccessible(true);
Expand All @@ -31,6 +46,18 @@ public function testSetConfigResolver()
->with('default_page')
->will($this->returnValue($defaultPage));
$successHandler->setConfigResolver($configResolver);
$successHandler->setEventDispatcher($this->createMock(EventDispatcherInterface::class));

$request = $this->createMock(Request::class);
$request
->method('getSession')
->willReturn($this->createMock(Session::class));

$request
->method('getUriForPath')
->willReturn($defaultPage);

$successHandler->onAuthenticationSuccess($request, $this->createMock(TokenInterface::class));
$options = $refOptions->getValue($successHandler);
$this->assertSame($defaultPage, $options['default_target_path']);
}
Expand Down

0 comments on commit 7c0b3d0

Please sign in to comment.