From d3a8c8628e718f8df07b13ea0dcda83ae9e6ad14 Mon Sep 17 00:00:00 2001 From: Michael Kaufmann Date: Mon, 23 May 2022 13:50:50 +0200 Subject: [PATCH] add with_ips parameter to SubDomains.listing() and SubDomains.get(); add column ips/ports to domain tablelisting (admin and customer) Signed-off-by: Michael Kaufmann --- lib/Froxlor/Api/Commands/SubDomains.php | 47 +++++++++++++++++++ lib/Froxlor/UI/Callbacks/Domain.php | 12 +++++ .../admin/tablelisting.domains.php | 6 +++ .../customer/tablelisting.domains.php | 6 +++ 4 files changed, 71 insertions(+) diff --git a/lib/Froxlor/Api/Commands/SubDomains.php b/lib/Froxlor/Api/Commands/SubDomains.php index c1bc5447..fd58b6f3 100644 --- a/lib/Froxlor/Api/Commands/SubDomains.php +++ b/lib/Froxlor/Api/Commands/SubDomains.php @@ -410,6 +410,8 @@ class SubDomains extends ApiCommand implements ResourceEntity * optional, the domain-id * @param string $domainname * optional, the domainname + * @param bool $with_ips + * optional, default true * * @access admin, customer * @return string json-encoded array @@ -420,6 +422,7 @@ class SubDomains extends ApiCommand implements ResourceEntity $id = $this->getParam('id', true, 0); $dn_optional = $id > 0; $domainname = $this->getParam('domainname', $dn_optional, ''); + $with_ips = $this->getParam('with_ips', true, true); // convert possible idn domain to punycode if (substr($domainname, 0, 4) != 'xn--') { @@ -478,6 +481,10 @@ class SubDomains extends ApiCommand implements ResourceEntity } $result = Database::pexecute_first($result_stmt, $params, true, true); if ($result) { + $result['ipsandports'] = []; + if ($with_ips) { + $result['ipsandports'] = $this->getIpsForDomain($result['id']); + } $result['domain_hascert'] = $this->getHasCertValueForDomain((int)$result['id'], (int)$result['parentdomainid']); $this->logger()->logAction($this->isAdmin() ? FroxlorLogger::ADM_ACTION : FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] get subdomain '" . $result['domain'] . "'"); return $this->response($result); @@ -854,6 +861,8 @@ class SubDomains extends ApiCommand implements ResourceEntity /** * lists all subdomain entries * + * @param bool $with_ips + * optional, default true * @param int $customerid * optional, admin-only, select (sub)domains of a specific customer by id * @param string $loginname @@ -875,6 +884,7 @@ class SubDomains extends ApiCommand implements ResourceEntity */ public function listing() { + $with_ips = $this->getParam('with_ips', true, true); if ($this->isAdmin()) { // if we're an admin, list all subdomains of all the admins customers // or optionally for one specific customer identified by id or loginname @@ -952,6 +962,10 @@ class SubDomains extends ApiCommand implements ResourceEntity $result = []; Database::pexecute($domains_stmt, $query_fields, true, true); while ($row = $domains_stmt->fetch(PDO::FETCH_ASSOC)) { + $row['ipsandports'] = []; + if ($with_ips) { + $row['ipsandports'] = $this->getIpsForDomain($row['id']); + } $row['domain_hascert'] = $this->getHasCertValueForDomain((int)$row['id'], (int)$row['parentdomainid']); $result[] = $row; } @@ -961,6 +975,39 @@ class SubDomains extends ApiCommand implements ResourceEntity ]); } + /** + * get ips connected to given domain as array + * + * @param number $domain_id + * @param bool $ssl_only + * optional, return only ssl enabled ip's, default false + * @return array + */ + private function getIpsForDomain($domain_id = 0, $ssl_only = false) + { + $fields = '`ips`.ip, `ips`.port, `ips`.ssl'; + if ($this->isAdmin()) { + $fields = '`ips`.*'; + } + $resultips_stmt = Database::prepare(" + SELECT " . $fields . " FROM `" . TABLE_DOMAINTOIP . "` AS `dti`, `" . TABLE_PANEL_IPSANDPORTS . "` AS `ips` + WHERE `dti`.`id_ipandports` = `ips`.`id` AND `dti`.`id_domain` = :domainid " . ($ssl_only ? " AND `ips`.`ssl` = '1'" : "")); + + Database::pexecute($resultips_stmt, [ + 'domainid' => $domain_id + ]); + + $ipandports = []; + 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; + } + /** * returns the total number of accessible subdomain entries * diff --git a/lib/Froxlor/UI/Callbacks/Domain.php b/lib/Froxlor/UI/Callbacks/Domain.php index 1c741910..4fb7f60b 100644 --- a/lib/Froxlor/UI/Callbacks/Domain.php +++ b/lib/Froxlor/UI/Callbacks/Domain.php @@ -197,4 +197,16 @@ class Domain return $result; } + + public static function listIPs(array $attributes): string + { + if (isset($attributes['fields']['ipsandports']) && !empty($attributes['fields']['ipsandports'])) { + $iplist = ""; + foreach ($attributes['fields']['ipsandports'] as $ipport) { + $iplist .= $ipport['ip'].':'.$ipport['port'].'
'; + } + return $iplist; + } + return lng('panel.empty'); + } } diff --git a/lib/tablelisting/admin/tablelisting.domains.php b/lib/tablelisting/admin/tablelisting.domains.php index bf277f5e..b5ecda83 100644 --- a/lib/tablelisting/admin/tablelisting.domains.php +++ b/lib/tablelisting/admin/tablelisting.domains.php @@ -45,6 +45,12 @@ return [ 'label' => lng('domains.domainname'), 'field' => 'domain_ace', ], + 'ipsandports' => [ + 'label' => lng('admin.ipsandports.ipsandports'), + 'field' => 'ipsandports', + 'sortable' => false, + 'callback' => [Domain::class, 'listIPs'], + ], 'c.name' => [ 'label' => lng('customer.name'), 'field' => 'customer.name', diff --git a/lib/tablelisting/customer/tablelisting.domains.php b/lib/tablelisting/customer/tablelisting.domains.php index 280cd812..4e922f12 100644 --- a/lib/tablelisting/customer/tablelisting.domains.php +++ b/lib/tablelisting/customer/tablelisting.domains.php @@ -39,6 +39,12 @@ return [ 'field' => 'domain_ace', 'callback' => [Domain::class, 'domainExternalLinkInfo'], ], + 'ipsandports' => [ + 'label' => lng('admin.ipsandports.ipsandports'), + 'field' => 'ipsandports', + 'sortable' => false, + 'callback' => [Domain::class, 'listIPs'], + ], 'd.documentroot' => [ 'label' => lng('panel.path'), 'field' => 'documentroot',