Viewing File: /usr/local/cpanel/whostmgr/docroot/cgi/ncssl/source/src/Service/Certificate/Install.php

<?php

namespace App\Service\Certificate;

use App\Repository\CertificateRepository;
use App\Service\CpanelHelper;
use App\Service\NcPlugin\PluginException;
use App\Entity\Certificate as CertificateEntity;
use App\Traits\ClearSensitiveData;
use Doctrine\ORM\EntityManagerInterface;

class Install
{
    use ClearSensitiveData;

    public function __construct(
        private readonly CpanelHelper          $cpanelHelper,
        private readonly CertificateRepository $repository,
        private readonly EntityManagerInterface $entityManager,
        private readonly PrivateKey            $privateKey
    ) {
    }

    private function isCertificateExpired(CertificateEntity $certificate): bool
    {
        $certExpirationDate = $certificate->getExpires() ?? 0;

        return $certExpirationDate > 0 && time() > $certExpirationDate;
    }

    /**
     * @throws PluginException
     */
    public function install($id, $certBody, $caBundle): void
    {
        if ($certBody === '') {
            throw new PluginException('Can\'t install certificate. Certificate body is empty');
        }

        $certificate = $this->repository->find($id);

        if (!$certificate) {
            throw new PluginException('Can\'t find certificate for installation');
        }

        if ($this->isCertificateExpired($certificate)) {
            return;
        }

        $certificate = $this->restorePrivateKey($certificate, $certBody);

        $caCpBundle = $this->getCaBundle($caBundle);

        $caCertificate = $this->installSsl($certificate, $certBody, $caCpBundle);

        $this->repository->removePreviousCertificate($certificate);

        $certificate->setCpanelId($caCertificate['cert_id']);
        $certificate->setPrivatekeyId($caCertificate['key_id']);
        $certificate->setStatus(CertificateEntity::STATUS_ACTIVE);

        $this->entityManager->flush();
    }

    /**
     * @throws PluginException
     */
    private function restorePrivateKey(CertificateEntity $certificate, $certificateBody): CertificateEntity
    {
        if (!$certificate->getPrivatekeyId()) {
            $certificate = $this->privateKey->restorePrivateKeyId($certificate, $certificateBody); // use private key service
        }

        if (!$certificate->getPrivatekeyId()) {
            throw new PluginException('Could not retrieve PKid for installation');
        }

        return $certificate;
    }

    private function getCaBundle($caBundle): string
    {
        $caCpBundle = '';

        if (!empty($caBundle) && is_array($caBundle)) {
            $caCpBundle = implode("\n", $caBundle);
        }

        return $caCpBundle;
    }

    /**
     * @throws PluginException
     */
    private function installSsl(CertificateEntity $certificate, $certificateBody, string $caBundle): array
    {
        try {
            $result = $this->cpanelHelper->installSsl($certificate->getHost(), $certificateBody, $certificate->getPrivatekeyId(), $caBundle, (string) $certificate->getNcId());
        } catch (\Exception $e) {
            $message = $this->clearSensitiveData($e->getMessage());
            $message = sprintf("Can't install certificate. Error: %s", $message);

            throw new PluginException($message);
        }

        if (empty($result['cert_id'])) {
            throw new PluginException("Can't install certificate. Can't get cpanel_id");
        }
        if (empty($result['key_id'])) {
            throw new PluginException("Can't install certificate. Can't get privatekey_id");
        }

        return $result;
    }
}
Back to Directory File Manager