From 284def5832121ffea409ae4eb90e2a60e07da562 Mon Sep 17 00:00:00 2001 From: Michael Kaufmann Date: Sun, 7 Jan 2024 10:23:02 +0100 Subject: [PATCH] add gui_access flag to admins and customers to allow/disallow login to the webui; fixes #1219 Signed-off-by: Michael Kaufmann --- index.php | 61 +++++++++++++------ install/froxlor.sql.php | 2 + install/updates/froxlor/update_2.2.inc.php | 4 ++ lib/Froxlor/Api/Commands/Admins.php | 11 ++++ lib/Froxlor/Api/Commands/Customers.php | 10 +++ .../admin/admin/formfield.admin_add.php | 9 ++- .../admin/admin/formfield.admin_edit.php | 10 ++- .../admin/customer/formfield.customer_add.php | 7 +++ .../customer/formfield.customer_edit.php | 7 +++ .../customer/tablelisting.emails.php | 8 +-- lng/de.lng.php | 8 ++- lng/en.lng.php | 4 ++ 12 files changed, 113 insertions(+), 28 deletions(-) diff --git a/index.php b/index.php index 5cccab8f86..d3e9b76d29 100644 --- a/index.php +++ b/index.php @@ -165,27 +165,33 @@ $loginname = Validate::validate($_POST['loginname'], 'loginname'); $password = Validate::validate($_POST['password'], 'password'); - $stmt = Database::prepare("SELECT `loginname` AS `customer` FROM `" . TABLE_PANEL_CUSTOMERS . "` - WHERE `loginname`= :loginname"); + $stmt = Database::prepare(" + SELECT `loginname` AS `customer` + FROM `" . TABLE_PANEL_CUSTOMERS . "` + WHERE `loginname`= :loginname + AND `gui_access` = 1 + "); Database::pexecute($stmt, [ "loginname" => $loginname ]); $row = $stmt->fetch(PDO::FETCH_ASSOC); + $is_admin = false; if ($row && $row['customer'] == $loginname) { $table = "`" . TABLE_PANEL_CUSTOMERS . "`"; $uid = 'customerid'; $adminsession = '0'; - $is_admin = false; } else { - $is_admin = true; if ((int)Settings::Get('login.domain_login') == 1) { $domainname = $idna_convert->encode(preg_replace([ '/\:(\d)+$/', '/^https?\:\/\//' ], '', $loginname)); - $stmt = Database::prepare("SELECT `customerid` FROM `" . TABLE_PANEL_DOMAINS . "` - WHERE `domain` = :domain"); + $stmt = Database::prepare(" + SELECT `customerid` + FROM `" . TABLE_PANEL_DOMAINS . "` + WHERE `domain` = :domain + "); Database::pexecute($stmt, [ "domain" => $domainname ]); @@ -194,8 +200,11 @@ if (isset($row2['customerid']) && $row2['customerid'] > 0) { $loginname = Customer::getCustomerDetail($row2['customerid'], 'loginname'); if ($loginname !== false) { - $stmt = Database::prepare("SELECT `loginname` AS `customer` FROM `" . TABLE_PANEL_CUSTOMERS . "` - WHERE `loginname`= :loginname"); + $stmt = Database::prepare(" + SELECT `loginname` AS `customer` + FROM `" . TABLE_PANEL_CUSTOMERS . "` + WHERE `loginname`= :loginname + "); Database::pexecute($stmt, [ "loginname" => $loginname ]); @@ -204,10 +213,11 @@ $table = "`" . TABLE_PANEL_CUSTOMERS . "`"; $uid = 'customerid'; $adminsession = '0'; - $is_admin = false; } } } + } else { + $is_admin = true; } } @@ -218,9 +228,11 @@ if ($is_admin) { if (Froxlor::hasUpdates() || Froxlor::hasDbUpdates()) { - $stmt = Database::prepare("SELECT `loginname` AS `admin` FROM `" . TABLE_PANEL_ADMINS . "` + $stmt = Database::prepare(" + SELECT `loginname` AS `admin` FROM `" . TABLE_PANEL_ADMINS . "` WHERE `loginname`= :loginname - AND `change_serversettings` = '1'"); + AND `change_serversettings` = '1' + "); Database::pexecute($stmt, [ "loginname" => $loginname ]); @@ -231,8 +243,12 @@ exit(); } } else { - $stmt = Database::prepare("SELECT `loginname` AS `admin` FROM `" . TABLE_PANEL_ADMINS . "` - WHERE `loginname`= :loginname"); + $stmt = Database::prepare(" + SELECT `loginname` AS `admin` + FROM `" . TABLE_PANEL_ADMINS . "` + WHERE `loginname`= :loginname + AND `gui_access` = 1 + "); Database::pexecute($stmt, [ "loginname" => $loginname ]); @@ -257,8 +273,9 @@ } } - $userinfo_stmt = Database::prepare("SELECT * FROM $table - WHERE `loginname`= :loginname"); + $userinfo_stmt = Database::prepare(" + SELECT * FROM $table WHERE `loginname`= :loginname + "); Database::pexecute($userinfo_stmt, [ "loginname" => $loginname ]); @@ -281,9 +298,11 @@ } else { // login correct // reset loginfail_counter, set lastlogin_succ - $stmt = Database::prepare("UPDATE $table - SET `lastlogin_succ`= :lastlogin_succ, `loginfail_count`='0' - WHERE `$uid`= :uid"); + $stmt = Database::prepare(" + UPDATE $table + SET `lastlogin_succ`= :lastlogin_succ, `loginfail_count`='0' + WHERE `$uid`= :uid + "); Database::pexecute($stmt, [ "lastlogin_succ" => time(), "uid" => $userinfo[$uid] @@ -293,9 +312,11 @@ } } else { // login incorrect - $stmt = Database::prepare("UPDATE $table + $stmt = Database::prepare(" + UPDATE $table SET `lastlogin_fail`= :lastlogin_fail, `loginfail_count`=`loginfail_count`+1 - WHERE `$uid`= :uid"); + WHERE `$uid`= :uid + "); Database::pexecute($stmt, [ "lastlogin_fail" => time(), "uid" => $userinfo[$uid] diff --git a/install/froxlor.sql.php b/install/froxlor.sql.php index f5d9517da4..c58a59f7ad 100644 --- a/install/froxlor.sql.php +++ b/install/froxlor.sql.php @@ -159,6 +159,7 @@ `type_2fa` tinyint(1) NOT NULL default '0', `data_2fa` varchar(25) NOT NULL default '', `api_allowed` tinyint(1) NOT NULL default '1', + `gui_access` tinyint(1) NOT NULL default '1', PRIMARY KEY (`adminid`), UNIQUE KEY `loginname` (`loginname`) ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci ROW_FORMAT=DYNAMIC; @@ -227,6 +228,7 @@ `api_allowed` tinyint(1) NOT NULL default '1', `logviewenabled` tinyint(1) NOT NULL default '0', `allowed_mysqlserver` text NOT NULL, + `gui_access` tinyint(1) NOT NULL default '1', PRIMARY KEY (`customerid`), UNIQUE KEY `loginname` (`loginname`) ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci ROW_FORMAT=DYNAMIC; diff --git a/install/updates/froxlor/update_2.2.inc.php b/install/updates/froxlor/update_2.2.inc.php index 62913e12f2..4b1a63094c 100644 --- a/install/updates/froxlor/update_2.2.inc.php +++ b/install/updates/froxlor/update_2.2.inc.php @@ -77,6 +77,10 @@ Update::lastStepStatus(1, '!!!'); } + Update::showUpdateStep("Enhancing admin and user table"); + Database::query("ALTER TABLE `" . TABLE_PANEL_ADMINS . "` ADD `gui_access` tinyint(1) NOT NULL default '1';"); + Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` ADD `gui_access` tinyint(1) NOT NULL default '1';"); + Update::lastStepStatus(0); $to_clean = [ 'actions/admin/settings/180.dkim.php', diff --git a/lib/Froxlor/Api/Commands/Admins.php b/lib/Froxlor/Api/Commands/Admins.php index 8f919a9cf8..3460061732 100644 --- a/lib/Froxlor/Api/Commands/Admins.php +++ b/lib/Froxlor/Api/Commands/Admins.php @@ -146,6 +146,8 @@ public function listingCount() * optional, default auto-generated * @param string $def_language * optional, default is system-default language + * @param bool $gui_access + * optional, allow login via webui, if false ONLY the login via webui is disallowed; default true * @param bool $api_allowed * optional, default is true if system setting api.enabled is true, else false * @param string $custom_notes @@ -219,6 +221,7 @@ public function add() // parameters $def_language = $this->getParam('def_language', true, Settings::Get('panel.standardlanguage')); + $gui_access = $this->getBoolParam('gui_access', true, true); $api_allowed = $this->getBoolParam('api_allowed', true, Settings::Get('api.enabled')); $custom_notes = $this->getParam('custom_notes', true, ''); $custom_notes_show = $this->getBoolParam('custom_notes_show', true, 0); @@ -316,6 +319,7 @@ public function add() 'name' => $name, 'email' => $email, 'lang' => $def_language, + 'gui_access' => $gui_access, 'api_allowed' => $api_allowed, 'change_serversettings' => $change_serversettings, 'customers' => $customers, @@ -344,6 +348,7 @@ public function add() `name` = :name, `email` = :email, `def_language` = :lang, + `gui_access` = :gui_access, `api_allowed` = :api_allowed, `change_serversettings` = :change_serversettings, `customers` = :customers, @@ -431,6 +436,8 @@ public function get() * optional, default auto-generated * @param string $def_language * optional, default is system-default language + * @param bool $gui_access + * * optional, allow login via webui, if false ONLY the login via webui is disallowed; default true * @param bool $api_allowed * optional, default is true if system setting api.enabled is true, else false * @param string $custom_notes @@ -524,6 +531,7 @@ public function update() // you cannot edit some of the details of yourself if ($result['adminid'] == $this->getUserDetail('adminid')) { + $gui_access = $result['gui_access']; $api_allowed = $result['api_allowed']; $deactivated = $result['deactivated']; $customers = $result['customers']; @@ -542,6 +550,7 @@ public function update() $traffic = $result['traffic']; $ipaddress = ($result['ip'] != -1 ? json_decode($result['ip'], true) : -1); } else { + $gui_access = $this->getBoolParam('gui_access', true, $result['gui_access']); $api_allowed = $this->getBoolParam('api_allowed', true, $result['api_allowed']); $deactivated = $this->getBoolParam('deactivated', true, $result['deactivated']); @@ -665,6 +674,7 @@ public function update() 'name' => $name, 'email' => $email, 'lang' => $def_language, + 'gui_access' => $gui_access, 'api_allowed' => $api_allowed, 'change_serversettings' => $change_serversettings, 'customers' => $customers, @@ -694,6 +704,7 @@ public function update() `name` = :name, `email` = :email, `def_language` = :lang, + `gui_access` = :gui_access, `api_allowed` = :api_allowed, `change_serversettings` = :change_serversettings, `customers` = :customers, diff --git a/lib/Froxlor/Api/Commands/Customers.php b/lib/Froxlor/Api/Commands/Customers.php index e6cb2c0f48..240daf21d2 100644 --- a/lib/Froxlor/Api/Commands/Customers.php +++ b/lib/Froxlor/Api/Commands/Customers.php @@ -191,6 +191,8 @@ public function listingCount() * optional * @param string $def_language , * optional, default is system-default language + * @param bool $gui_access + * optional, allow login via webui, if false ONLY the login via webui is disallowed; default true * @param bool $api_allowed * optional, default is true if system setting api.enabled is true, else false * @param int $gender @@ -297,6 +299,7 @@ public function add() $fax = $this->getParam('fax', true, ''); $customernumber = $this->getParam('customernumber', true, ''); $def_language = $this->getParam('def_language', true, Settings::Get('panel.standardlanguage')); + $gui_access = $this->getBoolParam('gui_access', true, 1); $api_allowed = $this->getBoolParam('api_allowed', true, (Settings::Get('api.enabled') && Settings::Get('api.customer_default'))); $gender = (int)$this->getParam('gender', true, 0); $custom_notes = $this->getParam('custom_notes', true, ''); @@ -515,6 +518,7 @@ public function add() 'email' => $email, 'customerno' => $customernumber, 'lang' => $def_language, + 'gui_access' => $gui_access, 'api_allowed' => $api_allowed, 'docroot' => $documentroot, 'guid' => $guid, @@ -557,6 +561,7 @@ public function add() `email` = :email, `customernumber` = :customerno, `def_language` = :lang, + `gui_access` = :gui_access, `api_allowed` = :api_allowed, `documentroot` = :docroot, `guid` = :guid, @@ -948,6 +953,8 @@ public static function increaseUsage($customerid = 0, $resource = null, $extra = * optional * @param string $def_language , * optional, default is system-default language + * @param bool $gui_access + * optional, allow login via webui, if false ONLY the login via webui is disallowed; default true * @param bool $api_allowed * optional, default is true if system setting api.enabled is true, else false * @param int $gender @@ -1062,6 +1069,7 @@ public function update() $fax = $this->getParam('fax', true, $result['fax']); $customernumber = $this->getParam('customernumber', true, $result['customernumber']); $def_language = $this->getParam('def_language', true, $result['def_language']); + $gui_access = $this->getBoolParam('gui_access', true, $result['gui_access']); $api_allowed = $this->getBoolParam('api_allowed', true, $result['api_allowed']); $gender = (int)$this->getParam('gender', true, $result['gender']); $custom_notes = $this->getParam('custom_notes', true, $result['custom_notes']); @@ -1396,6 +1404,7 @@ public function update() 'logviewenabled' => $logviewenabled, 'custom_notes' => $custom_notes, 'custom_notes_show' => $custom_notes_show, + 'gui_access' => $gui_access, 'api_allowed' => $api_allowed, 'allowed_mysqlserver' => empty($allowed_mysqlserver) ? "" : json_encode($allowed_mysqlserver) ]; @@ -1439,6 +1448,7 @@ public function update() `logviewenabled` = :logviewenabled, `custom_notes` = :custom_notes, `custom_notes_show` = :custom_notes_show, + `gui_access` = :gui_access, `api_allowed` = :api_allowed, `allowed_mysqlserver` = :allowed_mysqlserver"; $upd_query .= $admin_upd_query; diff --git a/lib/formfields/admin/admin/formfield.admin_add.php b/lib/formfields/admin/admin/formfield.admin_add.php index 71a428b38a..632ba58c54 100644 --- a/lib/formfields/admin/admin/formfield.admin_add.php +++ b/lib/formfields/admin/admin/formfield.admin_add.php @@ -64,6 +64,13 @@ 'selected' => $userinfo['language'] ], + 'gui_access' => [ + 'label' => lng('usersettings.gui_access.title'), + 'desc' => lng('usersettings.gui_access.description'), + 'type' => 'checkbox', + 'value' => '1', + 'checked' => 1, + ], 'api_allowed' => [ 'label' => lng('usersettings.api_allowed.title'), 'desc' => lng('usersettings.api_allowed.description'), @@ -71,7 +78,7 @@ 'value' => '1', 'checked' => Settings::Get('api.enabled') == '1', 'visible' => Settings::Get('api.enabled') == '1' - ] + ], ] ], 'section_b' => [ diff --git a/lib/formfields/admin/admin/formfield.admin_edit.php b/lib/formfields/admin/admin/formfield.admin_edit.php index ef15245d16..b9ad3c0cb5 100644 --- a/lib/formfields/admin/admin/formfield.admin_edit.php +++ b/lib/formfields/admin/admin/formfield.admin_edit.php @@ -71,6 +71,14 @@ 'selected' => $result['def_language'], 'visible' => $result['adminid'] != $userinfo['userid'] ], + 'gui_access' => [ + 'label' => lng('usersettings.gui_access.title'), + 'desc' => lng('usersettings.gui_access.description'), + 'type' => 'checkbox', + 'value' => '1', + 'checked' => $result['gui_access'], + 'visible' => $result['adminid'] != $userinfo['userid'] + ], 'api_allowed' => [ 'label' => lng('usersettings.api_allowed.title'), 'desc' => lng('usersettings.api_allowed.description'), @@ -78,7 +86,7 @@ 'value' => '1', 'checked' => $result['api_allowed'], 'visible' => Settings::Get('api.enabled') == '1' - ] + ], ] ], 'section_b' => [ diff --git a/lib/formfields/admin/customer/formfield.customer_add.php b/lib/formfields/admin/customer/formfield.customer_add.php index 6fb740a582..aca33e2526 100644 --- a/lib/formfields/admin/customer/formfield.customer_add.php +++ b/lib/formfields/admin/customer/formfield.customer_add.php @@ -82,6 +82,13 @@ 'select_var' => Language::getLanguages(), 'selected' => Settings::Get('panel.standardlanguage') ], + 'gui_access' => [ + 'label' => lng('usersettings.gui_access.title'), + 'desc' => lng('usersettings.gui_access.description'), + 'type' => 'checkbox', + 'value' => '1', + 'checked' => 1 + ], 'api_allowed' => [ 'label' => lng('usersettings.api_allowed.title'), 'desc' => lng('usersettings.api_allowed.description'), diff --git a/lib/formfields/admin/customer/formfield.customer_edit.php b/lib/formfields/admin/customer/formfield.customer_edit.php index a6ce7c571b..0c1639bf85 100644 --- a/lib/formfields/admin/customer/formfield.customer_edit.php +++ b/lib/formfields/admin/customer/formfield.customer_edit.php @@ -80,6 +80,13 @@ 'select_var' => Language::getLanguages(), 'selected' => $result['def_language'] ], + 'gui_access' => [ + 'label' => lng('usersettings.gui_access.title'), + 'desc' => lng('usersettings.gui_access.description'), + 'type' => 'checkbox', + 'value' => '1', + 'checked' => $result['gui_access'], + ], 'api_allowed' => [ 'label' => lng('usersettings.api_allowed.title'), 'desc' => lng('usersettings.api_allowed.description'), diff --git a/lib/tablelisting/customer/tablelisting.emails.php b/lib/tablelisting/customer/tablelisting.emails.php index 64243b015c..1b9da26c7b 100644 --- a/lib/tablelisting/customer/tablelisting.emails.php +++ b/lib/tablelisting/customer/tablelisting.emails.php @@ -50,20 +50,20 @@ 'callback' => [Email::class, 'account'], ], 'm.spam_tag_level' => [ - 'label' => lng('emails.spam_tag_level'), + 'label' => lng('antispam.spam_tag_level.title'), 'field' => 'spam_tag_level', ], 'm.spam_kill_level' => [ - 'label' => lng('emails.spam_kill_level'), + 'label' => lng('antispam.spam_kill_level.title'), 'field' => 'spam_kill_level', ], 'm.bypass_spam' => [ - 'label' => lng('emails.bypass_spam'), + 'label' => lng('antispam.bypass_spam.title'), 'field' => 'bypass_spam', 'callback' => [Text::class, 'boolean'], ], 'm.policy_greylist' => [ - 'label' => lng('emails.policy_greylist'), + 'label' => lng('antispam.policy_greylist.title'), 'field' => 'policy_greylist', 'callback' => [Text::class, 'boolean'], ], diff --git a/lng/de.lng.php b/lng/de.lng.php index b11edeeb67..b4c84075f6 100644 --- a/lng/de.lng.php +++ b/lng/de.lng.php @@ -613,11 +613,11 @@ 'description' => 'Achtung: Änderungen sind nur für neue Schlüssel gültig.

Erfordert einen speziellen DNS Eintrag für die Domain. Wenn das Nameserver-Feature nicht genutzt wird, muss dieser Eintrag manuell verwaltet werden.', ], 'spam_tag_level' => [ - 'title' => 'Spam Markierungs-Level', + 'title' => 'Spam Level', 'description' => 'Erforderliche Punktzahl zum Markieren einer E-Mail als Spam
Standard: 7.0' ], 'spam_kill_level' => [ - 'title' => 'Spam Ignorier-Level', + 'title' => 'Ablehnungs Level', 'description' => 'Erforderliche Punktzahl für das Ablehnen einer E-Mail
Standard: 14.0' ], 'bypass_spam' => [ @@ -2231,6 +2231,10 @@ 'description' => 'Wenn in den Einstellungen aktiviert, kann der Benutzer API Schlüssel erstellen und auf die froxlor API Zugreifen', 'notice' => 'API Zugriff ist für dieses Konto deaktiviert.', ], + 'gui_access' => [ + 'title' => 'WebUI-Anmeldung zulassen', + 'description' => 'Wenn diese Option deaktiviert ist, kann sich der Benutzer nicht bei der Froxlor-Weboberfläche anmelden, aber alle Dienste (Web, FTP, E-Mail, Datenbanken, API-Zugriff, usw.) funktionieren normal.', + ], ], 'install' => [ 'preflight' => 'System-Prüfung', diff --git a/lng/en.lng.php b/lng/en.lng.php index 1fa58d9107..c7b82410ec 100644 --- a/lng/en.lng.php +++ b/lng/en.lng.php @@ -2366,6 +2366,10 @@ 'description' => 'When enabled in the settings, this user can create API keys and access the froxlor API', 'notice' => 'API access is not allowed for your account.', ], + 'gui_access' => [ + 'title' => 'Allow WebUI login', + 'description' => 'When disabled, the user cannot log in to the froxlor web-ui but all the services (web, ftp, mail, databases, api-access, etc.) will work normally.', + ], ], 'install' => [ 'slogan' => 'froxlor Server Management Panel',