From f6c265dfa140b14a337a49b883e56b43388193f1 Mon Sep 17 00:00:00 2001 From: Michael Kaufmann Date: Fri, 20 May 2022 15:41:06 +0200 Subject: [PATCH] re-adding the different certificate sources for domains in overview Signed-off-by: Michael Kaufmann --- lib/Froxlor/Api/Commands/Domains.php | 31 ++++++++++++ lib/Froxlor/Api/Commands/SubDomains.php | 31 ++++++++++++ lib/Froxlor/UI/Callbacks/Domain.php | 48 ++++++++++++++++--- lib/Froxlor/UI/Listing.php | 7 +++ .../admin/tablelisting.domains.php | 10 +--- .../customer/tablelisting.domains.php | 10 +--- lng/de.lng.php | 2 + lng/en.lng.php | 2 + 8 files changed, 116 insertions(+), 25 deletions(-) diff --git a/lib/Froxlor/Api/Commands/Domains.php b/lib/Froxlor/Api/Commands/Domains.php index 3aa08bb8..44cc6b4b 100644 --- a/lib/Froxlor/Api/Commands/Domains.php +++ b/lib/Froxlor/Api/Commands/Domains.php @@ -94,6 +94,7 @@ class Domains extends ApiCommand implements ResourceEntity if ($with_ips) { $row['ipsandports'] = $this->getIpsForDomain($row['id']); } + $row['domain_hascert'] = $this->getHasCertValueForDomain((int)$row['id'], (int)$row['parentdomainid']); $result[] = $row; } return $this->response([ @@ -882,6 +883,7 @@ class Domains extends ApiCommand implements ResourceEntity if ($with_ips) { $result['ipsandports'] = $this->getIpsForDomain($result['id']); } + $result['domain_hascert'] = $this->getHasCertValueForDomain((int)$result['id'], (int)$result['parentdomainid']); $this->logger()->logAction(FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] get domain '" . $result['domain'] . "'"); return $this->response($result); } @@ -891,6 +893,35 @@ class Domains extends ApiCommand implements ResourceEntity throw new Exception("Not allowed to execute given command.", 403); } + private function getHasCertValueForDomain(int $domainid, int $parentdomainid): int + { + // nothing (ssl_global) + $domain_hascert = 0; + $ssl_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` WHERE `domainid` = :domainid"); + Database::pexecute($ssl_stmt, array( + "domainid" => $domainid + )); + $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) + $domain_hascert = 1; + } else { + // check if it's parent has one set (shared) + if ($parentdomainid != 0) { + $ssl_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` WHERE `domainid` = :domainid"); + Database::pexecute($ssl_stmt, array( + "domainid" => $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) + $domain_hascert = 2; + } + } + } + return $domain_hascert; + } + /** * validate given ips * diff --git a/lib/Froxlor/Api/Commands/SubDomains.php b/lib/Froxlor/Api/Commands/SubDomains.php index 5908fed3..c1bc5447 100644 --- a/lib/Froxlor/Api/Commands/SubDomains.php +++ b/lib/Froxlor/Api/Commands/SubDomains.php @@ -478,6 +478,7 @@ class SubDomains extends ApiCommand implements ResourceEntity } $result = Database::pexecute_first($result_stmt, $params, true, true); if ($result) { + $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); } @@ -485,6 +486,35 @@ class SubDomains extends ApiCommand implements ResourceEntity throw new Exception("Subdomain with " . $key . " could not be found", 404); } + private function getHasCertValueForDomain(int $domainid, int $parentdomainid): int + { + // nothing (ssl_global) + $domain_hascert = 0; + $ssl_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` WHERE `domainid` = :domainid"); + Database::pexecute($ssl_stmt, array( + "domainid" => $domainid + )); + $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) + $domain_hascert = 1; + } else { + // check if it's parent has one set (shared) + if ($parentdomainid != 0) { + $ssl_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` WHERE `domainid` = :domainid"); + Database::pexecute($ssl_stmt, array( + "domainid" => $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) + $domain_hascert = 2; + } + } + } + return $domain_hascert; + } + /** * validate given path and replace with url if given and valid * @@ -922,6 +952,7 @@ class SubDomains extends ApiCommand implements ResourceEntity $result = []; Database::pexecute($domains_stmt, $query_fields, true, true); while ($row = $domains_stmt->fetch(PDO::FETCH_ASSOC)) { + $row['domain_hascert'] = $this->getHasCertValueForDomain((int)$row['id'], (int)$row['parentdomainid']); $result[] = $row; } return $this->response([ diff --git a/lib/Froxlor/UI/Callbacks/Domain.php b/lib/Froxlor/UI/Callbacks/Domain.php index b49a1446..1c741910 100644 --- a/lib/Froxlor/UI/Callbacks/Domain.php +++ b/lib/Froxlor/UI/Callbacks/Domain.php @@ -37,12 +37,12 @@ class Domain $linker = UI::getLinker(); $result = '' . $attributes['data'] . ''; $result .= ' (' . $attributes['fields']['loginname'] . ')'; + 'section' => 'customers', + 'page' => 'customers', + 'action' => 'su', + 'sort' => $attributes['fields']['loginname'], + 'id' => $attributes['fields']['customerid'], + ]) . '">' . $attributes['fields']['loginname'] . ')'; return $result; } @@ -143,7 +143,8 @@ class Domain public static function canEditSSL(array $attributes): bool { - if (Settings::Get('system.use_ssl') == '1' + if ( + Settings::Get('system.use_ssl') == '1' && DDomain::domainHasSslIpPort($attributes['fields']['id']) && (int)$attributes['fields']['caneditdomain'] == 1 && (int)$attributes['fields']['letsencrypt'] == 0 @@ -163,4 +164,37 @@ class Domain { return ($attributes['fields']['parentdomainid'] == 0 && empty($attributes['fields']['domainaliasid'])); } + + public static function editSSLButtons(array $attributes): array + { + $result = [ + 'icon' => 'fa fa-shield', + 'title' => lng('panel.ssleditor'), + 'href' => [ + 'section' => 'domains', + 'page' => 'domainssleditor', + 'action' => 'view', + 'id' => ':id' + ], + ]; + + // specified certificate for domain + if ($attributes['fields']['domain_hascert'] == 1) { + $result['icon'] .= ' text-success'; + } + // shared certificates (e.g. subdomain if domain where certificate is specified) + elseif ($attributes['fields']['domain_hascert'] == 2) { + $result['icon'] .= ' text-warning'; + $result['title'] .= "\n".lng('panel.ssleditor_infoshared'); + } + // no certificate specified, using global fallbacks (IPs and Ports or if empty SSL settings) + elseif ($attributes['fields']['domain_hascert'] == 0) { + $result['icon'] .= ' text-danger'; + $result['title'] .= "\n".lng('panel.ssleditor_infoglobal'); + } + + $result['visible'] = [Domain::class, 'canEditSSL']; + + return $result; + } } diff --git a/lib/Froxlor/UI/Listing.php b/lib/Froxlor/UI/Listing.php index d35fb2fb..8a125eeb 100644 --- a/lib/Froxlor/UI/Listing.php +++ b/lib/Froxlor/UI/Listing.php @@ -160,6 +160,13 @@ class Listing // Check each action for a href foreach ($actions as $key => $action) { + + // complete link built via callback + if (isset($action['callback']) && !empty($action['callback'])) { + $action = call_user_func($action['callback'], ['fields' => $item]); + $actions[$key] = $action; + } + // Call user function if visible is an array if (isset($action['visible']) && is_array($action['visible'])) { $actions[$key]['visible'] = call_user_func($action['visible'], ['fields' => $item]); diff --git a/lib/tablelisting/admin/tablelisting.domains.php b/lib/tablelisting/admin/tablelisting.domains.php index 73adfcb1..bf277f5e 100644 --- a/lib/tablelisting/admin/tablelisting.domains.php +++ b/lib/tablelisting/admin/tablelisting.domains.php @@ -172,15 +172,7 @@ return [ 'visible' => [Domain::class, 'adminCanEditDNS'] ], 'domainssleditor' => [ - 'icon' => 'fa fa-shield', - 'title' => lng('panel.ssleditor'), // @todo different certificate types by $row['domain_hascert'] - 'href' => [ - 'section' => 'domains', - 'page' => 'domainssleditor', - 'action' => 'view', - 'id' => ':id' - ], - 'visible' => [Domain::class, 'canEditSSL'] + 'callback' => [Domain::class, 'editSSLButtons'], ], 'letsencrypt' => [ 'icon' => 'fa fa-shield', diff --git a/lib/tablelisting/customer/tablelisting.domains.php b/lib/tablelisting/customer/tablelisting.domains.php index 4b46620a..280cd812 100644 --- a/lib/tablelisting/customer/tablelisting.domains.php +++ b/lib/tablelisting/customer/tablelisting.domains.php @@ -111,15 +111,7 @@ return [ 'visible' => [Domain::class, 'canEditDNS'] ], 'domainssleditor' => [ - 'icon' => 'fa fa-shield', - 'title' => lng('panel.ssleditor'), // @todo different certificate types by $row['domain_hascert'] - 'href' => [ - 'section' => 'domains', - 'page' => 'domainssleditor', - 'action' => 'view', - 'id' => ':id' - ], - 'visible' => [Domain::class, 'canEditSSL'] + 'callback' => [Domain::class, 'editSSLButtons'], ], 'letsencrypt' => [ 'icon' => 'fa fa-shield', diff --git a/lng/de.lng.php b/lng/de.lng.php index 40ad77c6..46074813 100644 --- a/lng/de.lng.php +++ b/lng/de.lng.php @@ -1132,6 +1132,8 @@ Vielen Dank, Ihr Administrator', 'variable' => 'Variable', 'description' => 'Beschreibung', 'ssleditor' => 'SSL-Einstellungen für diese Domain', + 'ssleditor_infoshared' => 'Aktuell Zertifikat der Elterndomain genutzt', + 'ssleditor_infoglobal' => 'Aktuell globales Zertifikat genutzt', 'dashboard' => 'Dashboard', 'assigned' => 'zugewiesen', 'available' => 'verfügbar', diff --git a/lng/en.lng.php b/lng/en.lng.php index 3ca32959..25e79e30 100644 --- a/lng/en.lng.php +++ b/lng/en.lng.php @@ -1495,6 +1495,8 @@ Yours sincerely, your administrator', 'description' => 'Description', 'cancel' => 'Cancel', 'ssleditor' => 'SSL settings for this domain', + 'ssleditor_infoshared' => 'Currently using certificate of parentdomain', + 'ssleditor_infoglobal' => 'Currently using global certificate', 'dashboard' => 'Dashboard', 'assigned' => 'Assigned', 'available' => 'Available',