first commit

This commit is contained in:
Roman Pyrih
2026-04-21 15:48:41 +02:00
commit 7483681901
10216 changed files with 3236626 additions and 0 deletions

View File

@@ -0,0 +1,441 @@
<?php
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
//This class is called through both the router.php and main.installer.php
//Full Path: {DUPX_INIT}/api/
require_once("class.cpnl.base.php");
/**
* Class used to store cPanel host information
* */
class DUPX_cPanelHost
{
/** @var string */
public $url = '';
/** @var string */
public $host = '';
/** @var string */
public $scheme = '';
/** @var int */
public $port = 0;
/** @var string */
public $user = '';
/** @var string */
public $pass = '';
}
/**
* Wrapper Class for cPanel API
*
* <routable> */
class DUPX_cPanel_Controller
{
/** @var ?CPNL_API */
private $api;
/**
* Creates a security token to access the cPanel calls
* @param string $host The cPanel host name can be full url or just domain name
* https://mysite.com:2083, https://mysite.com, mysite.com
* @param string $user A valid cPanel user name
* @param string $pass A valid cPanel user password
* @return string A base64 encoded string of the input params
*
* <route template="/cpnl/create_token/{host}/{user}/{pass}/">
*/
public function create_token($host, $user, $pass): string
{
if (substr($host, 0, 4) !== 'http') {
$host = 'https://' . $host;
}
$url = parse_url($host);
$host = $url['host'] ?? null;
if (is_null($host)) {
throw new Exception('The create_token operation requires a valid host parameter');
}
if (!$user) {
throw new Exception('The create_token operation requires a valid user parameter');
}
if (!$pass) {
throw new Exception('The create_token operation requires a valid password parameter');
}
$scheme = $url['scheme'] ?? 'https';
$port = $url['port'] ?? '2083';
return base64_encode("{$scheme},{$host},{$port},{$user},{$pass}");
}
/**
* Get the host information about this cpanel server
* @param string $token The authtoken used to access cpanel
* @return DUPX_cPanelHost A DUPX_cPanelHost object
*
* <route template="/cpnl/get_host/{token}/">
*/
public function get_host($token): \DUPX_cPanelHost
{
$host = new DUPX_cPanelHost();
$creds = explode(",", base64_decode($token));
if (!isset($creds[1])) {
throw new Exception("Invalid hostname detected for get_host with token: $token");
}
$host->scheme = $creds[0];
$host->host = $creds[1];
$host->port = (int) $creds[2];
$host->user = $creds[3];
$host->pass = $creds[4];
$host->url = "{$host->scheme}://{$host->host}:{$host->port}";
return $host;
}
/**
* Get the setup data needed for validating and show DB information
* @param string $token The authtoken used to access cpanel
* @return array $data['valid_host'] Is the url a valid cpanel URL
* $data['valid_user'] Is the user a valid cpanel user
* $data['is_prefix_on'] Does the cpanel use a DB prefix
* $data['dbinfo'] A list of databases and info
* $data['dbusers'] A list of database users
*
* <route template="/cpnl/get_setup_data/{token}/">
*/
public function get_setup_data($token): array
{
$data = [];
$host = $this->connect($token);
$data['valid_host'] = false;
$data['valid_user'] = false;
$data['is_prefix_on'] = false;
$data['dbinfo'] = null;
$data['dbusers'] = null;
try {
$data = [];
$host = $this->connect($token);
$data['valid_host'] = $this->is_host_active($host->url);
$data['is_prefix_on'] = $this->is_prefix_on($token);
//Try two calls just in case
$obj = json_decode($this->api->api2_query($host->user, "Contactus", "isenabled"));
if (isset($obj->cpanelresult->func)) {
$data['valid_user'] = true;
} else {
$obj = json_decode($this->api->api2_query($host->user, "Email", "accountname"));
if (isset($obj->cpanelresult->func)) {
$data['valid_user'] = true;
}
}
//DB NAMES/USRERS
$obj = json_decode($this->api->api2_query($host->user, "MysqlFE", "getalldbsinfo"));
$obj_dbs = $obj->cpanelresult->data ?? null;
$data['dbinfo'] = ($obj_dbs != null && count($obj_dbs) >= 1) ? $obj_dbs : null;
$obj = json_decode($this->api->api2_query($host->user, "MysqlFE", "listusers"));
$obj_dbusers = $obj->cpanelresult->data ?? null;
$data['dbusers'] = ($obj_dbusers != null && count($obj_dbusers) >= 1) ? $obj_dbusers : null;
return $data;
} catch (Exception $ex) {
return $data;
}
}
/**
* Lists the databases for the specified cpanel account
* @param string $token The authtoken used to access cpanel
* @return array $data['status'] True/False or an error message.
* $data['cpnl_api'] The cpanel API result
*
* <route template="/cpnl/list_dbs/{token}/">
*/
public function list_dbs($token)
{
// Returns true/false or message on error
$data['status'] = "Error listing databases. See the log for more details.";
$data['cpnl_api'] = null;
$host = $this->connect($token);
$json = $this->api->api2_query($host->user, "MysqlFE", "listdbs");
if ($json !== false) {
$obj = json_decode($json);
$data['cpnl_api'] = $obj;
$data['status'] = isset($obj->cpanelresult->event->result) && $obj->cpanelresult->event->result == 1;
if (property_exists($obj->cpanelresult, 'error')) {
$data['status'] = $obj->cpanelresult->error;
}
}
return $data;
}
/**
* Creates a database via the cPanel API
*
* @param string $token The authtoken used to access cpanel
* @param string $dbname The name of database to create
* @return array $data['status'] True/False or an error message.
* $data['cpnl_api'] The cpanel API result
*
* <route template="/cpnl/create_db/{token}/{dbname}">
*/
public function create_db($token, $dbname)
{
// Returns true/false or message on error
$data['status'] = "Error creating database '{$dbname}'. See the log for more details.";
$data['cpnl_api'] = null;
$host = $this->connect($token);
$args = [];
$args['db'] = $dbname;
$json = $this->api->api2_query($host->user, "MysqlFE", "createdb", $args);
if ($json !== false) {
$obj = json_decode($json);
$data['cpnl_api'] = $obj;
$data['status'] = isset($obj->cpanelresult->event->result) && $obj->cpanelresult->event->result == 1;
if (property_exists($obj->cpanelresult, 'error')) {
$data['status'] = $obj->cpanelresult->error;
}
}
return $data;
}
/**
* Deletes a database via the cPanel API
*
* @param string $token The authtoken used to access cpanel
* @param string $dbname The name of database to delete
* @return array $data['status'] True/False or an error message.
* $data['cpnl_api'] The cpanel API result
*
* <route template="/cpnl/delete_db/{token}/{dbname}">
*/
public function delete_db($token, $dbname)
{
// Returns true/false or message on error
$data['status'] = "Error deleting database '{$dbname}'. See the log for more details.";
$data['cpnl_api'] = null;
$host = $this->connect($token);
$args = [];
$args['db'] = $dbname;
$json = $this->api->api2_query($host->user, "MysqlFE", "deletedb", $args);
if ($json !== false) {
$obj = json_decode($json);
$data['cpnl_api'] = $obj;
$data['status'] = isset($obj->cpanelresult->event->result) && $obj->cpanelresult->event->result == 1;
if (property_exists($obj->cpanelresult, 'error')) {
$data['status'] = $obj->cpanelresult->error;
}
}
return $data;
}
/**
* Creates a database user via the cPanel API
*
* @param string $token The authtoken used to access cpanel
* @param string $dbuser The name of database user to create
* @param string $dbpass The database password to create for the user
*
* @return array<string,mixed> $data['status'] True/False or an error message.
* $data['cpnl_api'] The cpanel API result
*
* <route template="/cpnl/create_db_user/{token}/{dbuser}/{dbpass}">
*/
public function create_db_user($token, $dbuser, $dbpass)
{
// Returns true/false or message on error
$data['status'] = "Error creating database user '{$dbuser}'. See the log for more details.";
$data['cpnl_api'] = null;
$host = $this->connect($token);
$args = [];
$args['dbuser'] = $dbuser;
$args['password'] = $dbpass;
$json = $this->api->api2_query($host->user, "MysqlFE", "createdbuser", $args);
if ($json !== false) {
$obj = json_decode($json);
$data['cpnl_api'] = $obj;
if (isset($obj->cpanelresult->event->result) && $obj->cpanelresult->event->result == 1) {
$data['status'] = true;
}
if (property_exists($obj->cpanelresult, 'error')) {
$data['status'] = $obj->cpanelresult->error;
}
}
return $data;
}
/**
* Deletes a database user via the cPanel API
*
* @param string $token The authtoken used to access cpanel
* @param string $dbuser The name of database user to delete
* @return array $data['status'] True/False or an error message.
* $data['cpnl_api'] The cpanel API result
*
* <route template="/cpnl/delete_db_user/{token}/{dbuser}">
*/
public function delete_db_user($token, $dbuser)
{
// Returns true/false or message on error
$data['status'] = "Error deleting database user '{$dbuser}'. See the log for more details.";
$data['cpnl_api'] = null;
$host = $this->connect($token);
$args = [];
$args['dbuser'] = $dbuser;
$json = $this->api->api2_query($host->user, "MysqlFE", "deletedbuser", $args);
if ($json !== false) {
$obj = json_decode($json);
$data['cpnl_api'] = $obj;
if (isset($obj->cpanelresult->event->result) && $obj->cpanelresult->event->result == 1) {
$data['status'] = true;
}
if (property_exists($obj->cpanelresult, 'error')) {
$data['status'] = $obj->cpanelresult->error;
}
}
return $data;
}
/**
* Assigns a user to a database via the cPanel API with ALL privileges
*
* @param string $token The authtoken used to access cpanel
* @param string $dbname The name of a valid database
* @param string $dbuser The user to add to the database
* @return array $data['status'] True/False or an error message.
* $data['cpnl_api'] The cpanel API result
*
* <route template="/cpnl/assign_db_user/{token}/{dbname}/{dbuser}">
*/
public function assign_db_user($token, $dbname, $dbuser)
{
// Returns true/false or message on error
$data['status'] = "Unable to retrieve error status from cPanel API'. See the log for more details.";
$data['cpnl_api'] = null;
$host = $this->connect($token);
$args = [];
$args['privileges'] = 'ALL PRIVILEGES';
$args['db'] = $dbname;
$args['dbuser'] = $dbuser;
$json = $this->api->api2_query($host->user, "MysqlFE", "setdbuserprivileges", $args);
if ($json !== false) {
$obj = json_decode($json);
$data['cpnl_api'] = $obj;
//On some APIs this method returns error = 1 even when result = 1. It seems that the result = 1 is more
//accurate for success detection so that will be the primary driver for success
if (isset($obj->cpanelresult->event->result) && $obj->cpanelresult->event->result == 1) {
$data['status'] = true;
} elseif (property_exists($obj->cpanelresult, 'error')) {
$data['status'] = $obj->cpanelresult->error;
}
}
return $data;
}
/**
* Is the user in the database specified
* @param string $token The authtoken used to access cpanel
* @param string $dbname The name of a valid database
* @param string $dbuser A database user
* @return array $data['status'] True/False or an error message.
* $data['cpnl_api'] The cpanel API result
*
* <route template="/cpnl/is_user_in_db/{token}/{dbname}/{dbuser}">
*/
public function is_user_in_db($token, $dbname, $dbuser)
{
// Returns true/false or message on error
$data['status'] = "Error determining if '{$dbuser}' can access database '{$dbname}'. See the log for more details.";
$data['cpnl_api'] = null;
$host = $this->connect($token);
$args = [];
$args['db'] = $dbname;
$json = $this->api->api2_query($host->user, "MysqlFE", "listusersindb", $args);
if ($json !== false) {
$obj = json_decode($json);
$data['cpnl_api'] = $obj;
$data['status'] = false;
foreach ($obj->cpanelresult->data as $database_pair) {
if ($database_pair->user == $dbuser) {
$data['status'] = true;
break;
}
}
} else {
$data['status'] = 'Could not retrieve list of users in database.';
}
return $data;
}
/**
* Does cpanel require the database to have a prefix
* <route template="/cpnl/is_prefix_on/{token}">
* Return
* $data['status'] True/False or an error message.
* $data['cpnl_api'] The cpanel API result
*
* @param string $token The authtoken used to access cpanel
*
* @return array{status:bool|string,cpnl_api:object}
*/
public function is_prefix_on($token): array
{
// Returns true/false or message on error
$data = [];
$data['status'] = "Error determining if database prefix name is enabled. See the log for more details.";
$data['cpnl_api'] = null;
$host = $this->connect($token);
$json = $this->api->api2_query($host->user, "DBmap", "status");
if ($json !== false) {
$obj = json_decode($json);
$data['cpnl_api'] = $obj;
$data['status'] = isset($obj->cpanelresult->data) ? "Error calling DBmap" : $obj->cpanelresult->data[0]->prefix == 1;
}
return $data;
}
/**
* Connect to the cPanel API
*
* @param string $token A valid token
* @return DUPX_cPanelHost A DUPX_cPanelHost object
*/
public function connect($token)
{
$host = $this->get_host($token);
if (!$host->host || !$host->user || !$host->pass) {
throw new Exception('DUPX_cPanel->connect invalid token provided.');
}
//Call to cPanel XMLAPI Client Class see /classes/_libs.php
$this->api = new CPNL_API($host->host);
$this->api->password_auth($host->user, $host->pass);
$this->api->set_protocol($host->scheme);
$this->api->set_port($host->port);
$this->api->set_output("json");
$this->api->set_debug(false);
return $host;
}
/**
* Check to see if the cPanel API is availble for use
*
* @param string $url
*
* @return bool True if this host supports the json api
*
* //https://mysite.com:2083/json-api/
*/
private function is_host_active($url): bool
{
$route = '/json-api/';
$url = (!strpos($url, $route)) ? "{$url}/json-api/" : $url;
$response = DUPX_HTTP::get($url);
$json = json_decode($response);
if (isset($json->cpanelresult)) {
return true;
}
return false;
}
}