Skip to content

Avoid class alias as a BC mechanism #308

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ parameters:
-
message: '/Symfony\\Component\\HttpKernel\\Event\\GetResponseForExceptionEvent.$/'
path: src/EventListener/ErrorListener.php
-
message: '/(GetResponseEvent|FilterControllerEvent)/'
path: src/EventListener/RequestListener.php
-
message: '/GetResponseEvent/'
path: src/EventListener/SubRequestListener.php

includes:
- vendor/jangregor/phpstan-prophecy/src/extension.neon
Expand Down
40 changes: 34 additions & 6 deletions src/DependencyInjection/SentryExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
use Sentry\Options;
use Sentry\SentryBundle\ErrorTypesParser;
use Sentry\SentryBundle\EventListener\ErrorListener;
use Sentry\SentryBundle\EventListener\RequestListener;
use Sentry\SentryBundle\EventListener\SubRequestListener;
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
Expand All @@ -17,7 +19,9 @@
use Symfony\Component\DependencyInjection\Loader;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\HttpKernel\Event\ControllerEvent;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;

/**
Expand All @@ -27,6 +31,8 @@
*/
class SentryExtension extends Extension
{
private const KERNEL_EVENT_LISTENER = 'kernel.event_listener';

/**
* {@inheritDoc}
*
Expand Down Expand Up @@ -165,18 +171,40 @@ private function configureErrorListener(ContainerBuilder $container, array $proc
*/
private function tagExceptionListener(ContainerBuilder $container): void
{
$listener = $container->getDefinition(ErrorListener::class);
$errorListener = $container->getDefinition(ErrorListener::class);
$method = class_exists(ExceptionEvent::class) && method_exists(ExceptionEvent::class, 'getThrowable')
? 'onException'
: 'onKernelException';

$tagAttributes = [
$errorListener->addTag(self::KERNEL_EVENT_LISTENER, [
'event' => KernelEvents::EXCEPTION,
'method' => $method,
'priority' => '%sentry.listener_priorities.request_error%',
];

$listener->addTag('kernel.event_listener', $tagAttributes);
]);

$requestListener = $container->getDefinition(RequestListener::class);
$requestListener->addTag(self::KERNEL_EVENT_LISTENER, [
'event' => KernelEvents::REQUEST,
'method' => class_exists(RequestEvent::class)
? 'onRequest'
: 'onKernelRequest',
'priority' => '%sentry.listener_priorities.request%',
]);
$requestListener->addTag(self::KERNEL_EVENT_LISTENER, [
'event' => KernelEvents::CONTROLLER,
'method' => class_exists(ControllerEvent::class)
? 'onController'
: 'onKernelController',
'priority' => '%sentry.listener_priorities.request%',
]);

$subrequestListener = $container->getDefinition(SubRequestListener::class);
$subrequestListener->addTag(self::KERNEL_EVENT_LISTENER, [
'event' => KernelEvents::REQUEST,
'method' => class_exists(RequestEvent::class)
? 'onRequest'
: 'onKernelRequest',
'priority' => '%sentry.listener_priorities.sub_request%',
]);
}

private function configureMonologHandler(ContainerBuilder $container, array $monologConfiguration): void
Expand Down
53 changes: 40 additions & 13 deletions src/EventListener/RequestListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,14 @@
use Sentry\SentrySdk;
use Sentry\State\HubInterface;
use Sentry\State\Scope;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\ControllerEvent;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\User\UserInterface;

if (! class_exists(RequestEvent::class)) {
class_alias(GetResponseEvent::class, RequestEvent::class);
}

if (! class_exists(ControllerEvent::class)) {
class_alias(FilterControllerEvent::class, ControllerEvent::class);
}

/**
* Class RequestListener
* @package Sentry\SentryBundle\EventListener
Expand Down Expand Up @@ -50,12 +43,29 @@ public function __construct(
*
* @param RequestEvent $event
*/
public function onKernelRequest(RequestEvent $event): void
public function onRequest(RequestEvent $event): void
{
if (! $event->isMasterRequest()) {
return;
}

$this->handleRequestEvent($event->getRequest());
}

/**
* BC layer for SF < 4.3
*/
public function onKernelRequest(GetResponseEvent $event): void
{
if (! $event->isMasterRequest()) {
return;
}

$this->handleRequestEvent($event->getRequest());
}

private function handleRequestEvent(Request $request): void
{
$currentClient = SentrySdk::getCurrentHub()->getClient();
if (null === $currentClient || ! $currentClient->getOptions()->shouldSendDefaultPii()) {
return;
Expand All @@ -77,25 +87,42 @@ public function onKernelRequest(RequestEvent $event): void
$userData = $this->getUserData($token->getUser());
}

$userData['ip_address'] = $event->getRequest()->getClientIp();
$userData['ip_address'] = $request->getClientIp();

SentrySdk::getCurrentHub()
->configureScope(function (Scope $scope) use ($userData): void {
$scope->setUser($userData, true);
});
}

public function onKernelController(ControllerEvent $event): void
public function onController(ControllerEvent $event): void
{
if (! $event->isMasterRequest()) {
return;
}

$this->handleControllerEvent($event->getRequest());
}

/**
* BC layer for SF < 4.3
*/
public function onKernelController(FilterControllerEvent $event): void
{
if (! $event->isMasterRequest()) {
return;
}

if (! $event->getRequest()->attributes->has('_route')) {
$this->handleControllerEvent($event->getRequest());
}

private function handleControllerEvent(Request $request): void
{
if (! $request->attributes->has('_route')) {
return;
}

$matchedRoute = (string) $event->getRequest()->attributes->get('_route');
$matchedRoute = (string)$request->attributes->get('_route');

SentrySdk::getCurrentHub()
->configureScope(function (Scope $scope) use ($matchedRoute): void {
Expand Down
20 changes: 14 additions & 6 deletions src/EventListener/SubRequestListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,26 @@
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Event\RequestEvent;

if (! class_exists(RequestEvent::class)) {
class_alias(GetResponseEvent::class, RequestEvent::class);
}

final class SubRequestListener
{
/**
* Pushes a new {@see Scope} for each SubRequest
*
* @param RequestEvent $event
*/
public function onKernelRequest(RequestEvent $event): void
public function onRequest(RequestEvent $event): void
{
if ($event->isMasterRequest()) {
return;
}

SentrySdk::getCurrentHub()->pushScope();
}

/**
* BC layer for SF < 4.3
*/
public function onKernelRequest(GetResponseEvent $event): void
{
if ($event->isMasterRequest()) {
return;
Expand All @@ -32,7 +40,7 @@ public function onKernelRequest(RequestEvent $event): void
*
* @param FinishRequestEvent $event
*/
public function onKernelFinishRequest(FinishRequestEvent $event): void
public function onFinishRequest(FinishRequestEvent $event): void
{
if ($event->isMasterRequest()) {
return;
Expand Down
10 changes: 6 additions & 4 deletions src/Resources/config/services.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,15 @@
<argument type="service" id="Sentry\State\HubInterface" />
<argument type="service" id="security.token_storage" on-invalid="ignore" />

<tag name="kernel.event_listener" event="kernel.request" method="onKernelRequest" priority="%sentry.listener_priorities.request%" />
<tag name="kernel.event_listener" event="kernel.controller" method="onKernelController" priority="%sentry.listener_priorities.request%" />
<!-- The following tags are done manually in PHP for BC with Symfony < 4.3, -->
<!-- <tag name="kernel.event_listener" event="kernel.request" method="onRequest" priority="%sentry.listener_priorities.request%" />-->
<!-- <tag name="kernel.event_listener" event="kernel.controller" method="onController" priority="%sentry.listener_priorities.request%" />-->
</service>

<service id="Sentry\SentryBundle\EventListener\SubRequestListener" class="Sentry\SentryBundle\EventListener\SubRequestListener" public="false">
<tag name="kernel.event_listener" event="kernel.request" method="onKernelRequest" priority="%sentry.listener_priorities.sub_request%" />
<tag name="kernel.event_listener" event="kernel.finish_request" method="onKernelFinishRequest" priority="%sentry.listener_priorities.sub_request%" />
<!-- The following tag is done manually in PHP for BC with Symfony < 4.3, -->
<!-- <tag name="kernel.event_listener" event="kernel.request" method="onRequest" priority="%sentry.listener_priorities.sub_request%" />-->
<tag name="kernel.event_listener" event="kernel.finish_request" method="onFinishRequest" priority="%sentry.listener_priorities.sub_request%" />
</service>

<service id="Sentry\SentryBundle\Command\SentryTestCommand" class="Sentry\SentryBundle\Command\SentryTestCommand" public="false">
Expand Down
39 changes: 29 additions & 10 deletions test/EventListener/RequestListenerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\ControllerEvent;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
Expand Down Expand Up @@ -79,7 +80,7 @@ public function testOnKernelRequestUserDataIsSetToScope($user): void
$tokenStorage->reveal()
);

$listener->onKernelRequest($event);
$this->callOnRequest($listener, $event);

$expectedUserData = [
'ip_address' => '1.2.3.4',
Expand Down Expand Up @@ -110,7 +111,7 @@ public function testOnKernelRequestUserDataIsNotSetIfSendPiiIsDisabled(): void
$tokenStorage->reveal()
);

$listener->onKernelRequest($event);
$this->callOnRequest($listener, $event);

$this->assertEquals([], $this->getUserContext($this->currentScope));
}
Expand All @@ -130,7 +131,7 @@ public function testOnKernelRequestUserDataIsNotSetIfNoClientIsPresent(): void
$tokenStorage->reveal()
);

$listener->onKernelRequest($event);
$this->callOnRequest($listener, $event);

$this->assertEquals([], $this->getUserContext($this->currentScope));
}
Expand All @@ -148,7 +149,7 @@ public function testOnKernelRequestUsernameIsNotSetIfTokenStorageIsAbsent(): voi
null
);

$listener->onKernelRequest($event);
$this->callOnRequest($listener, $event);

$expectedUserData = [
'ip_address' => '1.2.3.4',
Expand All @@ -173,7 +174,7 @@ public function testOnKernelRequestUsernameIsNotSetIfTokenIsAbsent(): void
$tokenStorage->reveal()
);

$listener->onKernelRequest($event);
$this->callOnRequest($listener, $event);

$expectedUserData = [
'ip_address' => '1.2.3.4',
Expand Down Expand Up @@ -205,7 +206,7 @@ public function testOnKernelRequestUsernameIsNotSetIfTokenIsNotAuthenticated():
$tokenStorage->reveal()
);

$listener->onKernelRequest($event);
$this->callOnRequest($listener, $event);

$expectedUserData = [
'ip_address' => '1.2.3.4',
Expand All @@ -230,7 +231,7 @@ public function testOnKernelRequestUsernameIsNotSetIfUserIsNotRemembered(): void
$tokenStorage->reveal()
);

$listener->onKernelRequest($event);
$this->callOnRequest($listener, $event);

$expectedUserData = [
'ip_address' => '1.2.3.4',
Expand All @@ -249,7 +250,7 @@ public function testOnKernelControllerAddsRouteTag(): void
$this->prophesize(TokenStorageInterface::class)->reveal()
);

$listener->onKernelController($event);
$this->callOnKernel($listener, $event);

$this->assertSame(['route' => 'sf-route'], $this->getTagsContext($this->currentScope));
}
Expand All @@ -266,7 +267,7 @@ public function testOnKernelControllerRouteTagIsNotSetIfRequestDoesNotHaveARoute
$this->prophesize(TokenStorageInterface::class)->reveal()
);

$listener->onKernelController($event);
$this->callOnKernel($listener, $event);
}

public function testOnKernelRequestUserDataAndTagsAreNotSetInSubRequest(): void
Expand All @@ -285,7 +286,7 @@ public function testOnKernelRequestUserDataAndTagsAreNotSetInSubRequest(): void
$tokenStorage->reveal()
);

$listener->onKernelRequest($event);
$this->callOnRequest($listener, $event);

$this->assertEmpty($this->getUserContext($this->currentScope));
$this->assertEmpty($this->getTagsContext($this->currentScope));
Expand Down Expand Up @@ -327,6 +328,24 @@ private function createControllerEvent(Request $request)

return $event;
}

private function callOnRequest(RequestListener $listener, $event): void
{
if (class_exists(RequestEvent::class)) {
$listener->onRequest($event);
} else {
$listener->onKernelRequest($event);
}
}

private function callOnKernel(RequestListener $listener, $event): void
{
if (class_exists(ControllerEvent::class)) {
$listener->onController($event);
} else {
$listener->onKernelController($event);
}
}
}

class UserWithInterface implements UserInterface
Expand Down
Loading