2024-04-13 20:35:20 +02:00
< ? php
2024-04-16 18:24:38 +02:00
declare ( strict_types = 1 );
namespace App\Controller ;
error_reporting ( error_level : E_ALL );
define ( constant_name : 'COLOR_RED' , value : " \033 [31m " );
define ( constant_name : 'COLOR_GREEN' , value : " \033 [32m " );
define ( constant_name : 'COLOR_YELLOW' , value : " \033 [33m " );
define ( constant_name : 'COLOR_BLUE' , value : " \033 [34m " );
define ( constant_name : 'COLOR_WHITE' , value : " \033 [37m " );
define ( constant_name : 'COLOR_DEFAULT' , value : " \033 [39m " );
use App\Controller\Commands\Command ;
use App\Controller\Commands\CommandGroup ;
use App\Controller\Commands\CommandGroupContainer ;
use App\Entity\Apikey ;
use App\Entity\Domain ;
use App\Entity\DynDNS ;
use App\Entity\KeyHelp\KeyHelpDomain ;
use App\Entity\Nameserver ;
use App\Entity\Panel ;
use App\Repository\ApikeyRepository ;
use App\Repository\DomainRepository ;
use App\Repository\DynDNSRepository ;
use App\Repository\NameserverRepository ;
use App\Repository\PanelRepository ;
use Arubacao\TldChecker\Validator ;
use Exception ;
use JsonMapper ;
use JsonMapper_Exception ;
use LucidFrame\Console\ConsoleTable ;
use Odan\Migration\Command\GenerateCommand ;
use Phinx\Console\PhinxApplication ;
use SodiumException ;
use Symfony\Component\Console\Input\ArrayInput ;
use Symfony\Component\Console\Input\InputInterface ;
use Symfony\Component\Console\Output\ConsoleOutput ;
use Symfony\Component\Console\Output\OutputInterface ;
if ( php_sapi_name () !== 'cli' ) {
exit ;
}
class CLIController
{
private array $arguments ;
private CommandGroupContainer $commandGroupContainer ;
/**
* @ throws Exception
*/
public function __construct (
private readonly ApiController $apiController ,
private readonly ApikeyRepository $apikeyRepository ,
private readonly DomainController $domainController ,
private readonly DomainRepository $domainRepository ,
private readonly DynDNSRepository $dynDNSRepository ,
private readonly NameserverRepository $nameserverRepository ,
private readonly PanelRepository $panelRepository ,
private readonly ConfigController $configController ,
private readonly EncryptionController $encryptionController ,
private $logger ,
private bool $quiet
)
2022-09-27 19:13:28 +02:00
{
2024-04-16 18:24:38 +02:00
// FIXME needs to be elsewhere $this->runCheckSetup();
$this -> commandGroupContainer = ( new CommandGroupContainer ())
-> addCommandGroup ( commandGroup : ( new CommandGroup ( name : 'check' , description : 'health checks the system can perform' ))
-> addCommand ( command : new Command (
name : 'permissions' ,
callback : function () {
$this -> checkPermissions ();
},
description : 'check file permissions' ))
2024-04-17 20:28:51 +02:00
-> addCommand ( command : new Command (
name : 'panel' ,
callback : function () {
$this -> checkPanel ();
},
optionalParameters : [ 'ID' , 'fix=xes' ],
description : 'Validate setting for this panel' ))
2024-04-16 18:24:38 +02:00
-> addCommand ( command : new Command (
name : 'panels' ,
callback : function () {
$this -> checkPanels ();
},
optionalParameters : [ 'ID' , 'fix=xes' ]))
-> addCommand ( command : new Command (
name : 'domains' ,
callback : function () {
$this -> checkDomains ();
}))
-> addCommand ( command : new Command (
name : 'mail' ,
callback : function () {
$this -> checkMail ();
}))
-> addCommand ( command : new Command (
name : 'showincludes' ,
callback : function () {
$this -> checkShowIncludes ();
},
description : 'Shows needed setting on panels' ))
-> addCommand ( command : new Command (
name : 'generatekey' ,
callback : function () {
$this -> checkGenerateKey ();
},
description : 'Generates a a new key for encryption' ))
-> addCommand ( command : new Command (
name : 'setup' ,
callback : function () {
$this -> checkSetup ();
},
mandatoryParameters : [ 'username' ],
description : 'Adapt filesystem permissions (requires elaborated permissions)' ))
-> addCommand ( command : new Command (
name : 'version' ,
callback : function () {
$this -> checksVersion ();
},
optionalParameters : [ 'major:minor:patch' ],
description : 'Read or set the bindApi version in the database' )))
-> addCommandGroup ( commandGroup : ( new CommandGroup ( name : 'panels' , description : 'all KeyHelp systems configured' ))
-> addCommand ( command : new Command (
name : 'list' ,
callback : function () {
$this -> panelsList ();
}))
-> addCommand ( command : new Command (
name : 'create' ,
callback : function () {
$this -> panelsCreate ();
},
mandatoryParameters : [ 'name' ],
optionalParameters : [ 'A=<IPv4>' , 'AAAA=<IPv6>' , 'apikey=<API-Key>' ]))
-> addCommand ( command : new Command (
name : 'update' ,
callback : function () {
$this -> panelsUpdate ();
},
mandatoryParameters : [ 'ID' ],
optionalParameters : [ 'name=<name>' , 'A=<IPv4>' , 'AAAA=<IPv6>' , 'apikey=<API-Key>' , 'self=<0|1>' ]))
-> addCommand ( command : new Command (
name : 'delete' ,
callback : function () {
$this -> panelsDelete ();
},
mandatoryParameters : [ 'ID' ]))
-> addCommand ( command : new Command (
name : 'apiping' ,
callback : function () {
$this -> apiPing ( type : 'panel' );
},
optionalParameters : [ 'ID' ])))
-> addCommandGroup ( commandGroup : ( new CommandGroup ( name : 'nameservers' , description : 'available nameservers' ))
-> addCommand ( command : new Command (
name : 'list' ,
callback : function () {
$this -> nameserversList ();
}))
-> addCommand ( command : new Command (
name : 'create' ,
callback : function () {
$this -> nameserversCreate ();
},
mandatoryParameters : [ 'name' ],
optionalParameters : [ 'A=<IPv4>' , 'AAAA=<IPv6>' , 'apikey=<API-Key>' ]))
-> addCommand ( command : new Command (
name : 'update' ,
callback : function () {
$this -> nameserversUpdate ();
},
mandatoryParameters : [ 'ID' ],
optionalParameters : [ 'name=<name>' , 'A=<IPv4>' , 'AAAA=<IPv6>' , 'apikey=<API-Key>' ]))
-> addCommand ( command : new Command (
name : 'delete' ,
callback : function () {
$this -> nameserversDelete ();
},
mandatoryParameters : [ 'ID' ]))
-> addCommand ( command : new Command (
name : 'apiping' ,
callback : function () {
$this -> apiPing ( type : 'nameserver' );
},
optionalParameters : [ 'ID' ])))
-> addCommandGroup ( commandGroup : ( new CommandGroup ( name : 'domains' , description : 'configured domains' ))
-> addCommand ( command : new Command (
name : 'list' ,
callback : function () {
$this -> domainsList ();
}))
-> addCommand ( command : new Command (
name : 'refresh' ,
callback : function () {
$this -> domainsRefresh ();
},
2024-04-09 18:45:28 +02:00
// mandatoryParameters: ['name'],
// optionalParameters: ['A=<IPv4>', 'AAAA=<IPv6>', 'apikey=<API-Key>'])))
2024-04-16 18:24:38 +02:00
description : 'Refresh domains' )))
-> addCommandGroup ( commandGroup : ( new CommandGroup ( name : 'dyndns' , description : 'handle DynDNS entries' ))
-> addCommand ( command : new Command (
name : 'list' ,
callback : function () {
$this -> dynDnsList ();
}))
-> addCommand ( command : new Command (
name : 'create' ,
callback : function () {
$this -> dynDnsCreate ();
},
mandatoryParameters : [ 'hostname.example.com' , 'password' ],
optionalParameters : [ 'A=<IPv4>' , 'AAAA=<IPv6>' ],
description : 'FQDN within a domain where this server is master' ))
-> addCommand ( command : new Command (
name : 'update' ,
callback : function () {
$this -> dynDnyUpdate ();
},
mandatoryParameters : [ 'hostname.example.com' ,],
optionalParameters : [ 'password=<password>' , 'A=<IPv4>' , 'AAAA=<IPv6>' ]))
-> addCommand ( command : new Command (
name : 'delete' ,
callback : function () {
$this -> dynDnsDelete ();
},
mandatoryParameters : [ 'ID' ])))
-> addCommandGroup ( commandGroup : ( new CommandGroup ( name : 'apikeys' , description : 'API keys to access this bindAPI' ))
-> addCommand ( command : new Command (
name : 'list' ,
callback : function () {
$this -> apikeysList ();
}))
-> addCommand ( command : new Command (
name : 'create' ,
callback : function () {
$this -> apikeysCreate ();
},
2024-04-17 20:28:51 +02:00
mandatoryParameters : [ 'name' ]))
2024-04-16 18:24:38 +02:00
-> addCommand ( command : new Command (
name : 'update' ,
callback : function () {
$this -> apikeysUpdate ();
},
mandatoryParameters : [ 'ID' ,],
optionalParameters : [ 'name=<name>' ]))
-> addCommand ( command : new Command (
name : 'delete' ,
callback : function () {
$this -> apikeysDelete ();
},
mandatoryParameters : [ 'ID' ])))
-> addCommandGroup ( commandGroup : ( new CommandGroup ( name : 'migrations' , description : 'maintain database migrations' ))
-> addCommand ( command : new Command (
name : 'status' ,
callback : function () {
$this -> migrationsStatus ();
},
description : 'List information about migrations'
))
-> addCommand ( command : new Command (
2024-04-17 20:28:51 +02:00
name : 'migrate' ,
2024-04-16 18:24:38 +02:00
callback : function () {
2024-04-17 20:28:51 +02:00
$this -> migrationsMigrate ();
2024-04-16 18:24:38 +02:00
},
2024-04-17 20:28:51 +02:00
description : 'Apply a new migration file'
2024-04-16 18:24:38 +02:00
))
-> addCommand ( command : new Command (
2024-04-17 20:28:51 +02:00
name : 'make' ,
2024-04-16 18:24:38 +02:00
callback : function () {
2024-04-17 20:28:51 +02:00
$this -> migrationsMake ();
2024-04-16 18:24:38 +02:00
},
2024-04-17 20:28:51 +02:00
description : '!Use only on dev environments, not in production! Build a new migration file'
2024-04-16 18:24:38 +02:00
))
);
2024-04-13 20:35:20 +02:00
2024-04-08 19:01:13 +02:00
// ->addCommandGroup(commandGroup: (new CommandGroup(name: 'webmail', description: 'manage webmail setup'))
// ->addCommand(command: new Command(
// name: 'check',
// callback: function () {
// $this->webmailCheck();
// },
// mandatoryParameters: ['example.com']
// ))
// ->addCommand(command: new Command(
// name: 'create',
// callback: function () {
// $this->webmailCreate();
// },
// mandatoryParameters: ['example.com']))
// ->addCommand(command: new Command(
// name: 'delete',
// callback: function () {
// $this->webmailDelete();
// },
// mandatoryParameters: ['ID'])));
2024-04-16 18:24:38 +02:00
}
2022-09-27 19:13:28 +02:00
2023-09-19 18:21:42 +02:00
2024-04-16 18:24:38 +02:00
function runCheckSetup () : void
{
if ( ! $this -> domainController -> checkPermissions ()) {
echo COLOR_RED . 'You need to setup the bindAPI permission first.' . COLOR_DEFAULT . PHP_EOL ;
echo 'Run ' . COLOR_YELLOW . './bin/console check:setup' . COLOR_DEFAULT . ' as root or with sudo.' . PHP_EOL ;
}
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
function runCommand ( array $arguments ) : void
{
if ( count ( $arguments ) < 1 ) {
$this -> showUsage ();
exit ( 0 );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$this -> logger -> debug ( message : " runCommand() " );
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( str_contains ( haystack : $arguments [ 0 ], needle : ':' )) {
[ $command , $subcommand ] = explode ( separator : ':' , string : $arguments [ 0 ]);
} else {
$command = $arguments [ 0 ];
$subcommand = '' ;
2024-04-13 20:35:20 +02:00
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$this -> arguments = $this -> parseArguments ( arguments : $arguments );
$this -> commandGroupContainer -> run ( command : $command , subcommand : $subcommand );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
* @ return void
*/
function showUsage () : void
{
$this -> logger -> debug ( message : " showUsage() " );
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$debug = $this -> configController -> getConfig ( configKey : 'debug' );
echo COLOR_DEFAULT . ')' . PHP_EOL ;
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
echo COLOR_YELLOW . 'Usage:' . PHP_EOL ;
echo COLOR_DEFAULT . " \t ./bin/console { options} { arguments} " . PHP_EOL . PHP_EOL ;
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
echo COLOR_YELLOW . 'Options:' . PHP_EOL ;
echo COLOR_GREEN . " \t -v, --version \t \t " . COLOR_DEFAULT . " Display the version of the API " . PHP_EOL ;
echo COLOR_GREEN . " \t -q, --quiet \t \t " . COLOR_DEFAULT . " No output to stdout, for cronjobs " . PHP_EOL . PHP_EOL ;
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
echo COLOR_YELLOW . 'Arguments: ' . COLOR_WHITE . '<mandatory> {optional}' . PHP_EOL ;
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$this -> commandGroupContainer -> printCommands ();
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
echo PHP_EOL . " \033 [39me.g. ./bin/console apikeys:list " . PHP_EOL ;
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
*/
public function checkPermissions () : void
{
$this -> logger -> debug ( message : " checkPermissions() " );
if ( ! $this -> domainController -> checkPermissions ()) {
if ( ! $this -> configController -> getConfig ( configKey : 'quiet' )) {
echo PHP_EOL . COLOR_DEFAULT ;
echo 'Missing permissions, please run ' . COLOR_YELLOW . './bin/console check:setup' . COLOR_DEFAULT . ' as root or with sudo.' . PHP_EOL ;
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
exit ( 1 );
} else {
exit ( 0 );
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
function checkSetup () : void
{
if ( empty ( $this -> arguments [ 1 ])) {
echo 'You need to supply a username.' . PHP_EOL ;
exit ( 1 );
}
$uid = posix_getuid ();
if ( $uid != 0 ) {
echo 'You need to run this as root or with sudo.' . PHP_EOL ;
exit ( 1 );
}
$username = $this -> arguments [ 1 ];
if ( ! $impersonatedUser = posix_getpwnam ( username : $username )) {
echo 'Cannot find user: ' . $username . PHP_EOL ;
exit ( 1 );
}
$impersonatedUserId = $impersonatedUser [ 'uid' ];
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
// add user to group bind
exec ( command : " adduser $username bind " , output : $output , result_code : $return );
if ( $return != 0 ) {
echo 'Could not add user to bind group.' . PHP_EOL ;
exit ( 1 );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
// for /etc/bind/local.zones file
if ( ! file_exists ( filename : $this -> domainController -> localZoneFile )) {
echo 'Could not find ' . COLOR_YELLOW . $this -> domainController -> localZoneFile . COLOR_DEFAULT . '.' . PHP_EOL ;
echo 'Creating …' ;
touch ( filename : $this -> domainController -> localZoneFile );
2022-09-27 19:13:28 +02:00
if ( ! file_exists ( filename : $this -> domainController -> localZoneFile )) {
2024-04-16 18:24:38 +02:00
echo 'Could not create ' . $this -> domainController -> localZoneFile . '.' . PHP_EOL ;
exit ( 1 );
2022-09-27 19:13:28 +02:00
} else {
echo ' done.' . PHP_EOL ;
echo 'Setting owner …' ;
2024-04-16 18:24:38 +02:00
if ( chown ( filename : $this -> domainController -> localZoneFile , user : 'bind' )) {
2022-09-27 19:13:28 +02:00
echo " done. " . PHP_EOL ;
}
echo 'Setting permissions …' ;
2024-04-16 18:24:38 +02:00
if ( chmod ( filename : $this -> domainController -> localZoneFile , permissions : 0664 )) {
2022-09-27 19:13:28 +02:00
echo " done. " . PHP_EOL ;
}
}
2024-04-16 18:24:38 +02:00
} else {
// check /etc/bind/local.zones permissions
echo 'Found ' . COLOR_YELLOW . $this -> domainController -> localZoneFile . COLOR_DEFAULT . '.' . PHP_EOL ;
2024-04-05 17:17:33 +02:00
2024-04-16 18:24:38 +02:00
echo 'Check permissions for ' . COLOR_YELLOW . $this -> domainController -> localZoneFile . COLOR_DEFAULT . ' …' ;
// dont repeat yourself, use check from DomainController FIXME
$this -> domainController -> checkPermissions ( impersonatedUserId : $impersonatedUserId );
}
// /etc/bind/local.zones file must be included in /etc/bind/named.conf.local
$namedConfLocal = file_get_contents ( filename : $this -> domainController -> namedConfLocalFile );
if ( str_contains ( haystack : $namedConfLocal , needle : $this -> domainController -> localZoneFile )) {
echo 'Found ' . COLOR_YELLOW . $this -> domainController -> localZoneFile . COLOR_DEFAULT . ' included ' . COLOR_YELLOW . $this -> domainController -> namedConfLocalFile . COLOR_DEFAULT . '.' . PHP_EOL ;
} else {
echo 'Could not find ' . COLOR_YELLOW . $this -> domainController -> localZoneFile . COLOR_DEFAULT . ' in ' . COLOR_YELLOW . $this -> domainController -> namedConfLocalFile . COLOR_DEFAULT . '.' . PHP_EOL ;
echo 'Adding …' ;
$namedConfLocal .= PHP_EOL . 'include "' . $this -> domainController -> localZoneFile . '";' . PHP_EOL ;
file_put_contents ( filename : $this -> domainController -> namedConfLocalFile , data : $namedConfLocal );
if ( str_contains ( haystack : $namedConfLocal , needle : $this -> domainController -> localZoneFile )) {
echo ' done.' . PHP_EOL ;
} else {
echo 'Could not add ' . COLOR_YELLOW . $this -> domainController -> localZoneFile . COLOR_DEFAULT . ' to ' . COLOR_YELLOW . $this -> domainController -> namedConfLocalFile . COLOR_DEFAULT . '.' . PHP_EOL ;
exit ( 1 );
}
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
// check /etc/bind/zones exists
echo 'Check for ' . COLOR_YELLOW . $this -> domainController -> localZonesDir . COLOR_DEFAULT . ' …' ;
if ( is_dir ( filename : $this -> domainController -> localZonesDir )) {
echo " exists. " . PHP_EOL ;
} else {
echo ' Could not find ' . COLOR_YELLOW . $this -> domainController -> localZonesDir . COLOR_DEFAULT . '.' . PHP_EOL ;
echo 'Creating …' ;
mkdir ( directory : $this -> domainController -> localZonesDir , permissions : 0775 , recursive : true );
echo ' done.' . PHP_EOL ;
echo 'Setting owner …' ;
if ( chown ( filename : $this -> domainController -> localZonesDir , user : 'bind' )) {
echo " done. " . PHP_EOL ;
}
echo 'Setting permissions …' ;
if ( chmod ( filename : $this -> domainController -> localZonesDir , permissions : 0774 )) {
echo " done. " . PHP_EOL ;
}
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
}
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
/**
*/
function checkPanels () : void
{
$this -> logger -> debug ( message : " checkPanels() " );
$id = intval ( value : $this -> arguments [ 1 ] ? ? 0 );
if ( $id != 0 ) {
if ( $panel = $this -> panelRepository -> findByID ( id : $id )) {
$this -> checkSinglePanel ( panel : $panel );
2024-04-13 20:35:20 +02:00
} else {
2024-04-16 18:24:38 +02:00
echo " Unknown panel ID $id " . PHP_EOL ;
}
} else {
if ( ! $this -> quiet ) {
2024-04-13 20:35:20 +02:00
echo " check all … " . PHP_EOL ;
2024-04-16 18:24:38 +02:00
}
$panels = $this -> panelRepository -> findAll ();
foreach ( $panels as $panel ) {
$this -> checkSinglePanel ( panel : $panel );
2022-09-27 19:13:28 +02:00
}
}
2024-04-16 18:24:38 +02:00
}
2024-04-05 17:17:33 +02:00
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
* @ param Panel $panel
*
* @ return void
*/
public
function checkSinglePanel ( Panel $panel ) : void
{
$this -> logger -> debug ( message : " checkSinglePanel() " );
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( ! $this -> quiet ) {
2024-04-13 20:35:20 +02:00
echo COLOR_DEFAULT . 'KeyHelp-Panel: ' . COLOR_YELLOW . $panel -> getName () . COLOR_DEFAULT ;
2024-04-16 18:24:38 +02:00
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$encryptionKey = $this -> configController -> getConfig ( configKey : 'encryptionKey' );
$decryptedKey = $this -> encryptionController -> safeDecrypt ( encrypted : $panel -> getApikey (), key : $encryptionKey );
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$f = $panel -> getA ();
if ( ! $this -> quiet ) {
2024-04-14 20:14:41 +02:00
echo COLOR_DEFAULT . ' IPv4: ' . COLOR_YELLOW . $f . COLOR_DEFAULT ;
2024-04-16 18:24:38 +02:00
}
2024-04-14 20:14:41 +02:00
2024-04-16 18:24:38 +02:00
if ( ! empty ( $panel -> getA ())) {
$panelRequest = $this -> apiController -> sendCommand (
requestType : 'GET' ,
serverName : $panel -> getName (),
versionIP : 4 ,
apiKey : $decryptedKey ,
command : '/server' ,
serverType : 'panel' );
} else {
$panelRequest = $this -> apiController -> sendCommand (
requestType : 'GET' ,
serverName : $panel -> getName (),
versionIP : 6 ,
apiKey : $decryptedKey ,
command : '/server' ,
serverType : 'panel' );
}
$panelData = json_decode ( json : $panelRequest [ 'data' ]);
if ( ! empty ( $panelData )) {
$panelVersion = $panelData -> meta -> panel_version ;
$responseTime = sprintf ( " %0.3f " , $panelRequest [ 'responseTime' ]);
} else {
$panelVersion = 'n/a' ;
$responseTime = 'n/a' ;
}
if ( ! $this -> quiet ) {
2024-04-13 20:35:20 +02:00
echo COLOR_DEFAULT . ' KeyHelp version: ' . $panelVersion . " ( $responseTime seconds) " . PHP_EOL ;
2024-04-16 18:24:38 +02:00
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( empty ( $panel -> getA ())) {
$result = $this -> apiController -> sendCommand (
requestType : 'GET' ,
serverName : $panel -> getName (),
versionIP : 6 ,
apiKey : $decryptedKey ,
command : 'domains?sort=domain&subdomains=false' ,
serverType : 'panel'
);
} else {
$result = $this -> apiController -> sendCommand (
requestType : 'GET' ,
serverName : $panel -> getName (),
versionIP : 4 ,
apiKey : $decryptedKey ,
command : 'domains?sort=domain&subdomains=false' ,
serverType : 'panel' );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( ! empty ( $result [ 'error' ])) {
if ( ! $this -> quiet ) {
2024-04-13 20:35:20 +02:00
echo $result [ 'data' ] . PHP_EOL ;
}
2024-04-16 18:24:38 +02:00
exit ( 1 );
}
if ( ! empty ( $result [ 'data' ])) {
$domains = json_decode ( json : $result [ 'data' ]);
} else {
if ( ! $this -> quiet ) {
2024-04-13 20:35:20 +02:00
echo 'No domains found' . PHP_EOL ;
}
2024-04-16 18:24:38 +02:00
exit ( 1 );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$maxDomainNameLength = 0 ;
$tmpDomainList = [];
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$mapper = new JsonMapper ();
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( count ( $domains ) > 0 ) {
foreach ( $domains as $domain ) {
$mapper -> bExceptionOnUndefinedProperty = true ;
$mapper -> bStrictNullTypes = false ;
try {
$domainObject = $mapper -> map ( json : $domain , object : new KeyHelpDomain ());
} catch ( JsonMapper_Exception $e ) {
exit ( $e -> getMessage () . PHP_EOL );
}
$tmpDomainList [] = $domainObject ;
if ( strlen ( string : $domain -> domain ) > $maxDomainNameLength ) {
$maxDomainNameLength = strlen ( string : $domain -> domain );
2022-09-27 19:13:28 +02:00
}
}
2024-04-16 18:24:38 +02:00
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$domainCount = 0 ;
foreach ( $tmpDomainList as $domain ) {
if ( ! $this -> quiet ) {
2024-04-13 20:35:20 +02:00
echo COLOR_DEFAULT . " Domain: " . COLOR_YELLOW . str_pad ( string : $domain -> getDomain (), length : $maxDomainNameLength );
2024-04-16 18:24:38 +02:00
}
2024-04-08 19:01:13 +02:00
2024-04-16 18:24:38 +02:00
if ( ! $domain -> isSubdomain ()) {
$this -> checkNS ( domainName : $domain -> getDomain (), panel : $panel );
$domainCount ++ ;
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( $domainCount == 0 ) {
if ( ! $this -> quiet ) {
2024-04-13 20:35:20 +02:00
echo 'No second level domains found.' . COLOR_DEFAULT . PHP_EOL ;
}
2024-04-16 18:24:38 +02:00
}
if ( ! $this -> quiet ) {
2024-04-13 20:35:20 +02:00
echo PHP_EOL ;
2024-04-16 18:24:38 +02:00
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
try {
sodium_memzero ( string : $decryptedKey );
} catch ( SodiumException $e ) {
exit ( $e -> getMessage () . PHP_EOL );
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
function isSubDomain ( Domain $domain ) : bool
{
$this -> logger -> debug ( message : " isSubDomain() " );
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
// valid second level domain
if ( ! Validator :: endsWithTld ( value : $domain )) {
return false ;
}
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
$domainParts = explode ( separator : '.' , string : $domain -> getName ());
$reversedParts = array_reverse ( array : $domainParts );
$testDomain = '' ;
$foundDomain = '' ;
foreach ( $reversedParts as $part ) {
if ( $testDomain ) {
$testDomain = $part . '.' . $testDomain ;
} else {
$testDomain = $part ;
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
if ( $this -> domainRepository -> findByName ( name : $testDomain )) {
$foundDomain = $testDomain ;
echo $part . PHP_EOL ;
2024-04-13 20:35:20 +02:00
}
2024-04-16 18:24:38 +02:00
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
echo " found domain *** " . $foundDomain . PHP_EOL ;
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/*
// system domain
if ( str_contains ( haystack : $domainName , needle : $panel )) {
return false ;
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
// no second level domain
if ( substr_count ( haystack : $domainName , needle : '.' ) > 1 ) {
return false ;
}
*/
return true ;
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
function isValidSecondLevelDomain ( string $domainName , string $panel , int $parent ) : bool
{
$this -> logger -> debug ( message : " isValidSecondLevelDomain() " );
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
// subdomain
if ( $parent != 0 ) {
return false ;
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
// system domain
if ( str_contains ( haystack : $domainName , needle : $panel )) {
return false ;
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
// valid second level domain
if ( ! Validator :: endsWithTld ( value : $domainName )) {
return false ;
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
// no second level domain
if ( substr_count ( haystack : $domainName , needle : '.' ) > 1 ) {
return false ;
2024-04-13 20:35:20 +02:00
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
return true ;
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
* @ param String $domainName
* @ param Panel $panel
*
* @ return void
*/
function checkNS ( string $domainName , Panel $panel ) : void
{
$this -> logger -> debug ( message : " checkNS() " );
2022-09-29 19:21:42 +02:00
2024-04-16 18:24:38 +02:00
$nameservers = $this -> nameserverRepository -> findAll ();
foreach ( $nameservers as $nameserver ) {
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
$encryptionKey = $this -> configController -> getConfig ( configKey : 'encryptionKey' );
$decryptedKey = $this -> encryptionController -> safeDecrypt ( encrypted : $nameserver -> getApikey (), key : $encryptionKey );
if ( ! $this -> quiet ) {
2024-04-13 20:35:20 +02:00
echo COLOR_YELLOW . ' ' . $nameserver -> getName ();
2024-04-16 18:24:38 +02:00
}
if ( ! empty ( $nameserver -> getName ())) {
$result = $this -> apiController -> sendCommand (
requestType : 'GET' ,
serverName : $nameserver -> getName (),
versionIP : 6 ,
apiKey : $decryptedKey ,
command : 'domains/name/' . $domainName ,
serverType : 'nameserver' );
} else {
$result = $this -> apiController -> sendCommand (
requestType : 'GET' ,
serverName : $nameserver -> getName (),
versionIP : 4 ,
apiKey : $decryptedKey (),
command : 'domains/name/' ,
serverType : 'nameserver' . $domainName );
}
2022-09-29 19:21:42 +02:00
2024-04-16 18:24:38 +02:00
switch ( $result [ 'header' ]) {
case 200 :
if ( ! $this -> quiet ) {
2024-04-13 20:35:20 +02:00
echo COLOR_GREEN . ' OK' ;
2024-04-16 18:24:38 +02:00
}
break ;
case 404 :
if ( ! $this -> quiet ) {
2024-04-13 20:35:20 +02:00
echo COLOR_RED . ' ' . $result [ 'header' ] . COLOR_DEFAULT ;
2024-04-16 18:24:38 +02:00
}
if ( ! empty ( $this -> arguments [ 'fix' ]) && $this -> arguments [ 'fix' ] == 'yes' ) {
if ( ! $this -> quiet ) {
echo ' trying to fix …' ;
}
$body = [
'name' => $domainName ,
'panel' => $panel -> getName (),
];
$encryptionKey = $this -> configController -> getConfig ( configKey : 'encryptionKey' );
$decryptedKey = $this -> encryptionController -> safeDecrypt ( encrypted : $nameserver -> getApikey (), key : $encryptionKey );
if ( ! empty ( $nameserver -> getAaaa ())) {
$create = $this -> apiController -> sendCommand (
requestType : 'POST' ,
serverName : $nameserver -> getName (),
versionIP : 6 ,
apiKey : $decryptedKey ,
command : 'domains' ,
serverType : 'nameserver' ,
body : $body );
} else {
$create = $this -> apiController -> sendCommand (
requestType : 'POST' ,
serverName : $nameserver -> getName (),
versionIP : 4 ,
apiKey : $decryptedKey (),
command : 'domains' ,
serverType : 'nameserver' ,
body : $body );
}
if ( $create [ 'header' ] != 201 ) {
print_r ( value : $create );
die ( " make error handling " );
} else {
2024-04-14 20:14:41 +02:00
if ( ! $this -> quiet ) {
2024-04-13 20:35:20 +02:00
echo COLOR_GREEN . 'OK' . COLOR_DEFAULT ;
}
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
}
break ;
default :
if ( ! $this -> quiet ) {
2024-04-13 20:35:20 +02:00
echo 'Server error' . PHP_EOL ;
2024-04-16 18:24:38 +02:00
}
exit ( 1 );
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
}
if ( ! $this -> quiet ) {
2024-04-13 20:35:20 +02:00
echo PHP_EOL ;
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
* @ param array $arguments
* @ return array
*/
public
function parseArguments ( array $arguments ) : array
{
$this -> logger -> debug ( message : " parseArguments() " );
$parsedArguments = [];
$parseCount = 0 ;
foreach ( $arguments as $argument ) {
if ( str_contains ( haystack : $argument , needle : '=' )) {
[ $key , $value ] = explode ( separator : '=' , string : $argument );
$parsedArguments [ strtolower ( string : $key )] = $value ;
$parsedArguments [ $parseCount ++ ] = $value ;
} else {
$parsedArguments [ strtolower ( string : $argument )] = $argument ;
$parsedArguments [ $parseCount ++ ] = $argument ;
2022-09-27 19:13:28 +02:00
}
}
2024-04-16 18:24:38 +02:00
return $parsedArguments ;
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
* @ return void
*/
function panelsCreate () : void
{
$this -> logger -> debug ( message : " panelsCreate() " );
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$name = $this -> arguments [ 1 ] ? ? '' ;
if ( empty ( $name )) {
echo 'You need to supply the panel name.' . PHP_EOL ;
exit ( 1 );
}
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
$filteredName = filter_var ( value : $name , filter : FILTER_VALIDATE_DOMAIN , options : FILTER_FLAG_HOSTNAME );
if ( ! empty ( $filteredName ) && str_contains ( haystack : $filteredName , needle : '.' )) {
$name = $filteredName ;
} else {
echo " $name is no valid DNS domain name. " . PHP_EOL ;
exit ( 1 );
}
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
$a = $this -> arguments [ 'a' ] ? ? '' ;
$aaaa = $this -> arguments [ 'aaaa' ] ? ? '' ;
if ( empty ( $a ) && empty ( $aaaa )) {
echo 'At least one IP address is required.' . PHP_EOL ;
exit ( 0 );
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
$apikey = $this -> arguments [ 'apikey' ] ? ? '' ;
$self = $this -> arguments [ 'self' ] ? ? 'no' ;
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( $this -> panelRepository -> findByName ( name : $name )) {
echo " Panel: $name already exists. " . PHP_EOL ;
exit ( 1 );
} else {
$panel = new Panel ( name : $name , a : $a , aaaa : $aaaa , passphrase : $apikey , self : $self );
$result = $this -> panelRepository -> insert ( panel : $panel );
echo " Panel $name has been created with id $result " . PHP_EOL ;
2022-09-27 19:13:28 +02:00
exit ( 0 );
}
2024-04-16 18:24:38 +02:00
}
/**
* @ return void
*/
function panelsList () : void
{
$this -> logger -> debug ( message : " panelsList() " );
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$panels = $this -> panelRepository -> findAll ();
if ( ! empty ( $panels )) {
echo 'All available panels:' . PHP_EOL ;
$table = new ConsoleTable ();
$table -> setHeaders ( content : [ 'ID' , 'Name' , 'A' , 'AAAA' , 'API Key (Prefix)' , 'This Panel' ]);
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
foreach ( $panels as $panel ) {
$row = [];
$row [] = $panel -> getID ();
$row [] = $panel -> getName ();
$row [] = $panel -> getA ();
$row [] = $panel -> getAaaa ();
$row [] = $panel -> getApikeyPrefix ();
$row [] = ucfirst ( string : $panel -> getSelf ());
$table -> addRow ( data : $row );
}
$table -> setPadding ( value : 2 );
$table -> display ();
} else {
echo 'No panels found.' . PHP_EOL ;
exit ( 1 );
}
exit ( 0 );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
*/
function panelsUpdate () : void
{
$this -> logger -> debug ( message : " panelsUpdate() " );
$id = intval ( value : $this -> arguments [ 1 ] ? ? 0 );
$name = $this -> arguments [ 'name' ] ? ? '' ;
$a = $this -> arguments [ 'a' ] ? ? '' ;
$aaaa = $this -> arguments [ 'aaaa' ] ? ? '' ;
$apikey = $this -> arguments [ 'apikey' ] ? ? '' ;
$self = $this -> arguments [ 'self' ] ? ? '' ;
if ( $id == 0 ) {
echo 'An ID is required' . PHP_EOL ;
exit ( 1 );
}
if ( ! $this -> panelRepository -> findByID ( id : $id )) {
echo " Panel with ID : $id doesn't exist. " . PHP_EOL ;
exit ( 1 );
}
if ( $apikey ) {
$panel = new Panel ( name : $name , id : $id , a : $a , aaaa : $aaaa , passphrase : $apikey , self : $self );
} else {
$panel = new Panel ( name : $name , id : $id , a : $a , aaaa : $aaaa , self : $self );
}
if ( $this -> panelRepository -> update ( panel : $panel ) !== false ) {
echo 'Panel ' . COLOR_YELLOW . $id . COLOR_DEFAULT . ' has been updated' . PHP_EOL ;
} else {
echo 'Error while updating domain server.' . PHP_EOL ;
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
*/
function panelsDelete () : void
{
$this -> logger -> debug ( message : " panelsDelete() " );
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( empty ( $this -> arguments [ 1 ])) {
echo " You need to supply an ID. " . PHP_EOL ;
exit ( 1 );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$id = intval ( value : $this -> arguments [ 1 ]) ? ? 0 ;
if ( $id == 0 ) {
echo " Panel with ID $id not found. " . PHP_EOL ;
exit ( 1 );
}
if ( ! $this -> panelRepository -> findByID ( id : $id )) {
echo " There is no panel with ID $id . " . PHP_EOL ;
exit ( 1 );
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
$this -> panelRepository -> delete ( id : $id );
echo " The panel with ID $id has been deleted. " . PHP_EOL ;
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
*/
function apiPing ( string $type ) : void
{
$this -> logger -> debug ( message : " apiPing() " );
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$error = false ;
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$id = $this -> getId ();
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( $id != 0 ) {
if ( $type == 'panel' ) {
$server = $this -> panelRepository -> findByID ( id : $id );
} else {
$server = $this -> nameserverRepository -> findByID ( id : $id );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( $server ) {
if ( ! $this -> checkPing ( server : $server , type : $type )) {
2022-09-27 19:13:28 +02:00
$error = true ;
}
} else {
2024-04-16 18:24:38 +02:00
if ( ! $this -> configController -> getConfig ( configKey : 'quiet' )) {
echo " Unknown $type ID $id " . PHP_EOL ;
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
$error = true ;
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
} else {
if ( $type == 'panel' ) {
$servers = $this -> panelRepository -> findAll ();
2022-09-27 19:13:28 +02:00
} else {
2024-04-16 18:24:38 +02:00
$servers = $this -> nameserverRepository -> findAll ();
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
if ( $servers ) {
foreach ( $servers as $server ) {
if ( ! $this -> checkPing ( server : $server , type : $type )) {
$error = true ;
}
2024-04-13 20:35:20 +02:00
}
} else {
2024-04-16 18:24:38 +02:00
echo 'No Servers of type ' . $type . ' defined' ;
2022-09-27 19:13:28 +02:00
}
}
2024-04-16 18:24:38 +02:00
if ( $error ) {
exit ( 1 );
} else {
exit ( 0 );
}
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
* @ return int | void
*/
public function getId ()
{
if ( ! empty ( $this -> arguments [ 1 ])) {
$id = intval ( value : $this -> arguments [ 1 ] ? ? 0 );
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( $id != $this -> arguments [ 1 ]) {
echo 'ID has to be a number.' . PHP_EOL ;
exit ( 1 );
2024-04-13 20:35:20 +02:00
}
2024-04-16 18:24:38 +02:00
} else {
$id = 0 ;
}
return $id ;
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
public function checkPing ( Panel | Nameserver $server , string $type ) : bool
{
$this -> logger -> debug ( message : " checkPing() - server, type: " . $server -> getName () . ', ' . $type );
$error = false ;
if ( $type == 'nameserver' ) {
$maxName = $this -> nameserverRepository -> getLongestEntry ( field : 'name' );
$maxA = $this -> nameserverRepository -> getLongestEntry ( field : 'a' );
$maxAAAA = $this -> nameserverRepository -> getLongestEntry ( field : 'aaaa' );
} else {
$maxName = $this -> panelRepository -> getLongestEntry ( field : 'name' );
$maxA = $this -> panelRepository -> getLongestEntry ( field : 'a' );
$maxAAAA = $this -> panelRepository -> getLongestEntry ( field : 'aaaa' );
}
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
if ( ! $this -> configController -> getConfig ( configKey : 'quiet' )) {
echo COLOR_YELLOW . str_pad ( string : $server -> getName (), length : $maxName );
}
$encryptionKey = $this -> configController -> getConfig ( configKey : 'encryptionKey' );
$decryptedKey = $this -> encryptionController -> safeDecrypt ( encrypted : $server -> getApikey (), key : $encryptionKey );
echo 'server: ' . $server -> getName () . PHP_EOL ;
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
$a = $server -> getA () ? ? '' ;
if ( ! empty ( $a )) {
$this -> logger -> debug ( " check a " );
if ( ! $this -> configController -> getConfig ( configKey : 'quiet' )) {
echo COLOR_DEFAULT . ' ' . str_pad ( string : $a , length : $maxA , pad_type : STR_PAD_LEFT ) . ' ' ;
}
if ( $result = $this -> apiController -> sendCommand (
requestType : 'GET' ,
serverName : $server -> getName (),
versionIP : 4 ,
apiKey : $decryptedKey ,
command : 'ping' ,
serverType : $type )) {
2022-09-27 19:13:28 +02:00
if ( ! $this -> configController -> getConfig ( configKey : 'quiet' )) {
2024-04-16 18:24:38 +02:00
if ( $result [ 'data' ] == 'pong' ) {
echo ' ' . COLOR_GREEN . $result [ 'data' ];
} else {
echo COLOR_BLUE . ' skip' . COLOR_DEFAULT ;
if ( ! $this -> configController -> getConfig ( configKey : 'quiet' )) {
echo ' ' . $result [ 'data' ];
2022-09-27 19:13:28 +02:00
}
}
}
2024-04-16 18:24:38 +02:00
} else {
$error = true ;
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
}
$aaaa = $server -> getAaaa () ? ? '' ;
if ( ! empty ( $aaaa )) {
$this -> logger -> debug ( " check aaaa " );
if ( ! $this -> configController -> getConfig ( configKey : 'quiet' )) {
echo COLOR_DEFAULT . ' ' . str_pad ( string : $aaaa , length : $maxAAAA , pad_type : STR_PAD_LEFT ) . ' ' ;
}
if ( $result = $this -> apiController -> sendCommand (
requestType : 'GET' ,
serverName : $server -> getName (),
versionIP : 6 ,
apiKey : $decryptedKey ,
command : 'ping' ,
serverType : $type )) {
2022-09-27 19:13:28 +02:00
if ( ! $this -> configController -> getConfig ( configKey : 'quiet' )) {
2024-04-16 18:24:38 +02:00
if ( $result [ 'data' ] == 'pong' ) {
echo ' ' . COLOR_GREEN . $result [ 'data' ];
} else {
echo COLOR_BLUE . ' skip' . COLOR_DEFAULT ;
if ( ! $this -> configController -> getConfig ( configKey : 'quiet' )) {
echo ' ' . $result [ 'data' ];
2022-09-27 19:13:28 +02:00
}
}
}
2024-04-16 18:24:38 +02:00
} else {
$error = true ;
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
}
try {
sodium_memzero ( string : $decryptedKey );
} catch ( SodiumException $e ) {
exit ( $e -> getMessage () . PHP_EOL );
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
if ( ! $this -> configController -> getConfig ( configKey : 'quiet' )) {
echo COLOR_DEFAULT . PHP_EOL ;
}
return ! $error ;
}
2022-09-16 14:59:23 +02:00
2024-04-16 18:24:38 +02:00
/**
* @ return void
*/
function apikeysCreate () : void
{
2024-04-17 20:28:51 +02:00
$name = $this -> arguments [ 1 ] ? ? '' ;
if ( empty ( $name )) {
echo 'You need to supply a descriptive name for the apikey.' . PHP_EOL ;
exit ( 1 );
}
2022-09-16 14:59:23 +02:00
2024-04-16 18:24:38 +02:00
$apiKeyPrefix = uniqid ();
try {
$apikeyRand = bin2hex ( string : random_bytes ( length : 24 ));
} catch ( Exception $e ) {
exit ( $e -> getMessage () . PHP_EOL );
}
2022-09-17 18:56:20 +02:00
2024-04-16 18:24:38 +02:00
$passphrase = password_hash ( password : $apiKeyPrefix . '.' . $apikeyRand , algo : PASSWORD_ARGON2ID );
2022-09-16 14:59:23 +02:00
2024-04-16 18:24:38 +02:00
$apikey = new Apikey ( name : $name , apikeyPrefix : $apiKeyPrefix , passphrase : $passphrase );
2022-09-16 14:59:23 +02:00
2024-04-16 18:24:38 +02:00
$result = $this -> apikeyRepository -> insert ( apikey : $apikey );
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( $name ) {
echo 'API key ' . COLOR_YELLOW . $name . COLOR_DEFAULT ;
} else {
echo 'Unnamed API key ' ;
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
echo ' with ID ' . COLOR_YELLOW . $result . COLOR_DEFAULT . ' has been generated. Store it in a safe place, it cannot be recovered.' . PHP_EOL ;
echo COLOR_YELLOW . $apiKeyPrefix . '.' . $apikeyRand . COLOR_DEFAULT . PHP_EOL ;
exit ( 0 );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
* @ return void
*/
function apikeysList () : void
{
$keys = $this -> apikeyRepository -> findAll ();
if ( ! empty ( $keys )) {
echo 'All valid API keys:' . PHP_EOL ;
$table = new ConsoleTable ();
$table -> setHeaders ( content : [ 'ID' , 'Name' , 'API key prefix' ]);
foreach ( $keys as $key ) {
$row = [];
$row [] = $key -> getID ();
$row [] = $key -> getName ();
$row [] = $key -> getApikeyPrefix ();
$table -> addRow ( data : $row );
}
$table -> setPadding ( value : 2 );
$table -> display ();
} else {
echo 'No keys found.' . PHP_EOL ;
}
exit ( 0 );
}
2022-09-17 17:39:47 +02:00
2024-04-16 18:24:38 +02:00
/**
*/
function apikeysUpdate () : void
{
$id = intval ( value : $this -> arguments [ 1 ]) ? ? 0 ;
$name = $this -> arguments [ 'name' ] ? ? '' ;
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
if ( $id == 0 ) {
echo 'An ID is required' . PHP_EOL ;
exit ( 1 );
}
if ( ! $this -> apikeyRepository -> findByID ( id : intval ( value : $id ))) {
echo " Apikeys with ID : $id doesn't exist. " . PHP_EOL ;
exit ( 1 );
}
if ( ! $name ) {
echo 'You need tu supply a name.' . PHP_EOL ;
exit ( 1 );
2022-09-27 19:13:28 +02:00
}
2022-09-16 14:59:23 +02:00
2024-04-16 18:24:38 +02:00
$apikey = new Apikey ( id : $id , name : $name );
if ( $this -> apikeyRepository -> update ( apikey : $apikey ) !== false ) {
echo 'Apikey has been updated' . PHP_EOL ;
} else {
echo 'Error while updating apikey.' . PHP_EOL ;
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
* @ return void
*/
function apikeysDelete () : void
{
$id = intval ( value : $this -> arguments [ 1 ] ? ? 0 );
if ( $id == 0 ) {
echo 'You need to add the ID of the API key.' . PHP_EOL ;
exit ( 1 );
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
if ( $this -> apikeyRepository -> findByID ( id : $id )) {
$this -> apikeyRepository -> delete ( id : $id );
echo 'API key ' . COLOR_YELLOW . $id . COLOR_DEFAULT . ' has been deleted.' . PHP_EOL ;
2024-04-13 20:35:20 +02:00
exit ( 0 );
2024-04-16 18:24:38 +02:00
} else {
echo 'Unknown ID ' . COLOR_YELLOW . $id . '.' . PHP_EOL ;
exit ( 1 );
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
}
2022-09-16 14:59:23 +02:00
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
* @ return void
*/
function domainsList () : void
{
$domains = $this -> domainRepository -> findAll ();
if ( ! empty ( $domains )) {
echo 'All available domains:' . PHP_EOL ;
$table = new ConsoleTable ();
$table -> setHeaders ( content : [ 'ID' , 'Name' , 'Panel' , 'Type' ]);
/** @var Domain $domain */
foreach ( $domains as $domain ) {
$row = [];
$row [] = $domain -> getId ();
$row [] = $domain -> getName ();
$row [] = $domain -> getPanel ();
$row [] = $this -> domainController -> isMasterZone ( domain : $domain ) ? 'MASTER' : 'SLAVE' ;
$table -> addRow ( data : $row );
}
$table -> setPadding ( value : 2 );
$table -> display ();
} else {
echo 'No domains found.' . PHP_EOL ;
}
exit ( 0 );
}
2022-09-16 14:59:23 +02:00
2024-04-16 18:24:38 +02:00
/**
* @ return void
*/
function dynDnsList () : void
{
$dyndns = $this -> dynDNSRepository -> findAll ();
if ( ! empty ( $dyndns )) {
echo 'All available DynDNS hosts:' . PHP_EOL ;
$table = new ConsoleTable ();
$table -> setHeaders ( content : [ 'ID' , 'Name' , 'Panel' , 'Type' ]);
/** @var \App\Entity\DynDNS $dyndnsHost */
foreach ( $dyndns as $dyndnsHost ) {
$row = [];
$row [] = $dyndnsHost -> getId ();
$row [] = $dyndnsHost -> getName ();
$table -> addRow ( data : $row );
}
$table -> setPadding ( value : 2 );
$table -> display ();
} else {
echo 'No DynDNS hosts found.' . PHP_EOL ;
}
exit ( 0 );
}
2022-09-16 14:59:23 +02:00
2024-04-16 18:24:38 +02:00
/**
* @ return void
*/
function dynDnsCreate () : void
{
$name = $this -> arguments [ 1 ] ? ? '' ;
if ( empty ( $name )) {
echo 'You need to supply the FQDN (hostname).' . PHP_EOL ;
exit ( 1 );
}
2022-09-16 14:59:23 +02:00
2024-04-16 18:24:38 +02:00
$filteredName = filter_var ( value : $name , filter : FILTER_VALIDATE_DOMAIN , options : FILTER_FLAG_HOSTNAME );
if ( ! empty ( $filteredName ) && str_contains ( haystack : $filteredName , needle : '.' )) {
$name = $filteredName ;
} else {
echo " $name is no valid DNS domain name. " . PHP_EOL ;
exit ( 1 );
}
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
$password = $this -> arguments [ 2 ] ? ? '' ;
2022-09-17 18:56:20 +02:00
2024-04-16 18:24:38 +02:00
var_dump ( $this -> arguments );
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
die ();
$domainParts = explode ( separator : '.' , string : $name );
$reversedParts = array_reverse ( array : $domainParts );
$testDomain = '' ;
$foundDomain = '' ;
foreach ( $reversedParts as $part ) {
if ( $testDomain ) {
$testDomain = $part . '.' . $testDomain ;
2024-04-13 20:35:20 +02:00
} else {
2024-04-16 18:24:38 +02:00
$testDomain = $part ;
}
if ( $this -> domainRepository -> findByName ( name : $testDomain )) {
$foundDomain = $testDomain ;
echo $part . PHP_EOL ;
2024-04-13 20:35:20 +02:00
}
2024-04-16 18:24:38 +02:00
}
if ( ! $foundDomain ) {
echo 'No matching domain found for this panel.' . PHP_EOL ;
exit ( 1 );
2022-09-16 14:59:23 +02:00
2024-04-16 18:24:38 +02:00
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( ! $this -> configController -> getConfig ( configKey : 'quiet' )) {
echo " Found domain: " . COLOR_YELLOW . $foundDomain . COLOR_DEFAULT . PHP_EOL ;
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
// get host
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
if ( $this -> dynDNSRepository -> findByName ( name : $name )) {
if ( ! $this -> configController -> getConfig ( configKey : 'quiet' )) {
echo " DynDNS host " . COLOR_YELLOW . $name . COLOR_DEFAULT . " already exists. " . PHP_EOL ;
2024-04-13 20:35:20 +02:00
exit ( 0 );
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
} else {
if ( ! $this -> configController -> getConfig ( configKey : 'quiet' )) {
echo " DynDNS host " . COLOR_YELLOW . $name . COLOR_DEFAULT . " will be created. " . PHP_EOL ;
// insert in db
$dyndnsHost = new DynDNS ( name : $name );
// why is the property set in the cunstructor and afterwards again? FIXME
$dyndnsHost -> setName ( name : $name );
}
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
// check on NS
// => add if missing
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( $this -> domainRepository -> findByName ( name : $name )) {
echo " Domain: $name already exists. " . PHP_EOL ;
exit ( 1 );
} else {
if ( ! $this -> panelRepository -> findByName ( name : $panel )) {
echo 'Unknown panel: ' . COLOR_YELLOW . $panel . COLOR_DEFAULT . '.' . PHP_EOL ;
2024-04-13 20:35:20 +02:00
exit ( 1 );
}
2024-04-16 18:24:38 +02:00
$domain = new Domain ( name : $name , panel : $panel );
$result = $this -> domainRepository -> insert ( domain : $domain );
echo 'Domain' . COLOR_YELLOW . $name . COLOR_DEFAULT . ' has been created with id ' . COLOR_YELLOW . $result . COLOR_DEFAULT . '.' . PHP_EOL ;
$this -> domainController -> createSlaveZoneFile ( domain : $domain );
exit ( 0 );
}
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
function domainsCreate () : void
{
// check if we're correctly setup
if ( ! $this -> domainController -> checkPermissions ()) {
echo 'You need to setup the bindAPI first.' . PHP_EOL ;
exit ( 1 );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$name = $this -> arguments [ 1 ] ? ? " " ;
if ( empty ( $name )) {
echo 'You need to supply the domain name.' . PHP_EOL ;
exit ( 1 );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$filteredName = filter_var ( value : $name , filter : FILTER_VALIDATE_DOMAIN , options : FILTER_FLAG_HOSTNAME );
if ( ! empty ( $filteredName ) && str_contains ( haystack : $filteredName , needle : '.' )) {
$name = $filteredName ;
} else {
echo " $name is no valid DNS domain name. " . PHP_EOL ;
exit ( 1 );
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
$panel = $this -> arguments [ 'panel' ] ? ? '' ;
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( empty ( $panel )) {
echo 'You need to supply the panel name.' . PHP_EOL ;
exit ( 1 );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( $this -> domainRepository -> findByName ( name : $name )) {
echo " Domain: $name already exists. " . PHP_EOL ;
exit ( 1 );
} else {
if ( ! $this -> panelRepository -> findByName ( name : $panel )) {
echo 'Unknown panel: ' . COLOR_YELLOW . $panel . COLOR_DEFAULT . '.' . PHP_EOL ;
2024-04-13 20:35:20 +02:00
exit ( 1 );
}
2024-04-16 18:24:38 +02:00
$domain = new Domain ( name : $name , panel : $panel );
$result = $this -> domainRepository -> insert ( domain : $domain );
echo 'Domain' . COLOR_YELLOW . $name . COLOR_DEFAULT . ' has been created with id ' . COLOR_YELLOW . $result . COLOR_DEFAULT . '.' . PHP_EOL ;
$this -> domainController -> createSlaveZoneFile ( domain : $domain );
exit ( 0 );
}
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
*/
function domainsUpdate () : void
{
// check if we're correctly setup
if ( ! $this -> domainController -> checkPermissions ()) {
echo 'You need to setup the bindAPI first.' . PHP_EOL ;
exit ( 1 );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$id = intval ( value : $this -> arguments [ 1 ] ? ? 0 );
$name = $this -> arguments [ 'name' ] ? ? '' ;
$panelName = $this -> arguments [ 'panel' ] ? ? '' ;
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( $id == 0 ) {
echo 'An ID is required' . PHP_EOL ;
exit ( 1 );
}
if ( ! $domain = $this -> domainRepository -> findByID ( id : $id )) {
echo " Domain with ID : $id doesn't exist. " . PHP_EOL ;
exit ( 1 );
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
if ( ! empty ( $panelName )) {
$panel = $this -> panelRepository -> findByName ( name : $panelName );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( empty ( $name ) && empty ( $panel )) {
echo COLOR_DEFAULT . 'No name or panel given, just recreate the config file' . PHP_EOL ;
$this -> domainController -> updateSlaveZones ();
exit ( 1 );
}
$newDomain = new Domain ( name : $name , panel : $panelName , id : $domain -> getId ());
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( $this -> domainRepository -> update ( domain : $newDomain ) !== false ) {
echo 'Domain server has been updated' . PHP_EOL ;
$this -> domainController -> updateSlaveZones ();
} else {
echo 'Error while updating domain server.' . PHP_EOL ;
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
*/
function domainsDelete () : void
{
if ( empty ( $this -> arguments [ 1 ])) {
echo " You need to supply an ID. " . PHP_EOL ;
exit ( 1 );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$id = intval ( value : $this -> arguments [ 1 ]) ? ? 0 ;
if ( $id == 0 ) {
echo " Domain with ID $id not found. " . PHP_EOL ;
exit ( 1 );
}
if ( ! $domain = $this -> domainRepository -> findByID ( id : $id )) {
echo " There is no domain with ID $id . " . PHP_EOL ;
exit ( 1 );
}
$this -> domainRepository -> delete ( domain : $domain );
$this -> domainController -> deleteZone ( domain : $domain );
echo " The domain with ID $id has been deleted. " . PHP_EOL ;
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
* @ return void
*/
function nameserversCreate () : void
{
$name = $this -> arguments [ 1 ] ? ? '' ;
if ( empty ( $name )) {
echo 'You need to supply the nameserver name.' . PHP_EOL ;
exit ( 1 );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$filteredName = filter_var ( value : $name , filter : FILTER_VALIDATE_DOMAIN );
if ( ! empty ( $filteredName ) && str_contains ( haystack : $filteredName , needle : '.' )) {
$name = $filteredName ;
} else {
echo " $name is no valid nameserver name. " . PHP_EOL ;
exit ( 1 );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
$a = $this -> arguments [ 'a' ] ? ? '' ;
$aaaa = $this -> arguments [ 'aaaa' ] ? ? '' ;
if ( empty ( $a ) && empty ( $aaaa )) {
echo 'At least one IP address is required.' . PHP_EOL ;
exit ( 0 );
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
$apikey = $this -> arguments [ 'apikey' ] ? ? '' ;
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( empty ( $apikey )) {
echo 'An API key is required.' . PHP_EOL ;
exit ( 0 );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( $this -> nameserverRepository -> findByName ( name : $name )) {
echo " Nameserver: $name already exists. " . PHP_EOL ;
exit ( 1 );
} else {
$nameserver = new Nameserver ( name : $name , a : $a , aaaa : $aaaa , passphrase : $apikey );
$result = $this -> nameserverRepository -> insert ( nameserver : $nameserver );
echo 'Nameserver ' . COLOR_YELLOW . $name . COLOR_DEFAULT . ' has been created with id ' . COLOR_YELLOW . $result . COLOR_DEFAULT . PHP_EOL ;
2024-04-13 20:35:20 +02:00
exit ( 0 );
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
* @ return void
*/
function nameserversList () : void
{
$nameservers = $this -> nameserverRepository -> findAll ();
if ( ! empty ( $nameservers )) {
echo 'All available nameservers:' . PHP_EOL ;
$table = new ConsoleTable ();
$table -> setHeaders ( content : [ 'ID' , 'Name' , 'A' , 'AAAA' , 'API Key' ]);
foreach ( $nameservers as $nameserver ) {
$row = [];
$row [] = $nameserver -> getId ();
$row [] = $nameserver -> getName ();
$row [] = $nameserver -> getA ();
$row [] = $nameserver -> getAaaa ();
$row [] = $nameserver -> getApikeyPrefix ();
$table -> addRow ( data : $row );
}
$table -> setPadding ( value : 2 );
$table -> display ();
} else {
echo 'No nameservers found.' . PHP_EOL ;
exit ( 1 );
}
exit ( 0 );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
*/
function nameserversUpdate () : void
{
$id = $this -> arguments [ 1 ] ? ? 0 ;
$name = $this -> arguments [ 'name' ] ? ? '' ;
$a = $this -> arguments [ 'a' ] ? ? '' ;
$aaaa = $this -> arguments [ 'aaaa' ] ? ? '' ;
$apikey = $this -> arguments [ 'apikey' ] ? ? '' ;
if ( $id == 0 ) {
echo 'An ID is required.' . PHP_EOL ;
exit ( 1 );
}
if ( ! $this -> nameserverRepository -> findByID ( id : intval ( value : $id ))) {
echo 'Nameserver with ID ' . COLOR_YELLOW . $id . COLOR_DEFAULT . " doesn't exist. " . PHP_EOL ;
exit ( 1 );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( $apikey ) {
$nameserver = new Nameserver ( name : $name , id : intval ( value : $id ), a : $a , aaaa : $aaaa , passphrase : $apikey );
} else {
$nameserver = new Nameserver ( name : $name , id : intval ( value : $id ), a : $a , aaaa : $aaaa );
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
if ( $this -> nameserverRepository -> update ( nameserver : $nameserver ) !== false ) {
echo 'Nameserver ' . COLOR_YELLOW . $id . COLOR_DEFAULT . ' has been updated.' . PHP_EOL ;
} else {
echo 'Error while updating nameserver ' . COLOR_YELLOW . $id . '.' . PHP_EOL ;
}
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
*/
function nameserversDelete () : void
{
if ( empty ( $this -> arguments [ 1 ])) {
echo " You need to supply an ID. " . PHP_EOL ;
exit ( 1 );
}
$id = intval ( value : $this -> arguments [ 1 ] ? ? 0 );
if ( $id == 0 ) {
echo 'Nameserver with ID ' . COLOR_YELLOW . $id . COLOR_DEFAULT . ' not found.' . PHP_EOL ;
exit ( 1 );
}
if ( ! $this -> nameserverRepository -> findByID ( id : $id )) {
echo 'There is no nameserver with ID ' . COLOR_YELLOW . $id . COLOR_DEFAULT . '.' . PHP_EOL ;
exit ( 1 );
}
$this -> nameserverRepository -> delete ( id : $id );
echo 'The nameserver with ID ' . COLOR_YELLOW . $id . COLOR_DEFAULT . ' has been deleted.' . PHP_EOL ;
}
/**
*/
function checkShowIncludes () : void
{
$nameservers = $this -> nameserverRepository -> findAll ();
if ( count ( $nameservers ) === 0 ) {
echo 'No nameservers found.' . PHP_EOL ;
echo 'You first need to setup the system.' . PHP_EOL ;
exit ( 1 );
}
echo COLOR_DEFAULT . 'You need to add these lines to ' . COLOR_YELLOW . '/etc/bind/local.bindapi.options' . COLOR_DEFAULT . ' on every panel and make sure' . PHP_EOL ;
echo 'that ' . COLOR_YELLOW . 'include "/etc/bind/local.bindapi.options";' . COLOR_DEFAULT . ' exists in ' . COLOR_YELLOW . '/etc/bind/named.conf.options' . COLOR_DEFAULT . '.' . PHP_EOL ;
$ip = [];
foreach ( $nameservers as $nameserver ) {
if ( ! empty ( $nameserver -> getA ())) {
$ip [] = $nameserver -> getA ();
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
if ( ! empty ( $nameserver -> getAaaa ())) {
$ip [] = $nameserver -> getAaaa ();
2022-09-27 19:13:28 +02:00
}
}
2024-04-16 18:24:38 +02:00
echo PHP_EOL . 'allow-transfer {' . PHP_EOL ;
foreach ( $ip as $currentIp )
echo " \t $currentIp ; " . PHP_EOL ;
echo '};' ;
echo PHP_EOL . 'also-notify {' . PHP_EOL ;
foreach ( $ip as $currentIp )
echo " \t $currentIp ; " . PHP_EOL ;
echo '};' . PHP_EOL ;
echo PHP_EOL . 'After the modification feel free to run ' . COLOR_YELLOW . 'named-checkconf' . COLOR_DEFAULT . ' to ensure there were no errors.' . PHP_EOL ;
echo PHP_EOL . 'Run ' . COLOR_YELLOW . 'rndc reload' . COLOR_DEFAULT . ' to activate the changes.' . PHP_EOL ;
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
*/
function checkDomains () : void
{
$this -> domainController -> checkDomains ();
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
*/
private function dynDnsPush () : void
{
$hostName = $this -> arguments [ 1 ] ? ? '' ;
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( empty ( $hostName )) {
echo 'You need to supply at least the hostname' . PHP_EOL ;
exit ( 1 );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
if ( ! $this -> configController -> getConfig ( configKey : 'quiet' )) {
echo " Updating DynDNS host: $hostName " . PHP_EOL ;
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
echo 'here' ;
$domain = $this -> domainRepository -> findByHost ( host : $hostName );
print_r ( value : $domain );
echo 'there' ;
// we need the panel who is master for zone
$panel = $this -> panelRepository -> findByName ( name : $domain -> getPanel ());
// which NS belongs to that panel
$encryptionKey = $this -> configController -> getConfig ( configKey : 'encryptionKey' );
$decryptedKey = $this -> encryptionController -> safeDecrypt ( encrypted : $panel -> getApikey (), key : $encryptionKey );
if ( ! empty ( $panel -> getAaaa ())) {
$result = $this -> apiController -> sendCommand (
requestType : 'POST' ,
serverName : $panel -> getName (),
versionIP : 6 ,
apiKey : $decryptedKey ,
command : 'dyndns/' . $hostName ,
serverType : 'nameserver' );
} else {
$result = $this -> apiController -> sendCommand (
requestType : 'POST' ,
serverName : $panel -> getName (),
versionIP : 4 ,
apiKey : $decryptedKey (),
command : 'dyndns/' . $hostName ,
serverType : 'nameserver' );
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
if ( $result [ 'header' ] == 200 ) {
if ( ! $this -> configController -> getConfig ( configKey : 'quiet' )) {
$data = $result [ 'data' ];
$decodedData = json_decode ( json : $data , associative : true );
echo $decodedData [ 'message' ] . PHP_EOL ;
}
} else {
echo 'Something went wrong:' . PHP_EOL ;
print_r ( value : $result );
exit ( 1 );
}
exit ( 0 );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
/**
*/
private
function checkGenerateKey () : void
{
echo 'This generates a fresh encryption key.' . PHP_EOL ;
echo 'Copy it to config.json.' . PHP_EOL ;
echo 'Note: You must update all API-Keys for panels and nameservers after changing the key!' . PHP_EOL ;
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
try {
$key = sodium_bin2hex ( string : sodium_crypto_secretbox_keygen ());
echo 'Suggested new key : "' . COLOR_YELLOW . $key . COLOR_DEFAULT . '".' . PHP_EOL ;
echo PHP_EOL ;
exit ( 0 );
} catch ( SodiumException $e ) {
exit ( $e -> getMessage () . PHP_EOL );
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
}
2022-09-27 19:13:28 +02:00
2024-04-16 18:24:38 +02:00
private function domainsRefresh () : void
{
$this -> logger -> debug ( message : " domainsRefresh() " );
2022-09-29 19:21:42 +02:00
2024-04-16 18:24:38 +02:00
$panels = $this -> panelRepository -> findAll ();
foreach ( $panels as $panel ) {
if ( ! $this -> quiet ) {
echo COLOR_DEFAULT . 'Checking panel ' . COLOR_YELLOW . $panel -> getName () . COLOR_DEFAULT . PHP_EOL ;
$longestEntry = $this -> domainRepository -> getLongestEntry ( field : 'name' );
}
2022-09-29 19:21:42 +02:00
$encryptionKey = $this -> configController -> getConfig ( configKey : 'encryptionKey' );
2024-04-16 18:24:38 +02:00
$decryptedKey = $this -> encryptionController -> safeDecrypt ( encrypted : $panel -> getApikey (), key : $encryptionKey );
$currentDomains = $this -> domainRepository -> findByPanel ( name : $panel -> getName ());
2022-09-29 19:21:42 +02:00
2024-04-16 18:24:38 +02:00
if ( empty ( $panel -> getA ())) {
2022-09-27 19:13:28 +02:00
$result = $this -> apiController -> sendCommand (
2024-04-16 18:24:38 +02:00
requestType : 'GET' ,
serverName : $panel -> getName (),
versionIP : 6 ,
apiKey : $decryptedKey ,
command : 'domains?sort=domain&subdomains=false' ,
serverType : 'panel'
);
2022-09-27 19:13:28 +02:00
} else {
$result = $this -> apiController -> sendCommand (
2024-04-16 18:24:38 +02:00
requestType : 'GET' ,
serverName : $panel -> getName (),
versionIP : 4 ,
apiKey : $decryptedKey ,
command : 'domains?sort=domain&subdomains=false' ,
serverType : 'panel' );
2022-09-27 19:13:28 +02:00
}
2024-04-16 18:24:38 +02:00
if ( ! empty ( $result [ 'error' ])) {
echo $result [ 'data' ] . PHP_EOL ;
2022-09-27 19:13:28 +02:00
exit ( 1 );
}
2024-04-16 18:24:38 +02:00
if ( ! empty ( $result [ 'data' ])) {
$domains = json_decode ( json : $result [ 'data' ]);
} else {
echo 'No domains found' . PHP_EOL ;
exit ( 1 );
2022-09-27 19:13:28 +02:00
}
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
$domainCount = 0 ;
if ( count ( $domains ) > 0 ) {
foreach ( $domains as $domain ) {
$domainCount ++ ;
if ( ! $this -> quiet ) {
echo COLOR_YELLOW . ' ' . str_pad ( string : $domain -> domain , length : $longestEntry + 1 , pad_type : STR_PAD_RIGHT );
}
2024-04-17 13:34:01 +02:00
if ( $currentDomain = $this -> domainRepository -> findByName ( name : $domain -> domain )) {
$currentPanel = $currentDomain -> getPanel ();
2024-04-16 18:24:38 +02:00
$panelName = $panel -> getName ();
if ( strcmp ( string1 : $currentPanel , string2 : $panelName )) {
2024-04-17 13:34:01 +02:00
$currentDomain -> setPanel ( panel : $panelName );
$this -> domainRepository -> update ( domain : $currentDomain );
2024-04-16 18:24:38 +02:00
if ( ! $this -> quiet ) {
echo COLOR_DEFAULT . ' updated to: ' . COLOR_YELLOW . $panelName ;
}
}
if ( ! $this -> quiet ) {
2024-04-13 20:35:20 +02:00
echo COLOR_GREEN . ' OK' . COLOR_DEFAULT . PHP_EOL ;
2024-04-16 18:24:38 +02:00
}
} else {
2024-04-17 13:34:01 +02:00
$newDomain = new Domain ( name : $domain -> domain , panel : $panel -> getName ());
2024-04-16 18:24:38 +02:00
$result = $this -> domainRepository -> insert ( domain : $newDomain );
if ( ! $this -> quiet ) {
2024-04-13 20:35:20 +02:00
echo COLOR_DEFAULT . ' has been created with id ' . COLOR_YELLOW . $result . COLOR_DEFAULT . '.' . PHP_EOL ;
}
}
2024-04-17 13:34:01 +02:00
unset ( $currentDomains [ $domain -> domain ]);
2024-04-13 20:35:20 +02:00
}
2024-04-16 18:24:38 +02:00
}
if ( $domainCount == 0 ) {
echo 'No second level domains found.' . COLOR_DEFAULT . PHP_EOL ;
}
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
//clean up stale domains
if ( count ( $currentDomains ) > 0 ) {
echo 'Dropping stale domains:' . PHP_EOL ;
foreach ( $currentDomains as $domain ) {
echo $domain -> getName () . PHP_EOL ;
$this -> domainRepository -> delete ( domain : $domain );
2024-04-13 20:35:20 +02:00
}
2022-09-29 19:21:42 +02:00
}
2024-04-16 18:24:38 +02:00
2022-09-29 19:21:42 +02:00
}
2024-04-16 18:24:38 +02:00
if ( ! $this -> quiet ) {
echo 'Creating slave zone files' . PHP_EOL ;
}
$this -> domainController -> updateSlaveZones ();
}
2022-09-29 19:21:42 +02:00
2024-04-16 18:24:38 +02:00
public function webmailCheck () : void
{
$quiet = $this -> configController -> getConfig ( configKey : 'quiet' );
2022-09-29 19:21:42 +02:00
2024-04-16 18:24:38 +02:00
if ( empty ( $this -> arguments [ 1 ])) {
if ( ! $quiet ) {
echo COLOR_DEFAULT . 'You need to supply a domain name.' . PHP_EOL ;
2024-04-13 20:35:20 +02:00
}
2024-04-16 18:24:38 +02:00
exit ( 1 );
} else {
$domainName = $this -> arguments [ 1 ];
}
2022-09-29 19:21:42 +02:00
2024-04-16 18:24:38 +02:00
if ( ! $quiet ) {
echo COLOR_DEFAULT . 'Checking domain ' . COLOR_YELLOW . $domainName . COLOR_DEFAULT . '.' . PHP_EOL ;
}
if ( ! $domain = $this -> domainRepository -> findByName ( name : $domainName )) {
2024-04-08 19:01:13 +02:00
if ( ! $quiet ) {
2024-04-16 18:24:38 +02:00
echo COLOR_DEFAULT . 'Domain ' . $domainName . ' not found on this server.' . PHP_EOL ;
2024-04-13 20:35:20 +02:00
}
2024-04-16 18:24:38 +02:00
exit ( 1 );
}
2022-09-29 19:21:42 +02:00
2024-04-16 18:24:38 +02:00
if ( ! $this -> domainController -> isMasterZone ( domain : $domain )) {
if ( ! $quiet ) {
echo 'This server is not responsible for ' . COLOR_YELLOW . $domainName . COLOR_DEFAULT . '.' . PHP_EOL ;
2022-09-29 19:21:42 +02:00
}
2024-04-16 18:24:38 +02:00
exit ( 1 );
}
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
$panel = $this -> panelRepository -> getSelf ();
2022-09-29 19:21:42 +02:00
2024-04-16 18:24:38 +02:00
$encryptionKey = $this -> configController -> getConfig ( configKey : 'encryptionKey' );
$decryptedKey = $this -> encryptionController -> safeDecrypt ( encrypted : $panel -> getApikey (), key : $encryptionKey );
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
$webmailDomain = 'webmail.' . $domainName ;
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
if ( ! empty ( $panel -> getAAAA ())) {
if ( ! $quiet ) {
echo 'Check using IPv6: ' . COLOR_YELLOW . $panel -> getAaaa () . '.' . COLOR_DEFAULT . PHP_EOL ;
}
$result = $this -> apiController -> sendCommand (
requestType : 'GET' ,
serverName : $panel -> getName (),
versionIP : 6 ,
apiKey : $decryptedKey ,
command : 'domains/name/' . $webmailDomain ,
serverType : 'panel' );
} else {
if ( ! $quiet ) {
echo 'Check using IPv4: ' . COLOR_YELLOW . $panel -> getA () . COLOR_DEFAULT . PHP_EOL ;
}
$result = $this -> apiController -> sendCommand (
requestType : 'GET' ,
serverName : $panel -> getName (),
versionIP : 4 ,
apiKey : $decryptedKey ,
command : 'domains/name/' . $webmailDomain ,
serverType : 'panel' );
}
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
if ( $result [ 'header' ] === 404 ) {
if ( ! $quiet ) {
echo 'The domain ' . COLOR_YELLOW . $webmailDomain . COLOR_DEFAULT . " doesn't exist. " . PHP_EOL ;
}
exit ( 1 );
} else {
if ( ! $quiet ) {
echo 'Found ' . COLOR_YELLOW . $webmailDomain . COLOR_DEFAULT . '.' . PHP_EOL ;
}
}
if ( $v4 = dns_get_record ( hostname : $webmailDomain , type : DNS_A )[ 0 ]) {
if ( ! $quiet ) {
echo " Found IPv4 entry: " . COLOR_YELLOW . $v4 [ 'ip' ] . COLOR_DEFAULT . '.' . PHP_EOL ;
2022-10-08 10:54:55 +02:00
}
2024-04-16 18:24:38 +02:00
$v4Test = $this -> apiController -> fileGetContents ( url : $webmailDomain , versionIP : 4 );
2022-10-08 10:54:55 +02:00
2024-04-16 18:24:38 +02:00
if ( $v4Test [ 'error' ]) {
2022-10-08 10:54:55 +02:00
if ( ! $quiet ) {
2024-04-16 18:24:38 +02:00
echo 'There was an error: ' . COLOR_YELLOW . $v4Test [ 'errorMessage' ] . COLOR_DEFAULT . '.' ;
2022-10-08 10:54:55 +02:00
}
exit ( 1 );
} else {
if ( ! $quiet ) {
2024-04-16 18:24:38 +02:00
echo 'Successfully connected to webserver via ' . COLOR_YELLOW . 'IPv4' . COLOR_DEFAULT . '.' . PHP_EOL ;
2022-10-08 10:54:55 +02:00
}
}
2024-04-16 18:24:38 +02:00
} else {
if ( ! $quiet ) {
echo " Found no IPv4 entry for " . COLOR_YELLOW . $webmailDomain . COLOR_DEFAULT . PHP_EOL ;
}
}
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
if ( $v6 = dns_get_record ( hostname : $webmailDomain , type : DNS_AAAA )[ 0 ]) {
if ( ! $quiet ) {
echo " Found IPv6 entry: " . COLOR_YELLOW . $v6 [ 'ipv6' ] . COLOR_DEFAULT . '.' . PHP_EOL ;
2022-10-08 10:54:55 +02:00
}
2024-04-16 18:24:38 +02:00
$v6Test = $this -> apiController -> fileGetContents ( url : $webmailDomain , versionIP : 6 );
2022-10-08 10:54:55 +02:00
2024-04-16 18:24:38 +02:00
if ( $v6Test [ 'error' ]) {
2024-04-13 20:35:20 +02:00
if ( ! $quiet ) {
2024-04-16 18:24:38 +02:00
echo 'There was an error: ' . COLOR_YELLOW . $v6Test [ 'errorMessage' ] . COLOR_DEFAULT . '.' ;
2024-04-13 20:35:20 +02:00
}
2024-04-16 18:24:38 +02:00
exit ( 1 );
2024-04-13 20:35:20 +02:00
} else {
if ( ! $quiet ) {
2024-04-16 18:24:38 +02:00
echo 'Successfully connected to webserver via ' . COLOR_YELLOW . 'IPv6' . COLOR_DEFAULT . '.' . PHP_EOL ;
2024-04-13 20:35:20 +02:00
}
2022-10-08 10:54:55 +02:00
}
2024-04-16 18:24:38 +02:00
} else {
if ( ! $quiet ) {
echo " Found no IPv6 entry for " . COLOR_YELLOW . $webmailDomain . COLOR_DEFAULT . '.' . PHP_EOL ;
}
}
2022-10-08 10:54:55 +02:00
2024-04-16 18:24:38 +02:00
// TODO check that at least IPv4 or IP6 exists?
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
$domainData = json_decode ( json : $result [ 'data' ]);
$apacheData = $domainData -> apache ;
$httpsDirectives = $apacheData -> https_directives . PHP_EOL ;
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
if ( ! str_contains ( haystack : $httpsDirectives , needle : '# bindAPI - webmailer' )) {
if ( ! $quiet ) {
echo 'Generated config is missing.' . PHP_EOL ;
}
exit ( 1 );
} else {
if ( ! $quiet ) {
echo 'Generated config is valid.' . PHP_EOL ;
2022-10-08 10:54:55 +02:00
}
2024-04-16 18:24:38 +02:00
exit ( 0 );
2022-10-08 10:54:55 +02:00
}
2024-04-16 18:24:38 +02:00
}
2022-10-08 10:54:55 +02:00
2024-04-16 18:24:38 +02:00
/**
* @ return void
*/
public function webmailCreate () : bool
{
2022-10-08 10:54:55 +02:00
2024-04-16 18:24:38 +02:00
// TODO
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
/*
$webmailConfig = '# bindAPI - webmailer' . PHP_EOL ;
$webmailConfig .= 'SSLProxyEngine On' . PHP_EOL ;
$webmailConfig .= 'ProxyPass /.well-known/ !' . PHP_EOL ;
$webmailConfig .= 'ProxyPass "/" "https://webmail' . $panel -> getName () . '"' . PHP_EOL ;
$webmailConfig .= '## bindAPI - webmailer' . PHP_EOL ;
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
echo $webmailConfig ;
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
//$httpsDirectives += $w
*/
2022-09-29 19:21:42 +02:00
2024-04-16 18:24:38 +02:00
}
2022-09-29 19:21:42 +02:00
2024-04-16 18:24:38 +02:00
private function checkMail () : void
{
echo 'Not yet implemented.' . PHP_EOL ;
}
2022-09-29 19:21:42 +02:00
2024-04-16 18:24:38 +02:00
private function checksVersion () : void
{
echo 'Not yet implemented.' . PHP_EOL ;
}
2022-09-29 19:21:42 +02:00
2024-04-16 18:24:38 +02:00
private function dynDnyUpdate () : void
{
echo 'Not yet implemented.' . PHP_EOL ;
}
2022-10-08 10:54:55 +02:00
2024-04-16 18:24:38 +02:00
private function dynDnsDelete () : void
{
echo 'Not yet implemented.' . PHP_EOL ;
}
2022-09-29 19:21:42 +02:00
2024-04-16 18:24:38 +02:00
private function webmailDelete () : void
{
}
2022-09-29 19:21:42 +02:00
2024-04-16 18:24:38 +02:00
private function migrationsStatus () : void
{
$phinx = new PhinxApplication ( 'Phinx' , '0.9.2' );
2022-09-29 19:21:42 +02:00
2024-04-16 18:24:38 +02:00
// use DI later when moving to symfony
$input = new \Symfony\Component\Console\Input\ArgvInput ();
$output = new \Symfony\Component\Console\Output\ConsoleOutput ();
2022-10-08 10:54:55 +02:00
2024-04-16 18:24:38 +02:00
echo 'show migration status' . PHP_EOL ;
$command = $phinx -> find ( name : 'status' ); // change 'migrate' to 'status'
2022-10-08 10:54:55 +02:00
2024-04-16 18:24:38 +02:00
$arguments = [
'command' => 'status' ,
];
2022-10-08 10:54:55 +02:00
2024-04-16 18:24:38 +02:00
$phinxOutput = new ConsoleOutput ();
$returnCode = $command -> run ( input : new ArrayInput ( parameters : $arguments ), output : $phinxOutput );
echo 'return code: ' . $returnCode . PHP_EOL ;
}
2022-10-08 10:54:55 +02:00
2024-04-16 18:24:38 +02:00
private function migrationsMake ()
{
$phinx = new PhinxApplication ();
2022-10-08 10:54:55 +02:00
2024-04-16 18:24:38 +02:00
$phinx -> add ( new GenerateCommand ());
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
$arguments = [
'command' => 'generate' ,
];
$output = new ConsoleOutput ();
$returnCode = $phinx -> run ( input : new ArrayInput ( parameters : $arguments ), output : $output );
}
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
private function migrationsMigrate () : void
{
$phinx = new PhinxApplication ( 'Phinx' , '0.9.2' );
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
echo 'show migration status' . PHP_EOL ;
$command = $phinx -> find ( name : 'migrate' );
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
$arguments = [
'command' => 'migrate' ,
];
2024-04-13 20:35:20 +02:00
2024-04-16 18:24:38 +02:00
$phinxOutput = new ConsoleOutput ();
$returnCode = $command -> run ( input : new ArrayInput ( parameters : $arguments ), output : $phinxOutput );
2022-10-08 10:54:55 +02:00
}
2024-04-17 20:28:51 +02:00
private function checkPanel ()
{
$self = $this -> panelRepository -> findSelf ();
$panelCount = count ( $self );
if ( $panelCount != 1 ) {
if ( $panelCount == 0 ) {
echo 'No panel marked as this server.' . PHP_EOL ;
echo 'Use ' . COLOR_YELLOW . 'panels:update <ID> self=1 ' . COLOR_DEFAULT . 'to mark this panel.' . PHP_EOL ;
} else {
echo 'Only one panel can be marked as self.' . PHP_EOL ;
echo 'Use ' . COLOR_YELLOW . 'panels:update <ID> self=0 ' . COLOR_DEFAULT . 'to remove the stale panel' . PHP_EOL ;
}
} else {
if ( ! $this -> quiet ) {
echo 'Only one panel is designated as our host' . COLOR_GREEN . ' OK' . COLOR_DEFAULT . PHP_EOL ;
}
}
}
2024-04-16 18:24:38 +02:00
}