2025-02-21 16:20:19 +01:00
|
|
|
<?php
|
|
|
|
|
|
2025-10-13 13:51:51 +02:00
|
|
|
namespace App\Service\Provider;
|
2025-02-21 16:20:19 +01:00
|
|
|
|
2025-03-03 15:41:48 +01:00
|
|
|
use App\Dto\Connector\DefaultProviderDto;
|
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-10-13 13:51:51 +02:00
|
|
|
use App\Exception\Provider\EppContactIsAvailableException;
|
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-03-03 15:41:48 +01:00
|
|
|
use Symfony\Component\Serializer\Exception\ExceptionInterface;
|
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-23 00:47:51 +01:00
|
|
|
protected string $dtoClass = EppClientProviderDto::class;
|
2025-03-03 15:41:48 +01:00
|
|
|
|
|
|
|
|
/** @var EppClientProviderDto */
|
|
|
|
|
protected DefaultProviderDto $authData;
|
|
|
|
|
|
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-03-03 15:41:48 +01:00
|
|
|
$contacts = [new eppContactHandle($this->authData->domain->registrant, eppContactHandle::CONTACT_TYPE_REGISTRANT)];
|
|
|
|
|
foreach ($this->authData->domain->contacts as $role => $roid) {
|
2025-02-25 22:44:12 +01:00
|
|
|
$contacts[] = new eppContactHandle($roid, $role);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** @var eppCheckContactResponse $resp */
|
|
|
|
|
$resp = $this->eppClient->request(new eppCheckContactRequest($contacts));
|
2025-02-25 22:47:33 +01:00
|
|
|
foreach ($resp->getCheckedContacts() as $contact => $available) {
|
|
|
|
|
if ($available) {
|
2025-10-13 13:51:51 +02:00
|
|
|
throw EppContactIsAvailableException::fromContact($contact);
|
2025-02-25 22:47:33 +01:00
|
|
|
}
|
2025-02-25 22:44:12 +01:00
|
|
|
}
|
|
|
|
|
|
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());
|
2025-03-03 15:41:48 +01:00
|
|
|
$d->setRegistrant($this->authData->domain->registrant);
|
|
|
|
|
$d->setPeriodUnit($this->authData->domain->unit);
|
|
|
|
|
$d->setPeriod($this->authData->domain->period);
|
|
|
|
|
$d->setAuthorisationCode($this->authData->domain->password);
|
2025-02-22 01:30:35 +01:00
|
|
|
|
2025-03-03 15:41:48 +01:00
|
|
|
foreach ($this->authData->domain->contacts as $type => $contact) {
|
2025-02-22 01:30:35 +01:00
|
|
|
$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-03-03 15:41:48 +01:00
|
|
|
* @throws ExceptionInterface
|
2025-02-22 01:30:35 +01:00
|
|
|
*/
|
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-03-03 15:41:48 +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 10:31:46 +01:00
|
|
|
|
2025-03-03 15:41:48 +01:00
|
|
|
$ssl = (array) $this->serializer->normalize($this->authData->auth->ssl, 'json');
|
2025-02-24 10:31:46 +01:00
|
|
|
|
2025-03-03 15:41:48 +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' => [
|
2025-03-03 15:41:48 +01:00
|
|
|
...$ssl,
|
|
|
|
|
'local_cert' => $this->authData->file_certificate_pem,
|
|
|
|
|
'local_pk' => $this->authData->file_certificate_key,
|
2025-02-24 10:31:46 +01:00
|
|
|
]]));
|
|
|
|
|
} else {
|
2025-03-03 15:41:48 +01:00
|
|
|
unset($ssl['local_cert'], $ssl['local_pk']);
|
|
|
|
|
$conn->setSslContext(stream_context_create(['ssl' => $ssl]));
|
2025-02-24 10:31:46 +01:00
|
|
|
}
|
|
|
|
|
|
2025-03-03 15:41:48 +01:00
|
|
|
$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-03-03 14:27:05 +01:00
|
|
|
|
|
|
|
|
public static function buildEppCertificateFolder(string $projectDir, string $connectorId): string
|
|
|
|
|
{
|
|
|
|
|
return sprintf('%s/%s/%s/', $projectDir, 'var/epp-certificates', $connectorId);
|
|
|
|
|
}
|
2025-02-21 16:20:19 +01:00
|
|
|
}
|