WIP
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
|
||||
namespace App\BusProNet;
|
||||
|
||||
use App\BusProNet\Model\CrmAttributeSelection;
|
||||
use App\BusProNet\Model\Profile;
|
||||
use App\BusProNet\Model\ErrorResponse;
|
||||
use App\BusProNet\Model\Result;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
use Symfony\Component\Serializer\SerializerInterface;
|
||||
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
|
||||
class ApiClient
|
||||
{
|
||||
private array $config;
|
||||
|
||||
public function __construct(
|
||||
private readonly HttpClientInterface $httpClient,
|
||||
private readonly SerializerInterface $serializer,
|
||||
array $options
|
||||
) {
|
||||
$this->config = $this->resolveOptions($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ApiClientException
|
||||
*/
|
||||
public function getProfile(string $email, string $password): mixed
|
||||
{
|
||||
$data = [
|
||||
'anfrage' => [
|
||||
'user' => $this->config['bpn_username'],
|
||||
'key' => $this->createKey($this->config['bpn_username'], $this->config['bpn_password'], 'KUNDENKONTO'),
|
||||
'satz' => ['@typ' => 'KUNDENKONTO'],
|
||||
'art' => 'Adressdaten',
|
||||
'email' => $email,
|
||||
'passwort' => md5($password),
|
||||
],
|
||||
];
|
||||
|
||||
$body = $this
|
||||
->serializer
|
||||
->serialize($data, 'xml')
|
||||
;
|
||||
|
||||
try {
|
||||
$response = $this->httpClient->request('GET', $this->config['bpn_url'], [
|
||||
'query' => [
|
||||
'operation' => $body,
|
||||
]
|
||||
]);
|
||||
|
||||
$xml = $response->getContent();
|
||||
|
||||
if (str_contains($xml, 'HINWEIS')) {
|
||||
return $this->serializer->deserialize($xml, ErrorResponse::class, 'xml');
|
||||
}
|
||||
|
||||
return $this->serializer->deserialize($xml, Profile::class, 'xml');
|
||||
} catch (\Throwable $e) {
|
||||
}
|
||||
|
||||
throw new ApiClientException($e->getMessage());
|
||||
}
|
||||
|
||||
public function updateProfile(): void
|
||||
{}
|
||||
|
||||
/**
|
||||
* @throws ApiClientException
|
||||
*/
|
||||
public function getCrmSelection(string $email, string $password): mixed
|
||||
{
|
||||
$data = [
|
||||
'anfrage' => [
|
||||
'user' => $this->config['bpn_username'],
|
||||
'key' => $this->createKey($this->config['bpn_username'], $this->config['bpn_password'], 'KUNDENKONTO'),
|
||||
'satz' => ['@typ' => 'KUNDENKONTO'],
|
||||
'art' => 'SelektionCRM',
|
||||
'email' => $email,
|
||||
'passwort' => md5($password),
|
||||
],
|
||||
];
|
||||
|
||||
$body = $this
|
||||
->serializer
|
||||
->serialize($data, 'xml')
|
||||
;
|
||||
|
||||
try {
|
||||
$response = $this->httpClient->request('GET', $this->config['bpn_url'], [
|
||||
'query' => [
|
||||
'operation' => $body,
|
||||
]
|
||||
]);
|
||||
|
||||
$xml = $response->getContent();
|
||||
|
||||
if (str_contains($xml, 'HINWEIS')) {
|
||||
return $this->serializer->deserialize($xml, ErrorResponse::class, 'xml');
|
||||
}
|
||||
|
||||
return $this->serializer->deserialize($xml, CrmAttributeSelection::class, 'xml');
|
||||
} catch (\Throwable $e) {
|
||||
}
|
||||
|
||||
throw new ApiClientException($e->getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* @Creates key for BusPro API access according to documentation
|
||||
*/
|
||||
private function createKey(string $username, string $password, string $type): string
|
||||
{
|
||||
$date = (new \DateTimeImmutable())->format('Ymd');
|
||||
|
||||
return md5($username.$password.$date.$type);
|
||||
}
|
||||
|
||||
private function resolveOptions(array $options): array
|
||||
{
|
||||
$optionsResolver = new OptionsResolver();
|
||||
$optionsResolver->setRequired(['bpn_url', 'bpn_username', 'bpn_password']);
|
||||
|
||||
return $optionsResolver->resolve($options);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace App\BusProNet;
|
||||
|
||||
class ApiClientException extends \Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace App\BusProNet\Model;
|
||||
|
||||
use Symfony\Component\Serializer\Annotation\SerializedName;
|
||||
|
||||
class Address
|
||||
{
|
||||
#[SerializedName('strasse')]
|
||||
private ?string $street = null;
|
||||
|
||||
#[SerializedName('plz')]
|
||||
private ?string $postCode = null;
|
||||
|
||||
#[SerializedName('ort')]
|
||||
private ?string $city = null;
|
||||
|
||||
#[SerializedName('land')]
|
||||
private ?string $country = null;
|
||||
|
||||
public function getStreet(): ?string
|
||||
{
|
||||
return $this->street;
|
||||
}
|
||||
|
||||
public function setStreet(?string $street): static
|
||||
{
|
||||
$this->street = $street;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPostCode(): ?string
|
||||
{
|
||||
return $this->postCode;
|
||||
}
|
||||
|
||||
public function setPostCode(?string $postCode): static
|
||||
{
|
||||
$this->postCode = $postCode;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCity(): ?string
|
||||
{
|
||||
return $this->city;
|
||||
}
|
||||
|
||||
public function setCity(?string $city): static
|
||||
{
|
||||
$this->city = $city;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCountry(): ?string
|
||||
{
|
||||
return $this->country;
|
||||
}
|
||||
|
||||
public function setCountry(?string $country): static
|
||||
{
|
||||
$this->country = $country;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace App\BusProNet\Model;
|
||||
|
||||
use Symfony\Component\Serializer\Annotation\SerializedName;
|
||||
|
||||
class Communication
|
||||
{
|
||||
#[SerializedName('telefonprivat')]
|
||||
private ?string $phone = null;
|
||||
|
||||
#[SerializedName('telefonmobil')]
|
||||
private ?string $mobile = null;
|
||||
|
||||
#[SerializedName('email')]
|
||||
private ?string $email = null;
|
||||
|
||||
public function getPhone(): ?string
|
||||
{
|
||||
return $this->phone;
|
||||
}
|
||||
|
||||
public function setPhone(?string $phone): static
|
||||
{
|
||||
$this->phone = $phone;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getMobile(): ?string
|
||||
{
|
||||
return $this->mobile;
|
||||
}
|
||||
|
||||
public function setMobile(?string $mobile): static
|
||||
{
|
||||
$this->mobile = $mobile;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getEmail(): ?string
|
||||
{
|
||||
return $this->email;
|
||||
}
|
||||
|
||||
public function setEmail(?string $email): static
|
||||
{
|
||||
$this->email = $email;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace App\BusProNet\Model;
|
||||
|
||||
use Symfony\Component\Serializer\Annotation\Ignore;
|
||||
use Symfony\Component\Serializer\Annotation\SerializedName;
|
||||
|
||||
class CrmAttribute
|
||||
{
|
||||
#[SerializedName('@id')]
|
||||
private ?int $id = null;
|
||||
|
||||
#[SerializedName('@bezeichnung')]
|
||||
private ?string $label = null;
|
||||
|
||||
#[SerializedName('@auswahl')]
|
||||
private ?string $selectedAsString = null;
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function setId(?int $id): static
|
||||
{
|
||||
$this->id = $id;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getLabel(): ?string
|
||||
{
|
||||
return $this->label;
|
||||
}
|
||||
|
||||
public function setLabel(?string $label): static
|
||||
{
|
||||
$this->label = $label;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSelectedAsString(): ?string
|
||||
{
|
||||
return $this->selectedAsString;
|
||||
}
|
||||
|
||||
public function setSelectedAsString(?string $selectedAsString): static
|
||||
{
|
||||
$this->selectedAsString = $selectedAsString;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isSelected(): bool
|
||||
{
|
||||
return 'true' === strtolower($this->selectedAsString);
|
||||
}
|
||||
|
||||
public function setSelected(bool $selected): static
|
||||
{
|
||||
$this->selectedAsString = $selected ? 'True' : 'False';
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\BusProNet\Model;
|
||||
|
||||
use Symfony\Component\Serializer\Annotation\SerializedPath;
|
||||
|
||||
class CrmAttributeSelection
|
||||
{
|
||||
#[SerializedPath('[selektionsmerkmale][selektionsgruppe]')]
|
||||
private ?array $selectionGroups = null;
|
||||
|
||||
/**
|
||||
* @return CrmAttributeSelectionGroup[]|null
|
||||
*/
|
||||
public function getSelectionGroups(): ?array
|
||||
{
|
||||
return $this->selectionGroups;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CrmAttributeSelectionGroup[]|null $selectionGroups
|
||||
* @return $this
|
||||
*/
|
||||
public function setSelectionGroups(?array $selectionGroups): static
|
||||
{
|
||||
$this->selectionGroups = $selectionGroups;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace App\BusProNet\Model;
|
||||
|
||||
use Symfony\Component\Serializer\Annotation\SerializedName;
|
||||
|
||||
class CrmAttributeSelectionGroup
|
||||
{
|
||||
#[SerializedName('@bezeichnung')]
|
||||
private ?string $label = null;
|
||||
|
||||
#[SerializedName('selektion')]
|
||||
private ?array $attributes = null;
|
||||
|
||||
public function getLabel(): ?string
|
||||
{
|
||||
return $this->label;
|
||||
}
|
||||
|
||||
public function setLabel(?string $label): static
|
||||
{
|
||||
$this->label = $label;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CrmAttribute[]|null
|
||||
*/
|
||||
public function getAttributes(): ?array
|
||||
{
|
||||
return $this->attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CrmAttribute[]|null $attributes
|
||||
* @return $this
|
||||
*/
|
||||
public function setAttributes(?array $attributes): static
|
||||
{
|
||||
$this->attributes = $attributes;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace App\BusProNet\Model;
|
||||
|
||||
use Symfony\Component\Serializer\Annotation\SerializedPath;
|
||||
|
||||
class ErrorResponse
|
||||
{
|
||||
#[SerializedPath('[satz][nr]')]
|
||||
private ?string $code;
|
||||
|
||||
#[SerializedPath('[satz][text]')]
|
||||
private ?string $type;
|
||||
|
||||
public function getCode(): ?string
|
||||
{
|
||||
return $this->code;
|
||||
}
|
||||
|
||||
public function setCode(?string $code): static
|
||||
{
|
||||
$this->code = $code;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getType(): ?string
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
public function setType(?string $type): static
|
||||
{
|
||||
$this->type = $type;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
<?php
|
||||
|
||||
namespace App\BusProNet\Model;
|
||||
|
||||
use Symfony\Component\Serializer\Annotation\Context;
|
||||
use Symfony\Component\Serializer\Annotation\SerializedPath;
|
||||
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
|
||||
|
||||
class Profile
|
||||
{
|
||||
#[SerializedPath('[idadresse]')]
|
||||
private ?int $addressId = null;
|
||||
|
||||
#[SerializedPath('[idperson]')]
|
||||
private ?int $personId = null;
|
||||
|
||||
#[SerializedPath('[adressdaten][name]')]
|
||||
private ?string $name = null;
|
||||
|
||||
#[SerializedPath('[adressdaten][vorname]')]
|
||||
private ?string $firstName = null;
|
||||
|
||||
#[SerializedPath('[adressdaten][anrede]')]
|
||||
private ?string $salutation = null;
|
||||
|
||||
#[SerializedPath('[adressdaten][titel]')]
|
||||
private ?string $title = null;
|
||||
|
||||
#[SerializedPath('[adressdaten][geschlecht]')]
|
||||
private ?string $gender = null;
|
||||
|
||||
#[SerializedPath('[adressdaten][geburtsdatum]')]
|
||||
#[Context([DateTimeNormalizer::FORMAT_KEY => 'd.m.Y'])]
|
||||
private ?\DateTimeImmutable $dateOfBirth = null;
|
||||
|
||||
#[SerializedPath('[adressdaten][anschrift]')]
|
||||
private ?Address $address = null;
|
||||
|
||||
#[SerializedPath('[adressdaten][kommunikation]')]
|
||||
private ?Communication $communication = null;
|
||||
|
||||
public function getAddressId(): ?int
|
||||
{
|
||||
return $this->addressId;
|
||||
}
|
||||
|
||||
public function setAddressId(?int $addressId): static
|
||||
{
|
||||
$this->addressId = $addressId;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPersonId(): ?int
|
||||
{
|
||||
return $this->personId;
|
||||
}
|
||||
|
||||
public function setPersonId(?int $personId): static
|
||||
{
|
||||
$this->personId = $personId;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getName(): ?string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function setName(?string $name): static
|
||||
{
|
||||
$this->name = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getFirstName(): ?string
|
||||
{
|
||||
return $this->firstName;
|
||||
}
|
||||
|
||||
public function setFirstName(?string $firstName): static
|
||||
{
|
||||
$this->firstName = $firstName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSalutation(): ?string
|
||||
{
|
||||
return $this->salutation;
|
||||
}
|
||||
|
||||
public function setSalutation(?string $salutation): static
|
||||
{
|
||||
$this->salutation = $salutation;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getTitle(): ?string
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
public function setTitle(?string $title): static
|
||||
{
|
||||
$this->title = $title;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getGender(): ?string
|
||||
{
|
||||
return $this->gender;
|
||||
}
|
||||
|
||||
public function setGender(?string $gender): static
|
||||
{
|
||||
$this->gender = $gender;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDateOfBirth(): \DateTimeImmutable
|
||||
{
|
||||
return $this->dateOfBirth;
|
||||
}
|
||||
|
||||
public function setDateOfBirth(?\DateTimeImmutable $dateOfBirth): static
|
||||
{
|
||||
$this->dateOfBirth = $dateOfBirth;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getAddress(): ?Address
|
||||
{
|
||||
return $this->address;
|
||||
}
|
||||
|
||||
public function setAddress(?Address $address): static
|
||||
{
|
||||
$this->address = $address;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCommunication(): ?Communication
|
||||
{
|
||||
return $this->communication;
|
||||
}
|
||||
|
||||
public function setCommunication(?Communication $communication): static
|
||||
{
|
||||
$this->communication = $communication;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller\Security;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
|
||||
|
||||
class LoginController extends AbstractController
|
||||
{
|
||||
#[Route('/login', name: 'app_security_login')]
|
||||
public function login(AuthenticationUtils $authenticationUtils): Response
|
||||
{
|
||||
// get the login error if there is one
|
||||
$error = $authenticationUtils->getLastAuthenticationError();
|
||||
|
||||
// last username entered by the user
|
||||
$lastUsername = $authenticationUtils->getLastUsername();
|
||||
|
||||
return $this->render('security/login.html.twig', [
|
||||
'last_username' => $lastUsername,
|
||||
'error' => $error,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use App\Repository\UserRepository;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
|
||||
use Symfony\Component\Security\Core\User\UserInterface;
|
||||
|
||||
#[ORM\Entity(repositoryClass: UserRepository::class)]
|
||||
class User implements UserInterface
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column]
|
||||
private ?int $id = null;
|
||||
|
||||
#[ORM\Column]
|
||||
private ?int $busProAddressId = null;
|
||||
|
||||
#[ORM\Column]
|
||||
private ?int $busProPersonId = null;
|
||||
|
||||
#[ORM\Column(length: 255)]
|
||||
private ?string $email = null;
|
||||
|
||||
#[ORM\Column(length: 255)]
|
||||
private ?string $firstName = null;
|
||||
|
||||
#[ORM\Column(length: 255)]
|
||||
private ?string $lastName = null;
|
||||
|
||||
#[ORM\Column(length: 255)]
|
||||
private ?string $role = null;
|
||||
|
||||
#[ORM\Column(nullable: true)]
|
||||
private ?\DateTimeImmutable $lastLoginAt = null;
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getBusProAddressId(): ?int
|
||||
{
|
||||
return $this->busProAddressId;
|
||||
}
|
||||
|
||||
public function setBusProAddressId(int $busProAddressId): static
|
||||
{
|
||||
$this->busProAddressId = $busProAddressId;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getBusProPersonId(): ?int
|
||||
{
|
||||
return $this->busProPersonId;
|
||||
}
|
||||
|
||||
public function setBusProPersonId(int $busProPersonId): static
|
||||
{
|
||||
$this->busProPersonId = $busProPersonId;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getEmail(): ?string
|
||||
{
|
||||
return $this->email;
|
||||
}
|
||||
|
||||
public function setEmail(string $email): static
|
||||
{
|
||||
$this->email = $email;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getFirstName(): ?string
|
||||
{
|
||||
return $this->firstName;
|
||||
}
|
||||
|
||||
public function setFirstName(string $firstName): static
|
||||
{
|
||||
$this->firstName = $firstName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getLastName(): ?string
|
||||
{
|
||||
return $this->lastName;
|
||||
}
|
||||
|
||||
public function setLastName(string $lastName): static
|
||||
{
|
||||
$this->lastName = $lastName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getRole(): ?string
|
||||
{
|
||||
return $this->role;
|
||||
}
|
||||
|
||||
public function setRole(string $role): static
|
||||
{
|
||||
$this->role = $role;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getLastLoginAt(): ?\DateTimeImmutable
|
||||
{
|
||||
return $this->lastLoginAt;
|
||||
}
|
||||
|
||||
public function setLastLoginAt(?\DateTimeImmutable $lastLoginAt): static
|
||||
{
|
||||
$this->lastLoginAt = $lastLoginAt;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDefaultRoute(): string
|
||||
{
|
||||
return 'app_index';
|
||||
}
|
||||
|
||||
public function getRoles(): array
|
||||
{
|
||||
return ['ROLE_USER'];
|
||||
}
|
||||
|
||||
public function eraseCredentials(): void
|
||||
{
|
||||
}
|
||||
|
||||
public function getUserIdentifier(): string
|
||||
{
|
||||
return $this->email;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\User;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
* @extends ServiceEntityRepository<User>
|
||||
*
|
||||
* @method User|null find($id, $lockMode = null, $lockVersion = null)
|
||||
* @method User|null findOneBy(array $criteria, array $orderBy = null)
|
||||
* @method User[] findAll()
|
||||
* @method User[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
|
||||
*/
|
||||
class UserRepository extends ServiceEntityRepository
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, User::class);
|
||||
}
|
||||
|
||||
public function save(User $entity, bool $flush = false): void
|
||||
{
|
||||
$this->getEntityManager()->persist($entity);
|
||||
|
||||
if ($flush) {
|
||||
$this->getEntityManager()->flush();
|
||||
}
|
||||
}
|
||||
|
||||
public function remove(User $entity, bool $flush = false): void
|
||||
{
|
||||
$this->getEntityManager()->remove($entity);
|
||||
|
||||
if ($flush) {
|
||||
$this->getEntityManager()->flush();
|
||||
}
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @return User[] Returns an array of User objects
|
||||
// */
|
||||
// public function findByExampleField($value): array
|
||||
// {
|
||||
// return $this->createQueryBuilder('u')
|
||||
// ->andWhere('u.exampleField = :val')
|
||||
// ->setParameter('val', $value)
|
||||
// ->orderBy('u.id', 'ASC')
|
||||
// ->setMaxResults(10)
|
||||
// ->getQuery()
|
||||
// ->getResult()
|
||||
// ;
|
||||
// }
|
||||
|
||||
// public function findOneBySomeField($value): ?User
|
||||
// {
|
||||
// return $this->createQueryBuilder('u')
|
||||
// ->andWhere('u.exampleField = :val')
|
||||
// ->setParameter('val', $value)
|
||||
// ->getQuery()
|
||||
// ->getOneOrNullResult()
|
||||
// ;
|
||||
// }
|
||||
}
|
||||
@@ -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