Sindbad~EG File Manager
<?php
namespace App\DataTransformer;
use O2switch\CpanelLib\Entity\Customization;
use O2switch\CpanelLib\Entity\WafCustomization;
use Doctrine\ORM\EntityManagerInterface;
use O2switch\CpanelLib\Repository\WafCustomizationRepository;
/**
* Enrich parsed data from the httpd.conf by fetching/loading custom user data
*/
class Enrich implements DataTransformerInterface
{
/**
* @var array
*/
protected $cpUserdata;
protected static $simpleCache = [];
/**
* @var array
*/
private $portsConfig;
/**
* @var string
*/
private $httpdDefaultSsl;
/**
* @var EntityManagerInterface
*/
private $em;
/** @var WafCustomization[] */
private $customizableDomains;
/**
* @var string
*/
private $defaultServerMode;
public function __construct(array $portsConfig, string $httpdDefaultSsl,
EntityManagerInterface $em, string $defaultServerMode)
{
$this->portsConfig = $portsConfig;
$this->httpdDefaultSsl = $httpdDefaultSsl;
$this->em = $em;
$this->defaultServerMode = $defaultServerMode;
}
/**
* @param array $cpUserdata
* @return Enrich
*/
public function setCpUserdata(array $cpUserdata): Enrich
{
$this->cpUserdata = $cpUserdata;
return $this;
}
// TODO : define listenToIp, proxyPassIp based on user conf or the default IP
// TODO : careful about the proxyPassIp
// TODO : check ssl here, check if we need to update it
public function transform(array $d, $k = null): array
{
if(empty($this->cpUserdata)){
throw new \LogicException("The cPanel userdata is not set. Please call the setCpUserdata() method before using the transform method.");
}
$d['additionalsParams'] = $this->checkWafRules($d, $k);
// Special case with the default key, default Vhost
if($k === 'default'){
$d['sslCertificateFilepath'] = $this->httpdDefaultSsl;
$d['rawServerAlias'] = 'default';
$d['serverAlias'] = ['default'];
unset($d['ip']); // For the default Vhost, we check with the DNS or based on $server_addr
}
// Special case for Addon Domain and Parked Domain. The $k is the subdomain, we don't wants that. So we inverse
// the $k with the real domain and put the subdomain as an alias (as it should fucking be)
if(isset($d['cpUser']) && isset($this->cpUserdata[$d['cpUser']][$k])){
$newK = $this->cpUserdata[$d['cpUser']][$k];
if(is_array($d['serverAlias'])){
foreach($d['serverAlias'] as $kk => $vv){
if($vv == $newK){
unset($d['serverAlias'][$kk]);
break;
}
}
$d['serverAlias'][] = $k;
$d['rawServerAlias'] = implode(' ', $d['serverAlias']);
}
$d['serverName'] = $newK;
$k = $newK;
}
// Openresty, on shared hosting, can't open the SSL file because of the Nginx process owner (nobody)
// So we put the SSL content in redis directly
if(isset($d['sslCertificateFilepath'])){
try {
$tmp = $this->getContent($d['sslCertificateFilepath']);
} catch (\Exception $e){
$tmp = false;
}
if($tmp !== false){
$d['rawSslContent'] = $tmp;
} else {
unset($d['sslCertificateFilepath']);
unset($d['httpsPort']);
}
}
if(isset($d['ip'])){
$d['listenToIp'] = $d['ip'];
$d['proxyPassIp'] = $d['ip'];
$d['proxyPassSslIp'] = $d['ip'];
}
$d['proxyPassProtocol'] = 'http';
$d['proxyPassSslProtocol'] = 'https';
$config = $this->defaultServerMode;
if(array_key_exists('configType', $d) && array_key_exists($d['configType'], $this->portsConfig)){
$config = $d['configType'];
}
$d['proxyPassPort'] = $this->portsConfig[$config]['http'];
$d['proxyPassSslPort'] = $this->portsConfig[$config]['https'];
return [$d, $k];
}
private function searchCustomization(?string $serverName, ?string $key) : ?WafCustomization {
if(is_null($this->customizableDomains)) {
$this->customizableDomains = $this->em->getRepository(WafCustomization::class)->findAll();
}
foreach($this->customizableDomains as $w){
if(in_array($w->getDomain(), [$serverName, $key])){
return $w;
}
// TODO : Check if it's a problem to check on the servername, added recently.
if(in_array($w->getServerName(), [$serverName, $key])){
return $w;
}
}
return null;
}
private function checkWafRules(array $d, $k = null){
$repository = $this->em->getRepository(WafCustomization::class);
$wafCustomization = $this->searchCustomization($d['serverName'], $k);
if(! $wafCustomization instanceof WafCustomization){
return null;
}
if(!is_array($wafCustomization->getRules()) || empty($wafCustomization->getRules())){
return null;
}
return ['wafCustomization' => $wafCustomization->getRules()];
}
private function getContent($file){
if(isset(self::$simpleCache[$file])){
return self::$simpleCache[$file];
}
self::$simpleCache[$file] = file_get_contents($file);
return self::$simpleCache[$file];
}
}
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists