2025-02-21 16:20:19 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace App\Service\Connector;
|
|
|
|
|
|
2025-02-23 00:47:51 +01:00
|
|
|
use App\Dto\Connector\EppClientProviderDto;
|
2025-02-21 16:20:19 +01:00
|
|
|
use App\Entity\Domain;
|
2025-02-25 22:44:12 +01:00
|
|
|
use Metaregistrar\EPP\eppCheckContactRequest;
|
|
|
|
|
use Metaregistrar\EPP\eppCheckContactResponse;
|
2025-02-22 01:30:35 +01:00
|
|
|
use Metaregistrar\EPP\eppCheckDomainRequest;
|
|
|
|
|
use Metaregistrar\EPP\eppCheckDomainResponse;
|
|
|
|
|
use Metaregistrar\EPP\eppConnection;
|
|
|
|
|
use Metaregistrar\EPP\eppContactHandle;
|
|
|
|
|
use Metaregistrar\EPP\eppCreateDomainRequest;
|
|
|
|
|
use Metaregistrar\EPP\eppDomain;
|
|
|
|
|
use Metaregistrar\EPP\eppException;
|
|
|
|
|
use Metaregistrar\EPP\eppHelloRequest;
|
2025-02-21 16:20:19 +01:00
|
|
|
use Psr\Cache\CacheItemInterface;
|
|
|
|
|
use Psr\Cache\CacheItemPoolInterface;
|
|
|
|
|
use Psr\Cache\InvalidArgumentException;
|
2025-02-25 22:44:12 +01:00
|
|
|
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
2025-02-23 00:47:51 +01:00
|
|
|
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
|
|
|
|
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
|
|
|
|
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
2025-02-21 16:20:19 +01:00
|
|
|
|
2025-02-22 13:36:10 +01:00
|
|
|
class EppClientProvider extends AbstractProvider implements CheckDomainProviderInterface
|
2025-02-21 16:20:19 +01:00
|
|
|
{
|
2025-02-22 18:57:50 +01:00
|
|
|
public const EPP_CERTIFICATES_PATH = '../var/epp-certificates/';
|
|
|
|
|
|
2025-02-23 00:47:51 +01:00
|
|
|
protected string $dtoClass = EppClientProviderDto::class;
|
2025-02-24 23:19:11 +01:00
|
|
|
private ?eppConnection $eppClient = null;
|
2025-02-22 01:30:35 +01:00
|
|
|
|
2025-02-21 16:20:19 +01:00
|
|
|
public function __construct(
|
|
|
|
|
CacheItemPoolInterface $cacheItemPool,
|
2025-02-23 00:47:51 +01:00
|
|
|
DenormalizerInterface&NormalizerInterface $serializer,
|
|
|
|
|
ValidatorInterface $validator,
|
2025-02-22 01:30:35 +01:00
|
|
|
) {
|
2025-02-23 00:47:51 +01:00
|
|
|
parent::__construct($cacheItemPool, $serializer, $validator);
|
2025-02-21 16:20:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected function assertAuthentication(): void
|
|
|
|
|
{
|
2025-02-24 10:31:46 +01:00
|
|
|
$this->connect();
|
2025-02-22 01:30:35 +01:00
|
|
|
$this->eppClient->login();
|
|
|
|
|
|
|
|
|
|
$this->eppClient->request(new eppHelloRequest());
|
|
|
|
|
|
2025-02-25 22:44:12 +01:00
|
|
|
$contacts = [];
|
|
|
|
|
foreach ($this->authData['domain']['contacts'] as $role => $roid) {
|
|
|
|
|
$contacts[] = new eppContactHandle($roid, $role);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** @var eppCheckContactResponse $resp */
|
|
|
|
|
$resp = $this->eppClient->request(new eppCheckContactRequest($contacts));
|
|
|
|
|
if (in_array(true, $resp->getCheckedContacts())) {
|
|
|
|
|
throw new BadRequestHttpException('At least one of the contacts entered cannot be used because they are indicated as available.');
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-22 01:30:35 +01:00
|
|
|
$this->eppClient->logout();
|
|
|
|
|
$this->eppClient->disconnect();
|
2025-02-21 16:20:19 +01:00
|
|
|
}
|
|
|
|
|
|
2025-02-22 01:30:35 +01:00
|
|
|
/**
|
|
|
|
|
* @throws eppException
|
|
|
|
|
*/
|
2025-02-21 16:20:19 +01:00
|
|
|
public function orderDomain(Domain $domain, bool $dryRun): void
|
|
|
|
|
{
|
2025-02-24 10:31:46 +01:00
|
|
|
$this->connect();
|
2025-02-22 01:30:35 +01:00
|
|
|
|
|
|
|
|
$d = new eppDomain($domain->getLdhName());
|
|
|
|
|
$d->setRegistrant($this->authData['domain']['registrant']);
|
|
|
|
|
$d->setPeriodUnit($this->authData['domain']['unit']);
|
|
|
|
|
$d->setPeriod($this->authData['domain']['period']);
|
|
|
|
|
$d->setAuthorisationCode($this->authData['domain']['password']);
|
|
|
|
|
|
|
|
|
|
foreach ($this->authData['domain']['contacts'] as $type => $contact) {
|
|
|
|
|
$d->addContact(new eppContactHandle($contact, $type));
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-22 13:36:10 +01:00
|
|
|
if (!$dryRun) {
|
|
|
|
|
$this->eppClient->request(new eppCreateDomainRequest($d));
|
|
|
|
|
}
|
2025-02-22 01:30:35 +01:00
|
|
|
|
|
|
|
|
$this->eppClient->logout();
|
2025-02-24 10:31:46 +01:00
|
|
|
$this->disconnect();
|
2025-02-21 16:20:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @throws InvalidArgumentException
|
|
|
|
|
*/
|
|
|
|
|
protected function getCachedTldList(): CacheItemInterface
|
|
|
|
|
{
|
|
|
|
|
return $this->cacheItemPool->getItem('app.provider.epp.supported-tld');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected function getSupportedTldList(): array
|
|
|
|
|
{
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function isSupported(Domain ...$domainList): bool
|
|
|
|
|
{
|
|
|
|
|
if (0 === count($domainList)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
$tld = $domainList[0]->getTld();
|
|
|
|
|
|
|
|
|
|
foreach ($domainList as $domain) {
|
|
|
|
|
if ($domain->getTld() !== $tld) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-22 01:30:35 +01:00
|
|
|
/**
|
2025-02-23 16:35:57 +01:00
|
|
|
* @return string[]
|
|
|
|
|
*
|
2025-02-22 01:30:35 +01:00
|
|
|
* @throws eppException
|
|
|
|
|
*/
|
|
|
|
|
public function checkDomains(string ...$domains): array
|
|
|
|
|
{
|
2025-02-24 10:31:46 +01:00
|
|
|
$this->connect();
|
2025-02-22 01:30:35 +01:00
|
|
|
$this->eppClient->login();
|
|
|
|
|
|
|
|
|
|
$check = new eppCheckDomainRequest($domains);
|
|
|
|
|
|
|
|
|
|
/** @var eppCheckDomainResponse $response */
|
|
|
|
|
$response = $this->eppClient->request($check);
|
|
|
|
|
$checkedDomains = $response->getCheckedDomains();
|
|
|
|
|
|
|
|
|
|
$return = array_map(
|
|
|
|
|
fn (array $d) => $d['domainname'],
|
|
|
|
|
array_filter($checkedDomains, fn (array $d) => true === $d['available'])
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
$this->eppClient->logout();
|
|
|
|
|
$this->eppClient->disconnect();
|
|
|
|
|
|
|
|
|
|
return $return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @throws eppException
|
|
|
|
|
*/
|
2025-02-24 10:31:46 +01:00
|
|
|
private function connect(): void
|
2025-02-21 16:20:19 +01:00
|
|
|
{
|
2025-02-24 23:19:11 +01:00
|
|
|
if ($this->eppClient && $this->eppClient->isConnected()) {
|
2025-02-24 22:18:49 +01:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-22 01:30:35 +01:00
|
|
|
$conn = new eppConnection(false, null);
|
2025-02-24 10:31:46 +01:00
|
|
|
$conn->setHostname($this->authData['hostname']);
|
|
|
|
|
$conn->setVersion($this->authData['version']);
|
|
|
|
|
$conn->setLanguage($this->authData['language']);
|
|
|
|
|
$conn->setPort($this->authData['port']);
|
|
|
|
|
|
|
|
|
|
$conn->setUsername($this->authData['auth']['username']);
|
|
|
|
|
$conn->setPassword($this->authData['auth']['password']);
|
|
|
|
|
|
2025-02-24 23:19:11 +01:00
|
|
|
if (isset($this->authData['file_certificate_pem'], $this->authData['file_certificate_key'])) {
|
2025-02-24 10:31:46 +01:00
|
|
|
$conn->setSslContext(stream_context_create(['ssl' => [
|
|
|
|
|
...$this->authData['auth']['ssl'],
|
2025-02-24 23:19:11 +01:00
|
|
|
'local_cert' => $this->authData['file_certificate_pem'],
|
|
|
|
|
'local_pk' => $this->authData['file_certificate_key'],
|
2025-02-24 10:31:46 +01:00
|
|
|
]]));
|
|
|
|
|
} else {
|
2025-02-24 23:19:11 +01:00
|
|
|
unset($this->authData['file_certificate_pem'], $this->authData['file_certificate_key']);
|
2025-02-24 10:31:46 +01:00
|
|
|
$conn->setSslContext(stream_context_create(['ssl' => $this->authData['auth']['ssl']]));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$conn->setExtensions($this->authData['extURI']);
|
|
|
|
|
$conn->setServices($this->authData['objURI']);
|
2025-02-22 01:30:35 +01:00
|
|
|
|
|
|
|
|
$conn->connect();
|
|
|
|
|
$this->eppClient = $conn;
|
2025-02-21 16:20:19 +01:00
|
|
|
}
|
2025-02-24 10:31:46 +01:00
|
|
|
|
|
|
|
|
private function disconnect(): void
|
|
|
|
|
{
|
|
|
|
|
$this->eppClient->disconnect();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function __destruct()
|
|
|
|
|
{
|
|
|
|
|
$this->disconnect();
|
|
|
|
|
}
|
2025-02-21 16:20:19 +01:00
|
|
|
}
|