put Api-Commands into namespaces
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
This commit is contained in:
@@ -1,502 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package API
|
||||
* @since 0.10.0
|
||||
*
|
||||
*/
|
||||
abstract class ApiCommand extends ApiParameter
|
||||
{
|
||||
|
||||
/**
|
||||
* debug flag
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private $debug = false;
|
||||
|
||||
/**
|
||||
* is admin flag
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private $is_admin = false;
|
||||
|
||||
/**
|
||||
* internal user data array
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $user_data = null;
|
||||
|
||||
/**
|
||||
* logger interface
|
||||
*
|
||||
* @var FroxlorLogger
|
||||
*/
|
||||
private $logger = null;
|
||||
|
||||
/**
|
||||
* mail interface
|
||||
*
|
||||
* @var PHPMailer
|
||||
*/
|
||||
private $mail = null;
|
||||
|
||||
/**
|
||||
* language strings array
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $lng = null;
|
||||
|
||||
/**
|
||||
* froxlor version
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $version = null;
|
||||
|
||||
/**
|
||||
* froxlor dbversion
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $dbversion = null;
|
||||
|
||||
/**
|
||||
* froxlor version-branding
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $branding = null;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $header
|
||||
* optional, passed via API
|
||||
* @param array $params
|
||||
* optional, array of parameters (var=>value) for the command
|
||||
* @param array $userinfo
|
||||
* optional, passed via WebInterface (instead of $header)
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __construct($header = null, $params = null, $userinfo = null)
|
||||
{
|
||||
global $lng, $version, $dbversion, $branding;
|
||||
|
||||
parent::__construct($params);
|
||||
|
||||
$this->version = $version;
|
||||
$this->dbversion = $dbversion;
|
||||
$this->branding = $branding;
|
||||
|
||||
if (! empty($header)) {
|
||||
$this->readUserData($header);
|
||||
} elseif (! empty($userinfo)) {
|
||||
$this->user_data = $userinfo;
|
||||
$this->is_admin = (isset($userinfo['adminsession']) && $userinfo['adminsession'] == 1 && $userinfo['adminid'] > 0) ? true : false;
|
||||
} else {
|
||||
throw new Exception("Invalid user data", 500);
|
||||
}
|
||||
$this->logger = FroxlorLogger::getInstanceOf($this->user_data);
|
||||
|
||||
// check whether the user is deactivated
|
||||
if ($this->getUserDetail('deactivated') == 1) {
|
||||
$this->logger()->logAction(LOG_ERROR, LOG_INFO, "[API] User '" . $this->getUserDetail('loginnname') . "' tried to use API but is deactivated");
|
||||
throw new Exception("Account suspended", 406);
|
||||
}
|
||||
|
||||
$this->initLang();
|
||||
$this->initMail();
|
||||
|
||||
if ($this->debug) {
|
||||
$this->logger()->logAction(LOG_ERROR, LOG_DEBUG, "[API] " . get_called_class() . ": " . json_encode($params, JSON_UNESCAPED_SLASHES));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* initialize global $lng variable to have
|
||||
* localized strings available for the ApiCommands
|
||||
*/
|
||||
private function initLang()
|
||||
{
|
||||
global $lng;
|
||||
|
||||
// query the whole table
|
||||
$result_stmt = Database::query("SELECT * FROM `" . TABLE_PANEL_LANGUAGE . "`");
|
||||
|
||||
$langs = array();
|
||||
// presort languages
|
||||
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$langs[$row['language']][] = $row;
|
||||
}
|
||||
|
||||
// set default language before anything else to
|
||||
// ensure that we can display messages
|
||||
$language = Settings::Get('panel.standardlanguage');
|
||||
|
||||
if (isset($this->user_data['language']) && isset($langs[$this->user_data['language']])) {
|
||||
// default: use language from session, #277
|
||||
$language = $this->user_data['language'];
|
||||
} elseif (isset($this->user_data['def_language'])) {
|
||||
$language = $this->user_data['def_language'];
|
||||
}
|
||||
|
||||
// include every english language file we can get
|
||||
foreach ($langs['English'] as $value) {
|
||||
include_once makeSecurePath(FROXLOR_INSTALL_DIR . '/' . $value['file']);
|
||||
}
|
||||
|
||||
// now include the selected language if its not english
|
||||
if ($language != 'English') {
|
||||
if (isset($langs[$language])) {
|
||||
foreach ($langs[$language] as $value) {
|
||||
include_once makeSecurePath(FROXLOR_INSTALL_DIR . '/' . $value['file']);
|
||||
}
|
||||
} else {
|
||||
if ($this->debug) {
|
||||
$this->logger()->logAction(LOG_ERROR, LOG_DEBUG, "[API] unable to include user-language '" . $language . "'. Not found in database.", 404);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// last but not least include language references file
|
||||
include_once makeSecurePath(FROXLOR_INSTALL_DIR . '/lng/lng_references.php');
|
||||
|
||||
// set array for ApiCommand
|
||||
$this->lng = $lng;
|
||||
}
|
||||
|
||||
/**
|
||||
* initialize mail interface so an API wide mail-object is available
|
||||
* @throws phpmailerException
|
||||
*/
|
||||
private function initMail()
|
||||
{
|
||||
/**
|
||||
* Initialize the mailingsystem
|
||||
*/
|
||||
$this->mail = new PHPMailer(true);
|
||||
$this->mail->CharSet = "UTF-8";
|
||||
|
||||
if (Settings::Get('system.mail_use_smtp')) {
|
||||
$this->mail->isSMTP();
|
||||
$this->mail->Host = Settings::Get('system.mail_smtp_host');
|
||||
$this->mail->SMTPAuth = Settings::Get('system.mail_smtp_auth') == '1' ? true : false;
|
||||
$this->mail->Username = Settings::Get('system.mail_smtp_user');
|
||||
$this->mail->Password = Settings::Get('system.mail_smtp_passwd');
|
||||
if (Settings::Get('system.mail_smtp_usetls')) {
|
||||
$this->mail->SMTPSecure = 'tls';
|
||||
} else {
|
||||
$this->mail->SMTPAutoTLS = false;
|
||||
}
|
||||
$this->mail->Port = Settings::Get('system.mail_smtp_port');
|
||||
}
|
||||
|
||||
if ( PHPMailer::validateAddress(Settings::Get('panel.adminmail')) !== false) {
|
||||
// set return-to address and custom sender-name, see #76
|
||||
$this->mail->setFrom(Settings::Get('panel.adminmail'), Settings::Get('panel.adminmail_defname'));
|
||||
if (Settings::Get('panel.adminmail_return') != '') {
|
||||
$this->mail->addReplyTo(Settings::Get('panel.adminmail_return'), Settings::Get('panel.adminmail_defname'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns an instance of the wanted ApiCommand (e.g.
|
||||
* Customers, Domains, etc);
|
||||
* this is used widely in the WebInterface
|
||||
*
|
||||
* @param array $userinfo
|
||||
* array of user-data
|
||||
* @param array $params
|
||||
* array of parameters for the command
|
||||
*
|
||||
* @return ApiCommand
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function getLocal($userinfo = null, $params = null)
|
||||
{
|
||||
return new static(null, $params, $userinfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* admin flag
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
protected function isAdmin()
|
||||
{
|
||||
return $this->is_admin;
|
||||
}
|
||||
|
||||
/**
|
||||
* return field from user-table
|
||||
*
|
||||
* @param string $detail
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getUserDetail($detail = null)
|
||||
{
|
||||
return (isset($this->user_data[$detail]) ? $this->user_data[$detail] : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* return user-data array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getUserData()
|
||||
{
|
||||
return $this->user_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* return logger instance
|
||||
*
|
||||
* @return FroxlorLogger
|
||||
*/
|
||||
protected function logger()
|
||||
{
|
||||
return $this->logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* return mailer instance
|
||||
*
|
||||
* @return PHPMailer
|
||||
*/
|
||||
protected function mailer()
|
||||
{
|
||||
return $this->mail;
|
||||
}
|
||||
|
||||
/**
|
||||
* call an api-command internally
|
||||
*
|
||||
* @param string $command
|
||||
* @param array|null $params
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function apiCall($command = null, $params = null)
|
||||
{
|
||||
$_command = explode(".", $command);
|
||||
$module = $_command[0];
|
||||
$function = $_command[1];
|
||||
$json_result = $module::getLocal($this->getUserData(), $params)->{$function}();
|
||||
return json_decode($json_result, true)['data'];
|
||||
}
|
||||
|
||||
/**
|
||||
* return api-compatible response in JSON format and send corresponding http-header
|
||||
*
|
||||
* @param int $status
|
||||
* @param string $status_message
|
||||
* @param mixed $data
|
||||
*
|
||||
* @return string json-encoded response message
|
||||
*/
|
||||
protected function response($status, $status_message, $data = null)
|
||||
{
|
||||
if (isset($_SERVER["SERVER_PROTOCOL"]) && ! empty($_SERVER["SERVER_PROTOCOL"])) {
|
||||
$resheader = $_SERVER["SERVER_PROTOCOL"] . " " . $status;
|
||||
if (! empty($status_message)) {
|
||||
$resheader .= ' ' . str_replace("\n", " ", $status_message);
|
||||
}
|
||||
header($resheader);
|
||||
}
|
||||
|
||||
$response = array();
|
||||
$response['status'] = $status;
|
||||
$response['status_message'] = $status_message;
|
||||
$response['data'] = $data;
|
||||
|
||||
$json_response = json_encode($response, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
|
||||
return $json_response;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns an array of customers the current user can access
|
||||
*
|
||||
* @param string $customer_hide_option
|
||||
* optional, when called as customer, some options might be hidden due to the panel.customer_hide_options ettings
|
||||
*
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
protected function getAllowedCustomerIds($customer_hide_option = '')
|
||||
{
|
||||
$customer_ids = array();
|
||||
if ($this->isAdmin()) {
|
||||
// if we're an admin, list all ftp-users of all the admins customers
|
||||
// or optionally for one specific customer identified by id or loginname
|
||||
$customerid = $this->getParam('customerid', true, 0);
|
||||
$loginname = $this->getParam('loginname', true, '');
|
||||
|
||||
if (! empty($customerid) || ! empty($loginname)) {
|
||||
$_result = $this->apiCall('Customers.get', array(
|
||||
'id' => $customerid,
|
||||
'loginname' => $loginname
|
||||
));
|
||||
$custom_list_result = array(
|
||||
$_result
|
||||
);
|
||||
} else {
|
||||
$_custom_list_result = $this->apiCall('Customers.listing');
|
||||
$custom_list_result = $_custom_list_result['list'];
|
||||
}
|
||||
foreach ($custom_list_result as $customer) {
|
||||
$customer_ids[] = $customer['customerid'];
|
||||
}
|
||||
} else {
|
||||
if (! empty($customer_hide_option) && Settings::IsInList('panel.customer_hide_options', $customer_hide_option)) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
$customer_ids = array(
|
||||
$this->getUserDetail('customerid')
|
||||
);
|
||||
}
|
||||
if (empty($customer_ids)) {
|
||||
throw new Exception("Required resource unsatisfied.", 405);
|
||||
}
|
||||
return $customer_ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns an array of customer data for customer, or by customer-id/loginname for admin/reseller
|
||||
*
|
||||
* @param int $customerid
|
||||
* optional, required if loginname is empty
|
||||
* @param string $loginname
|
||||
* optional, required of customerid is empty
|
||||
* @param string $customer_resource_check
|
||||
* optional, when called as admin, check the resources of the target customer
|
||||
*
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
protected function getCustomerData($customer_resource_check = '')
|
||||
{
|
||||
if ($this->isAdmin()) {
|
||||
$customerid = $this->getParam('customerid', true, 0);
|
||||
$loginname = $this->getParam('loginname', true, '');
|
||||
$customer = $this->apiCall('Customers.get', array(
|
||||
'id' => $customerid,
|
||||
'loginname' => $loginname
|
||||
));
|
||||
// check whether the customer has enough resources
|
||||
if (! empty($customer_resource_check) && $customer[$customer_resource_check . '_used'] >= $customer[$customer_resource_check] && $customer[$customer_resource_check] != '-1') {
|
||||
throw new Exception("Customer has no more resources available", 406);
|
||||
}
|
||||
} else {
|
||||
$customer = $this->getUserData();
|
||||
}
|
||||
return $customer;
|
||||
}
|
||||
|
||||
/**
|
||||
* increase/decrease a resource field for customers/admins
|
||||
*
|
||||
* @param string $table
|
||||
* @param string $keyfield
|
||||
* @param int $key
|
||||
* @param string $operator
|
||||
* @param string $resource
|
||||
* @param string $extra
|
||||
*/
|
||||
protected static function updateResourceUsage($table = null, $keyfield = null, $key = null, $operator = '+', $resource = null, $extra = null, $step = 1)
|
||||
{
|
||||
$stmt = Database::prepare("
|
||||
UPDATE `" . $table . "`
|
||||
SET `" . $resource . "` = `" . $resource . "` " . $operator . " " . (int) $step . " " . $extra . "
|
||||
WHERE `" . $keyfield . "` = :key
|
||||
");
|
||||
Database::pexecute($stmt, array(
|
||||
'key' => $key
|
||||
), true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* return email template content from database or global language file if not found in DB
|
||||
*
|
||||
* @param array $customerdata
|
||||
* @param string $group
|
||||
* @param string $varname
|
||||
* @param array $replace_arr
|
||||
* @param string $default
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getMailTemplate($customerdata = null, $group = null, $varname = null, $replace_arr = array(), $default = "")
|
||||
{
|
||||
// get template
|
||||
$stmt = Database::prepare("
|
||||
SELECT `value` FROM `" . TABLE_PANEL_TEMPLATES . "` WHERE `adminid`= :adminid
|
||||
AND `language`= :lang AND `templategroup`= :group AND `varname`= :var
|
||||
");
|
||||
$result = Database::pexecute_first($stmt, array(
|
||||
"adminid" => $customerdata['adminid'],
|
||||
"lang" => $customerdata['def_language'],
|
||||
"group" => $group,
|
||||
"var" => $varname
|
||||
), true, true);
|
||||
$content = html_entity_decode(replace_variables((($result['value'] != '') ? $result['value'] : $default), $replace_arr));
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* read user data from database by api-request-header fields
|
||||
*
|
||||
* @param array $header
|
||||
* api-request header
|
||||
*
|
||||
* @throws Exception
|
||||
* @return boolean
|
||||
*/
|
||||
private function readUserData($header = null)
|
||||
{
|
||||
$sel_stmt = Database::prepare("SELECT * FROM `api_keys` WHERE `apikey` = :ak AND `secret` = :as");
|
||||
$result = Database::pexecute_first($sel_stmt, array(
|
||||
'ak' => $header['apikey'],
|
||||
'as' => $header['secret']
|
||||
), true, true);
|
||||
if ($result) {
|
||||
// admin or customer?
|
||||
if ($result['customerid'] == 0 && $result['adminid'] > 0) {
|
||||
$this->is_admin = true;
|
||||
$table = 'panel_admins';
|
||||
$key = "adminid";
|
||||
} elseif ($result['customerid'] > 0 && $result['adminid'] > 0) {
|
||||
$this->is_admin = false;
|
||||
$table = 'panel_customers';
|
||||
$key = "customerid";
|
||||
} else {
|
||||
// neither adminid is > 0 nor customerid is > 0 - sorry man, no way
|
||||
throw new Exception("Invalid API credentials", 400);
|
||||
}
|
||||
$sel_stmt = Database::prepare("SELECT * FROM `" . $table . "` WHERE `" . $key . "` = :id");
|
||||
$this->user_data = Database::pexecute_first($sel_stmt, array(
|
||||
'id' => ($this->is_admin ? $result['adminid'] : $result['customerid'])
|
||||
), true, true);
|
||||
if ($this->is_admin) {
|
||||
$this->user_data['adminsession'] = 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
throw new Exception("Invalid API credentials", 400);
|
||||
}
|
||||
}
|
||||
@@ -1,190 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package API
|
||||
* @since 0.10.0
|
||||
*
|
||||
*/
|
||||
abstract class ApiParameter
|
||||
{
|
||||
|
||||
/**
|
||||
* array of parameters passed to the command
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $cmd_params = null;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $params
|
||||
* optional, array of parameters (var=>value) for the command
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __construct($params = null)
|
||||
{
|
||||
if (! is_null($params)) {
|
||||
$params = $this->trimArray($params);
|
||||
}
|
||||
$this->cmd_params = $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* get specific parameter from the parameterlist;
|
||||
* check for existence and != empty if needed.
|
||||
* Maybe more in the future
|
||||
*
|
||||
* @param string $param
|
||||
* parameter to get out of the request-parameter list
|
||||
* @param bool $optional
|
||||
* default: false
|
||||
* @param mixed $default
|
||||
* value which is returned if optional=true and param is not set
|
||||
*
|
||||
* @throws Exception
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getParam($param = null, $optional = false, $default = '')
|
||||
{
|
||||
// does it exist?
|
||||
if (! isset($this->cmd_params[$param])) {
|
||||
if ($optional === false) {
|
||||
// get module + function for better error-messages
|
||||
$inmod = $this->getModFunctionString();
|
||||
throw new Exception('Requested parameter "' . $param . '" could not be found for "' . $inmod . '"', 404);
|
||||
}
|
||||
return $default;
|
||||
}
|
||||
// is it empty? - test really on string, as value 0 is being seen as empty by php
|
||||
if ($this->cmd_params[$param] === "") {
|
||||
if ($optional === false) {
|
||||
// get module + function for better error-messages
|
||||
$inmod = $this->getModFunctionString();
|
||||
throw new Exception('Requested parameter "' . $param . '" is empty where it should not be for "' . $inmod . '"', 406);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
// everything else is fine
|
||||
return $this->cmd_params[$param];
|
||||
}
|
||||
|
||||
/**
|
||||
* getParam wrapper for boolean parameter
|
||||
*
|
||||
* @param string $param
|
||||
* parameter to get out of the request-parameter list
|
||||
* @param bool $optional
|
||||
* default: false
|
||||
* @param mixed $default
|
||||
* value which is returned if optional=true and param is not set
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getBoolParam($param = null, $optional = false, $default = false)
|
||||
{
|
||||
$_default = '0';
|
||||
if ($default) {
|
||||
$_default = '1';
|
||||
}
|
||||
$param_value = $this->getParam($param, $optional, $_default);
|
||||
if ($param_value && intval($param_value) != 0) {
|
||||
return '1';
|
||||
}
|
||||
return '0';
|
||||
}
|
||||
|
||||
/**
|
||||
* get specific parameter which also has and unlimited-field
|
||||
*
|
||||
* @param string $param
|
||||
* parameter to get out of the request-parameter list
|
||||
* @param string $ul_field
|
||||
* parameter to get out of the request-parameter list
|
||||
* @param bool $optional
|
||||
* default: false
|
||||
* @param mixed $default
|
||||
* value which is returned if optional=true and param is not set
|
||||
*
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function getUlParam($param = null, $ul_field = null, $optional = false, $default = 0)
|
||||
{
|
||||
$param_value = intval_ressource($this->getParam($param, $optional, $default));
|
||||
$ul_field_value = $this->getBoolParam($ul_field, true, 0);
|
||||
if ($ul_field_value != '0') {
|
||||
$param_value = - 1;
|
||||
}
|
||||
return $param_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* return list of all parameters
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getParamList()
|
||||
{
|
||||
return $this->cmd_params;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns "module::function()" for better error-messages (missing parameter etc.)
|
||||
* makes debugging a whole lot more comfortable
|
||||
*
|
||||
* @param int $level
|
||||
* depth of backtrace, default 2
|
||||
*
|
||||
* @param int $max_level
|
||||
* @param array|null $trace
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getModFunctionString($level = 1, $max_level = 5, $trace = null)
|
||||
{
|
||||
// which class called us
|
||||
$_class = get_called_class();
|
||||
if (empty($trace)) {
|
||||
// get backtrace
|
||||
$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
|
||||
}
|
||||
// check class and function
|
||||
$class = $trace[$level]['class'];
|
||||
$func = $trace[$level]['function'];
|
||||
// is it the one we are looking for?
|
||||
if ($class != $_class && $level <= $max_level) {
|
||||
// check one level deeper
|
||||
return $this->getModFunctionString(++ $level, $max_level, $trace);
|
||||
}
|
||||
return $class . ':' . $func;
|
||||
}
|
||||
|
||||
/**
|
||||
* run 'trim' function on an array recursively
|
||||
*
|
||||
* @param array $input
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function trimArray($input)
|
||||
{
|
||||
if (! is_array($input)) {
|
||||
return trim($input);
|
||||
}
|
||||
return array_map(array(
|
||||
$this,
|
||||
'trimArray'
|
||||
), $input);
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package API
|
||||
* @since 0.10.0
|
||||
*
|
||||
*/
|
||||
if (! defined('FROXLOR_INSTALL_DIR')) {
|
||||
define('FROXLOR_INSTALL_DIR', dirname(dirname(dirname(__DIR__))));
|
||||
// ensure that default timezone is set
|
||||
if (function_exists("date_default_timezone_set") && function_exists("date_default_timezone_get")) {
|
||||
@date_default_timezone_set(@date_default_timezone_get());
|
||||
}
|
||||
$installed = true;
|
||||
// check whether the userdata file exists
|
||||
if (! @file_exists(FROXLOR_INSTALL_DIR . '/lib/userdata.inc.php')) {
|
||||
$installed = false;
|
||||
}
|
||||
// check whether we can read the userdata file
|
||||
if ($installed && ! @is_readable(FROXLOR_INSTALL_DIR . '/lib/userdata.inc.php')) {
|
||||
$installed = false;
|
||||
}
|
||||
if ($installed) {
|
||||
// include userdata for content-check
|
||||
require FROXLOR_INSTALL_DIR . '/lib/userdata.inc.php';
|
||||
if (! isset($sql) || ! is_array($sql)) {
|
||||
$installed = false;
|
||||
}
|
||||
}
|
||||
// do not try to do anything if we have no installed/configured froxlor
|
||||
if (! $installed) {
|
||||
header("Status: 404 Not found", 404);
|
||||
header($_SERVER["SERVER_PROTOCOL"] . " 404 Not found", 404);
|
||||
exit();
|
||||
}
|
||||
require_once FROXLOR_INSTALL_DIR . '/lib/tables.inc.php';
|
||||
require_once FROXLOR_INSTALL_DIR . '/lib/functions.php';
|
||||
}
|
||||
|
||||
$lng = array();
|
||||
@@ -1,118 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package API
|
||||
* @since 0.10.0
|
||||
*
|
||||
*/
|
||||
class FroxlorRPC
|
||||
{
|
||||
|
||||
/**
|
||||
* validate a given request
|
||||
*
|
||||
* @param array $request
|
||||
*
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public static function validateRequest($request)
|
||||
{
|
||||
// check header
|
||||
if (! isset($request['header']) || empty($request['header'])) {
|
||||
throw new Exception("Invalid request header", 400);
|
||||
}
|
||||
|
||||
// check authorization
|
||||
if (! isset($request['header']['apikey']) || empty($request['header']['apikey']) || ! isset($request['header']['secret']) || empty($request['header']['secret'])) {
|
||||
throw new Exception("No authorization credentials given", 400);
|
||||
}
|
||||
self::validateAuth($request['header']['apikey'], $request['header']['secret']);
|
||||
|
||||
// check command
|
||||
return self::validateBody($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* validates the given api credentials
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $secret
|
||||
*
|
||||
* @throws Exception
|
||||
* @return boolean
|
||||
*/
|
||||
private static function validateAuth($key, $secret)
|
||||
{
|
||||
$sel_stmt = Database::prepare("SELECT * FROM `api_keys` WHERE `apikey` = :ak AND `secret` = :as");
|
||||
$result = Database::pexecute_first($sel_stmt, array(
|
||||
'ak' => $key,
|
||||
'as' => $secret
|
||||
), true, true);
|
||||
if ($result) {
|
||||
if ($result['apikey'] == $key && $result['secret'] == $secret && ($result['valid_until'] == -1 || $result['valid_until'] >= time())) {
|
||||
if (!empty($result['allowed_from'])) {
|
||||
// @todo allow specification and validating of whole subnets later
|
||||
$ip_list = explode(",", $result['allowed_from']);
|
||||
$access_ip = inet_ntop(inet_pton($_SERVER['REMOTE_ADDR']));
|
||||
if (in_array($access_ip, $ip_list)) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new Exception("Invalid authorization credentials", 403);
|
||||
}
|
||||
|
||||
/**
|
||||
* validates the given command
|
||||
*
|
||||
* @param array $request
|
||||
*
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
private static function validateBody($request)
|
||||
{
|
||||
// check body
|
||||
if (! isset($request['body']) || empty($request['body'])) {
|
||||
throw new Exception("Invalid request body", 400);
|
||||
}
|
||||
|
||||
// check command exists
|
||||
if (! isset($request['body']['command']) || empty($request['body']['command'])) {
|
||||
throw new Exception("No command given", 400);
|
||||
}
|
||||
|
||||
$command = explode(".", $request['body']['command']);
|
||||
|
||||
if (count($command) != 2) {
|
||||
throw new Exception("Invalid command", 400);
|
||||
}
|
||||
// simply check for file-existance, as we do not want to use our autoloader because this way
|
||||
// it will recognize non-api classes+methods as valid commands
|
||||
$apiclass = FROXLOR_INSTALL_DIR . '/lib/classes/api/commands/class.' . $command[0] . '.php';
|
||||
if (! file_exists($apiclass) || ! @method_exists($command[0], $command[1])) {
|
||||
throw new Exception("Unknown command", 400);
|
||||
}
|
||||
return array(
|
||||
'command' => array(
|
||||
'class' => $command[0],
|
||||
'method' => $command[1]
|
||||
),
|
||||
'params' => isset($request['body']['params']) ? $request['body']['params'] : null
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,854 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package API
|
||||
* @since 0.10.0
|
||||
*
|
||||
*/
|
||||
class Admins extends ApiCommand implements ResourceEntity
|
||||
{
|
||||
|
||||
/**
|
||||
* lists all admin entries
|
||||
*
|
||||
* @access admin
|
||||
* @throws Exception
|
||||
* @return array count|list
|
||||
*/
|
||||
public function listing()
|
||||
{
|
||||
if ($this->isAdmin() && $this->getUserDetail('change_serversettings') == 1) {
|
||||
$this->logger()->logAction(ADM_ACTION, LOG_NOTICE, "[API] list admins");
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT *
|
||||
FROM `" . TABLE_PANEL_ADMINS . "`
|
||||
ORDER BY `loginname` ASC
|
||||
");
|
||||
Database::pexecute($result_stmt, null, true, true);
|
||||
$result = array();
|
||||
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$result[] = $row;
|
||||
}
|
||||
return $this->response(200, "successfull", array(
|
||||
'count' => count($result),
|
||||
'list' => $result
|
||||
));
|
||||
}
|
||||
throw new Exception("Not allowed to execute given command.", 403);
|
||||
}
|
||||
|
||||
/**
|
||||
* return an admin entry by either id or loginname
|
||||
*
|
||||
* @param int $id
|
||||
* optional, the admin-id
|
||||
* @param string $loginname
|
||||
* optional, the loginname
|
||||
*
|
||||
* @access admin
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
$id = $this->getParam('id', true, 0);
|
||||
$ln_optional = ($id <= 0 ? false : true);
|
||||
$loginname = $this->getParam('loginname', $ln_optional, '');
|
||||
|
||||
if ($this->isAdmin() && ($this->getUserDetail('change_serversettings') == 1 || ($this->getUserDetail('adminid') == $id || $this->getUserDetail('loginname') == $loginname))) {
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_PANEL_ADMINS . "`
|
||||
WHERE " . ($id > 0 ? "`adminid` = :idln" : "`loginname` = :idln"));
|
||||
$params = array(
|
||||
'idln' => ($id <= 0 ? $loginname : $id)
|
||||
);
|
||||
$result = Database::pexecute_first($result_stmt, $params, true, true);
|
||||
if ($result) {
|
||||
$this->logger()->logAction(ADM_ACTION, LOG_NOTICE, "[API] get admin '" . $result['loginname'] . "'");
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
$key = ($id > 0 ? "id #" . $id : "loginname '" . $loginname . "'");
|
||||
throw new Exception("Admin with " . $key . " could not be found", 404);
|
||||
}
|
||||
throw new Exception("Not allowed to execute given command.", 403);
|
||||
}
|
||||
|
||||
/**
|
||||
* create a new admin user
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $email
|
||||
* @param string $new_loginname
|
||||
* @param string $admin_password
|
||||
* optional, default auto-generated
|
||||
* @param string $def_language
|
||||
* optional, default is system-default language
|
||||
* @param string $custom_notes
|
||||
* optional, default empty
|
||||
* @param bool $custom_notes_show
|
||||
* optional, default false
|
||||
* @param int $diskspace
|
||||
* optional, default 0
|
||||
* @param bool $diskspace_ul
|
||||
* optional, default false
|
||||
* @param int $traffic
|
||||
* optional, default 0
|
||||
* @param bool $traffic_ul
|
||||
* optional, default false
|
||||
* @param int $customers
|
||||
* optional, default 0
|
||||
* @param bool $customers_ul
|
||||
* optional, default false
|
||||
* @param int $domains
|
||||
* optional, default 0
|
||||
* @param bool $domains_ul
|
||||
* optional, default false
|
||||
* @param int $subdomains
|
||||
* optional, default 0
|
||||
* @param bool $subdomains_ul
|
||||
* optional, default false
|
||||
* @param int $emails
|
||||
* optional, default 0
|
||||
* @param bool $emails_ul
|
||||
* optional, default false
|
||||
* @param int $email_accounts
|
||||
* optional, default 0
|
||||
* @param bool $email_accounts_ul
|
||||
* optional, default false
|
||||
* @param int $email_forwarders
|
||||
* optional, default 0
|
||||
* @param bool $email_forwarders_ul
|
||||
* optional, default false
|
||||
* @param int $email_quota
|
||||
* optional, default 0
|
||||
* @param bool $email_quota_ul
|
||||
* optional, default false
|
||||
* @param int $ftps
|
||||
* optional, default 0
|
||||
* @param bool $ftps_ul
|
||||
* optional, default false
|
||||
* @param int $tickets
|
||||
* optional, default 0
|
||||
* @param bool $tickets_ul
|
||||
* optional, default false
|
||||
* @param int $mysqls
|
||||
* optional, default 0
|
||||
* @param bool $mysqls_ul
|
||||
* optional, default false
|
||||
* @param bool $customers_see_all
|
||||
* optional, default false
|
||||
* @param bool $domains_see_all
|
||||
* optional, default false
|
||||
* @param bool $tickets_see_all
|
||||
* optional, default false
|
||||
* @param bool $caneditphpsettings
|
||||
* optional, default false
|
||||
* @param bool $change_serversettings
|
||||
* optional, default false
|
||||
* @param array $ipaddress
|
||||
* optional, list of ip-address id's; default -1 (all IP's)
|
||||
*
|
||||
* @access admin
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
if ($this->isAdmin() && $this->getUserDetail('change_serversettings') == 1) {
|
||||
|
||||
// required parameters
|
||||
$name = $this->getParam('name');
|
||||
$email = $this->getParam('email');
|
||||
$loginname = $this->getParam('new_loginname');
|
||||
|
||||
// parameters
|
||||
$def_language = $this->getParam('def_language', true, Settings::Get('panel.standardlanguage'));
|
||||
$custom_notes = $this->getParam('custom_notes', true, '');
|
||||
$custom_notes_show = $this->getBoolParam('custom_notes_show', true, 0);
|
||||
$password = $this->getParam('admin_password', true, '');
|
||||
|
||||
$diskspace = $this->getUlParam('diskspace', 'diskspace_ul', true, 0);
|
||||
$traffic = $this->getUlParam('traffic', 'traffic_ul', true, 0);
|
||||
$customers = $this->getUlParam('customers', 'customers_ul', true, 0);
|
||||
$domains = $this->getUlParam('domains', 'domains_ul', true, 0);
|
||||
$subdomains = $this->getUlParam('subdomains', 'subdomains_ul', true, 0);
|
||||
$emails = $this->getUlParam('emails', 'emails_ul', true, 0);
|
||||
$email_accounts = $this->getUlParam('email_accounts', 'email_accounts_ul', true, 0);
|
||||
$email_forwarders = $this->getUlParam('email_forwarders', 'email_forwarders_ul', true, 0);
|
||||
$email_quota = $this->getUlParam('email_quota', 'email_quota_ul', true, 0);
|
||||
$ftps = $this->getUlParam('ftps', 'ftps_ul', true, 0);
|
||||
$tickets = $this->getUlParam('tickets', 'tickets_ul', true, 0);
|
||||
$mysqls = $this->getUlParam('mysqls', 'mysqls_ul', true, 0);
|
||||
|
||||
$customers_see_all = $this->getBoolParam('customers_see_all', true, 0);
|
||||
$domains_see_all = $this->getBoolParam('domains_see_all', true, 0);
|
||||
$tickets_see_all = $this->getBoolParam('tickets_see_all', true, 0);
|
||||
$caneditphpsettings = $this->getBoolParam('caneditphpsettings', true, 0);
|
||||
$change_serversettings = $this->getBoolParam('change_serversettings', true, 0);
|
||||
$ipaddress = $this->getParam('ipaddress', true, - 1);
|
||||
|
||||
// validation
|
||||
$name = validate($name, 'name', '', '', array(), true);
|
||||
$idna_convert = new idna_convert_wrapper();
|
||||
$email = $idna_convert->encode(validate($email, 'email', '', '', array(), true));
|
||||
$def_language = validate($def_language, 'default language', '', '', array(), true);
|
||||
$custom_notes = validate(str_replace("\r\n", "\n", $custom_notes), 'custom_notes', '/^[^\0]*$/', '', array(), true);
|
||||
|
||||
if (Settings::Get('system.mail_quota_enabled') != '1') {
|
||||
$email_quota = - 1;
|
||||
}
|
||||
|
||||
if (Settings::Get('ticket.enabled') != '1') {
|
||||
$tickets = - 1;
|
||||
}
|
||||
|
||||
$password = validate($password, 'password', '', '', array(), true);
|
||||
// only check if not empty,
|
||||
// cause empty == generate password automatically
|
||||
if ($password != '') {
|
||||
$password = validatePassword($password, true);
|
||||
}
|
||||
|
||||
$diskspace = $diskspace * 1024;
|
||||
$traffic = $traffic * 1024 * 1024;
|
||||
|
||||
// Check if the account already exists
|
||||
// do not check via api as we skip any permission checks for this task
|
||||
$loginname_check_stmt = Database::prepare("
|
||||
SELECT `loginname` FROM `" . TABLE_PANEL_CUSTOMERS . "` WHERE `loginname` = :login
|
||||
");
|
||||
$loginname_check = Database::pexecute_first($loginname_check_stmt, array(
|
||||
'login' => $loginname
|
||||
), true, true);
|
||||
|
||||
// Check if an admin with the loginname already exists
|
||||
// do not check via api as we skip any permission checks for this task
|
||||
$loginname_check_admin_stmt = Database::prepare("
|
||||
SELECT `loginname` FROM `" . TABLE_PANEL_ADMINS . "` WHERE `loginname` = :login
|
||||
");
|
||||
$loginname_check_admin = Database::pexecute_first($loginname_check_admin_stmt, array(
|
||||
'login' => $loginname
|
||||
), true, true);
|
||||
|
||||
if (strtolower($loginname_check['loginname']) == strtolower($loginname) || strtolower($loginname_check_admin['loginname']) == strtolower($loginname)) {
|
||||
standard_error('loginnameexists', $loginname, true);
|
||||
} // Accounts which match systemaccounts are not allowed, filtering them
|
||||
elseif (preg_match('/^' . preg_quote(Settings::Get('customer.accountprefix'), '/') . '([0-9]+)/', $loginname)) {
|
||||
standard_error('loginnameissystemaccount', Settings::Get('customer.accountprefix'), true);
|
||||
} elseif (! validateUsername($loginname)) {
|
||||
standard_error('loginnameiswrong', $loginname, true);
|
||||
} elseif (! validateEmail($email)) {
|
||||
standard_error('emailiswrong', $email, true);
|
||||
} else {
|
||||
|
||||
if ($customers_see_all != '1') {
|
||||
$customers_see_all = '0';
|
||||
}
|
||||
|
||||
if ($domains_see_all != '1') {
|
||||
$domains_see_all = '0';
|
||||
}
|
||||
|
||||
if ($caneditphpsettings != '1') {
|
||||
$caneditphpsettings = '0';
|
||||
}
|
||||
|
||||
if ($change_serversettings != '1') {
|
||||
$change_serversettings = '0';
|
||||
}
|
||||
|
||||
if ($tickets_see_all != '1') {
|
||||
$tickets_see_all = '0';
|
||||
}
|
||||
|
||||
if ($password == '') {
|
||||
$password = generatePassword();
|
||||
}
|
||||
|
||||
$_theme = Settings::Get('panel.default_theme');
|
||||
|
||||
$ins_data = array(
|
||||
'loginname' => $loginname,
|
||||
'password' => makeCryptPassword($password),
|
||||
'name' => $name,
|
||||
'email' => $email,
|
||||
'lang' => $def_language,
|
||||
'change_serversettings' => $change_serversettings,
|
||||
'customers' => $customers,
|
||||
'customers_see_all' => $customers_see_all,
|
||||
'domains' => $domains,
|
||||
'domains_see_all' => $domains_see_all,
|
||||
'caneditphpsettings' => $caneditphpsettings,
|
||||
'diskspace' => $diskspace,
|
||||
'traffic' => $traffic,
|
||||
'subdomains' => $subdomains,
|
||||
'emails' => $emails,
|
||||
'accounts' => $email_accounts,
|
||||
'forwarders' => $email_forwarders,
|
||||
'quota' => $email_quota,
|
||||
'ftps' => $ftps,
|
||||
'tickets' => $tickets,
|
||||
'tickets_see_all' => $tickets_see_all,
|
||||
'mysqls' => $mysqls,
|
||||
'ip' => empty($ipaddress) ? "" : (is_array($ipaddress) && $ipaddress > 0 ? json_encode($ipaddress) : - 1),
|
||||
'theme' => $_theme,
|
||||
'custom_notes' => $custom_notes,
|
||||
'custom_notes_show' => $custom_notes_show
|
||||
);
|
||||
|
||||
$ins_stmt = Database::prepare("
|
||||
INSERT INTO `" . TABLE_PANEL_ADMINS . "` SET
|
||||
`loginname` = :loginname,
|
||||
`password` = :password,
|
||||
`name` = :name,
|
||||
`email` = :email,
|
||||
`def_language` = :lang,
|
||||
`change_serversettings` = :change_serversettings,
|
||||
`customers` = :customers,
|
||||
`customers_see_all` = :customers_see_all,
|
||||
`domains` = :domains,
|
||||
`domains_see_all` = :domains_see_all,
|
||||
`caneditphpsettings` = :caneditphpsettings,
|
||||
`diskspace` = :diskspace,
|
||||
`traffic` = :traffic,
|
||||
`subdomains` = :subdomains,
|
||||
`emails` = :emails,
|
||||
`email_accounts` = :accounts,
|
||||
`email_forwarders` = :forwarders,
|
||||
`email_quota` = :quota,
|
||||
`ftps` = :ftps,
|
||||
`tickets` = :tickets,
|
||||
`tickets_see_all` = :tickets_see_all,
|
||||
`mysqls` = :mysqls,
|
||||
`ip` = :ip,
|
||||
`theme` = :theme,
|
||||
`custom_notes` = :custom_notes,
|
||||
`custom_notes_show` = :custom_notes_show
|
||||
");
|
||||
Database::pexecute($ins_stmt, $ins_data, true, true);
|
||||
|
||||
$adminid = Database::lastInsertId();
|
||||
$ins_data['adminid'] = $adminid;
|
||||
$this->logger()->logAction(ADM_ACTION, LOG_WARNING, "[API] added admin '" . $loginname . "'");
|
||||
|
||||
// get all admin-data for return-array
|
||||
$result = $this->apiCall('Admins.get', array(
|
||||
'id' => $adminid
|
||||
));
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
}
|
||||
throw new Exception("Not allowed to execute given command.", 403);
|
||||
}
|
||||
|
||||
/**
|
||||
* update an admin user by given id or loginname
|
||||
*
|
||||
* @param int $id
|
||||
* optional, the admin-id
|
||||
* @param string $loginname
|
||||
* optional, the loginname
|
||||
* @param string $name
|
||||
* optional
|
||||
* @param string $email
|
||||
* optional
|
||||
* @param string $admin_password
|
||||
* optional, default auto-generated
|
||||
* @param string $def_language
|
||||
* optional, default is system-default language
|
||||
* @param string $custom_notes
|
||||
* optional, default empty
|
||||
* @param string $theme
|
||||
* optional
|
||||
* @param bool $deactivated
|
||||
* optional, default false
|
||||
* @param bool $custom_notes_show
|
||||
* optional, default false
|
||||
* @param int $diskspace
|
||||
* optional, default 0
|
||||
* @param bool $diskspace_ul
|
||||
* optional, default false
|
||||
* @param int $traffic
|
||||
* optional, default 0
|
||||
* @param bool $traffic_ul
|
||||
* optional, default false
|
||||
* @param int $customers
|
||||
* optional, default 0
|
||||
* @param bool $customers_ul
|
||||
* optional, default false
|
||||
* @param int $domains
|
||||
* optional, default 0
|
||||
* @param bool $domains_ul
|
||||
* optional, default false
|
||||
* @param int $subdomains
|
||||
* optional, default 0
|
||||
* @param bool $subdomains_ul
|
||||
* optional, default false
|
||||
* @param int $emails
|
||||
* optional, default 0
|
||||
* @param bool $emails_ul
|
||||
* optional, default false
|
||||
* @param int $email_accounts
|
||||
* optional, default 0
|
||||
* @param bool $email_accounts_ul
|
||||
* optional, default false
|
||||
* @param int $email_forwarders
|
||||
* optional, default 0
|
||||
* @param bool $email_forwarders_ul
|
||||
* optional, default false
|
||||
* @param int $email_quota
|
||||
* optional, default 0
|
||||
* @param bool $email_quota_ul
|
||||
* optional, default false
|
||||
* @param int $ftps
|
||||
* optional, default 0
|
||||
* @param bool $ftps_ul
|
||||
* optional, default false
|
||||
* @param int $tickets
|
||||
* optional, default 0
|
||||
* @param bool $tickets_ul
|
||||
* optional, default false
|
||||
* @param int $mysqls
|
||||
* optional, default 0
|
||||
* @param bool $mysqls_ul
|
||||
* optional, default false
|
||||
* @param bool $customers_see_all
|
||||
* optional, default false
|
||||
* @param bool $domains_see_all
|
||||
* optional, default false
|
||||
* @param bool $tickets_see_all
|
||||
* optional, default false
|
||||
* @param bool $caneditphpsettings
|
||||
* optional, default false
|
||||
* @param bool $change_serversettings
|
||||
* optional, default false
|
||||
* @param array $ipaddress
|
||||
* optional, list of ip-address id's; default -1 (all IP's)
|
||||
*
|
||||
* @access admin
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function update()
|
||||
{
|
||||
if ($this->isAdmin()) {
|
||||
|
||||
$id = $this->getParam('id', true, 0);
|
||||
$ln_optional = ($id <= 0 ? false : true);
|
||||
$loginname = $this->getParam('loginname', $ln_optional, '');
|
||||
|
||||
$result = $this->apiCall('Admins.get', array(
|
||||
'id' => $id,
|
||||
'loginname' => $loginname
|
||||
));
|
||||
$id = $result['adminid'];
|
||||
|
||||
if ($this->getUserDetail('change_serversettings') == 1 || $result['adminid'] == $this->getUserDetail('adminid')) {
|
||||
// parameters
|
||||
$name = $this->getParam('name', true, $result['name']);
|
||||
$idna_convert = new idna_convert_wrapper();
|
||||
$email = $this->getParam('email', true, $idna_convert->decode($result['email']));
|
||||
$password = $this->getParam('admin_password', true, '');
|
||||
$def_language = $this->getParam('def_language', true, $result['def_language']);
|
||||
$custom_notes = $this->getParam('custom_notes', true, $result['custom_notes']);
|
||||
$custom_notes_show = $this->getBoolParam('custom_notes_show', true, $result['custom_notes_show']);
|
||||
$theme = $this->getParam('theme', true, $result['theme']);
|
||||
|
||||
// you cannot edit some of the details of yourself
|
||||
if ($result['adminid'] == $this->getUserDetail('adminid')) {
|
||||
$deactivated = $result['deactivated'];
|
||||
$customers = $result['customers'];
|
||||
$domains = $result['domains'];
|
||||
$subdomains = $result['subdomains'];
|
||||
$emails = $result['emails'];
|
||||
$email_accounts = $result['email_accounts'];
|
||||
$email_forwarders = $result['email_forwarders'];
|
||||
$email_quota = $result['email_quota'];
|
||||
$ftps = $result['ftps'];
|
||||
$tickets = $result['tickets'];
|
||||
$mysqls = $result['mysqls'];
|
||||
$tickets_see_all = $result['tickets_see_all'];
|
||||
$customers_see_all = $result['customers_see_all'];
|
||||
$domains_see_all = $result['domains_see_all'];
|
||||
$caneditphpsettings = $result['caneditphpsettings'];
|
||||
$change_serversettings = $result['change_serversettings'];
|
||||
$diskspace = $result['diskspace'];
|
||||
$traffic = $result['traffic'];
|
||||
$ipaddress = ($result['ip'] != - 1 ? json_decode($result['ip'], true) : - 1);
|
||||
} else {
|
||||
$deactivated = $this->getBoolParam('deactivated', true, $result['deactivated']);
|
||||
|
||||
$dec_places = Settings::Get('panel.decimal_places');
|
||||
$diskspace = $this->getUlParam('diskspace', 'diskspace_ul', true, round($result['diskspace'] / 1024, $dec_places));
|
||||
$traffic = $this->getUlParam('traffic', 'traffic_ul', true, round($result['traffic'] / (1024 * 1024), $dec_places));
|
||||
$customers = $this->getUlParam('customers', 'customers_ul', true, $result['customers']);
|
||||
$domains = $this->getUlParam('domains', 'domains_ul', true, $result['domains']);
|
||||
$subdomains = $this->getUlParam('subdomains', 'subdomains_ul', true, $result['subdomains']);
|
||||
$emails = $this->getUlParam('emails', 'emails_ul', true, $result['emails']);
|
||||
$email_accounts = $this->getUlParam('email_accounts', 'email_accounts_ul', true, $result['email_accounts']);
|
||||
$email_forwarders = $this->getUlParam('email_forwarders', 'email_forwarders_ul', true, $result['email_forwarders']);
|
||||
$email_quota = $this->getUlParam('email_quota', 'email_quota_ul', true, $result['email_quota']);
|
||||
$ftps = $this->getUlParam('ftps', 'ftps_ul', true, $result['ftps']);
|
||||
$tickets = $this->getUlParam('tickets', 'tickets_ul', true, $result['tickets']);
|
||||
$mysqls = $this->getUlParam('mysqls', 'mysqls_ul', true, $result['mysqls']);
|
||||
|
||||
$customers_see_all = $this->getBoolParam('customers_see_all', true, $result['customers_see_all']);
|
||||
$domains_see_all = $this->getBoolParam('domains_see_all', true, $result['domains_see_all']);
|
||||
$tickets_see_all = $this->getBoolParam('tickets_see_all', true, $result['tickets_see_all']);
|
||||
$caneditphpsettings = $this->getBoolParam('caneditphpsettings', true, $result['caneditphpsettings']);
|
||||
$change_serversettings = $this->getBoolParam('change_serversettings', true, $result['change_serversettings']);
|
||||
$ipaddress = $this->getParam('ipaddress', true, ($result['ip'] != - 1 ? json_decode($result['ip'], true) : - 1));
|
||||
|
||||
$diskspace = $diskspace * 1024;
|
||||
$traffic = $traffic * 1024 * 1024;
|
||||
}
|
||||
|
||||
// validation
|
||||
$name = validate($name, 'name', '', '', array(), true);
|
||||
$idna_convert = new idna_convert_wrapper();
|
||||
$email = $idna_convert->encode(validate($email, 'email', '', '', array(), true));
|
||||
$def_language = validate($def_language, 'default language', '', '', array(), true);
|
||||
$custom_notes = validate(str_replace("\r\n", "\n", $custom_notes), 'custom_notes', '/^[^\0]*$/', '', array(), true);
|
||||
$theme = validate($theme, 'theme', '', '', array(), true);
|
||||
$password = validate($password, 'password', '', '', array(), true);
|
||||
|
||||
if (Settings::Get('system.mail_quota_enabled') != '1') {
|
||||
$email_quota = - 1;
|
||||
}
|
||||
|
||||
if (Settings::Get('ticket.enabled') != '1') {
|
||||
$tickets = - 1;
|
||||
}
|
||||
|
||||
if (empty($theme)) {
|
||||
$theme = Settings::Get('panel.default_theme');
|
||||
}
|
||||
|
||||
if (! validateEmail($email)) {
|
||||
standard_error('emailiswrong', $email, true);
|
||||
} else {
|
||||
|
||||
if ($deactivated != '1') {
|
||||
$deactivated = '0';
|
||||
}
|
||||
|
||||
if ($customers_see_all != '1') {
|
||||
$customers_see_all = '0';
|
||||
}
|
||||
|
||||
if ($domains_see_all != '1') {
|
||||
$domains_see_all = '0';
|
||||
}
|
||||
|
||||
if ($caneditphpsettings != '1') {
|
||||
$caneditphpsettings = '0';
|
||||
}
|
||||
|
||||
if ($change_serversettings != '1') {
|
||||
$change_serversettings = '0';
|
||||
}
|
||||
|
||||
if ($tickets_see_all != '1') {
|
||||
$tickets_see_all = '0';
|
||||
}
|
||||
|
||||
if ($password != '') {
|
||||
$password = validatePassword($password, true);
|
||||
$password = makeCryptPassword($password);
|
||||
} else {
|
||||
$password = $result['password'];
|
||||
}
|
||||
|
||||
// check if a resource was set to something lower
|
||||
// than actually used by the admin/reseller
|
||||
$res_warning = "";
|
||||
if ($customers != $result['customers'] && $customers != - 1 && $customers < $result['customers_used']) {
|
||||
$res_warning .= sprintf($this->lng['error']['setlessthanalreadyused'], 'customers');
|
||||
}
|
||||
if ($domains != $result['domains'] && $domains != - 1 && $domains < $result['domains_used']) {
|
||||
$res_warning .= sprintf($this->lng['error']['setlessthanalreadyused'], 'domains');
|
||||
}
|
||||
if ($diskspace != $result['diskspace'] && ($diskspace / 1024) != - 1 && $diskspace < $result['diskspace_used']) {
|
||||
$res_warning .= sprintf($this->lng['error']['setlessthanalreadyused'], 'diskspace');
|
||||
}
|
||||
if ($traffic != $result['traffic'] && ($traffic / 1024 / 1024) != - 1 && $traffic < $result['traffic_used']) {
|
||||
$res_warning .= sprintf($this->lng['error']['setlessthanalreadyused'], 'traffic');
|
||||
}
|
||||
if ($emails != $result['emails'] && $emails != - 1 && $emails < $result['emails_used']) {
|
||||
$res_warning .= sprintf($this->lng['error']['setlessthanalreadyused'], 'emails');
|
||||
}
|
||||
if ($email_accounts != $result['email_accounts'] && $email_accounts != - 1 && $email_accounts < $result['email_accounts_used']) {
|
||||
$res_warning .= sprintf($this->lng['error']['setlessthanalreadyused'], 'email accounts');
|
||||
}
|
||||
if ($email_forwarders != $result['email_forwarders'] && $email_forwarders != - 1 && $email_forwarders < $result['email_forwarders_used']) {
|
||||
$res_warning .= sprintf($this->lng['error']['setlessthanalreadyused'], 'email forwarders');
|
||||
}
|
||||
if ($email_quota != $result['email_quota'] && $email_quota != - 1 && $email_quota < $result['email_quota_used']) {
|
||||
$res_warning .= sprintf($this->lng['error']['setlessthanalreadyused'], 'email quota');
|
||||
}
|
||||
if ($ftps != $result['ftps'] && $ftps != - 1 && $ftps < $result['ftps_used']) {
|
||||
$res_warning .= sprintf($this->lng['error']['setlessthanalreadyused'], 'ftps');
|
||||
}
|
||||
if ($tickets != $result['tickets'] && $tickets != - 1 && $tickets < $result['tickets_used']) {
|
||||
$res_warning .= sprintf($this->lng['error']['setlessthanalreadyused'], 'tickets');
|
||||
}
|
||||
if ($mysqls != $result['mysqls'] && $mysqls != - 1 && $mysqls < $result['mysqls_used']) {
|
||||
$res_warning .= sprintf($this->lng['error']['setlessthanalreadyused'], 'mysqls');
|
||||
}
|
||||
|
||||
if (! empty($res_warning)) {
|
||||
throw new Exception($res_warning, 406);
|
||||
}
|
||||
|
||||
$upd_data = array(
|
||||
'password' => $password,
|
||||
'name' => $name,
|
||||
'email' => $email,
|
||||
'lang' => $def_language,
|
||||
'change_serversettings' => $change_serversettings,
|
||||
'customers' => $customers,
|
||||
'customers_see_all' => $customers_see_all,
|
||||
'domains' => $domains,
|
||||
'domains_see_all' => $domains_see_all,
|
||||
'caneditphpsettings' => $caneditphpsettings,
|
||||
'diskspace' => $diskspace,
|
||||
'traffic' => $traffic,
|
||||
'subdomains' => $subdomains,
|
||||
'emails' => $emails,
|
||||
'accounts' => $email_accounts,
|
||||
'forwarders' => $email_forwarders,
|
||||
'quota' => $email_quota,
|
||||
'ftps' => $ftps,
|
||||
'tickets' => $tickets,
|
||||
'tickets_see_all' => $tickets_see_all,
|
||||
'mysqls' => $mysqls,
|
||||
'ip' => empty($ipaddress) ? "" : (is_array($ipaddress) && $ipaddress > 0 ? json_encode($ipaddress) : - 1),
|
||||
'deactivated' => $deactivated,
|
||||
'custom_notes' => $custom_notes,
|
||||
'custom_notes_show' => $custom_notes_show,
|
||||
'theme' => $theme,
|
||||
'adminid' => $id
|
||||
);
|
||||
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_ADMINS . "` SET
|
||||
`password` = :password,
|
||||
`name` = :name,
|
||||
`email` = :email,
|
||||
`def_language` = :lang,
|
||||
`change_serversettings` = :change_serversettings,
|
||||
`customers` = :customers,
|
||||
`customers_see_all` = :customers_see_all,
|
||||
`domains` = :domains,
|
||||
`domains_see_all` = :domains_see_all,
|
||||
`caneditphpsettings` = :caneditphpsettings,
|
||||
`diskspace` = :diskspace,
|
||||
`traffic` = :traffic,
|
||||
`subdomains` = :subdomains,
|
||||
`emails` = :emails,
|
||||
`email_accounts` = :accounts,
|
||||
`email_forwarders` = :forwarders,
|
||||
`email_quota` = :quota,
|
||||
`ftps` = :ftps,
|
||||
`tickets` = :tickets,
|
||||
`tickets_see_all` = :tickets_see_all,
|
||||
`mysqls` = :mysqls,
|
||||
`ip` = :ip,
|
||||
`deactivated` = :deactivated,
|
||||
`custom_notes` = :custom_notes,
|
||||
`custom_notes_show` = :custom_notes_show,
|
||||
`theme` = :theme
|
||||
WHERE `adminid` = :adminid
|
||||
");
|
||||
Database::pexecute($upd_stmt, $upd_data, true, true);
|
||||
$this->logger()->logAction(ADM_ACTION, LOG_INFO, "[API] edited admin '" . $result['loginname'] . "'");
|
||||
|
||||
// get all admin-data for return-array
|
||||
$result = $this->apiCall('Admins.get', array(
|
||||
'id' => $result['adminid']
|
||||
));
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new Exception("Not allowed to execute given command.", 403);
|
||||
}
|
||||
|
||||
/**
|
||||
* delete a admin entry by either id or loginname
|
||||
*
|
||||
* @param int $id
|
||||
* optional, the admin-id
|
||||
* @param string $loginname
|
||||
* optional, the loginname
|
||||
*
|
||||
* @access admin
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
if ($this->isAdmin() && $this->getUserDetail('change_serversettings') == 1) {
|
||||
$id = $this->getParam('id', true, 0);
|
||||
$ln_optional = ($id <= 0 ? false : true);
|
||||
$loginname = $this->getParam('loginname', $ln_optional, '');
|
||||
|
||||
$result = $this->apiCall('Admins.get', array(
|
||||
'id' => $id,
|
||||
'loginname' => $loginname
|
||||
));
|
||||
$id = $result['adminid'];
|
||||
|
||||
// don't be stupid
|
||||
if ($id == $this->getUserDetail('adminid')) {
|
||||
standard_error('youcantdeleteyourself', '', true);
|
||||
}
|
||||
|
||||
// delete admin
|
||||
$del_stmt = Database::prepare("
|
||||
DELETE FROM `" . TABLE_PANEL_ADMINS . "` WHERE `adminid` = :adminid
|
||||
");
|
||||
Database::pexecute($del_stmt, array(
|
||||
'adminid' => $id
|
||||
), true, true);
|
||||
|
||||
// delete the traffic-usage
|
||||
$del_stmt = Database::prepare("
|
||||
DELETE FROM `" . TABLE_PANEL_TRAFFIC_ADMINS . "` WHERE `adminid` = :adminid
|
||||
");
|
||||
Database::pexecute($del_stmt, array(
|
||||
'adminid' => $id
|
||||
), true, true);
|
||||
|
||||
// delete the diskspace usage
|
||||
$del_stmt = Database::prepare("
|
||||
DELETE FROM `" . TABLE_PANEL_DISKSPACE_ADMINS . "` WHERE `adminid` = :adminid
|
||||
");
|
||||
Database::pexecute($del_stmt, array(
|
||||
'adminid' => $id
|
||||
), true, true);
|
||||
|
||||
// set admin-id of the old admin's customer to current admins
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET
|
||||
`adminid` = :userid WHERE `adminid` = :adminid
|
||||
");
|
||||
Database::pexecute($upd_stmt, array(
|
||||
'userid' => $this->getUserDetail('adminid'),
|
||||
'adminid' => $id
|
||||
), true, true);
|
||||
|
||||
// set admin-id of the old admin's domains to current admins
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_DOMAINS . "` SET
|
||||
`adminid` = :userid WHERE `adminid` = :adminid
|
||||
");
|
||||
Database::pexecute($upd_stmt, array(
|
||||
'userid' => $this->getUserDetail('adminid'),
|
||||
'adminid' => $id
|
||||
), true, true);
|
||||
|
||||
// delete old admin's api keys if exists (no customer keys)
|
||||
$upd_stmt = Database::prepare("
|
||||
DELETE FROM `" . TABLE_API_KEYS . "` WHERE
|
||||
`adminid` = :adminid AND `customerid` = '0'
|
||||
");
|
||||
Database::pexecute($upd_stmt, array(
|
||||
'adminid' => $id
|
||||
), true, true);
|
||||
|
||||
// set admin-id of the old admin's api-keys to current admins
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_API_KEYS . "` SET
|
||||
`adminid` = :userid WHERE `adminid` = :adminid
|
||||
");
|
||||
Database::pexecute($upd_stmt, array(
|
||||
'userid' => $this->getUserDetail('adminid'),
|
||||
'adminid' => $id
|
||||
), true, true);
|
||||
|
||||
$this->logger()->logAction(ADM_ACTION, LOG_WARNING, "[API] deleted admin '" . $result['loginname'] . "'");
|
||||
updateCounters();
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
throw new Exception("Not allowed to execute given command.", 403);
|
||||
}
|
||||
|
||||
/**
|
||||
* unlock a locked admin by either id or loginname
|
||||
*
|
||||
* @param int $id
|
||||
* optional, the admin-id
|
||||
* @param string $loginname
|
||||
* optional, the loginname
|
||||
*
|
||||
* @access admin
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function unlock()
|
||||
{
|
||||
if ($this->isAdmin() && $this->getUserDetail('change_serversettings') == 1) {
|
||||
$id = $this->getParam('id', true, 0);
|
||||
$ln_optional = ($id <= 0 ? false : true);
|
||||
$loginname = $this->getParam('loginname', $ln_optional, '');
|
||||
|
||||
$result = $this->apiCall('Admins.get', array(
|
||||
'id' => $id,
|
||||
'loginname' => $loginname
|
||||
));
|
||||
$id = $result['adminid'];
|
||||
|
||||
$result_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_ADMINS . "` SET
|
||||
`loginfail_count` = '0'
|
||||
WHERE `adminid`= :id
|
||||
");
|
||||
Database::pexecute($result_stmt, array(
|
||||
'id' => $id
|
||||
), true, true);
|
||||
// set the new value for result-array
|
||||
$result['loginfail_count'] = 0;
|
||||
|
||||
$this->logger()->logAction(ADM_ACTION, LOG_WARNING, "[API] unlocked admin '" . $result['loginname'] . "'");
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
throw new Exception("Not allowed to execute given command.", 403);
|
||||
}
|
||||
|
||||
/**
|
||||
* increase resource-usage
|
||||
*
|
||||
* @param int $customerid
|
||||
* @param string $resource
|
||||
* @param string $extra
|
||||
* optional, default empty
|
||||
*/
|
||||
public static function increaseUsage($adminid = 0, $resource = null, $extra = '')
|
||||
{
|
||||
self::updateResourceUsage(TABLE_PANEL_ADMINS, 'adminid', $adminid, '+', $resource, $extra);
|
||||
}
|
||||
|
||||
/**
|
||||
* decrease resource-usage
|
||||
*
|
||||
* @param int $customerid
|
||||
* @param string $resource
|
||||
* @param string $extra
|
||||
* optional, default empty
|
||||
*/
|
||||
public static function decreaseUsage($adminid = 0, $resource = null, $extra = '')
|
||||
{
|
||||
self::updateResourceUsage(TABLE_PANEL_ADMINS, 'adminid', $adminid, '-', $resource, $extra);
|
||||
}
|
||||
}
|
||||
@@ -1,343 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package API
|
||||
* @since 0.10.0
|
||||
*
|
||||
*/
|
||||
class Certificates extends ApiCommand implements ResourceEntity
|
||||
{
|
||||
|
||||
/**
|
||||
* add new ssl-certificate entry for given domain by either id or domainname
|
||||
*
|
||||
* @param int $id
|
||||
* optional, the domain-id
|
||||
* @param string $domainname
|
||||
* optional, the domainname
|
||||
* @param string $ssl_cert_file
|
||||
* @param string $ssl_key_file
|
||||
* @param string $ssl_ca_file
|
||||
* optional
|
||||
* @param string $ssl_cert_chainfile
|
||||
* optional
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$domainid = $this->getParam('domainid', true, 0);
|
||||
$dn_optional = ($domainid <= 0 ? false : true);
|
||||
$domainname = $this->getParam('domainname', $dn_optional, '');
|
||||
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'domains')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
|
||||
$domain = $this->apiCall('SubDomains.get', array(
|
||||
'id' => $domainid,
|
||||
'domainname' => $domainname
|
||||
));
|
||||
$domainid = $domain['id'];
|
||||
|
||||
// parameters
|
||||
$ssl_cert_file = $this->getParam('ssl_cert_file');
|
||||
$ssl_key_file = $this->getParam('ssl_key_file');
|
||||
$ssl_ca_file = $this->getParam('ssl_ca_file', true, '');
|
||||
$ssl_cert_chainfile = $this->getParam('ssl_cert_chainfile', true, '');
|
||||
|
||||
// validate whether the domain does not already have an entry
|
||||
$result = $this->apiCall('Certificates.get', array(
|
||||
'id' => $domainid
|
||||
));
|
||||
if (empty($result)) {
|
||||
$this->addOrUpdateCertificate($domain['id'], $ssl_cert_file, $ssl_key_file, $ssl_ca_file, $ssl_cert_chainfile, true);
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_INFO, "[API] added ssl-certificate for '" . $domain['domain'] . "'");
|
||||
$result = $this->apiCall('Certificates.get', array(
|
||||
'id' => $domain['id']
|
||||
));
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
throw new Exception("Domain '" . $domain['domain'] . "' already has a certificate. Did you mean to call update?", 406);
|
||||
}
|
||||
|
||||
/**
|
||||
* return ssl-certificate entry for given domain by either id or domainname
|
||||
*
|
||||
* @param int $id
|
||||
* optional, the domain-id
|
||||
* @param string $domainname
|
||||
* optional, the domainname
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
$id = $this->getParam('id', true, 0);
|
||||
$dn_optional = ($id <= 0 ? false : true);
|
||||
$domainname = $this->getParam('domainname', $dn_optional, '');
|
||||
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'domains')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
|
||||
$domain = $this->apiCall('SubDomains.get', array(
|
||||
'id' => $id,
|
||||
'domainname' => $domainname
|
||||
));
|
||||
$domainid = $domain['id'];
|
||||
|
||||
$stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` WHERE `domainid`= :domainid");
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_INFO, "[API] get ssl-certificate for '" . $domain['domain'] . "'");
|
||||
$result = Database::pexecute_first($stmt, array(
|
||||
"domainid" => $domainid
|
||||
));
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* update ssl-certificate entry for given domain by either id or domainname
|
||||
*
|
||||
* @param int $id
|
||||
* optional, the domain-id
|
||||
* @param string $domainname
|
||||
* optional, the domainname
|
||||
* @param string $ssl_cert_file
|
||||
* @param string $ssl_key_file
|
||||
* @param string $ssl_ca_file
|
||||
* optional
|
||||
* @param string $ssl_cert_chainfile
|
||||
* optional
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function update()
|
||||
{
|
||||
$id = $this->getParam('id', true, 0);
|
||||
$dn_optional = ($id <= 0 ? false : true);
|
||||
$domainname = $this->getParam('domainname', $dn_optional, '');
|
||||
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'domains')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
|
||||
$domain = $this->apiCall('SubDomains.get', array(
|
||||
'id' => $id,
|
||||
'domainname' => $domainname
|
||||
));
|
||||
|
||||
// parameters
|
||||
$ssl_cert_file = $this->getParam('ssl_cert_file');
|
||||
$ssl_key_file = $this->getParam('ssl_key_file');
|
||||
$ssl_ca_file = $this->getParam('ssl_ca_file', true, '');
|
||||
$ssl_cert_chainfile = $this->getParam('ssl_cert_chainfile', true, '');
|
||||
$this->addOrUpdateCertificate($domain['id'], $ssl_cert_file, $ssl_key_file, $ssl_ca_file, $ssl_cert_chainfile, false);
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_INFO, "[API] updated ssl-certificate for '" . $domain['domain'] . "'");
|
||||
$result = $this->apiCall('Certificates.get', array(
|
||||
'id' => $domain['id']
|
||||
));
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* lists all certificate entries
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array count|list
|
||||
*/
|
||||
public function listing()
|
||||
{
|
||||
// select all my (accessable) certificates
|
||||
$certs_stmt_query = "SELECT s.*, d.domain, d.letsencrypt, c.customerid, c.loginname
|
||||
FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` s
|
||||
LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` d ON `d`.`id` = `s`.`domainid`
|
||||
LEFT JOIN `" . TABLE_PANEL_CUSTOMERS . "` c ON `c`.`customerid` = `d`.`customerid`
|
||||
WHERE ";
|
||||
|
||||
$qry_params = array();
|
||||
|
||||
if ($this->isAdmin() && $this->getUserDetail('customers_see_all') == '0') {
|
||||
// admin with only customer-specific permissions
|
||||
$certs_stmt_query .= "d.adminid = :adminid ";
|
||||
$qry_params['adminid'] = $this->getUserDetail('adminid');
|
||||
} elseif ($this->isAdmin() == false) {
|
||||
// customer-area
|
||||
$certs_stmt_query .= "d.customerid = :cid ";
|
||||
$qry_params['cid'] = $this->getUserDetail('customerid');
|
||||
} else {
|
||||
$certs_stmt_query .= "1 ";
|
||||
}
|
||||
$certs_stmt = Database::prepare($certs_stmt_query);
|
||||
Database::pexecute($certs_stmt, $qry_params, true, true);
|
||||
$result = array();
|
||||
while ($cert = $certs_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
// respect froxlor-hostname
|
||||
if ($cert['domainid'] == 0) {
|
||||
$cert['domain'] = Settings::Get('system.hostname');
|
||||
$cert['letsencrypt'] = Settings::Get('system.le_froxlor_enabled');
|
||||
$cert['loginname'] = 'froxlor.panel';
|
||||
}
|
||||
$result[] = $cert;
|
||||
}
|
||||
return $this->response(200, "successfull", array(
|
||||
'count' => count($result),
|
||||
'list' => $result
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* delete certificates entry by id
|
||||
*
|
||||
* @param int $id
|
||||
*
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
$id = $this->getParam('id');
|
||||
|
||||
if ($this->isAdmin() == false) {
|
||||
$chk_stmt = Database::prepare("
|
||||
SELECT d.domain FROM `" . TABLE_PANEL_DOMAINS . "` d
|
||||
LEFT JOIN `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` s ON s.domainid = d.id
|
||||
WHERE s.`id` = :id AND d.`customerid` = :cid
|
||||
");
|
||||
$chk = Database::pexecute_first($chk_stmt, array(
|
||||
'id' => $id,
|
||||
'cid' => $this->getUserDetail('customerid')
|
||||
));
|
||||
} elseif ($this->isAdmin()) {
|
||||
$chk_stmt = Database::prepare("
|
||||
SELECT d.domain FROM `" . TABLE_PANEL_DOMAINS . "` d
|
||||
LEFT JOIN `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` s ON s.domainid = d.id
|
||||
WHERE s.`id` = :id" . ($this->getUserDetail('customers_see_all') == '0' ? " AND d.`adminid` = :aid" : ""));
|
||||
$params = array(
|
||||
'id' => $id
|
||||
);
|
||||
if ($this->getUserDetail('customers_see_all') == '0') {
|
||||
$params['aid'] = $this->getUserDetail('adminid');
|
||||
}
|
||||
$chk = Database::pexecute_first($chk_stmt, $params);
|
||||
}
|
||||
if ($chk !== false) {
|
||||
// additional access check by trying to get the certificate
|
||||
$result = $this->apiCall('Certificates.get', array(
|
||||
'domainname' => $chk['domain']
|
||||
));
|
||||
$del_stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` WHERE id = :id");
|
||||
Database::pexecute($del_stmt, array(
|
||||
'id' => $id
|
||||
));
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_INFO, "[API] removed ssl-certificate for '" . $chk['domain'] . "'");
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* insert or update certificates entry
|
||||
*
|
||||
* @param int $domainid
|
||||
* @param string $ssl_cert_file
|
||||
* @param string $ssl_key_file
|
||||
* @param string $ssl_ca_file
|
||||
* @param string $ssl_cert_chainfile
|
||||
* @param boolean $do_insert
|
||||
* optional default false
|
||||
*
|
||||
* @return boolean
|
||||
* @throws Exception
|
||||
*/
|
||||
private function addOrUpdateCertificate($domainid = 0, $ssl_cert_file = '', $ssl_key_file = '', $ssl_ca_file = '', $ssl_cert_chainfile = '', $do_insert = false)
|
||||
{
|
||||
if ($ssl_cert_file != '' && $ssl_key_file == '') {
|
||||
standard_error('sslcertificateismissingprivatekey', '', true);
|
||||
}
|
||||
|
||||
$do_verify = true;
|
||||
// no cert-file given -> forget everything
|
||||
if ($ssl_cert_file == '') {
|
||||
$ssl_key_file = '';
|
||||
$ssl_ca_file = '';
|
||||
$ssl_cert_chainfile = '';
|
||||
$do_verify = false;
|
||||
}
|
||||
|
||||
// verify certificate content
|
||||
if ($do_verify) {
|
||||
// array openssl_x509_parse ( mixed $x509cert [, bool $shortnames = true ] )
|
||||
// openssl_x509_parse() returns information about the supplied x509cert, including fields such as
|
||||
// subject name, issuer name, purposes, valid from and valid to dates etc.
|
||||
$cert_content = openssl_x509_parse($ssl_cert_file);
|
||||
|
||||
if (is_array($cert_content) && isset($cert_content['subject']) && isset($cert_content['subject']['CN'])) {
|
||||
// bool openssl_x509_check_private_key ( mixed $cert , mixed $key )
|
||||
// Checks whether the given key is the private key that corresponds to cert.
|
||||
if (openssl_x509_check_private_key($ssl_cert_file, $ssl_key_file) === false) {
|
||||
standard_error('sslcertificateinvalidcertkeypair', '', true);
|
||||
}
|
||||
|
||||
// check optional stuff
|
||||
if ($ssl_ca_file != '') {
|
||||
$ca_content = openssl_x509_parse($ssl_ca_file);
|
||||
if (! is_array($ca_content)) {
|
||||
// invalid
|
||||
standard_error('sslcertificateinvalidca', '', true);
|
||||
}
|
||||
}
|
||||
if ($ssl_cert_chainfile != '') {
|
||||
$chain_content = openssl_x509_parse($ssl_cert_chainfile);
|
||||
if (! is_array($chain_content)) {
|
||||
// invalid
|
||||
standard_error('sslcertificateinvalidchain', '', true);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
standard_error('sslcertificateinvalidcert', '', true);
|
||||
}
|
||||
}
|
||||
|
||||
// Add/Update database entry
|
||||
$qrystart = "UPDATE ";
|
||||
$qrywhere = "WHERE ";
|
||||
if ($do_insert) {
|
||||
$qrystart = "INSERT INTO ";
|
||||
$qrywhere = ", ";
|
||||
}
|
||||
$stmt = Database::prepare($qrystart . " `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` SET
|
||||
`ssl_cert_file` = :ssl_cert_file,
|
||||
`ssl_key_file` = :ssl_key_file,
|
||||
`ssl_ca_file` = :ssl_ca_file,
|
||||
`ssl_cert_chainfile` = :ssl_cert_chainfile
|
||||
" . $qrywhere . " `domainid`= :domainid
|
||||
");
|
||||
$params = array(
|
||||
"ssl_cert_file" => $ssl_cert_file,
|
||||
"ssl_key_file" => $ssl_key_file,
|
||||
"ssl_ca_file" => $ssl_ca_file,
|
||||
"ssl_cert_chainfile" => $ssl_cert_chainfile,
|
||||
"domainid" => $domainid
|
||||
);
|
||||
Database::pexecute($stmt, $params, true, true);
|
||||
// insert task to re-generate webserver-configs (#1260)
|
||||
inserttask('1');
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,158 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package API
|
||||
* @since 0.10.0
|
||||
*
|
||||
*/
|
||||
class Cronjobs extends ApiCommand implements ResourceEntity
|
||||
{
|
||||
|
||||
/**
|
||||
* You cannot add new cronjobs yet.
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
throw new Exception('You cannot add new cronjobs yet.', 303);
|
||||
}
|
||||
|
||||
/**
|
||||
* return a cronjob entry by id
|
||||
*
|
||||
* @param int $id
|
||||
* cronjob-id
|
||||
*
|
||||
* @access admin
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
if ($this->isAdmin()) {
|
||||
$id = $this->getParam('id');
|
||||
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_PANEL_CRONRUNS . "` WHERE `id` = :id
|
||||
");
|
||||
$result = Database::pexecute_first($result_stmt, array(
|
||||
'id' => $id
|
||||
), true, true);
|
||||
if ($result) {
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
throw new Exception("cronjob with id #" . $id . " could not be found", 404);
|
||||
}
|
||||
throw new Exception("Not allowed to execute given command.", 403);
|
||||
}
|
||||
|
||||
/**
|
||||
* update a cronjob entry by given id
|
||||
*
|
||||
* @param int $id
|
||||
* @param bool $isactive
|
||||
* optional whether the cronjob is active or not
|
||||
* @param int $interval_value
|
||||
* optional number of seconds/minutes/hours/etc. for the interval
|
||||
* @param string $interval_interval
|
||||
* optional interval for the cronjob (MINUTE, HOUR, DAY, WEEK or MONTH)
|
||||
*
|
||||
* @access admin
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function update()
|
||||
{
|
||||
if ($this->isAdmin() && $this->getUserDetail('change_serversettings') == 1) {
|
||||
|
||||
// required parameter
|
||||
$id = $this->getParam('id');
|
||||
|
||||
$result = $this->apiCall('Cronjobs.get', array(
|
||||
'id' => $id
|
||||
));
|
||||
|
||||
// split interval
|
||||
$cur_int = explode(" ", $result['interval']);
|
||||
|
||||
// parameter
|
||||
$isactive = $this->getBoolParam('isactive', true, $result['isactive']);
|
||||
$interval_value = $this->getParam('interval_value', true, $cur_int[0]);
|
||||
$interval_interval = $this->getParam('interval_interval', true, $cur_int[1]);
|
||||
|
||||
// validation
|
||||
if ($isactive != 1) {
|
||||
$isactive = 0;
|
||||
}
|
||||
$interval_value = validate($interval_value, 'interval_value', '/^([0-9]+)$/Di', 'stringisempty', array(), true);
|
||||
$interval_interval = validate($interval_interval, 'interval_interval', '', '', array(), true);
|
||||
|
||||
// put together interval value
|
||||
$interval = $interval_value . ' ' . strtoupper($interval_interval);
|
||||
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_CRONRUNS . "`
|
||||
SET `isactive` = :isactive, `interval` = :int
|
||||
WHERE `id` = :id
|
||||
");
|
||||
Database::pexecute($upd_stmt, array(
|
||||
'isactive' => $isactive,
|
||||
'int' => $interval,
|
||||
'id' => $id
|
||||
), true, true);
|
||||
|
||||
// insert task to re-generate the cron.d-file
|
||||
inserttask('99');
|
||||
$this->logger()->logAction(ADM_ACTION, LOG_INFO, "[API] cronjob with description '" . $result['module'] . '/' . $result['cronfile'] . "' has been updated by '" . $this->getUserDetail('loginname') . "'");
|
||||
$result = $this->apiCall('Cronjobs.get', array(
|
||||
'id' => $id
|
||||
));
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
throw new Exception("Not allowed to execute given command.", 403);
|
||||
}
|
||||
|
||||
/**
|
||||
* lists all cronjob entries
|
||||
*
|
||||
* @access admin
|
||||
* @throws Exception
|
||||
* @return array count|list
|
||||
*/
|
||||
public function listing()
|
||||
{
|
||||
if ($this->isAdmin()) {
|
||||
$this->logger()->logAction(ADM_ACTION, LOG_NOTICE, "[API] list cronjobs");
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT `c`.* FROM `" . TABLE_PANEL_CRONRUNS . "` `c` ORDER BY `module` ASC, `cronfile` ASC
|
||||
");
|
||||
Database::pexecute($result_stmt);
|
||||
$result = array();
|
||||
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$result[] = $row;
|
||||
}
|
||||
return $this->response(200, "successfull", array(
|
||||
'count' => count($result),
|
||||
'list' => $result
|
||||
));
|
||||
}
|
||||
throw new Exception("Not allowed to execute given command.", 403);
|
||||
}
|
||||
|
||||
/**
|
||||
* You cannot delete system cronjobs.
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
throw new Exception('You cannot delete system cronjobs.', 303);
|
||||
}
|
||||
}
|
||||
@@ -1,202 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package API
|
||||
* @since 0.10.0
|
||||
*
|
||||
*/
|
||||
class CustomerBackups extends ApiCommand implements ResourceEntity
|
||||
{
|
||||
|
||||
/**
|
||||
* check whether backup is enabled systemwide and if accessable for customer (hide_options)
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
private function validateAccess()
|
||||
{
|
||||
if (Settings::Get('system.backupenabled') != 1) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'extras')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'extras.backup')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add a new customer backup job
|
||||
*
|
||||
* @param string $path
|
||||
* path to store the backup to
|
||||
* @param bool $backup_dbs
|
||||
* optional whether to backup databases, default is 0 (false)
|
||||
* @param bool $backup_mail
|
||||
* optional whether to backup mail-data, default is 0 (false)
|
||||
* @param bool $backup_web
|
||||
* optional whether to backup web-data, default is 0 (false)
|
||||
* @param int $customerid
|
||||
* required when called as admin, not needed when called as customer
|
||||
*
|
||||
* @access admin, customer
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$this->validateAccess();
|
||||
|
||||
// required parameter
|
||||
$path = $this->getParam('path');
|
||||
|
||||
// parameter
|
||||
$backup_dbs = $this->getBoolParam('backup_dbs', true, 0);
|
||||
$backup_mail = $this->getBoolParam('backup_mail', true, 0);
|
||||
$backup_web = $this->getBoolParam('backup_web', true, 0);
|
||||
|
||||
// get customer data
|
||||
$customer = $this->getCustomerData();
|
||||
|
||||
// validation
|
||||
$path = makeCorrectDir(validate($path, 'path', '', '', array(), true));
|
||||
$userpath = $path;
|
||||
$path = makeCorrectDir($customer['documentroot'] . '/' . $path);
|
||||
|
||||
// path cannot be the customers docroot
|
||||
if ($path == makeCorrectDir($customer['documentroot'])) {
|
||||
standard_error('backupfoldercannotbedocroot', '', true);
|
||||
}
|
||||
|
||||
if ($backup_dbs != '1') {
|
||||
$backup_dbs = '0';
|
||||
}
|
||||
|
||||
if ($backup_mail != '1') {
|
||||
$backup_mail = '0';
|
||||
}
|
||||
|
||||
if ($backup_web != '1') {
|
||||
$backup_web = '0';
|
||||
}
|
||||
|
||||
$task_data = array(
|
||||
'customerid' => $customer['customerid'],
|
||||
'uid' => $customer['guid'],
|
||||
'gid' => $customer['guid'],
|
||||
'loginname' => $customer['loginname'],
|
||||
'destdir' => $path,
|
||||
'backup_dbs' => $backup_dbs,
|
||||
'backup_mail' => $backup_mail,
|
||||
'backup_web' => $backup_web
|
||||
);
|
||||
// schedule backup job
|
||||
inserttask('20', $task_data);
|
||||
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_NOTICE, "[API] added customer-backup job for '" . $customer['loginname'] . "'. Target directory: " . $userpath);
|
||||
return $this->response(200, "successfull", $task_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* You cannot get a planned backup.
|
||||
* Try CustomerBackups.listing()
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
throw new Exception('You cannot get a planned backup. Try CustomerBackups.listing()', 303);
|
||||
}
|
||||
|
||||
/**
|
||||
* You cannot update a planned backup.
|
||||
* You need to delete it and re-add it.
|
||||
*/
|
||||
public function update()
|
||||
{
|
||||
throw new Exception('You cannot update a planned backup. You need to delete it and re-add it.', 303);
|
||||
}
|
||||
|
||||
/**
|
||||
* list all planned backup-jobs, if called from an admin, list all planned backup-jobs of all customers you are allowed to view, or specify id or loginname for one specific customer
|
||||
*
|
||||
* @param int $customerid
|
||||
* optional, admin-only, select backup-jobs of a specific customer by id
|
||||
* @param string $loginname
|
||||
* optional, admin-only, select backup-jobs of a specific customer by loginname
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array count|list
|
||||
*/
|
||||
public function listing()
|
||||
{
|
||||
$this->validateAccess();
|
||||
|
||||
$customer_ids = $this->getAllowedCustomerIds('extras.backup');
|
||||
|
||||
// check whether there is a backup-job for this customer
|
||||
$sel_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_TASKS . "` WHERE `type` = '20'");
|
||||
Database::pexecute($sel_stmt);
|
||||
$result = array();
|
||||
while ($entry = $sel_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$entry['data'] = json_decode($entry['data'], true);
|
||||
if (in_array($entry['data']['customerid'], $customer_ids)) {
|
||||
$result[] = $entry;
|
||||
}
|
||||
}
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_NOTICE, "[API] list customer-backups");
|
||||
return $this->response(200, "successfull", array(
|
||||
'count' => count($result),
|
||||
'list' => $result
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* delete a planned backup-jobs by id, if called from an admin you need to specify the customerid/loginname
|
||||
*
|
||||
* @param int $backup_job_entry
|
||||
* id of backup job
|
||||
* @param int $customerid
|
||||
* optional, required when called as admin (if $loginname is not specified)
|
||||
* @param string $loginname
|
||||
* optional, required when called as admin (if $customerid is not specified)
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return bool
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
// get planned backups
|
||||
$result = $this->apiCall('CustomerBackups.listing', $this->getParamList());
|
||||
|
||||
$entry = $this->getParam('backup_job_entry');
|
||||
$customer_ids = $this->getAllowedCustomerIds('extras.backup');
|
||||
|
||||
if ($result['count'] > 0 && $entry > 0) {
|
||||
// prepare statement
|
||||
$del_stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_TASKS . "` WHERE `id` = :tid");
|
||||
// check for the correct job
|
||||
foreach ($result['list'] as $backupjob) {
|
||||
if ($backupjob['id'] == $entry && in_array($backupjob['data']['customerid'], $customer_ids)) {
|
||||
Database::pexecute($del_stmt, array(
|
||||
'tid' => $entry
|
||||
));
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_NOTICE, "[API] deleted planned customer-backup #" . $entry);
|
||||
return $this->response(200, "successfull", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new Exception('Backup job with id #' . $entry . ' could not be found', 404);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,377 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package API
|
||||
* @since 0.10.0
|
||||
*
|
||||
*/
|
||||
class DirOptions extends ApiCommand implements ResourceEntity
|
||||
{
|
||||
|
||||
/**
|
||||
* add options for a given directory
|
||||
*
|
||||
* @param int $customerid
|
||||
* optional, admin-only, the customer-id
|
||||
* @param string $loginname
|
||||
* optional, admin-only, the loginname
|
||||
* @param string $path
|
||||
* path relative to the customer's home-Directory
|
||||
* @param bool $options_indexes
|
||||
* optional, activate directory-listing for this path, default 0 (false)
|
||||
* @param bool $options_cgi
|
||||
* optional, allow Perl/CGI execution, default 0 (false)
|
||||
* @param string $error404path
|
||||
* optional, custom 404 error string/file
|
||||
* @param string $error403path
|
||||
* optional, custom 403 error string/file
|
||||
* @param string $error500path
|
||||
* optional, custom 500 error string/file
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'extras')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'extras.pathoptions')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
|
||||
// get needed customer info to reduce the email-address-counter by one
|
||||
$customer = $this->getCustomerData();
|
||||
|
||||
// required parameters
|
||||
$path = $this->getParam('path');
|
||||
|
||||
// parameters
|
||||
$options_indexes = $this->getBoolParam('options_indexes', true, 0);
|
||||
$options_cgi = $this->getBoolParam('options_cgi', true, 0);
|
||||
$error404path = $this->getParam('error404path', true, '');
|
||||
$error403path = $this->getParam('error403path', true, '');
|
||||
$error500path = $this->getParam('error500path', true, '');
|
||||
|
||||
// validation
|
||||
$path = makeCorrectDir(validate($path, 'path', '', '', array(), true));
|
||||
$userpath = $path;
|
||||
$path = makeCorrectDir($customer['documentroot'] . '/' . $path);
|
||||
|
||||
if (! empty($error404path)) {
|
||||
$error404path = correctErrorDocument($error404path, true);
|
||||
}
|
||||
|
||||
if (! empty($error403path)) {
|
||||
$error403path = correctErrorDocument($error403path, true);
|
||||
}
|
||||
|
||||
if (! empty($error500path)) {
|
||||
$error500path = correctErrorDocument($error500path, true);
|
||||
}
|
||||
|
||||
// check for duplicate path
|
||||
$path_dupe_check_stmt = Database::prepare("
|
||||
SELECT `id`, `path` FROM `" . TABLE_PANEL_HTACCESS . "`
|
||||
WHERE `path`= :path AND `customerid`= :customerid
|
||||
");
|
||||
$path_dupe_check = Database::pexecute_first($path_dupe_check_stmt, array(
|
||||
"path" => $path,
|
||||
"customerid" => $customer['customerid']
|
||||
), true, true);
|
||||
|
||||
// duplicate check
|
||||
if ($path_dupe_check['path'] == $path) {
|
||||
standard_error('errordocpathdupe', $userpath, true);
|
||||
}
|
||||
|
||||
// insert the entry
|
||||
$stmt = Database::prepare('
|
||||
INSERT INTO `' . TABLE_PANEL_HTACCESS . '` SET
|
||||
`customerid` = :customerid,
|
||||
`path` = :path,
|
||||
`options_indexes` = :options_indexes,
|
||||
`error404path` = :error404path,
|
||||
`error403path` = :error403path,
|
||||
`error500path` = :error500path,
|
||||
`options_cgi` = :options_cgi
|
||||
');
|
||||
$params = array(
|
||||
"customerid" => $customer['customerid'],
|
||||
"path" => $path,
|
||||
"options_indexes" => $options_indexes,
|
||||
"error403path" => $error403path,
|
||||
"error404path" => $error404path,
|
||||
"error500path" => $error500path,
|
||||
"options_cgi" => $options_cgi
|
||||
);
|
||||
Database::pexecute($stmt, $params, true, true);
|
||||
$id = Database::lastInsertId();
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_INFO, "[API] added directory-option for '" . $userpath . "'");
|
||||
inserttask('1');
|
||||
|
||||
$result = $this->apiCall('DirOptions.get', array(
|
||||
'id' => $id
|
||||
));
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* return a directory-protection entry by id
|
||||
*
|
||||
* @param int $id
|
||||
* id of dir-protection entry
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'extras')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
|
||||
$id = $this->getParam('id', true, 0);
|
||||
|
||||
$params = array();
|
||||
if ($this->isAdmin()) {
|
||||
if ($this->getUserDetail('customers_see_all') == false) {
|
||||
// if it's a reseller or an admin who cannot see all customers, we need to check
|
||||
// whether the database belongs to one of his customers
|
||||
$_custom_list_result = $this->apiCall('Customers.listing');
|
||||
$custom_list_result = $_custom_list_result['list'];
|
||||
$customer_ids = array();
|
||||
foreach ($custom_list_result as $customer) {
|
||||
$customer_ids[] = $customer['customerid'];
|
||||
}
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_PANEL_HTACCESS . "`
|
||||
WHERE `customerid` IN (" . implode(", ", $customer_ids) . ")
|
||||
AND `id` = :id
|
||||
");
|
||||
} else {
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_PANEL_HTACCESS . "`
|
||||
WHERE `id` = :id
|
||||
");
|
||||
}
|
||||
} else {
|
||||
if (Settings::IsInList('panel.customer_hide_options', 'extras.pathoptions')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_PANEL_HTACCESS . "`
|
||||
WHERE `customerid` = :customerid
|
||||
AND `id` = :id
|
||||
");
|
||||
$params['customerid'] = $this->getUserDetail('customerid');
|
||||
}
|
||||
$params['id'] = $id;
|
||||
$result = Database::pexecute_first($result_stmt, $params, true, true);
|
||||
if ($result) {
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_NOTICE, "[API] get directory options for '" . $result['path'] . "'");
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
$key = "id #" . $id;
|
||||
throw new Exception("Directory option with " . $key . " could not be found", 404);
|
||||
}
|
||||
|
||||
/**
|
||||
* update options for a given directory by id
|
||||
*
|
||||
* @param int $id
|
||||
* id of dir-protection entry
|
||||
* @param int $customerid
|
||||
* optional, admin-only, the customer-id
|
||||
* @param string $loginname
|
||||
* optional, admin-only, the loginname
|
||||
* @param bool $options_indexes
|
||||
* optional, activate directory-listing for this path, default 0 (false)
|
||||
* @param bool $options_cgi
|
||||
* optional, allow Perl/CGI execution, default 0 (false)
|
||||
* @param string $error404path
|
||||
* optional, custom 404 error string/file
|
||||
* @param string $error403path
|
||||
* optional, custom 403 error string/file
|
||||
* @param string $error500path
|
||||
* optional, custom 500 error string/file
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function update()
|
||||
{
|
||||
$id = $this->getParam('id', true, 0);
|
||||
|
||||
// validation
|
||||
$result = $this->apiCall('DirOptions.get', array(
|
||||
'id' => $id
|
||||
));
|
||||
|
||||
// get needed customer info to reduce the email-address-counter by one
|
||||
$customer = $this->getCustomerData();
|
||||
|
||||
// parameters
|
||||
$options_indexes = $this->getBoolParam('options_indexes', true, $result['options_indexes']);
|
||||
$options_cgi = $this->getBoolParam('options_cgi', true, $result['options_cgi']);
|
||||
$error404path = $this->getParam('error404path', true, $result['error404path']);
|
||||
$error403path = $this->getParam('error403path', true, $result['error403path']);
|
||||
$error500path = $this->getParam('error500path', true, $result['error500path']);
|
||||
|
||||
if (! empty($error404path)) {
|
||||
$error404path = correctErrorDocument($error404path, true);
|
||||
}
|
||||
|
||||
if (! empty($error403path)) {
|
||||
$error403path = correctErrorDocument($error403path, true);
|
||||
}
|
||||
|
||||
if (! empty($error500path)) {
|
||||
$error500path = correctErrorDocument($error500path, true);
|
||||
}
|
||||
|
||||
if (($options_indexes != $result['options_indexes']) || ($error404path != $result['error404path']) || ($error403path != $result['error403path']) || ($error500path != $result['error500path']) || ($options_cgi != $result['options_cgi'])) {
|
||||
inserttask('1');
|
||||
$stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_HTACCESS . "`
|
||||
SET `options_indexes` = :options_indexes,
|
||||
`error404path` = :error404path,
|
||||
`error403path` = :error403path,
|
||||
`error500path` = :error500path,
|
||||
`options_cgi` = :options_cgi
|
||||
WHERE `customerid` = :customerid
|
||||
AND `id` = :id
|
||||
");
|
||||
$params = array(
|
||||
"customerid" => $customer['customerid'],
|
||||
"options_indexes" => $options_indexes,
|
||||
"error403path" => $error403path,
|
||||
"error404path" => $error404path,
|
||||
"error500path" => $error500path,
|
||||
"options_cgi" => $options_cgi,
|
||||
"id" => $id
|
||||
);
|
||||
Database::pexecute($stmt, $params, true, true);
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_INFO, "[API] edited directory options for '" . str_replace($customer['documentroot'], '/', $result['path']) . "'");
|
||||
}
|
||||
|
||||
$result = $this->apiCall('DirOptions.get', array(
|
||||
'id' => $id
|
||||
));
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* list all directory-options, if called from an admin, list all directory-options of all customers you are allowed to view, or specify id or loginname for one specific customer
|
||||
*
|
||||
* @param int $customerid
|
||||
* optional, admin-only, select directory-protections of a specific customer by id
|
||||
* @param string $loginname
|
||||
* optional, admin-only, select directory-protections of a specific customer by loginname
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array count|list
|
||||
*/
|
||||
public function listing()
|
||||
{
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'extras')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
$customer_ids = $this->getAllowedCustomerIds('extras.pathoptions');
|
||||
|
||||
$result = array();
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_PANEL_HTACCESS . "`
|
||||
WHERE `customerid` IN (" . implode(', ', $customer_ids) . ")
|
||||
");
|
||||
Database::pexecute($result_stmt, null, true, true);
|
||||
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$result[] = $row;
|
||||
}
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_NOTICE, "[API] list directory-options");
|
||||
return $this->response(200, "successfull", array(
|
||||
'count' => count($result),
|
||||
'list' => $result
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* delete a directory-options by id
|
||||
*
|
||||
* @param int $id
|
||||
* id of dir-protection entry
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'extras')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
|
||||
$id = $this->getParam('id');
|
||||
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'extras.pathoptions')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
|
||||
// get directory-option
|
||||
$result = $this->apiCall('DirOptions.get', array(
|
||||
'id' => $id
|
||||
));
|
||||
|
||||
if ($this->isAdmin()) {
|
||||
// get customer-data
|
||||
$customer_data = $this->apiCall('Customers.get', array(
|
||||
'id' => $result['customerid']
|
||||
));
|
||||
} else {
|
||||
$customer_data = $this->getUserData();
|
||||
}
|
||||
|
||||
// do we have to remove the symlink and folder in suexecpath?
|
||||
if ((int) Settings::Get('perl.suexecworkaround') == 1) {
|
||||
$loginname = $customer_data['loginname'];
|
||||
$suexecpath = makeCorrectDir(Settings::Get('perl.suexecpath') . '/' . $loginname . '/' . md5($result['path']) . '/');
|
||||
$perlsymlink = makeCorrectFile($result['path'] . '/cgi-bin');
|
||||
// remove symlink
|
||||
if (file_exists($perlsymlink)) {
|
||||
safe_exec('rm -f ' . escapeshellarg($perlsymlink));
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_DEBUG, "[API] deleted suexecworkaround symlink '" . $perlsymlink . "'");
|
||||
}
|
||||
// remove folder in suexec-path
|
||||
if (file_exists($suexecpath)) {
|
||||
safe_exec('rm -rf ' . escapeshellarg($suexecpath));
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_DEBUG, "[API] deleted suexecworkaround path '" . $suexecpath . "'");
|
||||
}
|
||||
}
|
||||
$stmt = Database::prepare("
|
||||
DELETE FROM `" . TABLE_PANEL_HTACCESS . "`
|
||||
WHERE `customerid`= :customerid
|
||||
AND `id`= :id
|
||||
");
|
||||
Database::pexecute($stmt, array(
|
||||
"customerid" => $customer_data['customerid'],
|
||||
"id" => $id
|
||||
));
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_INFO, "[API] deleted directory-option for '" . str_replace($customer_data['documentroot'], '/', $result['path']) . "'");
|
||||
inserttask('1');
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
}
|
||||
@@ -1,359 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package API
|
||||
* @since 0.10.0
|
||||
*
|
||||
*/
|
||||
class DirProtections extends ApiCommand implements ResourceEntity
|
||||
{
|
||||
|
||||
/**
|
||||
* add htaccess protection to a given directory
|
||||
*
|
||||
* @param int $customerid
|
||||
* optional, admin-only, the customer-id
|
||||
* @param string $loginname
|
||||
* optional, admin-only, the loginname
|
||||
* @param string $path
|
||||
* @param string $username
|
||||
* @param string $directory_password
|
||||
* @param string $directory_authname
|
||||
* optional name/description for the protection
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'extras')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'extras.directoryprotection')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
|
||||
// get needed customer info to reduce the email-address-counter by one
|
||||
$customer = $this->getCustomerData();
|
||||
|
||||
// required parameters
|
||||
$path = $this->getParam('path');
|
||||
$username = $this->getParam('username');
|
||||
$password = $this->getParam('directory_password');
|
||||
|
||||
// parameters
|
||||
$authname = $this->getParam('directory_authname', true, '');
|
||||
|
||||
// validation
|
||||
$path = makeCorrectDir(validate($path, 'path', '', '', array(), true));
|
||||
$path = makeCorrectDir($customer['documentroot'] . '/' . $path);
|
||||
$username = validate($username, 'username', '/^[a-zA-Z0-9][a-zA-Z0-9\-_]+\$?$/', '', array(), true);
|
||||
$authname = validate($authname, 'directory_authname', '/^[a-zA-Z0-9][a-zA-Z0-9\-_ ]+\$?$/', '', array(), true);
|
||||
validate($password, 'password', '', '', array(), true);
|
||||
|
||||
// check for duplicate usernames for the path
|
||||
$username_path_check_stmt = Database::prepare("
|
||||
SELECT `id`, `username`, `path` FROM `" . TABLE_PANEL_HTPASSWDS . "`
|
||||
WHERE `username`= :username AND `path`= :path AND `customerid`= :customerid
|
||||
");
|
||||
$params = array(
|
||||
"username" => $username,
|
||||
"path" => $path,
|
||||
"customerid" => $customer['customerid']
|
||||
);
|
||||
$username_path_check = Database::pexecute_first($username_path_check_stmt, $params, true, true);
|
||||
|
||||
// check whether we can used salted passwords
|
||||
if (CRYPT_STD_DES == 1) {
|
||||
$saltfordescrypt = substr(md5(uniqid(microtime(), 1)), 4, 2);
|
||||
$password_enc = crypt($password, $saltfordescrypt);
|
||||
} else {
|
||||
$password_enc = crypt($password);
|
||||
}
|
||||
|
||||
// duplicate check
|
||||
if ($username_path_check['username'] == $username && $username_path_check['path'] == $path) {
|
||||
standard_error('userpathcombinationdupe', '', true);
|
||||
} elseif ($password == $username) {
|
||||
standard_error('passwordshouldnotbeusername', '', true);
|
||||
}
|
||||
|
||||
// insert the entry
|
||||
$stmt = Database::prepare("
|
||||
INSERT INTO `" . TABLE_PANEL_HTPASSWDS . "` SET
|
||||
`customerid` = :customerid,
|
||||
`username` = :username,
|
||||
`password` = :password,
|
||||
`path` = :path,
|
||||
`authname` = :authname
|
||||
");
|
||||
$params = array(
|
||||
"customerid" => $customer['customerid'],
|
||||
"username" => $username,
|
||||
"password" => $password_enc,
|
||||
"path" => $path,
|
||||
"authname" => $authname
|
||||
);
|
||||
Database::pexecute($stmt, $params, true, true);
|
||||
$id = Database::lastInsertId();
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_INFO, "[API] added directory-protection for '" . $username . " (" . $path . ")'");
|
||||
inserttask('1');
|
||||
|
||||
$result = $this->apiCall('DirProtections.get', array(
|
||||
'id' => $id
|
||||
));
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* return a directory-protection entry by either id or username
|
||||
*
|
||||
* @param int $id
|
||||
* optional, the directory-protection-id
|
||||
* @param string $username
|
||||
* optional, the username
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'extras')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
|
||||
$id = $this->getParam('id', true, 0);
|
||||
$un_optional = ($id <= 0 ? false : true);
|
||||
$username = $this->getParam('username', $un_optional, '');
|
||||
|
||||
$params = array();
|
||||
if ($this->isAdmin()) {
|
||||
if ($this->getUserDetail('customers_see_all') == false) {
|
||||
// if it's a reseller or an admin who cannot see all customers, we need to check
|
||||
// whether the database belongs to one of his customers
|
||||
$_custom_list_result = $this->apiCall('Customers.listing');
|
||||
$custom_list_result = $_custom_list_result['list'];
|
||||
$customer_ids = array();
|
||||
foreach ($custom_list_result as $customer) {
|
||||
$customer_ids[] = $customer['customerid'];
|
||||
}
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_PANEL_HTPASSWDS . "`
|
||||
WHERE `customerid` IN (" . implode(", ", $customer_ids) . ")
|
||||
AND (`id` = :idun OR `username` = :idun)
|
||||
");
|
||||
} else {
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_PANEL_HTPASSWDS . "`
|
||||
WHERE (`id` = :idun OR `username` = :idun)
|
||||
");
|
||||
}
|
||||
} else {
|
||||
if (Settings::IsInList('panel.customer_hide_options', 'extras.directoryprotection')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_PANEL_HTPASSWDS . "`
|
||||
WHERE `customerid` = :customerid
|
||||
AND (`id` = :idun OR `username` = :idun)
|
||||
");
|
||||
$params['customerid'] = $this->getUserDetail('customerid');
|
||||
}
|
||||
$params['idun'] = ($id <= 0 ? $username : $id);
|
||||
$result = Database::pexecute_first($result_stmt, $params, true, true);
|
||||
if ($result) {
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_NOTICE, "[API] get directory protection for '" . $result['path'] . "'");
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
$key = ($id > 0 ? "id #" . $id : "username '" . $username . "'");
|
||||
throw new Exception("Directory protection with " . $key . " could not be found", 404);
|
||||
}
|
||||
|
||||
/**
|
||||
* update htaccess protection of a given directory
|
||||
*
|
||||
* @param int $id
|
||||
* optional the directory-protection-id
|
||||
* @param string $username
|
||||
* optional, the username
|
||||
* @param int $customerid
|
||||
* optional, admin-only, the customer-id
|
||||
* @param string $loginname
|
||||
* optional, admin-only, the loginname
|
||||
* @param string $directory_password
|
||||
* optional, leave empty for no change
|
||||
* @param string $directory_authname
|
||||
* optional name/description for the protection
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function update()
|
||||
{
|
||||
$id = $this->getParam('id', true, 0);
|
||||
$un_optional = ($id <= 0 ? false : true);
|
||||
$username = $this->getParam('username', $un_optional, '');
|
||||
|
||||
// validation
|
||||
$result = $this->apiCall('DirProtections.get', array(
|
||||
'id' => $id,
|
||||
'username' => $username
|
||||
));
|
||||
$id = $result['id'];
|
||||
|
||||
// parameters
|
||||
$password = $this->getParam('directory_password', true, '');
|
||||
$authname = $this->getParam('directory_authname', true, $result['authname']);
|
||||
|
||||
// get needed customer info
|
||||
$customer = $this->getCustomerData();
|
||||
|
||||
// validation
|
||||
$authname = validate($authname, 'directory_authname', '/^[a-zA-Z0-9][a-zA-Z0-9\-_ ]+\$?$/', '', array(), true);
|
||||
validate($password, 'password', '', '', array(), true);
|
||||
|
||||
$upd_query = "";
|
||||
$upd_params = array(
|
||||
"id" => $result['id'],
|
||||
"cid" => $customer['customerid']
|
||||
);
|
||||
if (! empty($password)) {
|
||||
if ($password == $result['username']) {
|
||||
standard_error('passwordshouldnotbeusername', '', true);
|
||||
}
|
||||
if (CRYPT_STD_DES == 1) {
|
||||
$saltfordescrypt = substr(md5(uniqid(microtime(), 1)), 4, 2);
|
||||
$password_enc = crypt($password, $saltfordescrypt);
|
||||
} else {
|
||||
$password_enc = crypt($password);
|
||||
}
|
||||
$upd_query .= "`password`= :password_enc";
|
||||
$upd_params['password_enc'] = $password_enc;
|
||||
}
|
||||
if ($authname != $result['authname']) {
|
||||
if (! empty($upd_query)) {
|
||||
$upd_query .= ", ";
|
||||
}
|
||||
$upd_query .= "`authname` = :authname";
|
||||
$upd_params['authname'] = $authname;
|
||||
}
|
||||
|
||||
// build update query
|
||||
if (! empty($upd_query)) {
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_HTPASSWDS . "` SET " . $upd_query . " WHERE `id` = :id AND `customerid`= :cid
|
||||
");
|
||||
Database::pexecute($upd_stmt, $upd_params, true, true);
|
||||
inserttask('1');
|
||||
}
|
||||
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_INFO, "[API] updated directory-protection '" . $result['username'] . " (" . $result['path'] . ")'");
|
||||
$result = $this->apiCall('DirProtections.get', array(
|
||||
'id' => $result['id']
|
||||
));
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* list all directory-protections, if called from an admin, list all directory-protections of all customers you are allowed to view, or specify id or loginname for one specific customer
|
||||
*
|
||||
* @param int $customerid
|
||||
* optional, admin-only, select directory-protections of a specific customer by id
|
||||
* @param string $loginname
|
||||
* optional, admin-only, select directory-protections of a specific customer by loginname
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array count|list
|
||||
*/
|
||||
public function listing()
|
||||
{
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'extras')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
$customer_ids = $this->getAllowedCustomerIds('extras.directoryprotection');
|
||||
|
||||
$result = array();
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_PANEL_HTPASSWDS . "`
|
||||
WHERE `customerid` IN (" . implode(', ', $customer_ids) . ")
|
||||
");
|
||||
Database::pexecute($result_stmt, null, true, true);
|
||||
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$result[] = $row;
|
||||
}
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_NOTICE, "[API] list directory-protections");
|
||||
return $this->response(200, "successfull", array(
|
||||
'count' => count($result),
|
||||
'list' => $result
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* delete a directory-protection by either id or username
|
||||
*
|
||||
* @param int $id
|
||||
* optional, the directory-protection-id
|
||||
* @param string $username
|
||||
* optional, the username
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'extras')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
|
||||
$id = $this->getParam('id', true, 0);
|
||||
$un_optional = ($id <= 0 ? false : true);
|
||||
$username = $this->getParam('username', $un_optional, '');
|
||||
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'extras.directoryprotection')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
|
||||
// get directory protection
|
||||
$result = $this->apiCall('DirProtections.get', array(
|
||||
'id' => $id,
|
||||
'username' => $username
|
||||
));
|
||||
$id = $result['id'];
|
||||
|
||||
if ($this->isAdmin()) {
|
||||
// get customer-data
|
||||
$customer_data = $this->apiCall('Customers.get', array(
|
||||
'id' => $result['customerid']
|
||||
));
|
||||
} else {
|
||||
$customer_data = $this->getUserData();
|
||||
}
|
||||
|
||||
$stmt = Database::prepare("
|
||||
DELETE FROM `" . TABLE_PANEL_HTPASSWDS . "` WHERE `customerid`= :customerid AND `id`= :id
|
||||
");
|
||||
Database::pexecute($stmt, array(
|
||||
"customerid" => $customer_data['customerid'],
|
||||
"id" => $id
|
||||
));
|
||||
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_INFO, "[API] deleted htpasswd for '" . $result['username'] . " (" . $result['path'] . ")'");
|
||||
inserttask('1');
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
}
|
||||
@@ -1,396 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package API
|
||||
* @since 0.10.0
|
||||
*
|
||||
*/
|
||||
class DomainZones extends ApiCommand implements ResourceEntity
|
||||
{
|
||||
|
||||
/**
|
||||
* add a new dns zone for a given domain by id or domainname
|
||||
*
|
||||
* @param int $id
|
||||
* optional domain id
|
||||
* @param string $domainname
|
||||
* optional domain name
|
||||
* @param string $record
|
||||
* optional, default empty
|
||||
* @param string $type
|
||||
* optional, zone-entry type (A, AAAA, TXT, etc.), default 'A'
|
||||
* @param int $prio
|
||||
* optional, priority, default empty
|
||||
* @param string $content
|
||||
* optional, default empty
|
||||
* @param int $ttl
|
||||
* optional, default 18000
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
if (Settings::Get('system.dnsenabled') != '1') {
|
||||
throw new Exception("DNS server not enabled on this system", 405);
|
||||
}
|
||||
|
||||
$id = $this->getParam('id', true, 0);
|
||||
$dn_optional = ($id <= 0 ? false : true);
|
||||
$domainname = $this->getParam('domainname', $dn_optional, '');
|
||||
|
||||
// get requested domain
|
||||
$result = $this->apiCall('SubDomains.get', array(
|
||||
'id' => $id,
|
||||
'domainname' => $domainname
|
||||
));
|
||||
$id = $result['id'];
|
||||
|
||||
// parameters
|
||||
$record = $this->getParam('record', true, null);
|
||||
$type = $this->getParam('type', true, 'A');
|
||||
$prio = $this->getParam('prio', true, null);
|
||||
$content = $this->getParam('content', true, null);
|
||||
$ttl = $this->getParam('ttl', true, 18000);
|
||||
|
||||
if ($result['parentdomainid'] != '0') {
|
||||
throw new Exception("DNS zones can only be generated for the main domain, not for subdomains", 406);
|
||||
}
|
||||
|
||||
if ($result['subisbinddomain'] != '1') {
|
||||
standard_error('dns_domain_nodns', '', true);
|
||||
}
|
||||
|
||||
$idna_convert = new idna_convert_wrapper();
|
||||
$domain = $idna_convert->encode($result['domain']);
|
||||
|
||||
// select all entries
|
||||
$sel_stmt = Database::prepare("SELECT * FROM `" . TABLE_DOMAIN_DNS . "` WHERE domain_id = :did");
|
||||
Database::pexecute($sel_stmt, array(
|
||||
'did' => $id
|
||||
), true, true);
|
||||
$dom_entries = $sel_stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// validation
|
||||
$errors = array();
|
||||
if (empty($record)) {
|
||||
$record = "@";
|
||||
}
|
||||
|
||||
$record = trim(strtolower($record));
|
||||
|
||||
if ($record != '@' && $record != '*') {
|
||||
// validate record
|
||||
if (strpos($record, '--') !== false) {
|
||||
$errors[] = $this->lng['error']['domain_nopunycode'];
|
||||
} else {
|
||||
// check for wildcard-record
|
||||
$add_wildcard_again = false;
|
||||
if (substr($record, 0, 2) == '*.') {
|
||||
$record = substr($record, 2);
|
||||
$add_wildcard_again = true;
|
||||
}
|
||||
// convert entry
|
||||
$record = $idna_convert->encode($record);
|
||||
|
||||
if ($add_wildcard_again) {
|
||||
$record = '*.' . $record;
|
||||
}
|
||||
|
||||
if (strlen($record) > 63) {
|
||||
$errors[] = $this->lng['error']['dns_record_toolong'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO regex validate content for invalid characters
|
||||
|
||||
if ($ttl <= 0) {
|
||||
$ttl = 18000;
|
||||
}
|
||||
|
||||
$content = trim($content);
|
||||
if (empty($content)) {
|
||||
$errors[] = $this->lng['error']['dns_content_empty'];
|
||||
}
|
||||
|
||||
// types
|
||||
if ($type == 'A' && filter_var($content, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false) {
|
||||
$errors[] = $this->lng['error']['dns_arec_noipv4'];
|
||||
} elseif ($type == 'AAAA' && filter_var($content, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false) {
|
||||
$errors[] = $this->lng['error']['dns_aaaarec_noipv6'];
|
||||
} elseif ($type == 'MX') {
|
||||
if ($prio === null || $prio < 0) {
|
||||
$errors[] = $this->lng['error']['dns_mx_prioempty'];
|
||||
}
|
||||
// check for trailing dot
|
||||
if (substr($content, - 1) == '.') {
|
||||
// remove it for checks
|
||||
$content = substr($content, 0, - 1);
|
||||
}
|
||||
if (! validateDomain($content)) {
|
||||
$errors[] = $this->lng['error']['dns_mx_needdom'];
|
||||
} else {
|
||||
// check whether there is a CNAME-record for the same resource
|
||||
foreach ($dom_entries as $existing_entries) {
|
||||
$fqdn = $existing_entries['record'] . '.' . $domain;
|
||||
if ($existing_entries['type'] == 'CNAME' && $fqdn == $content) {
|
||||
$errors[] = $this->lng['error']['dns_mx_noalias'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// append trailing dot (again)
|
||||
$content .= '.';
|
||||
} elseif ($type == 'CNAME') {
|
||||
// check for trailing dot
|
||||
if (substr($content, - 1) == '.') {
|
||||
// remove it for checks
|
||||
$content = substr($content, 0, - 1);
|
||||
} else {
|
||||
// add domain name
|
||||
$content .= '.' . $domain;
|
||||
}
|
||||
if (! validateDomain($content, true)) {
|
||||
$errors[] = $this->lng['error']['dns_cname_invaliddom'];
|
||||
} else {
|
||||
// check whether there are RR-records for the same resource
|
||||
foreach ($dom_entries as $existing_entries) {
|
||||
if (($existing_entries['type'] == 'A' || $existing_entries['type'] == 'AAAA' || $existing_entries['type'] == 'MX' || $existing_entries['type'] == 'NS') && $existing_entries['record'] == $record) {
|
||||
$errors[] = $this->lng['error']['dns_cname_nomorerr'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// append trailing dot (again)
|
||||
$content .= '.';
|
||||
} elseif ($type == 'NS') {
|
||||
// check for trailing dot
|
||||
if (substr($content, - 1) == '.') {
|
||||
// remove it for checks
|
||||
$content = substr($content, 0, - 1);
|
||||
}
|
||||
if (! validateDomain($content)) {
|
||||
$errors[] = $this->lng['error']['dns_ns_invaliddom'];
|
||||
}
|
||||
// append trailing dot (again)
|
||||
$content .= '.';
|
||||
} elseif ($type == 'TXT' && ! empty($content)) {
|
||||
// check that TXT content is enclosed in " "
|
||||
$content = encloseTXTContent($content);
|
||||
} elseif ($type == 'SRV') {
|
||||
if ($prio === null || $prio < 0) {
|
||||
$errors[] = $this->lng['error']['dns_srv_prioempty'];
|
||||
}
|
||||
// check only last part of content, as it can look like:
|
||||
// _service._proto.name. TTL class SRV priority weight port target.
|
||||
$_split_content = explode(" ", $content);
|
||||
// SRV content must be [weight] [port] [target]
|
||||
if (count($_split_content) != 3) {
|
||||
$errors[] = $this->lng['error']['dns_srv_invalidcontent'];
|
||||
}
|
||||
$target = trim($_split_content[count($_split_content) - 1]);
|
||||
if ($target != '.') {
|
||||
// check for trailing dot
|
||||
if (substr($target, - 1) == '.') {
|
||||
// remove it for checks
|
||||
$target = substr($target, 0, - 1);
|
||||
}
|
||||
}
|
||||
if ($target != '.' && ! validateDomain($target, true)) {
|
||||
$errors[] = $this->lng['error']['dns_srv_needdom'];
|
||||
} else {
|
||||
// check whether there is a CNAME-record for the same resource
|
||||
foreach ($dom_entries as $existing_entries) {
|
||||
$fqdn = $existing_entries['record'] . '.' . $domain;
|
||||
if ($existing_entries['type'] == 'CNAME' && $fqdn == $target) {
|
||||
$errors[] = $this->lng['error']['dns_srv_noalias'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// append trailing dot if there's none
|
||||
if (substr($content, - 1) != '.') {
|
||||
$content .= '.';
|
||||
}
|
||||
}
|
||||
|
||||
$new_entry = array(
|
||||
'record' => $record,
|
||||
'type' => $type,
|
||||
'prio' => (int) $prio,
|
||||
'content' => $content,
|
||||
'ttl' => (int) $ttl,
|
||||
'domain_id' => (int) $id
|
||||
);
|
||||
ksort($new_entry);
|
||||
|
||||
// check for duplicate
|
||||
foreach ($dom_entries as $existing_entry) {
|
||||
// compare json-encoded string of array
|
||||
$check_entry = $existing_entry;
|
||||
// new entry has no ID yet
|
||||
unset($check_entry['id']);
|
||||
// sort by key
|
||||
ksort($check_entry);
|
||||
// format integer fields to real integer (as they are read as string from the DB)
|
||||
$check_entry['prio'] = (int) $check_entry['prio'];
|
||||
$check_entry['ttl'] = (int) $check_entry['ttl'];
|
||||
$check_entry['domain_id'] = (int) $check_entry['domain_id'];
|
||||
// encode both
|
||||
$check_entry = json_encode($check_entry);
|
||||
$new = json_encode($new_entry);
|
||||
// compare
|
||||
if ($check_entry === $new) {
|
||||
$errors[] = $this->lng['error']['dns_duplicate_entry'];
|
||||
unset($check_entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($errors)) {
|
||||
$ins_stmt = Database::prepare("
|
||||
INSERT INTO `" . TABLE_DOMAIN_DNS . "` SET
|
||||
`record` = :record,
|
||||
`type` = :type,
|
||||
`prio` = :prio,
|
||||
`content` = :content,
|
||||
`ttl` = :ttl,
|
||||
`domain_id` = :domain_id
|
||||
");
|
||||
Database::pexecute($ins_stmt, $new_entry, true, true);
|
||||
$new_entry_id = Database::lastInsertId();
|
||||
|
||||
// add temporary to the entries-array (no reread of DB necessary)
|
||||
$new_entry['id'] = $new_entry_id;
|
||||
$dom_entries[] = $new_entry;
|
||||
|
||||
// re-generate bind configs
|
||||
inserttask('4');
|
||||
|
||||
$result = $this->apiCall('DomainZones.get', array(
|
||||
'id' => $id
|
||||
));
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
// return $errors
|
||||
throw new Exception(implode("\n", $errors));
|
||||
}
|
||||
|
||||
/**
|
||||
* return a domain-dns entry by either id or domainname
|
||||
*
|
||||
* @param int $id
|
||||
* optional, the domain id
|
||||
* @param string $domainname
|
||||
* optional, the domain name
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
if (Settings::Get('system.dnsenabled') != '1') {
|
||||
throw new Exception("DNS server not enabled on this system", 405);
|
||||
}
|
||||
|
||||
$id = $this->getParam('id', true, 0);
|
||||
$dn_optional = ($id <= 0 ? false : true);
|
||||
$domainname = $this->getParam('domainname', $dn_optional, '');
|
||||
|
||||
// get requested domain
|
||||
$result = $this->apiCall('SubDomains.get', array(
|
||||
'id' => $id,
|
||||
'domainname' => $domainname
|
||||
));
|
||||
$id = $result['id'];
|
||||
|
||||
if ($result['parentdomainid'] != '0') {
|
||||
throw new Exception("DNS zones can only be generated for the main domain, not for subdomains", 406);
|
||||
}
|
||||
|
||||
if ($result['subisbinddomain'] != '1') {
|
||||
standard_error('dns_domain_nodns', '', true);
|
||||
}
|
||||
|
||||
$zone = createDomainZone($id);
|
||||
$zonefile = (string) $zone;
|
||||
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_NOTICE, "[API] get dns-zone for '" . $result['domain'] . "'");
|
||||
return $this->response(200, "successfull", explode("\n", $zonefile));
|
||||
}
|
||||
|
||||
/**
|
||||
* You cannot update a dns zone entry.
|
||||
* You need to delete it and re-add it.
|
||||
*/
|
||||
public function update()
|
||||
{
|
||||
throw new Exception('You cannot update a dns zone entry. You need to delete it and re-add it.', 303);
|
||||
}
|
||||
|
||||
/**
|
||||
* You cannot list dns zones.
|
||||
* To get all domains use Domains.listing() or SubDomains.listing()
|
||||
*/
|
||||
public function listing()
|
||||
{
|
||||
throw new Exception('You cannot list dns zones. To get all domains use Domains.listing() or SubDomains.listing()', 303);
|
||||
}
|
||||
|
||||
/**
|
||||
* deletes a domain-dns entry by id
|
||||
*
|
||||
* @param int $entry_id
|
||||
* @param int $id
|
||||
* optional, the domain id
|
||||
* @param string $domainname
|
||||
* optional, the domain name
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return bool
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
if (Settings::Get('system.dnsenabled') != '1') {
|
||||
throw new Exception("DNS server not enabled on this system", 405);
|
||||
}
|
||||
|
||||
$entry_id = $this->getParam('entry_id');
|
||||
$id = $this->getParam('id', true, 0);
|
||||
$dn_optional = ($id <= 0 ? false : true);
|
||||
$domainname = $this->getParam('domainname', $dn_optional, '');
|
||||
|
||||
// get requested domain
|
||||
$result = $this->apiCall('SubDomains.get', array(
|
||||
'id' => $id,
|
||||
'domainname' => $domainname
|
||||
));
|
||||
$id = $result['id'];
|
||||
|
||||
$del_stmt = Database::prepare("DELETE FROM `" . TABLE_DOMAIN_DNS . "` WHERE `id` = :id AND `domain_id` = :did");
|
||||
Database::pexecute($del_stmt, array(
|
||||
'id' => $entry_id,
|
||||
'did' => $id
|
||||
), true, true);
|
||||
if ($del_stmt->rowCount() > 0) {
|
||||
// re-generate bind configs
|
||||
inserttask('4');
|
||||
return $this->response(200, "successfull", true);
|
||||
}
|
||||
return $this->response(304, "successfull", true);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,486 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package API
|
||||
* @since 0.10.0
|
||||
*
|
||||
*/
|
||||
class EmailAccounts extends ApiCommand implements ResourceEntity
|
||||
{
|
||||
|
||||
/**
|
||||
* add a new email account for a given email-address either by id or emailaddr
|
||||
*
|
||||
* @param int $id
|
||||
* optional email-address-id of email-address to add the account for
|
||||
* @param string $emailaddr
|
||||
* optional email-address to add the account for
|
||||
* @param int $customerid
|
||||
* optional, admin-only, the customer-id
|
||||
* @param string $loginname
|
||||
* optional, admin-only, the loginname
|
||||
* @param string $email_password
|
||||
* password for the account
|
||||
* @param string $alternative_email
|
||||
* optional email address to send account information to, default is the account that is being created
|
||||
* @param int $email_quota
|
||||
* optional quota if enabled in MB, default 0
|
||||
* @param bool $sendinfomail
|
||||
* optional, sends the welcome message to the new account (needed for creation, without the user won't be able to login before any mail is received), default 1 (true)
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'email')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
|
||||
if ($this->getUserDetail('email_accounts_used') < $this->getUserDetail('email_accounts') || $this->getUserDetail('email_accounts') == '-1') {
|
||||
|
||||
// parameter
|
||||
$id = $this->getParam('id', true, 0);
|
||||
$ea_optional = ($id <= 0 ? false : true);
|
||||
$emailaddr = $this->getParam('emailaddr', $ea_optional, '');
|
||||
$email_password = $this->getParam('email_password');
|
||||
$alternative_email = $this->getParam('alternative_email', true, '');
|
||||
$quota = $this->getParam('email_quota', true, 0);
|
||||
$sendinfomail = $this->getBoolParam('sendinfomail', true, 1);
|
||||
|
||||
// validation
|
||||
$quota = validate($quota, 'email_quota', '/^\d+$/', 'vmailquotawrong', array(), true);
|
||||
|
||||
// get needed customer info to reduce the email-account-counter by one
|
||||
$customer = $this->getCustomerData('email_accounts');
|
||||
|
||||
// check for imap||pop3 == 1, see #1298
|
||||
if ($customer['imap'] != '1' && $customer['pop3'] != '1') {
|
||||
standard_error('notallowedtouseaccounts', '', true);
|
||||
}
|
||||
|
||||
// get email address
|
||||
$result = $this->apiCall('Emails.get', array(
|
||||
'id' => $id,
|
||||
'emailaddr' => $emailaddr
|
||||
));
|
||||
$id = $result['id'];
|
||||
|
||||
$email_full = $result['email_full'];
|
||||
$idna_convert = new idna_convert_wrapper();
|
||||
$username = $idna_convert->decode($email_full);
|
||||
$password = validate($email_password, 'password', '', '', array(), true);
|
||||
$password = validatePassword($password, true);
|
||||
|
||||
if ($result['popaccountid'] != 0) {
|
||||
throw new Exception("Email address '" . $email_full . "' has already an account assigned.", 406);
|
||||
}
|
||||
|
||||
if (checkMailAccDeletionState($email_full)) {
|
||||
standard_error(array(
|
||||
'mailaccistobedeleted'
|
||||
), $email_full, true);
|
||||
}
|
||||
|
||||
// alternative email address to send info to
|
||||
if (Settings::Get('panel.sendalternativemail') == 1) {
|
||||
$alternative_email = $idna_convert->encode(validate($alternative_email, 'alternative_email', '', '', array(), true));
|
||||
if (! validateEmail($alternative_email)) {
|
||||
standard_error('emailiswrong', $alternative_email, true);
|
||||
}
|
||||
} else {
|
||||
$alternative_email = '';
|
||||
}
|
||||
|
||||
// validate quota if enabled
|
||||
if (Settings::Get('system.mail_quota_enabled') == 1) {
|
||||
if ($customer['email_quota'] != '-1' && ($quota == 0 || ($quota + $customer['email_quota_used']) > $customer['email_quota'])) {
|
||||
standard_error('allocatetoomuchquota', $quota, true);
|
||||
}
|
||||
} else {
|
||||
// disable
|
||||
$quota = 0;
|
||||
}
|
||||
|
||||
if ($password == $email_full) {
|
||||
standard_error('passwordshouldnotbeusername', '', true);
|
||||
}
|
||||
|
||||
// encrypt the password
|
||||
$cryptPassword = makeCryptPassword($password);
|
||||
|
||||
$email_user = substr($email_full, 0, strrpos($email_full, "@"));
|
||||
$email_domain = substr($email_full, strrpos($email_full, "@") + 1);
|
||||
$maildirname = trim(Settings::Get('system.vmail_maildirname'));
|
||||
// Add trailing slash to Maildir if needed
|
||||
$maildirpath = $maildirname;
|
||||
if (! empty($maildirname) && substr($maildirname, - 1) != "/") {
|
||||
$maildirpath .= "/";
|
||||
}
|
||||
|
||||
// insert data
|
||||
$stmt = Database::prepare("INSERT INTO `" . TABLE_MAIL_USERS . "` SET
|
||||
`customerid` = :cid,
|
||||
`email` = :email,
|
||||
`username` = :username," . (Settings::Get('system.mailpwcleartext') == '1' ? '`password` = :password, ' : '') . "
|
||||
`password_enc` = :password_enc,
|
||||
`homedir` = :homedir,
|
||||
`maildir` = :maildir,
|
||||
`uid` = :uid,
|
||||
`gid` = :gid,
|
||||
`domainid` = :domainid,
|
||||
`postfix` = 'y',
|
||||
`quota` = :quota,
|
||||
`imap` = :imap,
|
||||
`pop3` = :pop3
|
||||
");
|
||||
$params = array(
|
||||
"cid" => $customer['customerid'],
|
||||
"email" => $email_full,
|
||||
"username" => $username,
|
||||
"password_enc" => $cryptPassword,
|
||||
"homedir" => Settings::Get('system.vmail_homedir'),
|
||||
"maildir" => $customer['loginname'] . '/' . $email_domain . "/" . $email_user . "/" . $maildirpath,
|
||||
"uid" => Settings::Get('system.vmail_uid'),
|
||||
"gid" => Settings::Get('system.vmail_gid'),
|
||||
"domainid" => $result['domainid'],
|
||||
"quota" => $quota,
|
||||
"imap" => $customer['imap'],
|
||||
"pop3" => $customer['pop3']
|
||||
);
|
||||
if (Settings::Get('system.mailpwcleartext') == '1') {
|
||||
$params["password"] = $password;
|
||||
}
|
||||
Database::pexecute($stmt, $params, true, true);
|
||||
$popaccountid = Database::lastInsertId();
|
||||
|
||||
// add email address to its destination field
|
||||
$result['destination'] .= ' ' . $email_full;
|
||||
$stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_MAIL_VIRTUAL . "` SET `destination` = :destination, `popaccountid` = :popaccountid
|
||||
WHERE `customerid`= :cid AND `id`= :id
|
||||
");
|
||||
$params = array(
|
||||
"destination" => makeCorrectDestination($result['destination']),
|
||||
"popaccountid" => $popaccountid,
|
||||
"cid" => $customer['customerid'],
|
||||
"id" => $id
|
||||
);
|
||||
Database::pexecute($stmt, $params, true, true);
|
||||
|
||||
// update customer usage
|
||||
Customers::increaseUsage($customer['customerid'], 'email_accounts_used');
|
||||
Customers::increaseUsage($customer['customerid'], 'email_quota_used', '', $quota);
|
||||
|
||||
// update admin usage
|
||||
Admins::increaseUsage($customer['adminid'], 'email_accounts_used');
|
||||
Admins::increaseUsage($customer['adminid'], 'email_quota_used', '', $quota);
|
||||
|
||||
if ($sendinfomail) {
|
||||
// replacer array for mail to create account on server
|
||||
$replace_arr = array(
|
||||
'EMAIL' => $email_full,
|
||||
'USERNAME' => $username,
|
||||
'PASSWORD' => $password
|
||||
);
|
||||
|
||||
// get the customers admin
|
||||
$stmt = Database::prepare("SELECT `name`, `email` FROM `" . TABLE_PANEL_ADMINS . "` WHERE `adminid`= :adminid");
|
||||
$admin = Database::pexecute_first($stmt, array(
|
||||
"adminid" => $customer['adminid']
|
||||
));
|
||||
|
||||
// get template for mail subject
|
||||
$mail_subject = $this->getMailTemplate($customer, 'mails', 'pop_success_subject', $replace_arr, $this->lng['mails']['pop_success']['subject']);
|
||||
// get template for mail body
|
||||
$mail_body = $this->getMailTemplate($customer, 'mails', 'pop_success_mailbody', $replace_arr, $this->lng['mails']['pop_success']['mailbody']);
|
||||
|
||||
$_mailerror = false;
|
||||
$mailerr_msg = "";
|
||||
try {
|
||||
$this->mailer()->setFrom($admin['email'], getCorrectUserSalutation($admin));
|
||||
$this->mailer()->Subject = $mail_subject;
|
||||
$this->mailer()->AltBody = $mail_body;
|
||||
$this->mailer()->msgHTML(str_replace("\n", "<br />", $mail_body));
|
||||
$this->mailer()->addAddress($email_full);
|
||||
$this->mailer()->send();
|
||||
} catch (phpmailerException $e) {
|
||||
$mailerr_msg = $e->errorMessage();
|
||||
$_mailerror = true;
|
||||
} catch (Exception $e) {
|
||||
$mailerr_msg = $e->getMessage();
|
||||
$_mailerror = true;
|
||||
}
|
||||
|
||||
if ($_mailerror) {
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_ERR, "[API] Error sending mail: " . $mailerr_msg);
|
||||
standard_error('errorsendingmail', $email_full, true);
|
||||
}
|
||||
|
||||
$this->mailer()->clearAddresses();
|
||||
|
||||
// customer wants to send the e-mail to an alternative email address too
|
||||
if (Settings::Get('panel.sendalternativemail') == 1) {
|
||||
// get template for mail subject
|
||||
$mail_subject = $this->getMailTemplate($customer, 'mails', 'pop_success_alternative_subject', $replace_arr, $this->lng['mails']['pop_success_alternative']['subject']);
|
||||
// get template for mail body
|
||||
$mail_body = $this->getMailTemplate($customer, 'mails', 'pop_success_alternative_mailbody', $replace_arr, $this->lng['mails']['pop_success_alternative']['mailbody']);
|
||||
|
||||
$_mailerror = false;
|
||||
try {
|
||||
$this->mailer()->setFrom($admin['email'], getCorrectUserSalutation($admin));
|
||||
$this->mailer()->Subject = $mail_subject;
|
||||
$this->mailer()->AltBody = $mail_body;
|
||||
$this->mailer()->msgHTML(str_replace("\n", "<br />", $mail_body));
|
||||
$this->mailer()->addAddress($idna_convert->encode($alternative_email), getCorrectUserSalutation($customer));
|
||||
$this->mailer()->send();
|
||||
} catch (phpmailerException $e) {
|
||||
$mailerr_msg = $e->errorMessage();
|
||||
$_mailerror = true;
|
||||
} catch (Exception $e) {
|
||||
$mailerr_msg = $e->getMessage();
|
||||
$_mailerror = true;
|
||||
}
|
||||
|
||||
if ($_mailerror) {
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_ERR, "[API] Error sending mail: " . $mailerr_msg);
|
||||
standard_error(array(
|
||||
'errorsendingmail'
|
||||
), $alternative_email, true);
|
||||
}
|
||||
|
||||
$this->mailer()->clearAddresses();
|
||||
}
|
||||
}
|
||||
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_INFO, "[API] added email account for '" . $result['email_full'] . "'");
|
||||
$result = $this->apiCall('Emails.get', array(
|
||||
'emailaddr' => $result['email_full']
|
||||
));
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
throw new Exception("No more resources available", 406);
|
||||
}
|
||||
|
||||
/**
|
||||
* You cannot directly get an email account.
|
||||
* You need to call Emails.get()
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
throw new Exception('You cannot directly get an email account. You need to call Emails.get()', 303);
|
||||
}
|
||||
|
||||
/**
|
||||
* update email-account entry for given email-address by either id or email-address
|
||||
*
|
||||
* @param int $id
|
||||
* optional, the email-address-id
|
||||
* @param string $emailaddr
|
||||
* optional, the email-address to update
|
||||
* @param int $customerid
|
||||
* optional, admin-only, the customer-id
|
||||
* @param string $loginname
|
||||
* optional, admin-only, the loginname
|
||||
* @param int $email_quota
|
||||
* optional, update quota
|
||||
* @param string $email_password
|
||||
* optional, update password
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function update()
|
||||
{
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'email')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
|
||||
// parameter
|
||||
$id = $this->getParam('id', true, 0);
|
||||
$ea_optional = ($id <= 0 ? false : true);
|
||||
$emailaddr = $this->getParam('emailaddr', $ea_optional, '');
|
||||
|
||||
// validation
|
||||
$result = $this->apiCall('Emails.get', array(
|
||||
'id' => $id,
|
||||
'emailaddr' => $emailaddr
|
||||
));
|
||||
$id = $result['id'];
|
||||
|
||||
if (empty($result['popaccountid']) || $result['popaccountid'] == 0) {
|
||||
throw new Exception("Email address '" . $result['email_full'] . "' has no account assigned.", 406);
|
||||
}
|
||||
|
||||
$password = $this->getParam('email_password', true, '');
|
||||
$quota = $this->getParam('email_quota', true, $result['quota']);
|
||||
|
||||
// get needed customer info to reduce the email-account-counter by one
|
||||
$customer = $this->getCustomerData();
|
||||
|
||||
// validation
|
||||
$quota = validate($quota, 'email_quota', '/^\d+$/', 'vmailquotawrong', array(), true);
|
||||
|
||||
$upd_query = "";
|
||||
$upd_params = array(
|
||||
"id" => $result['popaccountid'],
|
||||
"cid" => $customer['customerid']
|
||||
);
|
||||
if (! empty($password)) {
|
||||
if ($password == $result['email_full']) {
|
||||
standard_error('passwordshouldnotbeusername', '', true);
|
||||
}
|
||||
$password = validatePassword($password, true);
|
||||
$cryptPassword = makeCryptPassword($password);
|
||||
$upd_query .= (Settings::Get('system.mailpwcleartext') == '1' ? "`password` = :password, " : '') . "`password_enc`= :password_enc";
|
||||
$upd_params['password_enc'] = $cryptPassword;
|
||||
if (Settings::Get('system.mailpwcleartext') == '1') {
|
||||
$upd_params['password'] = $password;
|
||||
}
|
||||
}
|
||||
|
||||
if (Settings::Get('system.mail_quota_enabled') == 1) {
|
||||
if ($quota != $result['quota']) {
|
||||
if ($customer['email_quota'] != '-1' && ($quota == 0 || ($quota + $customer['email_quota_used'] - $result['quota']) > $customer['email_quota'])) {
|
||||
standard_error('allocatetoomuchquota', $quota, true);
|
||||
}
|
||||
if (! empty($upd_query)) {
|
||||
$upd_query .= ", ";
|
||||
}
|
||||
$upd_query .= "`quota` = :quota";
|
||||
$upd_params['quota'] = $quota;
|
||||
}
|
||||
} else {
|
||||
// disable
|
||||
$quota = 0;
|
||||
}
|
||||
|
||||
// build update query
|
||||
if (! empty($upd_query)) {
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_MAIL_USERS . "` SET " . $upd_query . " WHERE `id` = :id AND `customerid`= :cid
|
||||
");
|
||||
Database::pexecute($upd_stmt, $upd_params, true, true);
|
||||
}
|
||||
|
||||
if ($customer['email_quota'] != '-1') {
|
||||
Customers::increaseUsage($customer['customerid'], 'email_quota_used', '', ($quota - $result['quota']));
|
||||
Admins::increaseUsage($customer['adminid'], 'email_quota_used', '', ($quota - $result['quota']));
|
||||
}
|
||||
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_INFO, "[API] updated email account '" . $result['email_full'] . "'");
|
||||
$result = $this->apiCall('Emails.get', array(
|
||||
'emailaddr' => $result['email_full']
|
||||
));
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* You cannot directly list email forwarders.
|
||||
* You need to call Emails.listing()
|
||||
*/
|
||||
public function listing()
|
||||
{
|
||||
throw new Exception('You cannot directly list email forwarders. You need to call Emails.listing()', 303);
|
||||
}
|
||||
|
||||
/**
|
||||
* delete email-account entry for given email-address by either id or email-address
|
||||
*
|
||||
* @param int $id
|
||||
* optional, the email-address-id
|
||||
* @param string $emailaddr
|
||||
* optional, the email-address to delete the account for
|
||||
* @param int $customerid
|
||||
* optional, admin-only, the customer-id
|
||||
* @param string $loginname
|
||||
* optional, admin-only, the loginname
|
||||
* @param bool $delete_userfiles
|
||||
* optional, default false
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'email')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
|
||||
// parameter
|
||||
$id = $this->getParam('id', true, 0);
|
||||
$ea_optional = ($id <= 0 ? false : true);
|
||||
$emailaddr = $this->getParam('emailaddr', $ea_optional, '');
|
||||
$delete_userfiles = $this->getBoolParam('delete_userfiles', true, 0);
|
||||
|
||||
// validation
|
||||
$result = $this->apiCall('Emails.get', array(
|
||||
'id' => $id,
|
||||
'emailaddr' => $emailaddr
|
||||
));
|
||||
$id = $result['id'];
|
||||
|
||||
if (empty($result['popaccountid']) || $result['popaccountid'] == 0) {
|
||||
throw new Exception("Email address '" . $result['email_full'] . "' has no account assigned.", 406);
|
||||
}
|
||||
|
||||
// get needed customer info to reduce the email-account-counter by one
|
||||
$customer = $this->getCustomerData();
|
||||
|
||||
// delete entry
|
||||
$stmt = Database::prepare("
|
||||
DELETE FROM `" . TABLE_MAIL_USERS . "` WHERE `customerid`= :cid AND `id`= :id
|
||||
");
|
||||
Database::pexecute($stmt, array(
|
||||
"cid" => $customer['customerid'],
|
||||
"id" => $result['popaccountid']
|
||||
), true, true);
|
||||
|
||||
// update mail-virtual entry
|
||||
$result['destination'] = str_replace($result['email_full'], '', $result['destination']);
|
||||
|
||||
$stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_MAIL_VIRTUAL . "` SET `destination` = :dest, `popaccountid` = '0' WHERE `customerid`= :cid AND `id`= :id
|
||||
");
|
||||
$params = array(
|
||||
"dest" => makeCorrectDestination($result['destination']),
|
||||
"cid" => $customer['customerid'],
|
||||
"id" => $id
|
||||
);
|
||||
Database::pexecute($stmt, $params, true, true);
|
||||
$result['popaccountid'] = 0;
|
||||
|
||||
if (Settings::Get('system.mail_quota_enabled') == '1' && $customer['email_quota'] != '-1') {
|
||||
$quota = (int) $result['quota'];
|
||||
} else {
|
||||
$quota = 0;
|
||||
}
|
||||
|
||||
if ($delete_userfiles) {
|
||||
inserttask('7', $customer['loginname'], $result['email_full']);
|
||||
}
|
||||
|
||||
// decrease usage for customer
|
||||
Customers::decreaseUsage($customer['customerid'], 'email_accounts_used');
|
||||
Customers::decreaseUsage($customer['customerid'], 'email_quota_used', '', $quota);
|
||||
// decrease admin usage
|
||||
Admins::decreaseUsage($customer['adminid'], 'email_accounts_used');
|
||||
Admins::decreaseUsage($customer['adminid'], 'email_quota_used', '', $quota);
|
||||
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_INFO, "[API] deleted email account for '" . $result['email_full'] . "'");
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
}
|
||||
@@ -1,210 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package API
|
||||
* @since 0.10.0
|
||||
*
|
||||
*/
|
||||
class EmailForwarders extends ApiCommand implements ResourceEntity
|
||||
{
|
||||
|
||||
/**
|
||||
* add new email-forwarder entry for given email-address by either id or email-address
|
||||
*
|
||||
* @param int $id
|
||||
* optional, the email-address-id
|
||||
* @param string $emailaddr
|
||||
* optional, the email-address to add the forwarder for
|
||||
* @param int $customerid
|
||||
* optional, admin-only, the customer-id
|
||||
* @param string $loginname
|
||||
* optional, admin-only, the loginname
|
||||
* @param string $destination
|
||||
* email-address to add as forwarder
|
||||
*
|
||||
* @access admin,customer
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'email')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
|
||||
if ($this->getUserDetail('email_forwarders_used') < $this->getUserDetail('email_forwarders') || $this->getUserDetail('email_forwarders') == '-1') {
|
||||
|
||||
// parameter
|
||||
$id = $this->getParam('id', true, 0);
|
||||
$ea_optional = ($id <= 0 ? false : true);
|
||||
$emailaddr = $this->getParam('emailaddr', $ea_optional, '');
|
||||
$destination = $this->getParam('destination');
|
||||
|
||||
// validation
|
||||
$idna_convert = new idna_convert_wrapper();
|
||||
$destination = $idna_convert->encode($destination);
|
||||
|
||||
$result = $this->apiCall('Emails.get', array(
|
||||
'id' => $id,
|
||||
'emailaddr' => $emailaddr
|
||||
));
|
||||
$id = $result['id'];
|
||||
|
||||
// current destination array
|
||||
$result['destination_array'] = explode(' ', $result['destination']);
|
||||
|
||||
// prepare destination
|
||||
$destination = trim($destination);
|
||||
|
||||
if (! validateEmail($destination)) {
|
||||
standard_error('destinationiswrong', $destination, true);
|
||||
} elseif ($destination == $result['email']) {
|
||||
standard_error('destinationalreadyexistasmail', $destination, true);
|
||||
} elseif (in_array($destination, $result['destination_array'])) {
|
||||
standard_error('destinationalreadyexist', $destination, true);
|
||||
}
|
||||
|
||||
// get needed customer info to reduce the email-forwarder-counter by one
|
||||
$customer = $this->getCustomerData('email_forwarders');
|
||||
|
||||
// add destination to address
|
||||
$result['destination'] .= ' ' . $destination;
|
||||
$stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_MAIL_VIRTUAL . "` SET `destination` = :dest
|
||||
WHERE `customerid`= :cid AND `id`= :id
|
||||
");
|
||||
$params = array(
|
||||
"dest" => makeCorrectDestination($result['destination']),
|
||||
"cid" => $customer['customerid'],
|
||||
"id" => $id
|
||||
);
|
||||
Database::pexecute($stmt, $params, true, true);
|
||||
|
||||
// update customer usage
|
||||
Customers::increaseUsage($customer['customerid'], 'email_forwarders_used');
|
||||
|
||||
// update admin usage
|
||||
Admins::increaseUsage($customer['adminid'], 'email_forwarders_used');
|
||||
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_INFO, "[API] added email forwarder for '" . $result['email_full'] . "'");
|
||||
|
||||
$result = $this->apiCall('Emails.get', array(
|
||||
'emailaddr' => $result['email_full']
|
||||
));
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
throw new Exception("No more resources available", 406);
|
||||
}
|
||||
|
||||
/**
|
||||
* You cannot directly get an email forwarder.
|
||||
* You need to call Emails.get()
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
throw new Exception('You cannot directly get an email forwarder. You need to call Emails.get()', 303);
|
||||
}
|
||||
|
||||
/**
|
||||
* You cannot update an email forwarder.
|
||||
* You need to delete the entry and create a new one.
|
||||
*/
|
||||
public function update()
|
||||
{
|
||||
throw new Exception('You cannot update an email forwarder. You need to delete the entry and create a new one.', 303);
|
||||
}
|
||||
|
||||
/**
|
||||
* You cannot directly list email forwarders.
|
||||
* You need to call Emails.listing()
|
||||
*/
|
||||
public function listing()
|
||||
{
|
||||
throw new Exception('You cannot directly list email forwarders. You need to call Emails.listing()', 303);
|
||||
}
|
||||
|
||||
/**
|
||||
* delete email-forwarder entry for given email-address by either id or email-address and forwarder-id
|
||||
*
|
||||
* @param int $id
|
||||
* optional, the email-address-id
|
||||
* @param string $emailaddr
|
||||
* optional, the email-address to delete the forwarder from
|
||||
* @param int $customerid
|
||||
* optional, admin-only, the customer-id
|
||||
* @param string $loginname
|
||||
* optional, admin-only, the loginname
|
||||
* @param int $forwarderid
|
||||
* id of the forwarder to delete
|
||||
*
|
||||
* @access admin,customer
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'email')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
|
||||
// parameter
|
||||
$id = $this->getParam('id', true, 0);
|
||||
$ea_optional = ($id <= 0 ? false : true);
|
||||
$emailaddr = $this->getParam('emailaddr', $ea_optional, '');
|
||||
$forwarderid = $this->getParam('forwarderid');
|
||||
|
||||
// validation
|
||||
$result = $this->apiCall('Emails.get', array(
|
||||
'id' => $id,
|
||||
'emailaddr' => $emailaddr
|
||||
));
|
||||
$id = $result['id'];
|
||||
|
||||
$result['destination'] = explode(' ', $result['destination']);
|
||||
if (isset($result['destination'][$forwarderid]) && $result['email'] != $result['destination'][$forwarderid]) {
|
||||
|
||||
// get needed customer info to reduce the email-forwarder-counter by one
|
||||
$customer = $this->getCustomerData();
|
||||
|
||||
// unset it from array
|
||||
unset($result['destination'][$forwarderid]);
|
||||
// rebuild destination-string
|
||||
$result['destination'] = implode(' ', $result['destination']);
|
||||
// update in DB
|
||||
$stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_MAIL_VIRTUAL . "` SET `destination` = :dest
|
||||
WHERE `customerid`= :cid AND `id`= :id
|
||||
");
|
||||
$params = array(
|
||||
"dest" => makeCorrectDestination($result['destination']),
|
||||
"cid" => $customer['customerid'],
|
||||
"id" => $id
|
||||
);
|
||||
Database::pexecute($stmt, $params, true, true);
|
||||
|
||||
// update customer usage
|
||||
Customers::decreaseUsage($customer['customerid'], 'email_forwarders_used');
|
||||
|
||||
// update admin usage
|
||||
Admins::decreaseUsage($customer['adminid'], 'email_forwarders_used');
|
||||
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_INFO, "[API] deleted email forwarder for '" . $result['email_full'] . "'");
|
||||
|
||||
$result = $this->apiCall('Emails.get', array(
|
||||
'emailaddr' => $result['email_full']
|
||||
));
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
throw new Exception("Unknown forwarder id", 404);
|
||||
}
|
||||
}
|
||||
@@ -1,385 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package API
|
||||
* @since 0.10.0
|
||||
*
|
||||
*/
|
||||
class Emails extends ApiCommand implements ResourceEntity
|
||||
{
|
||||
|
||||
/**
|
||||
* add a new email address
|
||||
*
|
||||
* @param string $email_part
|
||||
* name of the address before @
|
||||
* @param string $domain
|
||||
* domain-name for the email-address
|
||||
* @param boolean $iscatchall
|
||||
* optional, make this address a catchall address, default: no
|
||||
* @param int $customerid
|
||||
* optional, admin-only, the customer-id
|
||||
* @param string $loginname
|
||||
* optional, admin-only, the loginname
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'email')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
|
||||
if ($this->getUserDetail('emails_used') < $this->getUserDetail('emails') || $this->getUserDetail('emails') == '-1') {
|
||||
|
||||
// required parameters
|
||||
$email_part = $this->getParam('email_part');
|
||||
$domain = $this->getParam('domain');
|
||||
|
||||
// parameters
|
||||
$iscatchall = $this->getBoolParam('iscatchall', true, 0);
|
||||
|
||||
// validation
|
||||
if (substr($domain, 0, 4) != 'xn--') {
|
||||
$idna_convert = new idna_convert_wrapper();
|
||||
$domain = $idna_convert->encode(validate($domain, 'domain', '', '', array(), true));
|
||||
}
|
||||
|
||||
// check domain and whether it's an email-enabled domain
|
||||
$domain_check = $this->apiCall('SubDomains.get', array(
|
||||
'domainname' => $domain
|
||||
));
|
||||
if ($domain_check['isemaildomain'] == 0) {
|
||||
standard_error('maindomainnonexist', $domain, true);
|
||||
}
|
||||
|
||||
if (Settings::Get('catchall.catchall_enabled') != '1') {
|
||||
$iscatchall = 0;
|
||||
}
|
||||
|
||||
// check for catchall-flag
|
||||
if ($iscatchall) {
|
||||
$iscatchall = '1';
|
||||
$email = '@' . $domain;
|
||||
} else {
|
||||
$iscatchall = '0';
|
||||
$email = $email_part . '@' . $domain;
|
||||
}
|
||||
|
||||
// full email value
|
||||
$email_full = $email_part . '@' . $domain;
|
||||
|
||||
// validate it
|
||||
if (! validateEmail($email_full)) {
|
||||
standard_error('emailiswrong', $email_full, true);
|
||||
}
|
||||
|
||||
// get needed customer info to reduce the email-address-counter by one
|
||||
$customer = $this->getCustomerData('emails');
|
||||
|
||||
// duplicate check
|
||||
$stmt = Database::prepare("
|
||||
SELECT `id`, `email`, `email_full`, `iscatchall`, `destination`, `customerid` FROM `" . TABLE_MAIL_VIRTUAL . "`
|
||||
WHERE (`email` = :email OR `email_full` = :emailfull )
|
||||
AND `customerid`= :cid
|
||||
");
|
||||
$params = array(
|
||||
"email" => $email,
|
||||
"emailfull" => $email_full,
|
||||
"cid" => $customer['customerid']
|
||||
);
|
||||
$email_check = Database::pexecute_first($stmt, $params, true, true);
|
||||
|
||||
if (strtolower($email_check['email_full']) == strtolower($email_full)) {
|
||||
standard_error('emailexistalready', $email_full, true);
|
||||
} elseif ($email_check['email'] == $email) {
|
||||
standard_error('youhavealreadyacatchallforthisdomain', '', true);
|
||||
}
|
||||
|
||||
$stmt = Database::prepare("
|
||||
INSERT INTO `" . TABLE_MAIL_VIRTUAL . "` SET
|
||||
`customerid` = :cid,
|
||||
`email` = :email,
|
||||
`email_full` = :email_full,
|
||||
`iscatchall` = :iscatchall,
|
||||
`domainid` = :domainid
|
||||
");
|
||||
$params = array(
|
||||
"cid" => $customer['customerid'],
|
||||
"email" => $email,
|
||||
"email_full" => $email_full,
|
||||
"iscatchall" => $iscatchall,
|
||||
"domainid" => $domain_check['id']
|
||||
);
|
||||
Database::pexecute($stmt, $params, true, true);
|
||||
|
||||
// update customer usage
|
||||
Customers::increaseUsage($customer['customerid'], 'emails_used');
|
||||
|
||||
// update admin usage
|
||||
Admins::increaseUsage($customer['adminid'], 'emails_used');
|
||||
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_INFO, "[API] added email address '" . $email_full . "'");
|
||||
|
||||
$result = $this->apiCall('Emails.get', array(
|
||||
'emailaddr' => $email_full
|
||||
));
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
throw new Exception("No more resources available", 406);
|
||||
}
|
||||
|
||||
/**
|
||||
* return a email-address entry by either id or email-address
|
||||
*
|
||||
* @param int $id
|
||||
* optional, the email-address-id
|
||||
* @param string $emailaddr
|
||||
* optional, the email-address
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
$id = $this->getParam('id', true, 0);
|
||||
$ea_optional = ($id <= 0 ? false : true);
|
||||
$emailaddr = $this->getParam('emailaddr', $ea_optional, '');
|
||||
|
||||
$params = array();
|
||||
$customer_ids = $this->getAllowedCustomerIds('email');
|
||||
$params['idea'] = ($id <= 0 ? $emailaddr : $id);
|
||||
|
||||
$result_stmt = Database::prepare("SELECT v.`id`, v.`email`, v.`email_full`, v.`iscatchall`, v.`destination`, v.`customerid`, v.`popaccountid`, v.`domainid`, u.`quota`
|
||||
FROM `" . TABLE_MAIL_VIRTUAL . "` v
|
||||
LEFT JOIN `" . TABLE_MAIL_USERS . "` u ON v.`popaccountid` = u.`id`
|
||||
WHERE v.`customerid` IN (" . implode(", ", $customer_ids) . ")
|
||||
AND (v.`id`= :idea OR (v.`email` = :idea OR v.`email_full` = :idea))
|
||||
");
|
||||
$result = Database::pexecute_first($result_stmt, $params, true, true);
|
||||
if ($result) {
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_NOTICE, "[API] get email address '" . $result['email_full'] . "'");
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
$key = ($id > 0 ? "id #" . $id : "emailaddr '" . $emailaddr . "'");
|
||||
throw new Exception("Email address with " . $key . " could not be found", 404);
|
||||
}
|
||||
|
||||
/**
|
||||
* toggle catchall flag of given email address either by id or email-address
|
||||
*
|
||||
* @param int $id
|
||||
* optional, the email-address-id
|
||||
* @param string $emailaddr
|
||||
* optional, the email-address
|
||||
* @param int $customerid
|
||||
* optional, admin-only, the customer-id
|
||||
* @param string $loginname
|
||||
* optional, admin-only, the loginname
|
||||
* @param boolean $iscatchall
|
||||
* optional
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function update()
|
||||
{
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'email')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
|
||||
// if enabling catchall is not allowed by settings, we do not need
|
||||
// to run update()
|
||||
if (Settings::Get('catchall.catchall_enabled') != '1') {
|
||||
standard_error(array(
|
||||
'operationnotpermitted',
|
||||
'featureisdisabled'
|
||||
), 'catchall', true);
|
||||
}
|
||||
|
||||
$id = $this->getParam('id', true, 0);
|
||||
$ea_optional = ($id <= 0 ? false : true);
|
||||
$emailaddr = $this->getParam('emailaddr', $ea_optional, '');
|
||||
|
||||
$result = $this->apiCall('Emails.get', array(
|
||||
'id' => $id,
|
||||
'emailaddr' => $emailaddr
|
||||
));
|
||||
$id = $result['id'];
|
||||
|
||||
// parameters
|
||||
$iscatchall = $this->getBoolParam('iscatchall', true, $result['iscatchall']);
|
||||
|
||||
// get needed customer info to reduce the email-address-counter by one
|
||||
$customer = $this->getCustomerData();
|
||||
|
||||
// check for catchall-flag
|
||||
if ($iscatchall) {
|
||||
$iscatchall = '1';
|
||||
$email_parts = explode('@', $result['email_full']);
|
||||
$email = '@' . $email_parts[1];
|
||||
} else {
|
||||
$iscatchall = '0';
|
||||
$email = $result['email_full'];
|
||||
}
|
||||
|
||||
$stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_MAIL_VIRTUAL . "`
|
||||
SET `email` = :email , `iscatchall` = :caflag
|
||||
WHERE `customerid`= :cid AND `id`= :id
|
||||
");
|
||||
$params = array(
|
||||
"email" => $email,
|
||||
"caflag" => $iscatchall,
|
||||
"cid" => $customer['customerid'],
|
||||
"id" => $id
|
||||
);
|
||||
Database::pexecute($stmt, $params, true, true);
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_INFO, "[API] toggled catchall-flag for email address '" . $result['email_full'] . "'");
|
||||
|
||||
$result = $this->apiCall('Emails.get', array(
|
||||
'emailaddr' => $result['email_full']
|
||||
));
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* list all email addresses, if called from an admin, list all email addresses of all customers you are allowed to view, or specify id or loginname for one specific customer
|
||||
*
|
||||
* @param int $customerid
|
||||
* optional, admin-only, select email addresses of a specific customer by id
|
||||
* @param string $loginname
|
||||
* optional, admin-only, select email addresses of a specific customer by loginname
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array count|list
|
||||
*/
|
||||
public function listing()
|
||||
{
|
||||
$customer_ids = $this->getAllowedCustomerIds('email');
|
||||
$result = array();
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT m.`id`, m.`domainid`, m.`email`, m.`email_full`, m.`iscatchall`, u.`quota`, m.`destination`, m.`popaccountid`, d.`domain`, u.`mboxsize`
|
||||
FROM `" . TABLE_MAIL_VIRTUAL . "` m
|
||||
LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` d ON (m.`domainid` = d.`id`)
|
||||
LEFT JOIN `" . TABLE_MAIL_USERS . "` u ON (m.`popaccountid` = u.`id`)
|
||||
WHERE m.`customerid` IN (" . implode(", ", $customer_ids) . ")
|
||||
");
|
||||
Database::pexecute($result_stmt, null, true, true);
|
||||
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$result[] = $row;
|
||||
}
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_NOTICE, "[API] list email-addresses");
|
||||
return $this->response(200, "successfull", array(
|
||||
'count' => count($result),
|
||||
'list' => $result
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* delete an email address by either id or username
|
||||
*
|
||||
* @param int $id
|
||||
* optional, the email-address-id
|
||||
* @param string $emailaddr
|
||||
* optional, the email-address
|
||||
* @param int $customerid
|
||||
* optional, admin-only, the customer-id
|
||||
* @param string $loginname
|
||||
* optional, admin-only, the loginname
|
||||
* @param boolean $delete_userfiles
|
||||
* optional, delete email data from filesystem, default: 0 (false)
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'email')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
|
||||
$id = $this->getParam('id', true, 0);
|
||||
$ea_optional = ($id <= 0 ? false : true);
|
||||
$emailaddr = $this->getParam('emailaddr', $ea_optional, '');
|
||||
|
||||
$result = $this->apiCall('Emails.get', array(
|
||||
'id' => $id,
|
||||
'emailaddr' => $emailaddr
|
||||
));
|
||||
$id = $result['id'];
|
||||
|
||||
// parameters
|
||||
$delete_userfiles = $this->getBoolParam('delete_userfiles', true, 0);
|
||||
|
||||
// get needed customer info to reduce the email-address-counter by one
|
||||
$customer = $this->getCustomerData();
|
||||
|
||||
// check for forwarders
|
||||
$number_forwarders = 0;
|
||||
if ($result['destination'] != '') {
|
||||
$result['destination'] = explode(' ', $result['destination']);
|
||||
$number_forwarders = count($result['destination']);
|
||||
}
|
||||
// check whether this address is an account
|
||||
if ($result['popaccountid'] != 0) {
|
||||
// Free the Quota used by the email account
|
||||
if (Settings::Get('system.mail_quota_enabled') == 1) {
|
||||
$stmt = Database::prepare("SELECT `quota` FROM `" . TABLE_MAIL_USERS . "` WHERE `customerid`= :customerid AND `id`= :id");
|
||||
$res_quota = Database::pexecute_first($stmt, array(
|
||||
"customerid" => $customer['customerid'],
|
||||
"id" => $result['popaccountid']
|
||||
), true, true);
|
||||
Customers::decreaseUsage($customer['customerid'], 'email_quota_used', '', $res_quota['quota']);
|
||||
Admins::decreaseUsage($customer['customerid'], 'email_quota_used', '', $res_quota['quota']);
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_INFO, "[API] deleted quota entries for email address '" . $result['email_full'] . "'");
|
||||
}
|
||||
// delete account
|
||||
$stmt = Database::prepare("DELETE FROM `" . TABLE_MAIL_USERS . "` WHERE `customerid`= :customerid AND `id`= :id");
|
||||
Database::pexecute($stmt, array(
|
||||
"customerid" => $customer['customerid'],
|
||||
"id" => $result['popaccountid']
|
||||
), true, true);
|
||||
Customers::decreaseUsage($customer['customerid'], 'email_accounts_used');
|
||||
Admins::decreaseUsage($customer['customerid'], 'email_accounts_used');
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_INFO, "[API] deleted email account '" . $result['email_full'] . "'");
|
||||
$number_forwarders --;
|
||||
}
|
||||
|
||||
// decrease forwarder counter
|
||||
Customers::decreaseUsage($customer['customerid'], 'email_forwarders_used', '', $number_forwarders);
|
||||
Admins::decreaseUsage($customer['customerid'], 'email_forwarders_used', '', $number_forwarders);
|
||||
|
||||
if ($delete_userfiles) {
|
||||
inserttask('7', $customer['loginname'], $result['email_full']);
|
||||
}
|
||||
|
||||
// delete address
|
||||
$stmt = Database::prepare("DELETE FROM `" . TABLE_MAIL_VIRTUAL . "` WHERE `customerid`= :customerid AND `id`= :id");
|
||||
Database::pexecute($stmt, array(
|
||||
"customerid" => $customer['customerid'],
|
||||
"id" => $id
|
||||
), true, true);
|
||||
Customers::decreaseUsage($customer['customerid'], 'emails_used');
|
||||
Admins::decreaseUsage($customer['customerid'], 'emails_used');
|
||||
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_INFO, "[API] deleted email address '" . $result['email_full'] . "'");
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
}
|
||||
@@ -1,369 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package API
|
||||
* @since 0.10.0
|
||||
*
|
||||
*/
|
||||
class FpmDaemons extends ApiCommand implements ResourceEntity
|
||||
{
|
||||
|
||||
/**
|
||||
* lists all fpm-daemon entries
|
||||
*
|
||||
* @access admin
|
||||
* @throws Exception
|
||||
* @return array count|list
|
||||
*/
|
||||
public function listing()
|
||||
{
|
||||
if ($this->isAdmin()) {
|
||||
$this->logger()->logAction(ADM_ACTION, LOG_NOTICE, "[API] list fpm-daemons");
|
||||
|
||||
$result = Database::query("
|
||||
SELECT * FROM `" . TABLE_PANEL_FPMDAEMONS . "` ORDER BY `description` ASC
|
||||
");
|
||||
|
||||
$fpmdaemons = array();
|
||||
while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
|
||||
|
||||
$query_params = array(
|
||||
'id' => $row['id']
|
||||
);
|
||||
|
||||
$query = "SELECT * FROM `" . TABLE_PANEL_PHPCONFIGS . "` WHERE `fpmsettingid` = :id";
|
||||
|
||||
$configresult_stmt = Database::prepare($query);
|
||||
Database::pexecute($configresult_stmt, $query_params, true, true);
|
||||
|
||||
$configs = array();
|
||||
if (Database::num_rows() > 0) {
|
||||
while ($row2 = $configresult_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$configs[] = $row2['description'];
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($configs)) {
|
||||
$configs[] = $this->lng['admin']['phpsettings']['notused'];
|
||||
}
|
||||
|
||||
$row['configs'] = $configs;
|
||||
$fpmdaemons[] = $row;
|
||||
}
|
||||
|
||||
return $this->response(200, "successfull", array(
|
||||
'count' => count($fpmdaemons),
|
||||
'list' => $fpmdaemons
|
||||
));
|
||||
}
|
||||
throw new Exception("Not allowed to execute given command.", 403);
|
||||
}
|
||||
|
||||
/**
|
||||
* return a fpm-daemon entry by id
|
||||
*
|
||||
* @param int $id
|
||||
* fpm-daemon-id
|
||||
*
|
||||
* @access admin
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
if ($this->isAdmin()) {
|
||||
$id = $this->getParam('id');
|
||||
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_PANEL_FPMDAEMONS . "` WHERE `id` = :id
|
||||
");
|
||||
$result = Database::pexecute_first($result_stmt, array(
|
||||
'id' => $id
|
||||
), true, true);
|
||||
if ($result) {
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
throw new Exception("fpm-daemon with id #" . $id . " could not be found", 404);
|
||||
}
|
||||
throw new Exception("Not allowed to execute given command.", 403);
|
||||
}
|
||||
|
||||
/**
|
||||
* create a new fpm-daemon entry
|
||||
*
|
||||
* @param string $description
|
||||
* @param string $reload_cmd
|
||||
* @param string $config_dir
|
||||
* @param string $pm
|
||||
* optional, process-manager, one of 'static', 'dynamic' or 'ondemand', default 'static'
|
||||
* @param int $max_children
|
||||
* optional, default 0
|
||||
* @param int $start_servers
|
||||
* optional, default 0
|
||||
* @param int $min_spare_servers
|
||||
* optional, default 0
|
||||
* @param int $max_spare_servers
|
||||
* optional, default 0
|
||||
* @param int $max_requests
|
||||
* optional, default 0
|
||||
* @param int $idle_timeout
|
||||
* optional, default 0
|
||||
* @param string $limit_extensions
|
||||
* optional, limit execution to the following extensions, default '.php'
|
||||
*
|
||||
* @access admin
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
if ($this->isAdmin() && $this->getUserDetail('change_serversettings') == 1) {
|
||||
|
||||
// required parameter
|
||||
$description = $this->getParam('description');
|
||||
$reload_cmd = $this->getParam('reload_cmd');
|
||||
$config_dir = $this->getParam('config_dir');
|
||||
|
||||
// parameters
|
||||
$pmanager = $this->getParam('pm', true, 'static');
|
||||
$max_children = $this->getParam('max_children', true, 0);
|
||||
$start_servers = $this->getParam('start_servers', true, 0);
|
||||
$min_spare_servers = $this->getParam('min_spare_servers', true, 0);
|
||||
$max_spare_servers = $this->getParam('max_spare_servers', true, 0);
|
||||
$max_requests = $this->getParam('max_requests', true, 0);
|
||||
$idle_timeout = $this->getParam('idle_timeout', true, 0);
|
||||
$limit_extensions = $this->getParam('limit_extensions', true, '.php');
|
||||
|
||||
// validation
|
||||
$description = validate($description, 'description', '', '', array(), true);
|
||||
$reload_cmd = validate($reload_cmd, 'reload_cmd', '', '', array(), true);
|
||||
$config_dir = validate($config_dir, 'config_dir', '', '', array(), true);
|
||||
if (! in_array($pmanager, array(
|
||||
'static',
|
||||
'dynamic',
|
||||
'ondemand'
|
||||
))) {
|
||||
throw new ErrorException("Unknown process manager", 406);
|
||||
}
|
||||
if (empty($limit_extensions)) {
|
||||
$limit_extensions = '.php';
|
||||
}
|
||||
$limit_extensions = validate($limit_extensions, 'limit_extensions', '/^(\.[a-z]([a-z0-9]+)\ ?)+$/', '', array(), true);
|
||||
|
||||
if (strlen($description) == 0 || strlen($description) > 50) {
|
||||
standard_error('descriptioninvalid', '', true);
|
||||
}
|
||||
|
||||
$ins_stmt = Database::prepare("
|
||||
INSERT INTO `" . TABLE_PANEL_FPMDAEMONS . "` SET
|
||||
`description` = :desc,
|
||||
`reload_cmd` = :reload_cmd,
|
||||
`config_dir` = :config_dir,
|
||||
`pm` = :pm,
|
||||
`max_children` = :max_children,
|
||||
`start_servers` = :start_servers,
|
||||
`min_spare_servers` = :min_spare_servers,
|
||||
`max_spare_servers` = :max_spare_servers,
|
||||
`max_requests` = :max_requests,
|
||||
`idle_timeout` = :idle_timeout,
|
||||
`limit_extensions` = :limit_extensions
|
||||
");
|
||||
$ins_data = array(
|
||||
'desc' => $description,
|
||||
'reload_cmd' => $reload_cmd,
|
||||
'config_dir' => makeCorrectDir($config_dir),
|
||||
'pm' => $pmanager,
|
||||
'max_children' => $max_children,
|
||||
'start_servers' => $start_servers,
|
||||
'min_spare_servers' => $min_spare_servers,
|
||||
'max_spare_servers' => $max_spare_servers,
|
||||
'max_requests' => $max_requests,
|
||||
'idle_timeout' => $idle_timeout,
|
||||
'limit_extensions' => $limit_extensions
|
||||
);
|
||||
Database::pexecute($ins_stmt, $ins_data);
|
||||
$id = Database::lastInsertId();
|
||||
|
||||
inserttask('1');
|
||||
$this->logger()->logAction(ADM_ACTION, LOG_INFO, "[API] fpm-daemon with description '" . $description . "' has been created by '" . $this->getUserDetail('loginname') . "'");
|
||||
$result = $this->apiCall('FpmDaemons.get', array(
|
||||
'id' => $id
|
||||
));
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
throw new Exception("Not allowed to execute given command.", 403);
|
||||
}
|
||||
|
||||
/**
|
||||
* update a fpm-daemon entry by given id
|
||||
*
|
||||
* @param int $id
|
||||
* fpm-daemon id
|
||||
* @param string $description
|
||||
* optional
|
||||
* @param string $reload_cmd
|
||||
* optional
|
||||
* @param string $config_dir
|
||||
* optional
|
||||
* @param string $pm
|
||||
* optional, process-manager, one of 'static', 'dynamic' or 'ondemand', default 'static'
|
||||
* @param int $max_children
|
||||
* optional, default 0
|
||||
* @param int $start_servers
|
||||
* optional, default 0
|
||||
* @param int $min_spare_servers
|
||||
* optional, default 0
|
||||
* @param int $max_spare_servers
|
||||
* optional, default 0
|
||||
* @param int $max_requests
|
||||
* optional, default 0
|
||||
* @param int $idle_timeout
|
||||
* optional, default 0
|
||||
* @param string $limit_extensions
|
||||
* optional, limit execution to the following extensions, default '.php'
|
||||
*
|
||||
* @access admin
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function update()
|
||||
{
|
||||
if ($this->isAdmin() && $this->getUserDetail('change_serversettings') == 1) {
|
||||
|
||||
// required parameter
|
||||
$id = $this->getParam('id');
|
||||
|
||||
$result = $this->apiCall('FpmDaemons.get', array(
|
||||
'id' => $id
|
||||
));
|
||||
|
||||
// parameters
|
||||
$description = $this->getParam('description', true, $result['description']);
|
||||
$reload_cmd = $this->getParam('reload_cmd', true, $result['reload_cmd']);
|
||||
$config_dir = $this->getParam('config_dir', true, $result['config_dir']);
|
||||
$pmanager = $this->getParam('pm', true, $result['pm']);
|
||||
$max_children = $this->getParam('max_children', true, $result['max_children']);
|
||||
$start_servers = $this->getParam('start_servers', true, $result['start_servers']);
|
||||
$min_spare_servers = $this->getParam('min_spare_servers', true, $result['min_spare_servers']);
|
||||
$max_spare_servers = $this->getParam('max_spare_servers', true, $result['max_spare_servers']);
|
||||
$max_requests = $this->getParam('max_requests', true, $result['max_requests']);
|
||||
$idle_timeout = $this->getParam('idle_timeout', true, $result['idle_timeout']);
|
||||
$limit_extensions = $this->getParam('limit_extensions', true, $result['limit_extensions']);
|
||||
|
||||
// validation
|
||||
$description = validate($description, 'description', '', '', array(), true);
|
||||
$reload_cmd = validate($reload_cmd, 'reload_cmd', '', '', array(), true);
|
||||
$config_dir = validate($config_dir, 'config_dir', '', '', array(), true);
|
||||
if (! in_array($pmanager, array(
|
||||
'static',
|
||||
'dynamic',
|
||||
'ondemand'
|
||||
))) {
|
||||
throw new ErrorException("Unknown process manager", 406);
|
||||
}
|
||||
if (empty($limit_extensions)) {
|
||||
$limit_extensions = '.php';
|
||||
}
|
||||
$limit_extensions = validate($limit_extensions, 'limit_extensions', '/^(\.[a-z]([a-z0-9]+)\ ?)+$/', '', array(), true);
|
||||
|
||||
if (strlen($description) == 0 || strlen($description) > 50) {
|
||||
standard_error('descriptioninvalid', '', true);
|
||||
}
|
||||
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_FPMDAEMONS . "` SET
|
||||
`description` = :desc,
|
||||
`reload_cmd` = :reload_cmd,
|
||||
`config_dir` = :config_dir,
|
||||
`pm` = :pm,
|
||||
`max_children` = :max_children,
|
||||
`start_servers` = :start_servers,
|
||||
`min_spare_servers` = :min_spare_servers,
|
||||
`max_spare_servers` = :max_spare_servers,
|
||||
`max_requests` = :max_requests,
|
||||
`idle_timeout` = :idle_timeout,
|
||||
`limit_extensions` = :limit_extensions
|
||||
WHERE `id` = :id
|
||||
");
|
||||
$upd_data = array(
|
||||
'desc' => $description,
|
||||
'reload_cmd' => $reload_cmd,
|
||||
'config_dir' => makeCorrectDir($config_dir),
|
||||
'pm' => $pmanager,
|
||||
'max_children' => $max_children,
|
||||
'start_servers' => $start_servers,
|
||||
'min_spare_servers' => $min_spare_servers,
|
||||
'max_spare_servers' => $max_spare_servers,
|
||||
'max_requests' => $max_requests,
|
||||
'idle_timeout' => $idle_timeout,
|
||||
'limit_extensions' => $limit_extensions,
|
||||
'id' => $id
|
||||
);
|
||||
Database::pexecute($upd_stmt, $upd_data, true, true);
|
||||
|
||||
inserttask('1');
|
||||
$this->logger()->logAction(ADM_ACTION, LOG_INFO, "[API] fpm-daemon with description '" . $description . "' has been updated by '" . $this->getUserDetail('loginname') . "'");
|
||||
$result = $this->apiCall('FpmDaemons.get', array(
|
||||
'id' => $id
|
||||
));
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
throw new Exception("Not allowed to execute given command.", 403);
|
||||
}
|
||||
|
||||
/**
|
||||
* delete a fpm-daemon entry by id
|
||||
*
|
||||
* @param int $id
|
||||
* fpm-daemon-id
|
||||
*
|
||||
* @access admin
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
if ($this->isAdmin() && $this->getUserDetail('change_serversettings') == 1) {
|
||||
$id = $this->getParam('id');
|
||||
|
||||
if ($id == 1) {
|
||||
standard_error('cannotdeletedefaultphpconfig', '', true);
|
||||
}
|
||||
|
||||
$result = $this->apiCall('FpmDaemons.get', array(
|
||||
'id' => $id
|
||||
));
|
||||
|
||||
// set default fpm daemon config for all php-config that use this config that is to be deleted
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_PHPCONFIGS . "` SET
|
||||
`fpmsettingid` = '1' WHERE `fpmsettingid` = :id
|
||||
");
|
||||
Database::pexecute($upd_stmt, array(
|
||||
'id' => $id
|
||||
), true, true);
|
||||
|
||||
$del_stmt = Database::prepare("
|
||||
DELETE FROM `" . TABLE_PANEL_FPMDAEMONS . "` WHERE `id` = :id
|
||||
");
|
||||
Database::pexecute($del_stmt, array(
|
||||
'id' => $id
|
||||
), true, true);
|
||||
|
||||
inserttask('1');
|
||||
$this->logger()->logAction(ADM_ACTION, LOG_INFO, "[API] fpm-daemon setting '" . $result['description'] . "' has been deleted by '" . $this->getUserDetail('loginname') . "'");
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
throw new Exception("Not allowed to execute given command.", 403);
|
||||
}
|
||||
}
|
||||
@@ -1,428 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package API
|
||||
* @since 0.10.0
|
||||
*
|
||||
*/
|
||||
class Froxlor extends ApiCommand
|
||||
{
|
||||
|
||||
/**
|
||||
* checks whether there is a newer version of froxlor available
|
||||
*
|
||||
* @access admin
|
||||
* @throws Exception
|
||||
* @return string
|
||||
*/
|
||||
public function checkUpdate()
|
||||
{
|
||||
define('UPDATE_URI', "https://version.froxlor.org/Froxlor/api/" . $this->version);
|
||||
|
||||
if ($this->isAdmin() && $this->getUserDetail('change_serversettings')) {
|
||||
if (function_exists('curl_version')) {
|
||||
// log our actions
|
||||
$this->logger()->logAction(ADM_ACTION, LOG_NOTICE, "[API] checking for updates");
|
||||
|
||||
// check for new version
|
||||
$latestversion = HttpClient::urlGet(UPDATE_URI);
|
||||
$latestversion = explode('|', $latestversion);
|
||||
|
||||
if (is_array($latestversion) && count($latestversion) >= 1) {
|
||||
$_version = $latestversion[0];
|
||||
$_message = isset($latestversion[1]) ? $latestversion[1] : '';
|
||||
$_link = isset($latestversion[2]) ? $latestversion[2] : '';
|
||||
|
||||
// add the branding so debian guys are not gettings confused
|
||||
// about their version-number
|
||||
$version_label = $_version . $this->branding;
|
||||
$version_link = $_link;
|
||||
$message_addinfo = $_message;
|
||||
|
||||
// not numeric -> error-message
|
||||
if (! preg_match('/^((\d+\\.)(\d+\\.)(\d+\\.)?(\d+)?(\-(svn|dev|rc)(\d+))?)$/', $_version)) {
|
||||
// check for customized version to not output
|
||||
// "There is a newer version of froxlor" besides the error-message
|
||||
$isnewerversion = - 1;
|
||||
} elseif (version_compare2($this->version, $_version) == - 1) {
|
||||
// there is a newer version - yay
|
||||
$isnewerversion = 1;
|
||||
} else {
|
||||
// nothing new
|
||||
$isnewerversion = 0;
|
||||
}
|
||||
|
||||
// anzeige über version-status mit ggfls. formular
|
||||
// zum update schritt #1 -> download
|
||||
if ($isnewerversion == 1) {
|
||||
$text = 'There is a newer version available: "' . $_version . '" (Your current version is: ' . $this->version . ')';
|
||||
return $this->response(200, "successfull", array(
|
||||
'isnewerversion' => $isnewerversion,
|
||||
'version' => $_version,
|
||||
'message' => $text,
|
||||
'link' => $version_link,
|
||||
'additional_info' => $message_addinfo
|
||||
));
|
||||
} elseif ($isnewerversion == 0) {
|
||||
// all good
|
||||
return $this->response(200, "successfull", array(
|
||||
'isnewerversion' => $isnewerversion,
|
||||
'version' => $version_label,
|
||||
'message' => "",
|
||||
'link' => $version_link,
|
||||
'additional_info' => $message_addinfo
|
||||
));
|
||||
} else {
|
||||
standard_error('customized_version', '', true);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this->response(300, "successfull", array(
|
||||
'isnewerversion' => 0,
|
||||
'version' => $this->version.$this->branding,
|
||||
'message' => 'Version-check not available due to missing php-curl extension',
|
||||
'link' => UPDATE_URI.'/pretty',
|
||||
'additional_info' => ""
|
||||
));
|
||||
}
|
||||
throw new Exception("Not allowed to execute given command.", 403);
|
||||
}
|
||||
|
||||
/**
|
||||
* import settings
|
||||
*
|
||||
* @param string $json_str
|
||||
* content of exported froxlor-settings json file
|
||||
*
|
||||
* @access admin
|
||||
* @throws Exception
|
||||
* @return bool
|
||||
*/
|
||||
public function importSettings()
|
||||
{
|
||||
if ($this->isAdmin() && $this->getUserDetail('change_serversettings')) {
|
||||
$json_str = $this->getParam('json_str');
|
||||
$this->logger()->logAction(ADM_ACTION, LOG_NOTICE, "User " . $this->getUserDetail('loginname') . " imported settings");
|
||||
try {
|
||||
SImExporter::import($json_str);
|
||||
inserttask('1');
|
||||
inserttask('10');
|
||||
// Using nameserver, insert a task which rebuilds the server config
|
||||
inserttask('4');
|
||||
// cron.d file
|
||||
inserttask('99');
|
||||
return $this->response(200, "successfull", true);
|
||||
} catch (Exception $e) {
|
||||
throw new Exception($e->getMessage(), 406);
|
||||
}
|
||||
}
|
||||
throw new Exception("Not allowed to execute given command.", 403);
|
||||
}
|
||||
|
||||
/**
|
||||
* export settings
|
||||
*
|
||||
* @access admin
|
||||
* @throws Exception
|
||||
* @return string json-string
|
||||
*/
|
||||
public function exportSettings()
|
||||
{
|
||||
if ($this->isAdmin() && $this->getUserDetail('change_serversettings')) {
|
||||
$this->logger()->logAction(ADM_ACTION, LOG_NOTICE, "User " . $this->getUserDetail('loginname') . " exported settings");
|
||||
$json_export = SImExporter::export();
|
||||
return $this->response(200, "successfull", $json_export);
|
||||
}
|
||||
throw new Exception("Not allowed to execute given command.", 403);
|
||||
}
|
||||
|
||||
/**
|
||||
* return a list of all settings
|
||||
*
|
||||
* @access admin
|
||||
* @throws Exception
|
||||
* @return array count|list
|
||||
*/
|
||||
public function listSettings()
|
||||
{
|
||||
if ($this->isAdmin() && $this->getUserDetail('change_serversettings')) {
|
||||
$sel_stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_PANEL_SETTINGS . "` ORDER BY settinggroup ASC, varname ASC
|
||||
");
|
||||
Database::pexecute($sel_stmt, null, true, true);
|
||||
$result = array();
|
||||
while ($row = $sel_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$result[] = array(
|
||||
'key' => $row['settinggroup'] . '.' . $row['varname'],
|
||||
'value' => $row['value']
|
||||
);
|
||||
}
|
||||
return $this->response(200, "successfull", array(
|
||||
'count' => count($result),
|
||||
'list' => $result
|
||||
));
|
||||
}
|
||||
throw new Exception("Not allowed to execute given command.", 403);
|
||||
}
|
||||
|
||||
/**
|
||||
* return a setting by settinggroup.varname couple
|
||||
*
|
||||
* @param string $key
|
||||
* settinggroup.varname couple
|
||||
*
|
||||
* @access admin
|
||||
* @throws Exception
|
||||
* @return string
|
||||
*/
|
||||
public function getSetting()
|
||||
{
|
||||
if ($this->isAdmin() && $this->getUserDetail('change_serversettings')) {
|
||||
$setting = $this->getParam('key');
|
||||
return $this->response(200, "successfull", Settings::Get($setting));
|
||||
}
|
||||
throw new Exception("Not allowed to execute given command.", 403);
|
||||
}
|
||||
|
||||
/**
|
||||
* updates a setting
|
||||
*
|
||||
* @param string $key
|
||||
* settinggroup.varname couple
|
||||
* @param string $value
|
||||
* optional the new value, default is ''
|
||||
*
|
||||
* @access admin
|
||||
* @throws Exception
|
||||
* @return string
|
||||
*/
|
||||
public function updateSetting()
|
||||
{
|
||||
// currently not implemented as it required validation too so no wrong settings are being stored via API
|
||||
throw new Exception("Not available yet.", 501);
|
||||
|
||||
if ($this->isAdmin() && $this->getUserDetail('change_serversettings')) {
|
||||
$setting = $this->getParam('key');
|
||||
$value = $this->getParam('value', true, '');
|
||||
$oldvalue = Settings::Get($setting);
|
||||
if (is_null($oldvalue)) {
|
||||
throw new Exception("Setting '" . $setting . "' could not be found");
|
||||
}
|
||||
$this->logger()->logAction(ADM_ACTION, LOG_WARNING, "[API] Changing setting '" . $setting . "' from '" . $oldvalue . "' to '" . $value . "'");
|
||||
return $this->response(200, "successfull", Settings::Set($setting, $value, true));
|
||||
}
|
||||
throw new Exception("Not allowed to execute given command.", 403);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a list of all available api functions
|
||||
*
|
||||
* @param string $module
|
||||
* optional, return list of functions for a specific module
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function listFunctions()
|
||||
{
|
||||
$module = $this->getParam('module', true, '');
|
||||
|
||||
$functions = array();
|
||||
if ($module != null) {
|
||||
// check existence
|
||||
$this->requireModules($module);
|
||||
// now get all static functions
|
||||
$reflection = new \ReflectionClass($module);
|
||||
$_functions = $reflection->getMethods(\ReflectionMethod::IS_PUBLIC);
|
||||
foreach ($_functions as $func) {
|
||||
if ($func->class == $module && $func->isPublic()) {
|
||||
array_push($functions, array_merge(array(
|
||||
'module' => $module,
|
||||
'function' => $func->name
|
||||
), $this->getParamListFromDoc($module, $func->name)));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// check all the modules
|
||||
$path = FROXLOR_INSTALL_DIR . '/lib/classes/api/commands/';
|
||||
// valid directory?
|
||||
if (is_dir($path)) {
|
||||
// create RecursiveIteratorIterator
|
||||
$its = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path));
|
||||
// check every file
|
||||
foreach ($its as $it) {
|
||||
// does it match the Filename pattern?
|
||||
$matches = array();
|
||||
if (preg_match("/^class\.(.+)\.php$/i", $it->getFilename(), $matches)) {
|
||||
// check for existence
|
||||
try {
|
||||
// set the module to be in our namespace
|
||||
$mod = $matches[1];
|
||||
$this->requireModules($mod);
|
||||
} catch (Exception $e) {
|
||||
// @todo log?
|
||||
continue;
|
||||
}
|
||||
// now get all static functions
|
||||
$reflection = new \ReflectionClass($mod);
|
||||
$_functions = $reflection->getMethods(\ReflectionMethod::IS_PUBLIC);
|
||||
foreach ($_functions as $func) {
|
||||
if ($func->class == $mod && $func->isPublic() && ! $func->isStatic()) {
|
||||
array_push($functions, array_merge(array(
|
||||
'module' => $matches[1],
|
||||
'function' => $func->name
|
||||
), $this->getParamListFromDoc($matches[1], $func->name)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// yikes - no valid directory to check
|
||||
throw new Exception("Cannot search directory '" . $path . "'. No such directory.", 500);
|
||||
}
|
||||
}
|
||||
|
||||
// return the list
|
||||
return $this->response(200, "successfull", $functions);
|
||||
}
|
||||
|
||||
/**
|
||||
* generate an api-response to list all parameters and the return-value of
|
||||
* a given module.function-combination
|
||||
*
|
||||
* @param string $module
|
||||
* @param string $function
|
||||
*
|
||||
* @throws Exception
|
||||
* @return array|bool
|
||||
*/
|
||||
private function getParamListFromDoc($module = null, $function = null)
|
||||
{
|
||||
try {
|
||||
// set the module
|
||||
$cls = new \ReflectionMethod($module, $function);
|
||||
$comment = $cls->getDocComment();
|
||||
if ($comment == false) {
|
||||
return array(
|
||||
'head' => 'There is no comment-block for "' . $module . '.' . $function . '"'
|
||||
);
|
||||
}
|
||||
|
||||
$clines = explode("\n", $comment);
|
||||
$result = array();
|
||||
$result['params'] = array();
|
||||
$param_desc = false;
|
||||
$r = array();
|
||||
foreach ($clines as $c) {
|
||||
$c = trim($c);
|
||||
// check param-section
|
||||
if (strpos($c, '@param')) {
|
||||
preg_match('/^\*\s\@param\s(.+)\s(\$\w+)(\s.*)?/', $c, $r);
|
||||
// cut $ off the parameter-name as it is not wanted in the api-request
|
||||
$result['params'][] = array(
|
||||
'parameter' => substr($r[2], 1),
|
||||
'type' => $r[1],
|
||||
'desc' => (isset($r[3]) ? trim($r['3']) : '')
|
||||
);
|
||||
$param_desc = true;
|
||||
} // check access-section
|
||||
elseif (strpos($c, '@access')) {
|
||||
preg_match('/^\*\s\@access\s(.*)/', $c, $r);
|
||||
if (! isset($r[0]) || empty($r[0])) {
|
||||
$r[1] = 'This function has no restrictions';
|
||||
}
|
||||
$result['access'] = array(
|
||||
'groups' => (isset($r[1]) ? trim($r[1]) : '')
|
||||
);
|
||||
} // check return-section
|
||||
elseif (strpos($c, '@return')) {
|
||||
preg_match('/^\*\s\@return\s(\w+)(\s.*)?/', $c, $r);
|
||||
if (! isset($r[0]) || empty($r[0])) {
|
||||
$r[1] = 'null';
|
||||
$r[2] = 'This function has no return value given';
|
||||
}
|
||||
$result['return'] = array(
|
||||
'type' => $r[1],
|
||||
'desc' => (isset($r[2]) ? trim($r[2]) : '')
|
||||
);
|
||||
} // check throws-section
|
||||
elseif (! empty($c) && strpos($c, '@throws') === false) {
|
||||
if (substr($c, 0, 3) == "/**") {
|
||||
continue;
|
||||
}
|
||||
if (substr($c, 0, 2) == "*/") {
|
||||
continue;
|
||||
}
|
||||
if (substr($c, 0, 1) == "*") {
|
||||
$c = trim(substr($c, 1));
|
||||
if (empty($c)) {
|
||||
continue;
|
||||
}
|
||||
if ($param_desc) {
|
||||
$result['params'][count($result['params']) - 1]['desc'] .= $c;
|
||||
} else {
|
||||
if (! isset($result['head']) || empty($result['head'])) {
|
||||
$result['head'] = $c . " ";
|
||||
} else {
|
||||
$result['head'] .= $c . " ";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$result['head'] = trim($result['head']);
|
||||
return $result;
|
||||
} catch (\ReflectionException $e) {
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* this functions is used to check the availability
|
||||
* of a given list of modules.
|
||||
* If either one of
|
||||
* them are not found, throw an Exception
|
||||
*
|
||||
* @param string|array $modules
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
private function requireModules($modules = null)
|
||||
{
|
||||
if ($modules != null) {
|
||||
// no array -> create one
|
||||
if (! is_array($modules)) {
|
||||
$modules = array(
|
||||
$modules
|
||||
);
|
||||
}
|
||||
// check all the modules
|
||||
foreach ($modules as $module) {
|
||||
try {
|
||||
// can we use the class?
|
||||
if (class_exists($module)) {
|
||||
continue;
|
||||
} else {
|
||||
throw new Exception('The required class "' . $module . '" could not be found but the module-file exists', 404);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
// The autoloader will throw an Exception
|
||||
// that the required class could not be found
|
||||
// but we want a nicer error-message for this here
|
||||
throw new Exception('The required module "' . $module . '" could not be found', 404);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,550 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package API
|
||||
* @since 0.10.0
|
||||
*
|
||||
*/
|
||||
class Ftps extends ApiCommand implements ResourceEntity
|
||||
{
|
||||
|
||||
/**
|
||||
* add a new ftp-user
|
||||
*
|
||||
* @param string $ftp_password
|
||||
* password for the created database and database-user
|
||||
* @param string $path
|
||||
* destination path relative to the customers-homedir
|
||||
* @param string $ftp_description
|
||||
* optional, description for ftp-user
|
||||
* @param bool $sendinfomail
|
||||
* optional, send created resource-information to customer, default: false
|
||||
* @param string $shell
|
||||
* optional, default /bin/false (not changeable when deactivated)
|
||||
* @param string $ftp_username
|
||||
* optional if customer.ftpatdomain is allowed, specify an username
|
||||
* @param string $ftp_domain
|
||||
* optional if customer.ftpatdomain is allowed, specify a domain (customer must be owner)
|
||||
* @param int $customerid
|
||||
* required when called as admin, not needed when called as customer
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'ftp')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
|
||||
if ($this->getUserDetail('ftps_used') < $this->getUserDetail('ftps') || $this->getUserDetail('ftps') == '-1') {
|
||||
|
||||
// required paramters
|
||||
$path = $this->getParam('path');
|
||||
$password = $this->getParam('ftp_password');
|
||||
|
||||
// parameters
|
||||
$description = $this->getParam('ftp_description', true, '');
|
||||
$sendinfomail = $this->getBoolParam('sendinfomail', true, 0);
|
||||
$shell = $this->getParam('shell', true, '/bin/false');
|
||||
|
||||
$ftpusername = $this->getParam('ftp_username', true, '');
|
||||
$ftpdomain = $this->getParam('ftp_domain', true, '');
|
||||
|
||||
// validation
|
||||
$password = validate($password, 'password', '', '', array(), true);
|
||||
$password = validatePassword($password, true);
|
||||
$description = validate(trim($description), 'description', '', '', array(), true);
|
||||
|
||||
if (Settings::Get('system.allow_customer_shell') == '1') {
|
||||
$shell = validate(trim($shell), 'shell', '', '', array(), true);
|
||||
} else {
|
||||
$shell = "/bin/false";
|
||||
}
|
||||
|
||||
if (Settings::Get('customer.ftpatdomain') == '1') {
|
||||
$ftpusername = validate(trim($ftpusername), 'username', '/^[a-zA-Z0-9][a-zA-Z0-9\-_]+\$?$/', '', array(), true);
|
||||
if (substr($ftpdomain, 0, 4) != 'xn--') {
|
||||
$idna_convert = new idna_convert_wrapper();
|
||||
$ftpdomain = $idna_convert->encode(validate($ftpdomain, 'domain', '', '', array(), true));
|
||||
}
|
||||
}
|
||||
|
||||
$params = array();
|
||||
// get needed customer info to reduce the ftp-user-counter by one
|
||||
$customer = $this->getCustomerData('ftps');
|
||||
|
||||
if ($sendinfomail != 1) {
|
||||
$sendinfomail = 0;
|
||||
}
|
||||
|
||||
if (Settings::Get('customer.ftpatdomain') == '1') {
|
||||
if ($ftpusername == '') {
|
||||
standard_error(array(
|
||||
'stringisempty',
|
||||
'username'
|
||||
), '', true);
|
||||
}
|
||||
$ftpdomain_check_stmt = Database::prepare("SELECT `id`, `domain`, `customerid` FROM `" . TABLE_PANEL_DOMAINS . "`
|
||||
WHERE `domain` = :domain
|
||||
AND `customerid` = :customerid");
|
||||
$ftpdomain_check = Database::pexecute_first($ftpdomain_check_stmt, array(
|
||||
"domain" => $ftpdomain,
|
||||
"customerid" => $customer['customerid']
|
||||
), true, true);
|
||||
|
||||
if ($ftpdomain_check && $ftpdomain_check['domain'] != $ftpdomain) {
|
||||
standard_error('maindomainnonexist', $ftpdomain, true);
|
||||
}
|
||||
$username = $ftpusername . "@" . $ftpdomain;
|
||||
} else {
|
||||
$username = $customer['loginname'] . Settings::Get('customer.ftpprefix') . (intval($customer['ftp_lastaccountnumber']) + 1);
|
||||
}
|
||||
|
||||
$username_check_stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_FTP_USERS . "` WHERE `username` = :username
|
||||
");
|
||||
$username_check = Database::pexecute_first($username_check_stmt, array(
|
||||
"username" => $username
|
||||
), true, true);
|
||||
|
||||
if (! empty($username_check) && $username_check['username'] = $username) {
|
||||
standard_error('usernamealreadyexists', $username, true);
|
||||
} elseif ($username == $password) {
|
||||
standard_error('passwordshouldnotbeusername', '', true);
|
||||
} else {
|
||||
$path = makeCorrectDir($customer['documentroot'] . '/' . $path);
|
||||
$cryptPassword = makeCryptPassword($password);
|
||||
|
||||
$stmt = Database::prepare("INSERT INTO `" . TABLE_FTP_USERS . "`
|
||||
(`customerid`, `username`, `description`, `password`, `homedir`, `login_enabled`, `uid`, `gid`, `shell`)
|
||||
VALUES (:customerid, :username, :description, :password, :homedir, 'y', :guid, :guid, :shell)");
|
||||
$params = array(
|
||||
"customerid" => $customer['customerid'],
|
||||
"username" => $username,
|
||||
"description" => $description,
|
||||
"password" => $cryptPassword,
|
||||
"homedir" => $path,
|
||||
"guid" => $customer['guid'],
|
||||
"shell" => $shell
|
||||
);
|
||||
Database::pexecute($stmt, $params, true, true);
|
||||
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT `bytes_in_used` FROM `" . TABLE_FTP_QUOTATALLIES . "` WHERE `name` = :name
|
||||
");
|
||||
Database::pexecute($result_stmt, array(
|
||||
"name" => $customer['loginname']
|
||||
), true, true);
|
||||
|
||||
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$stmt = Database::prepare("INSERT INTO `" . TABLE_FTP_QUOTATALLIES . "`
|
||||
(`name`, `quota_type`, `bytes_in_used`, `bytes_out_used`, `bytes_xfer_used`, `files_in_used`, `files_out_used`, `files_xfer_used`)
|
||||
VALUES (:name, 'user', :bytes_in_used, '0', '0', '0', '0', '0')
|
||||
");
|
||||
Database::pexecute($stmt, array(
|
||||
"name" => $username,
|
||||
"bytes_in_used" => $row['bytes_in_used']
|
||||
), true, true);
|
||||
}
|
||||
|
||||
$stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_FTP_GROUPS . "`
|
||||
SET `members` = CONCAT_WS(',',`members`, :username)
|
||||
WHERE `customerid`= :customerid AND `gid`= :guid
|
||||
");
|
||||
$params = array(
|
||||
"username" => $username,
|
||||
"customerid" => $customer['customerid'],
|
||||
"guid" => $customer['guid']
|
||||
);
|
||||
Database::pexecute($stmt, $params, true, true);
|
||||
|
||||
// update customer usage
|
||||
Customers::increaseUsage($customer['customerid'], 'ftps_used');
|
||||
Customers::increaseUsage($customer['customerid'], 'ftp_lastaccountnumber');
|
||||
|
||||
// update admin usage
|
||||
Admins::increaseUsage($customer['adminid'], 'ftps_used');
|
||||
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_INFO, "[API] added ftp-account '" . $username . " (" . $path . ")'");
|
||||
inserttask(5);
|
||||
|
||||
if ($sendinfomail == 1) {
|
||||
$replace_arr = array(
|
||||
'SALUTATION' => getCorrectUserSalutation($customer),
|
||||
'CUST_NAME' => getCorrectUserSalutation($customer), // < keep this for compatibility
|
||||
'USR_NAME' => $username,
|
||||
'USR_PASS' => $password,
|
||||
'USR_PATH' => makeCorrectDir(str_replace($customer['documentroot'], "/", $path))
|
||||
);
|
||||
// get template for mail subject
|
||||
$mail_subject = $this->getMailTemplate($customer, 'mails', 'new_ftpaccount_by_customer_subject', $replace_arr, $this->lng['mails']['new_ftpaccount_by_customer']['subject']);
|
||||
// get template for mail body
|
||||
$mail_body = $this->getMailTemplate($customer, 'mails', 'new_ftpaccount_by_customer_mailbody', $replace_arr, $this->lng['mails']['new_ftpaccount_by_customer']['mailbody']);
|
||||
|
||||
$_mailerror = false;
|
||||
$mailerr_msg = "";
|
||||
try {
|
||||
$this->mailer()->Subject = $mail_subject;
|
||||
$this->mailer()->AltBody = $mail_body;
|
||||
$this->mailer()->msgHTML(str_replace("\n", "<br />", $mail_body));
|
||||
$this->mailer()->addAddress($customer['email'], getCorrectUserSalutation($customer));
|
||||
$this->mailer()->send();
|
||||
} catch (phpmailerException $e) {
|
||||
$mailerr_msg = $e->errorMessage();
|
||||
$_mailerror = true;
|
||||
} catch (Exception $e) {
|
||||
$mailerr_msg = $e->getMessage();
|
||||
$_mailerror = true;
|
||||
}
|
||||
|
||||
if ($_mailerror) {
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_ERR, "[API] Error sending mail: " . $mailerr_msg);
|
||||
standard_error('errorsendingmail', $customer['email'], true);
|
||||
}
|
||||
|
||||
$this->mailer()->clearAddresses();
|
||||
}
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_WARNING, "[API] added ftp-user '" . $username . "'");
|
||||
|
||||
$result = $this->apiCall('Ftps.get', array(
|
||||
'username' => $username
|
||||
));
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
}
|
||||
throw new Exception("No more resources available", 406);
|
||||
}
|
||||
|
||||
/**
|
||||
* return a ftp-user entry by either id or username
|
||||
*
|
||||
* @param int $id
|
||||
* optional, the customer-id
|
||||
* @param string $username
|
||||
* optional, the username
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
$id = $this->getParam('id', true, 0);
|
||||
$un_optional = ($id <= 0 ? false : true);
|
||||
$username = $this->getParam('username', $un_optional, '');
|
||||
|
||||
$params = array();
|
||||
if ($this->isAdmin()) {
|
||||
if ($this->getUserDetail('customers_see_all') == false) {
|
||||
// if it's a reseller or an admin who cannot see all customers, we need to check
|
||||
// whether the database belongs to one of his customers
|
||||
$_custom_list_result = $this->apiCall('Customers.listing');
|
||||
$custom_list_result = $_custom_list_result['list'];
|
||||
$customer_ids = array();
|
||||
foreach ($custom_list_result as $customer) {
|
||||
$customer_ids[] = $customer['customerid'];
|
||||
}
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_FTP_USERS . "`
|
||||
WHERE `customerid` IN (".implode(", ", $customer_ids).")
|
||||
AND (`id` = :idun OR `username` = :idun)
|
||||
");
|
||||
} else {
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_FTP_USERS . "`
|
||||
WHERE (`id` = :idun OR `username` = :idun)
|
||||
");
|
||||
}
|
||||
} else {
|
||||
if (Settings::IsInList('panel.customer_hide_options', 'ftp')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_FTP_USERS . "`
|
||||
WHERE `customerid` = :customerid
|
||||
AND (`id` = :idun OR `username` = :idun)
|
||||
");
|
||||
$params['customerid'] = $this->getUserDetail('customerid');
|
||||
}
|
||||
$params['idun'] = ($id <= 0 ? $username : $id);
|
||||
$result = Database::pexecute_first($result_stmt, $params, true, true);
|
||||
if ($result) {
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_NOTICE, "[API] get ftp-user '" . $result['username'] . "'");
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
$key = ($id > 0 ? "id #" . $id : "username '" . $username . "'");
|
||||
throw new Exception("FTP user with " . $key . " could not be found", 404);
|
||||
}
|
||||
|
||||
/**
|
||||
* update a given ftp-user by id or username
|
||||
*
|
||||
* @param int $id
|
||||
* optional, the customer-id
|
||||
* @param string $username
|
||||
* optional, the username
|
||||
* @param string $ftp_password
|
||||
* password for the created database and database-user
|
||||
* @param string $path
|
||||
* destination path relative to the customers-homedir
|
||||
* @param string $ftp_description
|
||||
* optional, description for ftp-user
|
||||
* @param string $shell
|
||||
* optional, default /bin/false (not changeable when deactivated)
|
||||
* @param int $customerid
|
||||
* required when called as admin, not needed when called as customer
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function update()
|
||||
{
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'ftp')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
|
||||
$id = $this->getParam('id', true, 0);
|
||||
$un_optional = ($id <= 0 ? false : true);
|
||||
$username = $this->getParam('username', $un_optional, '');
|
||||
|
||||
$result = $this->apiCall('Ftps.get', array(
|
||||
'id' => $id,
|
||||
'username' => $username
|
||||
));
|
||||
$id = $result['id'];
|
||||
|
||||
// parameters
|
||||
$path = $this->getParam('path', true, '');
|
||||
$password = $this->getParam('ftp_password', true, '');
|
||||
$description = $this->getParam('ftp_description', true, $result['description']);
|
||||
$shell = $this->getParam('shell', true, $result['shell']);
|
||||
|
||||
// validation
|
||||
$password = validate($password, 'password', '', '', array(), true);
|
||||
$description = validate(trim($description), 'description', '', '', array(), true);
|
||||
|
||||
if (Settings::Get('system.allow_customer_shell') == '1') {
|
||||
$shell = validate(trim($shell), 'shell', '', '', array(), true);
|
||||
} else {
|
||||
$shell = "/bin/false";
|
||||
}
|
||||
|
||||
// get needed customer info to reduce the ftp-user-counter by one
|
||||
$customer = $this->getCustomerData();
|
||||
|
||||
// password update?
|
||||
if ($password != '') {
|
||||
// validate password
|
||||
$password = validatePassword($password, true);
|
||||
|
||||
if ($password == $result['username']) {
|
||||
standard_error('passwordshouldnotbeusername', '', true);
|
||||
}
|
||||
$cryptPassword = makeCryptPassword($password);
|
||||
|
||||
$stmt = Database::prepare("UPDATE `" . TABLE_FTP_USERS . "`
|
||||
SET `password` = :password
|
||||
WHERE `customerid` = :customerid
|
||||
AND `id` = :id
|
||||
");
|
||||
Database::pexecute($stmt, array(
|
||||
"customerid" => $customer['customerid'],
|
||||
"id" => $id,
|
||||
"password" => $cryptPassword
|
||||
), true, true);
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_INFO, "[API] updated ftp-account password for '" . $result['username'] . "'");
|
||||
}
|
||||
|
||||
// path update?
|
||||
if ($path != '') {
|
||||
$path = makeCorrectDir($customer['documentroot'] . '/' . $path);
|
||||
|
||||
if ($path != $result['homedir']) {
|
||||
$stmt = Database::prepare("UPDATE `" . TABLE_FTP_USERS . "`
|
||||
SET `homedir` = :homedir
|
||||
WHERE `customerid` = :customerid
|
||||
AND `id` = :id
|
||||
");
|
||||
Database::pexecute($stmt, array(
|
||||
"homedir" => $path,
|
||||
"customerid" => $customer['customerid'],
|
||||
"id" => $id
|
||||
), true, true);
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_INFO, "[API] updated ftp-account homdir for '" . $result['username'] . "'");
|
||||
}
|
||||
}
|
||||
// it's the task for "new ftp" but that will
|
||||
// create all directories and correct their permissions
|
||||
inserttask(5);
|
||||
|
||||
$stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_FTP_USERS . "`
|
||||
SET `description` = :desc, `shell` = :shell
|
||||
WHERE `customerid` = :customerid
|
||||
AND `id` = :id
|
||||
");
|
||||
Database::pexecute($stmt, array(
|
||||
"desc" => $description,
|
||||
"shell" => $shell,
|
||||
"customerid" => $customer['customerid'],
|
||||
"id" => $id
|
||||
), true, true);
|
||||
|
||||
$result = $this->apiCall('Ftps.get', array(
|
||||
'username' => $result['username']
|
||||
));
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_NOTICE, "[API] updated ftp-user '" . $result['username'] . "'");
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* list all ftp-users, if called from an admin, list all ftp-users of all customers you are allowed to view, or specify id or loginname for one specific customer
|
||||
*
|
||||
* @param int $customerid
|
||||
* optional, admin-only, select ftp-users of a specific customer by id
|
||||
* @param string $loginname
|
||||
* optional, admin-only, select ftp-users of a specific customer by loginname
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array count|list
|
||||
*/
|
||||
public function listing()
|
||||
{
|
||||
$customer_ids = $this->getAllowedCustomerIds('ftp');
|
||||
$result = array();
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_FTP_USERS . "`
|
||||
WHERE `customerid` IN (".implode(", ", $customer_ids).")
|
||||
");
|
||||
Database::pexecute($result_stmt, null, true, true);
|
||||
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$result[] = $row;
|
||||
}
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_NOTICE, "[API] list ftp-users");
|
||||
return $this->response(200, "successfull", array(
|
||||
'count' => count($result),
|
||||
'list' => $result
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* delete a ftp-user by either id or username
|
||||
*
|
||||
* @param int $id
|
||||
* optional, the ftp-user-id
|
||||
* @param string $username
|
||||
* optional, the username
|
||||
* @param bool $delete_userfiles
|
||||
* optional, default false
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
$id = $this->getParam('id', true, 0);
|
||||
$un_optional = ($id <= 0 ? false : true);
|
||||
$username = $this->getParam('username', $un_optional, '');
|
||||
$delete_userfiles = $this->getBoolParam('delete_userfiles', true, 0);
|
||||
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'ftp')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
|
||||
// get ftp-user
|
||||
$result = $this->apiCall('Ftps.get', array(
|
||||
'id' => $id,
|
||||
'username' => $username
|
||||
));
|
||||
$id = $result['id'];
|
||||
|
||||
if ($this->isAdmin()) {
|
||||
// get customer-data
|
||||
$customer_data = $this->apiCall('Customers.get', array(
|
||||
'id' => $result['customerid']
|
||||
));
|
||||
} else {
|
||||
$customer_data = $this->getUserData();
|
||||
}
|
||||
|
||||
// add usage of this ftp-user to main-ftp user of customer if different
|
||||
if ($result['username'] != $customer_data['loginname']) {
|
||||
$stmt = Database::prepare("UPDATE `" . TABLE_FTP_USERS . "`
|
||||
SET `up_count` = `up_count` + :up_count,
|
||||
`up_bytes` = `up_bytes` + :up_bytes,
|
||||
`down_count` = `down_count` + :down_count,
|
||||
`down_bytes` = `down_bytes` + :down_bytes
|
||||
WHERE `username` = :username
|
||||
");
|
||||
$params = array(
|
||||
"up_count" => $result['up_count'],
|
||||
"up_bytes" => $result['up_bytes'],
|
||||
"down_count" => $result['down_count'],
|
||||
"down_bytes" => $result['down_bytes'],
|
||||
"username" => $customer_data['loginname']
|
||||
);
|
||||
Database::pexecute($stmt, $params, true, true);
|
||||
}
|
||||
|
||||
// remove all quotatallies
|
||||
$stmt = Database::prepare("DELETE FROM `" . TABLE_FTP_QUOTATALLIES . "` WHERE `name` = :name");
|
||||
Database::pexecute($stmt, array(
|
||||
"name" => $result['username']
|
||||
), true, true);
|
||||
|
||||
// remove user itself
|
||||
$stmt = Database::prepare("
|
||||
DELETE FROM `" . TABLE_FTP_USERS . "` WHERE `customerid` = :customerid AND `id` = :id
|
||||
");
|
||||
Database::pexecute($stmt, array(
|
||||
"customerid" => $customer_data['customerid'],
|
||||
"id" => $id
|
||||
), true, true);
|
||||
|
||||
// update ftp-groups
|
||||
$stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_FTP_GROUPS . "` SET
|
||||
`members` = REPLACE(`members`, :username,'')
|
||||
WHERE `customerid` = :customerid
|
||||
");
|
||||
Database::pexecute($stmt, array(
|
||||
"username" => "," . $result['username'],
|
||||
"customerid" => $customer_data['customerid']
|
||||
), true, true);
|
||||
|
||||
// refs #293
|
||||
if ($delete_userfiles == 1) {
|
||||
inserttask('8', $customer_data['loginname'], $result['homedir']);
|
||||
} else {
|
||||
if (Settings::Get('system.nssextrausers') == 1) {
|
||||
// this is used so that the libnss-extrausers cron is fired
|
||||
inserttask(5);
|
||||
}
|
||||
}
|
||||
|
||||
// decrease ftp-user usage for customer
|
||||
$resetaccnumber = ($customer_data['ftps_used'] == '1') ? " , `ftp_lastaccountnumber`='0'" : '';
|
||||
Customers::decreaseUsage($customer_data['customerid'], 'ftps_used', $resetaccnumber);
|
||||
// update admin usage
|
||||
Admins::decreaseUsage(($this->isAdmin() ? $customer_data['adminid'] : $this->getUserDetail('adminid')), 'ftps_used');
|
||||
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_WARNING, "[API] deleted ftp-user '" . $result['username'] . "'");
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package API
|
||||
* @since 0.10.0
|
||||
*
|
||||
*/
|
||||
class HostingPlans extends ApiCommand implements ResourceEntity
|
||||
{
|
||||
public function add()
|
||||
{}
|
||||
|
||||
public function get()
|
||||
{}
|
||||
|
||||
public function update()
|
||||
{}
|
||||
|
||||
public function listing()
|
||||
{}
|
||||
|
||||
public function delete()
|
||||
{}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,516 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package API
|
||||
* @since 0.10.0
|
||||
*
|
||||
*/
|
||||
class IpsAndPorts extends ApiCommand implements ResourceEntity
|
||||
{
|
||||
|
||||
/**
|
||||
* lists all ip/port entries
|
||||
*
|
||||
* @access admin
|
||||
* @throws Exception
|
||||
* @return array count|list
|
||||
*/
|
||||
public function listing()
|
||||
{
|
||||
if ($this->isAdmin() && ($this->getUserDetail('change_serversettings') || ! empty($this->getUserDetail('ip')))) {
|
||||
$this->logger()->logAction(ADM_ACTION, LOG_NOTICE, "[API] list ips and ports");
|
||||
$ip_where = "";
|
||||
if (! empty($this->getUserDetail('ip')) && $this->getUserDetail('ip') != - 1) {
|
||||
$ip_where = "WHERE `id` IN (" . implode(", ", json_decode($this->getUserDetail('ip'), true)) . ")";
|
||||
}
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_PANEL_IPSANDPORTS . "` " . $ip_where . " ORDER BY `ip` ASC, `port` ASC
|
||||
");
|
||||
Database::pexecute($result_stmt, null, true, true);
|
||||
$result = array();
|
||||
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$result[] = $row;
|
||||
}
|
||||
return $this->response(200, "successfull", array(
|
||||
'count' => count($result),
|
||||
'list' => $result
|
||||
));
|
||||
}
|
||||
throw new Exception("Not allowed to execute given command.", 403);
|
||||
}
|
||||
|
||||
/**
|
||||
* return an ip/port entry by id
|
||||
*
|
||||
* @param int $id
|
||||
* ip-port-id
|
||||
*
|
||||
* @access admin
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
if ($this->isAdmin() && ($this->getUserDetail('change_serversettings') || ! empty($this->getUserDetail('ip')))) {
|
||||
$id = $this->getParam('id');
|
||||
if (! empty($this->getUserDetail('ip')) && $this->getUserDetail('ip') != - 1) {
|
||||
$allowed_ips = json_decode($this->getUserDetail('ip'), true);
|
||||
if (! in_array($id, $allowed_ips)) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
}
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_PANEL_IPSANDPORTS . "` WHERE `id` = :id
|
||||
");
|
||||
$result = Database::pexecute_first($result_stmt, array(
|
||||
'id' => $id
|
||||
), true, true);
|
||||
if ($result) {
|
||||
$this->logger()->logAction(ADM_ACTION, LOG_NOTICE, "[API] get ip " . $result['ip'] . " " . $result['port']);
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
throw new Exception("IP/port with id #" . $id . " could not be found", 404);
|
||||
}
|
||||
throw new Exception("Not allowed to execute given command.", 403);
|
||||
}
|
||||
|
||||
/**
|
||||
* create a new ip/port entry
|
||||
*
|
||||
* @param string $ip
|
||||
* @param int $port
|
||||
* optional, default 80
|
||||
* @param bool $listen_statement
|
||||
* optional, default 0 (false)
|
||||
* @param bool $namevirtualhost_statement
|
||||
* optional, default 0 (false)
|
||||
* @param bool $vhostcontainer
|
||||
* optional, default 0 (false)
|
||||
* @param string $specialsettings
|
||||
* optional, default empty
|
||||
* @param bool $vhostcontainer_servername_statement
|
||||
* optional, default 0 (false)
|
||||
* @param string $default_vhostconf_domain
|
||||
* optional, defatul empty
|
||||
* @param string $docroot
|
||||
* optional, default empty (point to froxlor)
|
||||
* @param bool $ssl
|
||||
* optional, default 0 (false)
|
||||
* @param string $ssl_cert_file
|
||||
* optional, requires $ssl = 1, default empty
|
||||
* @param string $ssl_key_file
|
||||
* optional, requires $ssl = 1, default empty
|
||||
* @param string $ssl_ca_file
|
||||
* optional, requires $ssl = 1, default empty
|
||||
* @param string $ssl_cert_chainfile
|
||||
* optional, requires $ssl = 1, default empty
|
||||
*
|
||||
* @access admin
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
if ($this->isAdmin() && $this->getUserDetail('change_serversettings')) {
|
||||
|
||||
$ip = validate_ip2($this->getParam('ip'), false, 'invalidip', false, false, false, true);
|
||||
$port = validate($this->getParam('port', true, 80), 'port', '/^(([1-9])|([1-9][0-9])|([1-9][0-9][0-9])|([1-9][0-9][0-9][0-9])|([1-5][0-9][0-9][0-9][0-9])|(6[0-4][0-9][0-9][0-9])|(65[0-4][0-9][0-9])|(655[0-2][0-9])|(6553[0-5]))$/Di', array(
|
||||
'stringisempty',
|
||||
'myport'
|
||||
), array(), true);
|
||||
$listen_statement = ! empty($this->getBoolParam('listen_statement', true, 0)) ? 1 : 0;
|
||||
$namevirtualhost_statement = ! empty($this->getBoolParam('namevirtualhost_statement', true, 0)) ? 1 : 0;
|
||||
$vhostcontainer = ! empty($this->getBoolParam('vhostcontainer', true, 0)) ? 1 : 0;
|
||||
$specialsettings = validate(str_replace("\r\n", "\n", $this->getParam('specialsettings', true, '')), 'specialsettings', '/^[^\0]*$/', '', array(), true);
|
||||
$vhostcontainer_servername_statement = ! empty($this->getBoolParam('vhostcontainer_servername_statement', true, 1)) ? 1 : 0;
|
||||
$default_vhostconf_domain = validate(str_replace("\r\n", "\n", $this->getParam('default_vhostconf_domain', true, '')), 'default_vhostconf_domain', '/^[^\0]*$/', '', array(), true);
|
||||
$docroot = validate($this->getParam('docroot', true, ''), 'docroot', '', '', array(), true);
|
||||
|
||||
if ((int) Settings::Get('system.use_ssl') == 1) {
|
||||
$ssl = ! empty($this->getBoolParam('ssl', true, 0)) ? intval($this->getBoolParam('ssl', true, 0)) : 0;
|
||||
$ssl_cert_file = validate($this->getParam('ssl_cert_file', $ssl, ''), 'ssl_cert_file', '', '', array(), true);
|
||||
$ssl_key_file = validate($this->getParam('ssl_key_file', $ssl, ''), 'ssl_key_file', '', '', array(), true);
|
||||
$ssl_ca_file = validate($this->getParam('ssl_ca_file', true, ''), 'ssl_ca_file', '', '', array(), true);
|
||||
$ssl_cert_chainfile = validate($this->getParam('ssl_cert_chainfile', true, ''), 'ssl_cert_chainfile', '', '', array(), true);
|
||||
} else {
|
||||
$ssl = 0;
|
||||
$ssl_cert_file = '';
|
||||
$ssl_key_file = '';
|
||||
$ssl_ca_file = '';
|
||||
$ssl_cert_chainfile = '';
|
||||
}
|
||||
|
||||
if ($listen_statement != '1') {
|
||||
$listen_statement = '0';
|
||||
}
|
||||
|
||||
if ($namevirtualhost_statement != '1') {
|
||||
$namevirtualhost_statement = '0';
|
||||
}
|
||||
|
||||
if ($vhostcontainer != '1') {
|
||||
$vhostcontainer = '0';
|
||||
}
|
||||
|
||||
if ($vhostcontainer_servername_statement != '1') {
|
||||
$vhostcontainer_servername_statement = '0';
|
||||
}
|
||||
|
||||
if ($ssl != '1') {
|
||||
$ssl = '0';
|
||||
}
|
||||
|
||||
if ($ssl_cert_file != '') {
|
||||
$ssl_cert_file = makeCorrectFile($ssl_cert_file);
|
||||
}
|
||||
|
||||
if ($ssl_key_file != '') {
|
||||
$ssl_key_file = makeCorrectFile($ssl_key_file);
|
||||
}
|
||||
|
||||
if ($ssl_ca_file != '') {
|
||||
$ssl_ca_file = makeCorrectFile($ssl_ca_file);
|
||||
}
|
||||
|
||||
if ($ssl_cert_chainfile != '') {
|
||||
$ssl_cert_chainfile = makeCorrectFile($ssl_cert_chainfile);
|
||||
}
|
||||
|
||||
if (strlen(trim($docroot)) > 0) {
|
||||
$docroot = makeCorrectDir($docroot);
|
||||
} else {
|
||||
$docroot = '';
|
||||
}
|
||||
|
||||
$result_checkfordouble_stmt = Database::prepare("
|
||||
SELECT `id` FROM `" . TABLE_PANEL_IPSANDPORTS . "`
|
||||
WHERE `ip` = :ip AND `port` = :port");
|
||||
$result_checkfordouble = Database::pexecute_first($result_checkfordouble_stmt, array(
|
||||
'ip' => $ip,
|
||||
'port' => $port
|
||||
));
|
||||
|
||||
if ($result_checkfordouble['id'] != '') {
|
||||
standard_error('myipnotdouble', '', true);
|
||||
}
|
||||
|
||||
$ins_stmt = Database::prepare("
|
||||
INSERT INTO `" . TABLE_PANEL_IPSANDPORTS . "`
|
||||
SET
|
||||
`ip` = :ip, `port` = :port, `listen_statement` = :ls,
|
||||
`namevirtualhost_statement` = :nvhs, `vhostcontainer` = :vhc,
|
||||
`vhostcontainer_servername_statement` = :vhcss,
|
||||
`specialsettings` = :ss, `ssl` = :ssl,
|
||||
`ssl_cert_file` = :ssl_cert, `ssl_key_file` = :ssl_key,
|
||||
`ssl_ca_file` = :ssl_ca, `ssl_cert_chainfile` = :ssl_chain,
|
||||
`default_vhostconf_domain` = :dvhd, `docroot` = :docroot;
|
||||
");
|
||||
$ins_data = array(
|
||||
'ip' => $ip,
|
||||
'port' => $port,
|
||||
'ls' => $listen_statement,
|
||||
'nvhs' => $namevirtualhost_statement,
|
||||
'vhc' => $vhostcontainer,
|
||||
'vhcss' => $vhostcontainer_servername_statement,
|
||||
'ss' => $specialsettings,
|
||||
'ssl' => $ssl,
|
||||
'ssl_cert' => $ssl_cert_file,
|
||||
'ssl_key' => $ssl_key_file,
|
||||
'ssl_ca' => $ssl_ca_file,
|
||||
'ssl_chain' => $ssl_cert_chainfile,
|
||||
'dvhd' => $default_vhostconf_domain,
|
||||
'docroot' => $docroot
|
||||
);
|
||||
Database::pexecute($ins_stmt, $ins_data);
|
||||
$ins_data['id'] = Database::lastInsertId();
|
||||
|
||||
inserttask('1');
|
||||
// Using nameserver, insert a task which rebuilds the server config
|
||||
inserttask('4');
|
||||
|
||||
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
|
||||
$ip = '[' . $ip . ']';
|
||||
}
|
||||
$this->logger()->logAction(ADM_ACTION, LOG_WARNING, "[API] added IP/port '" . $ip . ":" . $port . "'");
|
||||
// get ip for return-array
|
||||
$result = $this->apiCall('IpsAndPorts.get', array(
|
||||
'id' => $ins_data['id']
|
||||
));
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
throw new Exception("Not allowed to execute given command.", 403);
|
||||
}
|
||||
|
||||
/**
|
||||
* update ip/port entry by given id
|
||||
*
|
||||
* @param int $id
|
||||
* @param string $ip
|
||||
* optional
|
||||
* @param int $port
|
||||
* optional, default 80
|
||||
* @param bool $listen_statement
|
||||
* optional, default 0 (false)
|
||||
* @param bool $namevirtualhost_statement
|
||||
* optional, default 0 (false)
|
||||
* @param bool $vhostcontainer
|
||||
* optional, default 0 (false)
|
||||
* @param string $specialsettings
|
||||
* optional, default empty
|
||||
* @param bool $vhostcontainer_servername_statement
|
||||
* optional, default 0 (false)
|
||||
* @param string $default_vhostconf_domain
|
||||
* optional, defatul empty
|
||||
* @param string $docroot
|
||||
* optional, default empty (point to froxlor)
|
||||
* @param bool $ssl
|
||||
* optional, default 0 (false)
|
||||
* @param string $ssl_cert_file
|
||||
* optional, requires $ssl = 1, default empty
|
||||
* @param string $ssl_key_file
|
||||
* optional, requires $ssl = 1, default empty
|
||||
* @param string $ssl_ca_file
|
||||
* optional, requires $ssl = 1, default empty
|
||||
* @param string $ssl_cert_chainfile
|
||||
* optional, requires $ssl = 1, default empty
|
||||
*
|
||||
*
|
||||
* @access admin
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function update()
|
||||
{
|
||||
if ($this->isAdmin() && ($this->getUserDetail('change_serversettings') || ! empty($this->getUserDetail('ip')))) {
|
||||
$id = $this->getParam('id');
|
||||
|
||||
$result = $this->apiCall('IpsAndPorts.get', array(
|
||||
'id' => $id
|
||||
));
|
||||
|
||||
$ip = validate_ip2($this->getParam('ip', true, $result['ip']), false, 'invalidip', false, false, false, true);
|
||||
$port = validate($this->getParam('port', true, $result['port']), 'port', '/^(([1-9])|([1-9][0-9])|([1-9][0-9][0-9])|([1-9][0-9][0-9][0-9])|([1-5][0-9][0-9][0-9][0-9])|(6[0-4][0-9][0-9][0-9])|(65[0-4][0-9][0-9])|(655[0-2][0-9])|(6553[0-5]))$/Di', array(
|
||||
'stringisempty',
|
||||
'myport'
|
||||
), array(), true);
|
||||
$listen_statement = $this->getBoolParam('listen_statement', true, $result['listen_statement']);
|
||||
$namevirtualhost_statement = $this->getBoolParam('namevirtualhost_statement', true, $result['namevirtualhost_statement']);
|
||||
$vhostcontainer = $this->getBoolParam('vhostcontainer', true, $result['vhostcontainer']);
|
||||
$specialsettings = validate(str_replace("\r\n", "\n", $this->getParam('specialsettings', true, $result['specialsettings'])), 'specialsettings', '/^[^\0]*$/', '', array(), true);
|
||||
$vhostcontainer_servername_statement = $this->getParam('vhostcontainer_servername_statement', true, $result['vhostcontainer_servername_statement']);
|
||||
$default_vhostconf_domain = validate(str_replace("\r\n", "\n", $this->getParam('default_vhostconf_domain', true, $result['default_vhostconf_domain'])), 'default_vhostconf_domain', '/^[^\0]*$/', '', array(), true);
|
||||
$docroot = validate($this->getParam('docroot', true, $result['docroot']), 'docroot', '', '', array(), true);
|
||||
|
||||
if ((int) Settings::Get('system.use_ssl') == 1) {
|
||||
$ssl = $this->getBoolParam('ssl', true, $result['ssl']);
|
||||
$ssl_cert_file = validate($this->getParam('ssl_cert_file', $ssl, $result['ssl_cert_file']), 'ssl_cert_file', '', '', array(), true);
|
||||
$ssl_key_file = validate($this->getParam('ssl_key_file', $ssl, $result['ssl_key_file']), 'ssl_key_file', '', '', array(), true);
|
||||
$ssl_ca_file = validate($this->getParam('ssl_ca_file', true, $result['ssl_ca_file']), 'ssl_ca_file', '', '', array(), true);
|
||||
$ssl_cert_chainfile = validate($this->getParam('ssl_cert_chainfile', true, $result['ssl_cert_chainfile']), 'ssl_cert_chainfile', '', '', array(), true);
|
||||
} else {
|
||||
$ssl = 0;
|
||||
$ssl_cert_file = '';
|
||||
$ssl_key_file = '';
|
||||
$ssl_ca_file = '';
|
||||
$ssl_cert_chainfile = '';
|
||||
}
|
||||
|
||||
$result_checkfordouble_stmt = Database::prepare("
|
||||
SELECT `id` FROM `" . TABLE_PANEL_IPSANDPORTS . "`
|
||||
WHERE `ip` = :ip AND `port` = :port
|
||||
");
|
||||
$result_checkfordouble = Database::pexecute_first($result_checkfordouble_stmt, array(
|
||||
'ip' => $ip,
|
||||
'port' => $port
|
||||
));
|
||||
|
||||
$result_sameipotherport_stmt = Database::prepare("
|
||||
SELECT `id` FROM `" . TABLE_PANEL_IPSANDPORTS . "`
|
||||
WHERE `ip` = :ip AND `id` <> :id
|
||||
");
|
||||
$result_sameipotherport = Database::pexecute_first($result_sameipotherport_stmt, array(
|
||||
'ip' => $ip,
|
||||
'id' => $id
|
||||
), true, true);
|
||||
|
||||
if ($listen_statement != '1') {
|
||||
$listen_statement = '0';
|
||||
}
|
||||
|
||||
if ($namevirtualhost_statement != '1') {
|
||||
$namevirtualhost_statement = '0';
|
||||
}
|
||||
|
||||
if ($vhostcontainer != '1') {
|
||||
$vhostcontainer = '0';
|
||||
}
|
||||
|
||||
if ($vhostcontainer_servername_statement != '1') {
|
||||
$vhostcontainer_servername_statement = '0';
|
||||
}
|
||||
|
||||
if ($ssl != '1') {
|
||||
$ssl = '0';
|
||||
}
|
||||
|
||||
if ($ssl_cert_file != '') {
|
||||
$ssl_cert_file = makeCorrectFile($ssl_cert_file);
|
||||
}
|
||||
|
||||
if ($ssl_key_file != '') {
|
||||
$ssl_key_file = makeCorrectFile($ssl_key_file);
|
||||
}
|
||||
|
||||
if ($ssl_ca_file != '') {
|
||||
$ssl_ca_file = makeCorrectFile($ssl_ca_file);
|
||||
}
|
||||
|
||||
if ($ssl_cert_chainfile != '') {
|
||||
$ssl_cert_chainfile = makeCorrectFile($ssl_cert_chainfile);
|
||||
}
|
||||
|
||||
if (strlen(trim($docroot)) > 0) {
|
||||
$docroot = makeCorrectDir($docroot);
|
||||
} else {
|
||||
$docroot = '';
|
||||
}
|
||||
|
||||
if ($result['ip'] != $ip && $result['ip'] == Settings::Get('system.ipaddress') && $result_sameipotherport['id'] == '') {
|
||||
standard_error('cantchangesystemip', '', true);
|
||||
} elseif ($result_checkfordouble['id'] != '' && $result_checkfordouble['id'] != $id) {
|
||||
standard_error('myipnotdouble', '', true);
|
||||
} else {
|
||||
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_IPSANDPORTS . "`
|
||||
SET
|
||||
`ip` = :ip, `port` = :port, `listen_statement` = :ls,
|
||||
`namevirtualhost_statement` = :nvhs, `vhostcontainer` = :vhc,
|
||||
`vhostcontainer_servername_statement` = :vhcss,
|
||||
`specialsettings` = :ss, `ssl` = :ssl,
|
||||
`ssl_cert_file` = :ssl_cert, `ssl_key_file` = :ssl_key,
|
||||
`ssl_ca_file` = :ssl_ca, `ssl_cert_chainfile` = :ssl_chain,
|
||||
`default_vhostconf_domain` = :dvhd, `docroot` = :docroot
|
||||
WHERE `id` = :id;
|
||||
");
|
||||
$upd_data = array(
|
||||
'ip' => $ip,
|
||||
'port' => $port,
|
||||
'ls' => $listen_statement,
|
||||
'nvhs' => $namevirtualhost_statement,
|
||||
'vhc' => $vhostcontainer,
|
||||
'vhcss' => $vhostcontainer_servername_statement,
|
||||
'ss' => $specialsettings,
|
||||
'ssl' => $ssl,
|
||||
'ssl_cert' => $ssl_cert_file,
|
||||
'ssl_key' => $ssl_key_file,
|
||||
'ssl_ca' => $ssl_ca_file,
|
||||
'ssl_chain' => $ssl_cert_chainfile,
|
||||
'dvhd' => $default_vhostconf_domain,
|
||||
'docroot' => $docroot,
|
||||
'id' => $id
|
||||
);
|
||||
Database::pexecute($upd_stmt, $upd_data);
|
||||
|
||||
inserttask('1');
|
||||
// Using nameserver, insert a task which rebuilds the server config
|
||||
inserttask('4');
|
||||
|
||||
$this->logger()->logAction(ADM_ACTION, LOG_WARNING, "[API] changed IP/port from '" . $result['ip'] . ":" . $result['port'] . "' to '" . $ip . ":" . $port . "'");
|
||||
|
||||
$result = $this->apiCall('IpsAndPorts.get', array(
|
||||
'id' => $result['id']
|
||||
));
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
}
|
||||
throw new Exception("Not allowed to execute given command.", 403);
|
||||
}
|
||||
|
||||
/**
|
||||
* delete an ip/port entry by id
|
||||
*
|
||||
* @param int $id
|
||||
* ip-port-id
|
||||
*
|
||||
* @access admin
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
if ($this->isAdmin() && $this->getUserDetail('change_serversettings')) {
|
||||
$id = $this->getParam('id');
|
||||
|
||||
$result = $this->apiCall('IpsAndPorts.get', array(
|
||||
'id' => $id
|
||||
));
|
||||
|
||||
$result_checkdomain_stmt = Database::prepare("
|
||||
SELECT `id_domain` as `id` FROM `" . TABLE_DOMAINTOIP . "` WHERE `id_ipandports` = :id
|
||||
");
|
||||
$result_checkdomain = Database::pexecute_first($result_checkdomain_stmt, array(
|
||||
'id' => $id
|
||||
), true, true);
|
||||
|
||||
if (empty($result_checkdomain)) {
|
||||
if (! in_array($result['id'], explode(',', Settings::Get('system.defaultip'))) && ! in_array($result['id'], explode(',', Settings::Get('system.defaultsslip')))) {
|
||||
|
||||
// check whether there is the same IP with a different port
|
||||
// in case this ip-address is the system.ipaddress and therefore
|
||||
// when there is one - we have an alternative
|
||||
$result_sameipotherport_stmt = Database::prepare("
|
||||
SELECT `id` FROM `" . TABLE_PANEL_IPSANDPORTS . "`
|
||||
WHERE `ip` = :ip AND `id` <> :id");
|
||||
$result_sameipotherport = Database::pexecute_first($result_sameipotherport_stmt, array(
|
||||
'id' => $id,
|
||||
'ip' => $result['ip']
|
||||
));
|
||||
|
||||
if (($result['ip'] != Settings::Get('system.ipaddress')) || ($result['ip'] == Settings::Get('system.ipaddress') && $result_sameipotherport['id'] != '')) {
|
||||
|
||||
$del_stmt = Database::prepare("
|
||||
DELETE FROM `" . TABLE_PANEL_IPSANDPORTS . "`
|
||||
WHERE `id` = :id
|
||||
");
|
||||
Database::pexecute($del_stmt, array(
|
||||
'id' => $id
|
||||
), true, true);
|
||||
|
||||
// also, remove connections to domains (multi-stack)
|
||||
$del_stmt = Database::prepare("
|
||||
DELETE FROM `" . TABLE_DOMAINTOIP . "` WHERE `id_ipandports` = :id
|
||||
");
|
||||
Database::pexecute($del_stmt, array(
|
||||
'id' => $id
|
||||
), true, true);
|
||||
|
||||
inserttask('1');
|
||||
// Using nameserver, insert a task which rebuilds the server config
|
||||
inserttask('4');
|
||||
|
||||
$this->logger()->logAction(ADM_ACTION, LOG_WARNING, "[API] deleted IP/port '" . $result['ip'] . ":" . $result['port'] . "'");
|
||||
return $this->response(200, "successfull", $result);
|
||||
} else {
|
||||
standard_error('cantdeletesystemip', '', true);
|
||||
}
|
||||
} else {
|
||||
standard_error('cantdeletedefaultip', '', true);
|
||||
}
|
||||
} else {
|
||||
standard_error('ipstillhasdomains', '', true);
|
||||
}
|
||||
}
|
||||
throw new Exception("Not allowed to execute given command.", 403);
|
||||
}
|
||||
}
|
||||
@@ -1,481 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package API
|
||||
* @since 0.10.0
|
||||
*
|
||||
*/
|
||||
class Mysqls extends ApiCommand implements ResourceEntity
|
||||
{
|
||||
|
||||
/**
|
||||
* add a new mysql-database
|
||||
*
|
||||
* @param string $mysql_password
|
||||
* password for the created database and database-user
|
||||
* @param int $mysql_server
|
||||
* optional, default is 0
|
||||
* @param string $description
|
||||
* optional, description for database
|
||||
* @param bool $sendinfomail
|
||||
* optional, send created resource-information to customer, default: false
|
||||
* @param int $customer_id
|
||||
* required when called as admin, not needed when called as customer
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
if ($this->getUserDetail('mysqls_used') < $this->getUserDetail('mysqls') || $this->getUserDetail('mysqls') == '-1') {
|
||||
|
||||
// required paramters
|
||||
$password = $this->getParam('mysql_password');
|
||||
|
||||
// parameters
|
||||
$dbserver = $this->getParam('mysql_server', true, 0);
|
||||
$databasedescription = $this->getParam('description', true, '');
|
||||
$sendinfomail = $this->getBoolParam('sendinfomail', true, 0);
|
||||
|
||||
// validation
|
||||
$password = validate($password, 'password', '', '', array(), true);
|
||||
$password = validatePassword($password, true);
|
||||
$databasedescription = validate(trim($databasedescription), 'description', '', '', array(), true);
|
||||
|
||||
// validate whether the dbserver exists
|
||||
$dbserver = validate($dbserver, html_entity_decode($this->lng['mysql']['mysql_server']), '', '', 0, true);
|
||||
Database::needRoot(true, $dbserver);
|
||||
Database::needSqlData();
|
||||
$sql_root = Database::getSqlData();
|
||||
Database::needRoot(false);
|
||||
if (! isset($sql_root) || ! is_array($sql_root)) {
|
||||
throw new ErrorException("Database server with index #" . $dbserver . " is unknown", 404);
|
||||
}
|
||||
|
||||
if ($sendinfomail != 1) {
|
||||
$sendinfomail = 0;
|
||||
}
|
||||
|
||||
// get needed customer info to reduce the mysql-usage-counter by one
|
||||
$customer = $this->getCustomerData('mysqls');
|
||||
|
||||
$newdb_params = array(
|
||||
'loginname' => ($this->isAdmin() ? $customer['loginname'] : $this->getUserDetail('loginname')),
|
||||
'mysql_lastaccountnumber' => ($this->isAdmin() ? $customer['mysql_lastaccountnumber'] : $this->getUserDetail('mysql_lastaccountnumber'))
|
||||
);
|
||||
// create database, user, set permissions, etc.pp.
|
||||
$dbm = new DbManager($this->logger());
|
||||
$username = $dbm->createDatabase($newdb_params['loginname'], $password, $newdb_params['mysql_lastaccountnumber']);
|
||||
|
||||
// we've checked against the password in dbm->createDatabase
|
||||
if ($username == false) {
|
||||
standard_error('passwordshouldnotbeusername', '', true);
|
||||
}
|
||||
|
||||
// add database info to froxlor
|
||||
$stmt = Database::prepare("
|
||||
INSERT INTO `" . TABLE_PANEL_DATABASES . "`
|
||||
SET
|
||||
`customerid` = :customerid,
|
||||
`databasename` = :databasename,
|
||||
`description` = :description,
|
||||
`dbserver` = :dbserver
|
||||
");
|
||||
$params = array(
|
||||
"customerid" => $customer['customerid'],
|
||||
"databasename" => $username,
|
||||
"description" => $databasedescription,
|
||||
"dbserver" => $dbserver
|
||||
);
|
||||
Database::pexecute($stmt, $params, true, true);
|
||||
$databaseid = Database::lastInsertId();
|
||||
$params['id'] = $databaseid;
|
||||
|
||||
// update customer usage
|
||||
Customers::increaseUsage($customer['customerid'], 'mysqls_used');
|
||||
Customers::increaseUsage($customer['customerid'], 'mysql_lastaccountnumber');
|
||||
|
||||
// update admin usage
|
||||
Admins::increaseUsage($this->getUserDetail('adminid'), 'mysqls_used');
|
||||
|
||||
// send info-mail?
|
||||
if ($sendinfomail == 1) {
|
||||
$pma = $this->lng['admin']['notgiven'];
|
||||
if (Settings::Get('panel.phpmyadmin_url') != '') {
|
||||
$pma = Settings::Get('panel.phpmyadmin_url');
|
||||
}
|
||||
|
||||
Database::needRoot(true, $dbserver);
|
||||
Database::needSqlData();
|
||||
$sql_root = Database::getSqlData();
|
||||
Database::needRoot(false);
|
||||
$userinfo = $customer;
|
||||
|
||||
$replace_arr = array(
|
||||
'SALUTATION' => getCorrectUserSalutation($userinfo),
|
||||
'CUST_NAME' => getCorrectUserSalutation($userinfo), // < keep this for compatibility
|
||||
'DB_NAME' => $username,
|
||||
'DB_PASS' => $password,
|
||||
'DB_DESC' => $databasedescription,
|
||||
'DB_SRV' => $sql_root['host'],
|
||||
'PMA_URI' => $pma
|
||||
);
|
||||
|
||||
// get template for mail subject
|
||||
$mail_subject = $this->getMailTemplate($userinfo, 'mails', 'new_database_by_customer_subject', $replace_arr, $this->lng['mails']['new_database_by_customer']['subject']);
|
||||
// get template for mail body
|
||||
$mail_body = $this->getMailTemplate($userinfo, 'mails', 'new_database_by_customer_mailbody', $replace_arr, $this->lng['mails']['new_database_by_customer']['mailbody']);
|
||||
|
||||
$_mailerror = false;
|
||||
$mailerr_msg = "";
|
||||
try {
|
||||
$this->mailer()->Subject = $mail_subject;
|
||||
$this->mailer()->AltBody = $mail_body;
|
||||
$this->mailer()->msgHTML(str_replace("\n", "<br />", $mail_body));
|
||||
$this->mailer()->addAddress($userinfo['email'], getCorrectUserSalutation($userinfo));
|
||||
$this->mailer()->send();
|
||||
} catch (phpmailerException $e) {
|
||||
$mailerr_msg = $e->errorMessage();
|
||||
$_mailerror = true;
|
||||
} catch (Exception $e) {
|
||||
$mailerr_msg = $e->getMessage();
|
||||
$_mailerror = true;
|
||||
}
|
||||
|
||||
if ($_mailerror) {
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_ERR, "[API] Error sending mail: " . $mailerr_msg);
|
||||
standard_error('errorsendingmail', $userinfo['email'], true);
|
||||
}
|
||||
|
||||
$this->mailer()->clearAddresses();
|
||||
}
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_WARNING, "[API] added mysql-database '" . $username . "'");
|
||||
|
||||
$result = $this->apiCall('Mysqls.get', array(
|
||||
'dbname' => $username
|
||||
));
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
throw new Exception("No more resources available", 406);
|
||||
}
|
||||
|
||||
/**
|
||||
* return a mysql database entry by either id or dbname
|
||||
*
|
||||
* @param int $id
|
||||
* optional, the database-id
|
||||
* @param string $dbname
|
||||
* optional, the databasename
|
||||
* @param int $mysql_server
|
||||
* optional, specify database-server, default is none
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
$id = $this->getParam('id', true, 0);
|
||||
$dn_optional = ($id <= 0 ? false : true);
|
||||
$dbname = $this->getParam('dbname', $dn_optional, '');
|
||||
$dbserver = $this->getParam('mysql_server', true, - 1);
|
||||
|
||||
if ($this->isAdmin()) {
|
||||
if ($this->getUserDetail('customers_see_all') != 1) {
|
||||
// if it's a reseller or an admin who cannot see all customers, we need to check
|
||||
// whether the database belongs to one of his customers
|
||||
$_custom_list_result = $this->apiCall('Customers.listing');
|
||||
$custom_list_result = $_custom_list_result['list'];
|
||||
$customer_ids = array();
|
||||
foreach ($custom_list_result as $customer) {
|
||||
$customer_ids[] = $customer['customerid'];
|
||||
}
|
||||
if (count($customer_ids) > 0) {
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_PANEL_DATABASES . "`
|
||||
WHERE " . ($id > 0 ? "`id` = :iddn" : "`databasename` = :iddn") . ($dbserver >= 0 ? " AND `dbserver` = :dbserver" : "") . " AND `customerid` IN (".implode(", ", $customer_ids).")
|
||||
");
|
||||
$params = array(
|
||||
'iddn' => ($id <= 0 ? $dbname : $id)
|
||||
);
|
||||
if ($dbserver >= 0) {
|
||||
$params['dbserver'] = $dbserver;
|
||||
}
|
||||
} else {
|
||||
throw new Exception("You do not have any customers yet", 406);
|
||||
}
|
||||
} else {
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_PANEL_DATABASES . "`
|
||||
WHERE " . ($id > 0 ? "`id` = :iddn" : "`databasename` = :iddn") . ($dbserver >= 0 ? " AND `dbserver` = :dbserver" : ""));
|
||||
$params = array(
|
||||
'iddn' => ($id <= 0 ? $dbname : $id)
|
||||
);
|
||||
if ($dbserver >= 0) {
|
||||
$params['dbserver'] = $dbserver;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (Settings::IsInList('panel.customer_hide_options', 'mysql')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_PANEL_DATABASES . "`
|
||||
WHERE `customerid`= :customerid AND " . ($id > 0 ? "`id` = :iddn" : "`databasename` = :iddn") . ($dbserver >= 0 ? " AND `dbserver` = :dbserver" : ""));
|
||||
$params = array(
|
||||
'customerid' => $this->getUserDetail('customerid'),
|
||||
'iddn' => ($id <= 0 ? $dbname : $id)
|
||||
);
|
||||
if ($dbserver >= 0) {
|
||||
$params['dbserver'] = $dbserver;
|
||||
}
|
||||
}
|
||||
$result = Database::pexecute_first($result_stmt, $params, true, true);
|
||||
if ($result) {
|
||||
Database::needRoot(true, $result['dbserver']);
|
||||
$mbdata_stmt = Database::prepare("
|
||||
SELECT SUM(data_length + index_length) as MB FROM information_schema.TABLES
|
||||
WHERE table_schema = :table_schema
|
||||
GROUP BY table_schema
|
||||
");
|
||||
Database::pexecute($mbdata_stmt, array(
|
||||
"table_schema" => $result['databasename']
|
||||
), true, true);
|
||||
$mbdata = $mbdata_stmt->fetch(PDO::FETCH_ASSOC);
|
||||
Database::needRoot(false);
|
||||
$result['size'] = $mbdata['MB'];
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_NOTICE, "[API] get database '" . $result['databasename'] . "'");
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
$key = ($id > 0 ? "id #" . $id : "dbname '" . $dbname . "'");
|
||||
throw new Exception("MySQL database with " . $key . " could not be found", 404);
|
||||
}
|
||||
|
||||
/**
|
||||
* update a mysql database entry by either id or dbname
|
||||
*
|
||||
* @param int $id
|
||||
* optional, the database-id
|
||||
* @param string $dbname
|
||||
* optional, the databasename
|
||||
* @param int $mysql_server
|
||||
* optional, specify database-server, default is none
|
||||
* @param string $mysql_password
|
||||
* optional, update password for the database
|
||||
* @param string $description
|
||||
* optional, description for database
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function update()
|
||||
{
|
||||
$id = $this->getParam('id', true, 0);
|
||||
$dn_optional = ($id <= 0 ? false : true);
|
||||
$dbname = $this->getParam('dbname', $dn_optional, '');
|
||||
$dbserver = $this->getParam('mysql_server', true, - 1);
|
||||
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'mysql')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
|
||||
$result = $this->apiCall('Mysqls.get', array(
|
||||
'id' => $id,
|
||||
'dbname' => $dbname,
|
||||
'mysql_server' => $dbserver
|
||||
));
|
||||
$id = $result['id'];
|
||||
|
||||
// paramters
|
||||
$password = $this->getParam('mysql_password', true, '');
|
||||
$databasedescription = $this->getParam('description', true, '');
|
||||
|
||||
// validation
|
||||
$password = validate($password, 'password', '', '', array(), true);
|
||||
$databasedescription = validate(trim($databasedescription), 'description', '', '', array(), true);
|
||||
|
||||
// get needed customer info to reduce the mysql-usage-counter by one
|
||||
$customer = $this->getCustomerData();
|
||||
|
||||
if ($password != '') {
|
||||
// validate password
|
||||
$password = validatePassword($password, true);
|
||||
|
||||
if ($password == $result['databasename']) {
|
||||
standard_error('passwordshouldnotbeusername', '', true);
|
||||
}
|
||||
|
||||
// Begin root-session
|
||||
Database::needRoot(true, $result['dbserver']);
|
||||
foreach (array_map('trim', explode(',', Settings::Get('system.mysql_access_host'))) as $mysql_access_host) {
|
||||
$stmt = Database::prepare("SET PASSWORD FOR :dbname@:host = PASSWORD(:password)");
|
||||
$params = array(
|
||||
"dbname" => $result['databasename'],
|
||||
"host" => $mysql_access_host,
|
||||
"password" => $password
|
||||
);
|
||||
Database::pexecute($stmt, $params, true, true);
|
||||
}
|
||||
|
||||
$stmt = Database::prepare("FLUSH PRIVILEGES");
|
||||
Database::pexecute($stmt, null, true, true);
|
||||
Database::needRoot(false);
|
||||
// End root-session
|
||||
}
|
||||
$stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_DATABASES . "`
|
||||
SET `description` = :desc
|
||||
WHERE `customerid` = :customerid
|
||||
AND `id` = :id
|
||||
");
|
||||
$params = array(
|
||||
"desc" => $databasedescription,
|
||||
"customerid" => $customer['customerid'],
|
||||
"id" => $id
|
||||
);
|
||||
Database::pexecute($stmt, $params, true, true);
|
||||
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_WARNING, "[API] updated mysql-database '" . $result['databasename'] . "'");
|
||||
$result = $this->apiCall('Mysqls.get', array(
|
||||
'dbname' => $result['databasename']
|
||||
));
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* list all databases, if called from an admin, list all databases of all customers you are allowed to view, or specify id or loginname for one specific customer
|
||||
*
|
||||
* @param int $mysql_server
|
||||
* optional, specify dbserver to select from, else use all available
|
||||
* @param int $customerid
|
||||
* optional, admin-only, select dbs of a specific customer by id
|
||||
* @param string $loginname
|
||||
* optional, admin-only, select dbs of a specific customer by loginname
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array count|list
|
||||
*/
|
||||
public function listing()
|
||||
{
|
||||
$result = array();
|
||||
$dbserver = $this->getParam('mysql_server', true, - 1);
|
||||
$customer_ids = $this->getAllowedCustomerIds('mysql');
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_PANEL_DATABASES . "`
|
||||
WHERE `customerid`= :customerid AND `dbserver` = :dbserver
|
||||
");
|
||||
if ($dbserver < 0) {
|
||||
// use all dbservers
|
||||
$dbservers_stmt = Database::query("SELECT DISTINCT `dbserver` FROM `" . TABLE_PANEL_DATABASES . "`");
|
||||
$dbservers = $dbservers_stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
} else {
|
||||
// use specific dbserver
|
||||
$dbservers = array(
|
||||
array(
|
||||
'dbserver' => $dbserver
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($customer_ids as $customer_id) {
|
||||
foreach ($dbservers as $_dbserver) {
|
||||
Database::pexecute($result_stmt, array(
|
||||
'customerid' => $customer_id,
|
||||
'dbserver' => $_dbserver['dbserver']
|
||||
), true, true);
|
||||
// Begin root-session
|
||||
Database::needRoot(true, $_dbserver['dbserver']);
|
||||
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$mbdata_stmt = Database::prepare("
|
||||
SELECT SUM(data_length + index_length) as MB FROM information_schema.TABLES
|
||||
WHERE table_schema = :table_schema
|
||||
GROUP BY table_schema
|
||||
");
|
||||
Database::pexecute($mbdata_stmt, array(
|
||||
"table_schema" => $row['databasename']
|
||||
), true, true);
|
||||
$mbdata = $mbdata_stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$row['size'] = $mbdata['MB'];
|
||||
$result[] = $row;
|
||||
}
|
||||
Database::needRoot(false);
|
||||
}
|
||||
}
|
||||
return $this->response(200, "successfull", array(
|
||||
'count' => count($result),
|
||||
'list' => $result
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* delete a mysql database by either id or dbname
|
||||
*
|
||||
* @param int $id
|
||||
* optional, the database-id
|
||||
* @param string $dbname
|
||||
* optional, the databasename
|
||||
* @param int $mysql_server
|
||||
* optional, specify database-server, default is none
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
$id = $this->getParam('id', true, 0);
|
||||
$dn_optional = ($id <= 0 ? false : true);
|
||||
$dbname = $this->getParam('dbname', $dn_optional, '');
|
||||
$dbserver = $this->getParam('mysql_server', true, - 1);
|
||||
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'mysql')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
|
||||
$result = $this->apiCall('Mysqls.get', array(
|
||||
'id' => $id,
|
||||
'dbname' => $dbname,
|
||||
'mysql_server' => $dbserver
|
||||
));
|
||||
$id = $result['id'];
|
||||
|
||||
// Begin root-session
|
||||
Database::needRoot(true, $result['dbserver']);
|
||||
$dbm = new DbManager($this->logger());
|
||||
$dbm->getManager()->deleteDatabase($result['databasename']);
|
||||
Database::needRoot(false);
|
||||
// End root-session
|
||||
|
||||
// delete from table
|
||||
$stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_DATABASES . "` WHERE `id` = :id");
|
||||
Database::pexecute($stmt, array(
|
||||
"id" => $id
|
||||
), true, true);
|
||||
|
||||
// get needed customer info to reduce the mysql-usage-counter by one
|
||||
$customer = $this->getCustomerData();
|
||||
$mysql_used = $customer['mysqls_used'];
|
||||
|
||||
// reduce mysql-usage-counter
|
||||
$resetaccnumber = ($mysql_used == '1') ? " , `mysql_lastaccountnumber` = '0' " : '';
|
||||
Customers::decreaseUsage($customer['customerid'], 'mysqls_used', $resetaccnumber);
|
||||
// update admin usage
|
||||
Admins::decreaseUsage(($this->isAdmin() ? $customer['adminid'] : $this->getUserDetail('adminid')), 'mysqls_used');
|
||||
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_WARNING, "[API] deleted database '" . $result['databasename'] . "'");
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
}
|
||||
@@ -1,589 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package API
|
||||
* @since 0.10.0
|
||||
*
|
||||
*/
|
||||
class PhpSettings extends ApiCommand implements ResourceEntity
|
||||
{
|
||||
|
||||
/**
|
||||
* lists all php-setting entries
|
||||
*
|
||||
* @param bool $with_subdomains
|
||||
* optional, also include subdomains to the list domains that use the config, default 0 (false)
|
||||
*
|
||||
* @access admin
|
||||
* @throws Exception
|
||||
* @return array count|list
|
||||
*/
|
||||
public function listing()
|
||||
{
|
||||
if ($this->isAdmin()) {
|
||||
$this->logger()->logAction(ADM_ACTION, LOG_NOTICE, "[API] list php-configs");
|
||||
|
||||
$with_subdomains = $this->getBoolParam('with_subdomains', true, false);
|
||||
|
||||
$result = Database::query("
|
||||
SELECT c.*, fd.description as fpmdesc
|
||||
FROM `" . TABLE_PANEL_PHPCONFIGS . "` c
|
||||
LEFT JOIN `" . TABLE_PANEL_FPMDAEMONS . "` fd ON fd.id = c.fpmsettingid
|
||||
ORDER BY c.description ASC
|
||||
");
|
||||
|
||||
$phpconfigs = array();
|
||||
while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
|
||||
$query_params = array(
|
||||
'id' => $row['id']
|
||||
);
|
||||
|
||||
$query = "SELECT * FROM `" . TABLE_PANEL_DOMAINS . "`
|
||||
WHERE `phpsettingid` = :id";
|
||||
|
||||
if (!$with_subdomains) {
|
||||
$query .= " AND `parentdomainid` = '0'";
|
||||
}
|
||||
|
||||
if ((int) $this->getUserDetail('domains_see_all') == 0) {
|
||||
$query .= " AND `adminid` = :adminid";
|
||||
$query_params['adminid'] = $this->getUserDetail('adminid');
|
||||
}
|
||||
|
||||
if ((int) Settings::Get('panel.phpconfigs_hidestdsubdomain') == 1) {
|
||||
$ssdids_res = Database::query("
|
||||
SELECT DISTINCT `standardsubdomain` FROM `" . TABLE_PANEL_CUSTOMERS . "`
|
||||
WHERE `standardsubdomain` > 0 ORDER BY `standardsubdomain` ASC;");
|
||||
$ssdids = array();
|
||||
while ($ssd = $ssdids_res->fetch(PDO::FETCH_ASSOC)) {
|
||||
$ssdids[] = $ssd['standardsubdomain'];
|
||||
}
|
||||
if (count($ssdids) > 0) {
|
||||
$query .= " AND `id` NOT IN (" . implode(', ', $ssdids) . ")";
|
||||
}
|
||||
}
|
||||
|
||||
$domains = array();
|
||||
$subdomains = array();
|
||||
$domainresult_stmt = Database::prepare($query);
|
||||
Database::pexecute($domainresult_stmt, $query_params, true, true);
|
||||
|
||||
if (Database::num_rows() > 0) {
|
||||
while ($row2 = $domainresult_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
if ($row2['parentdomainid'] != 0) {
|
||||
$subdomains[] = $row2['domain'];
|
||||
} else {
|
||||
$domains[] = $row2['domain'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check whether we use that config as froxor-vhost config
|
||||
if (Settings::Get('system.mod_fcgid_defaultini_ownvhost') == $row['id'] || Settings::Get('phpfpm.vhost_defaultini') == $row['id']) {
|
||||
$domains[] = Settings::Get('system.hostname');
|
||||
}
|
||||
|
||||
// check whether this is our default config
|
||||
if ((Settings::Get('system.mod_fcgid') == '1' && Settings::Get('system.mod_fcgid_defaultini') == $row['id']) || (Settings::Get('phpfpm.enabled') == '1' && Settings::Get('phpfpm.defaultini') == $row['id'])) {
|
||||
$row['is_default'] = true;
|
||||
}
|
||||
|
||||
$row['domains'] = $domains;
|
||||
$row['subdomains'] = $subdomains;
|
||||
$phpconfigs[] = $row;
|
||||
}
|
||||
|
||||
return $this->response(200, "successfull", array(
|
||||
'count' => count($phpconfigs),
|
||||
'list' => $phpconfigs
|
||||
));
|
||||
}
|
||||
throw new Exception("Not allowed to execute given command.", 403);
|
||||
}
|
||||
|
||||
/**
|
||||
* return a php-setting entry by id
|
||||
*
|
||||
* @param int $id
|
||||
* php-settings-id
|
||||
*
|
||||
* @access admin
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
if ($this->isAdmin()) {
|
||||
$id = $this->getParam('id');
|
||||
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_PANEL_PHPCONFIGS . "` WHERE `id` = :id
|
||||
");
|
||||
$result = Database::pexecute_first($result_stmt, array(
|
||||
'id' => $id
|
||||
), true, true);
|
||||
if ($result) {
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
throw new Exception("php-config with id #" . $id . " could not be found", 404);
|
||||
}
|
||||
throw new Exception("Not allowed to execute given command.", 403);
|
||||
}
|
||||
|
||||
/**
|
||||
* add new php-settings entry
|
||||
*
|
||||
* @param string $description
|
||||
* description of the php-config
|
||||
* @param string $phpsettings
|
||||
* the actual ini-settings
|
||||
* @param string $binary
|
||||
* optional the binary to php-cgi if FCGID is used
|
||||
* @param string $file_extensions
|
||||
* optional allowed php-file-extensions if FCGID is used, default is 'php'
|
||||
* @param int $mod_fcgid_starter
|
||||
* optional number of fcgid-starters if FCGID is used, default is -1
|
||||
* @param int $mod_fcgid_maxrequests
|
||||
* optional number of fcgid-maxrequests if FCGID is used, default is -1
|
||||
* @param string $mod_fcgid_umask
|
||||
* optional umask if FCGID is used, default is '022'
|
||||
* @param int $fpmconfig
|
||||
* optional id of the fpm-daemon-config if FPM is used
|
||||
* @param bool $phpfpm_enable_slowlog
|
||||
* optional whether to write a slowlog or not if FPM is used, default is 0 (false)
|
||||
* @param string $phpfpm_reqtermtimeout
|
||||
* optional request terminate timeout if FPM is used, default is '60s'
|
||||
* @param string $phpfpm_reqslowtimeout
|
||||
* optional request slowlog timeout if FPM is used, default is '5s'
|
||||
* @param bool $phpfpm_pass_authorizationheader
|
||||
* optional whether to pass authorization header to webserver if FPM is used, default is 0 (false)
|
||||
* @param bool $override_fpmconfig
|
||||
* optional whether to override fpm-daemon-config value for the following settings if FPM is used, default is 0 (false)
|
||||
* @param string $pm
|
||||
* optional process-manager to use if FPM is used (allowed values are 'static', 'dynamic' and 'ondemand'), default is fpm-daemon-value
|
||||
* @param int $max_children
|
||||
* optional number of max children if FPM is used, default is the fpm-daemon-value
|
||||
* @param int $start_server
|
||||
* optional number of servers to start if FPM is used, default is fpm-daemon-value
|
||||
* @param int $min_spare_servers
|
||||
* optional number of minimum spare servers if FPM is used, default is fpm-daemon-value
|
||||
* @param int $max_spare_servers
|
||||
* optional number of maximum spare servers if FPM is used, default is fpm-daemon-value
|
||||
* @param int $max_requests
|
||||
* optional number of maximum requests if FPM is used, default is fpm-daemon-value
|
||||
* @param int $idle_timeout
|
||||
* optional number of seconds for idle-timeout if FPM is used, default is fpm-daemon-value
|
||||
* @param string $limit_extensions
|
||||
* optional limitation of php-file-extensions if FPM is used, default is fpm-daemon-value
|
||||
*
|
||||
* @access admin
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
if ($this->isAdmin() && $this->getUserDetail('change_serversettings') == 1) {
|
||||
|
||||
// required parameter
|
||||
$description = $this->getParam('description');
|
||||
$phpsettings = $this->getParam('phpsettings');
|
||||
|
||||
if (Settings::Get('system.mod_fcgid') == 1) {
|
||||
$binary = $this->getParam('binary');
|
||||
$fpm_config_id = 1;
|
||||
} elseif (Settings::Get('phpfpm.enabled') == 1) {
|
||||
$fpm_config_id = intval($this->getParam('fpmconfig'));
|
||||
} else {
|
||||
$fpm_config_id = 1;
|
||||
}
|
||||
|
||||
// parameters
|
||||
$file_extensions = $this->getParam('file_extensions', true, 'php');
|
||||
$mod_fcgid_starter = $this->getParam('mod_fcgid_starter', true, - 1);
|
||||
$mod_fcgid_maxrequests = $this->getParam('mod_fcgid_maxrequests', true, - 1);
|
||||
$mod_fcgid_umask = $this->getParam('mod_fcgid_umask', true, "022");
|
||||
$fpm_enableslowlog = $this->getBoolParam('phpfpm_enable_slowlog', true, 0);
|
||||
$fpm_reqtermtimeout = $this->getParam('phpfpm_reqtermtimeout', true, "60s");
|
||||
$fpm_reqslowtimeout = $this->getParam('phpfpm_reqslowtimeout', true, "5s");
|
||||
$fpm_pass_authorizationheader = $this->getBoolParam('phpfpm_pass_authorizationheader', true, 0);
|
||||
|
||||
$override_fpmconfig = $this->getBoolParam('override_fpmconfig', true, 0);
|
||||
$def_fpmconfig = $this->apiCall('FpmDaemons.get', array(
|
||||
'id' => $fpm_config_id
|
||||
));
|
||||
$pmanager = $this->getParam('pm', true, $def_fpmconfig['pm']);
|
||||
$max_children = $this->getParam('max_children', true, $def_fpmconfig['max_children']);
|
||||
$start_servers = $this->getParam('start_servers', true, $def_fpmconfig['start_servers']);
|
||||
$min_spare_servers = $this->getParam('min_spare_servers', true, $def_fpmconfig['min_spare_servers']);
|
||||
$max_spare_servers = $this->getParam('max_spare_servers', true, $def_fpmconfig['max_spare_servers']);
|
||||
$max_requests = $this->getParam('max_requests', true, $def_fpmconfig['max_requests']);
|
||||
$idle_timeout = $this->getParam('idle_timeout', true, $def_fpmconfig['idle_timeout']);
|
||||
$limit_extensions = $this->getParam('limit_extensions', true, $def_fpmconfig['limit_extensions']);
|
||||
|
||||
// validation
|
||||
$description = validate($description, 'description', '', '', array(), true);
|
||||
$phpsettings = validate(str_replace("\r\n", "\n", $phpsettings), 'phpsettings', '/^[^\0]*$/', '', array(), true);
|
||||
if (Settings::Get('system.mod_fcgid') == 1) {
|
||||
$binary = makeCorrectFile(validate($binary, 'binary', '', '', array(), true));
|
||||
$file_extensions = validate($file_extensions, 'file_extensions', '/^[a-zA-Z0-9\s]*$/', '', array(), true);
|
||||
$mod_fcgid_starter = validate($mod_fcgid_starter, 'mod_fcgid_starter', '/^[0-9]*$/', '', array(
|
||||
'-1',
|
||||
''
|
||||
), true);
|
||||
$mod_fcgid_maxrequests = validate($mod_fcgid_maxrequests, 'mod_fcgid_maxrequests', '/^[0-9]*$/', '', array(
|
||||
'-1',
|
||||
''
|
||||
), true);
|
||||
$mod_fcgid_umask = validate($mod_fcgid_umask, 'mod_fcgid_umask', '/^[0-9]*$/', '', array(), true);
|
||||
// disable fpm stuff
|
||||
$fpm_config_id = 1;
|
||||
$fpm_enableslowlog = 0;
|
||||
$fpm_reqtermtimeout = 0;
|
||||
$fpm_reqslowtimeout = 0;
|
||||
$fpm_pass_authorizationheader = 0;
|
||||
$override_fpmconfig = 0;
|
||||
} elseif (Settings::Get('phpfpm.enabled') == 1) {
|
||||
$fpm_reqtermtimeout = validate($fpm_reqtermtimeout, 'phpfpm_reqtermtimeout', '/^([0-9]+)(|s|m|h|d)$/', '', array(), true);
|
||||
$fpm_reqslowtimeout = validate($fpm_reqslowtimeout, 'phpfpm_reqslowtimeout', '/^([0-9]+)(|s|m|h|d)$/', '', array(), true);
|
||||
if (! in_array($pmanager, array(
|
||||
'static',
|
||||
'dynamic',
|
||||
'ondemand'
|
||||
))) {
|
||||
throw new ErrorException("Unknown process manager", 406);
|
||||
}
|
||||
if (empty($limit_extensions)) {
|
||||
$limit_extensions = '.php';
|
||||
}
|
||||
$limit_extensions = validate($limit_extensions, 'limit_extensions', '/^(\.[a-z]([a-z0-9]+)\ ?)+$/', '', array(), true);
|
||||
|
||||
// disable fcgid stuff
|
||||
$binary = '/usr/bin/php-cgi';
|
||||
$file_extensions = 'php';
|
||||
$mod_fcgid_starter = 0;
|
||||
$mod_fcgid_maxrequests = 0;
|
||||
$mod_fcgid_umask = "022";
|
||||
}
|
||||
|
||||
if (strlen($description) == 0 || strlen($description) > 50) {
|
||||
standard_error('descriptioninvalid', '', true);
|
||||
}
|
||||
|
||||
$ins_stmt = Database::prepare("
|
||||
INSERT INTO `" . TABLE_PANEL_PHPCONFIGS . "` SET
|
||||
`description` = :desc,
|
||||
`binary` = :binary,
|
||||
`file_extensions` = :fext,
|
||||
`mod_fcgid_starter` = :starter,
|
||||
`mod_fcgid_maxrequests` = :mreq,
|
||||
`mod_fcgid_umask` = :umask,
|
||||
`fpm_slowlog` = :fpmslow,
|
||||
`fpm_reqterm` = :fpmreqterm,
|
||||
`fpm_reqslow` = :fpmreqslow,
|
||||
`phpsettings` = :phpsettings,
|
||||
`fpmsettingid` = :fpmsettingid,
|
||||
`pass_authorizationheader` = :fpmpassauth,
|
||||
`override_fpmconfig` = :ofc,
|
||||
`pm` = :pm,
|
||||
`max_children` = :max_children,
|
||||
`start_servers` = :start_servers,
|
||||
`min_spare_servers` = :min_spare_servers,
|
||||
`max_spare_servers` = :max_spare_servers,
|
||||
`max_requests` = :max_requests,
|
||||
`idle_timeout` = :idle_timeout,
|
||||
`limit_extensions` = :limit_extensions
|
||||
");
|
||||
$ins_data = array(
|
||||
'desc' => $description,
|
||||
'binary' => $binary,
|
||||
'fext' => $file_extensions,
|
||||
'starter' => $mod_fcgid_starter,
|
||||
'mreq' => $mod_fcgid_maxrequests,
|
||||
'umask' => $mod_fcgid_umask,
|
||||
'fpmslow' => $fpm_enableslowlog,
|
||||
'fpmreqterm' => $fpm_reqtermtimeout,
|
||||
'fpmreqslow' => $fpm_reqslowtimeout,
|
||||
'phpsettings' => $phpsettings,
|
||||
'fpmsettingid' => $fpm_config_id,
|
||||
'fpmpassauth' => $fpm_pass_authorizationheader,
|
||||
'ofc' => $override_fpmconfig,
|
||||
'pm' => $pmanager,
|
||||
'max_children' => $max_children,
|
||||
'start_servers' => $start_servers,
|
||||
'min_spare_servers' => $min_spare_servers,
|
||||
'max_spare_servers' => $max_spare_servers,
|
||||
'max_requests' => $max_requests,
|
||||
'idle_timeout' => $idle_timeout,
|
||||
'limit_extensions' => $limit_extensions
|
||||
);
|
||||
Database::pexecute($ins_stmt, $ins_data, true, true);
|
||||
$ins_data['id'] = Database::lastInsertId();
|
||||
|
||||
inserttask('1');
|
||||
$this->logger()->logAction(ADM_ACTION, LOG_INFO, "[API] php setting with description '" . $description . "' has been created by '" . $this->getUserDetail('loginname') . "'");
|
||||
|
||||
$result = $this->apiCall('PhpSettings.get', array(
|
||||
'id' => $ins_data['id']
|
||||
));
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
throw new Exception("Not allowed to execute given command.", 403);
|
||||
}
|
||||
|
||||
/**
|
||||
* update a php-setting entry by given id
|
||||
*
|
||||
* @param int $id
|
||||
* @param string $description
|
||||
* description of the php-config
|
||||
* @param string $phpsettings
|
||||
* the actual ini-settings
|
||||
* @param string $binary
|
||||
* optional the binary to php-cgi if FCGID is used
|
||||
* @param string $file_extensions
|
||||
* optional allowed php-file-extensions if FCGID is used, default is 'php'
|
||||
* @param int $mod_fcgid_starter
|
||||
* optional number of fcgid-starters if FCGID is used, default is -1
|
||||
* @param int $mod_fcgid_maxrequests
|
||||
* optional number of fcgid-maxrequests if FCGID is used, default is -1
|
||||
* @param string $mod_fcgid_umask
|
||||
* optional umask if FCGID is used, default is '022'
|
||||
* @param int $fpmconfig
|
||||
* optional id of the fpm-daemon-config if FPM is used
|
||||
* @param bool $phpfpm_enable_slowlog
|
||||
* optional whether to write a slowlog or not if FPM is used, default is 0 (false)
|
||||
* @param string $phpfpm_reqtermtimeout
|
||||
* optional request terminate timeout if FPM is used, default is '60s'
|
||||
* @param string $phpfpm_reqslowtimeout
|
||||
* optional request slowlog timeout if FPM is used, default is '5s'
|
||||
* @param bool $phpfpm_pass_authorizationheader
|
||||
* optional whether to pass authorization header to webserver if FPM is used, default is 0 (false)
|
||||
* @param bool $override_fpmconfig
|
||||
* optional whether to override fpm-daemon-config value for the following settings if FPM is used, default is 0 (false)
|
||||
* @param string $pm
|
||||
* optional process-manager to use if FPM is used (allowed values are 'static', 'dynamic' and 'ondemand'), default is fpm-daemon-value
|
||||
* @param int $max_children
|
||||
* optional number of max children if FPM is used, default is the fpm-daemon-value
|
||||
* @param int $start_server
|
||||
* optional number of servers to start if FPM is used, default is fpm-daemon-value
|
||||
* @param int $min_spare_servers
|
||||
* optional number of minimum spare servers if FPM is used, default is fpm-daemon-value
|
||||
* @param int $max_spare_servers
|
||||
* optional number of maximum spare servers if FPM is used, default is fpm-daemon-value
|
||||
* @param int $max_requests
|
||||
* optional number of maximum requests if FPM is used, default is fpm-daemon-value
|
||||
* @param int $idle_timeout
|
||||
* optional number of seconds for idle-timeout if FPM is used, default is fpm-daemon-value
|
||||
* @param string $limit_extensions
|
||||
* optional limitation of php-file-extensions if FPM is used, default is fpm-daemon-value
|
||||
*
|
||||
* @access admin
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function update()
|
||||
{
|
||||
if ($this->isAdmin() && $this->getUserDetail('change_serversettings') == 1) {
|
||||
|
||||
// required parameter
|
||||
$id = $this->getParam('id');
|
||||
|
||||
$result = $this->apiCall('PhpSettings.get', array(
|
||||
'id' => $id
|
||||
));
|
||||
|
||||
// parameters
|
||||
$description = $this->getParam('description', true, $result['description']);
|
||||
$phpsettings = $this->getParam('phpsettings', true, $result['phpsettings']);
|
||||
$binary = $this->getParam('binary', true, $result['binary']);
|
||||
$fpm_config_id = intval($this->getParam('fpmconfig', true, $result['fpmsettingid']));
|
||||
$file_extensions = $this->getParam('file_extensions', true, $result['file_extensions']);
|
||||
$mod_fcgid_starter = $this->getParam('mod_fcgid_starter', true, $result['mod_fcgid_starter']);
|
||||
$mod_fcgid_maxrequests = $this->getParam('mod_fcgid_maxrequests', true, $result['mod_fcgid_maxrequests']);
|
||||
$mod_fcgid_umask = $this->getParam('mod_fcgid_umask', true, $result['mod_fcgid_umask']);
|
||||
$fpm_enableslowlog = $this->getBoolParam('phpfpm_enable_slowlog', true, $result['fpm_slowlog']);
|
||||
$fpm_reqtermtimeout = $this->getParam('phpfpm_reqtermtimeout', true, $result['fpm_reqterm']);
|
||||
$fpm_reqslowtimeout = $this->getParam('phpfpm_reqslowtimeout', true, $result['fpm_reqslow']);
|
||||
$fpm_pass_authorizationheader = $this->getBoolParam('phpfpm_pass_authorizationheader', true, $result['pass_authorizationheader']);
|
||||
$override_fpmconfig = $this->getBoolParam('override_fpmconfig', true, $result['override_fpmconfig']);
|
||||
$pmanager = $this->getParam('pm', true, $result['pm']);
|
||||
$max_children = $this->getParam('max_children', true, $result['max_children']);
|
||||
$start_servers = $this->getParam('start_servers', true, $result['start_servers']);
|
||||
$min_spare_servers = $this->getParam('min_spare_servers', true, $result['min_spare_servers']);
|
||||
$max_spare_servers = $this->getParam('max_spare_servers', true, $result['max_spare_servers']);
|
||||
$max_requests = $this->getParam('max_requests', true, $result['max_requests']);
|
||||
$idle_timeout = $this->getParam('idle_timeout', true, $result['idle_timeout']);
|
||||
$limit_extensions = $this->getParam('limit_extensions', true, $result['limit_extensions']);
|
||||
|
||||
// validation
|
||||
$description = validate($description, 'description', '', '', array(), true);
|
||||
$phpsettings = validate(str_replace("\r\n", "\n", $phpsettings), 'phpsettings', '/^[^\0]*$/', '', array(), true);
|
||||
if (Settings::Get('system.mod_fcgid') == 1) {
|
||||
$binary = makeCorrectFile(validate($binary, 'binary', '', '', array(), true));
|
||||
$file_extensions = validate($file_extensions, 'file_extensions', '/^[a-zA-Z0-9\s]*$/', '', array(), true);
|
||||
$mod_fcgid_starter = validate($mod_fcgid_starter, 'mod_fcgid_starter', '/^[0-9]*$/', '', array(
|
||||
'-1',
|
||||
''
|
||||
), true);
|
||||
$mod_fcgid_maxrequests = validate($mod_fcgid_maxrequests, 'mod_fcgid_maxrequests', '/^[0-9]*$/', '', array(
|
||||
'-1',
|
||||
''
|
||||
), true);
|
||||
$mod_fcgid_umask = validate($mod_fcgid_umask, 'mod_fcgid_umask', '/^[0-9]*$/', '', array(), true);
|
||||
// disable fpm stuff
|
||||
$fpm_config_id = 1;
|
||||
$fpm_enableslowlog = 0;
|
||||
$fpm_reqtermtimeout = 0;
|
||||
$fpm_reqslowtimeout = 0;
|
||||
$fpm_pass_authorizationheader = 0;
|
||||
$override_fpmconfig = 0;
|
||||
} elseif (Settings::Get('phpfpm.enabled') == 1) {
|
||||
$fpm_reqtermtimeout = validate($fpm_reqtermtimeout, 'phpfpm_reqtermtimeout', '/^([0-9]+)(|s|m|h|d)$/', '', array(), true);
|
||||
$fpm_reqslowtimeout = validate($fpm_reqslowtimeout, 'phpfpm_reqslowtimeout', '/^([0-9]+)(|s|m|h|d)$/', '', array(), true);
|
||||
if (! in_array($pmanager, array(
|
||||
'static',
|
||||
'dynamic',
|
||||
'ondemand'
|
||||
))) {
|
||||
throw new ErrorException("Unknown process manager", 406);
|
||||
}
|
||||
if (empty($limit_extensions)) {
|
||||
$limit_extensions = '.php';
|
||||
}
|
||||
$limit_extensions = validate($limit_extensions, 'limit_extensions', '/^(\.[a-z]([a-z0-9]+)\ ?)+$/', '', array(), true);
|
||||
|
||||
// disable fcgid stuff
|
||||
$binary = '/usr/bin/php-cgi';
|
||||
$file_extensions = 'php';
|
||||
$mod_fcgid_starter = 0;
|
||||
$mod_fcgid_maxrequests = 0;
|
||||
$mod_fcgid_umask = "022";
|
||||
}
|
||||
|
||||
if (strlen($description) == 0 || strlen($description) > 50) {
|
||||
standard_error('descriptioninvalid', '', true);
|
||||
}
|
||||
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_PHPCONFIGS . "` SET
|
||||
`description` = :desc,
|
||||
`binary` = :binary,
|
||||
`file_extensions` = :fext,
|
||||
`mod_fcgid_starter` = :starter,
|
||||
`mod_fcgid_maxrequests` = :mreq,
|
||||
`mod_fcgid_umask` = :umask,
|
||||
`fpm_slowlog` = :fpmslow,
|
||||
`fpm_reqterm` = :fpmreqterm,
|
||||
`fpm_reqslow` = :fpmreqslow,
|
||||
`phpsettings` = :phpsettings,
|
||||
`fpmsettingid` = :fpmsettingid,
|
||||
`pass_authorizationheader` = :fpmpassauth,
|
||||
`override_fpmconfig` = :ofc,
|
||||
`pm` = :pm,
|
||||
`max_children` = :max_children,
|
||||
`start_servers` = :start_servers,
|
||||
`min_spare_servers` = :min_spare_servers,
|
||||
`max_spare_servers` = :max_spare_servers,
|
||||
`max_requests` = :max_requests,
|
||||
`idle_timeout` = :idle_timeout,
|
||||
`limit_extensions` = :limit_extensions
|
||||
WHERE `id` = :id
|
||||
");
|
||||
$upd_data = array(
|
||||
'desc' => $description,
|
||||
'binary' => $binary,
|
||||
'fext' => $file_extensions,
|
||||
'starter' => $mod_fcgid_starter,
|
||||
'mreq' => $mod_fcgid_maxrequests,
|
||||
'umask' => $mod_fcgid_umask,
|
||||
'fpmslow' => $fpm_enableslowlog,
|
||||
'fpmreqterm' => $fpm_reqtermtimeout,
|
||||
'fpmreqslow' => $fpm_reqslowtimeout,
|
||||
'phpsettings' => $phpsettings,
|
||||
'fpmsettingid' => $fpm_config_id,
|
||||
'fpmpassauth' => $fpm_pass_authorizationheader,
|
||||
'ofc' => $override_fpmconfig,
|
||||
'pm' => $pmanager,
|
||||
'max_children' => $max_children,
|
||||
'start_servers' => $start_servers,
|
||||
'min_spare_servers' => $min_spare_servers,
|
||||
'max_spare_servers' => $max_spare_servers,
|
||||
'max_requests' => $max_requests,
|
||||
'idle_timeout' => $idle_timeout,
|
||||
'limit_extensions' => $limit_extensions,
|
||||
'id' => $id
|
||||
);
|
||||
Database::pexecute($upd_stmt, $upd_data, true, true);
|
||||
|
||||
inserttask('1');
|
||||
$this->logger()->logAction(ADM_ACTION, LOG_INFO, "[API] php setting with description '" . $description . "' has been updated by '" . $this->getUserDetail('loginname') . "'");
|
||||
|
||||
$result = $this->apiCall('PhpSettings.get', array(
|
||||
'id' => $id
|
||||
));
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
throw new Exception("Not allowed to execute given command.", 403);
|
||||
}
|
||||
|
||||
/**
|
||||
* delete a php-setting entry by id
|
||||
*
|
||||
* @param int $id
|
||||
* php-settings-id
|
||||
*
|
||||
* @access admin
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
if ($this->isAdmin() && $this->getUserDetail('change_serversettings') == 1) {
|
||||
$id = $this->getParam('id');
|
||||
|
||||
$result = $this->apiCall('PhpSettings.get', array(
|
||||
'id' => $id
|
||||
));
|
||||
|
||||
if ((Settings::Get('system.mod_fcgid') == '1' && Settings::Get('system.mod_fcgid_defaultini_ownvhost') == $id) || (Settings::Get('phpfpm.enabled') == '1' && Settings::Get('phpfpm.vhost_defaultini') == $id)) {
|
||||
standard_error('cannotdeletehostnamephpconfig', '', true);
|
||||
}
|
||||
|
||||
if ((Settings::Get('system.mod_fcgid') == '1' && Settings::Get('system.mod_fcgid_defaultini') == $id) || (Settings::Get('phpfpm.enabled') == '1' && Settings::Get('phpfpm.defaultini') == $id)) {
|
||||
standard_error('cannotdeletedefaultphpconfig', '', true);
|
||||
}
|
||||
|
||||
// set php-config to default for all domains using the
|
||||
// config that is to be deleted
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_DOMAINS . "` SET
|
||||
`phpsettingid` = '1' WHERE `phpsettingid` = :id
|
||||
");
|
||||
Database::pexecute($upd_stmt, array(
|
||||
'id' => $id
|
||||
), true, true);
|
||||
|
||||
$del_stmt = Database::prepare("
|
||||
DELETE FROM `" . TABLE_PANEL_PHPCONFIGS . "` WHERE `id` = :id
|
||||
");
|
||||
Database::pexecute($del_stmt, array(
|
||||
'id' => $id
|
||||
), true, true);
|
||||
|
||||
inserttask('1');
|
||||
$this->logger()->logAction(ADM_ACTION, LOG_INFO, "[API] php setting '" . $result['description'] . "' has been deleted by '" . $this->getUserDetail('loginname') . "'");
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
throw new Exception("Not allowed to execute given command.", 403);
|
||||
}
|
||||
}
|
||||
@@ -1,880 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package API
|
||||
* @since 0.10.0
|
||||
*
|
||||
*/
|
||||
class SubDomains extends ApiCommand implements ResourceEntity
|
||||
{
|
||||
|
||||
/**
|
||||
* add a new subdomain
|
||||
*
|
||||
* @param string $subdomain
|
||||
* part before domain.tld to create as subdomain
|
||||
* @param string $domain
|
||||
* domainname of main-domain
|
||||
* @param int $alias
|
||||
* optional, domain-id of a domain that the new domain should be an alias of
|
||||
* @param string $path
|
||||
* optional, destination path relative to the customers-homedir, default is customers-homedir
|
||||
* @param string $url
|
||||
* optional, overwrites path value with an URL to generate a redirect, alternatively use the path parameter also for URLs
|
||||
* @param int $openbasedir_path
|
||||
* optional, either 0 for customers-homedir or 1 for domains-docroot
|
||||
* @param int $phpsettingid
|
||||
* optional, php-settings-id, if empty the $domain value is used
|
||||
* @param int $redirectcode
|
||||
* optional, redirect-code-id from TABLE_PANEL_REDIRECTCODES
|
||||
* @param bool $ssl_redirect
|
||||
* optional, whether to generate a https-redirect or not, default false; requires SSL to be enabled
|
||||
* @param bool $letsencrypt
|
||||
* optional, whether to generate a Let's Encrypt certificate for this domain, default false; requires SSL to be enabled
|
||||
* @param int $hsts_maxage
|
||||
* optional max-age value for HSTS header, default 0
|
||||
* @param bool $hsts_sub
|
||||
* optional whether or not to add subdomains to the HSTS header, default 0
|
||||
* @param bool $hsts_preload
|
||||
* optional whether or not to preload HSTS header value, default 0
|
||||
* @param int $customerid
|
||||
* required when called as admin, not needed when called as customer
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
if ($this->getUserDetail('subdomains_used') < $this->getUserDetail('subdomains') || $this->getUserDetail('subdomains') == '-1') {
|
||||
// parameters
|
||||
$subdomain = $this->getParam('subdomain');
|
||||
$domain = $this->getParam('domain');
|
||||
|
||||
// optional parameters
|
||||
$aliasdomain = $this->getParam('alias', true, 0);
|
||||
$path = $this->getParam('path', true, '');
|
||||
$url = $this->getParam('url', true, '');
|
||||
$openbasedir_path = $this->getParam('openbasedir_path', true, 1);
|
||||
$phpsettingid = $this->getParam('phpsettingid', true, 0);
|
||||
$redirectcode = $this->getParam('redirectcode', true, Settings::Get('customredirect.default'));
|
||||
$isemaildomain = $this->getParam('isemaildomain', true, 0);
|
||||
if (Settings::Get('system.use_ssl')) {
|
||||
$ssl_redirect = $this->getBoolParam('ssl_redirect', true, 0);
|
||||
$letsencrypt = $this->getBoolParam('letsencrypt', true, 0);
|
||||
$hsts_maxage = $this->getParam('hsts_maxage', true, 0);
|
||||
$hsts_sub = $this->getBoolParam('hsts_sub', true, 0);
|
||||
$hsts_preload = $this->getBoolParam('hsts_preload', true, 0);
|
||||
} else {
|
||||
$ssl_redirect = 0;
|
||||
$letsencrypt = 0;
|
||||
$hsts_maxage = 0;
|
||||
$hsts_sub = 0;
|
||||
$hsts_preload = 0;
|
||||
}
|
||||
|
||||
// get needed customer info to reduce the subdomain-usage-counter by one
|
||||
$customer = $this->getCustomerData('subdomains');
|
||||
|
||||
// validation
|
||||
if (substr($subdomain, 0, 4) == 'xn--') {
|
||||
standard_error('domain_nopunycode', '', true);
|
||||
}
|
||||
|
||||
$idna_convert = new idna_convert_wrapper();
|
||||
$subdomain = $idna_convert->encode(preg_replace(array(
|
||||
'/\:(\d)+$/',
|
||||
'/^https?\:\/\//'
|
||||
), '', validate($subdomain, 'subdomain', '', 'subdomainiswrong', array(), true)));
|
||||
|
||||
// merge the two parts together
|
||||
$completedomain = $subdomain . '.' . $domain;
|
||||
|
||||
if (Settings::Get('system.validate_domain') && ! validateDomain($completedomain)) {
|
||||
standard_error(array(
|
||||
'stringiswrong',
|
||||
'mydomain'
|
||||
), '', true);
|
||||
}
|
||||
if ($completedomain == Settings::Get('system.hostname')) {
|
||||
standard_error('admin_domain_emailsystemhostname', '', true);
|
||||
}
|
||||
|
||||
// check whether the domain already exists
|
||||
$completedomain_stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_PANEL_DOMAINS . "`
|
||||
WHERE `domain` = :domain
|
||||
AND `customerid` = :customerid
|
||||
AND `email_only` = '0'
|
||||
AND `caneditdomain` = '1'
|
||||
");
|
||||
$completedomain_check = Database::pexecute_first($completedomain_stmt, array(
|
||||
"domain" => $completedomain,
|
||||
"customerid" => $customer['customerid']
|
||||
), true, true);
|
||||
|
||||
if ($completedomain_check) {
|
||||
// no exception so far - domain exists
|
||||
standard_error('domainexistalready', $completedomain, true);
|
||||
}
|
||||
|
||||
// alias domain checked?
|
||||
if ($aliasdomain != 0) {
|
||||
// also check ip/port combination to be the same, #176
|
||||
$aliasdomain_stmt = Database::prepare("
|
||||
SELECT `d`.`id` FROM `" . TABLE_PANEL_DOMAINS . "` `d` , `" . TABLE_PANEL_CUSTOMERS . "` `c` , `" . TABLE_DOMAINTOIP . "` `dip`
|
||||
WHERE `d`.`aliasdomain` IS NULL
|
||||
AND `d`.`id` = :id
|
||||
AND `c`.`standardsubdomain` <> `d`.`id`
|
||||
AND `d`.`customerid` = :customerid
|
||||
AND `c`.`customerid` = `d`.`customerid`
|
||||
AND `d`.`id` = `dip`.`id_domain`
|
||||
AND `dip`.`id_ipandports`
|
||||
IN (SELECT `id_ipandports` FROM `" . TABLE_DOMAINTOIP . "` WHERE `id_domain` = :id )
|
||||
GROUP BY `d`.`domain`
|
||||
ORDER BY `d`.`domain` ASC
|
||||
");
|
||||
$aliasdomain_check = Database::pexecute_first($aliasdomain_stmt, array(
|
||||
"id" => $aliasdomain,
|
||||
"customerid" => $customer['customerid']
|
||||
), true, true);
|
||||
if ($aliasdomain_check['id'] != $aliasdomain) {
|
||||
standard_error('domainisaliasorothercustomer', '', true);
|
||||
}
|
||||
triggerLetsEncryptCSRForAliasDestinationDomain($aliasdomain, $this->logger());
|
||||
}
|
||||
|
||||
// validate / correct path/url of domain
|
||||
$_doredirect = false;
|
||||
$path = $this->validateDomainDocumentRoot($path, $url, $customer, $completedomain, $_doredirect);
|
||||
|
||||
if ($openbasedir_path != 1) {
|
||||
$openbasedir_path = 0;
|
||||
}
|
||||
|
||||
// get main domain for various checks
|
||||
$domain_stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_PANEL_DOMAINS . "`
|
||||
WHERE `domain` = :domain
|
||||
AND `customerid` = :customerid
|
||||
AND `parentdomainid` = '0'
|
||||
AND `email_only` = '0'
|
||||
AND `caneditdomain` = '1'
|
||||
");
|
||||
$domain_check = Database::pexecute_first($domain_stmt, array(
|
||||
"domain" => $domain,
|
||||
"customerid" => $customer['customerid']
|
||||
), true, true);
|
||||
|
||||
if (! $domain_check) {
|
||||
// the given main-domain
|
||||
standard_error('maindomainnonexist', $domain, true);
|
||||
} elseif ($subdomain == 'www' && $domain_check['wwwserveralias'] == '1') {
|
||||
// you cannot add 'www' as subdomain when the maindomain generates a www-alias
|
||||
standard_error('wwwnotallowed', '', true);
|
||||
} elseif (strtolower($completedomain_check['domain']) == strtolower($completedomain)) {
|
||||
// the domain does already exist as main-domain
|
||||
standard_error('domainexistalready', $completedomain, true);
|
||||
}
|
||||
|
||||
// if allowed, check for 'is email domain'-flag
|
||||
if ($domain_check['subcanemaildomain'] == '1' || $domain_check['subcanemaildomain'] == '2') {
|
||||
$isemaildomain = intval($isemaildomain);
|
||||
} else {
|
||||
$isemaildomain = $domain_check['subcanemaildomain'] == '3' ? 1 : 0;
|
||||
}
|
||||
|
||||
if ($ssl_redirect != 0) {
|
||||
// a ssl-redirect only works if there actually is a
|
||||
// ssl ip/port assigned to the domain
|
||||
if (domainHasSslIpPort($domain_check['id']) == true) {
|
||||
$ssl_redirect = '1';
|
||||
$_doredirect = true;
|
||||
} else {
|
||||
standard_error('sslredirectonlypossiblewithsslipport', '', true);
|
||||
}
|
||||
}
|
||||
|
||||
if ($letsencrypt != 0) {
|
||||
// let's encrypt only works if there actually is a
|
||||
// ssl ip/port assigned to the domain
|
||||
if (domainHasSslIpPort($domain_check['id']) == true) {
|
||||
$letsencrypt = '1';
|
||||
} else {
|
||||
standard_error('letsencryptonlypossiblewithsslipport', '', true);
|
||||
}
|
||||
}
|
||||
|
||||
// Temporarily deactivate ssl_redirect until Let's Encrypt certificate was generated
|
||||
if ($ssl_redirect > 0 && $letsencrypt == 1) {
|
||||
$ssl_redirect = 2;
|
||||
}
|
||||
|
||||
// get the phpsettingid from parentdomain, #107
|
||||
$phpsid_stmt = Database::prepare("
|
||||
SELECT `phpsettingid` FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `id` = :id
|
||||
");
|
||||
$phpsid_result = Database::pexecute_first($phpsid_stmt, array(
|
||||
"id" => $domain_check['id']
|
||||
), true, true);
|
||||
|
||||
if (! isset($phpsid_result['phpsettingid']) || (int) $phpsid_result['phpsettingid'] <= 0) {
|
||||
// assign default config
|
||||
$phpsid_result['phpsettingid'] = 1;
|
||||
}
|
||||
// check whether the customer has chosen its own php-config
|
||||
if ($phpsettingid > 0 && $phpsettingid != $phpsid_result['phpsettingid']) {
|
||||
$phpsid_result['phpsettingid'] = intval($phpsettingid);
|
||||
}
|
||||
|
||||
// acutall insert domain
|
||||
$stmt = Database::prepare("
|
||||
INSERT INTO `" . TABLE_PANEL_DOMAINS . "` SET
|
||||
`customerid` = :customerid,
|
||||
`adminid` = :adminid,
|
||||
`domain` = :domain,
|
||||
`documentroot` = :documentroot,
|
||||
`aliasdomain` = :aliasdomain,
|
||||
`parentdomainid` = :parentdomainid,
|
||||
`wwwserveralias` = :wwwserveralias,
|
||||
`isemaildomain` = :isemaildomain,
|
||||
`iswildcarddomain` = :iswildcarddomain,
|
||||
`phpenabled` = :phpenabled,
|
||||
`openbasedir` = :openbasedir,
|
||||
`openbasedir_path` = :openbasedir_path,
|
||||
`speciallogfile` = :speciallogfile,
|
||||
`specialsettings` = :specialsettings,
|
||||
`ssl_redirect` = :ssl_redirect,
|
||||
`phpsettingid` = :phpsettingid,
|
||||
`letsencrypt` = :letsencrypt,
|
||||
`hsts` = :hsts,
|
||||
`hsts_sub` = :hsts_sub,
|
||||
`hsts_preload` = :hsts_preload
|
||||
");
|
||||
$params = array(
|
||||
"customerid" => $customer['customerid'],
|
||||
"adminid" => $customer['adminid'],
|
||||
"domain" => $completedomain,
|
||||
"documentroot" => $path,
|
||||
"aliasdomain" => $aliasdomain != 0 ? $aliasdomain : null,
|
||||
"parentdomainid" => $domain_check['id'],
|
||||
"wwwserveralias" => $domain_check['wwwserveralias'] == '1' ? '1' : '0',
|
||||
"iswildcarddomain" => $domain_check['iswildcarddomain'] == '1' ? '1' : '0',
|
||||
"isemaildomain" => $isemaildomain,
|
||||
"openbasedir" => $domain_check['openbasedir'],
|
||||
"openbasedir_path" => $openbasedir_path,
|
||||
"phpenabled" => $domain_check['phpenabled'],
|
||||
"speciallogfile" => $domain_check['speciallogfile'],
|
||||
"specialsettings" => $domain_check['specialsettings'],
|
||||
"ssl_redirect" => $ssl_redirect,
|
||||
"phpsettingid" => $phpsid_result['phpsettingid'],
|
||||
"letsencrypt" => $letsencrypt,
|
||||
"hsts" => $hsts_maxage,
|
||||
"hsts_sub" => $hsts_sub,
|
||||
"hsts_preload" => $hsts_preload
|
||||
);
|
||||
Database::pexecute($stmt, $params, true, true);
|
||||
$subdomain_id = Database::lastInsertId();
|
||||
|
||||
$stmt = Database::prepare("
|
||||
INSERT INTO `" . TABLE_DOMAINTOIP . "`
|
||||
(`id_domain`, `id_ipandports`)
|
||||
SELECT LAST_INSERT_ID(), `id_ipandports`
|
||||
FROM `" . TABLE_DOMAINTOIP . "`
|
||||
WHERE `id_domain` = :id_domain
|
||||
");
|
||||
Database::pexecute($stmt, array(
|
||||
"id_domain" => $domain_check['id']
|
||||
));
|
||||
|
||||
if ($_doredirect) {
|
||||
addRedirectToDomain($subdomain_id, $redirectcode);
|
||||
}
|
||||
|
||||
inserttask('1');
|
||||
// Using nameserver, insert a task which rebuilds the server config
|
||||
inserttask('4');
|
||||
|
||||
Customers::increaseUsage($customer['customerid'], 'subdomains_used');
|
||||
Admins::increaseUsage(($this->isAdmin() ? $customer['adminid'] : $this->getUserDetail('adminid')), 'subdomains_used');
|
||||
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_INFO, "[API] added subdomain '" . $completedomain . "'");
|
||||
|
||||
$result = $this->apiCall('SubDomains.get', array(
|
||||
'id' => $subdomain_id
|
||||
));
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
throw new Exception("No more resources available", 406);
|
||||
}
|
||||
|
||||
/**
|
||||
* return a subdomain entry by either id or domainname
|
||||
*
|
||||
* @param int $id
|
||||
* optional, the domain-id
|
||||
* @param string $domainname
|
||||
* optional, the domainname
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
$id = $this->getParam('id', true, 0);
|
||||
$dn_optional = ($id <= 0 ? false : true);
|
||||
$domainname = $this->getParam('domainname', $dn_optional, '');
|
||||
|
||||
// convert possible idn domain to punycode
|
||||
if (substr($domainname, 0, 4) != 'xn--') {
|
||||
$idna_convert = new idna_convert_wrapper();
|
||||
$domainname = $idna_convert->encode($domainname);
|
||||
}
|
||||
|
||||
if ($this->isAdmin()) {
|
||||
if ($this->getUserDetail('customers_see_all') != 1) {
|
||||
// if it's a reseller or an admin who cannot see all customers, we need to check
|
||||
// whether the database belongs to one of his customers
|
||||
$_custom_list_result = $this->apiCall('Customers.listing');
|
||||
$custom_list_result = $_custom_list_result['list'];
|
||||
$customer_ids = array();
|
||||
foreach ($custom_list_result as $customer) {
|
||||
$customer_ids[] = $customer['customerid'];
|
||||
}
|
||||
if (count($customer_ids) > 0) {
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT d.*, pd.`subcanemaildomain`, pd.`isbinddomain` as subisbinddomain
|
||||
FROM `" . TABLE_PANEL_DOMAINS . "` d, `" . TABLE_PANEL_DOMAINS . "` pd
|
||||
WHERE " . ($id > 0 ? "d.`id` = :iddn" : "d.`domain` = :iddn") . " AND d.`customerid` IN (" . implode(", ", $customer_ids) . ")
|
||||
AND ((d.`parentdomainid`!='0' AND pd.`id` = d.`parentdomainid`) OR (d.`parentdomainid`='0' AND pd.`id` = d.`id`))
|
||||
");
|
||||
$params = array(
|
||||
'iddn' => ($id <= 0 ? $domainname : $id)
|
||||
);
|
||||
} else {
|
||||
throw new Exception("You do not have any customers yet", 406);
|
||||
}
|
||||
} else {
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT d.*, pd.`subcanemaildomain`, pd.`isbinddomain` as subisbinddomain
|
||||
FROM `" . TABLE_PANEL_DOMAINS . "` d, `" . TABLE_PANEL_DOMAINS . "` pd
|
||||
WHERE " . ($id > 0 ? "d.`id` = :iddn" : "d.`domain` = :iddn") . "
|
||||
AND ((d.`parentdomainid`!='0' AND pd.`id` = d.`parentdomainid`) OR (d.`parentdomainid`='0' AND pd.`id` = d.`id`))
|
||||
");
|
||||
$params = array(
|
||||
'iddn' => ($id <= 0 ? $domainname : $id)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (Settings::IsInList('panel.customer_hide_options', 'domains')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT d.*, pd.`subcanemaildomain`, pd.`isbinddomain` as subisbinddomain
|
||||
FROM `" . TABLE_PANEL_DOMAINS . "` d, `" . TABLE_PANEL_DOMAINS . "` pd
|
||||
WHERE d.`customerid`= :customerid AND " . ($id > 0 ? "d.`id` = :iddn" : "d.`domain` = :iddn") . "
|
||||
AND ((d.`parentdomainid`!='0' AND pd.`id` = d.`parentdomainid`) OR (d.`parentdomainid`='0' AND pd.`id` = d.`id`))
|
||||
");
|
||||
$params = array(
|
||||
'customerid' => $this->getUserDetail('customerid'),
|
||||
'iddn' => ($id <= 0 ? $domainname : $id)
|
||||
);
|
||||
}
|
||||
$result = Database::pexecute_first($result_stmt, $params, true, true);
|
||||
if ($result) {
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_NOTICE, "[API] get subdomain '" . $result['domain'] . "'");
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
$key = ($id > 0 ? "id #" . $id : "domainname '" . $domainname . "'");
|
||||
throw new Exception("Subdomain with " . $key . " could not be found", 404);
|
||||
}
|
||||
|
||||
/**
|
||||
* update subdomain entry by either id or domainname
|
||||
*
|
||||
* @param int $id
|
||||
* optional, the domain-id
|
||||
* @param string $domainname
|
||||
* optional, the domainname
|
||||
* @param int $alias
|
||||
* optional, domain-id of a domain that the new domain should be an alias of
|
||||
* @param string $path
|
||||
* optional, destination path relative to the customers-homedir, default is customers-homedir
|
||||
* @param string $url
|
||||
* optional, overwrites path value with an URL to generate a redirect, alternatively use the path parameter also for URLs
|
||||
* @param int $selectserveralias
|
||||
* optional, 0 = wildcard, 1 = www-alias, 2 = none
|
||||
* @param bool $isemaildomain
|
||||
* optional
|
||||
* @param int $openbasedir_path
|
||||
* optional, either 0 for customers-homedir or 1 for domains-docroot
|
||||
* @param int $phpsettingid
|
||||
* optional, php-settings-id, if empty the $domain value is used
|
||||
* @param int $redirectcode
|
||||
* optional, redirect-code-id from TABLE_PANEL_REDIRECTCODES
|
||||
* @param bool $ssl_redirect
|
||||
* optional, whether to generate a https-redirect or not, default false; requires SSL to be enabled
|
||||
* @param bool $letsencrypt
|
||||
* optional, whether to generate a Let's Encrypt certificate for this domain, default false; requires SSL to be enabled
|
||||
* @param int $hsts_maxage
|
||||
* optional max-age value for HSTS header
|
||||
* @param bool $hsts_sub
|
||||
* optional whether or not to add subdomains to the HSTS header
|
||||
* @param bool $hsts_preload
|
||||
* optional whether or not to preload HSTS header value
|
||||
* @param int $customerid
|
||||
* required when called as admin, not needed when called as customer
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function update()
|
||||
{
|
||||
$id = $this->getParam('id', true, 0);
|
||||
$dn_optional = ($id <= 0 ? false : true);
|
||||
$domainname = $this->getParam('domainname', $dn_optional, '');
|
||||
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'domains')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
|
||||
$result = $this->apiCall('SubDomains.get', array(
|
||||
'id' => $id,
|
||||
'domainname' => $domainname
|
||||
));
|
||||
$id = $result['id'];
|
||||
|
||||
// parameters
|
||||
$aliasdomain = $this->getParam('alias', true, 0);
|
||||
$path = $this->getParam('path', true, $result['documentroot']);
|
||||
$url = $this->getParam('url', true, '');
|
||||
// default: 0 = wildcard, 1 = www-alias, 2 = none
|
||||
$_serveraliasdefault = $result['iswildcarddomain'] == '1' ? 0 : ($result['wwwserveralias'] == '1' ? 1 : 2);
|
||||
$selectserveralias = $this->getParam('selectserveralias', true, $_serveraliasdefault);
|
||||
$isemaildomain = $this->getBoolParam('isemaildomain', true, $result['isemaildomain']);
|
||||
$openbasedir_path = $this->getParam('openbasedir_path', true, $result['openbasedir_path']);
|
||||
$phpsettingid = $this->getParam('phpsettingid', true, $result['phpsettingid']);
|
||||
$redirectcode = $this->getParam('redirectcode', true, getDomainRedirectId($id));
|
||||
if (Settings::Get('system.use_ssl')) {
|
||||
$ssl_redirect = $this->getBoolParam('ssl_redirect', true, $result['ssl_redirect']);
|
||||
$letsencrypt = $this->getBoolParam('letsencrypt', true, $result['letsencrypt']);
|
||||
$hsts_maxage = $this->getParam('hsts_maxage', true, $result['hsts']);
|
||||
$hsts_sub = $this->getBoolParam('hsts_sub', true, $result['hsts_sub']);
|
||||
$hsts_preload = $this->getBoolParam('hsts_preload', true, $result['hsts_preload']);
|
||||
} else {
|
||||
$ssl_redirect = 0;
|
||||
$letsencrypt = 0;
|
||||
$hsts_maxage = 0;
|
||||
$hsts_sub = 0;
|
||||
$hsts_preload = 0;
|
||||
}
|
||||
|
||||
// get needed customer info to reduce the subdomain-usage-counter by one
|
||||
$customer = $this->getCustomerData();
|
||||
|
||||
$alias_stmt = Database::prepare("SELECT COUNT(`id`) AS count FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `aliasdomain`= :aliasdomain");
|
||||
$alias_check = Database::pexecute_first($alias_stmt, array(
|
||||
"aliasdomain" => $result['id']
|
||||
));
|
||||
$alias_check = $alias_check['count'];
|
||||
|
||||
// alias domain checked?
|
||||
if ($aliasdomain != 0) {
|
||||
$aliasdomain_stmt = Database::prepare("
|
||||
SELECT `id` FROM `" . TABLE_PANEL_DOMAINS . "` `d`,`" . TABLE_PANEL_CUSTOMERS . "` `c`
|
||||
WHERE `d`.`customerid`= :customerid
|
||||
AND `d`.`aliasdomain` IS NULL
|
||||
AND `d`.`id`<>`c`.`standardsubdomain`
|
||||
AND `c`.`customerid`= :customerid
|
||||
AND `d`.`id`= :id
|
||||
");
|
||||
$aliasdomain_check = Database::pexecute_first($aliasdomain_stmt, array(
|
||||
"id" => $aliasdomain,
|
||||
"customerid" => $customer['customerid']
|
||||
), true, true);
|
||||
if ($aliasdomain_check['id'] != $aliasdomain) {
|
||||
standard_error('domainisaliasorothercustomer', '', true);
|
||||
}
|
||||
triggerLetsEncryptCSRForAliasDestinationDomain($aliasdomain, $this->logger());
|
||||
}
|
||||
|
||||
// validate / correct path/url of domain
|
||||
$_doredirect = false;
|
||||
$path = $this->validateDomainDocumentRoot($path, $url, $customer, $result['domain'], $_doredirect);
|
||||
|
||||
// set alias-fields according to selected alias mode
|
||||
$iswildcarddomain = ($selectserveralias == '0') ? '1' : '0';
|
||||
$wwwserveralias = ($selectserveralias == '1') ? '1' : '0';
|
||||
|
||||
// if allowed, check for 'is email domain'-flag
|
||||
if ($result['parentdomainid'] != '0' && ($result['subcanemaildomain'] == '1' || $result['subcanemaildomain'] == '2') && $isemaildomain != $result['isemaildomain']) {
|
||||
$isemaildomain = intval($isemaildomain);
|
||||
} elseif ($result['parentdomainid'] != '0') {
|
||||
$isemaildomain = $result['subcanemaildomain'] == '3' ? 1 : 0;
|
||||
}
|
||||
|
||||
// check changes of openbasedir-path variable
|
||||
if ($openbasedir_path != 1) {
|
||||
$openbasedir_path = 0;
|
||||
}
|
||||
|
||||
if ($ssl_redirect != 0) {
|
||||
// a ssl-redirect only works if there actually is a
|
||||
// ssl ip/port assigned to the domain
|
||||
if (domainHasSslIpPort($result['id']) == true) {
|
||||
$ssl_redirect = '1';
|
||||
$_doredirect = true;
|
||||
} else {
|
||||
standard_error('sslredirectonlypossiblewithsslipport', '', true);
|
||||
}
|
||||
}
|
||||
|
||||
if ($letsencrypt != 0) {
|
||||
// let's encrypt only works if there actually is a
|
||||
// ssl ip/port assigned to the domain
|
||||
if (domainHasSslIpPort($result['id']) == true) {
|
||||
$letsencrypt = '1';
|
||||
} else {
|
||||
standard_error('letsencryptonlypossiblewithsslipport', '', true);
|
||||
}
|
||||
}
|
||||
|
||||
// We can't enable let's encrypt for wildcard - domains when using acme-v1
|
||||
if ($iswildcarddomain == '1' && $letsencrypt == '1' && Settings::Get('system.leapiversion') == '1') {
|
||||
standard_error('nowildcardwithletsencrypt');
|
||||
}
|
||||
// if using acme-v2 we cannot issue wildcard-certificates
|
||||
// because they currently only support the dns-01 challenge
|
||||
if ($iswildcarddomain == '0' && $letsencrypt == '1' && Settings::Get('system.leapiversion') == '2') {
|
||||
standard_error('nowildcardwithletsencryptv2');
|
||||
}
|
||||
|
||||
// Temporarily deactivate ssl_redirect until Let's Encrypt certificate was generated
|
||||
if ($ssl_redirect > 0 && $letsencrypt == 1 && $result['letsencrypt'] != $letsencrypt) {
|
||||
$ssl_redirect = 2;
|
||||
}
|
||||
|
||||
// is-email-domain flag changed - remove mail accounts and mail-addresses
|
||||
if (($result['isemaildomain'] == '1') && $isemaildomain == '0') {
|
||||
$params = array(
|
||||
"customerid" => $customer['customerid'],
|
||||
"domainid" => $id
|
||||
);
|
||||
$stmt = Database::prepare("DELETE FROM `" . TABLE_MAIL_USERS . "` WHERE `customerid`= :customerid AND `domainid`= :domainid");
|
||||
Database::pexecute($stmt, $params, true, true);
|
||||
$stmt = Database::prepare("DELETE FROM `" . TABLE_MAIL_VIRTUAL . "` WHERE `customerid`= :customerid AND `domainid`= :domainid");
|
||||
Database::pexecute($stmt, $params, true, true);
|
||||
$idna_convert = new idna_convert_wrapper();
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_NOTICE, "[API] automatically deleted mail-table entries for '" . $idna_convert->decode($result['domain']) . "'");
|
||||
}
|
||||
|
||||
// handle redirect
|
||||
if ($_doredirect) {
|
||||
updateRedirectOfDomain($id, $redirectcode);
|
||||
}
|
||||
|
||||
if ($path != $result['documentroot'] || $isemaildomain != $result['isemaildomain'] || $wwwserveralias != $result['wwwserveralias'] || $iswildcarddomain != $result['iswildcarddomain'] || $aliasdomain != $result['aliasdomain'] || $openbasedir_path != $result['openbasedir_path'] || $ssl_redirect != $result['ssl_redirect'] || $letsencrypt != $result['letsencrypt'] || $hsts_maxage != $result['hsts'] || $hsts_sub != $result['hsts_sub'] || $hsts_preload != $result['hsts_preload'] || $phpsettingid != $result['phpsettingid']) {
|
||||
$stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_DOMAINS . "` SET
|
||||
`documentroot`= :documentroot,
|
||||
`isemaildomain`= :isemaildomain,
|
||||
`wwwserveralias`= :wwwserveralias,
|
||||
`iswildcarddomain`= :iswildcarddomain,
|
||||
`aliasdomain`= :aliasdomain,
|
||||
`openbasedir_path`= :openbasedir_path,
|
||||
`ssl_redirect`= :ssl_redirect,
|
||||
`letsencrypt`= :letsencrypt,
|
||||
`hsts` = :hsts,
|
||||
`hsts_sub` = :hsts_sub,
|
||||
`hsts_preload` = :hsts_preload,
|
||||
`phpsettingid` = :phpsettingid
|
||||
WHERE `customerid`= :customerid AND `id`= :id
|
||||
");
|
||||
$params = array(
|
||||
"documentroot" => $path,
|
||||
"isemaildomain" => $isemaildomain,
|
||||
"wwwserveralias" => $wwwserveralias,
|
||||
"iswildcarddomain" => $iswildcarddomain,
|
||||
"aliasdomain" => ($aliasdomain != 0 && $alias_check == 0) ? $aliasdomain : null,
|
||||
"openbasedir_path" => $openbasedir_path,
|
||||
"ssl_redirect" => $ssl_redirect,
|
||||
"letsencrypt" => $letsencrypt,
|
||||
"hsts" => $hsts_maxage,
|
||||
"hsts_sub" => $hsts_sub,
|
||||
"hsts_preload" => $hsts_preload,
|
||||
"phpsettingid" => $phpsettingid,
|
||||
"customerid" => $customer['customerid'],
|
||||
"id" => $id
|
||||
);
|
||||
Database::pexecute($stmt, $params, true, true);
|
||||
|
||||
if ($result['aliasdomain'] != $aliasdomain) {
|
||||
// trigger when domain id for alias destination has changed: both for old and new destination
|
||||
triggerLetsEncryptCSRForAliasDestinationDomain($result['aliasdomain'], $this->logger());
|
||||
triggerLetsEncryptCSRForAliasDestinationDomain($aliasdomain, $this->logger());
|
||||
} elseif ($result['wwwserveralias'] != $wwwserveralias || $result['letsencrypt'] != $letsencrypt) {
|
||||
// or when wwwserveralias or letsencrypt was changed
|
||||
triggerLetsEncryptCSRForAliasDestinationDomain($aliasdomain, $this->logger());
|
||||
}
|
||||
|
||||
// check whether LE has been disabled, so we remove the certificate
|
||||
if ($letsencrypt == '0' && $result['letsencrypt'] == '1') {
|
||||
$del_stmt = Database::prepare("
|
||||
DELETE FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` WHERE `domainid` = :id
|
||||
");
|
||||
Database::pexecute($del_stmt, array(
|
||||
'id' => $id
|
||||
), true, true);
|
||||
}
|
||||
|
||||
inserttask('1');
|
||||
inserttask('4');
|
||||
|
||||
$idna_convert = new idna_convert_wrapper();
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_INFO, "[API] edited domain '" . $idna_convert->decode($result['domain']) . "'");
|
||||
}
|
||||
$result = $this->apiCall('SubDomains.get', array(
|
||||
'id' => $id
|
||||
));
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* lists all subdomain entries
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array count|list
|
||||
*/
|
||||
public function listing()
|
||||
{
|
||||
if ($this->isAdmin()) {
|
||||
// if we're an admin, list all databases of all the admins customers
|
||||
// or optionally for one specific customer identified by id or loginname
|
||||
$customerid = $this->getParam('customerid', true, 0);
|
||||
$loginname = $this->getParam('loginname', true, '');
|
||||
|
||||
if (! empty($customerid) || ! empty($loginname)) {
|
||||
$result = $this->apiCall('Customers.get', array(
|
||||
'id' => $customerid,
|
||||
'loginname' => $loginname
|
||||
));
|
||||
$custom_list_result = array(
|
||||
$result
|
||||
);
|
||||
} else {
|
||||
$_custom_list_result = $this->apiCall('Customers.listing');
|
||||
$custom_list_result = $_custom_list_result['list'];
|
||||
}
|
||||
$customer_ids = array();
|
||||
$customer_stdsubs = array();
|
||||
foreach ($custom_list_result as $customer) {
|
||||
$customer_ids[] = $customer['customerid'];
|
||||
$customer_stdsubs[$customer['customerid']] = $customer['standardsubdomain'];
|
||||
}
|
||||
} else {
|
||||
if (Settings::IsInList('panel.customer_hide_options', 'domains')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
$customer_ids = array(
|
||||
$this->getUserDetail('customerid')
|
||||
);
|
||||
$customer_stdsubs = array(
|
||||
$this->getUserDetail('customerid') => $this->getUserDetail('standardsubdomain')
|
||||
);
|
||||
}
|
||||
|
||||
// prepare select statement
|
||||
$domains_stmt = Database::prepare("
|
||||
SELECT `d`.`id`, `d`.`customerid`, `d`.`domain`, `d`.`documentroot`, `d`.`isbinddomain`, `d`.`isemaildomain`, `d`.`caneditdomain`, `d`.`iswildcarddomain`, `d`.`parentdomainid`, `d`.`letsencrypt`, `d`.`termination_date`, `ad`.`id` AS `aliasdomainid`, `ad`.`domain` AS `aliasdomain`, `da`.`id` AS `domainaliasid`, `da`.`domain` AS `domainalias`
|
||||
FROM `" . TABLE_PANEL_DOMAINS . "` `d`
|
||||
LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` `ad` ON `d`.`aliasdomain`=`ad`.`id`
|
||||
LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` `da` ON `da`.`aliasdomain`=`d`.`id`
|
||||
WHERE `d`.`customerid`= :customerid
|
||||
AND `d`.`email_only`='0'
|
||||
AND `d`.`id` <> :standardsubdomain
|
||||
");
|
||||
|
||||
$result = array();
|
||||
foreach ($customer_ids as $customer_id) {
|
||||
Database::pexecute($domains_stmt, array(
|
||||
"customerid" => $customer_id,
|
||||
"standardsubdomain" => $customer_stdsubs[$customer_id]
|
||||
), true, true);
|
||||
while ($row = $domains_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$result[] = $row;
|
||||
}
|
||||
}
|
||||
return $this->response(200, "successfull", array(
|
||||
'count' => count($result),
|
||||
'list' => $result
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* delete a subdomain by either id or domainname
|
||||
*
|
||||
* @param int $id
|
||||
* optional, the domain-id
|
||||
* @param string $domainname
|
||||
* optional, the domainname
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
$id = $this->getParam('id', true, 0);
|
||||
$dn_optional = ($id <= 0 ? false : true);
|
||||
$domainname = $this->getParam('domainname', $dn_optional, '');
|
||||
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'domains')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
|
||||
$result = $this->apiCall('SubDomains.get', array(
|
||||
'id' => $id,
|
||||
'domainname' => $domainname
|
||||
));
|
||||
$id = $result['id'];
|
||||
|
||||
// get needed customer info to reduce the subdomain-usage-counter by one
|
||||
$customer = $this->getCustomerData();
|
||||
|
||||
if (! $this->isAdmin() && $result['caneditdomain'] == 0) {
|
||||
throw new Exception("You cannot edit this resource", 405);
|
||||
}
|
||||
|
||||
if ($result['isemaildomain'] == '1') {
|
||||
// check for e-mail addresses
|
||||
$emails_stmt = Database::prepare("
|
||||
SELECT COUNT(`id`) AS `count` FROM `" . TABLE_MAIL_VIRTUAL . "`
|
||||
WHERE `customerid` = :customerid AND `domainid` = :domainid
|
||||
");
|
||||
$emails = Database::pexecute_first($emails_stmt, array(
|
||||
"customerid" => $customer['customerid'],
|
||||
"domainid" => $id
|
||||
), true, true);
|
||||
|
||||
if ($emails['count'] != '0') {
|
||||
standard_error('domains_cantdeletedomainwithemail', '', true);
|
||||
}
|
||||
}
|
||||
|
||||
triggerLetsEncryptCSRForAliasDestinationDomain($result['aliasdomain'], $this->logger());
|
||||
|
||||
// delete domain from table
|
||||
$stmt = Database::prepare("
|
||||
DELETE FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `customerid` = :customerid AND `id` = :id
|
||||
");
|
||||
Database::pexecute($stmt, array(
|
||||
"customerid" => $customer['customerid'],
|
||||
"id" => $id
|
||||
), true, true);
|
||||
|
||||
// remove connections to ips and domainredirects
|
||||
$del_stmt = Database::prepare("
|
||||
DELETE FROM `" . TABLE_DOMAINTOIP . "`
|
||||
WHERE `id_domain` = :domainid
|
||||
");
|
||||
Database::pexecute($del_stmt, array(
|
||||
'domainid' => $id
|
||||
), true, true);
|
||||
|
||||
// remove redirect-codes
|
||||
$del_stmt = Database::prepare("
|
||||
DELETE FROM `" . TABLE_PANEL_DOMAINREDIRECTS . "`
|
||||
WHERE `did` = :domainid
|
||||
");
|
||||
Database::pexecute($del_stmt, array(
|
||||
'domainid' => $id
|
||||
), true, true);
|
||||
|
||||
// remove certificate from domain_ssl_settings, fixes #1596
|
||||
$del_stmt = Database::prepare("
|
||||
DELETE FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "`
|
||||
WHERE `domainid` = :domainid
|
||||
");
|
||||
Database::pexecute($del_stmt, array(
|
||||
'domainid' => $id
|
||||
), true, true);
|
||||
|
||||
// remove possible existing DNS entries
|
||||
$del_stmt = Database::prepare("
|
||||
DELETE FROM `" . TABLE_DOMAIN_DNS . "`
|
||||
WHERE `domain_id` = :domainid
|
||||
");
|
||||
Database::pexecute($del_stmt, array(
|
||||
'domainid' => $id
|
||||
), true, true);
|
||||
|
||||
inserttask('1');
|
||||
// Using nameserver, insert a task which rebuilds the server config
|
||||
inserttask('4');
|
||||
// remove domains DNS from powerDNS if used, #581
|
||||
inserttask('11', $result['domain']);
|
||||
|
||||
// reduce subdomain-usage-counter
|
||||
Customers::decreaseUsage($customer['customerid'], 'subdomains_used');
|
||||
// update admin usage
|
||||
Admins::decreaseUsage(($this->isAdmin() ? $customer['adminid'] : $this->getUserDetail('adminid')), 'subdomains_used');
|
||||
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_WARNING, "[API] deleted subdomain '" . $result['domain'] . "'");
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* validate given path and replace with url if given and valid
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $url
|
||||
* @param array $customer
|
||||
* @param string $completedomain
|
||||
* @param boolean $_doredirect
|
||||
*
|
||||
* @return string validated path
|
||||
* @throws Exception
|
||||
*/
|
||||
private function validateDomainDocumentRoot($path = null, $url = null, $customer = null, $completedomain = null, &$_doredirect = false)
|
||||
{
|
||||
// check whether an URL was specified
|
||||
$_doredirect = false;
|
||||
if (! empty($url) && validateUrl($url)) {
|
||||
$path = $url;
|
||||
$_doredirect = true;
|
||||
} else {
|
||||
$path = validate($path, 'path', '', '', array(), true);
|
||||
}
|
||||
|
||||
// check whether path is a real path
|
||||
if (! preg_match('/^https?\:\/\//', $path) || ! validateUrl($path)) {
|
||||
if (strstr($path, ":") !== false) {
|
||||
standard_error('pathmaynotcontaincolon', '', true);
|
||||
}
|
||||
// If path is empty or '/' and 'Use domain name as default value for DocumentRoot path' is enabled in settings,
|
||||
// set default path to subdomain or domain name
|
||||
if ((($path == '') || ($path == '/')) && Settings::Get('system.documentroot_use_default_value') == 1) {
|
||||
$path = makeCorrectDir($customer['documentroot'] . '/' . $completedomain);
|
||||
} else {
|
||||
$path = makeCorrectDir($customer['documentroot'] . '/' . $path);
|
||||
}
|
||||
} else {
|
||||
// no it's not, create a redirect
|
||||
$_doredirect = true;
|
||||
}
|
||||
return $path;
|
||||
}
|
||||
}
|
||||
@@ -1,125 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package API
|
||||
* @since 0.10.0
|
||||
*
|
||||
*/
|
||||
class Traffic extends ApiCommand implements ResourceEntity
|
||||
{
|
||||
|
||||
/**
|
||||
* You cannot add traffic data
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
throw new Exception('You cannot add traffic data', 303);
|
||||
}
|
||||
|
||||
/**
|
||||
* to get specific traffic details use year, month and/or day parameter for Traffic.listing()
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
throw new Exception('To get specific traffic details use year, month and/or day parameter for Traffic.listing()', 303);
|
||||
}
|
||||
|
||||
/**
|
||||
* You cannot update traffic data
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function update()
|
||||
{
|
||||
throw new Exception('You cannot update traffic data', 303);
|
||||
}
|
||||
|
||||
/**
|
||||
* list traffic information
|
||||
*
|
||||
* @param int $year
|
||||
* optional, default empty
|
||||
* @param int $month
|
||||
* optional, default empty
|
||||
* @param int $day
|
||||
* optional, default empty
|
||||
* @param bool $customer_traffic
|
||||
* optional, admin-only, whether to output ones own traffic or all of ones customers, default is 0 (false)
|
||||
* @param int $customerid
|
||||
* optional, admin-only, select traffic of a specific customer by id
|
||||
* @param string $loginname
|
||||
* optional, admin-only, select traffic of a specific customer by loginname
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws Exception
|
||||
* @return array count|list
|
||||
*/
|
||||
public function listing()
|
||||
{
|
||||
$year = $this->getParam('year', true, "");
|
||||
$month = $this->getParam('month', true, "");
|
||||
$day = $this->getParam('day', true, "");
|
||||
$customer_traffic = $this->getBoolParam('customer_traffic', true, 0);
|
||||
$customer_ids = $this->getAllowedCustomerIds();
|
||||
$result = array();
|
||||
$params = array();
|
||||
// check for year/month/day
|
||||
$where_str = "";
|
||||
if (! empty($year) && is_numeric($year)) {
|
||||
$where_str .= " AND `year` = :year";
|
||||
$params['year'] = $year;
|
||||
}
|
||||
if (! empty($month) && is_numeric($month)) {
|
||||
$where_str .= " AND `month` = :month";
|
||||
$params['month'] = $month;
|
||||
}
|
||||
if (! empty($day) && is_numeric($day)) {
|
||||
$where_str .= " AND `day` = :day";
|
||||
$params['day'] = $day;
|
||||
}
|
||||
|
||||
if (! $this->isAdmin() || ($this->isAdmin() && $customer_traffic)) {
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_PANEL_TRAFFIC . "`
|
||||
WHERE `customerid` IN (".implode(", ", $customer_ids).")" . $where_str);
|
||||
} else {
|
||||
$params['adminid'] = $this->getUserDetail('adminid');
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_PANEL_TRAFFIC_ADMINS . "`
|
||||
WHERE `adminid` = :adminid" . $where_str);
|
||||
}
|
||||
Database::pexecute($result_stmt, $params, true, true);
|
||||
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$result[] = $row;
|
||||
}
|
||||
$this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_NOTICE, "[API] list traffic");
|
||||
return $this->response(200, "successfull", array(
|
||||
'count' => count($result),
|
||||
'list' => $result
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* You cannot delete traffic data
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
throw new Exception('You cannot delete traffic data', 303);
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package API
|
||||
* @since 0.10.0
|
||||
*
|
||||
*/
|
||||
interface ResourceEntity
|
||||
{
|
||||
|
||||
public function listing();
|
||||
|
||||
public function get();
|
||||
|
||||
public function add();
|
||||
|
||||
public function update();
|
||||
|
||||
public function delete();
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
<?php
|
||||
|
||||
class HttpClient
|
||||
{
|
||||
|
||||
/**
|
||||
* Executes simple GET request
|
||||
*
|
||||
* @param string $url
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function urlGet($url, $follow_location = true)
|
||||
{
|
||||
include FROXLOR_INSTALL_DIR . '/lib/version.inc.php';
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_USERAGENT, 'Froxlor/' . $version);
|
||||
if ($follow_location) {
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
$output = curl_exec($ch);
|
||||
if ($output === false) {
|
||||
$e = curl_error($ch);
|
||||
curl_close($ch);
|
||||
throw new \Exception("Curl error: " . $e);
|
||||
}
|
||||
curl_close($ch);
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Downloads and stores a file from an url
|
||||
*
|
||||
* @param string $url
|
||||
* @param string $target
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function fileGet($url, $target)
|
||||
{
|
||||
include FROXLOR_INSTALL_DIR . '/lib/version.inc.php';
|
||||
$fh = fopen($target, 'w');
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_USERAGENT, 'Froxlor/' . $version);
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 50);
|
||||
//give curl the file pointer so that it can write to it
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_FILE, $fh);
|
||||
$output = curl_exec($ch);
|
||||
if ($output === false) {
|
||||
$e = curl_error($ch);
|
||||
curl_close($ch);
|
||||
throw new \Exception("Curl error: " . $e);
|
||||
}
|
||||
curl_close($ch);
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
@@ -1,129 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2018 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Michael Kaufmann <d00p@froxlor.org>
|
||||
* @author Froxlor team <team@froxlor.org> (2018-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Classes
|
||||
*
|
||||
* @since 0.9.39
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class SImExporter
|
||||
*
|
||||
* Import/Export settings to JSON
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Michael Kaufmann <d00p@froxlor.org>
|
||||
* @author Froxlor team <team@froxlor.org> (2018-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Classes
|
||||
*/
|
||||
class SImExporter
|
||||
{
|
||||
|
||||
/**
|
||||
* settings which are not being exported
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $_no_export = [
|
||||
'panel.adminmail',
|
||||
'admin.show_news_feed',
|
||||
'system.lastaccountnumber',
|
||||
'system.lastguid',
|
||||
'system.ipaddress',
|
||||
'system.last_traffic_run',
|
||||
'system.hostname',
|
||||
'system.mysql_access_host',
|
||||
'system.lastcronrun',
|
||||
'system.defaultip',
|
||||
'system.defaultsslip'.
|
||||
'system.last_tasks_run',
|
||||
'system.last_archive_run',
|
||||
'system.leprivatekey',
|
||||
'system.lepublickey'
|
||||
];
|
||||
|
||||
public static function export()
|
||||
{
|
||||
$result_stmt = Database::query("
|
||||
SELECT * FROM `" . TABLE_PANEL_SETTINGS . "` ORDER BY `settingid` ASC
|
||||
");
|
||||
$_data = array();
|
||||
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$index = $row['settinggroup'] . "." . $row['varname'];
|
||||
if (! in_array($index, self::$_no_export)) {
|
||||
$_data[$index] = $row['value'];
|
||||
}
|
||||
}
|
||||
// add checksum for validation
|
||||
$_data['_sha'] = sha1(var_export($_data, true));
|
||||
$_export = json_encode($_data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
||||
if (! $_export) {
|
||||
throw new Exception("Error exporting settings: " . json_last_error_msg());
|
||||
}
|
||||
return $_export;
|
||||
}
|
||||
|
||||
public static function import($json_str = null)
|
||||
{
|
||||
// decode data
|
||||
$_data = json_decode($json_str, true);
|
||||
if ($_data) {
|
||||
// get validity check data
|
||||
$_sha = isset($_data['_sha']) ? $_data['_sha'] : false;
|
||||
$_version = isset($_data['panel.version']) ? $_data['panel.version'] : false;
|
||||
$_dbversion = isset($_data['panel.db_version']) ? $_data['panel.db_version'] : false;
|
||||
// check if we have everything we need
|
||||
if (! $_sha || ! $_version || ! $_dbversion) {
|
||||
throw new Exception("Invalid froxlor settings data. Unable to import.");
|
||||
}
|
||||
// validate import file
|
||||
unset($_data['_sha']);
|
||||
// compare
|
||||
if ($_sha != sha1(var_export($_data, true))) {
|
||||
throw new Exception("SHA check of import data failed. Unable to import.");
|
||||
}
|
||||
// do not import version info - but we need that to possibily update settings
|
||||
// when there were changes in the variable-name or similar
|
||||
unset($_data['panel.version']);
|
||||
unset($_data['panel.db_version']);
|
||||
// validate we got ssl enabled ips when ssl is enabled
|
||||
// otherwise deactivate it
|
||||
if ($_data['system.use_ssl'] == 1) {
|
||||
$result_ssl_ipsandports_stmt = Database::prepare("
|
||||
SELECT COUNT(*) as count_ssl_ip FROM `" . TABLE_PANEL_IPSANDPORTS . "` WHERE `ssl`='1'
|
||||
");
|
||||
$result = Database::pexecute_first($result_ssl_ipsandports_stmt);
|
||||
if ($result['count_ssl_ip'] <= 0) {
|
||||
// no ssl-ip -> deactivate
|
||||
$_data['system.use_ssl'] = 0;
|
||||
// deactivate other ssl-related settings
|
||||
$_data['system.leenabled'] = 0;
|
||||
$_data['system.le_froxlor_enabled'] = 0;
|
||||
$_data['system.le_froxlor_redirect'] = 0;
|
||||
}
|
||||
}
|
||||
// store new data
|
||||
foreach ($_data as $index => $value) {
|
||||
Settings::Set($index, $value);
|
||||
}
|
||||
// save to DB
|
||||
Settings::Flush();
|
||||
// all good
|
||||
return true;
|
||||
}
|
||||
throw new Exception("Invalid JSON data: " . json_last_error_msg());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user