Compare commits

...

63 Commits

Author SHA1 Message Date
Michael Kaufmann
d5df4dd7a4 set version to 0.10.6 for upcoming maintenance release
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-11-15 16:43:36 +01:00
Michael Kaufmann
57497bd03f if no ssl IP/port is selected when editing a domain within the webinterface, set the remove_ssl_ipandport parameter to true to not fallback to defaults
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-11-15 16:36:14 +01:00
Michael Kaufmann
1a3cc52188 fix parameters defaults for Domains.update() and add new parameter 'remove_ssl_ipandport' to clear ssl ip/port instead of defaulting to the current set value; fixes #756
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-11-15 15:11:24 +01:00
Michael Kaufmann
21f6874a61 check whether there actually is quota read for a user if newly created, thx again to J-BBB
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-11-15 12:58:28 +01:00
Michael Kaufmann
b34e66dfd6 fix install-dir replacement in configfiles, thx to J-BBB
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-11-15 08:02:46 +01:00
Michael Kaufmann
a77f890462 Merge branch 'master' of github.com:Froxlor/Froxlor 2019-11-15 07:20:38 +01:00
Michael Kaufmann
3cc5352c01 implement EmailForwarders.listing(); fixes #754
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-11-15 07:20:16 +01:00
Michael Kaufmann
d01d470119 Merge pull request #755 from danielrona/patch-1
enabled autofocus for 2fa_code
2019-11-14 12:58:18 +01:00
Daniel
a97ce74cc8 enabled autofocus for 2fa_code 2019-11-14 12:31:29 +01:00
Michael Kaufmann
fe7bfcc7c2 fix update of hosting plans via interface; fixes #753
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-11-13 15:28:08 +01:00
Michael Kaufmann
cff0ac72d0 optimize varchar fields in admin/customer table; fixes #752
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-11-13 08:57:53 +01:00
Michael Kaufmann
e8dcb29b69 keep searching code in ssl_certificates if something was searched and no results were returned, thx to Ithariel
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-11-12 12:53:38 +01:00
Michael Kaufmann
2b3b68efa3 remove testing code
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-11-12 08:17:54 +01:00
Michael Kaufmann
d937029bf7 implement [ApiModule].listing() in frontend-module as sorting/limiting/searching is now possible via API call (partly untested)
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-11-10 18:35:32 +01:00
Michael Kaufmann
1955b5dd32 add task to remove certificate from acme.sh when removed in froxlor; fix issue when mode of certificate generation was not reset to 'issue' and kept trying to 'renew' instead
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-11-10 18:34:02 +01:00
Michael Kaufmann
c2a9880616 add new Api-Module 'SysLog' to query froxlor logs; set default value for api_allowed to the value of api.enabled setting when adding new customer via frontend to behave like Customers.add() API method
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-11-09 11:37:45 +01:00
Michael Kaufmann
dfedc478f7 check for given customer loginname/id before anything happens in Mysqls.add/update/delete when called as admin; fixes #749
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-11-07 15:53:30 +01:00
Michael Kaufmann
6efe500cee validate that the admin/reseller has customers in SubDomains.listing(); return all domain fields for admins/resellers in SubDomains.listing()
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-11-05 11:21:49 +01:00
Michael Kaufmann
9c3549c604 lowercase domain-names in AcmeSh implementation to avoid https://github.com/Neilpang/acme.sh/issues/2556
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-11-04 11:39:06 +01:00
Michael Kaufmann
50755f4399 set phpunit to fixed 8.4.1 in favor of https://github.com/sebastianbergmann/phpunit/issues/3793 to not break jenkins testing for now
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-11-02 13:26:38 +01:00
Michael Kaufmann
ef11ad8da7 fix broke count sql-queries
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-11-02 11:12:49 +01:00
Michael Kaufmann
1b2c186c07 introduce search, limit, offset and orderby possibilities for (almost) all API listing() functions; added listingCount() function in preparation to replace the old UI\Paging class later on
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-11-02 10:58:52 +01:00
Michael Kaufmann
b162324ff0 fix renew-check of let's encrypt implementation, set version to 0.10.5 for bugfix release; fixes #747
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-11-01 14:19:06 +01:00
Michael Kaufmann
6cd061d74c set version to 0.10.4 for upcoming maintenance release; minor code formatting + adjustments
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-11-01 11:16:13 +01:00
Michael Kaufmann
53b7420dc9 fix stripping of escape-sequences in api-endpoint; fixes #746
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-11-01 07:39:28 +01:00
Michael Kaufmann
aa85c648a3 check for renewal of certificates not only if there's a task to regenerate vhosts but everytime the letsencrypt cronjob runs (which is basically obsolete due to the integration into the tasks cron but perfect for checking renewal dates
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-31 21:37:54 +01:00
Michael Kaufmann
35e228ff09 Merge pull request #745 from pquerner/unittests/564
Add UnitTests for #679
2019-10-30 13:01:02 +01:00
Pascal
62236da496 changed method name 2019-10-30 12:50:16 +01:00
Pascal
e1cc896b6c add unit tests for Validate::is_ipv6 2019-10-30 12:39:56 +01:00
Pascal
36595baa65 Merge remote-tracking branch 'Froxlor/master' 2019-10-30 12:14:39 +01:00
Michael Kaufmann
ec3fd1d105 Create SECURITY.md 2019-10-30 11:00:08 +01:00
Michael Kaufmann
e39dcfbfe2 Update FUNDING.yml 2019-10-30 10:50:20 +01:00
Michael Kaufmann
ef6254b307 Merge pull request #679 from pquerner/#564
Allow CIDR and Netmask in mysql_host_access; fixes #564
2019-10-30 10:40:26 +01:00
Michael Kaufmann
44bf211ab5 Merge pull request #743 from kionez/fix_split_path_info
Correct fastcgi_split_path_info; fixes #744
2019-10-29 16:09:44 +01:00
kionez
b0e920104f Fix fastcgi_split_path_info as https://www.nginx.com/resources/wiki/start/topics/examples/phpfcgi/ 2019-10-29 16:00:14 +01:00
kionez
299e201142 Fix fastcgi_split_path_info 2019-10-29 15:47:28 +01:00
Michael Kaufmann
46982ad2dc validate that a customer gets the default ftp account created even if the admin/reseller has no more resource for ftp accounts; fixes #741
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-29 07:52:00 +01:00
Michael Kaufmann
c0e07fd659 fix undefined variable in hosting-plans frontend, fixes #742
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-28 20:06:14 +01:00
Pascal
5c11eecbd7 remove code for checking ipv6 mapped ipv4 notation 2019-10-28 17:27:39 +01:00
Pascal
9689afc759 change method signature of \Froxlor\Validate\Validate::validate_ip2 2019-10-28 16:58:34 +01:00
Pascal
d76f4108e5 dont need $result if we're expecting an exception 2019-10-28 16:40:22 +01:00
Pascal
9c4d619840 remove inner if statement
check ipv6 when cidr>netmask flag is set
2019-10-28 16:32:52 +01:00
Pascal
7774e7606d dont check notated ips again 2019-10-28 16:29:53 +01:00
Pascal
2ed0cad27b #564:
cidr notation can only be 1 through 32
2019-10-28 16:27:54 +01:00
Pascal
686c2ae534 fix comparison 2019-10-28 16:00:43 +01:00
Pascal
faf3abe800 introduce new parameter to allow automatic convert cidr notation to netmask notation 2019-10-28 15:33:26 +01:00
Pascal
220b493a1b better readability 2019-10-28 14:16:27 +01:00
Pascal
e8d67f9711 check if ipv6 first 2019-10-28 14:07:31 +01:00
Pascal
83e932b068 switch join with implode 2019-10-28 13:26:32 +01:00
Pascal
84d1be538e block ipv6 addresses in cidr notation (mysql can't handle it) 2019-10-28 13:25:34 +01:00
Pascal
c97cdb1c0e make it more readable 2019-10-28 13:15:48 +01:00
Pascal
ffefe85fb4 Merge branch 'master' into #564 2019-10-28 12:18:55 +01:00
Pascal
27341ca490 Merge remote-tracking branch 'Froxlor/master' 2019-10-28 12:17:51 +01:00
Michael Kaufmann
822bb2bd4d fixed deletion of default-ftp-user possible via API (not through the interface though); refs #741
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-27 16:02:32 +01:00
Michael Kaufmann
88ee76e4c9 setting version to 0.10.3 for upcoming release
Signed-off-by: Michael Kaufmann <michael.kaufmann@aixit.com>
2019-10-25 14:48:13 +02:00
Michael Kaufmann
90d921ebb5 preserve downward compatibility for 0.10.1 updaters regarding specialsettings for ssl-enabled domains; fixes #739
Signed-off-by: Michael Kaufmann <michael.kaufmann@aixit.com>
2019-10-24 18:14:51 +02:00
Michael Kaufmann
7b162c4bd0 added tls-settings per domain for admins with change_serversettings-flag set; fixes #519
Signed-off-by: Michael Kaufmann <michael.kaufmann@aixit.com>
2019-10-22 16:45:03 +02:00
Michael Kaufmann
32e2d48aed fallback to /tmp/froxlor.log if file-log is activated but no file given or not writeable; fixes #737
Signed-off-by: Michael Kaufmann <michael.kaufmann@aixit.com>
2019-10-22 15:06:41 +02:00
Michael Kaufmann
1fdc524171 correct permissions
Signed-off-by: Michael Kaufmann <michael.kaufmann@aixit.com>
2019-10-19 11:08:55 +02:00
Pascal
836b6f2fdb Merge remote-tracking branch 'upstream/master' 2019-05-10 02:54:33 +02:00
Pascal
f297058461 #564
fix wording
add validation for cidr syntax
add automatic transform of cidr to netmask for mysql
2019-05-04 00:39:12 +02:00
Pascal
0f4d8d76ae #564
fix wording
2019-05-03 23:31:31 +02:00
Pascal
12884c91a6 #564
fix #564 by allowing CIDR in mysql host validation. 
fix english and german field description accordingly
2019-05-03 22:32:57 +02:00
97 changed files with 3476 additions and 1592 deletions

1
.github/FUNDING.yml vendored
View File

@@ -1,3 +1,4 @@
# These are supported funding model platforms # These are supported funding model platforms
github: d00p
custom: ['https://paypal.me/Froxlor'] custom: ['https://paypal.me/Froxlor']

14
SECURITY.md Normal file
View File

@@ -0,0 +1,14 @@
# Security Policy
## Supported Versions
Our main and active version is currently 0.10.x. It will receive maintenance and security updates periodically. The older version 0.9.x will not receive any kind of updates. Please update to [0.10.x](https://github.com/Froxlor/Froxlor/wiki/Updating-Froxlor)
| Version | Supported |
| ------- | ------------------ |
| 0.10.x | :white_check_mark: |
| 0.9.x | :x: |
## Reporting a Vulnerability
If you think you have found a vulnerability in froxlor, please send an email to [team@froxlor.org](mailto:team@froxlor.org) with as many information as possible. Also, please give us appropriate time to fix the issue and build update-packages before publishing anything into the wild.

View File

@@ -43,23 +43,29 @@ if ($page == 'admins' && $userinfo['change_serversettings'] == '1') {
'traffic_used' => $lng['customer']['traffic'] . ' (' . $lng['panel']['used'] . ')', 'traffic_used' => $lng['customer']['traffic'] . ' (' . $lng['panel']['used'] . ')',
'deactivated' => $lng['admin']['deactivated'] 'deactivated' => $lng['admin']['deactivated']
); );
$paging = new \Froxlor\UI\Paging($userinfo, TABLE_PANEL_ADMINS, $fields); try {
// get total count
$json_result = Admins::getLocal($userinfo)->listingCount();
$result = json_decode($json_result, true)['data'];
// initialize pagination and filtering
$paging = new \Froxlor\UI\Pagination($userinfo, $fields, $result);
// get list
$json_result = Admins::getLocal($userinfo, $paging->getApiCommandParams())->listing();
} catch (Exception $e) {
\Froxlor\UI\Response::dynamic_error($e->getMessage());
}
$result = json_decode($json_result, true)['data'];
$admins = ''; $admins = '';
$result_stmt = Database::query("SELECT * FROM `" . TABLE_PANEL_ADMINS . "` " . $paging->getSqlWhere(false) . " " . $paging->getSqlOrderBy() . " " . $paging->getSqlLimit());
$numrows_admins = Database::num_rows();
$paging->setEntries($numrows_admins);
$sortcode = $paging->getHtmlSortCode($lng, true); $sortcode = $paging->getHtmlSortCode($lng, true);
$arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s);
$searchcode = $paging->getHtmlSearchCode($lng); $searchcode = $paging->getHtmlSearchCode($lng);
$pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s);
$i = 0;
$count = 0; $count = 0;
$dec_places = Settings::Get('panel.decimal_places'); $dec_places = Settings::Get('panel.decimal_places');
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { foreach ($result['list'] as $row) {
if ($paging->checkDisplay($i)) {
$row['traffic_used'] = round($row['traffic_used'] / (1024 * 1024), $dec_places); $row['traffic_used'] = round($row['traffic_used'] / (1024 * 1024), $dec_places);
$row['traffic'] = round($row['traffic'] / (1024 * 1024), $dec_places); $row['traffic'] = round($row['traffic'] / (1024 * 1024), $dec_places);
@@ -100,10 +106,8 @@ if ($page == 'admins' && $userinfo['change_serversettings'] == '1') {
eval("\$admins.=\"" . \Froxlor\UI\Template::getTemplate("admins/admins_admin") . "\";"); eval("\$admins.=\"" . \Froxlor\UI\Template::getTemplate("admins/admins_admin") . "\";");
$count ++; $count ++;
} }
$i ++;
}
$admincount = $numrows_admins; $admincount = $paging->getEntries();
eval("echo \"" . \Froxlor\UI\Template::getTemplate("admins/admins") . "\";"); eval("echo \"" . \Froxlor\UI\Template::getTemplate("admins/admins") . "\";");
} elseif ($action == 'su') { } elseif ($action == 'su') {

View File

@@ -17,8 +17,7 @@
define('AREA', 'admin'); define('AREA', 'admin');
require './lib/init.php'; require './lib/init.php';
use Froxlor\Database\Database; use Froxlor\Api\Commands\Cronjobs;
use Froxlor\Api\Commands\Cronjobs as Cronjobs;
if (isset($_POST['id'])) { if (isset($_POST['id'])) {
$id = intval($_POST['id']); $id = intval($_POST['id']);
@@ -31,47 +30,49 @@ if ($page == 'cronjobs' || $page == 'overview') {
$log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, 'viewed admin_cronjobs'); $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, 'viewed admin_cronjobs');
$fields = array( $fields = array(
'c.module' => 'Module',
'c.lastrun' => $lng['cron']['lastrun'], 'c.lastrun' => $lng['cron']['lastrun'],
'c.interval' => $lng['cron']['interval'], 'c.interval' => $lng['cron']['interval'],
'c.isactive' => $lng['cron']['isactive'] 'c.isactive' => $lng['cron']['isactive']
); );
$paging = new \Froxlor\UI\Paging($userinfo, TABLE_PANEL_CRONRUNS, $fields); try {
// get total count
$json_result = Cronjobs::getLocal($userinfo)->listingCount();
$result = json_decode($json_result, true)['data'];
// initialize pagination and filtering
$paging = new \Froxlor\UI\Pagination($userinfo, $fields, $result);
// get list
$json_result = Cronjobs::getLocal($userinfo, $paging->getApiCommandParams())->listing();
} catch (Exception $e) {
\Froxlor\UI\Response::dynamic_error($e->getMessage());
}
$result = json_decode($json_result, true)['data'];
$crons = ''; $crons = '';
$result_stmt = Database::prepare("SELECT `c`.* FROM `" . TABLE_PANEL_CRONRUNS . "` `c` ORDER BY `module` ASC, `cronfile` ASC");
Database::pexecute($result_stmt);
$paging->setEntries(Database::num_rows());
$sortcode = $paging->getHtmlSortCode($lng); $sortcode = $paging->getHtmlSortCode($lng);
$arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s);
$searchcode = $paging->getHtmlSearchCode($lng); $searchcode = $paging->getHtmlSearchCode($lng);
$pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s);
$i = 0;
$count = 0; $count = 0;
$cmod = ''; $cmod = '';
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { foreach ($result['list'] as $row) {
if ($cmod != $row['module']) { if ($cmod != $row['module']) {
$_mod = explode("/", $row['module']); $_mod = explode("/", $row['module']);
$module = ucfirst($_mod[1]); $module = ucfirst($_mod[1]);
eval("\$crons.=\"" . \Froxlor\UI\Template::getTemplate('cronjobs/cronjobs_cronjobmodule') . "\";"); eval("\$crons.=\"" . \Froxlor\UI\Template::getTemplate('cronjobs/cronjobs_cronjobmodule') . "\";");
$cmod = $row['module']; $cmod = $row['module'];
} }
if ($paging->checkDisplay($i)) {
$row = \Froxlor\PhpHelper::htmlentitiesArray($row); $row = \Froxlor\PhpHelper::htmlentitiesArray($row);
$row['lastrun'] = date('d.m.Y H:i', $row['lastrun']); $row['lastrun'] = date('d.m.Y H:i', $row['lastrun']);
$row['isactive'] = ((int) $row['isactive'] == 1) ? $lng['panel']['yes'] : $lng['panel']['no']; $row['isactive'] = ((int) $row['isactive'] == 1) ? $lng['panel']['yes'] : $lng['panel']['no'];
$description = $lng['crondesc'][$row['desc_lng_key']]; $description = $lng['crondesc'][$row['desc_lng_key']];
eval("\$crons.=\"" . \Froxlor\UI\Template::getTemplate('cronjobs/cronjobs_cronjob') . "\";"); eval("\$crons.=\"" . \Froxlor\UI\Template::getTemplate('cronjobs/cronjobs_cronjob') . "\";");
$count ++; $count ++;
} }
$i ++;
}
eval("echo \"" . \Froxlor\UI\Template::getTemplate('cronjobs/cronjobs') . "\";"); eval("echo \"" . \Froxlor\UI\Template::getTemplate('cronjobs/cronjobs') . "\";");
} elseif ($action == 'new') { } elseif ($action == 'new') {
/* /*

View File

@@ -35,6 +35,7 @@ if ($page == 'customers' && $userinfo['customers'] != '0') {
unset($_SESSION['requestData']); unset($_SESSION['requestData']);
$log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "viewed admin_customers"); $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "viewed admin_customers");
$fields = array( $fields = array(
'c.loginname' => $lng['login']['username'], 'c.loginname' => $lng['login']['username'],
'a.loginname' => $lng['admin']['admin'], 'a.loginname' => $lng['admin']['admin'],
@@ -47,36 +48,35 @@ if ($page == 'customers' && $userinfo['customers'] != '0') {
'c.traffic' => $lng['customer']['traffic'], 'c.traffic' => $lng['customer']['traffic'],
'c.traffic_used' => $lng['customer']['traffic'] . ' (' . $lng['panel']['used'] . ')' 'c.traffic_used' => $lng['customer']['traffic'] . ' (' . $lng['panel']['used'] . ')'
); );
try {
// get total count
$json_result = Customers::getLocal($userinfo)->listingCount();
$result = json_decode($json_result, true)['data'];
// initialize pagination and filtering
$paging = new \Froxlor\UI\Pagination($userinfo, $fields, $result);
// get list
$json_result = Customers::getLocal($userinfo, $paging->getApiCommandParams())->listing();
} catch (Exception $e) {
\Froxlor\UI\Response::dynamic_error($e->getMessage());
}
$result = json_decode($json_result, true)['data'];
$paging = new \Froxlor\UI\Paging($userinfo, TABLE_PANEL_CUSTOMERS, $fields);
$customers = ''; $customers = '';
$result_stmt = Database::prepare("
SELECT `c`.*, `a`.`loginname` AS `adminname`
FROM `" . TABLE_PANEL_CUSTOMERS . "` `c`, `" . TABLE_PANEL_ADMINS . "` `a`
WHERE " . ($userinfo['customers_see_all'] ? '' : " `c`.`adminid` = :adminid AND ") . "
`c`.`adminid` = `a`.`adminid` " . $paging->getSqlWhere(true) . " " . $paging->getSqlOrderBy() . " " . $paging->getSqlLimit());
Database::pexecute($result_stmt, array(
'adminid' => $userinfo['adminid']
));
$num_rows = Database::num_rows();
$paging->setEntries($num_rows);
$sortcode = $paging->getHtmlSortCode($lng, true); $sortcode = $paging->getHtmlSortCode($lng, true);
$arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s);
$searchcode = $paging->getHtmlSearchCode($lng); $searchcode = $paging->getHtmlSearchCode($lng);
$pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s);
$i = 0;
$count = 0; $count = 0;
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { foreach ($result['list'] as $row) {
if ($paging->checkDisplay($i)) {
$domains_stmt = Database::prepare(" $domains_stmt = Database::prepare("
SELECT COUNT(`id`) AS `domains` SELECT COUNT(`id`) AS `domains`
FROM `" . TABLE_PANEL_DOMAINS . "` FROM `" . TABLE_PANEL_DOMAINS . "`
WHERE `customerid` = :cid WHERE `customerid` = :cid
AND `parentdomainid` = '0' AND `parentdomainid` = '0'
AND `id`<> :stdd"); AND `id`<> :stdd
");
Database::pexecute($domains_stmt, array( Database::pexecute($domains_stmt, array(
'cid' => $row['customerid'], 'cid' => $row['customerid'],
'stdd' => $row['standardsubdomain'] 'stdd' => $row['standardsubdomain']
@@ -86,13 +86,16 @@ if ($page == 'customers' && $userinfo['customers'] != '0') {
$dec_places = Settings::Get('panel.decimal_places'); $dec_places = Settings::Get('panel.decimal_places');
// get disk-space usages for web, mysql and mail // get disk-space usages for web, mysql and mail
$usages_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_DISKSPACE . "` WHERE `customerid` = :cid ORDER BY `stamp` DESC LIMIT 1"); $usages_stmt = Database::prepare("
SELECT * FROM `" . TABLE_PANEL_DISKSPACE . "`
WHERE `customerid` = :cid
ORDER BY `stamp` DESC LIMIT 1
");
$usages = Database::pexecute_first($usages_stmt, array( $usages = Database::pexecute_first($usages_stmt, array(
'cid' => $row['customerid'] 'cid' => $row['customerid']
)); ));
if ($usages) if ($usages) {
{
$row['webspace_used'] = round($usages['webspace'] / 1024, $dec_places); $row['webspace_used'] = round($usages['webspace'] / 1024, $dec_places);
$row['mailspace_used'] = round($usages['mail'] / 1024, $dec_places); $row['mailspace_used'] = round($usages['mail'] / 1024, $dec_places);
$row['dbspace_used'] = round($usages['mysql'] / 1024, $dec_places); $row['dbspace_used'] = round($usages['mysql'] / 1024, $dec_places);
@@ -110,7 +113,6 @@ if ($page == 'customers' && $userinfo['customers'] != '0') {
/** /**
* percent-values for progressbar * percent-values for progressbar
*/ */
// For Disk usage
if ($row['diskspace'] > 0) { if ($row['diskspace'] > 0) {
$disk_percent = round(($row['diskspace_used'] * 100) / $row['diskspace'], 0); $disk_percent = round(($row['diskspace_used'] * 100) / $row['diskspace'], 0);
$disk_doublepercent = round($disk_percent * 2, 2); $disk_doublepercent = round($disk_percent * 2, 2);
@@ -118,7 +120,6 @@ if ($page == 'customers' && $userinfo['customers'] != '0') {
$disk_percent = 0; $disk_percent = 0;
$disk_doublepercent = 0; $disk_doublepercent = 0;
} }
if ($row['traffic'] > 0) { if ($row['traffic'] > 0) {
$traffic_percent = round(($row['traffic_used'] * 100) / $row['traffic'], 0); $traffic_percent = round(($row['traffic_used'] * 100) / $row['traffic'], 0);
$traffic_doublepercent = round($traffic_percent * 2, 2); $traffic_doublepercent = round($traffic_percent * 2, 2);
@@ -149,10 +150,7 @@ if ($page == 'customers' && $userinfo['customers'] != '0') {
$count ++; $count ++;
} }
$i ++; $customercount = $paging->getEntries();
}
$customercount = $num_rows;
eval("echo \"" . \Froxlor\UI\Template::getTemplate("customers/customers") . "\";"); eval("echo \"" . \Froxlor\UI\Template::getTemplate("customers/customers") . "\";");
} elseif ($action == 'su' && $id != 0) { } elseif ($action == 'su' && $id != 0) {
try { try {

View File

@@ -21,6 +21,7 @@ require './lib/init.php';
use Froxlor\Database\Database; use Froxlor\Database\Database;
use Froxlor\Settings; use Froxlor\Settings;
use Froxlor\Api\Commands\Customers as Customers;
use Froxlor\Api\Commands\Domains as Domains; use Froxlor\Api\Commands\Domains as Domains;
if (isset($_POST['id'])) { if (isset($_POST['id'])) {
@@ -31,14 +32,8 @@ if (isset($_POST['id'])) {
if ($page == 'domains' || $page == 'overview') { if ($page == 'domains' || $page == 'overview') {
// Let's see how many customers we have // Let's see how many customers we have
$stmt = Database::prepare(" $json_result = Customers::getLocal($userinfo)->listingCount();
SELECT COUNT(`customerid`) as `countcustomers` FROM `" . TABLE_PANEL_CUSTOMERS . "` " . ($userinfo['customers_see_all'] ? '' : " WHERE `adminid` = :adminid")); $countcustomers = json_decode($json_result, true)['data'];
$params = array();
if ($userinfo['customers_see_all'] == '0') {
$params['adminid'] = $userinfo['adminid'];
}
$countcustomers = Database::pexecute_first($stmt, $params);
$countcustomers = (int) $countcustomers['countcustomers'];
if ($action == '') { if ($action == '') {
@@ -51,28 +46,27 @@ if ($page == 'domains' || $page == 'overview') {
'c.loginname' => $lng['login']['username'], 'c.loginname' => $lng['login']['username'],
'd.aliasdomain' => $lng['domains']['aliasdomain'] 'd.aliasdomain' => $lng['domains']['aliasdomain']
); );
$paging = new \Froxlor\UI\Paging($userinfo, TABLE_PANEL_DOMAINS, $fields); try {
$domains = ""; // get total count
$result_stmt = Database::prepare(" $json_result = Domains::getLocal($userinfo)->listingCount();
SELECT `d`.*, `c`.`loginname`, `c`.`deactivated`, `c`.`name`, `c`.`firstname`, `c`.`company`, `c`.`standardsubdomain`, `ad`.`id` AS `aliasdomainid`, `ad`.`domain` AS `aliasdomain` $result = json_decode($json_result, true)['data'];
FROM `" . TABLE_PANEL_DOMAINS . "` `d` // initialize pagination and filtering
LEFT JOIN `" . TABLE_PANEL_CUSTOMERS . "` `c` USING(`customerid`) $paging = new \Froxlor\UI\Pagination($userinfo, $fields, $result);
LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` `ad` ON `d`.`aliasdomain`=`ad`.`id` // get list
WHERE `d`.`parentdomainid`='0' " . ($userinfo['customers_see_all'] ? '' : " AND `d`.`adminid` = :adminid ") . " " . $paging->getSqlWhere(true) . " " . $paging->getSqlOrderBy() . " " . $paging->getSqlLimit()); $json_result = Domains::getLocal($userinfo, $paging->getApiCommandParams())->listing();
$params = array(); } catch (Exception $e) {
if ($userinfo['customers_see_all'] == '0') { \Froxlor\UI\Response::dynamic_error($e->getMessage());
$params['adminid'] = $userinfo['adminid'];
} }
Database::pexecute($result_stmt, $params); $result = json_decode($json_result, true)['data'];
$numrows_domains = Database::num_rows();
$paging->setEntries($numrows_domains); $domains = '';
$sortcode = $paging->getHtmlSortCode($lng); $sortcode = $paging->getHtmlSortCode($lng);
$arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s);
$searchcode = $paging->getHtmlSearchCode($lng); $searchcode = $paging->getHtmlSearchCode($lng);
$pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s);
$domain_array = array(); $domain_array = array();
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { foreach ($result['list'] as $row) {
formatDomainEntry($row, $idna_convert); formatDomainEntry($row, $idna_convert);
@@ -100,11 +94,10 @@ if ($page == 'domains' || $page == 'overview') {
krsort($domain_array); krsort($domain_array);
} }
$i = 0;
$count = 0; $count = 0;
foreach ($domain_array as $row) { foreach ($domain_array as $row) {
if (isset($row['domain']) && $row['domain'] != '' && $paging->checkDisplay($i)) { if (isset($row['domain']) && $row['domain'] != '') {
$row['customername'] = \Froxlor\User::getCorrectFullUserDetails($row); $row['customername'] = \Froxlor\User::getCorrectFullUserDetails($row);
$row = \Froxlor\PhpHelper::htmlentitiesArray($row); $row = \Froxlor\PhpHelper::htmlentitiesArray($row);
// display a nice list of IP's // display a nice list of IP's
@@ -112,10 +105,9 @@ if ($page == 'domains' || $page == 'overview') {
eval("\$domains.=\"" . \Froxlor\UI\Template::getTemplate("domains/domains_domain") . "\";"); eval("\$domains.=\"" . \Froxlor\UI\Template::getTemplate("domains/domains_domain") . "\";");
$count ++; $count ++;
} }
$i ++;
} }
$domainscount = $numrows_domains; $domainscount = $paging->getEntries();
// Display the list // Display the list
eval("echo \"" . \Froxlor\UI\Template::getTemplate("domains/domains") . "\";"); eval("echo \"" . \Froxlor\UI\Template::getTemplate("domains/domains") . "\";");
@@ -416,6 +408,10 @@ if ($page == 'domains' || $page == 'overview') {
if (isset($_POST['send']) && $_POST['send'] == 'send') { if (isset($_POST['send']) && $_POST['send'] == 'send') {
try { try {
// remove ssl ip/ports if set is empty
if (isset($_POST['ssl_ipandport']) && empty($_POST['ssl_ipandport'])) {
$_POST['remove_ssl_ipandport'] = true;
}
Domains::getLocal($userinfo, $_POST)->update(); Domains::getLocal($userinfo, $_POST)->update();
} catch (Exception $e) { } catch (Exception $e) {
\Froxlor\UI\Response::dynamic_error($e->getMessage()); \Froxlor\UI\Response::dynamic_error($e->getMessage());
@@ -717,18 +713,8 @@ function formatDomainEntry(&$row, &$idna_convert)
$row['domain'] = $idna_convert->decode($row['domain']); $row['domain'] = $idna_convert->decode($row['domain']);
$row['aliasdomain'] = $idna_convert->decode($row['aliasdomain']); $row['aliasdomain'] = $idna_convert->decode($row['aliasdomain']);
$resultips_stmt = Database::prepare("
SELECT `ips`.* FROM `" . TABLE_DOMAINTOIP . "` AS `dti`, `" . TABLE_PANEL_IPSANDPORTS . "` AS `ips`
WHERE `dti`.`id_ipandports` = `ips`.`id` AND `dti`.`id_domain` = :domainid
");
Database::pexecute($resultips_stmt, array(
'domainid' => $row['id']
));
$row['ipandport'] = ''; $row['ipandport'] = '';
while ($rowip = $resultips_stmt->fetch(PDO::FETCH_ASSOC)) { foreach ($row['ipsandports'] as $rowip) {
if (filter_var($rowip['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { if (filter_var($rowip['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
$row['ipandport'] .= '[' . $rowip['ip'] . ']:' . $rowip['port'] . "\n"; $row['ipandport'] .= '[' . $rowip['ip'] . ']:' . $rowip['port'] . "\n";
} else { } else {

View File

@@ -19,9 +19,8 @@
define('AREA', 'admin'); define('AREA', 'admin');
require './lib/init.php'; require './lib/init.php';
use Froxlor\Database\Database;
use Froxlor\Settings; use Froxlor\Settings;
use Froxlor\Api\Commands\IpsAndPorts as IpsAndPorts; use Froxlor\Api\Commands\IpsAndPorts;
if (isset($_POST['id'])) { if (isset($_POST['id'])) {
$id = intval($_POST['id']); $id = intval($_POST['id']);
@@ -43,21 +42,27 @@ if ($page == 'ipsandports' || $page == 'overview') {
'ip' => $lng['admin']['ipsandports']['ip'], 'ip' => $lng['admin']['ipsandports']['ip'],
'port' => $lng['admin']['ipsandports']['port'] 'port' => $lng['admin']['ipsandports']['port']
); );
$paging = new \Froxlor\UI\Paging($userinfo, TABLE_PANEL_IPSANDPORTS, $fields); try {
// get total count
$json_result = IpsAndPorts::getLocal($userinfo)->listingCount();
$result = json_decode($json_result, true)['data'];
// initialize pagination and filtering
$paging = new \Froxlor\UI\Pagination($userinfo, $fields, $result);
// get list
$json_result = IpsAndPorts::getLocal($userinfo, $paging->getApiCommandParams())->listing();
} catch (Exception $e) {
\Froxlor\UI\Response::dynamic_error($e->getMessage());
}
$result = json_decode($json_result, true)['data'];
$ipsandports = ''; $ipsandports = '';
$result_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_IPSANDPORTS . "` " . $paging->getSqlWhere(false) . " " . $paging->getSqlOrderBy() . " " . $paging->getSqlLimit());
Database::pexecute($result_stmt);
$paging->setEntries(Database::num_rows());
$sortcode = $paging->getHtmlSortCode($lng); $sortcode = $paging->getHtmlSortCode($lng);
$arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s);
$searchcode = $paging->getHtmlSearchCode($lng); $searchcode = $paging->getHtmlSearchCode($lng);
$pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s);
$i = 0;
$count = 0; $count = 0;
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { foreach ($result['list'] as $row) {
if ($paging->checkDisplay($i)) {
$row = \Froxlor\PhpHelper::htmlentitiesArray($row); $row = \Froxlor\PhpHelper::htmlentitiesArray($row);
if (filter_var($row['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { if (filter_var($row['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
$row['ip'] = '[' . $row['ip'] . ']'; $row['ip'] = '[' . $row['ip'] . ']';
@@ -65,8 +70,6 @@ if ($page == 'ipsandports' || $page == 'overview') {
eval("\$ipsandports.=\"" . \Froxlor\UI\Template::getTemplate("ipsandports/ipsandports_ipandport") . "\";"); eval("\$ipsandports.=\"" . \Froxlor\UI\Template::getTemplate("ipsandports/ipsandports_ipandport") . "\";");
$count ++; $count ++;
} }
$i ++;
}
eval("echo \"" . \Froxlor\UI\Template::getTemplate("ipsandports/ipsandports") . "\";"); eval("echo \"" . \Froxlor\UI\Template::getTemplate("ipsandports/ipsandports") . "\";");
} elseif ($action == 'delete' && $id != 0) { } elseif ($action == 'delete' && $id != 0) {
try { try {

View File

@@ -19,7 +19,7 @@
define('AREA', 'admin'); define('AREA', 'admin');
require './lib/init.php'; require './lib/init.php';
use Froxlor\Database\Database; use Froxlor\Api\Commands\SysLog;
if ($page == 'log' && $userinfo['change_serversettings'] == '1') { if ($page == 'log' && $userinfo['change_serversettings'] == '1') {
if ($action == '') { if ($action == '') {
@@ -29,20 +29,25 @@ if ($page == 'log' && $userinfo['change_serversettings'] == '1') {
'user' => $lng['logger']['user'], 'user' => $lng['logger']['user'],
'text' => $lng['logger']['action'] 'text' => $lng['logger']['action']
); );
$paging = new \Froxlor\UI\Paging($userinfo, TABLE_PANEL_LOG, $fields, null, null, 0, 'desc', 30); try {
$query = 'SELECT * FROM `' . TABLE_PANEL_LOG . '` ' . $paging->getSqlWhere(false) . ' ' . $paging->getSqlOrderBy(); // get total count
$result_stmt = Database::query($query . ' ' . $paging->getSqlLimit()); $json_result = SysLog::getLocal($userinfo)->listingCount();
$result_cnt_stmt = Database::query($query); $result = json_decode($json_result, true)['data'];
$logs_count = $result_cnt_stmt->rowCount(); // initialize pagination and filtering
$paging->setEntries($logs_count); $paging = new \Froxlor\UI\Pagination($userinfo, $fields, $result);
// get list
$json_result = SysLog::getLocal($userinfo, $paging->getApiCommandParams())->listing();
} catch (Exception $e) {
\Froxlor\UI\Response::dynamic_error($e->getMessage());
}
$result = json_decode($json_result, true)['data'];
$sortcode = $paging->getHtmlSortCode($lng); $sortcode = $paging->getHtmlSortCode($lng);
$arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s);
$searchcode = $paging->getHtmlSearchCode($lng); $searchcode = $paging->getHtmlSearchCode($lng);
$pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s);
$clog = array(); $clog = array();
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { foreach ($result['list'] as $row) {
if (! isset($clog[$row['action']]) || ! is_array($clog[$row['action']])) { if (! isset($clog[$row['action']]) || ! is_array($clog[$row['action']])) {
$clog[$row['action']] = array(); $clog[$row['action']] = array();
} }
@@ -55,7 +60,6 @@ if ($page == 'log' && $userinfo['change_serversettings'] == '1') {
ksort($clog); ksort($clog);
} }
$i = 0;
$count = 0; $count = 0;
$log_count = 0; $log_count = 0;
$log = ''; $log = '';
@@ -100,23 +104,20 @@ if ($page == 'log' && $userinfo['change_serversettings'] == '1') {
eval("\$log.=\"" . \Froxlor\UI\Template::getTemplate('logger/logger_log') . "\";"); eval("\$log.=\"" . \Froxlor\UI\Template::getTemplate('logger/logger_log') . "\";");
$count ++; $count ++;
$_action = $action; $_action = $action;
// }
$i ++;
} }
$i ++;
} }
eval("echo \"" . \Froxlor\UI\Template::getTemplate('logger/logger') . "\";"); eval("echo \"" . \Froxlor\UI\Template::getTemplate('logger/logger') . "\";");
} elseif ($action == 'truncate') { } elseif ($action == 'truncate') {
if (isset($_POST['send']) && $_POST['send'] == 'send') { if (isset($_POST['send']) && $_POST['send'] == 'send') {
$truncatedate = time() - (60 * 10); try {
$trunc_stmt = Database::prepare(" SysLog::getLocal($userinfo, array(
DELETE FROM `" . TABLE_PANEL_LOG . "` WHERE `date` < :trunc"); 'min_to_keep' => 10
Database::pexecute($trunc_stmt, array( ))->delete();
'trunc' => $truncatedate } catch (Exception $e) {
)); \Froxlor\UI\Response::dynamic_error($e->getMessage());
$log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, 'truncated the system-log (mysql)'); }
\Froxlor\UI\Response::redirectTo($filename, array( \Froxlor\UI\Response::redirectTo($filename, array(
'page' => $page, 'page' => $page,
's' => $s 's' => $s

View File

@@ -52,7 +52,7 @@ if ($page == 'overview') {
$domains = ""; $domains = "";
$subdomains_count = count($row['subdomains']); $subdomains_count = count($row['subdomains']);
foreach ($row['domains'] as $configdomain) { foreach ($row['domains'] as $configdomain) {
$domains .= $configdomain . "<br>"; $domains .= $idna_convert->decode($configdomain) . "<br>";
} }
$count ++; $count ++;
if ($subdomains_count == 0 && empty($domains)) { if ($subdomains_count == 0 && empty($domains)) {

View File

@@ -38,34 +38,32 @@ if ($page == '' || $page == 'overview') {
'adminname' => $lng['admin']['admin'], 'adminname' => $lng['admin']['admin'],
'p.ts' => $lng['admin']['plans']['last_update'] 'p.ts' => $lng['admin']['plans']['last_update']
); );
$paging = new \Froxlor\UI\Paging($userinfo, TABLE_PANEL_PLANS, $fields); try {
// get total count
$json_result = HostingPlans::getLocal($userinfo)->listingCount();
$result = json_decode($json_result, true)['data'];
// initialize pagination and filtering
$paging = new \Froxlor\UI\Pagination($userinfo, $fields, $result);
// get list
$json_result = HostingPlans::getLocal($userinfo, $paging->getApiCommandParams())->listing();
} catch (Exception $e) {
\Froxlor\UI\Response::dynamic_error($e->getMessage());
}
$result = json_decode($json_result, true)['data'];
$plans = ''; $plans = '';
$result_stmt = Database::prepare("
SELECT p.*, a.loginname as adminname
FROM `" . TABLE_PANEL_PLANS . "` p, `" . TABLE_PANEL_ADMINS . "` a
WHERE " . ($userinfo['customers_see_all'] ? '' : " `p`.`adminid` = :adminid AND ") . "
`p`.`adminid` = `a`.`adminid` " . $paging->getSqlWhere(false) . " " . $paging->getSqlOrderBy() . " " . $paging->getSqlLimit());
Database::pexecute($result_stmt, array(
'adminid' => $userinfo['adminid']
));
$paging->setEntries(Database::num_rows());
$sortcode = $paging->getHtmlSortCode($lng); $sortcode = $paging->getHtmlSortCode($lng);
$arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s);
$searchcode = $paging->getHtmlSearchCode($lng); $searchcode = $paging->getHtmlSearchCode($lng);
$pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s);
$i = 0;
$count = 0; $count = 0;
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { foreach ($result['list'] as $row) {
if ($paging->checkDisplay($i)) {
$row = \Froxlor\PhpHelper::htmlentitiesArray($row); $row = \Froxlor\PhpHelper::htmlentitiesArray($row);
$row['ts_format'] = date("d.m.Y H:i", $row['ts']); $row['ts_format'] = date("d.m.Y H:i", $row['ts']);
eval("\$plans.=\"" . \Froxlor\UI\Template::getTemplate("plans/plans_plan") . "\";"); eval("\$plans.=\"" . \Froxlor\UI\Template::getTemplate("plans/plans_plan") . "\";");
$count ++; $count ++;
} }
$i ++;
}
eval("echo \"" . \Froxlor\UI\Template::getTemplate("plans/plans") . "\";"); eval("echo \"" . \Froxlor\UI\Template::getTemplate("plans/plans") . "\";");
} elseif ($action == 'delete' && $id != 0) { } elseif ($action == 'delete' && $id != 0) {
@@ -191,9 +189,7 @@ if ($page == '' || $page == 'overview') {
if (isset($_POST['send']) && $_POST['send'] == 'send') { if (isset($_POST['send']) && $_POST['send'] == 'send') {
try { try {
HostingPlans::getLocal($userinfo, array( HostingPlans::getLocal($userinfo, $_POST)->update();
'id' => $id
))->update();
} catch (Exception $e) { } catch (Exception $e) {
\Froxlor\UI\Response::dynamic_error($e->getMessage()); \Froxlor\UI\Response::dynamic_error($e->getMessage());
} }
@@ -289,6 +285,7 @@ if ($page == '' || $page == 'overview') {
$result['customernumber'] = null; $result['customernumber'] = null;
$result['custom_notes'] = null; $result['custom_notes'] = null;
$result['custom_notes_show'] = null; $result['custom_notes_show'] = null;
$result['api_allowed'] = null;
$hosting_plans = null; $hosting_plans = null;
$admin_select_cnt = null; $admin_select_cnt = null;
$admin_select = null; $admin_select = null;

View File

@@ -23,7 +23,7 @@ if (empty($request)) {
} }
// decode json request // decode json request
$decoded_request = json_decode(stripslashes($request), true); $decoded_request = json_decode($request, true);
// is it valid? // is it valid?
if (is_null($decoded_request)) { if (is_null($decoded_request)) {
@@ -32,6 +32,7 @@ if (is_null($decoded_request)) {
// validate content // validate content
try { try {
$decoded_request = stripcslashes_deep($decoded_request);
$request = \Froxlor\Api\FroxlorRPC::validateRequest($decoded_request); $request = \Froxlor\Api\FroxlorRPC::validateRequest($decoded_request);
// now actually do it // now actually do it
$cls = "\\Froxlor\\Api\\Commands\\" . $request['command']['class']; $cls = "\\Froxlor\\Api\\Commands\\" . $request['command']['class'];
@@ -72,3 +73,8 @@ function json_response($status, $status_message = '', $data = null)
echo $json_response; echo $json_response;
exit(); exit();
} }
function stripcslashes_deep($value)
{
return is_array($value) ? array_map('stripcslashes_deep', $value) : stripcslashes($value);
}

View File

@@ -49,7 +49,7 @@
"algo26-matthias/idna-convert": "^2.1" "algo26-matthias/idna-convert": "^2.1"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^8", "phpunit/phpunit": "8.4.1",
"php": ">=7.3", "php": ">=7.3",
"ext-pcntl": "*", "ext-pcntl": "*",
"phpcompatibility/php-compatibility": "*", "phpcompatibility/php-compatibility": "*",

87
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "77819131afd1abe70f1ea6caad9fc3e5", "content-hash": "5699c65bbdcd2a61a9ced0ac7be84d64",
"packages": [ "packages": [
{ {
"name": "algo26-matthias/idna-convert", "name": "algo26-matthias/idna-convert",
@@ -200,16 +200,16 @@
}, },
{ {
"name": "psr/log", "name": "psr/log",
"version": "1.1.0", "version": "1.1.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/php-fig/log.git", "url": "https://github.com/php-fig/log.git",
"reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd" "reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", "url": "https://api.github.com/repos/php-fig/log/zipball/446d54b4cb6bf489fc9d75f55843658e6f25d801",
"reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", "reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -218,7 +218,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.0.x-dev" "dev-master": "1.1.x-dev"
} }
}, },
"autoload": { "autoload": {
@@ -243,7 +243,7 @@
"psr", "psr",
"psr-3" "psr-3"
], ],
"time": "2018-11-20T15:27:04+00:00" "time": "2019-11-01T11:05:21+00:00"
}, },
{ {
"name": "robthree/twofactorauth", "name": "robthree/twofactorauth",
@@ -404,16 +404,16 @@
}, },
{ {
"name": "nikic/php-parser", "name": "nikic/php-parser",
"version": "v4.2.4", "version": "v4.2.5",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/nikic/PHP-Parser.git", "url": "https://github.com/nikic/PHP-Parser.git",
"reference": "97e59c7a16464196a8b9c77c47df68e4a39a45c4" "reference": "b76bbc3c51f22c570648de48e8c2d941ed5e2cf2"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/97e59c7a16464196a8b9c77c47df68e4a39a45c4", "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/b76bbc3c51f22c570648de48e8c2d941ed5e2cf2",
"reference": "97e59c7a16464196a8b9c77c47df68e4a39a45c4", "reference": "b76bbc3c51f22c570648de48e8c2d941ed5e2cf2",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -421,6 +421,7 @@
"php": ">=7.0" "php": ">=7.0"
}, },
"require-dev": { "require-dev": {
"ircmaxell/php-yacc": "0.0.4",
"phpunit/phpunit": "^6.5 || ^7.0 || ^8.0" "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0"
}, },
"bin": [ "bin": [
@@ -451,7 +452,7 @@
"parser", "parser",
"php" "php"
], ],
"time": "2019-09-01T07:51:21+00:00" "time": "2019-10-25T18:33:07+00:00"
}, },
{ {
"name": "pdepend/pdepend", "name": "pdepend/pdepend",
@@ -597,16 +598,16 @@
}, },
{ {
"name": "phpcompatibility/php-compatibility", "name": "phpcompatibility/php-compatibility",
"version": "9.3.1", "version": "9.3.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/PHPCompatibility/PHPCompatibility.git", "url": "https://github.com/PHPCompatibility/PHPCompatibility.git",
"reference": "9999344e47e7af6b00e1a898eacc4e4368fb7196" "reference": "bfca2be3992f40e92206e5a7ebe5eaee37280b58"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/9999344e47e7af6b00e1a898eacc4e4368fb7196", "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/bfca2be3992f40e92206e5a7ebe5eaee37280b58",
"reference": "9999344e47e7af6b00e1a898eacc4e4368fb7196", "reference": "bfca2be3992f40e92206e5a7ebe5eaee37280b58",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -651,7 +652,7 @@
"phpcs", "phpcs",
"standards" "standards"
], ],
"time": "2019-09-05T18:36:49+00:00" "time": "2019-10-16T21:24:24+00:00"
}, },
{ {
"name": "phpdocumentor/reflection-common", "name": "phpdocumentor/reflection-common",
@@ -2074,16 +2075,16 @@
}, },
{ {
"name": "squizlabs/php_codesniffer", "name": "squizlabs/php_codesniffer",
"version": "3.5.0", "version": "3.5.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/squizlabs/PHP_CodeSniffer.git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
"reference": "0afebf16a2e7f1e434920fa976253576151effe9" "reference": "65b12cdeaaa6cd276d4c3033a95b9b88b12701e7"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/0afebf16a2e7f1e434920fa976253576151effe9", "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/65b12cdeaaa6cd276d4c3033a95b9b88b12701e7",
"reference": "0afebf16a2e7f1e434920fa976253576151effe9", "reference": "65b12cdeaaa6cd276d4c3033a95b9b88b12701e7",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -2121,20 +2122,20 @@
"phpcs", "phpcs",
"standards" "standards"
], ],
"time": "2019-09-26T23:12:26+00:00" "time": "2019-10-28T04:36:32+00:00"
}, },
{ {
"name": "symfony/config", "name": "symfony/config",
"version": "v4.3.5", "version": "v4.3.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/config.git", "url": "https://github.com/symfony/config.git",
"reference": "0acb26407a9e1a64a275142f0ae5e36436342720" "reference": "f4ee0ebb91b16ca1ac105aa39f9284f3cac19a15"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/config/zipball/0acb26407a9e1a64a275142f0ae5e36436342720", "url": "https://api.github.com/repos/symfony/config/zipball/f4ee0ebb91b16ca1ac105aa39f9284f3cac19a15",
"reference": "0acb26407a9e1a64a275142f0ae5e36436342720", "reference": "f4ee0ebb91b16ca1ac105aa39f9284f3cac19a15",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -2185,20 +2186,20 @@
], ],
"description": "Symfony Config Component", "description": "Symfony Config Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2019-09-19T15:51:53+00:00" "time": "2019-10-30T13:18:51+00:00"
}, },
{ {
"name": "symfony/console", "name": "symfony/console",
"version": "v4.3.5", "version": "v4.3.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/console.git", "url": "https://github.com/symfony/console.git",
"reference": "929ddf360d401b958f611d44e726094ab46a7369" "reference": "136c4bd62ea871d00843d1bc0316de4c4a84bb78"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/929ddf360d401b958f611d44e726094ab46a7369", "url": "https://api.github.com/repos/symfony/console/zipball/136c4bd62ea871d00843d1bc0316de4c4a84bb78",
"reference": "929ddf360d401b958f611d44e726094ab46a7369", "reference": "136c4bd62ea871d00843d1bc0316de4c4a84bb78",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -2260,20 +2261,20 @@
], ],
"description": "Symfony Console Component", "description": "Symfony Console Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2019-10-07T12:36:49+00:00" "time": "2019-10-30T12:58:49+00:00"
}, },
{ {
"name": "symfony/dependency-injection", "name": "symfony/dependency-injection",
"version": "v4.3.5", "version": "v4.3.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/dependency-injection.git", "url": "https://github.com/symfony/dependency-injection.git",
"reference": "e1e0762a814b957a1092bff75a550db49724d05b" "reference": "fc036941dfafa037a7485714b62593c7eaf68edd"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/e1e0762a814b957a1092bff75a550db49724d05b", "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/fc036941dfafa037a7485714b62593c7eaf68edd",
"reference": "e1e0762a814b957a1092bff75a550db49724d05b", "reference": "fc036941dfafa037a7485714b62593c7eaf68edd",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -2333,11 +2334,11 @@
], ],
"description": "Symfony DependencyInjection Component", "description": "Symfony DependencyInjection Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2019-10-02T12:58:58+00:00" "time": "2019-10-28T17:07:32+00:00"
}, },
{ {
"name": "symfony/filesystem", "name": "symfony/filesystem",
"version": "v4.3.5", "version": "v4.3.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/filesystem.git", "url": "https://github.com/symfony/filesystem.git",
@@ -2387,16 +2388,16 @@
}, },
{ {
"name": "symfony/finder", "name": "symfony/finder",
"version": "v4.3.5", "version": "v4.3.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/finder.git", "url": "https://github.com/symfony/finder.git",
"reference": "5e575faa95548d0586f6bedaeabec259714e44d1" "reference": "72a068f77e317ae77c0a0495236ad292cfb5ce6f"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/5e575faa95548d0586f6bedaeabec259714e44d1", "url": "https://api.github.com/repos/symfony/finder/zipball/72a068f77e317ae77c0a0495236ad292cfb5ce6f",
"reference": "5e575faa95548d0586f6bedaeabec259714e44d1", "reference": "72a068f77e317ae77c0a0495236ad292cfb5ce6f",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -2432,7 +2433,7 @@
], ],
"description": "Symfony Finder Component", "description": "Symfony Finder Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2019-09-16T11:29:48+00:00" "time": "2019-10-30T12:53:54+00:00"
}, },
{ {
"name": "symfony/polyfill-ctype", "name": "symfony/polyfill-ctype",

View File

@@ -44,144 +44,74 @@ if ($page == 'overview') {
$fields = array( $fields = array(
'd.domain' => $lng['domains']['domainname'] 'd.domain' => $lng['domains']['domainname']
); );
$paging = new \Froxlor\UI\Paging($userinfo, TABLE_PANEL_DOMAINS, $fields); try {
$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`.`registration_date`, `d`.`termination_date`, `ad`.`id` AS `aliasdomainid`, `ad`.`domain` AS `aliasdomain`, `da`.`id` AS `domainaliasid`, `da`.`domain` AS `domainalias` FROM `" . TABLE_PANEL_DOMAINS . "` `d` // get total count
LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` `ad` ON `d`.`aliasdomain`=`ad`.`id` $json_result = SubDomains::getLocal($userinfo)->listingCount();
LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` `da` ON `da`.`aliasdomain`=`d`.`id` $result = json_decode($json_result, true)['data'];
WHERE `d`.`customerid`= :customerid // initialize pagination and filtering
AND `d`.`email_only`='0' $paging = new \Froxlor\UI\Pagination($userinfo, $fields, $result);
AND `d`.`id` <> :standardsubdomain " . $paging->getSqlWhere(true) . " " . $paging->getSqlOrderBy() . " " . $paging->getSqlLimit()); // get list
Database::pexecute($domains_stmt, array( $json_result = SubDomains::getLocal($userinfo, $paging->getApiCommandParams())->listing();
"customerid" => $userinfo['customerid'], } catch (Exception $e) {
"standardsubdomain" => $userinfo['standardsubdomain'] \Froxlor\UI\Response::dynamic_error($e->getMessage());
)); }
$paging->setEntries(Database::num_rows()); $result = json_decode($json_result, true)['data'];
$sortcode = $paging->getHtmlSortCode($lng); $sortcode = $paging->getHtmlSortCode($lng);
$arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s);
$searchcode = $paging->getHtmlSearchCode($lng); $searchcode = $paging->getHtmlSearchCode($lng);
$pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s);
$domains = ''; $domains = '';
$parentdomains_count = 0; $parentdomains_count = 0;
$domains_count = 0; $domains_count = $paging->getEntries();
$domain_array = array(); $domain_array = array();
while ($row = $domains_stmt->fetch(PDO::FETCH_ASSOC)) { foreach ($result['list'] as $row) {
$row['domain'] = $idna_convert->decode($row['domain']); formatDomainEntry($row, $idna_convert);
$row['aliasdomain'] = $idna_convert->decode($row['aliasdomain']);
$row['domainalias'] = $idna_convert->decode($row['domainalias']);
if ($row['parentdomainid'] == '0' && $row['caneditdomain'] == '1') { if ($row['parentdomainid'] == '0' && $row['caneditdomain'] == '1') {
$parentdomains_count ++; $parentdomains_count ++;
} }
$domain_array[$row['parentdomainid']][] = $row;
/**
* check for set ssl-certs to show different state-icons
*/
// nothing (ssl_global)
$row['domain_hascert'] = 0;
$ssl_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` WHERE `domainid` = :domainid");
Database::pexecute($ssl_stmt, array(
"domainid" => $row['id']
));
$ssl_result = $ssl_stmt->fetch(PDO::FETCH_ASSOC);
if (is_array($ssl_result) && isset($ssl_result['ssl_cert_file']) && $ssl_result['ssl_cert_file'] != '') {
// own certificate (ssl_customer_green)
$row['domain_hascert'] = 1;
} else {
// check if it's parent has one set (shared)
if ($row['parentdomainid'] != 0) {
$ssl_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` WHERE `domainid` = :domainid");
Database::pexecute($ssl_stmt, array(
"domainid" => $row['parentdomainid']
));
$ssl_result = $ssl_stmt->fetch(PDO::FETCH_ASSOC);
if (is_array($ssl_result) && isset($ssl_result['ssl_cert_file']) && $ssl_result['ssl_cert_file'] != '') {
// parent has a certificate (ssl_shared)
$row['domain_hascert'] = 2;
}
}
} }
$row['termination_date'] = str_replace("0000-00-00", "", $row['termination_date']); if (isset($domain_array[0])) {
if ($row['termination_date'] != "") { foreach ($domain_array[0] as $pdomain) {
$cdate = strtotime($row['termination_date'] . " 23:59:59"); // PARENTDOMAIN
$today = time(); $row = \Froxlor\PhpHelper::htmlentitiesArray($pdomain);
if ($cdate < $today) {
$row['termination_css'] = 'domain-expired';
} else {
$row['termination_css'] = 'domain-canceled';
}
}
$domains_count ++;
$domain_array[$row['domain']] = $row;
}
ksort($domain_array);
$domain_id_array = array();
foreach ($domain_array as $sortkey => $row) {
$domain_id_array[$row['id']] = $sortkey;
}
$domain_sort_array = array();
foreach ($domain_array as $sortkey => $row) {
if ($row['parentdomainid'] == 0) {
$domain_sort_array[$sortkey][$sortkey] = $row;
} else {
// when searching and the results are subdomains only, we need to get
// the parent domain to this subdomain
if (! isset($domain_id_array[$row['parentdomainid']])) {
$domain_id_array[$row['parentdomainid']] = "[parent-domain]";
}
$domain_sort_array[$domain_id_array[$row['parentdomainid']]][$sortkey] = $row;
}
}
$domain_array = array();
if ($paging->sortfield == 'd.domain' && $paging->sortorder == 'asc') {
ksort($domain_sort_array);
} elseif ($paging->sortfield == 'd.domain' && $paging->sortorder == 'desc') {
krsort($domain_sort_array);
}
$i = 0;
foreach ($domain_sort_array as $sortkey => $domain_array) {
if ($paging->checkDisplay($i)) {
if (isset($domain_array[$sortkey])) {
$row = \Froxlor\PhpHelper::htmlentitiesArray($domain_array[$sortkey]);
if (Settings::Get('system.awstats_enabled') == '1') { if (Settings::Get('system.awstats_enabled') == '1') {
$statsapp = 'awstats'; $statsapp = 'awstats';
} else { } else {
$statsapp = 'webalizer'; $statsapp = 'webalizer';
} }
eval("\$domains.=\"" . \Froxlor\UI\Template::getTemplate("domains/domains_delimiter") . "\";"); eval("\$domains.=\"" . \Froxlor\UI\Template::getTemplate("domains/domains_delimiter") . "\";");
} // show docroot nicely
if (strpos($row['documentroot'], $userinfo['documentroot']) === 0) {
if ($paging->sortfield == 'd.domain' && $paging->sortorder == 'asc') { $row['documentroot'] = \Froxlor\FileDir::makeCorrectDir(str_replace($userinfo['documentroot'], "/", $row['documentroot']));
ksort($domain_array); }
} elseif ($paging->sortfield == 'd.domain' && $paging->sortorder == 'desc') { // get ssl-ips if activated
krsort($domain_array); $show_ssledit = false;
} if (Settings::Get('system.use_ssl') == '1' && \Froxlor\Domain\Domain::domainHasSslIpPort($row['id']) && $row['caneditdomain'] == '1' && $row['letsencrypt'] == 0) {
$show_ssledit = true;
foreach ($domain_array as $row) { }
eval("\$domains.=\"" . \Froxlor\UI\Template::getTemplate("domains/domains_domain") . "\";");
// every domain below the parentdomain
if (isset($domain_array[$pdomain['id']])) {
$mydomains = $domain_array[$pdomain['id']];
foreach ($mydomains as $row) {
// show docroot nicely
if (strpos($row['documentroot'], $userinfo['documentroot']) === 0) { if (strpos($row['documentroot'], $userinfo['documentroot']) === 0) {
$row['documentroot'] = \Froxlor\FileDir::makeCorrectDir(str_replace($userinfo['documentroot'], "/", $row['documentroot'])); $row['documentroot'] = \Froxlor\FileDir::makeCorrectDir(str_replace($userinfo['documentroot'], "/", $row['documentroot']));
} }
// get ssl-ips if activated // get ssl-ips if activated
$show_ssledit = false; $show_ssledit = false;
if (Settings::Get('system.use_ssl') == '1' && \Froxlor\Domain\Domain::domainHasSslIpPort($row['id']) && $row['caneditdomain'] == '1' && $row['letsencrypt'] == 0) { if (Settings::Get('system.use_ssl') == '1' && \Froxlor\Domain\Domain::domainHasSslIpPort($row['id']) && $row['caneditdomain'] == '1' && $row['letsencrypt'] == 0) {
$show_ssledit = true; $show_ssledit = true;
} }
$row = \Froxlor\PhpHelper::htmlentitiesArray($row);
eval("\$domains.=\"" . \Froxlor\UI\Template::getTemplate("domains/domains_domain") . "\";"); eval("\$domains.=\"" . \Froxlor\UI\Template::getTemplate("domains/domains_domain") . "\";");
} }
} }
}
$i += count($domain_array);
} }
eval("echo \"" . \Froxlor\UI\Template::getTemplate("domains/domainlist") . "\";"); eval("echo \"" . \Froxlor\UI\Template::getTemplate("domains/domainlist") . "\";");
@@ -459,7 +389,9 @@ if ($page == 'overview') {
} }
$alias_stmt = Database::prepare("SELECT COUNT(`id`) AS count FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `aliasdomain`= :aliasdomain"); $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 = Database::pexecute_first($alias_stmt, array(
"aliasdomain" => $result['id']
));
$alias_check = $alias_check['count']; $alias_check = $alias_check['count'];
$domainip = $result_ipandport['ip']; $domainip = $result_ipandport['ip'];
@@ -547,3 +479,53 @@ if ($page == 'overview') {
require_once __DIR__ . '/logfiles_viewer.php'; require_once __DIR__ . '/logfiles_viewer.php';
} }
function formatDomainEntry(&$row, &$idna_convert)
{
$row['domain'] = $idna_convert->decode($row['domain']);
$row['aliasdomain'] = $idna_convert->decode($row['aliasdomain']);
$row['domainalias'] = $idna_convert->decode($row['domainalias']);
/**
* check for set ssl-certs to show different state-icons
*/
// nothing (ssl_global)
$row['domain_hascert'] = 0;
$ssl_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` WHERE `domainid` = :domainid");
Database::pexecute($ssl_stmt, array(
"domainid" => $row['id']
));
$ssl_result = $ssl_stmt->fetch(PDO::FETCH_ASSOC);
if (is_array($ssl_result) && isset($ssl_result['ssl_cert_file']) && $ssl_result['ssl_cert_file'] != '') {
// own certificate (ssl_customer_green)
$row['domain_hascert'] = 1;
} else {
// check if it's parent has one set (shared)
if ($row['parentdomainid'] != 0) {
$ssl_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` WHERE `domainid` = :domainid");
Database::pexecute($ssl_stmt, array(
"domainid" => $row['parentdomainid']
));
$ssl_result = $ssl_stmt->fetch(PDO::FETCH_ASSOC);
if (is_array($ssl_result) && isset($ssl_result['ssl_cert_file']) && $ssl_result['ssl_cert_file'] != '') {
// parent has a certificate (ssl_shared)
$row['domain_hascert'] = 2;
}
}
}
$row['termination_date'] = str_replace("0000-00-00", "", $row['termination_date']);
$row['termination_css'] = "";
if ($row['termination_date'] != "") {
$cdate = strtotime($row['termination_date'] . " 23:59:59");
$today = time();
if ($cdate < $today) {
$row['termination_css'] = 'domain-expired';
} else {
$row['termination_css'] = 'domain-canceled';
}
}
}

View File

@@ -19,6 +19,7 @@
define('AREA', 'customer'); define('AREA', 'customer');
require './lib/init.php'; require './lib/init.php';
use Froxlor\Api\Commands\SubDomains;
use Froxlor\Database\Database; use Froxlor\Database\Database;
use Froxlor\Settings; use Froxlor\Settings;
use Froxlor\Api\Commands\Emails as Emails; use Froxlor\Api\Commands\Emails as Emails;
@@ -47,23 +48,27 @@ if ($page == 'overview') {
'm.email_full' => $lng['emails']['emailaddress'], 'm.email_full' => $lng['emails']['emailaddress'],
'm.destination' => $lng['emails']['forwarders'] 'm.destination' => $lng['emails']['forwarders']
); );
$paging = new \Froxlor\UI\Paging($userinfo, TABLE_MAIL_VIRTUAL, $fields); try {
$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` // get total count
LEFT JOIN `' . TABLE_PANEL_DOMAINS . '` `d` ON (`m`.`domainid` = `d`.`id`) $json_result = Emails::getLocal($userinfo)->listingCount();
LEFT JOIN `' . TABLE_MAIL_USERS . '` `u` ON (`m`.`popaccountid` = `u`.`id`) $result = json_decode($json_result, true)['data'];
WHERE `m`.`customerid`= :customerid ' . $paging->getSqlWhere(true) . " " . $paging->getSqlOrderBy() . " " . $paging->getSqlLimit()); // initialize pagination and filtering
Database::pexecute($result_stmt, array( $paging = new \Froxlor\UI\Pagination($userinfo, $fields, $result);
"customerid" => $userinfo['customerid'] // get list
)); $json_result = Emails::getLocal($userinfo, $paging->getApiCommandParams())->listing();
$emailscount = Database::num_rows(); } catch (Exception $e) {
$paging->setEntries($emailscount); \Froxlor\UI\Response::dynamic_error($e->getMessage());
}
$result = json_decode($json_result, true)['data'];
$sortcode = $paging->getHtmlSortCode($lng); $sortcode = $paging->getHtmlSortCode($lng);
$arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s);
$searchcode = $paging->getHtmlSearchCode($lng); $searchcode = $paging->getHtmlSearchCode($lng);
$pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s);
$emails = array(); $emails = array();
$emailscount = $paging->getEntries();
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { foreach ($result['list'] as $row) {
if (! isset($emails[$row['domain']]) || ! is_array($emails[$row['domain']])) { if (! isset($emails[$row['domain']]) || ! is_array($emails[$row['domain']])) {
$emails[$row['domain']] = array(); $emails[$row['domain']] = array();
} }
@@ -77,7 +82,6 @@ if ($page == 'overview') {
ksort($emails); ksort($emails);
} }
$i = 0;
$count = 0; $count = 0;
$accounts = ''; $accounts = '';
$emails_count = 0; $emails_count = 0;
@@ -90,7 +94,6 @@ if ($page == 'overview') {
} }
foreach ($emailaddresses as $row) { foreach ($emailaddresses as $row) {
if ($paging->checkDisplay($i)) {
if ($domainname != $idna_convert->decode($row['domain'])) { if ($domainname != $idna_convert->decode($row['domain'])) {
$domainname = $idna_convert->decode($row['domain']); $domainname = $idna_convert->decode($row['domain']);
eval("\$accounts.=\"" . \Froxlor\UI\Template::getTemplate("email/emails_domain") . "\";"); eval("\$accounts.=\"" . \Froxlor\UI\Template::getTemplate("email/emails_domain") . "\";");
@@ -124,19 +127,18 @@ if ($page == 'overview') {
eval("\$accounts.=\"" . \Froxlor\UI\Template::getTemplate("email/emails_email") . "\";"); eval("\$accounts.=\"" . \Froxlor\UI\Template::getTemplate("email/emails_email") . "\";");
$count ++; $count ++;
} }
$i ++;
}
} }
$emaildomains_count_stmt = Database::prepare("SELECT COUNT(`id`) AS `count` FROM `" . TABLE_PANEL_DOMAINS . "` $json_result = SubDomains::getLocal($userinfo, [
WHERE `customerid`= :customerid 'sql_search' => [
AND `isemaildomain`='1' ORDER BY `domain` ASC"); 'd.isemaildomain' => [
Database::pexecute($emaildomains_count_stmt, array( 'value' => 1,
"customerid" => $userinfo['customerid'] 'op' => '='
)); ]
$emaildomains_count = $emaildomains_count_stmt->fetch(PDO::FETCH_ASSOC); ]
$emaildomains_count = $emaildomains_count['count']; ])->listing();
$result = json_decode($json_result, true)['data'];
$emaildomains_count = $result['count'];
eval("echo \"" . \Froxlor\UI\Template::getTemplate("email/emails") . "\";"); eval("echo \"" . \Froxlor\UI\Template::getTemplate("email/emails") . "\";");
} elseif ($action == 'delete' && $id != 0) { } elseif ($action == 'delete' && $id != 0) {

View File

@@ -19,7 +19,6 @@
define('AREA', 'customer'); define('AREA', 'customer');
require './lib/init.php'; require './lib/init.php';
use Froxlor\Database\Database;
use Froxlor\Settings; use Froxlor\Settings;
use Froxlor\Api\Commands\DirOptions as DirOptions; use Froxlor\Api\Commands\DirOptions as DirOptions;
use Froxlor\Api\Commands\DirProtections as DirProtections; use Froxlor\Api\Commands\DirProtections as DirProtections;
@@ -52,23 +51,27 @@ if ($page == 'overview') {
'username' => $lng['login']['username'], 'username' => $lng['login']['username'],
'path' => $lng['panel']['path'] 'path' => $lng['panel']['path']
); );
$paging = new \Froxlor\UI\Paging($userinfo, TABLE_PANEL_HTPASSWDS, $fields); try {
$result_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_HTPASSWDS . "` // get total count
WHERE `customerid`= :customerid " . $paging->getSqlWhere(true) . " " . $paging->getSqlOrderBy() . " " . $paging->getSqlLimit()); $json_result = DirProtections::getLocal($userinfo)->listingCount();
Database::pexecute($result_stmt, array( $result = json_decode($json_result, true)['data'];
"customerid" => $userinfo['customerid'] // initialize pagination and filtering
)); $paging = new \Froxlor\UI\Pagination($userinfo, $fields, $result);
$paging->setEntries(Database::num_rows()); // get list
$json_result = DirProtections::getLocal($userinfo, $paging->getApiCommandParams())->listing();
} catch (Exception $e) {
\Froxlor\UI\Response::dynamic_error($e->getMessage());
}
$result = json_decode($json_result, true)['data'];
$sortcode = $paging->getHtmlSortCode($lng); $sortcode = $paging->getHtmlSortCode($lng);
$arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s);
$searchcode = $paging->getHtmlSearchCode($lng); $searchcode = $paging->getHtmlSearchCode($lng);
$pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s);
$i = 0;
$count = 0; $count = 0;
$htpasswds = ''; $htpasswds = '';
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { foreach ($result['list'] as $row) {
if ($paging->checkDisplay($i)) {
if (strpos($row['path'], $userinfo['documentroot']) === 0) { if (strpos($row['path'], $userinfo['documentroot']) === 0) {
$row['path'] = str_replace($userinfo['documentroot'], "/", $row['path']); $row['path'] = str_replace($userinfo['documentroot'], "/", $row['path']);
} }
@@ -78,9 +81,6 @@ if ($page == 'overview') {
$count ++; $count ++;
} }
$i ++;
}
eval("echo \"" . \Froxlor\UI\Template::getTemplate("extras/htpasswds") . "\";"); eval("echo \"" . \Froxlor\UI\Template::getTemplate("extras/htpasswds") . "\";");
} elseif ($action == 'delete' && $id != 0) { } elseif ($action == 'delete' && $id != 0) {
try { try {
@@ -192,25 +192,29 @@ if ($page == 'overview') {
'error500path' => $lng['extras']['error500path'], 'error500path' => $lng['extras']['error500path'],
'options_cgi' => $lng['extras']['execute_perl'] 'options_cgi' => $lng['extras']['execute_perl']
); );
$paging = new \Froxlor\UI\Paging($userinfo, TABLE_PANEL_HTACCESS, $fields); try {
$result_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_HTACCESS . "` // get total count
WHERE `customerid`= :customerid " . $paging->getSqlWhere(true) . " " . $paging->getSqlOrderBy() . " " . $paging->getSqlLimit()); $json_result = DirOptions::getLocal($userinfo)->listingCount();
Database::pexecute($result_stmt, array( $result = json_decode($json_result, true)['data'];
"customerid" => $userinfo['customerid'] // initialize pagination and filtering
)); $paging = new \Froxlor\UI\Pagination($userinfo, $fields, $result);
$paging->setEntries(Database::num_rows()); // get list
$json_result = DirOptions::getLocal($userinfo, $paging->getApiCommandParams())->listing();
} catch (Exception $e) {
\Froxlor\UI\Response::dynamic_error($e->getMessage());
}
$result = json_decode($json_result, true)['data'];
$sortcode = $paging->getHtmlSortCode($lng); $sortcode = $paging->getHtmlSortCode($lng);
$arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s);
$searchcode = $paging->getHtmlSearchCode($lng); $searchcode = $paging->getHtmlSearchCode($lng);
$pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s);
$i = 0;
$count = 0; $count = 0;
$htaccess = ''; $htaccess = '';
$cperlenabled = \Froxlor\Customer\Customer::customerHasPerlEnabled($userinfo['customerid']); $cperlenabled = \Froxlor\Customer\Customer::customerHasPerlEnabled($userinfo['customerid']);
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { foreach ($result['list'] as $row) {
if ($paging->checkDisplay($i)) {
if (strpos($row['path'], $userinfo['documentroot']) === 0) { if (strpos($row['path'], $userinfo['documentroot']) === 0) {
$row['path'] = str_replace($userinfo['documentroot'], "/", $row['path']); $row['path'] = str_replace($userinfo['documentroot'], "/", $row['path']);
} }
@@ -224,9 +228,6 @@ if ($page == 'overview') {
$count ++; $count ++;
} }
$i ++;
}
eval("echo \"" . \Froxlor\UI\Template::getTemplate("extras/htaccess") . "\";"); eval("echo \"" . \Froxlor\UI\Template::getTemplate("extras/htaccess") . "\";");
} elseif ($action == 'delete' && $id != 0) { } elseif ($action == 'delete' && $id != 0) {
try { try {

View File

@@ -46,41 +46,38 @@ if ($page == 'overview') {
'homedir' => $lng['panel']['path'], 'homedir' => $lng['panel']['path'],
'description' => $lng['panel']['ftpdesc'] 'description' => $lng['panel']['ftpdesc']
); );
$paging = new \Froxlor\UI\Paging($userinfo, TABLE_FTP_USERS, $fields); try {
// get total count
$result_stmt = Database::prepare("SELECT `id`, `username`, `description`, `homedir`, `shell` FROM `" . TABLE_FTP_USERS . "` $json_result = Ftps::getLocal($userinfo)->listingCount();
WHERE `customerid`= :customerid " . $paging->getSqlWhere(true) . " " . $paging->getSqlOrderBy() . " " . $paging->getSqlLimit()); $result = json_decode($json_result, true)['data'];
Database::pexecute($result_stmt, array( // initialize pagination and filtering
"customerid" => $userinfo['customerid'] $paging = new \Froxlor\UI\Pagination($userinfo, $fields, $result);
)); // get list
$ftps_count = Database::num_rows(); $json_result = Ftps::getLocal($userinfo, $paging->getApiCommandParams())->listing();
$paging->setEntries($ftps_count); } catch (Exception $e) {
\Froxlor\UI\Response::dynamic_error($e->getMessage());
}
$result = json_decode($json_result, true)['data'];
$ftps_count = $paging->getEntries();
$sortcode = $paging->getHtmlSortCode($lng); $sortcode = $paging->getHtmlSortCode($lng);
$arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s);
$searchcode = $paging->getHtmlSearchCode($lng); $searchcode = $paging->getHtmlSearchCode($lng);
$pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s);
$i = 0;
$count = 0; $count = 0;
$accounts = ''; $accounts = '';
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { foreach ($result['list'] as $row) {
if ($paging->checkDisplay($i)) {
if (strpos($row['homedir'], $userinfo['documentroot']) === 0) { if (strpos($row['homedir'], $userinfo['documentroot']) === 0) {
$row['documentroot'] = str_replace($userinfo['documentroot'], "/", $row['homedir']); $row['documentroot'] = str_replace($userinfo['documentroot'], "/", $row['homedir']);
} else { } else {
$row['documentroot'] = $row['homedir']; $row['documentroot'] = $row['homedir'];
} }
$row['documentroot'] = \Froxlor\FileDir::makeCorrectDir($row['documentroot']); $row['documentroot'] = \Froxlor\FileDir::makeCorrectDir($row['documentroot']);
$row = \Froxlor\PhpHelper::htmlentitiesArray($row); $row = \Froxlor\PhpHelper::htmlentitiesArray($row);
eval("\$accounts.=\"" . \Froxlor\UI\Template::getTemplate('ftp/accounts_account') . "\";"); eval("\$accounts.=\"" . \Froxlor\UI\Template::getTemplate('ftp/accounts_account') . "\";");
$count ++; $count ++;
} }
$i ++;
}
eval("echo \"" . \Froxlor\UI\Template::getTemplate('ftp/accounts') . "\";"); eval("echo \"" . \Froxlor\UI\Template::getTemplate('ftp/accounts') . "\";");
} elseif ($action == 'delete' && $id != 0) { } elseif ($action == 'delete' && $id != 0) {
try { try {

View File

@@ -19,6 +19,7 @@
define('AREA', 'customer'); define('AREA', 'customer');
require './lib/init.php'; require './lib/init.php';
use Froxlor\Api\Commands\SysLog;
use Froxlor\Database\Database; use Froxlor\Database\Database;
use Froxlor\Settings; use Froxlor\Settings;
@@ -35,26 +36,25 @@ if ($page == 'log') {
'user' => $lng['logger']['user'], 'user' => $lng['logger']['user'],
'text' => $lng['logger']['action'] 'text' => $lng['logger']['action']
); );
$paging = new \Froxlor\UI\Paging($userinfo, TABLE_PANEL_LOG, $fields, null, null, 0, 'desc', 30); try {
$query = 'SELECT * FROM `' . TABLE_PANEL_LOG . '` WHERE `user` = :loginname ' . $paging->getSqlWhere(true) . ' ' . $paging->getSqlOrderBy(); // get total count
$result_stmt = Database::prepare($query . ' ' . $paging->getSqlLimit()); $json_result = SysLog::getLocal($userinfo)->listingCount();
Database::pexecute($result_stmt, array( $result = json_decode($json_result, true)['data'];
"loginname" => $userinfo['loginname'] // initialize pagination and filtering
)); $paging = new \Froxlor\UI\Pagination($userinfo, $fields, $result);
$result_cnt_stmt = Database::prepare($query); // get list
Database::pexecute($result_cnt_stmt, array( $json_result = SysLog::getLocal($userinfo, $paging->getApiCommandParams())->listing();
"loginname" => $userinfo['loginname'] } catch (Exception $e) {
)); \Froxlor\UI\Response::dynamic_error($e->getMessage());
$res_cnt = $result_cnt_stmt->fetch(PDO::FETCH_ASSOC); }
$logs_count = $result_cnt_stmt->rowCount(); $result = json_decode($json_result, true)['data'];
$paging->setEntries($logs_count);
$sortcode = $paging->getHtmlSortCode($lng); $sortcode = $paging->getHtmlSortCode($lng);
$arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s);
$searchcode = $paging->getHtmlSearchCode($lng); $searchcode = $paging->getHtmlSearchCode($lng);
$pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s);
$clog = array(); $clog = array();
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { foreach ($result['list'] as $row) {
if (! isset($clog[$row['action']]) || ! is_array($clog[$row['action']])) { if (! isset($clog[$row['action']]) || ! is_array($clog[$row['action']])) {
$clog[$row['action']] = array(); $clog[$row['action']] = array();
@@ -68,7 +68,6 @@ if ($page == 'log') {
ksort($clog); ksort($clog);
} }
$i = 0;
$count = 0; $count = 0;
$log_count = 0; $log_count = 0;
$log = ''; $log = '';
@@ -113,10 +112,7 @@ if ($page == 'log') {
eval("\$log.=\"" . \Froxlor\UI\Template::getTemplate('logger/logger_log') . "\";"); eval("\$log.=\"" . \Froxlor\UI\Template::getTemplate('logger/logger_log') . "\";");
$count ++; $count ++;
$_action = $action; $_action = $action;
// }
$i ++;
} }
$i ++;
} }
eval("echo \"" . \Froxlor\UI\Template::getTemplate('logger/logger') . "\";"); eval("echo \"" . \Froxlor\UI\Template::getTemplate('logger/logger') . "\";");

View File

@@ -53,20 +53,24 @@ if ($page == 'overview') {
'databasename' => $lng['mysql']['databasename'], 'databasename' => $lng['mysql']['databasename'],
'description' => $lng['mysql']['databasedescription'] 'description' => $lng['mysql']['databasedescription']
); );
$paging = new \Froxlor\UI\Paging($userinfo, TABLE_PANEL_DATABASES, $fields); try {
$result_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_DATABASES . "` // get total count
WHERE `customerid`= :customerid " . $paging->getSqlWhere(true) . " " . $paging->getSqlOrderBy() . " " . $paging->getSqlLimit()); $json_result = Mysqls::getLocal($userinfo)->listingCount();
Database::pexecute($result_stmt, array( $result = json_decode($json_result, true)['data'];
"customerid" => $userinfo['customerid'] // initialize pagination and filtering
)); $paging = new \Froxlor\UI\Pagination($userinfo, $fields, $result);
$mysqls_count = Database::num_rows(); // get list
$paging->setEntries($mysqls_count); $json_result = Mysqls::getLocal($userinfo, $paging->getApiCommandParams())->listing();
} catch (Exception $e) {
\Froxlor\UI\Response::dynamic_error($e->getMessage());
}
$result = json_decode($json_result, true)['data'];
$mysqls_count = $paging->getEntries();
$sortcode = $paging->getHtmlSortCode($lng); $sortcode = $paging->getHtmlSortCode($lng);
$arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s);
$searchcode = $paging->getHtmlSearchCode($lng); $searchcode = $paging->getHtmlSearchCode($lng);
$pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s);
$i = 0;
$count = 0; $count = 0;
$mysqls = ''; $mysqls = '';
@@ -76,8 +80,7 @@ if ($page == 'overview') {
// Begin root-session // Begin root-session
Database::needRoot(true); Database::needRoot(true);
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { foreach ($result['list'] as $row) {
if ($paging->checkDisplay($i)) {
$row = \Froxlor\PhpHelper::htmlentitiesArray($row); $row = \Froxlor\PhpHelper::htmlentitiesArray($row);
$mbdata_stmt = Database::prepare("SELECT SUM(data_length + index_length) as MB FROM information_schema.TABLES $mbdata_stmt = Database::prepare("SELECT SUM(data_length + index_length) as MB FROM information_schema.TABLES
WHERE table_schema = :table_schema WHERE table_schema = :table_schema
@@ -90,8 +93,6 @@ if ($page == 'overview') {
eval("\$mysqls.=\"" . \Froxlor\UI\Template::getTemplate('mysql/mysqls_database') . "\";"); eval("\$mysqls.=\"" . \Froxlor\UI\Template::getTemplate('mysql/mysqls_database') . "\";");
$count ++; $count ++;
} }
$i ++;
}
Database::needRoot(false); Database::needRoot(false);
// End root-session // End root-session

View File

@@ -37,11 +37,16 @@ $ttl = isset($_POST['record']['ttl']) ? (int) $_POST['record']['ttl'] : 18000;
$domain = \Froxlor\Dns\Dns::getAllowedDomainEntry($domain_id, AREA, $userinfo); $domain = \Froxlor\Dns\Dns::getAllowedDomainEntry($domain_id, AREA, $userinfo);
// select all entries // select all entries
$sel_stmt = Database::prepare("SELECT * FROM `" . TABLE_DOMAIN_DNS . "` WHERE domain_id = :did"); try {
Database::pexecute($sel_stmt, array( // get list
'did' => $domain_id $json_result = DomainZones::getLocal($userinfo, [
)); 'id' => $domain_id
$dom_entries = $sel_stmt->fetchAll(PDO::FETCH_ASSOC); ])->listing();
} catch (Exception $e) {
\Froxlor\UI\Response::dynamic_error($e->getMessage());
}
$result = json_decode($json_result, true)['data'];
$dom_entries = $result['list'];
$errors = ""; $errors = "";
$success_message = ""; $success_message = "";
@@ -117,7 +122,7 @@ $type_select_values = array(
'RP', 'RP',
'SRV', 'SRV',
'SSHFP', 'SSHFP',
'TXT', 'TXT'
); );
asort($type_select_values); asort($type_select_values);
foreach ($type_select_values as $_type) { foreach ($type_select_values as $_type) {

View File

@@ -94,7 +94,7 @@ CREATE TABLE `panel_admins` (
`password` varchar(255) NOT NULL default '', `password` varchar(255) NOT NULL default '',
`name` varchar(255) NOT NULL default '', `name` varchar(255) NOT NULL default '',
`email` varchar(255) NOT NULL default '', `email` varchar(255) NOT NULL default '',
`def_language` varchar(255) NOT NULL default '', `def_language` varchar(100) NOT NULL default '',
`ip` varchar(500) NOT NULL default '-1', `ip` varchar(500) NOT NULL default '-1',
`customers` int(15) NOT NULL default '0', `customers` int(15) NOT NULL default '0',
`customers_used` int(15) NOT NULL default '0', `customers_used` int(15) NOT NULL default '0',
@@ -127,11 +127,11 @@ CREATE TABLE `panel_admins` (
`lastlogin_fail` int(11) unsigned NOT NULL default '0', `lastlogin_fail` int(11) unsigned NOT NULL default '0',
`loginfail_count` int(11) unsigned NOT NULL default '0', `loginfail_count` int(11) unsigned NOT NULL default '0',
`reportsent` tinyint(4) unsigned NOT NULL default '0', `reportsent` tinyint(4) unsigned NOT NULL default '0',
`theme` varchar(255) NOT NULL default 'Sparkle', `theme` varchar(50) NOT NULL default 'Sparkle',
`custom_notes` text, `custom_notes` text,
`custom_notes_show` tinyint(1) NOT NULL default '0', `custom_notes_show` tinyint(1) NOT NULL default '0',
`type_2fa` tinyint(1) NOT NULL default '0', `type_2fa` tinyint(1) NOT NULL default '0',
`data_2fa` varchar(500) NOT NULL default '', `data_2fa` varchar(25) NOT NULL default '',
`api_allowed` tinyint(1) NOT NULL default '1', `api_allowed` tinyint(1) NOT NULL default '1',
PRIMARY KEY (`adminid`), PRIMARY KEY (`adminid`),
UNIQUE KEY `loginname` (`loginname`) UNIQUE KEY `loginname` (`loginname`)
@@ -150,13 +150,13 @@ CREATE TABLE `panel_customers` (
`gender` int(1) NOT NULL DEFAULT '0', `gender` int(1) NOT NULL DEFAULT '0',
`company` varchar(255) NOT NULL default '', `company` varchar(255) NOT NULL default '',
`street` varchar(255) NOT NULL default '', `street` varchar(255) NOT NULL default '',
`zipcode` varchar(255) NOT NULL default '', `zipcode` varchar(25) NOT NULL default '',
`city` varchar(255) NOT NULL default '', `city` varchar(255) NOT NULL default '',
`phone` varchar(255) NOT NULL default '', `phone` varchar(50) NOT NULL default '',
`fax` varchar(255) NOT NULL default '', `fax` varchar(50) NOT NULL default '',
`email` varchar(255) NOT NULL default '', `email` varchar(255) NOT NULL default '',
`customernumber` varchar(255) NOT NULL default '', `customernumber` varchar(255) NOT NULL default '',
`def_language` varchar(255) NOT NULL default '', `def_language` varchar(100) NOT NULL default '',
`diskspace` bigint(30) NOT NULL default '0', `diskspace` bigint(30) NOT NULL default '0',
`diskspace_used` bigint(30) NOT NULL default '0', `diskspace_used` bigint(30) NOT NULL default '0',
`mysqls` int(15) NOT NULL default '0', `mysqls` int(15) NOT NULL default '0',
@@ -190,16 +190,15 @@ CREATE TABLE `panel_customers` (
`imap` tinyint(1) NOT NULL default '1', `imap` tinyint(1) NOT NULL default '1',
`perlenabled` tinyint(1) NOT NULL default '0', `perlenabled` tinyint(1) NOT NULL default '0',
`dnsenabled` tinyint(1) NOT NULL default '0', `dnsenabled` tinyint(1) NOT NULL default '0',
`theme` varchar(255) NOT NULL default 'Sparkle', `theme` varchar(50) NOT NULL default 'Sparkle',
`custom_notes` text, `custom_notes` text,
`custom_notes_show` tinyint(1) NOT NULL default '0', `custom_notes_show` tinyint(1) NOT NULL default '0',
`lepublickey` mediumtext default NULL, `lepublickey` mediumtext default NULL,
`leprivatekey` mediumtext default NULL, `leprivatekey` mediumtext default NULL,
`leregistered` tinyint(1) NOT NULL default '0', `leregistered` tinyint(1) NOT NULL default '0',
`leaccount` varchar(255) default '',
`allowed_phpconfigs` varchar(500) NOT NULL default '', `allowed_phpconfigs` varchar(500) NOT NULL default '',
`type_2fa` tinyint(1) NOT NULL default '0', `type_2fa` tinyint(1) NOT NULL default '0',
`data_2fa` varchar(500) NOT NULL default '', `data_2fa` varchar(25) NOT NULL default '',
`api_allowed` tinyint(1) NOT NULL default '1', `api_allowed` tinyint(1) NOT NULL default '1',
`logviewenabled` tinyint(1) NOT NULL default '0', `logviewenabled` tinyint(1) NOT NULL default '0',
PRIMARY KEY (`customerid`), PRIMARY KEY (`customerid`),
@@ -268,6 +267,10 @@ CREATE TABLE `panel_domains` (
`notryfiles` tinyint(1) DEFAULT '0', `notryfiles` tinyint(1) DEFAULT '0',
`writeaccesslog` tinyint(1) DEFAULT '1', `writeaccesslog` tinyint(1) DEFAULT '1',
`writeerrorlog` tinyint(1) DEFAULT '1', `writeerrorlog` tinyint(1) DEFAULT '1',
`override_tls` tinyint(1) DEFAULT '0',
`ssl_protocols` text,
`ssl_cipher_list` text,
`tlsv13_cipher_list` text,
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
KEY `customerid` (`customerid`), KEY `customerid` (`customerid`),
KEY `parentdomain` (`parentdomainid`), KEY `parentdomain` (`parentdomainid`),
@@ -691,8 +694,8 @@ opcache.interned_strings_buffer'),
('panel', 'password_special_char', '!?<>§$%+#=@'), ('panel', 'password_special_char', '!?<>§$%+#=@'),
('panel', 'customer_hide_options', ''), ('panel', 'customer_hide_options', ''),
('panel', 'is_configured', '0'), ('panel', 'is_configured', '0'),
('panel', 'version', '0.10.2'), ('panel', 'version', '0.10.6'),
('panel', 'db_version', '201910120'); ('panel', 'db_version', '201911130');
DROP TABLE IF EXISTS `panel_tasks`; DROP TABLE IF EXISTS `panel_tasks`;

View File

@@ -403,6 +403,26 @@ if (\Froxlor\Froxlor::isDatabaseVersion('201910110')) {
lastStepStatus(0); lastStepStatus(0);
} }
// select all domains with an ssl IP connected and specialsettings content to include these in the ssl-vhost
// to maintain former behavior
$sel_stmt = Database::prepare("
SELECT d.id FROM `" . TABLE_PANEL_DOMAINS . "` d
LEFT JOIN `" . TABLE_DOMAINTOIP . "` d2i ON d2i.id_domain = d.id
LEFT JOIN `" . TABLE_PANEL_IPSANDPORTS . "` i ON i.id = d2i.id_ipandports
WHERE d.specialsettings <> '' AND i.ssl = '1'
");
Database::pexecute($sel_stmt);
$upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_DOMAINS . "` SET `include_specialsettings` = '1' WHERE `id` = :id");
if ($sel_stmt->columnCount() > 0) {
showUpdateStep("Adjusting domain settings for downward compatibility");
while ($row = $sel_stmt->fetch(PDO::FETCH_ASSOC)) {
Database::pexecute($upd_stmt, [
'id' => $row['id']
]);
}
lastStepStatus(0);
}
\Froxlor\Froxlor::updateToDbVersion('201910120'); \Froxlor\Froxlor::updateToDbVersion('201910120');
} }
@@ -410,3 +430,55 @@ if (\Froxlor\Froxlor::isFroxlorVersion('0.10.1')) {
showUpdateStep("Updating from 0.10.1 to 0.10.2", false); showUpdateStep("Updating from 0.10.1 to 0.10.2", false);
\Froxlor\Froxlor::updateToVersion('0.10.2'); \Froxlor\Froxlor::updateToVersion('0.10.2');
} }
if (\Froxlor\Froxlor::isDatabaseVersion('201910120')) {
showUpdateStep("Adding new TLS options to domains-table");
Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `override_tls` tinyint(1) DEFAULT '0' AFTER `writeerrorlog`;");
Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `ssl_protocols` text AFTER `override_tls`;");
Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `ssl_cipher_list` text AFTER `ssl_protocols`;");
Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `tlsv13_cipher_list` text AFTER `ssl_cipher_list`;");
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('201910200');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.2')) {
showUpdateStep("Updating from 0.10.2 to 0.10.3", false);
\Froxlor\Froxlor::updateToVersion('0.10.3');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.3')) {
showUpdateStep("Updating from 0.10.3 to 0.10.4", false);
\Froxlor\Froxlor::updateToVersion('0.10.4');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.4')) {
showUpdateStep("Updating from 0.10.4 to 0.10.5", false);
\Froxlor\Froxlor::updateToVersion('0.10.5');
}
if (\Froxlor\Froxlor::isDatabaseVersion('201910200')) {
showUpdateStep("Optimizing customer and admin table for size");
// ALTER TABLE `panel_customers` CHANGE `name` `name` VARCHAR(250) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '';
Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` CHANGE `zipcode` `zipcode` varchar(25) NOT NULL default '';");
Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` CHANGE `phone` `phone` varchar(50) NOT NULL default '';");
Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` CHANGE `fax` `fax` varchar(50) NOT NULL default '';");
Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` CHANGE `def_language` `def_language` varchar(100) NOT NULL default '';");
Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` CHANGE `theme` `theme` varchar(50) NOT NULL default 'Sparkle';");
Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` CHANGE `data_2fa` `data_2fa` varchar(25) NOT NULL default '';");
Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` CHANGE `def_language` `def_language` varchar(100) NOT NULL default '';");
Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` DROP `leaccount`;");
Database::query("ALTER TABLE `" . TABLE_PANEL_ADMINS . "` CHANGE `def_language` `def_language` varchar(100) NOT NULL default '';");
Database::query("ALTER TABLE `" . TABLE_PANEL_ADMINS . "` CHANGE `theme` `theme` varchar(50) NOT NULL default 'Sparkle';");
Database::query("ALTER TABLE `" . TABLE_PANEL_ADMINS . "` CHANGE `data_2fa` `data_2fa` varchar(25) NOT NULL default '';");
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('201911130');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.5')) {
showUpdateStep("Updating from 0.10.5 to 0.10.6", false);
\Froxlor\Froxlor::updateToVersion('0.10.6');
}

View File

@@ -232,6 +232,151 @@ abstract class ApiCommand extends ApiParameter
return $this->user_data; return $this->user_data;
} }
/**
* return SQL when parameter $sql_search is given via API
*
* @param array $sql_search
* optional array with index = fieldname, and value = array with 'op' => operator (one of <, > or =), LIKE is used if left empty and 'value' => searchvalue
* @param array $query_fields
* optional array of placeholders mapped to the actual value which is used in the API commands when executing the statement [internal]
* @param boolean $append
* optional append to WHERE clause rather then create new one, default false [internal]
*
* @return string
*/
protected function getSearchWhere(&$query_fields = array(), $append = false)
{
$search = $this->getParam('sql_search', true, array());
$condition = '';
if (! empty($search)) {
if ($append == true) {
$condition = ' AND ';
} else {
$condition = ' WHERE ';
}
$ops = array(
'<',
'>',
'='
);
$first = true;
foreach ($search as $field => $valoper) {
$cleanfield = str_replace(".", "", $field);
$sortfield = explode('.', $field);
foreach ($sortfield as $id => $sfield) {
if (substr($sfield, - 1, 1) != '`') {
$sfield .= '`';
}
if ($sfield[0] != '`') {
$sfield = '`' . $sfield;
}
$sortfield[$id] = $sfield;
}
$field = implode('.', $sortfield);
if (! $first) {
$condition .= ' AND ';
}
if (! is_array($valoper) || ! isset($valoper['op']) || empty($valoper['op'])) {
$condition .= $field . ' LIKE :' . $cleanfield;
if (! is_array($valoper)) {
$query_fields[':' . $cleanfield] = '%' . $valoper . '%';
} else {
$query_fields[':' . $cleanfield] = '%' . $valoper['value'] . '%';
}
} elseif (in_array($valoper['op'], $ops)) {
$condition .= $field . ' ' . $valoper['op'] . ':' . $cleanfield;
$query_fields[':' . $cleanfield] = $valoper['value'] ?? '';
} else {
continue;
}
if ($first) {
$first = false;
}
}
}
return $condition;
}
/**
* return LIMIT clause when at least $sql_limit parameter is given via API
*
* @param int $sql_limit
* optional, limit resultset, default 0
* @param int $sql_offset
* optional, offset for limitation, default 0
*
* @return string
*/
protected function getLimit()
{
$limit = $this->getParam('sql_limit', true, 0);
$offset = $this->getParam('sql_offset', true, 0);
if (! is_numeric($limit)) {
$limit = 0;
}
if (! is_numeric($offset)) {
$offset = 0;
}
if ($limit > 0) {
return ' LIMIT ' . $offset . ',' . $limit;
}
return '';
}
/**
* return ORDER BY clause if parameter $sql_orderby parameter is given via API
*
* @param array $sql_orderby
* optional array with index = fieldname and value = ASC|DESC
*
* @return string
*/
protected function getOrderBy()
{
$orderby = $this->getParam('sql_orderby', true, array());
$order = "";
if (! empty($orderby)) {
$order .= " ORDER BY ";
foreach ($orderby as $field => $by) {
$sortfield = explode('.', $field);
foreach ($sortfield as $id => $sfield) {
if (substr($sfield, - 1, 1) != '`') {
$sfield .= '`';
}
if ($sfield[0] != '`') {
$sfield = '`' . $sfield;
}
$sortfield[$id] = $sfield;
}
$field = implode('.', $sortfield);
$by = strtoupper($by);
if (! in_array($by, [
'ASC',
'DESC'
])) {
$by = 'ASC';
}
if (\Froxlor\Settings::Get('panel.natsorting') == 1) {
// Acts similar to php's natsort(), found in one comment at http://my.opera.com/cpr/blog/show.dml/160556
$order .= "CONCAT( IF( ASCII( LEFT( " . $field . ", 5 ) ) > 57,
LEFT( " . $field . ", 1 ), 0 ),
IF( ASCII( RIGHT( " . $field . ", 1 ) ) > 57,
LPAD( " . $field . ", 255, '0' ),
LPAD( CONCAT( " . $field . ", '-' ), 255, '0' )
)) " . $by . ", ";
} else {
$order .= $field . " " . $by . ", ";
}
}
$order = substr($order, 0, - 2);
}
return $order;
}
/** /**
* return logger instance * return logger instance
* *

View File

@@ -25,6 +25,15 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
/** /**
* lists all admin entries * lists all admin entries
* *
* @param array $sql_search
* optional array with index = fieldname, and value = array with 'op' => operator (one of <, > or =), LIKE is used if left empty and 'value' => searchvalue
* @param int $sql_limit
* optional specify number of results to be returned
* @param int $sql_offset
* optional specify offset for resultset
* @param array $sql_orderby
* optional array with index = fieldname and value = ASC|DESC to order the resultset by one or more fields
*
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return string json-encoded array count|list * @return string json-encoded array count|list
@@ -33,12 +42,11 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
{ {
if ($this->isAdmin() && $this->getUserDetail('change_serversettings') == 1) { if ($this->isAdmin() && $this->getUserDetail('change_serversettings') == 1) {
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] list admins"); $this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] list admins");
$query_fields = array();
$result_stmt = Database::prepare(" $result_stmt = Database::prepare("
SELECT * SELECT *
FROM `" . TABLE_PANEL_ADMINS . "` FROM `" . TABLE_PANEL_ADMINS . "`" . $this->getSearchWhere($query_fields) . $this->getOrderBy() . $this->getLimit());
ORDER BY `loginname` ASC Database::pexecute($result_stmt, $query_fields, true, true);
");
Database::pexecute($result_stmt, null, true, true);
$result = array(); $result = array();
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) { while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
$result[] = $row; $result[] = $row;
@@ -51,6 +59,28 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);
} }
/**
* returns the total number of admins for the given admin
*
* @access admin
* @throws \Exception
* @return string json-encoded array
*/
public function listingCount()
{
if ($this->isAdmin() && $this->getUserDetail('change_serversettings') == 1) {
$result_stmt = Database::prepare("
SELECT COUNT(*) as num_admins
FROM `" . TABLE_PANEL_ADMINS . "`
");
$result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) {
return $this->response(200, "successfull", $result['num_admins']);
}
}
throw new \Exception("Not allowed to execute given command.", 403);
}
/** /**
* return an admin entry by either id or loginname * return an admin entry by either id or loginname
* *

View File

@@ -75,7 +75,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
throw $e; throw $e;
} }
} }
if (!$has_cert) { if (! $has_cert) {
$this->addOrUpdateCertificate($domain['id'], $ssl_cert_file, $ssl_key_file, $ssl_ca_file, $ssl_cert_chainfile, true); $this->addOrUpdateCertificate($domain['id'], $ssl_cert_file, $ssl_key_file, $ssl_ca_file, $ssl_cert_chainfile, true);
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] added ssl-certificate for '" . $domain['domain'] . "'"); $this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] added ssl-certificate for '" . $domain['domain'] . "'");
$result = $this->apiCall('Certificates.get', array( $result = $this->apiCall('Certificates.get', array(
@@ -174,6 +174,15 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
/** /**
* lists all certificate entries * lists all certificate entries
* *
* @param array $sql_search
* optional array with index = fieldname, and value = array with 'op' => operator (one of <, > or =), LIKE is used if left empty and 'value' => searchvalue
* @param int $sql_limit
* optional specify number of results to be returned
* @param int $sql_offset
* optional specify offset for resultset
* @param array $sql_orderby
* optional array with index = fieldname and value = ASC|DESC to order the resultset by one or more fields
*
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return string json-encoded array count|list * @return string json-encoded array count|list
@@ -188,7 +197,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
WHERE "; WHERE ";
$qry_params = array(); $qry_params = array();
$query_fields = array();
if ($this->isAdmin() && $this->getUserDetail('customers_see_all') == '0') { if ($this->isAdmin() && $this->getUserDetail('customers_see_all') == '0') {
// admin with only customer-specific permissions // admin with only customer-specific permissions
$certs_stmt_query .= "d.adminid = :adminid "; $certs_stmt_query .= "d.adminid = :adminid ";
@@ -200,7 +209,8 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
} else { } else {
$certs_stmt_query .= "1 "; $certs_stmt_query .= "1 ";
} }
$certs_stmt = Database::prepare($certs_stmt_query); $certs_stmt = Database::prepare($certs_stmt_query . $this->getSearchWhere($query_fields) . $this->getOrderBy() . $this->getLimit());
$qry_params = array_merge($qry_params, $query_fields);
Database::pexecute($certs_stmt, $qry_params, true, true); Database::pexecute($certs_stmt, $qry_params, true, true);
$result = array(); $result = array();
while ($cert = $certs_stmt->fetch(\PDO::FETCH_ASSOC)) { while ($cert = $certs_stmt->fetch(\PDO::FETCH_ASSOC)) {
@@ -218,6 +228,40 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
)); ));
} }
/**
* returns the total number of certificates for the given user
*
* @access admin, customer
* @throws \Exception
* @return string json-encoded array
*/
public function listingCount()
{
// select all my (accessable) certificates
$certs_stmt_query = "SELECT COUNT(*) as num_certs
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);
$result = Database::pexecute_first($certs_stmt, $qry_params, true, true);
if ($result) {
return $this->response(200, "successfull", $result['num_certs']);
}
}
/** /**
* delete certificates entry by id * delete certificates entry by id
* *
@@ -232,7 +276,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
if ($this->isAdmin() == false) { if ($this->isAdmin() == false) {
$chk_stmt = Database::prepare(" $chk_stmt = Database::prepare("
SELECT d.domain FROM `" . TABLE_PANEL_DOMAINS . "` d SELECT d.domain, d.letsencrypt FROM `" . TABLE_PANEL_DOMAINS . "` d
LEFT JOIN `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` s ON s.domainid = d.id LEFT JOIN `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` s ON s.domainid = d.id
WHERE s.`id` = :id AND d.`customerid` = :cid WHERE s.`id` = :id AND d.`customerid` = :cid
"); ");
@@ -242,7 +286,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
)); ));
} elseif ($this->isAdmin()) { } elseif ($this->isAdmin()) {
$chk_stmt = Database::prepare(" $chk_stmt = Database::prepare("
SELECT d.domain FROM `" . TABLE_PANEL_DOMAINS . "` d SELECT d.domain, d.letsencrypt FROM `" . TABLE_PANEL_DOMAINS . "` d
LEFT JOIN `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` s ON s.domainid = d.id 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" : "")); WHERE s.`id` = :id" . ($this->getUserDetail('customers_see_all') == '0' ? " AND d.`adminid` = :aid" : ""));
$params = array( $params = array(
@@ -255,7 +299,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
if ($chk == false && $this->getUserDetail('change_serversettings')) { if ($chk == false && $this->getUserDetail('change_serversettings')) {
// check whether it might be the froxlor-vhost certificate // check whether it might be the froxlor-vhost certificate
$chk_stmt = Database::prepare(" $chk_stmt = Database::prepare("
SELECT \"" . Settings::Get('system.hostname') . "\" as domain FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` SELECT \"" . Settings::Get('system.hostname') . "\" as domain, \"" . Settings::Get('system.le_froxlor_enabled') . "\" as letsencrypt FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "`
WHERE `id` = :id AND `domainid` = '0'"); WHERE `id` = :id AND `domainid` = '0'");
$params = array( $params = array(
'id' => $id 'id' => $id
@@ -277,13 +321,16 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
Database::pexecute($del_stmt, array( Database::pexecute($del_stmt, array(
'id' => $id 'id' => $id
)); ));
// trigger removing of certificate from acme.sh if let's encrypt
if ($chk['letsencrypt'] == '1') {
\Froxlor\System\Cronjob::inserttask('12', $chk['domain']);
}
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] removed ssl-certificate for '" . $chk['domain'] . "'"); $this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] removed ssl-certificate for '" . $chk['domain'] . "'");
return $this->response(200, "successfull", $result); return $this->response(200, "successfull", $result);
} }
throw new \Exception("Unable to determine SSL certificate. Maybe no access?", 406); throw new \Exception("Unable to determine SSL certificate. Maybe no access?", 406);
} }
/** /**
* insert or update certificates entry * insert or update certificates entry
* *

View File

@@ -127,6 +127,15 @@ class Cronjobs extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceE
/** /**
* lists all cronjob entries * lists all cronjob entries
* *
* @param array $sql_search
* optional array with index = fieldname, and value = array with 'op' => operator (one of <, > or =), LIKE is used if left empty and 'value' => searchvalue
* @param int $sql_limit
* optional specify number of results to be returned
* @param int $sql_offset
* optional specify offset for resultset
* @param array $sql_orderby
* optional array with index = fieldname and value = ASC|DESC to order the resultset by one or more fields
*
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return string json-encoded array count|list * @return string json-encoded array count|list
@@ -135,10 +144,10 @@ class Cronjobs extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceE
{ {
if ($this->isAdmin()) { if ($this->isAdmin()) {
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] list cronjobs"); $this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] list cronjobs");
$query_fields = array();
$result_stmt = Database::prepare(" $result_stmt = Database::prepare("
SELECT `c`.* FROM `" . TABLE_PANEL_CRONRUNS . "` `c` ORDER BY `module` ASC, `cronfile` ASC SELECT `c`.* FROM `" . TABLE_PANEL_CRONRUNS . "` `c` " . $this->getSearchWhere($query_fields) . $this->getOrderBy() . $this->getLimit());
"); Database::pexecute($result_stmt, $query_fields, true, true);
Database::pexecute($result_stmt);
$result = array(); $result = array();
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) { while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
$result[] = $row; $result[] = $row;
@@ -151,6 +160,27 @@ class Cronjobs extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceE
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);
} }
/**
* returns the total number of cronjobs
*
* @access admin
* @throws \Exception
* @return string json-encoded array
*/
public function listingCount()
{
if ($this->isAdmin()) {
$result_stmt = Database::prepare("
SELECT COUNT(*) as num_crons FROM `" . TABLE_PANEL_CRONRUNS . "` `c`
");
$result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) {
return $this->response(200, "successfull", $result['num_crons']);
}
}
throw new \Exception("Not allowed to execute given command.", 403);
}
/** /**
* You cannot delete system cronjobs. * You cannot delete system cronjobs.
*/ */

View File

@@ -137,6 +137,14 @@ class CustomerBackups extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
* optional, admin-only, select backup-jobs of a specific customer by id * optional, admin-only, select backup-jobs of a specific customer by id
* @param string $loginname * @param string $loginname
* optional, admin-only, select backup-jobs of a specific customer by loginname * optional, admin-only, select backup-jobs of a specific customer by loginname
* @param array $sql_search
* optional array with index = fieldname, and value = array with 'op' => operator (one of <, > or =), LIKE is used if left empty and 'value' => searchvalue
* @param int $sql_limit
* optional specify number of results to be returned
* @param int $sql_offset
* optional specify offset for resultset
* @param array $sql_orderby
* optional array with index = fieldname and value = ASC|DESC to order the resultset by one or more fields
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
@@ -149,8 +157,9 @@ class CustomerBackups extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
$customer_ids = $this->getAllowedCustomerIds('extras.backup'); $customer_ids = $this->getAllowedCustomerIds('extras.backup');
// check whether there is a backup-job for this customer // check whether there is a backup-job for this customer
$sel_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_TASKS . "` WHERE `type` = '20'"); $query_fields = array();
Database::pexecute($sel_stmt); $sel_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_TASKS . "` WHERE `type` = '20'" . $this->getSearchWhere($query_fields, true) . $this->getOrderBy() . $this->getLimit());
Database::pexecute($sel_stmt, $query_fields, true, true);
$result = array(); $result = array();
while ($entry = $sel_stmt->fetch(\PDO::FETCH_ASSOC)) { while ($entry = $sel_stmt->fetch(\PDO::FETCH_ASSOC)) {
$entry['data'] = json_decode($entry['data'], true); $entry['data'] = json_decode($entry['data'], true);
@@ -165,6 +174,37 @@ class CustomerBackups extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
)); ));
} }
/**
* returns the total number of planned backups
*
* @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 string json-encoded array
*/
public function listingCount()
{
$this->validateAccess();
$customer_ids = $this->getAllowedCustomerIds('extras.backup');
// check whether there is a backup-job for this customer
$result_count = 0;
$sel_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_TASKS . "` WHERE `type` = '20'");
Database::pexecute($sel_stmt, null, true, true);
while ($entry = $sel_stmt->fetch(\PDO::FETCH_ASSOC)) {
$entry['data'] = json_decode($entry['data'], true);
if (in_array($entry['data']['customerid'], $customer_ids)) {
$result_count ++;
}
}
return $this->response(200, "successfull", $result_count);
}
/** /**
* delete a planned backup-jobs by id, if called from an admin you need to specify the customerid/loginname * delete a planned backup-jobs by id, if called from an admin you need to specify the customerid/loginname
* *
@@ -195,7 +235,7 @@ class CustomerBackups extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
if ($backupjob['id'] == $entry && in_array($backupjob['data']['customerid'], $customer_ids)) { if ($backupjob['id'] == $entry && in_array($backupjob['data']['customerid'], $customer_ids)) {
Database::pexecute($del_stmt, array( Database::pexecute($del_stmt, array(
'tid' => $entry 'tid' => $entry
)); ), true, true);
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] deleted planned customer-backup #" . $entry); $this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] deleted planned customer-backup #" . $entry);
return $this->response(200, "successfull", true); return $this->response(200, "successfull", true);
} }

View File

@@ -25,6 +25,15 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
/** /**
* lists all customer entries * lists all customer entries
* *
* @param array $sql_search
* optional array with index = fieldname, and value = array with 'op' => operator (one of <, > or =), LIKE is used if left empty and 'value' => searchvalue
* @param int $sql_limit
* optional specify number of results to be returned
* @param int $sql_offset
* optional specify offset for resultset
* @param array $sql_orderby
* optional array with index = fieldname and value = ASC|DESC to order the resultset by one or more fields
*
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return string json-encoded array count|list * @return string json-encoded array count|list
@@ -33,19 +42,19 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
{ {
if ($this->isAdmin()) { if ($this->isAdmin()) {
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] list customers"); $this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] list customers");
$query_fields = array();
$result_stmt = Database::prepare(" $result_stmt = Database::prepare("
SELECT `c`.*, `a`.`loginname` AS `adminname` SELECT `c`.*, `a`.`loginname` AS `adminname`
FROM `" . TABLE_PANEL_CUSTOMERS . "` `c`, `" . TABLE_PANEL_ADMINS . "` `a` FROM `" . TABLE_PANEL_CUSTOMERS . "` `c`, `" . TABLE_PANEL_ADMINS . "` `a`
WHERE " . ($this->getUserDetail('customers_see_all') ? '' : " `c`.`adminid` = :adminid AND ") . " WHERE " . ($this->getUserDetail('customers_see_all') ? '' : " `c`.`adminid` = :adminid AND ") . "
`c`.`adminid` = `a`.`adminid` `c`.`adminid` = `a`.`adminid`" . $this->getSearchWhere($query_fields, true) . $this->getOrderBy() . $this->getLimit());
ORDER BY `c`.`loginname` ASC
");
$params = array(); $params = array();
if ($this->getUserDetail('customers_see_all') == '0') { if ($this->getUserDetail('customers_see_all') == '0') {
$params = array( $params = array(
'adminid' => $this->getUserDetail('adminid') 'adminid' => $this->getUserDetail('adminid')
); );
} }
$params = array_merge($params, $query_fields);
Database::pexecute($result_stmt, $params, true, true); Database::pexecute($result_stmt, $params, true, true);
$result = array(); $result = array();
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) { while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
@@ -59,6 +68,34 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);
} }
/**
* returns the total number of customers for the given admin
*
* @access admin
* @throws \Exception
* @return string json-encoded array
*/
public function listingCount()
{
if ($this->isAdmin()) {
$result_stmt = Database::prepare("
SELECT COUNT(*) as num_customers
FROM `" . TABLE_PANEL_CUSTOMERS . "`
WHERE " . ($this->getUserDetail('customers_see_all') ? "1" : " `adminid` = :adminid "));
$params = array();
if ($this->getUserDetail('customers_see_all') == '0') {
$params = array(
'adminid' => $this->getUserDetail('adminid')
);
}
$result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) {
return $this->response(200, "successfull", $result['num_customers']);
}
}
throw new \Exception("Not allowed to execute given command.", 403);
}
/** /**
* return a customer entry by either id or loginname * return a customer entry by either id or loginname
* *

View File

@@ -285,6 +285,14 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* optional, admin-only, select directory-protections of a specific customer by id * optional, admin-only, select directory-protections of a specific customer by id
* @param string $loginname * @param string $loginname
* optional, admin-only, select directory-protections of a specific customer by loginname * optional, admin-only, select directory-protections of a specific customer by loginname
* @param array $sql_search
* optional array with index = fieldname, and value = array with 'op' => operator (one of <, > or =), LIKE is used if left empty and 'value' => searchvalue
* @param int $sql_limit
* optional specify number of results to be returned
* @param int $sql_offset
* optional specify offset for resultset
* @param array $sql_orderby
* optional array with index = fieldname and value = ASC|DESC to order the resultset by one or more fields
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
@@ -298,11 +306,12 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$customer_ids = $this->getAllowedCustomerIds('extras.pathoptions'); $customer_ids = $this->getAllowedCustomerIds('extras.pathoptions');
$result = array(); $result = array();
$query_fields = array();
$result_stmt = Database::prepare(" $result_stmt = Database::prepare("
SELECT * FROM `" . TABLE_PANEL_HTACCESS . "` SELECT * FROM `" . TABLE_PANEL_HTACCESS . "`
WHERE `customerid` IN (" . implode(', ', $customer_ids) . ") WHERE `customerid` IN (" . implode(', ', $customer_ids) . ")" . $this->getSearchWhere($query_fields, true) . $this->getOrderBy() . $this->getLimit()
"); );
Database::pexecute($result_stmt, null, true, true); Database::pexecute($result_stmt, $query_fields, true, true);
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) { while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
$result[] = $row; $result[] = $row;
} }
@@ -313,6 +322,36 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
)); ));
} }
/**
* returns the total number of accessable directory options
*
* @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 string json-encoded array count|list
*/
public function listingCount()
{
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 COUNT(*) as num_htaccess FROM `" . TABLE_PANEL_HTACCESS . "`
WHERE `customerid` IN (" . implode(', ', $customer_ids) . ")
");
$result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) {
return $this->response(200, "successfull", $result['num_htaccess']);
}
}
/** /**
* delete a directory-options by id * delete a directory-options by id
* *
@@ -373,7 +412,7 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
Database::pexecute($stmt, array( Database::pexecute($stmt, array(
"customerid" => $customer_data['customerid'], "customerid" => $customer_data['customerid'],
"id" => $id "id" => $id
)); ), true, true);
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] deleted directory-option for '" . str_replace($customer_data['documentroot'], '/', $result['path']) . "'"); $this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] deleted directory-option for '" . str_replace($customer_data['documentroot'], '/', $result['path']) . "'");
\Froxlor\System\Cronjob::inserttask('1'); \Froxlor\System\Cronjob::inserttask('1');
return $this->response(200, "successfull", $result); return $this->response(200, "successfull", $result);

View File

@@ -268,6 +268,14 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
* optional, admin-only, select directory-protections of a specific customer by id * optional, admin-only, select directory-protections of a specific customer by id
* @param string $loginname * @param string $loginname
* optional, admin-only, select directory-protections of a specific customer by loginname * optional, admin-only, select directory-protections of a specific customer by loginname
* @param array $sql_search
* optional array with index = fieldname, and value = array with 'op' => operator (one of <, > or =), LIKE is used if left empty and 'value' => searchvalue
* @param int $sql_limit
* optional specify number of results to be returned
* @param int $sql_offset
* optional specify offset for resultset
* @param array $sql_orderby
* optional array with index = fieldname and value = ASC|DESC to order the resultset by one or more fields
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
@@ -281,11 +289,11 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
$customer_ids = $this->getAllowedCustomerIds('extras.directoryprotection'); $customer_ids = $this->getAllowedCustomerIds('extras.directoryprotection');
$result = array(); $result = array();
$query_fields = array();
$result_stmt = Database::prepare(" $result_stmt = Database::prepare("
SELECT * FROM `" . TABLE_PANEL_HTPASSWDS . "` SELECT * FROM `" . TABLE_PANEL_HTPASSWDS . "`
WHERE `customerid` IN (" . implode(', ', $customer_ids) . ") WHERE `customerid` IN (" . implode(', ', $customer_ids) . ")" . $this->getSearchWhere($query_fields, true) . $this->getOrderBy() . $this->getLimit());
"); Database::pexecute($result_stmt, $query_fields, true, true);
Database::pexecute($result_stmt, null, true, true);
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) { while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
$result[] = $row; $result[] = $row;
} }
@@ -296,6 +304,36 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
)); ));
} }
/**
* returns the total number of accessable directory protections
*
* @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 string json-encoded array count|list
*/
public function listingCount()
{
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 COUNT(*) as num_htpasswd FROM `" . TABLE_PANEL_HTPASSWDS . "`
WHERE `customerid` IN (" . implode(', ', $customer_ids) . ")
");
$result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) {
return $this->response(200, "successfull", $result['num_htpasswd']);
}
}
/** /**
* delete a directory-protection by either id or username * delete a directory-protection by either id or username
* *

View File

@@ -379,6 +379,14 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
* optional, the domain id * optional, the domain id
* @param string $domainname * @param string $domainname
* optional, the domain name * optional, the domain name
* @param array $sql_search
* optional array with index = fieldname, and value = array with 'op' => operator (one of <, > or =), LIKE is used if left empty and 'value' => searchvalue
* @param int $sql_limit
* optional specify number of results to be returned
* @param int $sql_offset
* optional specify offset for resultset
* @param array $sql_orderby
* optional array with index = fieldname and value = ASC|DESC to order the resultset by one or more fields
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
@@ -404,11 +412,10 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
'domainname' => $domainname 'domainname' => $domainname
)); ));
$id = $result['id']; $id = $result['id'];
$query_fields = array();
$sel_stmt = Database::prepare("SELECT * FROM `" . TABLE_DOMAIN_DNS . "` WHERE `domain_id` = :did"); $sel_stmt = Database::prepare("SELECT * FROM `" . TABLE_DOMAIN_DNS . "` WHERE `domain_id` = :did" . $this->getSearchWhere($query_fields, true) . $this->getOrderBy() . $this->getLimit());
Database::pexecute($sel_stmt, array( $query_fields['did'] = $id;
'did' => $id Database::pexecute($sel_stmt, $query_fields, true, true);
), true, true);
$result = []; $result = [];
while ($row = $sel_stmt->fetch(\PDO::FETCH_ASSOC)) { while ($row = $sel_stmt->fetch(\PDO::FETCH_ASSOC)) {
$result[] = $row; $result[] = $row;
@@ -419,6 +426,48 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
)); ));
} }
/**
* returns the total number of domainzone-entries for given domain
*
* @param int $id
* optional, the domain id
* @param string $domainname
* optional, the domain name
*
* @access admin, customer
* @throws \Exception
* @return bool
*/
public function listingCount()
{
if (Settings::Get('system.dnsenabled') != '1') {
throw new \Exception("DNS service not enabled on this system", 405);
}
if ($this->isAdmin() == false && $this->getUserDetail('dnsenabled') != '1') {
throw new \Exception("You cannot access this resource", 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'];
$sel_stmt = Database::prepare("SELECT COUNT(*) as num_dns FROM `" . TABLE_DOMAIN_DNS . "` WHERE `domain_id` = :did");
$result = Database::pexecute_first($sel_stmt, array(
'did' => $id
), true, true);
if ($result) {
return $this->response(200, "successfull", $result['num_dns']);
}
}
/** /**
* deletes a domain-dns entry by id * deletes a domain-dns entry by id
* *

View File

@@ -25,6 +25,17 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
/** /**
* lists all domain entries * lists all domain entries
* *
* @param bool $with_ips
* optional, default true
* @param array $sql_search
* optional array with index = fieldname, and value = array with 'op' => operator (one of <, > or =), LIKE is used if left empty and 'value' => searchvalue
* @param int $sql_limit
* optional specify number of results to be returned
* @param int $sql_offset
* optional specify offset for resultset
* @param array $sql_orderby
* optional array with index = fieldname and value = ASC|DESC to order the resultset by one or more fields
*
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return string json-encoded array count|list * @return string json-encoded array count|list
@@ -32,7 +43,9 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
public function listing() public function listing()
{ {
if ($this->isAdmin()) { if ($this->isAdmin()) {
$with_ips = $this->getParam('with_ips', true, true);
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] list domains"); $this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] list domains");
$query_fields = array();
$result_stmt = Database::prepare(" $result_stmt = Database::prepare("
SELECT SELECT
`d`.*, `c`.`loginname`, `c`.`deactivated`, `c`.`name`, `c`.`firstname`, `c`.`company`, `c`.`standardsubdomain`, `d`.*, `c`.`loginname`, `c`.`deactivated`, `c`.`name`, `c`.`firstname`, `c`.`company`, `c`.`standardsubdomain`,
@@ -40,14 +53,19 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
FROM `" . TABLE_PANEL_DOMAINS . "` `d` FROM `" . TABLE_PANEL_DOMAINS . "` `d`
LEFT JOIN `" . TABLE_PANEL_CUSTOMERS . "` `c` USING(`customerid`) LEFT JOIN `" . TABLE_PANEL_CUSTOMERS . "` `c` USING(`customerid`)
LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` `ad` ON `d`.`aliasdomain`=`ad`.`id` LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` `ad` ON `d`.`aliasdomain`=`ad`.`id`
WHERE `d`.`parentdomainid`='0' " . ($this->getUserDetail('customers_see_all') ? '' : " AND `d`.`adminid` = :adminid ")); WHERE `d`.`parentdomainid`='0' " . ($this->getUserDetail('customers_see_all') ? '' : " AND `d`.`adminid` = :adminid ") . $this->getSearchWhere($query_fields, true) . $this->getOrderBy() . $this->getLimit());
$params = array(); $params = array();
if ($this->getUserDetail('customers_see_all') == '0') { if ($this->getUserDetail('customers_see_all') == '0') {
$params['adminid'] = $this->getUserDetail('adminid'); $params['adminid'] = $this->getUserDetail('adminid');
} }
Database::pexecute($result_stmt, $params); $params = array_merge($params, $query_fields);
Database::pexecute($result_stmt, $params, true, true);
$result = array(); $result = array();
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) { while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
$row['ipsandports'] = array();
if ($with_ips) {
$row['ipsandports'] = $this->getIpsForDomain($row['id']);
}
$result[] = $row; $result[] = $row;
} }
return $this->response(200, "successfull", array( return $this->response(200, "successfull", array(
@@ -58,6 +76,36 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);
} }
/**
* returns the total number of accessable domains
*
* @access admin
* @throws \Exception
* @return string json-encoded array count|list
*/
public function listingCount()
{
if ($this->isAdmin()) {
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] list domains");
$result_stmt = Database::prepare("
SELECT
COUNT(*) as num_domains
FROM `" . TABLE_PANEL_DOMAINS . "` `d`
LEFT JOIN `" . TABLE_PANEL_CUSTOMERS . "` `c` USING(`customerid`)
LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` `ad` ON `d`.`aliasdomain`=`ad`.`id`
WHERE `d`.`parentdomainid`='0' " . ($this->getUserDetail('customers_see_all') ? '' : " AND `d`.`adminid` = :adminid "));
$params = array();
if ($this->getUserDetail('customers_see_all') == '0') {
$params['adminid'] = $this->getUserDetail('adminid');
}
$result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) {
return $this->response(200, "successfull", $result['num_domains']);
}
}
throw new \Exception("Not allowed to execute given command.", 403);
}
/** /**
* return a domain entry by either id or domainname * return a domain entry by either id or domainname
* *
@@ -65,6 +113,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
* optional, the domain-id * optional, the domain-id
* @param string $domainname * @param string $domainname
* optional, the domainname * optional, the domainname
* @param bool $with_ips
* optional, default true
* @param bool $no_std_subdomain * @param bool $no_std_subdomain
* optional, default false * optional, default false
* *
@@ -78,6 +128,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$id = $this->getParam('id', true, 0); $id = $this->getParam('id', true, 0);
$dn_optional = ($id <= 0 ? false : true); $dn_optional = ($id <= 0 ? false : true);
$domainname = $this->getParam('domainname', $dn_optional, ''); $domainname = $this->getParam('domainname', $dn_optional, '');
$with_ips = $this->getParam('with_ips', true, true);
$no_std_subdomain = $this->getParam('no_std_subdomain', true, false); $no_std_subdomain = $this->getParam('no_std_subdomain', true, false);
// convert possible idn domain to punycode // convert possible idn domain to punycode
@@ -100,6 +151,10 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
} }
$result = Database::pexecute_first($result_stmt, $params, true, true); $result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) { if ($result) {
$result['ipsandports'] = array();
if ($with_ips) {
$result['ipsandports'] = $this->getIpsForDomain($result['id']);
}
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] get domain '" . $result['domain'] . "'"); $this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] get domain '" . $result['domain'] . "'");
return $this->response(200, "successfull", $result); return $this->response(200, "successfull", $result);
} }
@@ -109,6 +164,34 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);
} }
/**
* get ips connected to given domain as array
*
* @param number $domain_id
* @return array
*/
private function getIpsForDomain($domain_id = 0)
{
$resultips_stmt = Database::prepare("
SELECT `ips`.* FROM `" . TABLE_DOMAINTOIP . "` AS `dti`, `" . TABLE_PANEL_IPSANDPORTS . "` AS `ips`
WHERE `dti`.`id_ipandports` = `ips`.`id` AND `dti`.`id_domain` = :domainid
");
Database::pexecute($resultips_stmt, array(
'domainid' => $domain_id
));
$ipandports = array();
while ($rowip = $resultips_stmt->fetch(\PDO::FETCH_ASSOC)) {
if (filter_var($rowip['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
$rowip['is_ipv6'] = true;
}
$ipandports[] = $rowip;
}
return $ipandports;
}
/** /**
* add new domain entry * add new domain entry
* *
@@ -187,6 +270,14 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
* optional whether or not to preload HSTS header value * optional whether or not to preload HSTS header value
* @param bool $ocsp_stapling * @param bool $ocsp_stapling
* optional whether to enable ocsp-stapling for this domain. default 0 (false), requires SSL * optional whether to enable ocsp-stapling for this domain. default 0 (false), requires SSL
* @param bool $override_tls
* optional whether or not to override system-tls settings like protocol, ssl-ciphers and if applicable tls-1.3 ciphers, requires change_serversettings flag for the admin, default false
* @param array $ssl_protocols
* optional list of allowed/used ssl/tls protocols, see system.ssl_protocols setting, only used/required if $override_tls is true, default empty or system.ssl_protocols setting if $override_tls is true
* @param string $ssl_cipher_list
* optional list of allowed/used ssl/tls ciphers, see system.ssl_cipher_list setting, only used/required if $override_tls is true, default empty or system.ssl_cipher_list setting if $override_tls is true
* @param string $tlsv13_cipher_list
* optional list of allowed/used tls-1.3 specific ciphers, see system.tlsv13_cipher_list setting, only used/required if $override_tls is true, default empty or system.tlsv13_cipher_list setting if $override_tls is true
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
@@ -239,6 +330,19 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$hsts_preload = $this->getBoolParam('hsts_preload', true, 0); $hsts_preload = $this->getBoolParam('hsts_preload', true, 0);
$ocsp_stapling = $this->getBoolParam('ocsp_stapling', true, 0); $ocsp_stapling = $this->getBoolParam('ocsp_stapling', true, 0);
$override_tls = $this->getBoolParam('override_tls', true, 0);
$p_ssl_protocols = array();
$ssl_cipher_list = "";
$tlsv13_cipher_list = "";
if ($this->getUserDetail('change_serversettings') == '1') {
if ($override_tls) {
$p_ssl_protocols = $this->getParam('ssl_protocols', true, explode(',', Settings::Get('system.ssl_protocols')));
$ssl_cipher_list = $this->getParam('ssl_cipher_list', true, Settings::Get('system.ssl_cipher_list'));
$tlsv13_cipher_list = $this->getParam('tlsv13_cipher_list', true, Settings::Get('system.tlsv13_cipher_list'));
}
}
// validation // validation
if ($p_domain == Settings::Get('system.hostname')) { if ($p_domain == Settings::Get('system.hostname')) {
\Froxlor\UI\Response::standard_error('admin_domain_emailsystemhostname', '', true); \Froxlor\UI\Response::standard_error('admin_domain_emailsystemhostname', '', true);
@@ -325,6 +429,34 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
} else { } else {
$documentroot = $_documentroot; $documentroot = $_documentroot;
} }
$ssl_protocols = array();
if (! empty($p_ssl_protocols) && is_numeric($p_ssl_protocols)) {
$p_ssl_protocols = array(
$p_ssl_protocols
);
}
if (! empty($p_ssl_protocols) && ! is_array($p_ssl_protocols)) {
$p_ssl_protocols = json_decode($p_ssl_protocols, true);
}
if (! empty($p_ssl_protocols) && is_array($p_ssl_protocols)) {
$protocols_available = array(
'TLSv1',
'TLSv1.1',
'TLSv1.2',
'TLSv1.3'
);
foreach ($p_ssl_protocols as $ssl_protocol) {
if (! in_array(trim($ssl_protocol), $protocols_available)) {
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_DEBUG, "[API] unknown SSL protocol '" . trim($ssl_protocol) . "'");
continue;
}
$ssl_protocols[] = $ssl_protocol;
}
}
if (empty($ssl_protocols)) {
$override_tls = '0';
}
} else { } else {
$isbinddomain = '0'; $isbinddomain = '0';
if (Settings::Get('system.bind_enable') == '1') { if (Settings::Get('system.bind_enable') == '1') {
@@ -340,6 +472,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$writeaccesslog = '1'; $writeaccesslog = '1';
$writeerrorlog = '1'; $writeerrorlog = '1';
$documentroot = $_documentroot; $documentroot = $_documentroot;
$override_tls = '0';
$ssl_protocols = array();
} }
if ($this->getUserDetail('caneditphpsettings') == '1' || $this->getUserDetail('change_serversettings') == '1') { if ($this->getUserDetail('caneditphpsettings') == '1' || $this->getUserDetail('change_serversettings') == '1') {
@@ -574,7 +708,11 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
'hsts' => $hsts_maxage, 'hsts' => $hsts_maxage,
'hsts_sub' => $hsts_sub, 'hsts_sub' => $hsts_sub,
'hsts_preload' => $hsts_preload, 'hsts_preload' => $hsts_preload,
'ocsp_stapling' => $ocsp_stapling 'ocsp_stapling' => $ocsp_stapling,
'override_tls' => $override_tls,
'ssl_protocols' => implode(",", $ssl_protocols),
'ssl_cipher_list' => $ssl_cipher_list,
'tlsv13_cipher_list' => $tlsv13_cipher_list
); );
$ins_stmt = Database::prepare(" $ins_stmt = Database::prepare("
@@ -618,7 +756,11 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
`hsts` = :hsts, `hsts` = :hsts,
`hsts_sub` = :hsts_sub, `hsts_sub` = :hsts_sub,
`hsts_preload` = :hsts_preload, `hsts_preload` = :hsts_preload,
`ocsp_stapling` = :ocsp_stapling `ocsp_stapling` = :ocsp_stapling,
`override_tls` = :override_tls,
`ssl_protocols` = :ssl_protocols,
`ssl_cipher_list` = :ssl_cipher_list,
`tlsv13_cipher_list` = :tlsv13_cipher_list
"); ");
Database::pexecute($ins_stmt, $ins_data, true, true); Database::pexecute($ins_stmt, $ins_data, true, true);
$domainid = Database::lastInsertId(); $domainid = Database::lastInsertId();
@@ -749,7 +891,9 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
* @param bool $letsencrypt * @param bool $letsencrypt
* optional, whether to generate a Let's Encrypt certificate for this domain, default false; requires SSL to be enabled * optional, whether to generate a Let's Encrypt certificate for this domain, default false; requires SSL to be enabled
* @param array $ssl_ipandport * @param array $ssl_ipandport
* optional, list of ssl-enabled ip/port id's to assign to this domain * optional, list of ssl-enabled ip/port id's to assign to this domain, if left empty, the current set value is being used, to remove all ssl ips use $remove_ssl_ipandport
* @param bool $remove_ssl_ipandport
* optional, if set to true and no $ssl_ipandport value is given, the ip's get removed, otherwise, the currently set value is used, default false
* @param bool $http2 * @param bool $http2
* optional, whether to enable http/2 for this domain (requires to be enabled in the settings), default 0 (false) * optional, whether to enable http/2 for this domain (requires to be enabled in the settings), default 0 (false)
* @param int $hsts_maxage * @param int $hsts_maxage
@@ -816,13 +960,34 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$mod_fcgid_maxrequests = $this->getParam('mod_fcgid_maxrequests', true, $result['mod_fcgid_maxrequests']); $mod_fcgid_maxrequests = $this->getParam('mod_fcgid_maxrequests', true, $result['mod_fcgid_maxrequests']);
$ssl_redirect = $this->getBoolParam('ssl_redirect', true, $result['ssl_redirect']); $ssl_redirect = $this->getBoolParam('ssl_redirect', true, $result['ssl_redirect']);
$letsencrypt = $this->getBoolParam('letsencrypt', true, $result['letsencrypt']); $letsencrypt = $this->getBoolParam('letsencrypt', true, $result['letsencrypt']);
$p_ssl_ipandports = $this->getParam('ssl_ipandport', true, array()); $remove_ssl_ipandport = $this->getBoolParam('remove_ssl_ipandport', true, 0);
$p_ssl_ipandports = $this->getParam('ssl_ipandport', true, $remove_ssl_ipandport ? array(
- 1
) : null);
$http2 = $this->getBoolParam('http2', true, $result['http2']); $http2 = $this->getBoolParam('http2', true, $result['http2']);
$hsts_maxage = $this->getParam('hsts_maxage', true, $result['hsts']); $hsts_maxage = $this->getParam('hsts_maxage', true, $result['hsts']);
$hsts_sub = $this->getBoolParam('hsts_sub', true, $result['hsts_sub']); $hsts_sub = $this->getBoolParam('hsts_sub', true, $result['hsts_sub']);
$hsts_preload = $this->getBoolParam('hsts_preload', true, $result['hsts_preload']); $hsts_preload = $this->getBoolParam('hsts_preload', true, $result['hsts_preload']);
$ocsp_stapling = $this->getBoolParam('ocsp_stapling', true, $result['ocsp_stapling']); $ocsp_stapling = $this->getBoolParam('ocsp_stapling', true, $result['ocsp_stapling']);
$override_tls = $this->getBoolParam('override_tls', true, $result['override_tls']);
if ($this->getUserDetail('change_serversettings') == '1') {
if ($override_tls) {
$p_ssl_protocols = $this->getParam('ssl_protocols', true, explode(',', $result['ssl_protocols']));
$ssl_cipher_list = $this->getParam('ssl_cipher_list', true, $result['ssl_cipher_list']);
$tlsv13_cipher_list = $this->getParam('tlsv13_cipher_list', true, $result['tlsv13_cipher_list']);
} else {
$p_ssl_protocols = array();
$ssl_cipher_list = "";
$tlsv13_cipher_list = "";
}
} else {
$p_ssl_protocols = explode(',', $result['ssl_protocols']);
$ssl_cipher_list = $result['ssl_cipher_list'];
$tlsv13_cipher_list = $result['tlsv13_cipher_list'];
}
// count subdomain usage of source-domain // count subdomain usage of source-domain
$subdomains_stmt = Database::prepare(" $subdomains_stmt = Database::prepare("
SELECT COUNT(`id`) AS count FROM `" . TABLE_PANEL_DOMAINS . "` WHERE SELECT COUNT(`id`) AS count FROM `" . TABLE_PANEL_DOMAINS . "` WHERE
@@ -992,6 +1157,34 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
if (! preg_match('/^https?\:\/\//', $documentroot) && strstr($documentroot, ":") !== false) { if (! preg_match('/^https?\:\/\//', $documentroot) && strstr($documentroot, ":") !== false) {
\Froxlor\UI\Response::standard_error('pathmaynotcontaincolon', '', true); \Froxlor\UI\Response::standard_error('pathmaynotcontaincolon', '', true);
} }
$ssl_protocols = array();
if (! empty($p_ssl_protocols) && is_numeric($p_ssl_protocols)) {
$p_ssl_protocols = array(
$p_ssl_protocols
);
}
if (! empty($p_ssl_protocols) && ! is_array($p_ssl_protocols)) {
$p_ssl_protocols = json_decode($p_ssl_protocols, true);
}
if (! empty($p_ssl_protocols) && is_array($p_ssl_protocols)) {
$protocols_available = array(
'TLSv1',
'TLSv1.1',
'TLSv1.2',
'TLSv1.3'
);
foreach ($p_ssl_protocols as $ssl_protocol) {
if (! in_array(trim($ssl_protocol), $protocols_available)) {
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_DEBUG, "[API] unknown SSL protocol '" . trim($ssl_protocol) . "'");
continue;
}
$ssl_protocols[] = $ssl_protocol;
}
}
if (empty($ssl_protocols)) {
$override_tls = '0';
}
} else { } else {
$isbinddomain = $result['isbinddomain']; $isbinddomain = $result['isbinddomain'];
$zonefile = $result['zonefile']; $zonefile = $result['zonefile'];
@@ -1004,6 +1197,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$writeaccesslog = $result['writeaccesslog']; $writeaccesslog = $result['writeaccesslog'];
$writeerrorlog = $result['writeerrorlog']; $writeerrorlog = $result['writeerrorlog'];
$documentroot = $result['documentroot']; $documentroot = $result['documentroot'];
$override_tls = $result['override_tls'];
} }
if ($this->getUserDetail('caneditphpsettings') == '1' || $this->getUserDetail('change_serversettings') == '1') { if ($this->getUserDetail('caneditphpsettings') == '1' || $this->getUserDetail('change_serversettings') == '1') {
@@ -1051,14 +1246,24 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
// check non-ssl IP // check non-ssl IP
$ipandports = $this->validateIpAddresses($p_ipandports, false, $result['id']); $ipandports = $this->validateIpAddresses($p_ipandports, false, $result['id']);
// check ssl IP // check ssl IP
if (empty($p_ssl_ipandports) || (! is_array($p_ssl_ipandports) && is_null($p_ssl_ipandports))) {
foreach ($result['ipsandports'] as $ip) {
if ($ip['ssl'] == 1) {
$p_ssl_ipandports[] = $ip['id'];
}
}
}
$ssl_ipandports = array(); $ssl_ipandports = array();
if (Settings::Get('system.use_ssl') == "1" && ! empty($p_ssl_ipandports)) { if (Settings::Get('system.use_ssl') == "1" && ! empty($p_ssl_ipandports) && $p_ssl_ipandports[0] != - 1) {
$ssl_ipandports = $this->validateIpAddresses($p_ssl_ipandports, true, $result['id']); $ssl_ipandports = $this->validateIpAddresses($p_ssl_ipandports, true, $result['id']);
if ($this->getUserDetail('change_serversettings') == '1') { if ($this->getUserDetail('change_serversettings') == '1') {
$ssl_specialsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $ssl_specialsettings), 'ssl_specialsettings', '/^[^\0]*$/', '', array(), true); $ssl_specialsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $ssl_specialsettings), 'ssl_specialsettings', '/^[^\0]*$/', '', array(), true);
} }
} }
if ($remove_ssl_ipandport || (! empty($p_ssl_ipandports) && $p_ssl_ipandports[0] == - 1)) {
$ssl_ipandports = array();
}
if (Settings::Get('system.use_ssl') == "0" || empty($ssl_ipandports)) { if (Settings::Get('system.use_ssl') == "0" || empty($ssl_ipandports)) {
$ssl_redirect = 0; $ssl_redirect = 0;
$letsencrypt = 0; $letsencrypt = 0;
@@ -1337,6 +1542,10 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$update_data['hsts_sub'] = $hsts_sub; $update_data['hsts_sub'] = $hsts_sub;
$update_data['hsts_preload'] = $hsts_preload; $update_data['hsts_preload'] = $hsts_preload;
$update_data['ocsp_stapling'] = $ocsp_stapling; $update_data['ocsp_stapling'] = $ocsp_stapling;
$update_data['override_tls'] = $override_tls;
$update_data['ssl_protocols'] = implode(",", $ssl_protocols);
$update_data['ssl_cipher_list'] = $ssl_cipher_list;
$update_data['tlsv13_cipher_list'] = $tlsv13_cipher_list;
$update_data['id'] = $id; $update_data['id'] = $id;
$update_stmt = Database::prepare(" $update_stmt = Database::prepare("
@@ -1375,7 +1584,11 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
`hsts` = :hsts, `hsts` = :hsts,
`hsts_sub` = :hsts_sub, `hsts_sub` = :hsts_sub,
`hsts_preload` = :hsts_preload, `hsts_preload` = :hsts_preload,
`ocsp_stapling` = :ocsp_stapling `ocsp_stapling` = :ocsp_stapling,
`override_tls` = :override_tls,
`ssl_protocols` = :ssl_protocols,
`ssl_cipher_list` = :ssl_cipher_list,
`tlsv13_cipher_list` = :tlsv13_cipher_list
WHERE `id` = :id WHERE `id` = :id
"); ");
Database::pexecute($update_stmt, $update_data, true, true); Database::pexecute($update_stmt, $update_data, true, true);
@@ -1386,6 +1599,10 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$_update_data['openbasedir'] = $openbasedir; $_update_data['openbasedir'] = $openbasedir;
$_update_data['mod_fcgid_starter'] = $mod_fcgid_starter; $_update_data['mod_fcgid_starter'] = $mod_fcgid_starter;
$_update_data['mod_fcgid_maxrequests'] = $mod_fcgid_maxrequests; $_update_data['mod_fcgid_maxrequests'] = $mod_fcgid_maxrequests;
$_update_data['override_tls'] = $override_tls;
$_update_data['ssl_protocols'] = implode(",", $ssl_protocols);
$_update_data['ssl_cipher_list'] = $ssl_cipher_list;
$_update_data['tlsv13_cipher_list'] = $tlsv13_cipher_list;
$_update_data['parentdomainid'] = $id; $_update_data['parentdomainid'] = $id;
// if php config is to be set for all subdomains, check here // if php config is to be set for all subdomains, check here
@@ -1394,7 +1611,6 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$_update_data['phpsettingid'] = $phpsettingid; $_update_data['phpsettingid'] = $phpsettingid;
$update_phpconfig = ", `phpsettingid` = :phpsettingid"; $update_phpconfig = ", `phpsettingid` = :phpsettingid";
} }
// if we have no more ssl-ip's for this domain, // if we have no more ssl-ip's for this domain,
// all its subdomains must have "ssl-redirect = 0" // all its subdomains must have "ssl-redirect = 0"
// and disable let's encrypt // and disable let's encrypt
@@ -1410,7 +1626,11 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
`phpenabled` = :phpenabled, `phpenabled` = :phpenabled,
`openbasedir` = :openbasedir, `openbasedir` = :openbasedir,
`mod_fcgid_starter` = :mod_fcgid_starter, `mod_fcgid_starter` = :mod_fcgid_starter,
`mod_fcgid_maxrequests` = :mod_fcgid_maxrequests `mod_fcgid_maxrequests` = :mod_fcgid_maxrequests,
`override_tls` = :override_tls,
`ssl_protocols` = :ssl_protocols,
`ssl_cipher_list` = :ssl_cipher_list,
`tlsv13_cipher_list` = :tlsv13_cipher_list
" . $update_phpconfig . $upd_specialsettings . $updatechildren . $update_sslredirect . " " . $update_phpconfig . $upd_specialsettings . $updatechildren . $update_sslredirect . "
WHERE `parentdomainid` = :parentdomainid WHERE `parentdomainid` = :parentdomainid
"); ");
@@ -1735,8 +1955,10 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
} elseif ($edit_id > 0) { } elseif ($edit_id > 0) {
// set currently used ip's // set currently used ip's
$ipsresult_stmt = Database::prepare(" $ipsresult_stmt = Database::prepare("
SELECT `id_ipandports` FROM `" . TABLE_DOMAINTOIP . "` WHERE `id_domain` = :id SELECT d2i.`id_ipandports`
"); FROM `" . TABLE_DOMAINTOIP . "` d2i
LEFT JOIN `" . TABLE_PANEL_IPSANDPORTS . "` i ON i.id = d2i.id_ipandports
WHERE d2i.`id_domain` = :id AND i.`ssl` = " . ($ssl ? "'1'" : "'0'"));
Database::pexecute($ipsresult_stmt, array( Database::pexecute($ipsresult_stmt, array(
'id' => $edit_id 'id' => $edit_id
), true, true); ), true, true);

View File

@@ -388,12 +388,21 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
} }
/** /**
* You cannot directly list email forwarders. * You cannot directly list email accounts.
* You need to call Emails.listing() * You need to call Emails.listing()
*/ */
public function listing() public function listing()
{ {
throw new \Exception('You cannot directly list email forwarders. You need to call Emails.listing()', 303); throw new \Exception('You cannot directly list email accounts. You need to call Emails.listing()', 303);
}
/**
* You cannot directly count email accounts.
* You need to call Emails.listingCount()
*/
public function listingCount()
{
throw new \Exception('You cannot directly count email accounts. You need to call Emails.listingCount()', 303);
} }
/** /**

View File

@@ -109,11 +109,11 @@ class EmailForwarders extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
/** /**
* You cannot directly get an email forwarder. * You cannot directly get an email forwarder.
* You need to call Emails.get() * Try EmailForwarders.listing()
*/ */
public function get() public function get()
{ {
throw new \Exception('You cannot directly get an email forwarder. You need to call Emails.get()', 303); throw new \Exception('You cannot directly get an email forwarder. Try EmailForwarders.listing()', 303);
} }
/** /**
@@ -126,12 +126,91 @@ class EmailForwarders extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
} }
/** /**
* You cannot directly list email forwarders. * List email forwarders for a given email address
* You need to call Emails.listing() *
* @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
*
* @access admin,customer
* @throws \Exception
* @return string json-encoded array count|list
*/ */
public function listing() public function listing()
{ {
throw new \Exception('You cannot directly list email forwarders. You need to call Emails.listing()', 303); 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'];
$result['destination'] = explode(' ', $result['destination']);
$destination = array();
foreach ($result['destination'] as $index => $address) {
$destination[] = [
'id' => $index,
'address' => $address
];
}
return $this->response(200, "successfull", [
'count' => count($destination),
'list' => $destination
]);
}
/**
* count email forwarders for a given email address
*
* @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
*
* @access admin,customer
* @throws \Exception
* @return string json-encoded array
*/
public function listingCount()
{
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'];
$result['destination'] = explode(' ', $result['destination']);
return $this->response(200, "successfull", count($result['destination']));
} }
/** /**

View File

@@ -265,6 +265,14 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* optional, admin-only, select email addresses of a specific customer by id * optional, admin-only, select email addresses of a specific customer by id
* @param string $loginname * @param string $loginname
* optional, admin-only, select email addresses of a specific customer by loginname * optional, admin-only, select email addresses of a specific customer by loginname
* @param array $sql_search
* optional array with index = fieldname, and value = array with 'op' => operator (one of <, > or =), LIKE is used if left empty and 'value' => searchvalue
* @param int $sql_limit
* optional specify number of results to be returned
* @param int $sql_offset
* optional specify offset for resultset
* @param array $sql_orderby
* optional array with index = fieldname and value = ASC|DESC to order the resultset by one or more fields
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
@@ -274,14 +282,14 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
{ {
$customer_ids = $this->getAllowedCustomerIds('email'); $customer_ids = $this->getAllowedCustomerIds('email');
$result = array(); $result = array();
$query_fields = array();
$result_stmt = Database::prepare(" $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` 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 FROM `" . TABLE_MAIL_VIRTUAL . "` m
LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` d ON (m.`domainid` = d.`id`) LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` d ON (m.`domainid` = d.`id`)
LEFT JOIN `" . TABLE_MAIL_USERS . "` u ON (m.`popaccountid` = u.`id`) LEFT JOIN `" . TABLE_MAIL_USERS . "` u ON (m.`popaccountid` = u.`id`)
WHERE m.`customerid` IN (" . implode(", ", $customer_ids) . ") WHERE m.`customerid` IN (" . implode(", ", $customer_ids) . ")" . $this->getSearchWhere($query_fields, true) . $this->getOrderBy() . $this->getLimit());
"); Database::pexecute($result_stmt, $query_fields, true, true);
Database::pexecute($result_stmt, null, true, true);
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) { while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
$result[] = $row; $result[] = $row;
} }
@@ -292,6 +300,34 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
)); ));
} }
/**
* returns the total number of accessable email addresses
*
* @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 string json-encoded array
*/
public function listingCount()
{
$customer_ids = $this->getAllowedCustomerIds('email');
$result_stmt = Database::prepare("
SELECT COUNT(*) as num_emails
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) . ")
");
$result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) {
return $this->response(200, "successfull", $result['num_emails']);
}
}
/** /**
* delete an email address by either id or username * delete an email address by either id or username
* *

View File

@@ -24,6 +24,15 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
/** /**
* lists all fpm-daemon entries * lists all fpm-daemon entries
* *
* @param array $sql_search
* optional array with index = fieldname, and value = array with 'op' => operator (one of <, > or =), LIKE is used if left empty and 'value' => searchvalue
* @param int $sql_limit
* optional specify number of results to be returned
* @param int $sql_offset
* optional specify offset for resultset
* @param array $sql_orderby
* optional array with index = fieldname and value = ASC|DESC to order the resultset by one or more fields
*
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return string json-encoded array count|list * @return string json-encoded array count|list
@@ -32,21 +41,18 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
{ {
if ($this->isAdmin()) { if ($this->isAdmin()) {
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] list fpm-daemons"); $this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] list fpm-daemons");
$query_fields = array();
$result = Database::query(" $result_stmt = Database::prepare("
SELECT * FROM `" . TABLE_PANEL_FPMDAEMONS . "` ORDER BY `description` ASC SELECT * FROM `" . TABLE_PANEL_FPMDAEMONS . "`" . $this->getSearchWhere($query_fields) . $this->getOrderBy() . $this->getLimit());
"); Database::pexecute($result_stmt, $query_fields, true, true);
$fpmdaemons = array(); $fpmdaemons = array();
while ($row = $result->fetch(\PDO::FETCH_ASSOC)) { while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
$query_params = array( $query_params = array(
'id' => $row['id'] 'id' => $row['id']
); );
$query = "SELECT * FROM `" . TABLE_PANEL_PHPCONFIGS . "` WHERE `fpmsettingid` = :id"; $configresult_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_PHPCONFIGS . "` WHERE `fpmsettingid` = :id");
$configresult_stmt = Database::prepare($query);
Database::pexecute($configresult_stmt, $query_params, true, true); Database::pexecute($configresult_stmt, $query_params, true, true);
$configs = array(); $configs = array();
@@ -72,6 +78,27 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);
} }
/**
* returns the total number of accessable fpm daemons
*
* @access admin
* @throws \Exception
* @return string json-encoded array
*/
public function listingCount()
{
if ($this->isAdmin()) {
$result_stmt = Database::prepare("
SELECT COUNT(*) as num_fpms FROM `" . TABLE_PANEL_FPMDAEMONS . "`
");
$result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) {
return $this->response(200, "successfull", $result['num_fpms']);
}
}
throw new \Exception("Not allowed to execute given command.", 403);
}
/** /**
* return a fpm-daemon entry by id * return a fpm-daemon entry by id
* *

View File

@@ -56,7 +56,9 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
throw new \Exception("You cannot access this resource", 405); throw new \Exception("You cannot access this resource", 405);
} }
if ($this->getUserDetail('ftps_used') < $this->getUserDetail('ftps') || $this->getUserDetail('ftps') == '-1') { $is_defaultuser = $this->getBoolParam('is_defaultuser', true, 0);
if (($this->getUserDetail('ftps_used') < $this->getUserDetail('ftps') || $this->getUserDetail('ftps') == '-1') || $this->isAdmin() && $is_defaultuser == 1) {
// required paramters // required paramters
$path = $this->getParam('path'); $path = $this->getParam('path');
@@ -71,7 +73,6 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
$ftpdomain = $this->getParam('ftp_domain', true, ''); $ftpdomain = $this->getParam('ftp_domain', true, '');
$additional_members = $this->getParam('additional_members', true, array()); $additional_members = $this->getParam('additional_members', true, array());
$is_defaultuser = $this->getBoolParam('is_defaultuser', true, 0);
// validation // validation
$password = \Froxlor\Validate\Validate::validate($password, 'password', '', '', array(), true); $password = \Froxlor\Validate\Validate::validate($password, 'password', '', '', array(), true);
@@ -105,7 +106,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
$sendinfomail = 0; $sendinfomail = 0;
} }
if (Settings::Get('customer.ftpatdomain') == '1' && !$is_defaultuser) { if (Settings::Get('customer.ftpatdomain') == '1' && ! $is_defaultuser) {
if ($ftpusername == '') { if ($ftpusername == '') {
\Froxlor\UI\Response::standard_error(array( \Froxlor\UI\Response::standard_error(array(
'stringisempty', 'stringisempty',
@@ -459,6 +460,14 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
* optional, admin-only, select ftp-users of a specific customer by id * optional, admin-only, select ftp-users of a specific customer by id
* @param string $loginname * @param string $loginname
* optional, admin-only, select ftp-users of a specific customer by loginname * optional, admin-only, select ftp-users of a specific customer by loginname
* @param array $sql_search
* optional array with index = fieldname, and value = array with 'op' => operator (one of <, > or =), LIKE is used if left empty and 'value' => searchvalue
* @param int $sql_limit
* optional specify number of results to be returned
* @param int $sql_offset
* optional specify offset for resultset
* @param array $sql_orderby
* optional array with index = fieldname and value = ASC|DESC to order the resultset by one or more fields
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
@@ -468,11 +477,11 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
{ {
$customer_ids = $this->getAllowedCustomerIds('ftp'); $customer_ids = $this->getAllowedCustomerIds('ftp');
$result = array(); $result = array();
$query_fields = array();
$result_stmt = Database::prepare(" $result_stmt = Database::prepare("
SELECT * FROM `" . TABLE_FTP_USERS . "` SELECT * FROM `" . TABLE_FTP_USERS . "`
WHERE `customerid` IN (" . implode(", ", $customer_ids) . ") WHERE `customerid` IN (" . implode(", ", $customer_ids) . ")" . $this->getSearchWhere($query_fields, true) . $this->getOrderBy() . $this->getLimit());
"); Database::pexecute($result_stmt, $query_fields, true, true);
Database::pexecute($result_stmt, null, true, true);
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) { while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
$result[] = $row; $result[] = $row;
} }
@@ -483,6 +492,32 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
)); ));
} }
/**
* returns the total number of accessable ftp accounts
*
* @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 string json-encoded array
*/
public function listingCount()
{
$customer_ids = $this->getAllowedCustomerIds('ftp');
$result = array();
$result_stmt = Database::prepare("
SELECT COUNT(*) as num_ftps FROM `" . TABLE_FTP_USERS . "`
WHERE `customerid` IN (" . implode(", ", $customer_ids) . ")
");
$result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) {
return $this->response(200, "successfull", $result['num_ftps']);
}
}
/** /**
* delete a ftp-user by either id or username * delete a ftp-user by either id or username
* *
@@ -541,6 +576,9 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
"username" => $customer_data['loginname'] "username" => $customer_data['loginname']
); );
Database::pexecute($stmt, $params, true, true); Database::pexecute($stmt, $params, true, true);
} else {
// do not allow removing default ftp-account
\Froxlor\UI\Response::standard_error('ftp_cantdeletemainaccount', '', true);
} }
// remove all quotatallies // remove all quotatallies

View File

@@ -25,6 +25,15 @@ class HostingPlans extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
/** /**
* list all available hosting plans * list all available hosting plans
* *
* @param array $sql_search
* optional array with index = fieldname, and value = array with 'op' => operator (one of <, > or =), LIKE is used if left empty and 'value' => searchvalue
* @param int $sql_limit
* optional specify number of results to be returned
* @param int $sql_offset
* optional specify offset for resultset
* @param array $sql_orderby
* optional array with index = fieldname and value = ASC|DESC to order the resultset by one or more fields
*
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return string json-encoded array count|list * @return string json-encoded array count|list
@@ -33,15 +42,17 @@ class HostingPlans extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
{ {
if ($this->isAdmin()) { if ($this->isAdmin()) {
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] list hosting-plans"); $this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] list hosting-plans");
$query_fields = array();
$result_stmt = Database::prepare(" $result_stmt = Database::prepare("
SELECT p.*, a.loginname as adminname SELECT p.*, a.loginname as adminname
FROM `" . TABLE_PANEL_PLANS . "` p, `" . TABLE_PANEL_ADMINS . "` a FROM `" . TABLE_PANEL_PLANS . "` p, `" . TABLE_PANEL_ADMINS . "` a
WHERE `p`.`adminid` = `a`.`adminid`" . ($this->getUserDetail('customers_see_all') ? '' : " AND `p`.`adminid` = :adminid ")); WHERE `p`.`adminid` = `a`.`adminid`" . ($this->getUserDetail('customers_see_all') ? '' : " AND `p`.`adminid` = :adminid ") . $this->getSearchWhere($query_fields, true) . $this->getOrderBy() . $this->getLimit());
$params = array(); $params = array();
if ($this->getUserDetail('customers_see_all') == '0') { if ($this->getUserDetail('customers_see_all') == '0') {
$params['adminid'] = $this->getUserDetail('adminid'); $params['adminid'] = $this->getUserDetail('adminid');
} }
Database::pexecute($result_stmt, $params); $params = array_merge($params, $query_fields);
Database::pexecute($result_stmt, $params, true, true);
$result = array(); $result = array();
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) { while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
$result[] = $row; $result[] = $row;
@@ -54,6 +65,32 @@ class HostingPlans extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);
} }
/**
* returns the total number of accessable hosting plans
*
* @access admin
* @throws \Exception
* @return string json-encoded array
*/
public function listingCount()
{
if ($this->isAdmin()) {
$result_stmt = Database::prepare("
SELECT COUNT(*) as num_plans
FROM `" . TABLE_PANEL_PLANS . "` p, `" . TABLE_PANEL_ADMINS . "` a
WHERE `p`.`adminid` = `a`.`adminid`" . ($this->getUserDetail('customers_see_all') ? '' : " AND `p`.`adminid` = :adminid "));
$params = array();
if ($this->getUserDetail('customers_see_all') == '0') {
$params['adminid'] = $this->getUserDetail('adminid');
}
$result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) {
return $this->response(200, "successfull", $result['num_plans']);
}
}
throw new \Exception("Not allowed to execute given command.", 403);
}
/** /**
* return a hosting-plan entry by either id or plan-name * return a hosting-plan entry by either id or plan-name
* *

View File

@@ -25,6 +25,15 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
/** /**
* lists all ip/port entries * lists all ip/port entries
* *
* @param array $sql_search
* optional array with index = fieldname, and value = array with 'op' => operator (one of <, > or =), LIKE is used if left empty and 'value' => searchvalue
* @param int $sql_limit
* optional specify number of results to be returned
* @param int $sql_offset
* optional specify offset for resultset
* @param array $sql_orderby
* optional array with index = fieldname and value = ASC|DESC to order the resultset by one or more fields
*
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return string json-encoded array count|list * @return string json-encoded array count|list
@@ -34,12 +43,14 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
if ($this->isAdmin() && ($this->getUserDetail('change_serversettings') || ! empty($this->getUserDetail('ip')))) { if ($this->isAdmin() && ($this->getUserDetail('change_serversettings') || ! empty($this->getUserDetail('ip')))) {
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] list ips and ports"); $this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] list ips and ports");
$ip_where = ""; $ip_where = "";
$append_where = false;
if (! empty($this->getUserDetail('ip')) && $this->getUserDetail('ip') != - 1) { if (! empty($this->getUserDetail('ip')) && $this->getUserDetail('ip') != - 1) {
$ip_where = "WHERE `id` IN (" . implode(", ", json_decode($this->getUserDetail('ip'), true)) . ")"; $ip_where = "WHERE `id` IN (" . implode(", ", json_decode($this->getUserDetail('ip'), true)) . ")";
$append_where = true;
} }
$query_fields = array();
$result_stmt = Database::prepare(" $result_stmt = Database::prepare("
SELECT * FROM `" . TABLE_PANEL_IPSANDPORTS . "` " . $ip_where . " ORDER BY `ip` ASC, `port` ASC SELECT * FROM `" . TABLE_PANEL_IPSANDPORTS . "` " . $ip_where . $this->getSearchWhere($query_fields, $append_where) . $this->getOrderBy() . $this->getLimit());
");
Database::pexecute($result_stmt, null, true, true); Database::pexecute($result_stmt, null, true, true);
$result = array(); $result = array();
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) { while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
@@ -53,6 +64,30 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);
} }
/**
* returns the total number of accessable ip/port entries
*
* @access admin
* @throws \Exception
* @return string json-encoded array
*/
public function listingCount()
{
if ($this->isAdmin() && ($this->getUserDetail('change_serversettings') || ! empty($this->getUserDetail('ip')))) {
$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 COUNT(*) as num_ips FROM `" . TABLE_PANEL_IPSANDPORTS . "` " . $ip_where);
$result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) {
return $this->response(200, "successfull", $result['num_ips']);
}
}
throw new \Exception("Not allowed to execute given command.", 403);
}
/** /**
* return an ip/port entry by id * return an ip/port entry by id
* *
@@ -135,7 +170,7 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
{ {
if ($this->isAdmin() && $this->getUserDetail('change_serversettings')) { if ($this->isAdmin() && $this->getUserDetail('change_serversettings')) {
$ip = \Froxlor\Validate\Validate::validate_ip2($this->getParam('ip'), false, 'invalidip', false, false, false, true); $ip = \Froxlor\Validate\Validate::validate_ip2($this->getParam('ip'), false, 'invalidip', false, false, false, false, true);
$port = \Froxlor\Validate\Validate::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( $port = \Froxlor\Validate\Validate::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', 'stringisempty',
'myport' 'myport'
@@ -332,7 +367,7 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
'id' => $id 'id' => $id
)); ));
$ip = \Froxlor\Validate\Validate::validate_ip2($this->getParam('ip', true, $result['ip']), false, 'invalidip', false, false, false, true); $ip = \Froxlor\Validate\Validate::validate_ip2($this->getParam('ip', true, $result['ip']), false, 'invalidip', false, false, false, false, true);
$port = \Froxlor\Validate\Validate::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( $port = \Froxlor\Validate\Validate::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', 'stringisempty',
'myport' 'myport'

View File

@@ -34,7 +34,9 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* @param bool $sendinfomail * @param bool $sendinfomail
* optional, send created resource-information to customer, default: false * optional, send created resource-information to customer, default: false
* @param int $customerid * @param int $customerid
* required when called as admin, not needed when called as customer * optional, admin-only, the customer-id
* @param string $loginname
* optional, admin-only, the loginname
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
@@ -42,8 +44,6 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
*/ */
public function add() public function add()
{ {
if ($this->getUserDetail('mysqls_used') < $this->getUserDetail('mysqls') || $this->getUserDetail('mysqls') == '-1') {
// required paramters // required paramters
$password = $this->getParam('mysql_password'); $password = $this->getParam('mysql_password');
@@ -51,6 +51,8 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$dbserver = $this->getParam('mysql_server', true, 0); $dbserver = $this->getParam('mysql_server', true, 0);
$databasedescription = $this->getParam('description', true, ''); $databasedescription = $this->getParam('description', true, '');
$sendinfomail = $this->getBoolParam('sendinfomail', true, 0); $sendinfomail = $this->getBoolParam('sendinfomail', true, 0);
// get needed customer info to reduce the mysql-usage-counter by one
$customer = $this->getCustomerData('mysqls');
// validation // validation
$password = \Froxlor\Validate\Validate::validate($password, 'password', '', '', array(), true); $password = \Froxlor\Validate\Validate::validate($password, 'password', '', '', array(), true);
@@ -71,9 +73,6 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$sendinfomail = 0; $sendinfomail = 0;
} }
// get needed customer info to reduce the mysql-usage-counter by one
$customer = $this->getCustomerData('mysqls');
$newdb_params = array( $newdb_params = array(
'loginname' => ($this->isAdmin() ? $customer['loginname'] : $this->getUserDetail('loginname')), 'loginname' => ($this->isAdmin() ? $customer['loginname'] : $this->getUserDetail('loginname')),
'mysql_lastaccountnumber' => ($this->isAdmin() ? $customer['mysql_lastaccountnumber'] : $this->getUserDetail('mysql_lastaccountnumber')) 'mysql_lastaccountnumber' => ($this->isAdmin() ? $customer['mysql_lastaccountnumber'] : $this->getUserDetail('mysql_lastaccountnumber'))
@@ -168,8 +167,6 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
)); ));
return $this->response(200, "successfull", $result); return $this->response(200, "successfull", $result);
} }
throw new \Exception("No more resources available", 406);
}
/** /**
* return a mysql database entry by either id or dbname * return a mysql database entry by either id or dbname
@@ -276,6 +273,10 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* optional, update password for the database * optional, update password for the database
* @param string $description * @param string $description
* optional, description for database * optional, description for database
* @param int $customerid
* optional, admin-only, the customer-id
* @param string $loginname
* optional, admin-only, the loginname
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
@@ -287,6 +288,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$dn_optional = ($id <= 0 ? false : true); $dn_optional = ($id <= 0 ? false : true);
$dbname = $this->getParam('dbname', $dn_optional, ''); $dbname = $this->getParam('dbname', $dn_optional, '');
$dbserver = $this->getParam('mysql_server', true, - 1); $dbserver = $this->getParam('mysql_server', true, - 1);
$customer = $this->getCustomerData();
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'mysql')) { if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'mysql')) {
throw new \Exception("You cannot access this resource", 405); throw new \Exception("You cannot access this resource", 405);
@@ -307,9 +309,6 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$password = \Froxlor\Validate\Validate::validate($password, 'password', '', '', array(), true); $password = \Froxlor\Validate\Validate::validate($password, 'password', '', '', array(), true);
$databasedescription = \Froxlor\Validate\Validate::validate(trim($databasedescription), 'description', '', '', array(), true); $databasedescription = \Froxlor\Validate\Validate::validate(trim($databasedescription), 'description', '', '', array(), true);
// get needed customer info to reduce the mysql-usage-counter by one
$customer = $this->getCustomerData();
if ($password != '') { if ($password != '') {
// validate password // validate password
$password = \Froxlor\System\Crypt::validatePassword($password, true); $password = \Froxlor\System\Crypt::validatePassword($password, true);
@@ -359,6 +358,14 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* optional, admin-only, select dbs of a specific customer by id * optional, admin-only, select dbs of a specific customer by id
* @param string $loginname * @param string $loginname
* optional, admin-only, select dbs of a specific customer by loginname * optional, admin-only, select dbs of a specific customer by loginname
* @param array $sql_search
* optional array with index = fieldname, and value = array with 'op' => operator (one of <, > or =), LIKE is used if left empty and 'value' => searchvalue
* @param int $sql_limit
* optional specify number of results to be returned
* @param int $sql_offset
* optional specify offset for resultset
* @param array $sql_orderby
* optional array with index = fieldname and value = ASC|DESC to order the resultset by one or more fields
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
@@ -369,10 +376,10 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$result = array(); $result = array();
$dbserver = $this->getParam('mysql_server', true, - 1); $dbserver = $this->getParam('mysql_server', true, - 1);
$customer_ids = $this->getAllowedCustomerIds('mysql'); $customer_ids = $this->getAllowedCustomerIds('mysql');
$query_fields = array();
$result_stmt = Database::prepare(" $result_stmt = Database::prepare("
SELECT * FROM `" . TABLE_PANEL_DATABASES . "` SELECT * FROM `" . TABLE_PANEL_DATABASES . "`
WHERE `customerid`= :customerid AND `dbserver` = :dbserver WHERE `customerid`= :customerid AND `dbserver` = :dbserver" . $this->getSearchWhere($query_fields, true) . $this->getOrderBy() . $this->getLimit());
");
if ($dbserver < 0) { if ($dbserver < 0) {
// use all dbservers // use all dbservers
$dbservers_stmt = Database::query("SELECT DISTINCT `dbserver` FROM `" . TABLE_PANEL_DATABASES . "`"); $dbservers_stmt = Database::query("SELECT DISTINCT `dbserver` FROM `" . TABLE_PANEL_DATABASES . "`");
@@ -388,10 +395,10 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
foreach ($customer_ids as $customer_id) { foreach ($customer_ids as $customer_id) {
foreach ($dbservers as $_dbserver) { foreach ($dbservers as $_dbserver) {
Database::pexecute($result_stmt, array( Database::pexecute($result_stmt, array_merge(array(
'customerid' => $customer_id, 'customerid' => $customer_id,
'dbserver' => $_dbserver['dbserver'] 'dbserver' => $_dbserver['dbserver']
), true, true); ), $query_fields), true, true);
// Begin root-session // Begin root-session
Database::needRoot(true, $_dbserver['dbserver']); Database::needRoot(true, $_dbserver['dbserver']);
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) { while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
@@ -416,6 +423,31 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
)); ));
} }
/**
* returns the total number of accessable databases
*
* @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 string json-encoded array
*/
public function listingCount()
{
$customer_ids = $this->getAllowedCustomerIds('mysql');
$result_stmt = Database::prepare("
SELECT COUNT(*) as num_dbs FROM `" . TABLE_PANEL_DATABASES . "`
WHERE `customerid` IN (" . implode(", ", $customer_ids) . ")
");
$result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) {
return $this->response(200, "successfull", $result['num_dbs']);
}
}
/** /**
* delete a mysql database by either id or dbname * delete a mysql database by either id or dbname
* *
@@ -425,6 +457,10 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* optional, the databasename * optional, the databasename
* @param int $mysql_server * @param int $mysql_server
* optional, specify database-server, default is none * optional, specify database-server, default is none
* @param int $customerid
* optional, admin-only, the customer-id
* @param string $loginname
* optional, admin-only, the loginname
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
@@ -436,6 +472,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$dn_optional = ($id <= 0 ? false : true); $dn_optional = ($id <= 0 ? false : true);
$dbname = $this->getParam('dbname', $dn_optional, ''); $dbname = $this->getParam('dbname', $dn_optional, '');
$dbserver = $this->getParam('mysql_server', true, - 1); $dbserver = $this->getParam('mysql_server', true, - 1);
$customer = $this->getCustomerData();
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'mysql')) { if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'mysql')) {
throw new \Exception("You cannot access this resource", 405); throw new \Exception("You cannot access this resource", 405);
@@ -462,7 +499,6 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
), true, true); ), true, true);
// get needed customer info to reduce the mysql-usage-counter by one // get needed customer info to reduce the mysql-usage-counter by one
$customer = $this->getCustomerData();
$mysql_used = $customer['mysqls_used']; $mysql_used = $customer['mysqls_used'];
// reduce mysql-usage-counter // reduce mysql-usage-counter

View File

@@ -27,6 +27,14 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
* *
* @param bool $with_subdomains * @param bool $with_subdomains
* optional, also include subdomains to the list domains that use the config, default 0 (false) * optional, also include subdomains to the list domains that use the config, default 0 (false)
* @param array $sql_search
* optional array with index = fieldname, and value = array with 'op' => operator (one of <, > or =), LIKE is used if left empty and 'value' => searchvalue
* @param int $sql_limit
* optional specify number of results to be returned
* @param int $sql_offset
* optional specify offset for resultset
* @param array $sql_orderby
* optional array with index = fieldname and value = ASC|DESC to order the resultset by one or more fields
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
@@ -38,16 +46,15 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] list php-configs"); $this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] list php-configs");
$with_subdomains = $this->getBoolParam('with_subdomains', true, false); $with_subdomains = $this->getBoolParam('with_subdomains', true, false);
$query_fields = array();
$result = Database::query(" $result_stmt = Database::prepare("
SELECT c.*, fd.description as fpmdesc SELECT c.*, fd.description as fpmdesc
FROM `" . TABLE_PANEL_PHPCONFIGS . "` c FROM `" . TABLE_PANEL_PHPCONFIGS . "` c
LEFT JOIN `" . TABLE_PANEL_FPMDAEMONS . "` fd ON fd.id = c.fpmsettingid LEFT JOIN `" . TABLE_PANEL_FPMDAEMONS . "` fd ON fd.id = c.fpmsettingid" . $this->getSearchWhere($query_fields) . $this->getOrderBy() . $this->getLimit()
ORDER BY c.description ASC );
"); Database::pexecute($result_stmt, $query_fields, true, true);
$phpconfigs = array(); $phpconfigs = array();
while ($row = $result->fetch(\PDO::FETCH_ASSOC)) { while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
$query_params = array( $query_params = array(
'id' => $row['id'] 'id' => $row['id']
); );
@@ -115,6 +122,28 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);
} }
/**
* returns the total number of accessable php-setting entries
*
* @access admin
* @throws \Exception
* @return string json-encoded array
*/
public function listingCount()
{
if ($this->isAdmin()) {
$result_stmt = Database::prepare("
SELECT COUNT(*) as num_phps
FROM `" . TABLE_PANEL_PHPCONFIGS . "` c
");
$result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) {
return $this->response(200, "successfull", $result['num_phps']);
}
}
throw new \Exception("Not allowed to execute given command.", 403);
}
/** /**
* return a php-setting entry by id * return a php-setting entry by id
* *

View File

@@ -270,7 +270,12 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
`http2` = :http2, `http2` = :http2,
`hsts` = :hsts, `hsts` = :hsts,
`hsts_sub` = :hsts_sub, `hsts_sub` = :hsts_sub,
`hsts_preload` = :hsts_preload `hsts_preload` = :hsts_preload,
`ocsp_stapling` = :ocsp_stapling,
`override_tls` = :override_tls,
`ssl_protocols` = :ssl_protocols,
`ssl_cipher_list` = :ssl_cipher_list,
`tlsv13_cipher_list` = :tlsv13_cipher_list
"); ");
$params = array( $params = array(
"customerid" => $customer['customerid'], "customerid" => $customer['customerid'],
@@ -295,7 +300,12 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
"http2" => $http2, "http2" => $http2,
"hsts" => $hsts_maxage, "hsts" => $hsts_maxage,
"hsts_sub" => $hsts_sub, "hsts_sub" => $hsts_sub,
"hsts_preload" => $hsts_preload "hsts_preload" => $hsts_preload,
"ocsp_stapling" => $domain_check['ocsp_stapling'],
"override_tls" => $domain_check['override_tls'],
"ssl_protocols" => $domain_check['ssl_protocols'],
"ssl_cipher_list" => $domain_check['ssl_cipher_list'],
"tlsv13_cipher_list" => $domain_check['tlsv13_cipher_list']
); );
Database::pexecute($stmt, $params, true, true); Database::pexecute($stmt, $params, true, true);
$subdomain_id = Database::lastInsertId(); $subdomain_id = Database::lastInsertId();
@@ -674,6 +684,19 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
/** /**
* lists all subdomain entries * lists all subdomain entries
* *
* @param int $customerid
* optional, admin-only, select (sub)domains of a specific customer by id
* @param string $loginname
* optional, admin-only, select (sub)domains of a specific customer by loginname
* @param array $sql_search
* optional array with index = fieldname, and value = array with 'op' => operator (one of <, > or =), LIKE is used if left empty and 'value' => searchvalue
* @param int $sql_limit
* optional specify number of results to be returned
* @param int $sql_offset
* optional specify offset for resultset
* @param array $sql_orderby
* optional array with index = fieldname and value = ASC|DESC to order the resultset by one or more fields
*
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return string json-encoded array count|list * @return string json-encoded array count|list
@@ -686,6 +709,103 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$customerid = $this->getParam('customerid', true, 0); $customerid = $this->getParam('customerid', true, 0);
$loginname = $this->getParam('loginname', true, ''); $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'];
}
if (empty($customer_ids)) {
throw new \Exception("Required resource unsatisfied.", 405);
}
if (empty($customer_stdsubs)) {
throw new \Exception("Required resource unsatisfied.", 405);
}
$select_fields = [
'`d`.*'
];
} 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')
);
$select_fields = [
'`d`.`id`',
'`d`.`customerid`',
'`d`.`domain`',
'`d`.`documentroot`',
'`d`.`isbinddomain`',
'`d`.`isemaildomain`',
'`d`.`caneditdomain`',
'`d`.`iswildcarddomain`',
'`d`.`parentdomainid`',
'`d`.`letsencrypt`',
'`d`.`registration_date`',
'`d`.`termination_date`'
];
}
$query_fields = array();
// prepare select statement
$domains_stmt = Database::prepare("
SELECT " . implode(",", $select_fields) . ", `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` IN (" . implode(', ', $customer_ids) . ")
AND `d`.`email_only` = '0'
AND `d`.`id` NOT IN (" . implode(', ', $customer_stdsubs) . ")" . $this->getSearchWhere($query_fields, true) . $this->getOrderBy() . $this->getLimit());
$result = array();
Database::pexecute($domains_stmt, $query_fields, true, true);
while ($row = $domains_stmt->fetch(\PDO::FETCH_ASSOC)) {
$result[] = $row;
}
return $this->response(200, "successfull", array(
'count' => count($result),
'list' => $result
));
}
/**
* returns the total number of accessable subdomain entries
*
* @param int $customerid
* optional, admin-only, select (sub)domains of a specific customer by id
* @param string $loginname
* optional, admin-only, select (sub)domains of a specific customer by loginname
*
* @access admin, customer
* @throws \Exception
* @return string json-encoded array
*/
public function listingCount()
{
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)) { if (! empty($customerid) || ! empty($loginname)) {
$result = $this->apiCall('Customers.get', array( $result = $this->apiCall('Customers.get', array(
'id' => $customerid, 'id' => $customerid,
@@ -715,33 +835,21 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$this->getUserDetail('customerid') => $this->getUserDetail('standardsubdomain') $this->getUserDetail('customerid') => $this->getUserDetail('standardsubdomain')
); );
} }
// prepare select statement // prepare select statement
$domains_stmt = Database::prepare(" $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` SELECT COUNT(*) as num_subdom
FROM `" . TABLE_PANEL_DOMAINS . "` `d` FROM `" . TABLE_PANEL_DOMAINS . "` `d`
LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` `ad` ON `d`.`aliasdomain`=`ad`.`id` LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` `ad` ON `d`.`aliasdomain`=`ad`.`id`
LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` `da` ON `da`.`aliasdomain`=`d`.`id` LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` `da` ON `da`.`aliasdomain`=`d`.`id`
WHERE `d`.`customerid`= :customerid WHERE `d`.`customerid` IN (" . implode(', ', $customer_ids) . ")
AND `d`.`email_only`='0' AND `d`.`email_only` = '0'
AND `d`.`id` <> :standardsubdomain AND `d`.`id` NOT IN (" . implode(', ', $customer_stdsubs) . ")
"); ");
$result = Database::pexecute_first($domains_stmt, null, true, true);
$result = array(); if ($result) {
foreach ($customer_ids as $customer_id) { return $this->response(200, "successfull", $result['num_subdom']);
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 * delete a subdomain by either id or domainname

View File

@@ -0,0 +1,212 @@
<?php
namespace Froxlor\Api\Commands;
use Froxlor\Database\Database;
/**
* 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.6
*
*/
class SysLog extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntity
{
/**
* list all log-entries
*
* @param array $sql_search
* optional array with index = fieldname, and value = array with 'op' => operator (one of <, > or =), LIKE is used if left empty and 'value' => searchvalue
* @param int $sql_limit
* optional specify number of results to be returned
* @param int $sql_offset
* optional specify offset for resultset
* @param array $sql_orderby
* optional array with index = fieldname and value = ASC|DESC to order the resultset by one or more fields
*
* @access admin, customer
* @throws \Exception
* @return string json-encoded array count|list
*/
public function listing()
{
$result = array();
$query_fields = array();
if ($this->isAdmin() && $this->getUserDetail('customers_see_all') == '1') {
$result_stmt = Database::prepare("
SELECT * FROM `" . TABLE_PANEL_LOG . "` " . $this->getSearchWhere($query_fields) . $this->getOrderBy() . $this->getLimit());
} elseif ($this->isAdmin()) {
// get all admin customers
$_custom_list_result = $this->apiCall('Customers.listing');
$custom_list_result = $_custom_list_result['list'];
$customer_names = array();
foreach ($custom_list_result as $customer) {
$customer_names[] = $customer['loginname'];
}
if (count($customer_names) > 0) {
$result_stmt = Database::prepare("
SELECT * FROM `" . TABLE_PANEL_LOG . "`
WHERE `user` = :loginname OR `user` IN (" . implode(', ', $customer_names) . ")" . $this->getSearchWhere($query_fields, true) . $this->getOrderBy() . $this->getLimit());
} else {
$result_stmt = Database::prepare("
SELECT * FROM `" . TABLE_PANEL_LOG . "`
WHERE `user` = :loginname" . $this->getSearchWhere($query_fields, true) . $this->getOrderBy() . $this->getLimit());
}
$query_fields['loginname'] = $this->getUserDetail('loginname');
} else {
// every one else just sees their logs
$result_stmt = Database::prepare("
SELECT * FROM `" . TABLE_PANEL_LOG . "`
WHERE `user` = :loginname AND `action` <> 99 " . $this->getSearchWhere($query_fields, true) . $this->getOrderBy() . $this->getLimit());
$query_fields['loginname'] = $this->getUserDetail('loginname');
}
Database::pexecute($result_stmt, $query_fields, true, true);
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
$result[] = $row;
}
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] list log-entries");
return $this->response(200, "successfull", array(
'count' => count($result),
'list' => $result
));
}
/**
* returns the total number of log-entries
*
* @access admin
* @throws \Exception
* @return string json-encoded array
*/
public function listingCount()
{
$params = null;
if ($this->isAdmin() && $this->getUserDetail('customers_see_all') == '1') {
$result_stmt = Database::prepare("
SELECT COUNT(*) as num_logs FROM `" . TABLE_PANEL_LOG . "`
");
} elseif ($this->isAdmin()) {
// get all admin customers
$_custom_list_result = $this->apiCall('Customers.listing');
$custom_list_result = $_custom_list_result['list'];
$customer_names = array();
foreach ($custom_list_result as $customer) {
$customer_names[] = $customer['loginname'];
}
if (count($customer_names) > 0) {
$result_stmt = Database::prepare("
SELECT COUNT(*) as num_logs FROM `" . TABLE_PANEL_LOG . "`
WHERE `user` = :loginname OR `user` IN (" . implode(', ', $customer_names) . ")
");
} else {
$result_stmt = Database::prepare("
SELECT COUNT(*) as num_logs FROM `" . TABLE_PANEL_LOG . "`
WHERE `user` = :loginname
");
}
$params = [
'loginname' => $this->getUserDetail('loginname')
];
} else {
// every one else just sees their logs
$result_stmt = Database::prepare("
SELECT COUNT(*) as num_logs FROM `" . TABLE_PANEL_LOG . "`
WHERE `user` = :loginname AND `action` <> 99
");
$params = [
'loginname' => $this->getUserDetail('loginname')
];
}
$result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) {
return $this->response(200, "successfull", $result['num_logs']);
}
}
/**
* You cannot get log entries
*/
public function get()
{
throw new \Exception('You cannot get log entries', 303);
}
/**
* You cannot add log entries
*/
public function add()
{
throw new \Exception('You cannot add log entries', 303);
}
/**
* You cannot update log entries
*/
public function update()
{
throw new \Exception('You cannot update log entries', 303);
}
/**
* delete log entries
*
* @param int $min_to_keep
* optional minutes to keep, default is 10
*
* @access admin
* @throws \Exception
* @return string json-encoded array
*/
public function delete()
{
if ($this->isAdmin()) {
$min_to_keep = self::getParam('min_to_keep', true, 10);
if ($min_to_keep < 0) {
$min_to_keep = 0;
}
$truncatedate = time() - (60 * $min_to_keep);
$params = array();
if ($this->getUserDetail('customers_see_all') == '1') {
$result_stmt = Database::prepare("
DELETE FROM `" . TABLE_PANEL_LOG . "` WHERE `date` < :trunc
");
} else {
// get all admin customers
$_custom_list_result = $this->apiCall('Customers.listing');
$custom_list_result = $_custom_list_result['list'];
$customer_names = array();
foreach ($custom_list_result as $customer) {
$customer_names[] = $customer['loginname'];
}
if (count($customer_names) > 0) {
$result_stmt = Database::prepare("
DELETE FROM `" . TABLE_PANEL_LOG . "` WHERE `date` < :trunc AND `user` = :loginname OR `user` IN (" . implode(', ', $customer_names) . ")
");
} else {
$result_stmt = Database::prepare("
SELECT COUNT(*) as num_logs FROM `" . TABLE_PANEL_LOG . "`
DELETE FROM `" . TABLE_PANEL_LOG . "` WHERE `date` < :trunc AND `user` = :loginname
");
}
$params = [
'loginname' => $this->getUserDetail('loginname')
];
}
$params['trunc'] = $truncatedate;
Database::execute($result_stmt, $params, true, true);
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_WARNING, "[API] truncated the froxlor syslog");
return $this->response(200, "successfull", true);
}
throw new \Exception("Not allowed to execute given command.", 403);
}
}

View File

@@ -116,6 +116,16 @@ class Traffic extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
)); ));
} }
/**
* You cannot count the traffic data list
*
* @throws \Exception
*/
public function listingCount()
{
throw new \Exception('You cannot count the traffic data list', 303);
}
/** /**
* You cannot delete traffic data * You cannot delete traffic data
* *

View File

@@ -21,6 +21,8 @@ interface ResourceEntity
public function listing(); public function listing();
public function listingCount();
public function get(); public function get();
public function add(); public function add();

0
lib/Froxlor/Cli/ConfigServicesCmd.php Executable file → Normal file
View File

0
lib/Froxlor/Cli/SwitchServerIpCmd.php Executable file → Normal file
View File

View File

@@ -435,11 +435,7 @@ class ConfigDaemon
} }
return ''; return '';
} elseif (preg_match('/^const\.(.*)$/', $matches[1], $match)) { } elseif (preg_match('/^const\.(.*)$/', $matches[1], $match)) {
if (defined($match[1])) { return $this->returnDynamic($match[1]);
return constant($match[1]);
} else {
return '';
}
} elseif (preg_match('/^sql\.(.*)$/', $matches[1], $match)) { } elseif (preg_match('/^sql\.(.*)$/', $matches[1], $match)) {
if (is_null($this->sqldata_cache)) { if (is_null($this->sqldata_cache)) {
// read in sql-data (if exists) // read in sql-data (if exists)
@@ -455,6 +451,14 @@ class ConfigDaemon
return $content; return $content;
} }
private function returnDynamic($key = null)
{
$dynamics = [
'install_dir' => \Froxlor\Froxlor::getInstallDir()
];
return $dynamics[$key] ?? '';
}
/** /**
* Check if visibility should be changed * Check if visibility should be changed
* *

View File

@@ -178,7 +178,7 @@ class Apache extends HttpConfigBase
$this->virtualhosts_data[$vhosts_filename] .= ' ServerName ' . Settings::Get('system.hostname') . "\n"; $this->virtualhosts_data[$vhosts_filename] .= ' ServerName ' . Settings::Get('system.hostname') . "\n";
$froxlor_aliases = Settings::Get('system.froxloraliases'); $froxlor_aliases = Settings::Get('system.froxloraliases');
if (!empty($froxlor_aliases)) { if (! empty($froxlor_aliases)) {
$froxlor_aliases = explode(",", $froxlor_aliases); $froxlor_aliases = explode(",", $froxlor_aliases);
$aliases = ""; $aliases = "";
foreach ($froxlor_aliases as $falias) { foreach ($froxlor_aliases as $falias) {
@@ -187,7 +187,7 @@ class Apache extends HttpConfigBase
} }
} }
$aliases = trim($aliases); $aliases = trim($aliases);
if (!empty($aliases)) { if (! empty($aliases)) {
$this->virtualhosts_data[$vhosts_filename] .= ' ServerAlias ' . $aliases . "\n"; $this->virtualhosts_data[$vhosts_filename] .= ' ServerAlias ' . $aliases . "\n";
} }
} }
@@ -483,7 +483,7 @@ class Apache extends HttpConfigBase
$this->virtualhosts_data[$vhosts_filename] .= ' SSLHonorCipherOrder On' . "\n"; $this->virtualhosts_data[$vhosts_filename] .= ' SSLHonorCipherOrder On' . "\n";
$this->virtualhosts_data[$vhosts_filename] .= ' SSLCipherSuite ' . Settings::Get('system.ssl_cipher_list') . "\n"; $this->virtualhosts_data[$vhosts_filename] .= ' SSLCipherSuite ' . Settings::Get('system.ssl_cipher_list') . "\n";
$protocols = array_map('trim', explode(",", Settings::Get('system.ssl_protocols'))); $protocols = array_map('trim', explode(",", Settings::Get('system.ssl_protocols')));
if (in_array("TLSv1.3", $protocols) && !empty(Settings::Get('system.tlsv13_cipher_list')) && Settings::Get('system.apache24') == 1) { if (in_array("TLSv1.3", $protocols) && ! empty(Settings::Get('system.tlsv13_cipher_list')) && Settings::Get('system.apache24') == 1) {
$this->virtualhosts_data[$vhosts_filename] .= ' SSLCipherSuite TLSv1.3 ' . Settings::Get('system.tlsv13_cipher_list') . "\n"; $this->virtualhosts_data[$vhosts_filename] .= ' SSLCipherSuite TLSv1.3 ' . Settings::Get('system.tlsv13_cipher_list') . "\n";
} }
$this->virtualhosts_data[$vhosts_filename] .= ' SSLVerifyDepth 10' . "\n"; $this->virtualhosts_data[$vhosts_filename] .= ' SSLVerifyDepth 10' . "\n";
@@ -967,8 +967,13 @@ class Apache extends HttpConfigBase
} }
if ($domain['ssl_cert_file'] != '') { if ($domain['ssl_cert_file'] != '') {
$ssl_protocols = ($domain['override_tls'] == '1' && ! empty($domain['ssl_protocols'])) ? $domain['ssl_protocols'] : Settings::Get('system.ssl_protocols');
$ssl_cipher_list = ($domain['override_tls'] == '1' && ! empty($domain['ssl_cipher_list'])) ? $domain['ssl_cipher_list'] : Settings::Get('system.ssl_cipher_list');
$tlsv13_cipher_list = ($domain['override_tls'] == '1' && ! empty($domain['tlsv13_cipher_list'])) ? $domain['tlsv13_cipher_list'] : Settings::Get('system.tlsv13_cipher_list');
$vhost_content .= ' SSLEngine On' . "\n"; $vhost_content .= ' SSLEngine On' . "\n";
$vhost_content .= ' SSLProtocol -ALL +' . str_replace(",", " +", Settings::Get('system.ssl_protocols')) . "\n"; $vhost_content .= ' SSLProtocol -ALL +' . str_replace(",", " +", $ssl_protocols) . "\n";
if (Settings::Get('system.apache24') == '1') { if (Settings::Get('system.apache24') == '1') {
if (isset($domain['http2']) && $domain['http2'] == '1' && Settings::Get('system.http2_support') == '1') { if (isset($domain['http2']) && $domain['http2'] == '1' && Settings::Get('system.http2_support') == '1') {
$vhost_content .= ' Protocols h2 http/1.1' . "\n"; $vhost_content .= ' Protocols h2 http/1.1' . "\n";
@@ -984,10 +989,10 @@ class Apache extends HttpConfigBase
} }
// this makes it more secure, thx to Marcel (08/2013) // this makes it more secure, thx to Marcel (08/2013)
$vhost_content .= ' SSLHonorCipherOrder On' . "\n"; $vhost_content .= ' SSLHonorCipherOrder On' . "\n";
$vhost_content .= ' SSLCipherSuite ' . Settings::Get('system.ssl_cipher_list') . "\n"; $vhost_content .= ' SSLCipherSuite ' . $ssl_cipher_list . "\n";
$protocols = array_map('trim', explode(",", Settings::Get('system.ssl_protocols'))); $protocols = array_map('trim', explode(",", $ssl_protocols));
if (in_array("TLSv1.3", $protocols) && !empty(Settings::Get('system.tlsv13_cipher_list')) && Settings::Get('system.apache24') == 1) { if (in_array("TLSv1.3", $protocols) && ! empty($tlsv13_cipher_list) && Settings::Get('system.apache24') == 1) {
$vhost_content .= ' SSLCipherSuite TLSv1.3 ' . Settings::Get('system.tlsv13_cipher_list') . "\n"; $vhost_content .= ' SSLCipherSuite TLSv1.3 ' . $tlsv13_cipher_list . "\n";
} }
$vhost_content .= ' SSLVerifyDepth 10' . "\n"; $vhost_content .= ' SSLVerifyDepth 10' . "\n";
$vhost_content .= ' SSLCertificateFile ' . \Froxlor\FileDir::makeCorrectFile($domain['ssl_cert_file']) . "\n"; $vhost_content .= ' SSLCertificateFile ' . \Froxlor\FileDir::makeCorrectFile($domain['ssl_cert_file']) . "\n";

View File

@@ -45,19 +45,8 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
public static $no_inserttask = false; public static $no_inserttask = false;
public static function run($internal = false) private static function needRenew()
{ {
if (! defined('CRON_IS_FORCED') && ! defined('CRON_DEBUG_FLAG') && $internal == false) {
// FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_WARNING, "Let's Encrypt cronjob is combined with regeneration of webserver configuration files.\nFor debugging purposes you can use the --debug switch and/or the --force switch to run the cron manually.");
return 0;
}
self::checkInstall();
self::$apiserver = 'https://acme-v0' . \Froxlor\Settings::Get('system.leapiversion') . '.api.letsencrypt.org/directory';
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Requesting/renewing Let's Encrypt certificates");
$certificates_stmt = Database::query(" $certificates_stmt = Database::query("
SELECT SELECT
domssl.`id`, domssl.`id`,
@@ -94,6 +83,52 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
OR domssl.`expirationdate` IS NULL OR domssl.`expirationdate` IS NULL
) )
"); ");
$customer_ssl = $certificates_stmt->fetchAll(\PDO::FETCH_ASSOC);
if (!$customer_ssl) {
$customer_ssl = array();
}
$froxlor_ssl = array();
if (Settings::Get('system.le_froxlor_enabled') == '1') {
$froxlor_ssl_settings_stmt = Database::prepare("
SELECT * FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "`
WHERE `domainid` = '0' AND
(`expirationdate` < DATE_ADD(NOW(), INTERVAL 30 DAY) OR `expirationdate` IS NULL)
");
$froxlor_ssl = Database::pexecute_first($froxlor_ssl_settings_stmt);
if (!$froxlor_ssl) {
$froxlor_ssl = array();
}
}
if (count($customer_ssl) > 0 || count($froxlor_ssl) > 0) {
return array(
'customer_ssl' => $customer_ssl,
'froxlor_ssl' => $froxlor_ssl
);
}
return false;
}
public static function run($internal = false)
{
if (! defined('CRON_IS_FORCED') && ! defined('CRON_DEBUG_FLAG') && $internal == false) {
// Let's Encrypt cronjob is combined with regeneration of webserver configuration files.
// For debugging purposes you can use the --debug switch and the --force switch to run the cron manually.
// check whether we MIGHT need to run although there is no task to regenerate config-files
$needRenew = self::needRenew();
if ($needRenew) {
// insert task to generate certificates and vhost-configs
\Froxlor\System\Cronjob::inserttask(1);
}
return 0;
}
self::checkInstall();
self::$apiserver = 'https://acme-v0' . \Froxlor\Settings::Get('system.leapiversion') . '.api.letsencrypt.org/directory';
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Requesting/renewing Let's Encrypt certificates");
$aliasdomains_stmt = Database::prepare(" $aliasdomains_stmt = Database::prepare("
SELECT SELECT
@@ -127,6 +162,8 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
// flag for re-generation of vhost files // flag for re-generation of vhost files
$changedetected = 0; $changedetected = 0;
$needRenew = self::needRenew();
// first - generate LE for system-vhost if enabled // first - generate LE for system-vhost if enabled
if (Settings::Get('system.le_froxlor_enabled') == '1') { if (Settings::Get('system.le_froxlor_enabled') == '1') {
@@ -147,15 +184,10 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
'id' => null 'id' => null
); );
$froxlor_ssl_settings_stmt = Database::prepare(" $froxlor_ssl = $needRenew ? $needRenew['froxlor_ssl'] : array();
SELECT * FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "`
WHERE `domainid` = '0' AND
(`expirationdate` < DATE_ADD(NOW(), INTERVAL 30 DAY) OR `expirationdate` IS NULL)
");
$froxlor_ssl = Database::pexecute_first($froxlor_ssl_settings_stmt);
$cert_mode = 'issue'; $cert_mode = 'issue';
if ($froxlor_ssl) { if (count($froxlor_ssl) > 0) {
$cert_mode = 'renew'; $cert_mode = 'renew';
$certrow['id'] = $froxlor_ssl['id']; $certrow['id'] = $froxlor_ssl['id'];
$certrow['expirationdate'] = $froxlor_ssl['expirationdate']; $certrow['expirationdate'] = $froxlor_ssl['expirationdate'];
@@ -177,7 +209,7 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
if ($cert_mode) { if ($cert_mode) {
$domains = array( $domains = array(
$certrow['domain'] strtolower($certrow['domain'])
); );
$froxlor_aliases = Settings::Get('system.froxloraliases'); $froxlor_aliases = Settings::Get('system.froxloraliases');
@@ -185,7 +217,7 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
$froxlor_aliases = explode(",", $froxlor_aliases); $froxlor_aliases = explode(",", $froxlor_aliases);
foreach ($froxlor_aliases as $falias) { foreach ($froxlor_aliases as $falias) {
if (\Froxlor\Validate\Validate::validateDomain(trim($falias))) { if (\Froxlor\Validate\Validate::validateDomain(trim($falias))) {
$domains[] = trim($falias); $domains[] = strtolower(trim($falias));
} }
} }
} }
@@ -210,10 +242,12 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
} }
// customer domains // customer domains
$certrows = $certificates_stmt->fetchAll(\PDO::FETCH_ASSOC); $certrows = $needRenew ? $needRenew['customer_ssl'] : array();
$cert_mode = 'issue';
foreach ($certrows as $certrow) { foreach ($certrows as $certrow) {
// initialize mode to 'issue'
$cert_mode = 'issue';
// set logger to corresponding loginname for the log to appear in the users system-log // set logger to corresponding loginname for the log to appear in the users system-log
$cronlog = FroxlorLogger::getInstanceOf(array( $cronlog = FroxlorLogger::getInstanceOf(array(
'loginname' => $certrow['loginname'], 'loginname' => $certrow['loginname'],
@@ -237,12 +271,12 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Adding SAN entry: " . $certrow['domain']); $cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Adding SAN entry: " . $certrow['domain']);
$domains = array( $domains = array(
$certrow['domain'] strtolower($certrow['domain'])
); );
// add www.<domain> to SAN list // add www.<domain> to SAN list
if ($certrow['wwwserveralias'] == 1) { if ($certrow['wwwserveralias'] == 1) {
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Adding SAN entry: www." . $certrow['domain']); $cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Adding SAN entry: www." . $certrow['domain']);
$domains[] = 'www.' . $certrow['domain']; $domains[] = strtolower('www.' . $certrow['domain']);
} }
// add alias domains (and possibly www.<aliasdomain>) to SAN list // add alias domains (and possibly www.<aliasdomain>) to SAN list
@@ -252,10 +286,10 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
$aliasdomains = $aliasdomains_stmt->fetchAll(\PDO::FETCH_ASSOC); $aliasdomains = $aliasdomains_stmt->fetchAll(\PDO::FETCH_ASSOC);
foreach ($aliasdomains as $aliasdomain) { foreach ($aliasdomains as $aliasdomain) {
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Adding SAN entry: " . $aliasdomain['domain']); $cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Adding SAN entry: " . $aliasdomain['domain']);
$domains[] = $aliasdomain['domain']; $domains[] = strtolower($aliasdomain['domain']);
if ($aliasdomain['wwwserveralias'] == 1) { if ($aliasdomain['wwwserveralias'] == 1) {
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Adding SAN entry: www." . $aliasdomain['domain']); $cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Adding SAN entry: www." . $aliasdomain['domain']);
$domains[] = 'www.' . $aliasdomain['domain']; $domains[] = strtolower('www.' . $aliasdomain['domain']);
} }
} }
@@ -390,6 +424,6 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
$acmesh_result = \Froxlor\FileDir::safe_exec(self::$acmesh . " --upgrade"); $acmesh_result = \Froxlor\FileDir::safe_exec(self::$acmesh . " --upgrade");
// check for activated cron (which is installed automatically) but we don't need it // check for activated cron (which is installed automatically) but we don't need it
$acmesh_result2 = \Froxlor\FileDir::safe_exec(self::$acmesh . " --uninstall-cronjob"); $acmesh_result2 = \Froxlor\FileDir::safe_exec(self::$acmesh . " --uninstall-cronjob");
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Checking for LetsEncrypt client upgrades before renewing certificates:\n" . implode("\n", $acmesh_result)."\n".implode("\n", $acmesh_result2)); FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Checking for LetsEncrypt client upgrades before renewing certificates:\n" . implode("\n", $acmesh_result) . "\n" . implode("\n", $acmesh_result2));
} }
} }

View File

@@ -570,6 +570,8 @@ class Lighttpd extends HttpConfigBase
if ($domain['ssl_cert_file'] != '') { if ($domain['ssl_cert_file'] != '') {
$ssl_cipher_list = ($domain['override_tls'] == '1' && ! empty($domain['ssl_cipher_list'])) ? $domain['ssl_cipher_list'] : Settings::Get('system.ssl_cipher_list');
// ssl.engine only necessary once in the ip/port vhost (SERVER['socket'] condition) // ssl.engine only necessary once in the ip/port vhost (SERVER['socket'] condition)
// $ssl_settings .= 'ssl.engine = "enable"' . "\n"; // $ssl_settings .= 'ssl.engine = "enable"' . "\n";
$ssl_settings .= 'ssl.use-compression = "disable"' . "\n"; $ssl_settings .= 'ssl.use-compression = "disable"' . "\n";
@@ -583,7 +585,7 @@ class Lighttpd extends HttpConfigBase
} }
$ssl_settings .= 'ssl.use-sslv2 = "disable"' . "\n"; $ssl_settings .= 'ssl.use-sslv2 = "disable"' . "\n";
$ssl_settings .= 'ssl.use-sslv3 = "disable"' . "\n"; $ssl_settings .= 'ssl.use-sslv3 = "disable"' . "\n";
$ssl_settings .= 'ssl.cipher-list = "' . Settings::Get('system.ssl_cipher_list') . '"' . "\n"; $ssl_settings .= 'ssl.cipher-list = "' . $ssl_cipher_list . '"' . "\n";
$ssl_settings .= 'ssl.honor-cipher-order = "enable"' . "\n"; $ssl_settings .= 'ssl.honor-cipher-order = "enable"' . "\n";
$ssl_settings .= 'ssl.pemfile = "' . \Froxlor\FileDir::makeCorrectFile($domain['ssl_cert_file']) . '"' . "\n"; $ssl_settings .= 'ssl.pemfile = "' . \Froxlor\FileDir::makeCorrectFile($domain['ssl_cert_file']) . '"' . "\n";

View File

@@ -285,7 +285,7 @@ class Nginx extends HttpConfigBase
if (! $is_redirect) { if (! $is_redirect) {
$this->nginx_data[$vhost_filename] .= "\tlocation ~ \.php {\n"; $this->nginx_data[$vhost_filename] .= "\tlocation ~ \.php {\n";
$this->nginx_data[$vhost_filename] .= "\t\tfastcgi_split_path_info ^(.+\.php)(/.+)\$;\n"; $this->nginx_data[$vhost_filename] .= "\t\tfastcgi_split_path_info ^(.+?\.php)(/.*)$;\n";
$this->nginx_data[$vhost_filename] .= "\t\tinclude " . Settings::Get('nginx.fastcgiparams') . ";\n"; $this->nginx_data[$vhost_filename] .= "\t\tinclude " . Settings::Get('nginx.fastcgiparams') . ";\n";
$this->nginx_data[$vhost_filename] .= "\t\tfastcgi_param SCRIPT_FILENAME \$request_filename;\n"; $this->nginx_data[$vhost_filename] .= "\t\tfastcgi_param SCRIPT_FILENAME \$request_filename;\n";
$this->nginx_data[$vhost_filename] .= "\t\tfastcgi_param PATH_INFO \$fastcgi_path_info;\n"; $this->nginx_data[$vhost_filename] .= "\t\tfastcgi_param PATH_INFO \$fastcgi_path_info;\n";
@@ -678,10 +678,14 @@ class Nginx extends HttpConfigBase
if (! file_exists($domain_or_ip['ssl_cert_file'])) { if (! file_exists($domain_or_ip['ssl_cert_file'])) {
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_ERR, $domain_or_ip['domain'] . ' :: certificate file "' . $domain_or_ip['ssl_cert_file'] . '" does not exist! Cannot create ssl-directives'); \Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_ERR, $domain_or_ip['domain'] . ' :: certificate file "' . $domain_or_ip['ssl_cert_file'] . '" does not exist! Cannot create ssl-directives');
} else { } else {
$ssl_protocols = (isset($domain_or_ip['override_tls']) && $domain_or_ip['override_tls'] == '1' && ! empty($domain_or_ip['ssl_protocols'])) ? $domain_or_ip['ssl_protocols'] : Settings::Get('system.ssl_protocols');
$ssl_cipher_list = (isset($domain_or_ip['override_tls']) && $domain_or_ip['override_tls'] == '1' && ! empty($domain_or_ip['ssl_cipher_list'])) ? $domain_or_ip['ssl_cipher_list'] : Settings::Get('system.ssl_cipher_list');
// obsolete: ssl on now belongs to the listen block as 'ssl' at the end // obsolete: ssl on now belongs to the listen block as 'ssl' at the end
// $sslsettings .= "\t" . 'ssl on;' . "\n"; // $sslsettings .= "\t" . 'ssl on;' . "\n";
$sslsettings .= "\t" . 'ssl_protocols ' . str_replace(",", " ", Settings::Get('system.ssl_protocols')) . ';' . "\n"; $sslsettings .= "\t" . 'ssl_protocols ' . str_replace(",", " ", $ssl_protocols) . ';' . "\n";
$sslsettings .= "\t" . 'ssl_ciphers ' . Settings::Get('system.ssl_cipher_list') . ';' . "\n"; $sslsettings .= "\t" . 'ssl_ciphers ' . $ssl_cipher_list . ';' . "\n";
if (! empty(Settings::Get('system.dhparams_file'))) { if (! empty(Settings::Get('system.dhparams_file'))) {
$dhparams = \Froxlor\FileDir::makeCorrectFile(Settings::Get('system.dhparams_file')); $dhparams = \Froxlor\FileDir::makeCorrectFile(Settings::Get('system.dhparams_file'));
if (! file_exists($dhparams)) { if (! file_exists($dhparams)) {
@@ -951,7 +955,7 @@ class Nginx extends HttpConfigBase
$phpopts .= "\t" . '}' . "\n\n"; $phpopts .= "\t" . '}' . "\n\n";
$phpopts .= "\tlocation @php {\n"; $phpopts .= "\tlocation @php {\n";
$phpopts .= "\t\tfastcgi_split_path_info ^(.+\.php)(/.+)\$;\n"; $phpopts .= "\t\tfastcgi_split_path_info ^(.+?\.php)(/.*)$;\n";
$phpopts .= "\t\tinclude " . Settings::Get('nginx.fastcgiparams') . ";\n"; $phpopts .= "\t\tinclude " . Settings::Get('nginx.fastcgiparams') . ";\n";
$phpopts .= "\t\tfastcgi_param SCRIPT_FILENAME \$request_filename;\n"; $phpopts .= "\t\tfastcgi_param SCRIPT_FILENAME \$request_filename;\n";
$phpopts .= "\t\tfastcgi_param PATH_INFO \$fastcgi_path_info;\n"; $phpopts .= "\t\tfastcgi_param PATH_INFO \$fastcgi_path_info;\n";

View File

@@ -37,7 +37,7 @@ class NginxFcgi extends Nginx
$php_options_text .= "\t" . 'location @php {' . "\n"; $php_options_text .= "\t" . 'location @php {' . "\n";
$php_options_text .= "\t\t" . 'try_files $1 =404;' . "\n\n"; $php_options_text .= "\t\t" . 'try_files $1 =404;' . "\n\n";
$php_options_text .= "\t\t" . 'include ' . Settings::Get('nginx.fastcgiparams') . ";\n"; $php_options_text .= "\t\t" . 'include ' . Settings::Get('nginx.fastcgiparams') . ";\n";
$php_options_text .= "\t\t" . 'fastcgi_split_path_info ^(.+\.php)(/.+)\$;' . "\n"; $php_options_text .= "\t\t" . 'fastcgi_split_path_info ^(.+?\.php)(/.*)$;' . "\n";
$php_options_text .= "\t\t" . 'fastcgi_param SCRIPT_FILENAME $request_filename;' . "\n"; $php_options_text .= "\t\t" . 'fastcgi_param SCRIPT_FILENAME $request_filename;' . "\n";
$php_options_text .= "\t\t" . 'fastcgi_param PATH_INFO $2;' . "\n"; $php_options_text .= "\t\t" . 'fastcgi_param PATH_INFO $2;' . "\n";
if ($domain['ssl'] == '1' && $ssl_vhost) { if ($domain['ssl'] == '1' && $ssl_vhost) {

View File

@@ -36,9 +36,7 @@ class WebserverBase
`d`.`phpsettingid`, `c`.`adminid`, `c`.`guid`, `c`.`email`, `d`.`phpsettingid`, `c`.`adminid`, `c`.`guid`, `c`.`email`,
`c`.`documentroot` AS `customerroot`, `c`.`deactivated`, `c`.`documentroot` AS `customerroot`, `c`.`deactivated`,
`c`.`phpenabled` AS `phpenabled_customer`, `c`.`phpenabled` AS `phpenabled_customer`,
`d`.`phpenabled` AS `phpenabled_vhost`, `d`.`phpenabled` AS `phpenabled_vhost`
`d`.`mod_fcgid_starter`,`d`.`mod_fcgid_maxrequests`,
`d`.`ocsp_stapling`
FROM `" . TABLE_PANEL_DOMAINS . "` `d` FROM `" . TABLE_PANEL_DOMAINS . "` `d`
LEFT JOIN `" . TABLE_PANEL_CUSTOMERS . "` `c` USING(`customerid`) LEFT JOIN `" . TABLE_PANEL_CUSTOMERS . "` `c` USING(`customerid`)

View File

@@ -418,17 +418,18 @@ class TasksCron extends \Froxlor\Cron\FroxlorCron
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) { while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
// We do not want to set a quota for root by accident // We do not want to set a quota for root by accident
if ($row['guid'] != 0) { if ($row['guid'] != 0) {
$used_quota = isset($usedquota[$row['guid']]) ? $usedquota[$row['guid']]['block']['hard'] : 0;
// The user has no quota in Froxlor, but on the filesystem // The user has no quota in Froxlor, but on the filesystem
if (($row['diskspace'] == 0 || $row['diskspace'] == - 1024) && $usedquota[$row['guid']]['block']['hard'] != 0) { if (($row['diskspace'] == 0 || $row['diskspace'] == - 1024) && $used_quota != 0) {
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, "Disabling quota for " . $row['loginname']); \Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, "Disabling quota for " . $row['loginname']);
if (\Froxlor\FileDir::isFreeBSD()) { if (\Froxlor\FileDir::isFreeBSD()) {
\Froxlor\FileDir::safe_exec(Settings::Get('system.diskquota_quotatool_path') . " -e " . escapeshellarg(Settings::Get('system.diskquota_customer_partition')) . ":0:0 " . $row['guid']); \Froxlor\FileDir::safe_exec(Settings::Get('system.diskquota_quotatool_path') . " -e " . escapeshellarg(Settings::Get('system.diskquota_customer_partition')) . ":0:0 " . $row['guid']);
} else { } else {
\Froxlor\FileDir::safe_exec(Settings::Get('system.diskquota_quotatool_path') . " -u " . $row['guid'] . " -bl 0 -q 0 " . escapeshellarg(Settings::Get('system.diskquota_customer_partition'))); \Froxlor\FileDir::safe_exec(Settings::Get('system.diskquota_quotatool_path') . " -u " . $row['guid'] . " -bl 0 -q 0 " . escapeshellarg(Settings::Get('system.diskquota_customer_partition')));
} }
} elseif ($row['diskspace'] != $usedquota[$row['guid']]['block']['hard'] && $row['diskspace'] != - 1024) { } elseif ($row['diskspace'] != $used_quota && $row['diskspace'] != - 1024) {
// The user quota in Froxlor is different than on the filesystem // The user quota in Froxlor is different than on the filesystem
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, "Setting quota for " . $row['loginname'] . " from " . $usedquota[$row['guid']]['block']['hard'] . " to " . $row['diskspace']); \Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, "Setting quota for " . $row['loginname'] . " from " . $used_quota . " to " . $row['diskspace']);
if (\Froxlor\FileDir::isFreeBSD()) { if (\Froxlor\FileDir::isFreeBSD()) {
\Froxlor\FileDir::safe_exec(Settings::Get('system.diskquota_quotatool_path') . " -e " . escapeshellarg(Settings::Get('system.diskquota_customer_partition')) . ":" . $row['diskspace'] . ":" . $row['diskspace'] . " " . $row['guid']); \Froxlor\FileDir::safe_exec(Settings::Get('system.diskquota_quotatool_path') . " -e " . escapeshellarg(Settings::Get('system.diskquota_customer_partition')) . ":" . $row['diskspace'] . ":" . $row['diskspace'] . " " . $row['guid']);
} else { } else {

View File

@@ -7,10 +7,10 @@ final class Froxlor
{ {
// Main version variable // Main version variable
const VERSION = '0.10.2'; const VERSION = '0.10.6';
// Database version (YYYYMMDDC where C is a daily counter) // Database version (YYYYMMDDC where C is a daily counter)
const DBVERSION = '201910120'; const DBVERSION = '201911130';
// Distribution branding-tag (used for Debian etc.) // Distribution branding-tag (used for Debian etc.)
const BRANDING = ''; const BRANDING = '';

View File

@@ -87,6 +87,9 @@ class FroxlorLogger
self::$ml->pushHandler(new SyslogHandler('froxlor', LOG_USER, Logger::DEBUG)); self::$ml->pushHandler(new SyslogHandler('froxlor', LOG_USER, Logger::DEBUG));
break; break;
case 'file': case 'file':
if (empty(Settings::Get('logger.logfile')) || ! is_writeable(Settings::Get('logger.logfile'))) {
Settings::Set('logger.logfile', '/tmp/froxlor.log');
}
self::$ml->pushHandler(new StreamHandler(Settings::Get('logger.logfile'), Logger::DEBUG)); self::$ml->pushHandler(new StreamHandler(Settings::Get('logger.logfile'), Logger::DEBUG));
break; break;
case 'mysql': case 'mysql':

View File

@@ -4,6 +4,36 @@ namespace Froxlor;
class PhpHelper class PhpHelper
{ {
private static $sort_key = 'id';
private static $sort_type = SORT_STRING;
/**
* sort an array by either natural or string sort and a given index where the value for comparison is found
*
* @param array $list
* @param string $key
*
* @return boolean
*/
public static function sortListBy(&$list, $key = 'id')
{
self::$sort_type = Settings::Get('panel.natsorting') == 1 ? SORT_NATURAL : SORT_STRING;
self::$sort_key = $key;
return usort($list, array(
'self',
'sortListByGivenKey'
));
}
private static function sortListByGivenKey($a, $b)
{
if (self::$sort_type == SORT_NATURAL) {
return strnatcasecmp($a[self::$sort_key], $b[self::$sort_key]);
}
return strcasecmp($a[self::$sort_key], $b[self::$sort_key]);
}
/** /**
* Wrapper around htmlentities to handle arrays, with the advantage that you * Wrapper around htmlentities to handle arrays, with the advantage that you
* can select which fields should be handled by htmlentities * can select which fields should be handled by htmlentities

View File

@@ -252,6 +252,28 @@ class Store
public static function storeSettingMysqlAccessHost($fieldname, $fielddata, $newfieldvalue) public static function storeSettingMysqlAccessHost($fieldname, $fielddata, $newfieldvalue)
{ {
$ips = $newfieldvalue;
// Convert cidr to netmask for mysql, if needed be
if (strpos($ips, ',') !== false) {
$ips = explode(',', $ips);
}
if (is_array($ips) && count($ips) > 0) {
$newfieldvalue = [];
foreach ($ips as $ip) {
$org_ip = $ip;
$ip_cidr = explode("/", $ip);
if (count($ip_cidr) === 2) {
$ip = $ip_cidr[0];
if (strlen($ip_cidr[1]) <= 2) {
$ip_cidr[1] = \Froxlor\Validate\Validate::cidr2NetmaskAddr($org_ip);
}
$newfieldvalue[] = $ip . '/' . $ip_cidr[1];
} else {
$newfieldvalue[] = $org_ip;
}
}
$newfieldvalue = implode(',', $newfieldvalue);
}
$returnvalue = self::storeSettingField($fieldname, $fielddata, $newfieldvalue); $returnvalue = self::storeSettingField($fieldname, $fielddata, $newfieldvalue);
if ($returnvalue !== false && is_array($fielddata) && isset($fielddata['settinggroup']) && $fielddata['settinggroup'] == 'system' && isset($fielddata['varname']) && $fielddata['varname'] == 'mysql_access_host') { if ($returnvalue !== false && is_array($fielddata) && isset($fielddata['settinggroup']) && $fielddata['settinggroup'] == 'system' && isset($fielddata['varname']) && $fielddata['varname'] == 'mysql_access_host') {

View File

@@ -0,0 +1,313 @@
<?php
namespace Froxlor\UI;
/**
* 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 to manage pagination, limiting and ordering
*/
class Pagination
{
private $data = array();
private $fields = null;
public $sortorder = 'ASC';
public $sortfield = null;
private $searchtext = null;
private $searchfield = null;
private $is_search = false;
private $pageno = 0;
private $entries = 0;
/**
* Create new pagination object to search/filter, limit and sort Api-listing() calls
*
* @param array $userinfo
* @param array $fields
* @param number $total_entries
*/
public function __construct($userinfo, $fields = array(), $total_entries = 0)
{
$this->fields = $fields;
$this->entries = $total_entries;
$this->pageno = 1;
// add default limitation by settings
$this->addLimit(\Froxlor\Settings::Get('panel.paging'));
// check search request
$this->searchtext = '';
if (count($fields) > 0) {
$orderfields = array_keys($fields);
$this->searchfield = $orderfields[0];
}
if (isset($_REQUEST['searchtext']) && (preg_match('/[-_@\p{L}\p{N}*.]+$/u', $_REQUEST['searchtext']) || $_REQUEST['searchtext'] === '')) {
$this->searchtext = trim($_REQUEST['searchtext']);
}
if (isset($_REQUEST['searchfield']) && isset($fields[$_REQUEST['searchfield']])) {
$this->searchfield = $_REQUEST['searchfield'];
}
if (! empty($this->searchtext) && ! empty($this->searchfield)) {
$this->addSearch($this->searchtext, $this->searchfield);
}
// check other ordering requests
if (isset($_REQUEST['sortorder']) && (strtolower($_REQUEST['sortorder']) == 'desc' || strtolower($_REQUEST['sortorder']) == 'asc')) {
$this->sortorder = strtoupper($_REQUEST['sortorder']);
}
if (isset($_REQUEST['sortfield']) && isset($fields[$_REQUEST['sortfield']])) {
$this->sortfield = $_REQUEST['sortfield'];
$this->addOrderBy($this->sortfield, $this->sortorder);
} else {
// add default ordering by given fields
if (count($fields) > 0) {
$orderfields = array_keys($fields);
$this->addOrderBy($orderfields[0]);
}
}
// check current page / pages
if (isset($_REQUEST['pageno']) && intval($_REQUEST['pageno']) != 0) {
$this->pageno = intval($_REQUEST['pageno']);
}
if (($this->pageno - 1) * \Froxlor\Settings::Get('panel.paging') > $this->entries) {
$this->pageno = 1;
}
$this->addOffset(($this->pageno - 1) * \Froxlor\Settings::Get('panel.paging'));
}
/**
* add a field for ordering
*
* @param string $field
* @param string $order
* optional, default 'ASC'
*
* @return \Froxlor\UI\Pagination
*/
public function addOrderBy($field = null, $order = 'ASC')
{
if (! isset($this->data['sql_orderby'])) {
$this->data['sql_orderby'] = array();
}
$this->data['sql_orderby'][$field] = $order;
return $this;
}
/**
* add a limit
*
* @param number $limit
* optional, default 0
*
* @return \Froxlor\UI\Pagination
*/
public function addLimit($limit = 0)
{
$this->data['sql_limit'] = (int) $limit;
return $this;
}
/**
* add an offset
*
* @param number $offset
* optional, default 0
*
* @return \Froxlor\UI\Pagination
*/
public function addOffset($offset = 0)
{
$this->data['sql_offset'] = (int) $offset;
return $this;
}
/**
* add a search operation
*
* @param string $searchtext
* @param string $field
* @param string $operator
*
* @return \Froxlor\UI\Pagination
*/
public function addSearch($searchtext = null, $field = null, $operator = null)
{
if (! isset($this->data['sql_search'])) {
$this->data['sql_search'] = array();
}
$this->data['sql_search'][$field] = [
'value' => $searchtext,
'op' => $operator
];
// if a search is performed, the result-entries-count is irrelevant
// we do not want pagination
$this->is_search = true;
return $this;
}
/**
* return number of total entries the user can access from the current resource
*
* @return number
*/
public function getEntries()
{
return $this->entries;
}
/**
* Returns html code for sorting field
*
* @param array $lng
* Language array
* @return string the html sortcode
*/
public function getHtmlSortCode($lng, $break = false)
{
$sortcode = '';
$fieldoptions = '';
$orderoptions = '';
foreach ($this->fields as $fieldname => $fieldcaption) {
$fieldoptions .= HTML::makeoption($fieldcaption, $fieldname, $this->sortfield, true, true);
}
$breakorws = ($break ? '<br />' : '&nbsp;');
foreach (array(
'asc' => $lng['panel']['ascending'],
'desc' => $lng['panel']['descending']
) as $sortordertype => $sortorderdescription) {
$orderoptions .= HTML::makeoption($sortorderdescription, $sortordertype, $this->sortorder, true, true);
}
eval("\$sortcode =\"" . Template::getTemplate("misc/htmlsortcode", '1') . "\";");
return $sortcode;
}
/**
* Returns html code for sorting arrows
*
* @param string $baseurl
* URL to use as base for links
* @param string $field
* If set, only this field will be returned
*
* @return mixed An array or a string (if field is set) of html code of arrows
*/
public function getHtmlArrowCode($baseurl, $field = '')
{
global $theme;
if ($field != '' && isset($this->fields[$field])) {
$baseurl = htmlspecialchars($baseurl);
$fieldname = htmlspecialchars($field);
eval("\$arrowcode =\"" . Template::getTemplate("misc/htmlarrowcode", '1') . "\";");
} else {
$baseurl = htmlspecialchars($baseurl);
$arrowcode = array();
foreach ($this->fields as $fieldname => $fieldcaption) {
$fieldname = htmlspecialchars($fieldname);
eval("\$arrowcode[\$fieldname] =\"" . Template::getTemplate("misc/htmlarrowcode", '1') . "\";");
}
}
return $arrowcode;
}
/**
* Returns html code for searching field
*
* @param array $lng
* Language array
*
* @return string the html searchcode
*/
public function getHtmlSearchCode($lng)
{
$searchcode = '';
$fieldoptions = '';
$searchtext = htmlspecialchars($this->searchtext);
foreach ($this->fields as $fieldname => $fieldcaption) {
$fieldoptions .= HTML::makeoption($fieldcaption, $fieldname, $this->searchfield, true, true);
}
eval("\$searchcode =\"" . Template::getTemplate("misc/htmlsearchcode", '1') . "\";");
return $searchcode;
}
/**
* Returns html code for paging
*
* @param string $baseurl
* URL to use as base for links
*
* @return string the html pagingcode
*/
public function getHtmlPagingCode($baseurl)
{
if (\Froxlor\Settings::Get('panel.paging') == 0 || $this->is_search) {
return '';
} else {
$pages = intval($this->getEntries() / \Froxlor\Settings::Get('panel.paging'));
}
if ($this->getEntries() % \Froxlor\Settings::Get('panel.paging') != 0) {
$pages ++;
}
if ($pages > 1) {
$start = $this->pageno - 4;
if ($start < 1) {
$start = 1;
}
$stop = $this->pageno + 4;
if ($stop > $pages) {
$stop = $pages;
}
$pagingcode = '<a href="' . htmlspecialchars($baseurl) . '&amp;pageno=1">&laquo;</a> <a href="' . htmlspecialchars($baseurl) . '&amp;pageno=' . ((intval($this->pageno) - 1) == 0 ? '1' : intval($this->pageno) - 1) . '">&lt;</a>&nbsp;';
for ($i = $start; $i <= $stop; $i ++) {
if ($i != $this->pageno) {
$pagingcode .= ' <a href="' . htmlspecialchars($baseurl) . '&amp;pageno=' . $i . '">' . $i . '</a>&nbsp;';
} else {
$pagingcode .= ' <strong>' . $i . '</strong>&nbsp;';
}
}
$pagingcode .= ' <a href="' . htmlspecialchars($baseurl) . '&amp;pageno=' . ((intval($this->pageno) + 1) > $pages ? $pages : intval($this->pageno) + 1) . '">&gt;</a> <a href="' . $baseurl . '&amp;pageno=' . $pages . '">&raquo;</a>';
} else {
$pagingcode = '';
}
return $pagingcode;
}
/**
* return parameter array for API command parameters $sql_search, $sql_limit, $sql_offset and $sql_orderby
*
* @return array
*/
public function getApiCommandParams()
{
return $this->data;
}
}

View File

@@ -1,520 +0,0 @@
<?php
namespace Froxlor\UI;
/**
* This file is part of the Froxlor project.
* Copyright (c) 2003-2009 the SysCP Team (see authors).
* 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 Florian Lippert <flo@syscp.org> (2003-2009)
* @author Froxlor team <team@froxlor.org> (2010-)
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
* @package Classes
*
*/
/**
* Class to manage paging system
*
* @package Functions
*/
class Paging
{
/**
* Userinfo
*
* @var array
*/
private $userinfo = array();
/**
* MySQL-Table
*
* @var string
*/
private $table = '';
/**
* Fields with description which should be selectable
*
* @var array
*/
private $fields = array();
/**
* Entries per page
*
* @var int
*/
private $entriesperpage = 0;
/**
* Number of entries of table
*
* @var int
*/
private $entries = 0;
/**
* Sortorder, asc or desc
*
* @var string
*/
public $sortorder = 'asc';
/**
* Sortfield
*
* @var string
*/
public $sortfield = '';
/**
* Searchfield
*
* @var string
*/
private $searchfield = '';
/**
* Searchtext
*
* @var string
*/
private $searchtext = '';
/**
* Pagenumber
*
* @var int
*/
private $pageno = 0;
/**
* Switch natsorting on/off
*
* @var bool
*/
private $natSorting = false;
private $limit = 0;
/**
* Class constructor.
* Loads settings from request or from userdata and saves them to session.
*
* @param
* array userinfo
* @param
* string Name of Table
* @param
* array Fields, in format array( 'fieldname_in_mysql' => 'field_caption' )
* @param
* int *deprecated* entries per page
* @param
* bool *deprecated* Switch natsorting on/off (global, affects all calls of sort)
* @param int $default_field
* default sorting-field-index
* @param string $default_order
* default sorting order 'asc' or 'desc'
*
*/
public function __construct($userinfo, $table, $fields, $entriesperpage = 0, $natSorting = false, $default_field = 0, $default_order = 'asc', $limit = 0)
{
// entries per page and natsorting-flag are not
// passed as parameter anymore, because these are
// from the settings anyway
$entriesperpage = \Froxlor\Settings::Get('panel.paging');
$natSorting = \Froxlor\Settings::Get('panel.natsorting');
$this->userinfo = $userinfo;
if (! is_array($this->userinfo['lastpaging'])) {
$this->userinfo['lastpaging'] = json_decode($this->userinfo['lastpaging'], true);
}
$this->table = $table;
$this->fields = $fields;
$this->entriesperpage = $entriesperpage;
$this->natSorting = $natSorting;
$checklastpaging = (isset($this->userinfo['lastpaging']['table']) && $this->userinfo['lastpaging']['table'] == $this->table);
$this->userinfo['lastpaging']['table'] = $this->table;
if (isset($_REQUEST['sortorder']) && (strtolower($_REQUEST['sortorder']) == 'desc' || strtolower($_REQUEST['sortorder']) == 'asc')) {
$this->sortorder = strtolower($_REQUEST['sortorder']);
} else {
if ($checklastpaging && isset($this->userinfo['lastpaging']['sortorder']) && (strtolower($this->userinfo['lastpaging']['sortorder']) == 'desc' || strtolower($this->userinfo['lastpaging']['sortorder']) == 'asc')) {
$this->sortorder = strtolower($this->userinfo['lastpaging']['sortorder']);
} else {
$this->sortorder = $default_order;
}
}
$this->userinfo['lastpaging']['sortorder'] = $this->sortorder;
if (isset($_REQUEST['sortfield']) && isset($fields[$_REQUEST['sortfield']])) {
$this->sortfield = $_REQUEST['sortfield'];
} else {
if ($checklastpaging && isset($this->userinfo['lastpaging']['sortfield']) && isset($fields[$this->userinfo['lastpaging']['sortfield']])) {
$this->sortfield = $this->userinfo['lastpaging']['sortfield'];
} else {
$fieldnames = array_keys($fields);
$this->sortfield = $fieldnames[$default_field];
}
}
$this->userinfo['lastpaging']['sortfield'] = $this->sortfield;
if (isset($_REQUEST['searchfield']) && isset($fields[$_REQUEST['searchfield']])) {
$this->searchfield = $_REQUEST['searchfield'];
} else {
if ($checklastpaging && isset($this->userinfo['lastpaging']['searchfield']) && isset($fields[$this->userinfo['lastpaging']['searchfield']])) {
$this->searchfield = $this->userinfo['lastpaging']['searchfield'];
} else {
$fieldnames = array_keys($fields);
$this->searchfield = $fieldnames[0];
}
}
$this->userinfo['lastpaging']['searchfield'] = $this->searchfield;
if (isset($_REQUEST['searchtext']) && (preg_match('/[-_@\p{L}\p{N}*.]+$/u', $_REQUEST['searchtext']) || $_REQUEST['searchtext'] === '')) {
$this->searchtext = trim($_REQUEST['searchtext']);
} else {
if ($checklastpaging && isset($this->userinfo['lastpaging']['searchtext']) && preg_match('/[-_@\p{L}\p{N}*.]+$/u', $this->userinfo['lastpaging']['searchtext'])) {
$this->searchtext = $this->userinfo['lastpaging']['searchtext'];
} else {
$this->searchtext = '';
}
}
$this->userinfo['lastpaging']['searchtext'] = $this->searchtext;
if (isset($_REQUEST['pageno']) && intval($_REQUEST['pageno']) != 0) {
$this->pageno = intval($_REQUEST['pageno']);
} else {
if ($checklastpaging && isset($this->userinfo['lastpaging']['pageno']) && intval($this->userinfo['lastpaging']['pageno']) != 0) {
$this->pageno = intval($this->userinfo['lastpaging']['pageno']);
} else {
$this->pageno = 1;
}
}
$this->userinfo['lastpaging']['pageno'] = $this->pageno;
$upd_stmt = \Froxlor\Database\Database::prepare("
UPDATE `" . TABLE_PANEL_SESSIONS . "` SET
`lastpaging` = :lastpaging
WHERE `hash` = :hash AND `userid` = :userid
AND `ipaddress` = :ipaddr AND `useragent` = :ua
AND `adminsession` = :adminsession
");
$upd_data = array(
'lastpaging' => json_encode($this->userinfo['lastpaging']),
'hash' => $userinfo['hash'],
'userid' => $userinfo['userid'],
'ipaddr' => $userinfo['ipaddress'],
'ua' => $userinfo['useragent'],
'adminsession' => $userinfo['adminsession']
);
\Froxlor\Database\Database::pexecute($upd_stmt, $upd_data);
$this->limit = $limit;
}
/**
* Sets number of entries and adjusts pageno if the number of entries doesn't correspond to the pageno.
*
* @param
* int entries
*/
public function setEntries($entries)
{
$this->entries = $entries;
if (($this->pageno - 1) * $this->entriesperpage > $this->entries) {
$this->pageno = 1;
}
return true;
}
/**
* Checks if a row should be displayed or not, used in loops
*
* @param
* int number of row
* @return bool to display or not to display, that's the question
*/
public function checkDisplay($count)
{
$begin = (intval($this->pageno) - 1) * intval($this->entriesperpage);
$end = (intval($this->pageno) * intval($this->entriesperpage));
return (($count >= $begin && $count < $end) || $this->entriesperpage == 0);
}
/**
* Returns condition code for sql query
*
* @param
* bool should returned condition code start with WHERE (false) or AND (true)?
* @return string the condition code
*/
public function getSqlWhere($append = false)
{
if ($this->searchtext != '') {
if ($append == true) {
$condition = ' AND ';
} else {
$condition = ' WHERE ';
}
$searchfield = explode('.', $this->searchfield);
foreach ($searchfield as $id => $field) {
if (substr($field, - 1, 1) != '`') {
$field .= '`';
}
if ($field[0] != '`') {
$field = '`' . $field;
}
$searchfield[$id] = $field;
}
$searchfield = implode('.', $searchfield);
$ops = array(
'<',
'>',
'='
);
// check if we use an operator or not
$useOper = 0;
$oper = "=";
if (in_array(substr($this->searchtext, 0, 1), $ops)) {
$useOper = 1;
$oper = substr($this->searchtext, 0, 1);
}
// check for diskspace and whether searchtext is a number
// in any other case the logical-operators would make no sense
if (strpos($searchfield, 'diskspace') > 0 && is_numeric(substr($this->searchtext, $useOper))) {
// anything with diskspace is *1024
$searchtext = ((int) substr($this->searchtext, $useOper)) * 1024;
$useOper = 1;
} elseif (strpos($searchfield, 'traffic') > 0 && is_numeric(substr($this->searchtext, $useOper))) {
// anything with traffic is *1024*1024
$searchtext = ((int) substr($this->searchtext, $useOper)) * 1024 * 1024;
$useOper = 1;
} else {
// any other field
$searchtext = substr($this->searchtext, $useOper);
}
if ($useOper == 1 && is_numeric(substr($this->searchtext, $useOper))) {
// now as we use >, < or = we use the given operator and not LIKE
$condition .= $searchfield . " " . $oper . " " . \Froxlor\Database\Database::quote($searchtext);
} else {
$searchtext = str_replace('*', '%', $this->searchtext);
// append wildcards if user did not enter any
if (strpos($searchtext, '%') === false)
$searchtext = '%' . $searchtext . '%';
$condition .= $searchfield . " LIKE " . \Froxlor\Database\Database::quote($searchtext);
}
} else {
$condition = '';
}
return $condition;
}
/**
* Returns "order by"-code for sql query
*
* @param
* bool Switch natsorting on/off (local, affects just this call)
* @return string the "order by"-code
*/
public function getSqlOrderBy($natSorting = null)
{
$sortfield = explode('.', $this->sortfield);
foreach ($sortfield as $id => $field) {
if (substr($field, - 1, 1) != '`') {
$field .= '`';
}
if ($field[0] != '`') {
$field = '`' . $field;
}
$sortfield[$id] = $field;
}
$sortfield = implode('.', $sortfield);
$sortorder = strtoupper($this->sortorder);
if ($natSorting == true || ($natSorting === null && $this->natSorting == true)) {
// Acts similar to php's natsort(), found in one comment at http://my.opera.com/cpr/blog/show.dml/160556
$sortcode = "ORDER BY CONCAT( IF( ASCII( LEFT( " . $sortfield . ", 5 ) ) > 57,
LEFT( " . $sortfield . ", 1 ), 0 ),
IF( ASCII( RIGHT( " . $sortfield . ", 1 ) ) > 57,
LPAD( " . $sortfield . ", 255, '0' ),
LPAD( CONCAT( " . $sortfield . ", '-' ), 255, '0' )
)) " . $sortorder;
} else {
$sortcode = 'ORDER BY ' . $sortfield . ' ' . $sortorder;
}
return $sortcode;
}
/**
* Currently not used
*
* @return string always empty
*/
public function getSqlLimit()
{
if ($this->limit > 0) {
$_offset = ($this->pageno - 1) * $this->limit;
return ' LIMIT ' . $_offset . ',' . $this->limit;
}
/**
* currently not in use
*/
return '';
}
/**
* Returns html code for sorting field
*
* @param
* array Language array
* @return string the html sortcode
*/
public function getHtmlSortCode($lng, $break = false)
{
$sortcode = '';
$fieldoptions = '';
$orderoptions = '';
foreach ($this->fields as $fieldname => $fieldcaption) {
$fieldoptions .= HTML::makeoption($fieldcaption, $fieldname, $this->sortfield, true, true);
}
$breakorws = ($break ? '<br />' : '&nbsp;');
foreach (array(
'asc' => $lng['panel']['ascending'],
'desc' => $lng['panel']['descending']
) as $sortordertype => $sortorderdescription) {
$orderoptions .= HTML::makeoption($sortorderdescription, $sortordertype, $this->sortorder, true, true);
}
eval("\$sortcode =\"" . Template::getTemplate("misc/htmlsortcode", '1') . "\";");
return $sortcode;
}
/**
* Returns html code for sorting arrows
*
* @param
* string URL to use as base for links
* @param
* string If set, only this field will be returned
* @return mixed An array or a string (if field is set) of html code of arrows
*/
public function getHtmlArrowCode($baseurl, $field = '')
{
global $theme;
if ($field != '' && isset($this->fields[$field])) {
$baseurl = htmlspecialchars($baseurl);
$fieldname = htmlspecialchars($field);
eval("\$arrowcode =\"" . Template::getTemplate("misc/htmlarrowcode", '1') . "\";");
} else {
$baseurl = htmlspecialchars($baseurl);
$arrowcode = array();
foreach ($this->fields as $fieldname => $fieldcaption) {
$fieldname = htmlspecialchars($fieldname);
eval("\$arrowcode[\$fieldname] =\"" . Template::getTemplate("misc/htmlarrowcode", '1') . "\";");
}
}
return $arrowcode;
}
/**
* Returns html code for searching field
*
* @param
* array Language array
* @return string the html searchcode
*/
public function getHtmlSearchCode($lng)
{
$searchcode = '';
$fieldoptions = '';
$searchtext = htmlspecialchars($this->searchtext);
foreach ($this->fields as $fieldname => $fieldcaption) {
$fieldoptions .= HTML::makeoption($fieldcaption, $fieldname, $this->searchfield, true, true);
}
eval("\$searchcode =\"" . Template::getTemplate("misc/htmlsearchcode", '1') . "\";");
return $searchcode;
}
/**
* Returns html code for paging
*
* @param
* string URL to use as base for links
* @return string the html pagingcode
*/
public function getHtmlPagingCode($baseurl)
{
if ($this->entriesperpage == 0) {
return '';
} else {
$pages = intval($this->entries / $this->entriesperpage);
}
if ($this->entries % $this->entriesperpage != 0) {
$pages ++;
}
if ($pages > 1) {
$start = $this->pageno - 4;
if ($start < 1) {
$start = 1;
}
$stop = $this->pageno + 4;
if ($stop > $pages) {
$stop = $pages;
}
$pagingcode = '<a href="' . htmlspecialchars($baseurl) . '&amp;pageno=1">&laquo;</a> <a href="' . htmlspecialchars($baseurl) . '&amp;pageno=' . ((intval($this->pageno) - 1) == 0 ? '1' : intval($this->pageno) - 1) . '">&lt;</a>&nbsp;';
for ($i = $start; $i <= $stop; $i ++) {
if ($i != $this->pageno) {
$pagingcode .= ' <a href="' . htmlspecialchars($baseurl) . '&amp;pageno=' . $i . '">' . $i . '</a>&nbsp;';
} else {
$pagingcode .= ' <strong>' . $i . '</strong>&nbsp;';
}
}
$pagingcode .= ' <a href="' . htmlspecialchars($baseurl) . '&amp;pageno=' . ((intval($this->pageno) + 1) > $pages ? $pages : intval($this->pageno) + 1) . '">&gt;</a> <a href="' . $baseurl . '&amp;pageno=' . $pages . '">&raquo;</a>';
} else {
$pagingcode = '';
}
return $pagingcode;
}
}

View File

@@ -77,8 +77,7 @@ class Check
$mysql_access_host_array = array_map('trim', explode(',', $newfieldvalue)); $mysql_access_host_array = array_map('trim', explode(',', $newfieldvalue));
foreach ($mysql_access_host_array as $host_entry) { foreach ($mysql_access_host_array as $host_entry) {
if (Validate::validate_ip2($host_entry, true, 'invalidip', true, true, true, true, false) == false && Validate::validateDomain($host_entry) == false && Validate::validateLocalHostname($host_entry) == false && $host_entry != '%') {
if (Validate::validate_ip2($host_entry, true, 'invalidip', true, true) == false && Validate::validateDomain($host_entry) == false && Validate::validateLocalHostname($host_entry) == false && $host_entry != '%') {
return array( return array(
self::FORMFIELDS_PLAUSIBILITY_CHECK_ERROR, self::FORMFIELDS_PLAUSIBILITY_CHECK_ERROR,
'invalidmysqlhost', 'invalidmysqlhost',

View File

@@ -62,6 +62,38 @@ class Validate
\Froxlor\UI\Response::standard_error($lng, $fieldname, $throw_exception); \Froxlor\UI\Response::standard_error($lng, $fieldname, $throw_exception);
} }
/**
* Converts CIDR to a netmask address
*
* @thx to https://stackoverflow.com/a/5711080/3020926
* @param string $cidr
*
* @return string
*/
public static function cidr2NetmaskAddr($cidr)
{
$ta = substr($cidr, strpos($cidr, '/') + 1) * 1;
$netmask = str_split(str_pad(str_pad('', $ta, '1'), 32, '0'), 8);
foreach ($netmask as &$element) {
$element = bindec($element);
}
return implode('.', $netmask);
}
/**
* Checks if an $address (IP) is IPv6
*
* @param string $address
*
* @return string|bool ip address on success, false on failure
*/
public static function is_ipv6($address)
{
return filter_var($address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6);
}
/** /**
* Checks whether it is a valid ip * Checks whether it is a valid ip
* *
@@ -77,17 +109,35 @@ class Validate
* whether to allow private network addresses * whether to allow private network addresses
* @param bool $allow_cidr * @param bool $allow_cidr
* whether to allow CIDR values e.g. 10.10.10.10/16 * whether to allow CIDR values e.g. 10.10.10.10/16
* @param bool $cidr_as_netmask
* whether to format CIDR nodation to netmask notation
* @param bool $throw_exception
* whether to throw an exception on failure
* *
* @return string|bool ip address on success, false on failure * @return string|bool ip address on success, false on failure
*/ */
public static function validate_ip2($ip, $return_bool = false, $lng = 'invalidip', $allow_localhost = false, $allow_priv = false, $allow_cidr = false, $throw_exception = false) public static function validate_ip2($ip, $return_bool = false, $lng = 'invalidip', $allow_localhost = false, $allow_priv = false, $allow_cidr = false, $cidr_as_netmask = false, $throw_exception = false)
{ {
$cidr = ""; $cidr = "";
if ($allow_cidr) { if ($allow_cidr) {
$org_ip = $ip; $org_ip = $ip;
$ip_cidr = explode("/", $ip); $ip_cidr = explode("/", $ip);
if (count($ip_cidr) == 2) { if (count($ip_cidr) === 2) {
if (strlen($ip_cidr[1]) <= 2 && in_array((int) $ip_cidr[1], array_values(range(1, 32)), true) === false) {
\Froxlor\UI\Response::standard_error($lng, $ip, $throw_exception);
}
if ($cidr_as_netmask && self::is_ipv6($ip_cidr[0])) {
// MySQL does not handle CIDR of IPv6 addresses, return error
if ($return_bool) {
return false;
} else {
\Froxlor\UI\Response::standard_error($lng, $ip, $throw_exception);
}
}
$ip = $ip_cidr[0]; $ip = $ip_cidr[0];
if ($cidr_as_netmask && strlen($ip_cidr[1]) <= 2) {
$ip_cidr[1] = self::cidr2NetmaskAddr($org_ip);
}
$cidr = "/" . $ip_cidr[1]; $cidr = "/" . $ip_cidr[1];
} else { } else {
$ip = $org_ip; $ip = $org_ip;

View File

@@ -4629,7 +4629,7 @@ aliases: files
</commands> </commands>
<!-- instead of just restarting apache, we let the cronjob do all the <!-- instead of just restarting apache, we let the cronjob do all the
dirty work --> dirty work -->
<command><![CDATA[php {{const.\Froxlor\Froxlor::getInstallDir()}}/scripts/froxlor_master_cronjob.php --force]]></command> <command><![CDATA[php {{const.install_dir}}scripts/froxlor_master_cronjob.php --force]]></command>
</daemon> </daemon>
<!-- PHP-FPM --> <!-- PHP-FPM -->
<daemon name="php-fpm" <daemon name="php-fpm"
@@ -4667,7 +4667,7 @@ aliases: files
</commands> </commands>
<!-- instead of just restarting apache, we let the cronjob do all the <!-- instead of just restarting apache, we let the cronjob do all the
dirty work --> dirty work -->
<command><![CDATA[php {{const.\Froxlor\Froxlor::getInstallDir()}}/scripts/froxlor_master_cronjob.php --force]]></command> <command><![CDATA[php {{const.install_dir}}scripts/froxlor_master_cronjob.php --force]]></command>
</daemon> </daemon>
</service> </service>
</services> </services>

View File

@@ -4831,7 +4831,7 @@ aliases: files
</commands> </commands>
<!-- instead of just restarting apache, we let the cronjob do all the <!-- instead of just restarting apache, we let the cronjob do all the
dirty work --> dirty work -->
<command><![CDATA[php {{const.\Froxlor\Froxlor::getInstallDir()}}/scripts/froxlor_master_cronjob.php --force]]></command> <command><![CDATA[php {{const.install_dir}}scripts/froxlor_master_cronjob.php --force]]></command>
</daemon> </daemon>
<!-- PHP-FPM --> <!-- PHP-FPM -->
<daemon name="php-fpm" <daemon name="php-fpm"
@@ -4869,7 +4869,7 @@ aliases: files
</commands> </commands>
<!-- instead of just restarting apache, we let the cronjob do all the <!-- instead of just restarting apache, we let the cronjob do all the
dirty work --> dirty work -->
<command><![CDATA[php {{const.\Froxlor\Froxlor::getInstallDir()}}/scripts/froxlor_master_cronjob.php --force]]></command> <command><![CDATA[php {{const.install_dir}}scripts/froxlor_master_cronjob.php --force]]></command>
</daemon> </daemon>
</service> </service>
</services> </services>

View File

@@ -3825,7 +3825,7 @@ aliases: files
</commands> </commands>
<!-- instead of just restarting apache, we let the cronjob do all the <!-- instead of just restarting apache, we let the cronjob do all the
dirty work --> dirty work -->
<command><![CDATA[php {{const.\Froxlor\Froxlor::getInstallDir()}}/scripts/froxlor_master_cronjob.php --force]]></command> <command><![CDATA[php {{const.install_dir}}scripts/froxlor_master_cronjob.php --force]]></command>
</daemon> </daemon>
<!-- PHP-FPM --> <!-- PHP-FPM -->
<daemon name="php-fpm" <daemon name="php-fpm"
@@ -3864,7 +3864,7 @@ aliases: files
</commands> </commands>
<!-- instead of just restarting apache, we let the cronjob do all the <!-- instead of just restarting apache, we let the cronjob do all the
dirty work --> dirty work -->
<command><![CDATA[php {{const.\Froxlor\Froxlor::getInstallDir()}}/scripts/froxlor_master_cronjob.php --force]]></command> <command><![CDATA[php {{const.install_dir}}scripts/froxlor_master_cronjob.php --force]]></command>
</daemon> </daemon>
</service> </service>
</services> </services>

View File

@@ -4724,7 +4724,7 @@ aliases: files
</commands> </commands>
<!-- instead of just restarting apache, we let the cronjob do all the <!-- instead of just restarting apache, we let the cronjob do all the
dirty work --> dirty work -->
<command><![CDATA[php {{const.\Froxlor\Froxlor::getInstallDir()}}/scripts/froxlor_master_cronjob.php --force]]></command> <command><![CDATA[php {{const.install_dir}}scripts/froxlor_master_cronjob.php --force]]></command>
</daemon> </daemon>
<!-- PHP-FPM --> <!-- PHP-FPM -->
<daemon name="php-fpm" <daemon name="php-fpm"
@@ -4768,7 +4768,7 @@ aliases: files
</commands> </commands>
<!-- instead of just restarting apache, we let the cronjob do all the <!-- instead of just restarting apache, we let the cronjob do all the
dirty work --> dirty work -->
<command><![CDATA[php {{const.\Froxlor\Froxlor::getInstallDir()}}/scripts/froxlor_master_cronjob.php --force]]></command> <command><![CDATA[php {{const.install_dir}}scripts/froxlor_master_cronjob.php --force]]></command>
</daemon> </daemon>
</service> </service>
</services> </services>

View File

@@ -4618,7 +4618,7 @@ aliases: files
</commands> </commands>
<!-- instead of just restarting apache, we let the cronjob do all the <!-- instead of just restarting apache, we let the cronjob do all the
dirty work --> dirty work -->
<command><![CDATA[php {{const.\Froxlor\Froxlor::getInstallDir()}}/scripts/froxlor_master_cronjob.php --force]]></command> <command><![CDATA[php {{const.install_dir}}scripts/froxlor_master_cronjob.php --force]]></command>
</daemon> </daemon>
<!-- PHP-FPM --> <!-- PHP-FPM -->
<daemon name="php-fpm" <daemon name="php-fpm"
@@ -4656,7 +4656,7 @@ aliases: files
</commands> </commands>
<!-- instead of just restarting apache, we let the cronjob do all the <!-- instead of just restarting apache, we let the cronjob do all the
dirty work --> dirty work -->
<command><![CDATA[php {{const.\Froxlor\Froxlor::getInstallDir()}}/scripts/froxlor_master_cronjob.php --force]]></command> <command><![CDATA[php {{const.install_dir}}scripts/froxlor_master_cronjob.php --force]]></command>
</daemon> </daemon>
</service> </service>
</services> </services>

View File

@@ -1732,7 +1732,7 @@ aliases: files
</commands> </commands>
<!-- instead of just restarting apache, we let the cronjob do all the <!-- instead of just restarting apache, we let the cronjob do all the
dirty work --> dirty work -->
<command><![CDATA[php {{const.\Froxlor\Froxlor::getInstallDir()}}/scripts/froxlor_master_cronjob.php --force]]></command> <command><![CDATA[php {{const.install_dir}}scripts/froxlor_master_cronjob.php --force]]></command>
</daemon> </daemon>
<!-- PHP-FPM --> <!-- PHP-FPM -->
<daemon name="php-fpm" <daemon name="php-fpm"
@@ -1776,7 +1776,7 @@ aliases: files
</commands> </commands>
<!-- instead of just restarting apache, we let the cronjob do all the <!-- instead of just restarting apache, we let the cronjob do all the
dirty work --> dirty work -->
<command><![CDATA[php {{const.\Froxlor\Froxlor::getInstallDir()}}/scripts/froxlor_master_cronjob.php --force]]></command> <command><![CDATA[php {{const.install_dir}}scripts/froxlor_master_cronjob.php --force]]></command>
</daemon> </daemon>
</service> </service>
</services> </services>

View File

@@ -4629,7 +4629,7 @@ aliases: files
</commands> </commands>
<!-- instead of just restarting apache, we let the cronjob do all the <!-- instead of just restarting apache, we let the cronjob do all the
dirty work --> dirty work -->
<command><![CDATA[php {{const.\Froxlor\Froxlor::getInstallDir()}}/scripts/froxlor_master_cronjob.php --force]]></command> <command><![CDATA[php {{const.install_dir}}scripts/froxlor_master_cronjob.php --force]]></command>
</daemon> </daemon>
<!-- PHP-FPM --> <!-- PHP-FPM -->
<daemon name="php-fpm" <daemon name="php-fpm"
@@ -4667,7 +4667,7 @@ aliases: files
</commands> </commands>
<!-- instead of just restarting apache, we let the cronjob do all the <!-- instead of just restarting apache, we let the cronjob do all the
dirty work --> dirty work -->
<command><![CDATA[php {{const.\Froxlor\Froxlor::getInstallDir()}}/scripts/froxlor_master_cronjob.php --force]]></command> <command><![CDATA[php {{const.install_dir}}scripts/froxlor_master_cronjob.php --force]]></command>
</daemon> </daemon>
</service> </service>
</services> </services>

View File

@@ -93,7 +93,7 @@ return array(
) )
), ),
'value' => array( 'value' => array(
'1' (\Froxlor\Settings::Get('api.enabled') == '1' ? '1' : '0')
), ),
'visible' => (\Froxlor\Settings::Get('api.enabled') == '1' ? true : false) 'visible' => (\Froxlor\Settings::Get('api.enabled') == '1' ? true : false)
) )

View File

@@ -180,6 +180,12 @@ return array(
'image' => 'icons/domain_add.png', 'image' => 'icons/domain_add.png',
'visible' => \Froxlor\Settings::Get('system.use_ssl') == '1' ? true : false, 'visible' => \Froxlor\Settings::Get('system.use_ssl') == '1' ? true : false,
'fields' => array( 'fields' => array(
'no_ssl_available_info' => array(
'visible' => ($ssl_ipsandports == '' ? true : false),
'label' => 'SSL',
'type' => 'label',
'value' => $lng['panel']['nosslipsavailable']
),
'ssl_ipandport' => array( 'ssl_ipandport' => array(
'label' => $lng['domains']['ipandport_ssl_multi']['title'], 'label' => $lng['domains']['ipandport_ssl_multi']['title'],
'desc' => $lng['domains']['ipandport_ssl_multi']['description'], 'desc' => $lng['domains']['ipandport_ssl_multi']['description'],
@@ -188,26 +194,6 @@ return array(
'value' => explode(',', \Froxlor\Settings::Get('system.defaultsslip')), 'value' => explode(',', \Froxlor\Settings::Get('system.defaultsslip')),
'is_array' => 1 'is_array' => 1
), ),
'ssl_specialsettings' => array(
'visible' => ($userinfo['change_serversettings'] == '1' ? true : false),
'style' => 'align-top',
'label' => $lng['admin']['ownsslvhostsettings'],
'desc' => $lng['serversettings']['default_vhostconf']['description'],
'type' => 'textarea',
'cols' => 60,
'rows' => 12
),
'include_specialsettings' => array(
'label' => $lng['admin']['include_ownvhostsettings'],
'type' => 'checkbox',
'values' => array(
array(
'label' => $lng['panel']['yes'],
'value' => '1'
)
),
'value' => array()
),
'ssl_redirect' => array( 'ssl_redirect' => array(
'visible' => ($ssl_ipsandports != '' ? true : false), 'visible' => ($ssl_ipsandports != '' ? true : false),
'label' => $lng['domains']['ssl_redirect']['title'], 'label' => $lng['domains']['ssl_redirect']['title'],
@@ -247,11 +233,81 @@ return array(
), ),
'value' => array() 'value' => array()
), ),
'no_ssl_available_info' => array( 'override_tls' => array(
'visible' => ($ssl_ipsandports == '' ? true : false), 'visible' => (($ssl_ipsandports != '' ? true : false) && $userinfo['change_serversettings'] == '1' ? true : false),
'label' => 'SSL', 'label' => $lng['admin']['domain_override_tls'],
'type' => 'label', 'type' => 'checkbox',
'value' => $lng['panel']['nosslipsavailable'] 'values' => array(
array(
'label' => $lng['panel']['yes'],
'value' => '1'
)
),
'value' => array()
),
'ssl_protocols' => array(
'visible' => (($ssl_ipsandports != '' ? true : false) && $userinfo['change_serversettings'] == '1' && \Froxlor\Settings::Get('system.webserver') != 'lighttpd' ? true : false),
'label' => $lng['serversettings']['ssl']['ssl_protocols']['title'],
'desc' => $lng['serversettings']['ssl']['ssl_protocols']['description'],
'type' => 'checkbox',
'value' => array(
'TLSv1',
'TLSv1.2'
),
'values' => array(
array(
'value' => 'TLSv1',
'label' => 'TLSv1<br />'
),
array(
'value' => 'TLSv1.1',
'label' => 'TLSv1.1<br />'
),
array(
'value' => 'TLSv1.2',
'label' => 'TLSv1.2<br />'
),
array(
'value' => 'TLSv1.3',
'label' => 'TLSv1.3<br />'
)
),
'is_array' => 1
),
'ssl_cipher_list' => array(
'visible' => (($ssl_ipsandports != '' ? true : false) && $userinfo['change_serversettings'] == '1' ? true : false),
'label' => $lng['serversettings']['ssl']['ssl_cipher_list']['title'],
'desc' => $lng['serversettings']['ssl']['ssl_cipher_list']['description'],
'type' => 'text',
'value' => \Froxlor\Settings::Get('system.ssl_cipher_list')
),
'tlsv13_cipher_list' => array(
'visible' => (($ssl_ipsandports != '' ? true : false) && $userinfo['change_serversettings'] == '1' && \Froxlor\Settings::Get('system.webserver') == "apache2" && \Froxlor\Settings::Get('system.apache24') == 1 ? true : false),
'label' => $lng['serversettings']['ssl']['tlsv13_cipher_list']['title'],
'desc' => $lng['serversettings']['ssl']['tlsv13_cipher_list']['description'],
'type' => 'text',
'value' => \Froxlor\Settings::Get('system.tlsv13_cipher_list')
),
'ssl_specialsettings' => array(
'visible' => (($ssl_ipsandports != '' ? true : false) && $userinfo['change_serversettings'] == '1' ? true : false),
'style' => 'align-top',
'label' => $lng['admin']['ownsslvhostsettings'],
'desc' => $lng['serversettings']['default_vhostconf']['description'],
'type' => 'textarea',
'cols' => 60,
'rows' => 12
),
'include_specialsettings' => array(
'visible' => (($ssl_ipsandports != '' ? true : false) && $userinfo['change_serversettings'] == '1' ? true : false),
'label' => $lng['admin']['include_ownvhostsettings'],
'type' => 'checkbox',
'values' => array(
array(
'label' => $lng['panel']['yes'],
'value' => '1'
)
),
'value' => array()
), ),
'hsts_maxage' => array( 'hsts_maxage' => array(
'visible' => ($ssl_ipsandports != '' ? true : false), 'visible' => ($ssl_ipsandports != '' ? true : false),

View File

@@ -212,6 +212,12 @@ return array(
'image' => 'icons/domain_edit.png', 'image' => 'icons/domain_edit.png',
'visible' => \Froxlor\Settings::Get('system.use_ssl') == '1' ? true : false, 'visible' => \Froxlor\Settings::Get('system.use_ssl') == '1' ? true : false,
'fields' => array( 'fields' => array(
'no_ssl_available_info' => array(
'visible' => ($ssl_ipsandports == '' ? true : false),
'label' => 'SSL',
'type' => 'label',
'value' => $lng['panel']['nosslipsavailable']
),
'ssl_ipandport' => array( 'ssl_ipandport' => array(
'label' => $lng['domains']['ipandport_ssl_multi']['title'], 'label' => $lng['domains']['ipandport_ssl_multi']['title'],
'desc' => $lng['domains']['ipandport_ssl_multi']['description'], 'desc' => $lng['domains']['ipandport_ssl_multi']['description'],
@@ -220,29 +226,6 @@ return array(
'value' => $usedips, 'value' => $usedips,
'is_array' => 1 'is_array' => 1
), ),
'ssl_specialsettings' => array(
'visible' => ($userinfo['change_serversettings'] == '1' ? true : false),
'style' => 'align-top',
'label' => $lng['admin']['ownsslvhostsettings'],
'desc' => $lng['serversettings']['default_vhostconf']['description'],
'type' => 'textarea',
'cols' => 60,
'rows' => 12,
'value' => $result['ssl_specialsettings']
),
'include_specialsettings' => array(
'label' => $lng['admin']['include_ownvhostsettings'],
'type' => 'checkbox',
'values' => array(
array(
'label' => $lng['panel']['yes'],
'value' => '1'
)
),
'value' => array(
$result['include_specialsettings']
)
),
'ssl_redirect' => array( 'ssl_redirect' => array(
'visible' => ($ssl_ipsandports != '' ? true : false), 'visible' => ($ssl_ipsandports != '' ? true : false),
'label' => $lng['domains']['ssl_redirect']['title'], 'label' => $lng['domains']['ssl_redirect']['title'],
@@ -288,11 +271,82 @@ return array(
$result['http2'] $result['http2']
) )
), ),
'no_ssl_available_info' => array( 'override_tls' => array(
'visible' => ($ssl_ipsandports == '' ? true : false), 'visible' => (($ssl_ipsandports != '' ? true : false) && $userinfo['change_serversettings'] == '1' ? true : false),
'label' => 'SSL', 'label' => $lng['admin']['domain_override_tls'],
'type' => 'label', 'type' => 'checkbox',
'value' => $lng['panel']['nosslipsavailable'] 'values' => array(
array(
'label' => $lng['panel']['yes'],
'value' => '1'
)
),
'value' => array(
$result['override_tls']
)
),
'ssl_protocols' => array(
'visible' => (($ssl_ipsandports != '' ? true : false) && $userinfo['change_serversettings'] == '1' && \Froxlor\Settings::Get('system.webserver') != 'lighttpd' ? true : false),
'label' => $lng['serversettings']['ssl']['ssl_protocols']['title'],
'desc' => $lng['serversettings']['ssl']['ssl_protocols']['description'],
'type' => 'checkbox',
'value' => !empty($result['ssl_protocols']) ? explode(",", $result['ssl_protocols']) : explode(",", \Froxlor\Settings::Get('system.ssl_protocols')),
'values' => array(
array(
'value' => 'TLSv1',
'label' => 'TLSv1<br />'
),
array(
'value' => 'TLSv1.1',
'label' => 'TLSv1.1<br />'
),
array(
'value' => 'TLSv1.2',
'label' => 'TLSv1.2<br />'
),
array(
'value' => 'TLSv1.3',
'label' => 'TLSv1.3<br />'
)
),
'is_array' => 1
),
'ssl_cipher_list' => array(
'visible' => (($ssl_ipsandports != '' ? true : false) && $userinfo['change_serversettings'] == '1' ? true : false),
'label' => $lng['serversettings']['ssl']['ssl_cipher_list']['title'],
'desc' => $lng['serversettings']['ssl']['ssl_cipher_list']['description'],
'type' => 'text',
'value' => !empty($result['ssl_cipher_list']) ? $result['ssl_cipher_list'] : \Froxlor\Settings::Get('system.ssl_cipher_list')
),
'tlsv13_cipher_list' => array(
'visible' => (($ssl_ipsandports != '' ? true : false) && $userinfo['change_serversettings'] == '1' && \Froxlor\Settings::Get('system.webserver') == "apache2" && \Froxlor\Settings::Get('system.apache24') == 1 ? true : false),
'label' => $lng['serversettings']['ssl']['tlsv13_cipher_list']['title'],
'desc' => $lng['serversettings']['ssl']['tlsv13_cipher_list']['description'],
'type' => 'text',
'value' => !empty($result['tlsv13_cipher_list']) ? $result['tlsv13_cipher_list'] : \Froxlor\Settings::Get('system.tlsv13_cipher_list')
),
'ssl_specialsettings' => array(
'visible' => ($userinfo['change_serversettings'] == '1' ? true : false),
'style' => 'align-top',
'label' => $lng['admin']['ownsslvhostsettings'],
'desc' => $lng['serversettings']['default_vhostconf']['description'],
'type' => 'textarea',
'cols' => 60,
'rows' => 12,
'value' => $result['ssl_specialsettings']
),
'include_specialsettings' => array(
'label' => $lng['admin']['include_ownvhostsettings'],
'type' => 'checkbox',
'values' => array(
array(
'label' => $lng['panel']['yes'],
'value' => '1'
)
),
'value' => array(
$result['include_specialsettings']
)
), ),
'hsts_maxage' => array( 'hsts_maxage' => array(
'visible' => ($ssl_ipsandports != '' ? true : false), 'visible' => ($ssl_ipsandports != '' ? true : false),

View File

@@ -569,7 +569,7 @@ $lng['serversettings']['apacheconf_htpasswddir']['description'] = 'Where should
$lng['error']['formtokencompromised'] = 'The request seems to be compromised. For security reasons you were logged out.'; $lng['error']['formtokencompromised'] = 'The request seems to be compromised. For security reasons you were logged out.';
$lng['serversettings']['mysql_access_host']['title'] = 'MySQL-Access-Hosts'; $lng['serversettings']['mysql_access_host']['title'] = 'MySQL-Access-Hosts';
$lng['serversettings']['mysql_access_host']['description'] = 'A comma separated list of hosts from which users should be allowed to connect to the MySQL-Server.'; $lng['serversettings']['mysql_access_host']['description'] = 'A comma separated list of hosts from which users should be allowed to connect to the MySQL-Server. To allow a subnet the netmask or cidr syntax is valid.';
// ADDED IN 1.2.18-svn1 // ADDED IN 1.2.18-svn1
@@ -2078,3 +2078,4 @@ $lng['serversettings']['includedefault_sslvhostconf'] = 'Include non-SSL vHost-s
$lng['admin']['ownsslvhostsettings'] = 'Own SSL vHost-settings'; $lng['admin']['ownsslvhostsettings'] = 'Own SSL vHost-settings';
$lng['admin']['ipsandports']['ssl_default_vhostconf_domain'] = 'Default SSL vHost-settings for every domain container'; $lng['admin']['ipsandports']['ssl_default_vhostconf_domain'] = 'Default SSL vHost-settings for every domain container';
$lng['customer']['total_diskspace'] = 'Total diskspace (MiB)'; $lng['customer']['total_diskspace'] = 'Total diskspace (MiB)';
$lng['admin']['domain_override_tls'] = 'Override system TLS settings';

View File

@@ -564,7 +564,7 @@ $lng['serversettings']['apacheconf_htpasswddir']['description'] = 'Wo sollen die
$lng['error']['formtokencompromised'] = 'Das Formular scheint manipuliert worden zu sein. Aus Sicherheitsgründen wurden Sie ausgelogged.'; $lng['error']['formtokencompromised'] = 'Das Formular scheint manipuliert worden zu sein. Aus Sicherheitsgründen wurden Sie ausgelogged.';
$lng['serversettings']['mysql_access_host']['title'] = 'MySQL-Access-Hosts'; $lng['serversettings']['mysql_access_host']['title'] = 'MySQL-Access-Hosts';
$lng['serversettings']['mysql_access_host']['description'] = 'Eine durch Komma getrennte Liste mit den Hostnamen aller Hostnames/IP-Adressen, von denen sich die Benutzer einloggen dürfen.'; $lng['serversettings']['mysql_access_host']['description'] = 'Eine durch Komma getrennte Liste mit den Hostnamen aller Hostnames/IP-Adressen, von denen sich die Benutzer einloggen dürfen. Um ein Subnetz zu erlauben ist die Netzmaske oder CIDR Syntax erlaubt.';
// ADDED IN 1.2.18-svn1 // ADDED IN 1.2.18-svn1
@@ -1725,3 +1725,4 @@ $lng['serversettings']['includedefault_sslvhostconf'] = 'Nicht-SSL vHost-Einstel
$lng['admin']['ownsslvhostsettings'] = 'Eigene SSL vHost-Einstellungen'; $lng['admin']['ownsslvhostsettings'] = 'Eigene SSL vHost-Einstellungen';
$lng['admin']['ipsandports']['ssl_default_vhostconf_domain'] = 'Standard SSL vHost-Einstellungen für jeden Domain-Container'; $lng['admin']['ipsandports']['ssl_default_vhostconf_domain'] = 'Standard SSL vHost-Einstellungen für jeden Domain-Container';
$lng['customer']['total_diskspace'] = 'Gesamtspeicherplatz (MiB)'; $lng['customer']['total_diskspace'] = 'Gesamtspeicherplatz (MiB)';
$lng['admin']['domain_override_tls'] = 'Überschreibe System TLS Einstellungen';

View File

@@ -19,7 +19,6 @@ if (! defined('AREA')) {
* *
*/ */
use Froxlor\Database\Database;
use Froxlor\Settings; use Froxlor\Settings;
use Froxlor\Api\Commands\Certificates as Certificates; use Froxlor\Api\Commands\Certificates as Certificates;
@@ -47,35 +46,20 @@ $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed domains:
$fields = array( $fields = array(
'd.domain' => $lng['domains']['domainname'] 'd.domain' => $lng['domains']['domainname']
); );
$paging = new \Froxlor\UI\Paging($userinfo, TABLE_PANEL_DOMAIN_SSL_SETTINGS, $fields); try {
// get total count
// select all my (accessable) certificates $json_result = Certificates::getLocal($userinfo)->listingCount();
$certs_stmt_query = "SELECT s.*, d.domain, d.letsencrypt, c.customerid, c.loginname $result = json_decode($json_result, true)['data'];
FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` s // initialize pagination and filtering
LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` d ON `d`.`id` = `s`.`domainid` $paging = new \Froxlor\UI\Pagination($userinfo, $fields, $result);
LEFT JOIN `" . TABLE_PANEL_CUSTOMERS . "` c ON `c`.`customerid` = `d`.`customerid` // get list
WHERE "; $json_result = Certificates::getLocal($userinfo, $paging->getApiCommandParams())->listing();
} catch (Exception $e) {
$qry_params = array(); \Froxlor\UI\Response::dynamic_error($e->getMessage());
if (AREA == 'admin' && $userinfo['customers_see_all'] == '0') {
// admin with only customer-specific permissions
$certs_stmt_query .= "d.adminid = :adminid ";
$qry_params['adminid'] = $userinfo['adminid'];
} elseif (AREA == 'customer') {
// customer-area
$certs_stmt_query .= "d.customerid = :cid ";
$qry_params['cid'] = $userinfo['customerid'];
} else {
$certs_stmt_query .= "1 ";
} }
$result = json_decode($json_result, true)['data'];
// sorting by domain-name $all_certs = $result['list'];
$certs_stmt_query .= $paging->getSqlWhere(true) . " " . $paging->getSqlOrderBy() . " " . $paging->getSqlLimit();
$certs_stmt = Database::prepare($certs_stmt_query);
Database::pexecute($certs_stmt, $qry_params);
$all_certs = $certs_stmt->fetchAll(PDO::FETCH_ASSOC);
$certificates = ""; $certificates = "";
if (count($all_certs) == 0) { if (count($all_certs) == 0) {
@@ -84,19 +68,17 @@ if (count($all_certs) == 0) {
$arrowcode = array( $arrowcode = array(
'd.domain' => '' 'd.domain' => ''
); );
$searchcode = ""; // keep searching code if something was searched and no results were returned
$searchcode = $paging->getHtmlSearchCode($lng);
$pagingcode = ""; $pagingcode = "";
eval("\$certificates.=\"" . \Froxlor\UI\Template::getTemplate("ssl_certificates/certs_error", true) . "\";"); eval("\$certificates.=\"" . \Froxlor\UI\Template::getTemplate("ssl_certificates/certs_error", true) . "\";");
} else { } else {
$paging->setEntries(count($all_certs));
$sortcode = $paging->getHtmlSortCode($lng); $sortcode = $paging->getHtmlSortCode($lng);
$arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s);
$searchcode = $paging->getHtmlSearchCode($lng); $searchcode = $paging->getHtmlSearchCode($lng);
$pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s);
foreach ($all_certs as $idx => $cert) { foreach ($all_certs as $idx => $cert) {
if ($paging->checkDisplay($idx)) {
// respect froxlor-hostname // respect froxlor-hostname
if ($cert['domainid'] == 0) { if ($cert['domainid'] == 0) {
$cert['domain'] = Settings::Get('system.hostname'); $cert['domain'] = Settings::Get('system.hostname');
@@ -159,9 +141,6 @@ if (count($all_certs) == 0) {
$message = sprintf($lng['domains']['ssl_certificate_error'], $cert['domain']); $message = sprintf($lng['domains']['ssl_certificate_error'], $cert['domain']);
eval("\$certificates.=\"" . \Froxlor\UI\Template::getTemplate("ssl_certificates/certs_error", true) . "\";"); eval("\$certificates.=\"" . \Froxlor\UI\Template::getTemplate("ssl_certificates/certs_error", true) . "\";");
} }
} else {
continue;
}
} }
} }
eval("echo \"" . \Froxlor\UI\Template::getTemplate("ssl_certificates/certs_list", true) . "\";"); eval("echo \"" . \Froxlor\UI\Template::getTemplate("ssl_certificates/certs_list", true) . "\";");

View File

@@ -9,7 +9,7 @@ $header
<legend>Froxlor&nbsp;-&nbsp;{$lng['login']['2fa']}</legend> <legend>Froxlor&nbsp;-&nbsp;{$lng['login']['2fa']}</legend>
<p> <p>
<label for="2fa_code">{$lng['login']['2facode']}:</label>&nbsp; <label for="2fa_code">{$lng['login']['2facode']}:</label>&nbsp;
<input type="text" name="2fa_code" id="2fa_code" value="" required/> <input type="text" name="2fa_code" id="2fa_code" value="" autofocus required/>
</p> </p>
<p class="submit"> <p class="submit">
<input type="hidden" name="action" value="2fa_verify" /> <input type="hidden" name="action" value="2fa_verify" />

View File

@@ -156,6 +156,51 @@ class AdminsTest extends TestCase
$json_result = Admins::getLocal($admin_userdata)->listing(); $json_result = Admins::getLocal($admin_userdata)->listing();
$result = json_decode($json_result, true)['data']; $result = json_decode($json_result, true)['data'];
$this->assertEquals(2, $result['count']); $this->assertEquals(2, $result['count']);
$json_result = Admins::getLocal($admin_userdata)->listingCount();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(2, $result);
}
public function testAdminAdminsListLimitOffsetOrderSearch()
{
global $admin_userdata;
$json_result = Admins::getLocal($admin_userdata, [
'sql_orderby' => [
'loginname' => 'DESC'
]
])->listing();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(2, $result['count']);
$this->assertEquals('reseller', $result['list'][0]['loginname']);
$json_result = Admins::getLocal($admin_userdata, [
'sql_limit' => 1
])->listing();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(1, $result['count']);
$this->assertEquals('admin', $result['list'][0]['loginname']);
$json_result = Admins::getLocal($admin_userdata, [
'sql_limit' => 1,
'sql_offset' => 1
])->listing();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(1, $result['count']);
$this->assertEquals('reseller', $result['list'][0]['loginname']);
$json_result = Admins::getLocal($admin_userdata, [
'sql_search' => [
'loginname' => [
'value' => 'adm',
'op' => null /* LIKE */
]
]
])->listing();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(1, $result['count']);
$this->assertEquals('admin', $result['list'][0]['loginname']);
} }
public function testResellerAdminsGet() public function testResellerAdminsGet()

View File

@@ -154,6 +154,10 @@ class CustomerBackupsTest extends TestCase
$this->assertEquals('1', $result['list'][0]['data']['backup_dbs']); $this->assertEquals('1', $result['list'][0]['data']['backup_dbs']);
$this->assertEquals('1', $result['list'][0]['data']['backup_mail']); $this->assertEquals('1', $result['list'][0]['data']['backup_mail']);
$this->assertEquals('1', $result['list'][0]['data']['backup_web']); $this->assertEquals('1', $result['list'][0]['data']['backup_web']);
$json_result = CustomerBackups::getLocal($admin_userdata)->listingCount();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(1, $result);
} }
/** /**

View File

@@ -74,6 +74,10 @@ class CertificatesTest extends TestCase
$json_result = Certificates::getLocal($admin_userdata)->listing(); $json_result = Certificates::getLocal($admin_userdata)->listing();
$result = json_decode($json_result, true)['data']; $result = json_decode($json_result, true)['data'];
$this->assertEquals(2, $result['count']); $this->assertEquals(2, $result['count']);
$json_result = Certificates::getLocal($admin_userdata)->listingCount();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(2, $result);
} }
public function testResellerCertificatesList() public function testResellerCertificatesList()
@@ -89,6 +93,10 @@ class CertificatesTest extends TestCase
$json_result = Certificates::getLocal($reseller_userdata)->listing(); $json_result = Certificates::getLocal($reseller_userdata)->listing();
$result = json_decode($json_result, true)['data']; $result = json_decode($json_result, true)['data'];
$this->assertEquals(2, $result['count']); $this->assertEquals(2, $result['count']);
$json_result = Certificates::getLocal($reseller_userdata)->listingCount();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(2, $result);
} }
public function testCustomerCertificatesList() public function testCustomerCertificatesList()
@@ -103,6 +111,10 @@ class CertificatesTest extends TestCase
$json_result = Certificates::getLocal($customer_userdata)->listing(); $json_result = Certificates::getLocal($customer_userdata)->listing();
$result = json_decode($json_result, true)['data']; $result = json_decode($json_result, true)['data'];
$this->assertEquals(2, $result['count']); $this->assertEquals(2, $result['count']);
$json_result = Certificates::getLocal($customer_userdata)->listingCount();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(2, $result);
} }
public function testAdminCertificatesUpdate() public function testAdminCertificatesUpdate()
@@ -189,7 +201,6 @@ class CertificatesTest extends TestCase
)); ));
// export // export
openssl_csr_export($csr, $csrout);
openssl_x509_export($sscert, $certout); openssl_x509_export($sscert, $certout);
openssl_pkey_export($privkey, $pkeyout, null); openssl_pkey_export($privkey, $pkeyout, null);

View File

@@ -21,6 +21,10 @@ class CronjobsTest extends TestCase
$result = json_decode($json_result, true)['data']; $result = json_decode($json_result, true)['data'];
$this->assertTrue(isset($result['list'][0]['module'])); $this->assertTrue(isset($result['list'][0]['module']));
$this->assertTrue(isset($result['list'][0]['cronfile'])); $this->assertTrue(isset($result['list'][0]['cronfile']));
$json_result = Cronjobs::getLocal($admin_userdata)->listingCount();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(6, $result);
} }
public function testCustomerCronjobsListNotAllowed() public function testCustomerCronjobsListNotAllowed()

View File

@@ -6,6 +6,7 @@ use Froxlor\Database\Database;
use Froxlor\Api\Commands\Admins; use Froxlor\Api\Commands\Admins;
use Froxlor\Api\Commands\Customers; use Froxlor\Api\Commands\Customers;
use Froxlor\Api\Commands\SubDomains; use Froxlor\Api\Commands\SubDomains;
use Froxlor\Api\Commands\Ftps;
/** /**
* *
@@ -61,7 +62,9 @@ class CustomersTest extends TestCase
$this->assertEquals('secret', $result['custom_notes']); $this->assertEquals('secret', $result['custom_notes']);
// validate that the std-subdomain has been added // validate that the std-subdomain has been added
$json_result = SubDomains::getLocal($admin_userdata, array('id' => $result['standardsubdomain']))->get(); $json_result = SubDomains::getLocal($admin_userdata, array(
'id' => $result['standardsubdomain']
))->get();
$result = json_decode($json_result, true)['data']; $result = json_decode($json_result, true)['data'];
$this->assertEquals('test1.dev.froxlor.org', $result['domain']); $this->assertEquals('test1.dev.froxlor.org', $result['domain']);
} }
@@ -107,6 +110,10 @@ class CustomersTest extends TestCase
$json_result = Customers::getLocal($admin_userdata)->listing(); $json_result = Customers::getLocal($admin_userdata)->listing();
$result = json_decode($json_result, true)['data']; $result = json_decode($json_result, true)['data'];
$this->assertEquals(1, $result['count']); $this->assertEquals(1, $result['count']);
$json_result = Customers::getLocal($admin_userdata)->listingCount();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(1, $result);
} }
/** /**
@@ -125,6 +132,10 @@ class CustomersTest extends TestCase
$json_result = Customers::getLocal($reseller_userdata)->listing(); $json_result = Customers::getLocal($reseller_userdata)->listing();
$result = json_decode($json_result, true)['data']; $result = json_decode($json_result, true)['data'];
$this->assertEquals(0, $result['count']); $this->assertEquals(0, $result['count']);
$json_result = Customers::getLocal($reseller_userdata)->listingCount();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(0, $result);
} }
/** /**
@@ -142,8 +153,11 @@ class CustomersTest extends TestCase
$this->expectExceptionCode(403); $this->expectExceptionCode(403);
$this->expectExceptionMessage("Not allowed to execute given command."); $this->expectExceptionMessage("Not allowed to execute given command.");
$json_result = Customers::getLocal($customer_userdata)->listing(); $json_result = Customers::getLocal($customer_userdata)->listing();
$this->expectExceptionCode(403);
$this->expectExceptionMessage("Not allowed to execute given command.");
$json_result = Customers::getLocal($customer_userdata)->listingCount();
} }
/** /**
@@ -555,4 +569,49 @@ class CustomersTest extends TestCase
$this->expectExceptionMessage('Loginname contains too many characters. Only ' . (\Froxlor\Database\Database::getSqlUsernameLength() - strlen(Settings::Get('customer.mysqlprefix'))) . ' characters are allowed.'); $this->expectExceptionMessage('Loginname contains too many characters. Only ' . (\Froxlor\Database\Database::getSqlUsernameLength() - strlen(Settings::Get('customer.mysqlprefix'))) . ' characters are allowed.');
Customers::getLocal($admin_userdata, $data)->add(); Customers::getLocal($admin_userdata, $data)->add();
} }
/**
*
* @depends testAdminCustomersAddAutoLoginname
*/
public function testResellerCustomersAddNoFtpValidateDefaultUserExists()
{
global $admin_userdata;
// get reseller
$json_result = Admins::getLocal($admin_userdata, array(
'loginname' => 'reseller'
))->get();
$reseller_userdata = json_decode($json_result, true)['data'];
$reseller_userdata['adminsession'] = 1;
// set available ftp resources to 0 to validate that when the customer
// is added the default ftp user for the customer is created too regardless of
// available resource of the reseller/admin
$reseller_userdata['ftps'] = 0;
// add new customer
$data = [
'new_loginname' => 'testftpx',
'email' => 'testftp@froxlor.org',
'firstname' => 'Test',
'name' => 'Ftpman',
'customernumber' => 1339,
'new_customer_password' => 'h0lYmo1y'
];
Customers::getLocal($reseller_userdata, $data)->add();
// get FTP user
$json_result = Ftps::getLocal($reseller_userdata, [
'username' => 'testftpx'
])->get();
$ftp_data = json_decode($json_result, true)['data'];
$this->assertEquals("testftpx", $ftp_data['username']);
// now get rid of the customer again
$json_result = Customers::getLocal($reseller_userdata, array(
'loginname' => 'testftpx'
))->delete();
$result = json_decode($json_result, true)['data'];
$this->assertEquals('testftpx', $result['loginname']);
}
} }

View File

@@ -83,6 +83,10 @@ class HostingPlansTest extends TestCase
$json_result = HostingPlans::getLocal($admin_userdata)->listing(); $json_result = HostingPlans::getLocal($admin_userdata)->listing();
$result = json_decode($json_result, true)['data']; $result = json_decode($json_result, true)['data'];
$this->assertEquals(1, $result['count']); $this->assertEquals(1, $result['count']);
$json_result = HostingPlans::getLocal($admin_userdata)->listingCount();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(1, $result);
} }
/** /**
@@ -101,6 +105,10 @@ class HostingPlansTest extends TestCase
$json_result = HostingPlans::getLocal($reseller_userdata)->listing(); $json_result = HostingPlans::getLocal($reseller_userdata)->listing();
$result = json_decode($json_result, true)['data']; $result = json_decode($json_result, true)['data'];
$this->assertEquals(0, $result['count']); $this->assertEquals(0, $result['count']);
$json_result = HostingPlans::getLocal($reseller_userdata)->listingCount();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(0, $result);
} }
/** /**
@@ -118,8 +126,11 @@ class HostingPlansTest extends TestCase
$this->expectExceptionCode(403); $this->expectExceptionCode(403);
$this->expectExceptionMessage("Not allowed to execute given command."); $this->expectExceptionMessage("Not allowed to execute given command.");
$json_result = HostingPlans::getLocal($customer_userdata)->listing(); $json_result = HostingPlans::getLocal($customer_userdata)->listing();
$this->expectExceptionCode(403);
$this->expectExceptionMessage("Not allowed to execute given command.");
$json_result = HostingPlans::getLocal($customer_userdata)->listingCount();
} }
public function testCustomerPlanAdd() public function testCustomerPlanAdd()

View File

@@ -116,6 +116,10 @@ class DomainZonesTest extends TestCase
$result = json_decode($json_result, true)['data']; $result = json_decode($json_result, true)['data'];
$this->assertEquals(1, $result['count']); $this->assertEquals(1, $result['count']);
$this->assertEquals('www2', $result['list'][0]['record']); $this->assertEquals('www2', $result['list'][0]['record']);
$json_result = DomainZones::getLocal($admin_userdata, $data)->listingCount();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(1, $result);
} }
/** /**

View File

@@ -5,6 +5,7 @@ use Froxlor\Settings;
use Froxlor\Api\Commands\Admins; use Froxlor\Api\Commands\Admins;
use Froxlor\Api\Commands\Customers; use Froxlor\Api\Commands\Customers;
use Froxlor\Api\Commands\Domains; use Froxlor\Api\Commands\Domains;
use Froxlor\Database\Database;
/** /**
* *
@@ -26,11 +27,17 @@ class DomainsTest extends TestCase
$customer_userdata = json_decode($json_result, true)['data']; $customer_userdata = json_decode($json_result, true)['data'];
$data = [ $data = [
'domain' => 'test.local', 'domain' => 'test.local',
'customerid' => $customer_userdata['customerid'] 'customerid' => $customer_userdata['customerid'],
'override_tls' => 1,
'ssl_protocols' => array(
'TLSv1.2',
'TLSv1.3'
)
]; ];
$json_result = Domains::getLocal($admin_userdata, $data)->add(); $json_result = Domains::getLocal($admin_userdata, $data)->add();
$result = json_decode($json_result, true)['data']; $result = json_decode($json_result, true)['data'];
$this->assertEquals($customer_userdata['documentroot'] . 'test.local/', $result['documentroot']); $this->assertEquals($customer_userdata['documentroot'] . 'test.local/', $result['documentroot']);
$this->assertTrue(in_array('TLSv1.3', explode(",", $result['ssl_protocols'])));
} }
/** /**
@@ -44,6 +51,18 @@ class DomainsTest extends TestCase
$result = json_decode($json_result, true)['data']; $result = json_decode($json_result, true)['data'];
$this->assertEquals(1, $result['count']); $this->assertEquals(1, $result['count']);
$this->assertEquals('test.local', $result['list'][0]['domain']); $this->assertEquals('test.local', $result['list'][0]['domain']);
$this->assertEquals(2, count($result['list'][0]['ipsandports']));
$this->assertEquals("82.149.225.56", $result['list'][0]['ipsandports'][1]['ip']);
$json_result = Domains::getLocal($admin_userdata)->listingCount();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(1, $result);
$json_result = Domains::getLocal($admin_userdata, [
'with_ips' => false
])->listing();
$result = json_decode($json_result, true)['data'];
$this->assertEmpty($result['list'][0]['ipsandports']);
} }
/** /**
@@ -62,6 +81,10 @@ class DomainsTest extends TestCase
$json_result = Domains::getLocal($reseller_userdata)->listing(); $json_result = Domains::getLocal($reseller_userdata)->listing();
$result = json_decode($json_result, true)['data']; $result = json_decode($json_result, true)['data'];
$this->assertEquals(0, $result['count']); $this->assertEquals(0, $result['count']);
$json_result = Domains::getLocal($reseller_userdata)->listingCount();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(0, $result);
} }
public function testResellerDomainsAddWithCanEditPhpSettingsDefaultIp() public function testResellerDomainsAddWithCanEditPhpSettingsDefaultIp()
@@ -153,11 +176,68 @@ class DomainsTest extends TestCase
global $admin_userdata; global $admin_userdata;
$data = [ $data = [
'domainname' => 'test.local', 'domainname' => 'test.local',
'email_only' => 1 'email_only' => 1,
'override_tls' => 0
]; ];
$json_result = Domains::getLocal($admin_userdata, $data)->update(); $json_result = Domains::getLocal($admin_userdata, $data)->update();
$result = json_decode($json_result, true)['data']; $result = json_decode($json_result, true)['data'];
$this->assertEquals(1, $result['email_only']); $this->assertEquals(1, $result['email_only']);
$this->assertFalse(in_array('TLSv1.3', explode(",", $result['ssl_protocols'])));
}
/**
*
* @depends testAdminDomainsAdd
*/
public function testAdminDomainsUpdateIssue756()
{
global $admin_userdata;
$data = [
'domainname' => 'test.local',
'ssl_redirect' => 1
];
$json_result = Domains::getLocal($admin_userdata, $data)->update();
$result = json_decode($json_result, true)['data'];
// get ssl ip/port for domain which should still exist
$sel_stmt = Database::prepare("
SELECT COUNT(*) as numips
FROM `" . TABLE_DOMAINTOIP . "` di
LEFT JOIN `" . TABLE_PANEL_IPSANDPORTS . "` i ON i.id = di.id_ipandports
LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` d ON d.id = di.id_domain
WHERE d.id = :did AND i.ssl = 1
");
$result_ips = Database::pexecute_first($sel_stmt, [
'did' => $result['id']
], true, true);
$this->assertEquals(1, $result_ips['numips']);
// test clearing
$data = [
'domainname' => 'test.local',
'ssl_ipandport' => array()
];
$json_result = Domains::getLocal($admin_userdata, $data)->update();
$result = json_decode($json_result, true)['data'];
// get ssl ip/port for domain which should still exist
$result_ips = Database::pexecute_first($sel_stmt, [
'did' => $result['id']
], true, true);
$this->assertEquals(1, $result_ips['numips']);
$data = [
'domainname' => 'test.local',
'remove_ssl_ipandport' => 1
];
$json_result = Domains::getLocal($admin_userdata, $data)->update();
$result = json_decode($json_result, true)['data'];
// get ssl ip/port for domain which should still exist
$result_ips = Database::pexecute_first($sel_stmt, [
'did' => $result['id']
], true, true);
$this->assertEquals(0, $result_ips['numips']);
} }
/** /**
@@ -226,4 +306,22 @@ class DomainsTest extends TestCase
'loginname' => 'test3' 'loginname' => 'test3'
))->delete(); ))->delete();
} }
public function testCustomerDomainsList()
{
global $admin_userdata;
// get customer
$json_result = Customers::getLocal($admin_userdata, array(
'id' => 1
))->get();
$customer_userdata = json_decode($json_result, true)['data'];
$this->expectExceptionCode(403);
$this->expectExceptionMessage("Not allowed to execute given command.");
$json_result = Domains::getLocal($customer_userdata)->listing();
$this->expectExceptionCode(403);
$this->expectExceptionMessage("Not allowed to execute given command.");
$json_result = Domains::getLocal($customer_userdata)->listingCount();
}
} }

View File

@@ -191,6 +191,38 @@ class MailsTest extends TestCase
$this->assertEquals('other@domain.tld other2@domain.tld', $result['destination']); $this->assertEquals('other@domain.tld other2@domain.tld', $result['destination']);
} }
/**
*
* @depends testCustomerEmailForwardersAddAnother
*/
public function testCustomerEmailForwardersListing()
{
global $admin_userdata;
Settings::Set('panel.customer_hide_options', '', true);
// get customer
$json_result = Customers::getLocal($admin_userdata, array(
'loginname' => 'test1'
))->get();
$customer_userdata = json_decode($json_result, true)['data'];
$data = [
'emailaddr' => 'info@test2.local'
];
$json_result = EmailForwarders::getLocal($customer_userdata, $data)->listing();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(2, $result['count']);
$this->assertEquals(0, $result['list'][0]['id']);
$this->assertEquals('other@domain.tld', $result['list'][0]['address']);
$this->assertEquals(1, $result['list'][1]['id']);
$this->assertEquals('other2@domain.tld', $result['list'][1]['address']);
$json_result = EmailForwarders::getLocal($customer_userdata, $data)->listingCount();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(2, $result);
}
/** /**
* *
* @depends testCustomerEmailForwardersDeleteEmailHidden * @depends testCustomerEmailForwardersDeleteEmailHidden
@@ -292,13 +324,6 @@ class MailsTest extends TestCase
EmailForwarders::getLocal($admin_userdata)->update(); EmailForwarders::getLocal($admin_userdata)->update();
} }
public function testAdminEmailForwadersUndefinedListing()
{
global $admin_userdata;
$this->expectExceptionCode(303);
EmailForwarders::getLocal($admin_userdata)->listing();
}
/** /**
* *
* @depends testCustomerEmailForwardersAddAnother * @depends testCustomerEmailForwardersAddAnother
@@ -362,6 +387,10 @@ class MailsTest extends TestCase
$this->assertEquals(2, $result['count']); $this->assertEquals(2, $result['count']);
$this->assertEquals("info@test2.local", $result['list'][0]['email']); $this->assertEquals("info@test2.local", $result['list'][0]['email']);
$this->assertEquals("@test2.local", $result['list'][1]['email']); $this->assertEquals("@test2.local", $result['list'][1]['email']);
$json_result = Emails::getLocal($customer_userdata)->listingCount();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(2, $result);
} }
public function testCustomerEmailAccountsAdd() public function testCustomerEmailAccountsAdd()

View File

@@ -158,6 +158,10 @@ class DirOptionsTest extends TestCase
$result = json_decode($json_result, true)['data']; $result = json_decode($json_result, true)['data'];
$this->assertEquals(1, $result['count']); $this->assertEquals(1, $result['count']);
$this->assertEquals($customer_userdata['documentroot'] . 'test/', $result['list'][0]['path']); $this->assertEquals($customer_userdata['documentroot'] . 'test/', $result['list'][0]['path']);
$json_result = DirOptions::getLocal($admin_userdata)->listingCount();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(1, $result);
} }
/** /**

View File

@@ -175,6 +175,10 @@ class DirProtectionsTest extends TestCase
$this->assertEquals(2, $result['count']); $this->assertEquals(2, $result['count']);
$this->assertEquals('test1', $result['list'][0]['username']); $this->assertEquals('test1', $result['list'][0]['username']);
$this->assertEquals('testing', $result['list'][1]['username']); $this->assertEquals('testing', $result['list'][1]['username']);
$json_result = DirProtections::getLocal($customer_userdata)->listingCount();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(2, $result);
} }
/** /**

View File

@@ -50,7 +50,7 @@ class ValidateTest extends TestCase
public function testValidateIp() public function testValidateIp()
{ {
$result = Validate::validate_ip2("12.34.56.78", false, 'invalidip', false, false, false, true); $result = Validate::validate_ip2("12.34.56.78", false, 'invalidip', false, false, false, false, true);
$this->assertEquals("12.34.56.78", $result); $this->assertEquals("12.34.56.78", $result);
} }
@@ -58,12 +58,12 @@ class ValidateTest extends TestCase
{ {
$this->expectException("Exception"); $this->expectException("Exception");
$this->expectExceptionCode(400); $this->expectExceptionCode(400);
Validate::validate_ip2("10.0.0.1", false, 'invalidip', false, false, false, true); Validate::validate_ip2("10.0.0.1", false, 'invalidip', false, false, false, false, true);
} }
public function testValidateIpPrivNotAllowedBool() public function testValidateIpPrivNotAllowedBool()
{ {
$result = Validate::validate_ip2("10.0.0.1", true, 'invalidip', false, false, false, true); $result = Validate::validate_ip2("10.0.0.1", true, 'invalidip', false, false, false, false, true);
$this->assertFalse($result); $this->assertFalse($result);
} }
@@ -71,32 +71,63 @@ class ValidateTest extends TestCase
{ {
$this->expectException("Exception"); $this->expectException("Exception");
$this->expectExceptionCode(400); $this->expectExceptionCode(400);
Validate::validate_ip2("12.34.56.78/24", false, 'invalidip', false, false, false, true); Validate::validate_ip2("12.34.56.78/24", false, 'invalidip', false, false, false, false, true);
} }
public function testValidateIpCidrNotAllowedBool() public function testValidateIpCidrNotAllowedBool()
{ {
$result = Validate::validate_ip2("12.34.56.78/24", true, 'invalidip', false, false, false, true); $result = Validate::validate_ip2("12.34.56.78/24", true, 'invalidip', false, false, false, false, true);
$this->assertFalse($result); $this->assertFalse($result);
} }
public function testValidateIpCidr() public function testValidateIpCidr()
{ {
$result = Validate::validate_ip2("12.34.56.78/24", false, 'invalidip', false, false, true, true); $result = Validate::validate_ip2("12.34.56.78/24", false, 'invalidip', false, false, true, false, true);
$this->assertEquals("12.34.56.78/24", $result); $this->assertEquals("12.34.56.78/24", $result);
} }
public function testValidateIpv6Disallowed()
{
$this->expectException("Exception");
$this->expectExceptionCode(400);
Validate::validate_ip2("2620:0:2d0:200::7/32", false, 'invalidip', false, false, true, true, true);
}
public function testValidateIpLocalhostAllowed() public function testValidateIpLocalhostAllowed()
{ {
$result = Validate::validate_ip2("127.0.0.1/32", false, 'invalidip', true, false, true, true); $result = Validate::validate_ip2("127.0.0.1/32", false, 'invalidip', true, false, true, false, true);
$this->assertEquals("127.0.0.1/32", $result); $this->assertEquals("127.0.0.1/32", $result);
} }
public function testValidateCidrNoationToNetmaskNotationIPv4()
{
$result = Validate::validate_ip2("1.1.1.1/4", false, 'invalidip', true, false, true, true, true);
$this->assertEquals("1.1.1.1/240.0.0.0", $result);
$result = Validate::validate_ip2("8.8.8.8/18", false, 'invalidip', true, false, true, true, true);
$this->assertEquals("8.8.8.8/255.255.192.0", $result);
$result = Validate::validate_ip2("8.8.8.8/1", false, 'invalidip', true, false, true, true, true);
$this->assertEquals("8.8.8.8/128.0.0.0", $result);
}
public function testValidateIPv6()
{
$result = Validate::is_ipv6('1.1.1.1/4');
$this->assertFalse($result);
$result = Validate::is_ipv6('1.1.1.1');
$this->assertFalse($result);
$result = Validate::is_ipv6('::ffff:10.20.30.40');
$this->assertEquals('::ffff:10.20.30.40', $result);
$result = Validate::is_ipv6('2620:0:2d0:200::7/32');
$this->assertFalse($result);
$result = Validate::is_ipv6('2620:0:2d0:200::7');
$this->assertEquals('2620:0:2d0:200::7', $result);
}
public function testValidateIpLocalhostAllowedWrongIp() public function testValidateIpLocalhostAllowedWrongIp()
{ {
$this->expectException("Exception"); $this->expectException("Exception");
$this->expectExceptionCode(400); $this->expectExceptionCode(400);
Validate::validate_ip2("127.0.0.2", false, 'invalidip', true, false, false, true); Validate::validate_ip2("127.0.0.2", false, 'invalidip', true, false, false, false, true);
} }
public function testValidateUrl() public function testValidateUrl()

View File

@@ -88,6 +88,10 @@ class FtpsTest extends TestCase
$json_result = Ftps::getLocal($admin_userdata)->listing(); $json_result = Ftps::getLocal($admin_userdata)->listing();
$result = json_decode($json_result, true)['data']; $result = json_decode($json_result, true)['data'];
$this->assertEquals(2, $result['count']); $this->assertEquals(2, $result['count']);
$json_result = Ftps::getLocal($admin_userdata)->listingCount();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(2, $result);
} }
public function testAdminFtpsListSpecificCustomer() public function testAdminFtpsListSpecificCustomer()
@@ -115,6 +119,10 @@ class FtpsTest extends TestCase
$result = json_decode($json_result, true)['data']; $result = json_decode($json_result, true)['data'];
$this->assertEquals(1, $result['count']); $this->assertEquals(1, $result['count']);
$this->assertEquals('test1', $result['list'][0]['username']); $this->assertEquals('test1', $result['list'][0]['username']);
$json_result = Ftps::getLocal($reseller_userdata)->listingCount();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(1, $result);
} }
public function testCustomerFtpsList() public function testCustomerFtpsList()
@@ -129,6 +137,10 @@ class FtpsTest extends TestCase
$result = json_decode($json_result, true)['data']; $result = json_decode($json_result, true)['data'];
$this->assertEquals(1, $result['count']); $this->assertEquals(1, $result['count']);
$this->assertEquals('test1', $result['list'][0]['username']); $this->assertEquals('test1', $result['list'][0]['username']);
$json_result = Ftps::getLocal($customer_userdata)->listingCount();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(1, $result);
} }
public function testCustomerFtpsAdd() public function testCustomerFtpsAdd()
@@ -277,4 +289,21 @@ class FtpsTest extends TestCase
$result = json_decode($json_result, true)['data']; $result = json_decode($json_result, true)['data'];
$this->assertEquals('test1ftp2', $result['username']); $this->assertEquals('test1ftp2', $result['username']);
} }
public function testCustomerFtpsDeleteDefaultUser()
{
global $admin_userdata;
// get customer
$json_result = Customers::getLocal($admin_userdata, array(
'loginname' => 'test1'
))->get();
$customer_userdata = json_decode($json_result, true)['data'];
$data = [
'username' => 'test1'
];
$this->expectExceptionCode(400);
$this->expectExceptionMessage('You cannot delete your main FTP account');
Ftps::getLocal($customer_userdata, $data)->delete();
}
} }

View File

@@ -124,4 +124,63 @@ class FroxlorRpcTest extends TestCase
$this->assertEquals('listFunctions', $result['command']['method']); $this->assertEquals('listFunctions', $result['command']['method']);
$this->assertNull($result['params']); $this->assertNull($result['params']);
} }
public function testApiPhpEscaping()
{
$key = $this->generateKey();
$request = array(
'body' => [
'command' => 'Froxlor.listFunctions',
'params' => $key
]
);
$json_request = json_encode($request);
$decoded_request = json_decode($json_request, true);
$decoded_request = $this->stripcslashes_deep($decoded_request);
$this->assertEquals($key['key'], $decoded_request['body']['params']['key']);
$this->assertEquals($key['cert'], $decoded_request['body']['params']['cert']);
}
private function stripcslashes_deep($value)
{
return is_array($value) ? array_map([$this, 'stripcslashes_deep'], $value) : stripcslashes($value);
}
private function generateKey()
{
$dn = array(
"countryName" => "DE",
"stateOrProvinceName" => "Hessen",
"localityName" => "Frankfurt",
"organizationName" => "Froxlor",
"organizationalUnitName" => "Testing",
"commonName" => "test2.local",
"emailAddress" => "team@froxlor.org"
);
// generate key pair
$privkey = openssl_pkey_new(array(
"private_key_bits" => 2048,
"private_key_type" => OPENSSL_KEYTYPE_RSA
));
// generate csr
$csr = openssl_csr_new($dn, $privkey, array(
'digest_alg' => 'sha256'
));
// generate self-signed certificate
$sscert = openssl_csr_sign($csr, null, $privkey, 365, array(
'digest_alg' => 'sha256'
));
// export
openssl_x509_export($sscert, $certout);
openssl_pkey_export($privkey, $pkeyout, null);
return array(
'cert' => $certout,
'key' => $pkeyout
);
}
} }

View File

@@ -21,6 +21,10 @@ class IpsAndPortsTest extends TestCase
$result = json_decode($json_result, true)['data']; $result = json_decode($json_result, true)['data'];
$this->assertEquals(2, $result['count']); $this->assertEquals(2, $result['count']);
$this->assertEquals('82.149.225.46', $result['list'][0]['ip']); $this->assertEquals('82.149.225.46', $result['list'][0]['ip']);
$json_result = IpsAndPorts::getLocal($admin_userdata)->listingCount();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(2, $result);
} }
public function testResellerIpsAndPortsListHasNone() public function testResellerIpsAndPortsListHasNone()
@@ -107,6 +111,10 @@ class IpsAndPortsTest extends TestCase
$result = json_decode($json_result, true)['data']; $result = json_decode($json_result, true)['data'];
$this->assertEquals(1, $result['count']); $this->assertEquals(1, $result['count']);
$this->assertEquals('82.149.225.47', $result['list'][0]['ip']); $this->assertEquals('82.149.225.47', $result['list'][0]['ip']);
$json_result = IpsAndPorts::getLocal($reseller_userdata)->listingCount();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(1, $result);
} }
/** /**

View File

@@ -139,6 +139,10 @@ class MysqlsTest extends TestCase
$result = json_decode($json_result, true)['data']; $result = json_decode($json_result, true)['data'];
$this->assertEquals(1, $result['count']); $this->assertEquals(1, $result['count']);
$this->assertEquals('test1sql1', $result['list'][0]['databasename']); $this->assertEquals('test1sql1', $result['list'][0]['databasename']);
$json_result = Mysqls::getLocal($customer_userdata)->listingCount();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(1, $result);
} }
/** /**

View File

@@ -141,6 +141,10 @@ class FpmDaemonsTest extends TestCase
$this->assertEquals(2, $result['count']); $this->assertEquals(2, $result['count']);
$this->assertEquals('System default', $result['list'][0]['description']); $this->assertEquals('System default', $result['list'][0]['description']);
$this->assertEquals('test2 fpm edit', $result['list'][1]['description']); $this->assertEquals('test2 fpm edit', $result['list'][1]['description']);
$json_result = FpmDaemons::getLocal($admin_userdata)->listingCount();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(2, $result);
} }
public function testAdminFpmDaemonsGetNotFound() public function testAdminFpmDaemonsGetNotFound()
@@ -190,6 +194,10 @@ class FpmDaemonsTest extends TestCase
$this->expectExceptionCode(403); $this->expectExceptionCode(403);
$this->expectExceptionMessage("Not allowed to execute given command."); $this->expectExceptionMessage("Not allowed to execute given command.");
FpmDaemons::getLocal($customer_userdata)->listing(); FpmDaemons::getLocal($customer_userdata)->listing();
$this->expectExceptionCode(403);
$this->expectExceptionMessage("Not allowed to execute given command.");
FpmDaemons::getLocal($customer_userdata)->listingCount();
} }
public function testCustomerFpmDaemonsUpdate() public function testCustomerFpmDaemonsUpdate()

View File

@@ -23,6 +23,10 @@ class PhpSettingsText extends TestCase
$result = json_decode($json_result, true)['data']; $result = json_decode($json_result, true)['data'];
$this->assertEquals("Default Config", $result['list'][0]['description']); $this->assertEquals("Default Config", $result['list'][0]['description']);
$this->assertEquals("/usr/bin/php-cgi", $result['list'][0]['binary']); $this->assertEquals("/usr/bin/php-cgi", $result['list'][0]['binary']);
$json_result = PhpSettings::getLocal($admin_userdata)->listingCount();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(2, $result);
} }
public function testCustomerPhpSettingsListNotAllowed() public function testCustomerPhpSettingsListNotAllowed()
@@ -36,6 +40,10 @@ class PhpSettingsText extends TestCase
$this->expectExceptionCode(403); $this->expectExceptionCode(403);
$this->expectExceptionMessage("Not allowed to execute given command."); $this->expectExceptionMessage("Not allowed to execute given command.");
PhpSettings::getLocal($customer_userdata)->listing(); PhpSettings::getLocal($customer_userdata)->listing();
$this->expectExceptionCode(403);
$this->expectExceptionMessage("Not allowed to execute given command.");
PhpSettings::getLocal($customer_userdata)->listingCount();
} }
public function testAdminPhpSettingsAdd() public function testAdminPhpSettingsAdd()

View File

@@ -201,6 +201,10 @@ class SubDomainsTest extends TestCase
$json_result = SubDomains::getLocal($customer_userdata)->listing(); $json_result = SubDomains::getLocal($customer_userdata)->listing();
$result = json_decode($json_result, true)['data']; $result = json_decode($json_result, true)['data'];
$this->assertEquals(3, $result['count']); $this->assertEquals(3, $result['count']);
$json_result = SubDomains::getLocal($customer_userdata)->listingCount();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(3, $result);
} }
public function testResellerSubDomainsList() public function testResellerSubDomainsList()
@@ -215,6 +219,10 @@ class SubDomainsTest extends TestCase
$json_result = SubDomains::getLocal($reseller_userdata)->listing(); $json_result = SubDomains::getLocal($reseller_userdata)->listing();
$result = json_decode($json_result, true)['data']; $result = json_decode($json_result, true)['data'];
$this->assertEquals(3, $result['count']); $this->assertEquals(3, $result['count']);
$json_result = SubDomains::getLocal($reseller_userdata)->listingCount();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(3, $result);
} }
public function testAdminSubDomainsListWithCustomer() public function testAdminSubDomainsListWithCustomer()
@@ -225,6 +233,12 @@ class SubDomainsTest extends TestCase
])->listing(); ])->listing();
$result = json_decode($json_result, true)['data']; $result = json_decode($json_result, true)['data'];
$this->assertEquals(3, $result['count']); $this->assertEquals(3, $result['count']);
$json_result = SubDomains::getLocal($admin_userdata, [
'loginname' => 'test1'
])->listingCount();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(3, $result);
} }
/** /**

View File

@@ -79,6 +79,10 @@ class TrafficTest extends TestCase
$this->assertEquals(1, $result['count']); $this->assertEquals(1, $result['count']);
$http = 2 * (5 * 1024 * 1024 * 1024); // 2x 5 GB $http = 2 * (5 * 1024 * 1024 * 1024); // 2x 5 GB
$this->assertEquals($http, $result['list'][0]['http']); $this->assertEquals($http, $result['list'][0]['http']);
$this->expectExceptionCode(303);
$this->expectExceptionMessage("You cannot count the traffic data list");
Traffic::getLocal($admin_userdata)->listingCount();
} }
public function testAdminTrafficListSpecificDate() public function testAdminTrafficListSpecificDate()
@@ -120,6 +124,10 @@ class TrafficTest extends TestCase
$this->assertEquals(1, $result['count']); $this->assertEquals(1, $result['count']);
$mail = 250 * 1024 * 1024; // 250 MB $mail = 250 * 1024 * 1024; // 250 MB
$this->assertEquals($mail, $result['list'][0]['mail']); $this->assertEquals($mail, $result['list'][0]['mail']);
$this->expectExceptionCode(303);
$this->expectExceptionMessage("You cannot count the traffic data list");
Traffic::getLocal($admin_userdata)->listingCount();
} }
public function testAdminTrafficAdd() public function testAdminTrafficAdd()