WIP
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
namespace App\Security;
|
||||
|
||||
use App\BusProNet\ApiClient;
|
||||
use App\BusProNet\ApiClientException;
|
||||
use App\BusProNet\Model\ErrorResponse;
|
||||
use App\BusProNet\Model\Profile;
|
||||
use App\Entity\User;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Http\Authenticator\AbstractLoginFormAuthenticator;
|
||||
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\CsrfTokenBadge;
|
||||
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;
|
||||
use Symfony\Component\Security\Http\Util\TargetPathTrait;
|
||||
|
||||
class BpnAuthenticator extends AbstractLoginFormAuthenticator implements AuthenticationEntryPointInterface
|
||||
{
|
||||
use TargetPathTrait;
|
||||
|
||||
public function __construct(
|
||||
private readonly UrlGeneratorInterface $urlGenerator,
|
||||
private readonly EntityManagerInterface $entityManager,
|
||||
private readonly ApiClient $apiClient,
|
||||
private readonly LoggerInterface $logger
|
||||
) {
|
||||
}
|
||||
|
||||
protected function getLoginUrl(Request $request): string
|
||||
{
|
||||
return $this->urlGenerator->generate('app_security_login');
|
||||
}
|
||||
|
||||
public function authenticate(Request $request): Passport
|
||||
{
|
||||
$email = trim($request->request->get('_username', ''));
|
||||
$password = trim($request->request->get('_password', ''));
|
||||
$csrfToken = $request->request->get('_csrf_token', '');
|
||||
|
||||
return new SelfValidatingPassport(
|
||||
new UserBadge($email, function () use ($email, $password) {
|
||||
try {
|
||||
$response = $this->apiClient->getProfile($email, $password);
|
||||
} catch (ApiClientException $e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($response instanceof ErrorResponse) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->getOrCreateLocalUser($response, $email, $password);
|
||||
}),
|
||||
[new CsrfTokenBadge('authenticate', $csrfToken)]
|
||||
);
|
||||
}
|
||||
|
||||
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = $token->getUser();
|
||||
|
||||
$user->setLastLoginAt(new \DateTimeImmutable());
|
||||
|
||||
$this->entityManager->flush();
|
||||
|
||||
if ($targetPath = $this->getTargetPath($request->getSession(), $firewallName)) {
|
||||
return new RedirectResponse($targetPath);
|
||||
}
|
||||
|
||||
$url = $this->urlGenerator->generate($user->getDefaultRoute());
|
||||
|
||||
return new RedirectResponse($url);
|
||||
}
|
||||
|
||||
private function getOrCreateLocalUser(Profile $profile, string $email, string $password): User
|
||||
{
|
||||
$repository = $this->entityManager->getRepository(User::class);
|
||||
|
||||
$user = $repository->findOneBy([
|
||||
'busProAddressId' => $profile->getAddressId(),
|
||||
'busProPersonId' => $profile->getPersonId(),
|
||||
]);
|
||||
|
||||
if (null !== $user) {
|
||||
return $user;
|
||||
}
|
||||
|
||||
try {
|
||||
$response = $this->apiClient->getCrmSelection($email, $password);
|
||||
} catch (ApiClientException $e) {
|
||||
}
|
||||
|
||||
$user = new User();
|
||||
$user
|
||||
->setBusProAddressId($profile->getAddressId())
|
||||
->setBusProPersonId($profile->getPersonId())
|
||||
->setRole('ROLE_FOO')
|
||||
->setEmail($profile->getCommunication()->getEmail())
|
||||
->setFirstName($profile->getFirstName())
|
||||
->setLastName($profile->getName())
|
||||
;
|
||||
|
||||
$this->entityManager->persist($user);
|
||||
$this->entityManager->flush();
|
||||
|
||||
return $user;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user