added Traffic.listing ApiCommand; added first Unit-Tests for Traffic-Api; SQL IN-clause cannot be prepared, replaced all occurances accordingly; added --no-fork parameter to traffic-cron

Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
This commit is contained in:
Michael Kaufmann
2018-11-11 21:51:39 +01:00
parent 41acbc745c
commit 18aa8eb5d2
15 changed files with 206 additions and 48 deletions

View File

@@ -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'])) {

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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)) {

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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()
{

View File

@@ -23,6 +23,7 @@
<directory>tests/DomainZones</directory>
<directory>tests/Mysqls</directory>
<directory>tests/PhpAndFpm</directory>
<directory>tests/Traffic</directory>
</testsuite>
</testsuites>

View File

@@ -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) {

View File

@@ -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();
}

View File

@@ -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()

View File

@@ -0,0 +1,104 @@
<?php
use PHPUnit\Framework\TestCase;
/**
*
* @covers ApiCommand
* @covers ApiParameter
* @covers Traffic
* @covers Customers
* @covers Admins
*/
class TrafficTest extends TestCase
{
public static function setUpBeforeClass()
{
$ins_stmt = Database::prepare("
INSERT INTO `" . TABLE_PANEL_TRAFFIC . "` SET
`customerid` = :cid,
`year` = :y, `month` = :m, `day` = :d,
`stamp` = :ts,
`http` = :http, `ftp_up` = :fup, `ftp_down` = :fdown, `mail` = :mail
");
$ins_adm_stmt = Database::prepare("
INSERT INTO `" . TABLE_PANEL_TRAFFIC_ADMINS . "` SET
`adminid` = :aid,
`year` = :y, `month` = :m, `day` = :d,
`stamp` = :ts,
`http` = :http, `ftp_up` = :fup, `ftp_down` = :fdown, `mail` = :mail
");
$http = 5 * 1024 * 1024 * 1024; // 5 GB
$fup = 50 * 1024 * 1024; // 50 MB
$fdown = 2 * 1024 * 1024 * 1024; // 2 GB
$mail = 250 * 1024 * 1024; // 250 MB
foreach (array(1,2,3) as $cid)
{
Database::pexecute($ins_stmt, array(
'cid' => $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']);
}
}

View File

@@ -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);