From b205f8ea5df1cdebd25bef661b6963b30d2872b9 Mon Sep 17 00:00:00 2001 From: "Michael Kaufmann (d00p)" Date: Sun, 11 Mar 2018 10:24:17 +0100 Subject: [PATCH] add EmailFowarders ApiCommand Signed-off-by: Michael Kaufmann (d00p) --- customer_email.php | 86 ++----- lib/classes/api/abstract.ApiCommand.php | 15 +- .../api/commands/class.EmailForwarders.php | 226 ++++++++++++++++++ lib/classes/api/commands/class.Emails.php | 15 +- 4 files changed, 274 insertions(+), 68 deletions(-) create mode 100644 lib/classes/api/commands/class.EmailForwarders.php diff --git a/customer_email.php b/customer_email.php index 870f243c..8be1013c 100644 --- a/customer_email.php +++ b/customer_email.php @@ -658,48 +658,21 @@ if ($page == 'overview') { } elseif ($page == 'forwarders') { if ($action == 'add' && $id != 0) { if ($userinfo['email_forwarders_used'] < $userinfo['email_forwarders'] || $userinfo['email_forwarders'] == '-1') { - $stmt = Database::prepare("SELECT `id`, `email`, `email_full`, `iscatchall`, `destination`, `customerid`, `popaccountid`, `domainid` FROM `" . TABLE_MAIL_VIRTUAL . "` - WHERE `customerid`= :cid - AND `id`= :id" - ); - $result = Database::pexecute_first($stmt, array("cid" => $userinfo['customerid'], "id" => $id)); + try { + $json_result = Emails::getLocal($userinfo, array('id' => $id))->get(); + } catch (Exception $e) { + dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; if (isset($result['email']) && $result['email'] != '') { if (isset($_POST['send']) && $_POST['send'] == 'send') { - $destination = $idna_convert->encode($_POST['destination']); - $result['destination_array'] = explode(' ', $result['destination']); - - if ($destination == '') { - standard_error('destinationnonexist'); - } elseif (!validateEmail($destination)) { - standard_error('destinationiswrong', $destination); - } elseif ($destination == $result['email']) { - standard_error('destinationalreadyexistasmail', $destination); - } elseif (in_array($destination, $result['destination_array'])) { - standard_error('destinationalreadyexist', $destination); - } else { - $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" => $userinfo['customerid'], - "id" => $id - ); - Database::pexecute($stmt, $params); - - $stmt = Database::prepare("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` - SET `email_forwarders_used` = `email_forwarders_used` + 1 - WHERE `customerid`= :cid" - ); - Database::pexecute($stmt, array("cid" => $userinfo['customerid'])); - - $log->logAction(USR_ACTION, LOG_INFO, "added email forwarder for '" . $result['email_full'] . "'"); - redirectTo($filename, array('page' => 'emails', 'action' => 'edit', 'id' => $id, 's' => $s)); + try { + EmailForwarders::getLocal($userinfo, $_POST)->add(); + } catch (Exception $e) { + dynamic_error($e->getMessage()); } + redirectTo($filename, array('page' => 'emails', 'action' => 'edit', 'id' => $id, 's' => $s)); } else { $result['email_full'] = $idna_convert->decode($result['email_full']); $result = htmlentities_array($result); @@ -717,11 +690,12 @@ if ($page == 'overview') { standard_error('allresourcesused'); } } elseif ($action == 'delete' && $id != 0) { - $stmt = Database::prepare("SELECT `id`, `email`, `email_full`, `iscatchall`, `destination`, `customerid`, `popaccountid` FROM `" . TABLE_MAIL_VIRTUAL . "` - WHERE `customerid`='" . (int)$userinfo['customerid'] . "' - AND `id`='" . (int)$id . "'" - ); - $result = Database::pexecute_first($stmt, array("cid" => $userinfo['customerid'])); + try { + $json_result = Emails::getLocal($userinfo, array('id' => $id))->get(); + } catch (Exception $e) { + dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; if (isset($result['destination']) && $result['destination'] != '') { if (isset($_POST['forwarderid'])) { @@ -738,27 +712,11 @@ if ($page == 'overview') { $forwarder = $result['destination'][$forwarderid]; if (isset($_POST['send']) && $_POST['send'] == 'send') { - unset($result['destination'][$forwarderid]); - $result['destination'] = implode(' ', $result['destination']); - $stmt = Database::prepare("UPDATE `" . TABLE_MAIL_VIRTUAL . "` - SET `destination` = :dest - WHERE `customerid`= :cid - AND `id`= :id" - ); - $params = array( - "dest" => makeCorrectDestination($result['destination']), - "cid" => $userinfo['customerid'], - "id" => $id - ); - Database::pexecute($stmt, $params); - - $stmt = Database::prepare("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` - SET `email_forwarders_used` = `email_forwarders_used` - 1 - WHERE `customerid`= :cid" - ); - Database::pexecute($stmt, array("cid" => $userinfo['customerid'])); - - $log->logAction(USR_ACTION, LOG_INFO, "deleted email forwarder for '" . $result['email_full'] . "'"); + try { + EmailForwarders::getLocal($userinfo, $_POST)->delete(); + } catch (Exception $e) { + dynamic_error($e->getMessage()); + } redirectTo($filename, array('page' => 'emails', 'action' => 'edit', 'id' => $id, 's' => $s)); } else { ask_yesno('email_reallydelete_forwarder', $filename, array('id' => $id, 'forwarderid' => $forwarderid, 'page' => $page, 'action' => $action), $idna_convert->decode($result['email_full']) . ' -> ' . $idna_convert->decode($forwarder)); diff --git a/lib/classes/api/abstract.ApiCommand.php b/lib/classes/api/abstract.ApiCommand.php index 0528a79c..da3f0430 100644 --- a/lib/classes/api/abstract.ApiCommand.php +++ b/lib/classes/api/abstract.ApiCommand.php @@ -349,6 +349,16 @@ abstract class ApiCommand throw new Exception("Unable to update parameter '" . $param . "' as it does not exist", 500); } + /** + * return list of all parameters + * + * @return array + */ + protected function getParamList() + { + return $this->cmd_params; + } + /** * return logger instance * @@ -455,6 +465,9 @@ abstract class ApiCommand $this->getUserDetail('customerid') ); } + if (empty($customer_ids)) { + throw new Exception("Required resource unsatisfied.", 405); + } return $customer_ids; } @@ -472,7 +485,7 @@ abstract class ApiCommand { $stmt = Database::prepare(" UPDATE `" . $table . "` - SET `" . $resource . "` = `" . $resource . "` " . $operator . " " . (int)$step . " " . $extra . " + SET `" . $resource . "` = `" . $resource . "` " . $operator . " " . (int) $step . " " . $extra . " WHERE `" . $keyfield . "` = :key "); Database::pexecute($stmt, array( diff --git a/lib/classes/api/commands/class.EmailForwarders.php b/lib/classes/api/commands/class.EmailForwarders.php new file mode 100644 index 00000000..f4658c9b --- /dev/null +++ b/lib/classes/api/commands/class.EmailForwarders.php @@ -0,0 +1,226 @@ + (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 string $destination + * email-address to add as forwarder + * @param int $customerid + * optional, required when called as admin/reseller + * + * @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']); + + 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-address-counter by one + if ($this->isAdmin()) { + // get customer id + $customer_id = $this->getParam('customerid'); + $customer = $this->apiCall('Customers.get', array( + 'id' => $customer_id + )); + // check whether the customer has enough resources to get the mail-forwarder added + if ($customer['email_forwarders_used'] >= $customer['email_forwarders'] && $customer['email_forwarders'] != '-1') { + throw new Exception("Customer has no more resources available", 406); + } + } else { + $customer_id = $this->getUserDetail('customerid'); + $customer = $this->getUserData(); + } + + // 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_id, + "id" => $id + ); + Database::pexecute($stmt, $params, true, true); + + // update customer usage + Customers::increaseUsage($customer_id, '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); + } + + public function get() + { + throw new Exception('You cannot directly get an email forwarder. You need to call Emails.get()', 303); + } + + public function update() + { + throw new Exception('You cannot update an email forwarder. You need to delete the entry and create a new one.', 303); + } + + 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 add the forwarder for + * @param int $forwarderid + * id of the forwarder to delete + * @param int $customerid + * optional, required when called as admin/reseller + * + * @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); + } + + 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, ''); + $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-address-counter by one + if ($this->isAdmin()) { + // get customer id + $customer_id = $this->getParam('customer_id'); + $customer = $this->apiCall('Customers.get', array( + 'id' => $customer_id + )); + } else { + $customer_id = $this->getUserDetail('customerid'); + $customer = $this->getUserData(); + } + + // get specific forwarder + $forwarder = $result['destination'][$forwarderid]; + // 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); + + $stmt = Database::prepare("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` + SET `email_forwarders_used` = `email_forwarders_used` - 1 + WHERE `customerid`= :cid"); + Database::pexecute($stmt, array( + "cid" => $userinfo['customerid'] + )); + + // update customer usage + Customers::decreaseUsage($customer_id, '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); + } + throw new Exception("No more resources available", 406); + } +} diff --git a/lib/classes/api/commands/class.Emails.php b/lib/classes/api/commands/class.Emails.php index 8f712c31..b72bfbeb 100644 --- a/lib/classes/api/commands/class.Emails.php +++ b/lib/classes/api/commands/class.Emails.php @@ -21,6 +21,15 @@ 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, required when called as admin/reseller + * * @access admin, customer * @throws Exception * @return array @@ -78,11 +87,11 @@ class Emails extends ApiCommand implements ResourceEntity // get needed customer info to reduce the email-address-counter by one if ($this->isAdmin()) { // get customer id - $customer_id = $this->getParam('customer_id'); + $customer_id = $this->getParam('customerid'); $customer = $this->apiCall('Customers.get', array( 'id' => $customer_id )); - // check whether the customer has enough resources to get the ftp-user added + // check whether the customer has enough resources to get the mail-address added if ($customer['emails_used'] >= $customer['emails'] && $customer['emails'] != '-1') { throw new Exception("Customer has no more resources available", 406); } @@ -148,7 +157,7 @@ class Emails extends ApiCommand implements ResourceEntity * return a email-address entry by either id or email-address * * @param int $id - * optional, the customer-id + * optional, the email-address-id * @param string $emailaddr * optional, the email-address *