|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
declare(strict_types=1); |
|
4
|
|
|
|
|
5
|
|
|
namespace Acme\App\Infrastructure\Auth\Authentication\Oauth; |
|
6
|
|
|
|
|
7
|
|
|
use Acme\App\Core\Port\Auth\Authentication\Oauth\OauthProtectedControllerInterface; |
|
8
|
|
|
use Exception; |
|
9
|
|
|
use League\OAuth2\Server\Exception\OAuthServerException; |
|
10
|
|
|
use League\OAuth2\Server\ResourceServer; |
|
11
|
|
|
use Psr\Http\Message\ServerRequestInterface; |
|
12
|
|
|
use Symfony\Bridge\PsrHttpMessage\Factory\DiactorosFactory; |
|
13
|
|
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface; |
|
14
|
|
|
use Symfony\Component\HttpFoundation\JsonResponse; |
|
15
|
|
|
use Symfony\Component\HttpFoundation\Request; |
|
16
|
|
|
use Symfony\Component\HttpFoundation\Response; |
|
17
|
|
|
use Symfony\Component\HttpKernel\Event\FilterControllerEvent; |
|
18
|
|
|
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; |
|
19
|
|
|
use Symfony\Component\HttpKernel\KernelEvents; |
|
20
|
|
|
use function is_array; |
|
21
|
|
|
|
|
22
|
|
|
final class OauthProtectedControllerSubscriber implements EventSubscriberInterface |
|
23
|
|
|
{ |
|
24
|
|
|
private const DEFAULT_PRIORITY = 20; |
|
25
|
|
|
|
|
26
|
|
|
/** |
|
27
|
|
|
* @var ResourceServer |
|
28
|
|
|
*/ |
|
29
|
|
|
private $resourceServer; |
|
30
|
|
|
|
|
31
|
|
|
public function __construct(ResourceServer $resourceServer) |
|
32
|
|
|
{ |
|
33
|
|
|
$this->resourceServer = $resourceServer; |
|
34
|
|
|
} |
|
35
|
|
|
|
|
36
|
|
|
/** |
|
37
|
|
|
* Return the subscribed events, their methods and possibly their priorities |
|
38
|
|
|
* (the higher the priority the earlier the method is called). |
|
39
|
|
|
* |
|
40
|
|
|
* @see http://symfony.com/doc/current/event_dispatcher.html#creating-an-event-subscriber |
|
41
|
|
|
*/ |
|
42
|
|
|
public static function getSubscribedEvents(): array |
|
43
|
|
|
{ |
|
44
|
|
|
return [ |
|
45
|
|
|
KernelEvents::CONTROLLER => ['onKernelController', self::DEFAULT_PRIORITY], |
|
46
|
|
|
KernelEvents::EXCEPTION => ['onKernelException', self::DEFAULT_PRIORITY], |
|
47
|
|
|
]; |
|
48
|
|
|
} |
|
49
|
|
|
|
|
50
|
|
|
/** |
|
51
|
|
|
* @throws OAuthServerException |
|
52
|
|
|
*/ |
|
53
|
|
|
public function onKernelController(FilterControllerEvent $event): void |
|
54
|
|
|
{ |
|
55
|
|
|
$controller = $event->getController(); |
|
56
|
|
|
/* |
|
57
|
|
|
* $controller passed can be either a class or a Closure. |
|
58
|
|
|
* This is not usual in Symfony but it may happen. |
|
59
|
|
|
* If it is a class, it comes in array format |
|
60
|
|
|
*/ |
|
61
|
|
|
if (!is_array($controller)) { |
|
62
|
|
|
return; |
|
63
|
|
|
} |
|
64
|
|
|
if ($controller[0] instanceof OauthProtectedControllerInterface) { |
|
65
|
|
|
$request = $event->getRequest(); |
|
66
|
|
|
$psrRequest = (new DiactorosFactory)->createRequest($request); |
|
67
|
|
|
try { |
|
68
|
|
|
$psrRequest = $this->resourceServer->validateAuthenticatedRequest($psrRequest); |
|
69
|
|
|
} catch (OAuthServerException $exception) { |
|
|
|
|
|
|
70
|
|
|
throw $exception; |
|
71
|
|
|
} catch (Exception $exception) { |
|
72
|
|
|
throw new OAuthServerException( |
|
73
|
|
|
$exception->getMessage(), |
|
74
|
|
|
0, |
|
75
|
|
|
'unknown_error', |
|
76
|
|
|
Response::HTTP_INTERNAL_SERVER_ERROR |
|
77
|
|
|
); |
|
78
|
|
|
} |
|
79
|
|
|
$this->enrichSymfonyRequestWithAuthData($request, $psrRequest); |
|
80
|
|
|
} |
|
81
|
|
|
} |
|
82
|
|
|
|
|
83
|
|
|
private function enrichSymfonyRequestWithAuthData(Request $request, ServerRequestInterface $psrRequest): void |
|
84
|
|
|
{ |
|
85
|
|
|
$request = $request->request; |
|
86
|
|
|
$requestArray = $request->all(); |
|
87
|
|
|
$requestArray['oauth_user_id'] = $psrRequest->getAttribute('oauth_user_id'); |
|
88
|
|
|
$requestArray['oauth_access_token_id'] = $psrRequest->getAttribute('oauth_access_token_id'); |
|
89
|
|
|
$requestArray['oauth_client_id'] = $psrRequest->getAttribute('oauth_client_id'); |
|
90
|
|
|
$request->replace($requestArray); |
|
91
|
|
|
} |
|
92
|
|
|
|
|
93
|
|
|
public function onKernelException(GetResponseForExceptionEvent $event): void |
|
94
|
|
|
{ |
|
95
|
|
|
$exception = $event->getException(); |
|
96
|
|
|
if (!$exception instanceof OAuthServerException) { |
|
|
|
|
|
|
97
|
|
|
return; |
|
98
|
|
|
} |
|
99
|
|
|
$response = new JsonResponse(['error' => $exception->getMessage()], $exception->getHttpStatusCode()); |
|
100
|
|
|
$event->setResponse($response); |
|
101
|
|
|
} |
|
102
|
|
|
} |
|
103
|
|
|
|
Scrutinizer analyzes your
composer.json/composer.lockfile if available to determine the classes, and functions that are defined by your dependencies.It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.