diff --git a/admin_traffic.php b/admin_traffic.php index fdf8b6da..31b2fc2f 100644 --- a/admin_traffic.php +++ b/admin_traffic.php @@ -19,16 +19,6 @@ define('AREA', 'admin'); require './lib/init.php'; -if ($action == 'logout') { - $logout_stmt = Database::prepare(" - DELETE FROM `" . TABLE_PANEL_SESSIONS . "` - WHERE `userid` = :adminid - AND `adminsession` = '1'" - ); - Database::pexecute($logout_stmt, array('adminid' => $userinfo['adminid'])); - redirectTo('index.php'); -} - if (isset($_POST['id'])) { $id = intval($_POST['id']); } elseif(isset($_GET['id'])) { diff --git a/lib/classes/api/commands/class.DirOptions.php b/lib/classes/api/commands/class.DirOptions.php index 957d1bdd..80a5f522 100644 --- a/lib/classes/api/commands/class.DirOptions.php +++ b/lib/classes/api/commands/class.DirOptions.php @@ -148,10 +148,9 @@ class DirOptions extends ApiCommand implements ResourceEntity } $result_stmt = Database::prepare(" SELECT * FROM `" . TABLE_PANEL_HTACCESS . "` - WHERE `customerid` IN (:customerid) + WHERE `customerid` IN (".implode(", ", $customer_ids).") AND `id` = :id "); - $params['customerid'] = implode(", ", $customer_ids); } else { $result_stmt = Database::prepare(" SELECT * FROM `" . TABLE_PANEL_HTACCESS . "` @@ -272,13 +271,12 @@ class DirOptions extends ApiCommand implements ResourceEntity } $customer_ids = $this->getAllowedCustomerIds('extras.pathoptions'); + $result = array(); $result_stmt = Database::prepare(" SELECT * FROM `" . TABLE_PANEL_HTACCESS . "` - WHERE `customerid` IN (:customerids) + WHERE `customerid` IN (".implode(', ', $customer_ids).") "); - Database::pexecute($result_stmt, array( - "customerids" => implode(', ', $customer_ids) - ), true, true); + Database::pexecute($result_stmt, null, true, true); while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { $result[] = $row; } diff --git a/lib/classes/api/commands/class.DirProtections.php b/lib/classes/api/commands/class.DirProtections.php index 95a8e1bc..018253cd 100644 --- a/lib/classes/api/commands/class.DirProtections.php +++ b/lib/classes/api/commands/class.DirProtections.php @@ -134,10 +134,9 @@ class DirProtections extends ApiCommand implements ResourceEntity } $result_stmt = Database::prepare(" SELECT * FROM `" . TABLE_PANEL_HTPASSWDS . "` - WHERE `customerid` IN (:customerid) + WHERE `customerid` IN (".implode(", ", $customer_ids).") AND (`id` = :idun OR `username` = :idun) "); - $params['customerid'] = implode(", ", $customer_ids); } else { $result_stmt = Database::prepare(" SELECT * FROM `" . TABLE_PANEL_HTPASSWDS . "` @@ -250,13 +249,12 @@ class DirProtections extends ApiCommand implements ResourceEntity } $customer_ids = $this->getAllowedCustomerIds('extras.directoryprotection'); + $result = array(); $result_stmt = Database::prepare(" SELECT * FROM `" . TABLE_PANEL_HTPASSWDS . "` - WHERE `customerid` IN (:customerids) + WHERE `customerid` IN (".implode(', ', $customer_ids).") "); - Database::pexecute($result_stmt, array( - "customerids" => implode(', ', $customer_ids) - ), true, true); + Database::pexecute($result_stmt, null, true, true); while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { $result[] = $row; } diff --git a/lib/classes/api/commands/class.Domains.php b/lib/classes/api/commands/class.Domains.php index b1438f2d..7ae01cca 100644 --- a/lib/classes/api/commands/class.Domains.php +++ b/lib/classes/api/commands/class.Domains.php @@ -1546,10 +1546,7 @@ class Domains extends ApiCommand implements ResourceEntity $aip_param = array(); if ($this->getUserDetail('ip') != "-1") { // handle multiple-ip-array - $additional_ip_condition = " AND `ip` IN (:adminips) "; - $aip_param = array( - 'adminips' => implode(",", json_decode($this->getUserDetail('ip'), true)) - ); + $additional_ip_condition = " AND `ip` IN (".implode(",", json_decode($this->getUserDetail('ip'), true)).") "; } if (! empty($p_ipandports) && is_array($p_ipandports)) { diff --git a/lib/classes/api/commands/class.Emails.php b/lib/classes/api/commands/class.Emails.php index 5255cf33..2c4e7418 100644 --- a/lib/classes/api/commands/class.Emails.php +++ b/lib/classes/api/commands/class.Emails.php @@ -159,13 +159,12 @@ class Emails extends ApiCommand implements ResourceEntity $params = array(); $customer_ids = $this->getAllowedCustomerIds('email'); - $params['customerid'] = implode(", ", $customer_ids); $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 (:customerid) + 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); @@ -270,15 +269,14 @@ class Emails extends ApiCommand implements ResourceEntity { $customer_ids = $this->getAllowedCustomerIds('email'); $result = array(); - $params['customerid'] = implode(", ", $customer_ids); $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 (:customerid) + WHERE m.`customerid` IN (".implode(", ", $customer_ids).") "); - Database::pexecute($result_stmt, $params, true, true); + Database::pexecute($result_stmt, null, true, true); while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { $result[] = $row; } diff --git a/lib/classes/api/commands/class.Ftps.php b/lib/classes/api/commands/class.Ftps.php index e83da4ba..ae4c9e95 100644 --- a/lib/classes/api/commands/class.Ftps.php +++ b/lib/classes/api/commands/class.Ftps.php @@ -258,10 +258,9 @@ class Ftps extends ApiCommand implements ResourceEntity } $result_stmt = Database::prepare(" SELECT * FROM `" . TABLE_FTP_USERS . "` - WHERE `customerid` IN (:customerid) + WHERE `customerid` IN (".implode(", ", $customer_ids).") AND (`id` = :idun OR `username` = :idun) "); - $params['customerid'] = implode(", ", $customer_ids); } else { $result_stmt = Database::prepare(" SELECT * FROM `" . TABLE_FTP_USERS . "` @@ -429,12 +428,11 @@ class Ftps extends ApiCommand implements ResourceEntity { $customer_ids = $this->getAllowedCustomerIds('ftp'); $result = array(); - $params = array('customerid' => implode(", ", $customer_ids)); $result_stmt = Database::prepare(" SELECT * FROM `" . TABLE_FTP_USERS . "` - WHERE `customerid` IN (:customerid) + WHERE `customerid` IN (".implode(", ", $customer_ids).") "); - Database::pexecute($result_stmt, $params, true, true); + Database::pexecute($result_stmt, null, true, true); while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { $result[] = $row; } diff --git a/lib/classes/api/commands/class.Mysqls.php b/lib/classes/api/commands/class.Mysqls.php index 37091ccc..996c8d80 100644 --- a/lib/classes/api/commands/class.Mysqls.php +++ b/lib/classes/api/commands/class.Mysqls.php @@ -203,11 +203,10 @@ class Mysqls extends ApiCommand implements ResourceEntity 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 (:customerids) + 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), - 'customerids' => implode(", ", $customer_ids) + 'iddn' => ($id <= 0 ? $dbname : $id) ); if ($dbserver >= 0) { $params['dbserver'] = $dbserver; diff --git a/lib/classes/api/commands/class.SubDomains.php b/lib/classes/api/commands/class.SubDomains.php index b7be8393..d4847e1d 100644 --- a/lib/classes/api/commands/class.SubDomains.php +++ b/lib/classes/api/commands/class.SubDomains.php @@ -349,12 +349,11 @@ class SubDomains extends ApiCommand implements ResourceEntity $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 (:customerids) + 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), - 'customerids' => implode(", ", $customer_ids) + 'iddn' => ($id <= 0 ? $domainname : $id) ); } else { throw new Exception("You do not have any customers yet", 406); diff --git a/lib/classes/api/commands/class.Traffic.php b/lib/classes/api/commands/class.Traffic.php index d850b4a7..73a7761f 100644 --- a/lib/classes/api/commands/class.Traffic.php +++ b/lib/classes/api/commands/class.Traffic.php @@ -20,32 +20,103 @@ 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->getParam('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() { diff --git a/phpunit.xml b/phpunit.xml index 7ca27cb9..02370269 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -23,6 +23,7 @@ tests/DomainZones tests/Mysqls tests/PhpAndFpm + tests/Traffic diff --git a/scripts/froxlor_master_cronjob.php b/scripts/froxlor_master_cronjob.php index a6d0d817..b3f25da6 100644 --- a/scripts/froxlor_master_cronjob.php +++ b/scripts/froxlor_master_cronjob.php @@ -29,7 +29,8 @@ if (count($argv) < 2 || (isset($argv[1]) && strtolower($argv[1]) == '--help')) { echo "Below are possible parameters for this file\n\n"; echo "--[cronname]\t\tincludes the given cron-file\n"; echo "--force\t\t\tforces re-generating of config-files (webserver, nameserver, etc.)\n"; - echo "--debug\t\t\toutput debug information about what is going on to STDOUT.\n\n"; + echo "--debug\t\t\toutput debug information about what is going on to STDOUT.\n"; + echo "--no-fork\t\t\tdo not fork to backkground (traffic cron only).\n\n"; } /** @@ -56,6 +57,9 @@ for ($x = 1; $x < count($argv); $x++) { elseif (strtolower($argv[$x]) == '--debug') { define('CRON_DEBUG_FLAG', 1); } + elseif (strtolower($argv[$x]) == '--no-fork') { + define('CRON_NOFORK_FLAG', 1); + } // --[cronname] elseif (substr(strtolower($argv[$x]), 0, 2) == '--') { if (strlen($argv[$x]) > 3) { diff --git a/scripts/jobs/cron_traffic.php b/scripts/jobs/cron_traffic.php index d5e077d4..c420e5e6 100644 --- a/scripts/jobs/cron_traffic.php +++ b/scripts/jobs/cron_traffic.php @@ -18,7 +18,7 @@ */ // Check Traffic-Lock -if (function_exists('pcntl_fork')) { +if (function_exists('pcntl_fork') && !defined('CRON_NOFORK_FLAG')) { $TrafficLock = makeCorrectFile(dirname($lockfile)."/froxlor_cron_traffic.lock"); if (file_exists($TrafficLock) && is_numeric($TrafficPid=file_get_contents($TrafficLock)) @@ -606,7 +606,7 @@ while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { Database::query("UPDATE `" . TABLE_PANEL_SETTINGS . "` SET `value` = UNIX_TIMESTAMP() WHERE `settinggroup` = 'system' AND `varname` = 'last_traffic_run'"); -if (function_exists('pcntl_fork')) { +if (function_exists('pcntl_fork') && !defined('CRON_NOFORK_FLAG')) { @unlink($TrafficLock); die(); } diff --git a/tests/Ftps/FtpsTest.php b/tests/Ftps/FtpsTest.php index 09a3bfcd..65939bd0 100644 --- a/tests/Ftps/FtpsTest.php +++ b/tests/Ftps/FtpsTest.php @@ -82,7 +82,7 @@ class FtpsTest extends TestCase $json_result = Ftps::getLocal($admin_userdata)->listing(); $result = json_decode($json_result, true)['data']; - $this->assertEquals(1, $result['count']); + $this->assertEquals(2, $result['count']); } public function testAdminFtpsListSpecificCustomer() diff --git a/tests/Traffic/TrafficTest.php b/tests/Traffic/TrafficTest.php new file mode 100644 index 00000000..69a68b7c --- /dev/null +++ b/tests/Traffic/TrafficTest.php @@ -0,0 +1,104 @@ + $cid, + 'y' => date('Y'), + 'm' => date('m'), + 'd' => date('d'), + 'ts' => time(), + 'http' => $http, + 'fup' => $fup, + 'fdown' => $fdown, + 'mail' => $mail + )); + } + + Database::pexecute($ins_adm_stmt, array( + 'aid' => 1, + 'y' => date('Y'), + 'm' => date('m'), + 'd' => date('d'), + 'ts' => time(), + 'http' => $http * 2, + 'fup' => $fup * 2, + 'fdown' => $fdown * 2, + 'mail' => $mail * 2 + )); + } + + public function testAdminTrafficList() + { + global $admin_userdata; + + $json_result = Traffic::getLocal($admin_userdata)->listing(); + $result = json_decode($json_result, true)['data']; + $this->assertEquals(1, $result['count']); + $http = 2 * (5 * 1024 * 1024 * 1024); // 2x 5 GB + $this->assertEquals($http, $result['list'][0]['http']); + } + + public function testAdminTrafficListCustomers() + { + global $admin_userdata; + + $json_result = Traffic::getLocal($admin_userdata, array( + 'customer_traffic' => 1 + ))->listing(); + $result = json_decode($json_result, true)['data']; + $this->assertEquals(2, $result['count']); + $this->assertEquals(1, $result['list'][0]['customerid']); + $this->assertEquals(3, $result['list'][1]['customerid']); + } + + public function testCustomerTrafficList() + { + global $admin_userdata; + // get customer + $json_result = Customers::getLocal($admin_userdata, array( + 'loginname' => 'test1' + ))->get(); + $customer_userdata = json_decode($json_result, true)['data']; + $json_result = Traffic::getLocal($customer_userdata)->listing(); + $result = json_decode($json_result, true)['data']; + $this->assertEquals(1, $result['count']); + $mail = 250 * 1024 * 1024; // 250 MB + $this->assertEquals($mail, $result['list'][0]['mail']); + } +} diff --git a/tests/bootstrap.php b/tests/bootstrap.php index eb7fa9d3..f032cfa5 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -130,3 +130,4 @@ $admin_userdata = Database::pexecute_first($sel_stmt); $admin_userdata['adminsession'] = 1; Settings::Set('panel.standardlanguage', 'English', true); +Settings::Set('system.lastguid', '10000', true);