<?php
namespace App\Listener;
use Nyholm\Psr7\Response;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Trikoder\Bundle\OAuth2Bundle\Event\AuthorizationRequestResolveEvent;
use Symfony\Component\Security\Core\Security;
use Twig\Environment;
final class AuthorizationCodeListener
{
private $urlGenerator;
private $requestStack;
private $twig;
public function __construct(
UrlGeneratorInterface $urlGenerator,
RequestStack $requestStack,
Environment $twig,
Security $security
) {
$this->urlGenerator = $urlGenerator;
$this->requestStack = $requestStack;
$this->twig = $twig;
$this->security = $security;
}
public function onAuthorizationRequestResolve(AuthorizationRequestResolveEvent $event): void
{
$request = $this->requestStack->getCurrentRequest();
// only handle post requests for logged-in users:
// get requests will be intercepted and shown the login form
// other verbs we will handle as an authorization denied
// and this implementation ensures a user is set at this point already
if (!\Empire\Core\Login::isLoggedIn()) {
$event->setResponse(
new Response(
302,
[
'Location' => $this->urlGenerator->generate(
'login',
[
'client' => "Forum",
'returnUrl' => $this->requestStack->getMasterRequest()->getUri(),
]
),
]
)
);
return;
}
if (!$request->request->has('action')) {
// 1. successful login, goes to grant page
$user = $this->security->getUser()->initialize();
preg_match('~https?:\/\/(.*?[^\/])/~s', $request->query->get('redirect_uri'), $cancelUrl);
$content = $this->twig->render('security/grant.html.twig', [
'scopes' => $event->getScopes(),
'client' => $event->getClient(),
'grant' => AuthorizationRequestResolveEvent::AUTHORIZATION_APPROVED,
// very simple way to ensure user gets to this point in the
// flow when granting or denying is to pre-add their credentials
'name' => $request->request->get('name'),
'cancelUrl' => $cancelUrl[0],
'user' => $user,
]);
$response = new Response(200, [], $content);
$event->setResponse($response);
} else {
// 2. grant operation, either grants or denies
if ($request->request->get('action') == AuthorizationRequestResolveEvent::AUTHORIZATION_APPROVED) {
$event->resolveAuthorization(AuthorizationRequestResolveEvent::AUTHORIZATION_APPROVED);
} else {
$event->resolveAuthorization(AuthorizationRequestResolveEvent::AUTHORIZATION_DENIED);
}
}
}
}