You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

82 lines
2.8 KiB

<?php
namespace App\Security;
use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
use KnpU\OAuth2ClientBundle\Security\Authenticator\OAuth2Authenticator;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
class OpenStreetMapAuthenticator extends OAuth2Authenticator implements AuthenticationEntryPointInterface
{
public function __construct(
private ClientRegistry $clientRegistry,
private EntityManagerInterface $entityManager,
private RouterInterface $router,
) {
}
public function supports(Request $request): ?bool
{
return 'app_osm_callback' === $request->attributes->get('_route');
}
public function authenticate(Request $request): Passport
{
$client = $this->clientRegistry->getClient('openstreetmap');
$accessToken = $this->fetchAccessToken($client);
$session = $request->getSession();
$session->set('access_token', $accessToken);
return new SelfValidatingPassport(
new UserBadge($accessToken->getToken(), function () use ($accessToken, $client) {
$resourceOwner = $client->fetchUserFromToken($accessToken);
$existingUser = $this->entityManager->getRepository(User::class)->findOneBy(['osmId' => $resourceOwner->getId()]);
if ($existingUser) {
return $existingUser;
}
$user = new User();
$user->setOsmId($resourceOwner->getId());
$user->setUsername($resourceOwner->getDisplayName());
$this->entityManager->persist($user);
$this->entityManager->flush();
return $user;
})
);
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
{
return null;
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response
{
return null;
}
public function start(Request $request, ?AuthenticationException $authException = null): Response
{
return new RedirectResponse(
'/',
Response::HTTP_TEMPORARY_REDIRECT
);
}
}