File: //usr/local/mailchannels/controllers/DomainsController.php
<?php
namespace MailChannels;
use MailChannels\WHM;
use GuzzleHttp\Exception\ClientException;
use MailChannels;
PathRegistry::registerPath("domains", "index", "GET", DomainsController::class, "index");
PathRegistry::registerPath("domains", "protectDomains", "POST", DomainsController::class, "protectDomains");
PathRegistry::registerPath("domains", "protectAll", "POST", DomainsController::class, "protectAll");
PathRegistry::registerPath("domains", "protectAllLocalDNS", "POST", DomainsController::class, "protectAllLocalDNS");
PathRegistry::registerPath("domains", "getDomains", "GET", DomainsController::class, "getDomains");
PathRegistry::registerPath("domains", "unprotectDomains", "POST", DomainsController::class, "unProtectDomains");
PathRegistry::registerPath("domains", "unprotectAll", "POST", DomainsController::class, "unProtectAll");
class DomainsController extends BaseController {
const API_KEY_NOT_SET_ERROR = "You must set an API key before you can view this page. Please see the configuration page.";
const PAGE_NOT_POSITIVE_INTEGER_ERROR = "Page number must be a positive integer.";
const PAGE_LIMIT_NOT_POSITIVE_INTEGER_ERROR = "Page limit must be a positive integer.";
const UNEXPECTED_ERROR = "An unexpected error occurred. Please check the error logs.";
const PROTECT_DOMAINS_PROCESS_ALREADY_RUNNING = "A protect or un-protect domains process is already running, please try again later.";
const NO_API_KEY_SET_ERROR = "You must set your MailChannels API key";
const NO_SUBSCRIPTION_SET_ERROR = "You must set the MailChannels subscription";
const API_KEY_INVALID_ERROR = "Your MailChannels API key is invalid";
private $inboundAPI;
public function __construct() {
parent::__construct();
$this->inboundAPI = App::getInboundAPIClient();
}
public function setInboundAPI($api){
$this->inboundAPI = $api;
}
public function index() {
$this->render("index");
}
public function getDomains() {
$inboundConfig = $this->storage->getInboundConfig();
if (!$inboundConfig->getInboundAPIKey()) {
$this->renderJson(['message' => self::API_KEY_NOT_SET_ERROR], 400);
return;
}
$page = $this->requestParam('page');
$limit = $this->requestParam('limit');
$search = $this->requestParam('search');
$page = $page ? $page : 1;
$limit = $limit ? $limit : 10;
if (!ctype_digit((string) $page)) {
$this->renderJson(['message' => self::PAGE_NOT_POSITIVE_INTEGER_ERROR], 400);
return;
} else if (!ctype_digit((string) $limit) || $limit <= 0) {
$this->renderJson(['message' => self::PAGE_LIMIT_NOT_POSITIVE_INTEGER_ERROR], 400);
return;
}
$response = array();
try {
$domains = $this->inboundSMTPService->getSystemDomains($page, $limit, $search, true);
$rDomains = $this->addSubscriptionInfoToDomain($domains->getDomains());
$response = [
'domains' => $rDomains,
'total' => $domains->getTotal()
];
} catch (InboundSMTPServiceInternalErrorException $e) {
$this->logger->error($e);
$this->renderJson(['message' => self::UNEXPECTED_ERROR], 500);
return;
} catch (InboundSMTPServiceNotConfiguredException $e) {
$this->handleInboundSMTPServiceNotConfigured($e);
return;
} catch (UAPIException $e) {
$this->handleUAPIException($e);
return;
}
$this->renderJson($response);
}
public function protectDomains() {
$response = array();
$request = $this->requestBodyAsJson();
if (!$request || !property_exists($request, 'domains') || !$request->domains) {
$this->renderJson(['message' => "Domains must be provided to protect."], 400);
return;
}
$domains = $request->domains;
if (!is_array($domains)) {
$domains = [$domains];
}
try {
$result = $this->inboundSMTPService->protectDomains(...$domains);
$this->logger->info("Finished protecting domains: [".implode(",", $domains)."]");
$response = [
'domains' => $this->addSubscriptionInfoToDomain($result->getUpdatedDomains()),
'skipped' => $result->getSkippedDomains(),
'failed' => $result->getFailedDomains()
];
} catch (InboundSMTPServiceNotConfiguredException $e) {
$this->handleInboundSMTPServiceNotConfigured($e);
return;
} catch (UAPIException $e) {
$this->handleUAPIException($e);
return;
}
$this->renderJson($response);
}
public function protectAll() {
$this->protectAllHelper(false);
}
public function protectAllLocalDNS() {
$this->protectAllHelper(true);
}
private function protectAllHelper($skipExternalDNS) {
$response = array();
try {
$result = $this->inboundSMTPService->protectAll($skipExternalDNS);
$response = [
'domains' => $this->addSubscriptionInfoToDomain($result->getUpdatedDomains()),
'skipped' => $result->getSkippedDomains(),
'failed' => $result->getFailedDomains()
];
} catch(LockUnavailableException $e) {
$this->logger->error($e);
$this->renderJson(['message' => self::PROTECT_DOMAINS_PROCESS_ALREADY_RUNNING], 500);
return;
} catch (InboundSMTPServiceNotConfiguredException $e) {
$this->handleInboundSMTPServiceNotConfigured($e);
return;
} catch (UAPIException $e) {
$this->handleUAPIException($e);
return;
}
$this->renderJson($response);
}
public function unProtectDomains() {
$response = array();
$request = $this->requestBodyAsJson();
if (!$request || !property_exists($request, 'domains') || !$request->domains) {
$this->renderJson(['message' => "Domains must be provided to un-protect."], 400);
return;
}
$domains = $request->domains;
if (!is_array($domains)) {
$domains = [$domains];
}
try {
$result = $this->inboundSMTPService->unProtectDomains(...$domains);
$response = [
'domains' => $this->addSubscriptionInfoToDomain($result->getUpdatedDomains()),
'skipped' => $result->getSkippedDomains(),
'failed' => $result->getFailedDomains()
];
} catch(LockUnavailableException $e) {
$this->logger->error($e);
$this->renderJson(['message' => self::PROTECT_DOMAINS_PROCESS_ALREADY_RUNNING], 500);
return;
} catch (InboundSMTPServiceNotConfiguredException $e) {
$this->handleInboundSMTPServiceNotConfigured($e);
return;
} catch (UAPIException $e) {
$this->handleUAPIException($e);
return;
}
$this->renderJson($response);
}
public function unProtectAll() {
$response = array();
try {
$result = $this->inboundSMTPService->unProtectAll();
$response = [
'domains' => $this->addSubscriptionInfoToDomain($result->getUpdatedDomains()),
'skipped' => $result->getSkippedDomains(),
'failed' => $result->getFailedDomains()
];
} catch(LockUnavailableException $e) {
$this->logger->error($e);
$this->renderJson(['message' => self::PROTECT_DOMAINS_PROCESS_ALREADY_RUNNING], 500);
return;
} catch (InboundSMTPServiceNotConfiguredException $e) {
$this->handleInboundSMTPServiceNotConfigured($e);
return;
} catch (UAPIException $e) {
$this->handleUAPIException($e);
return;
}
$this->renderJson($response);
}
private function addSubscriptionInfoToDomain($domains) {
if (!$domains) {
return [];
}
$rDomains = array();
$subscriptionsMap = array();
$subscriptions = $this->inboundSMTPService->getInboundSubscriptions();
if ($subscriptions) {
foreach ($subscriptions as $subscription) {
$subscriptionsMap[$subscription->getHandle()] = $subscription->getPlan();
}
}
foreach ($domains as $domain) {
$rDomain = $domain->jsonSerialize();
$mcDomain = $domain->getMCDomain();
if (!empty($subscriptionsMap) && $mcDomain) {
$plan = $subscriptionsMap[$mcDomain->getSubscriptionHandle()];
$rDomain['planName'] = $plan->getName();
}
$rDomains[] = $rDomain;
}
return $rDomains;
}
private function handleInboundSMTPServiceNotConfigured(InboundSMTPServiceNotConfiguredException $e) {
switch (get_class($e)) {
case InboundAPIKeyNotSetException::class:
$message = self::NO_API_KEY_SET_ERROR;
break;
case NoInboundSubscriptionSetException::class:
$message = self::NO_SUBSCRIPTION_SET_ERROR;
break;
case InvalidInboundAPIKeyException::class:
$message = self::API_KEY_INVALID_ERROR;
break;
default:
$this->logger->error($e);
$message = self::UNEXPECTED_ERROR;
break;
}
$this->renderJson(['message' => $message], 403);
}
/**
* @return InboundSMTPService
* @throws NullPointerException
*/
protected function getInboundSMTPService() {
$inboundSMTPService = ServiceSelector::getService(InboundSMTPService::class);
if ($inboundSMTPService == null) {
throw new NullPointerException("InboundSMTPService must not be null");
}
return $inboundSMTPService;
}
}