From 6eb190c3733a493e01221770104b66af973aed8f Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Wed, 12 Feb 2020 22:04:54 +0800 Subject: [PATCH] Expose WebUI ban duration to users --- src/base/preferences.cpp | 12 +++++ src/base/preferences.h | 2 + src/gui/optionsdialog.cpp | 3 ++ src/gui/optionsdialog.ui | 49 ++++++++++++++------ src/webui/api/appcontroller.cpp | 3 ++ src/webui/api/authcontroller.cpp | 4 +- src/webui/www/private/views/preferences.html | 6 +++ 7 files changed, 63 insertions(+), 16 deletions(-) diff --git a/src/base/preferences.cpp b/src/base/preferences.cpp index 3e8424353..80660f17d 100644 --- a/src/base/preferences.cpp +++ b/src/base/preferences.cpp @@ -29,6 +29,8 @@ #include "preferences.h" +#include + #ifdef Q_OS_MACOS #include #endif @@ -631,6 +633,16 @@ void Preferences::setWebUIMaxAuthFailCount(const int count) setValue("Preferences/WebUI/MaxAuthenticationFailCount", count); } +std::chrono::seconds Preferences::getWebUIBanDuration() const +{ + return std::chrono::seconds {value("Preferences/WebUI/BanDuration", 3600).toInt()}; +} + +void Preferences::setWebUIBanDuration(const std::chrono::seconds duration) +{ + setValue("Preferences/WebUI/BanDuration", static_cast(duration.count())); +} + int Preferences::getWebUISessionTimeout() const { return value("Preferences/WebUI/SessionTimeout", 3600).toInt(); diff --git a/src/base/preferences.h b/src/base/preferences.h index b4d25590a..aba678a3d 100644 --- a/src/base/preferences.h +++ b/src/base/preferences.h @@ -196,6 +196,8 @@ public: void setWebUIPassword(const QByteArray &password); int getWebUIMaxAuthFailCount() const; void setWebUIMaxAuthFailCount(int count); + std::chrono::seconds getWebUIBanDuration() const; + void setWebUIBanDuration(std::chrono::seconds duration); int getWebUISessionTimeout() const; void setWebUISessionTimeout(int timeout); diff --git a/src/gui/optionsdialog.cpp b/src/gui/optionsdialog.cpp index 8df4dea70..db680ae81 100644 --- a/src/gui/optionsdialog.cpp +++ b/src/gui/optionsdialog.cpp @@ -422,6 +422,7 @@ OptionsDialog::OptionsDialog(QWidget *parent) connect(m_ui->checkBypassAuthSubnetWhitelist, &QAbstractButton::toggled, this, &ThisType::enableApplyButton); connect(m_ui->checkBypassAuthSubnetWhitelist, &QAbstractButton::toggled, m_ui->IPSubnetWhitelistButton, &QPushButton::setEnabled); connect(m_ui->spinBanCounter, qSpinBoxValueChanged, this, &ThisType::enableApplyButton); + connect(m_ui->spinBanDuration, qSpinBoxValueChanged, this, &ThisType::enableApplyButton); connect(m_ui->spinSessionTimeout, qSpinBoxValueChanged, this, &ThisType::enableApplyButton); connect(m_ui->checkClickjacking, &QCheckBox::toggled, this, &ThisType::enableApplyButton); connect(m_ui->checkCSRFProtection, &QCheckBox::toggled, this, &ThisType::enableApplyButton); @@ -772,6 +773,7 @@ void OptionsDialog::saveOptions() pref->setWebUIHttpsCertificatePath(m_ui->textWebUIHttpsCert->selectedPath()); pref->setWebUIHttpsKeyPath(m_ui->textWebUIHttpsKey->selectedPath()); pref->setWebUIMaxAuthFailCount(m_ui->spinBanCounter->value()); + pref->setWebUIBanDuration(std::chrono::seconds {m_ui->spinBanDuration->value()}); pref->setWebUISessionTimeout(m_ui->spinSessionTimeout->value()); // Authentication pref->setWebUiUsername(webUiUsername()); @@ -1156,6 +1158,7 @@ void OptionsDialog::loadOptions() m_ui->checkBypassAuthSubnetWhitelist->setChecked(pref->isWebUiAuthSubnetWhitelistEnabled()); m_ui->IPSubnetWhitelistButton->setEnabled(m_ui->checkBypassAuthSubnetWhitelist->isChecked()); m_ui->spinBanCounter->setValue(pref->getWebUIMaxAuthFailCount()); + m_ui->spinBanDuration->setValue(pref->getWebUIBanDuration().count()); m_ui->spinSessionTimeout->setValue(pref->getWebUISessionTimeout()); // Security diff --git a/src/gui/optionsdialog.ui b/src/gui/optionsdialog.ui index f46bded2d..dd0857d37 100644 --- a/src/gui/optionsdialog.ui +++ b/src/gui/optionsdialog.ui @@ -2987,25 +2987,15 @@ Specify an IPv4 or IPv6 address. You can specify "0.0.0.0" for any IPv - - + + Ban client after consecutive failures: - - - - Never - - - 2147483647 - - - - + Qt::Horizontal @@ -3018,6 +3008,39 @@ Specify an IPv4 or IPv6 address. You can specify "0.0.0.0" for any IPv + + + + Never + + + 2147483647 + + + + + + + ban for: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + sec + + + 1 + + + 2147483647 + + + diff --git a/src/webui/api/appcontroller.cpp b/src/webui/api/appcontroller.cpp index c28800445..49f5c5a72 100644 --- a/src/webui/api/appcontroller.cpp +++ b/src/webui/api/appcontroller.cpp @@ -233,6 +233,7 @@ void AppController::preferencesAction() authSubnetWhitelistStringList << Utils::Net::subnetToString(subnet); data["bypass_auth_subnet_whitelist"] = authSubnetWhitelistStringList.join("\n"); data["web_ui_max_auth_fail_count"] = pref->getWebUIMaxAuthFailCount(); + data["web_ui_ban_duration"] = static_cast(pref->getWebUIBanDuration().count()); data["web_ui_session_timeout"] = pref->getWebUISessionTimeout(); // Use alternative Web UI data["alternative_webui_enabled"] = pref->isAltWebUiEnabled(); @@ -604,6 +605,8 @@ void AppController::setPreferencesAction() } if (hasKey("web_ui_max_auth_fail_count")) pref->setWebUIMaxAuthFailCount(it.value().toInt()); + if (hasKey("web_ui_ban_duration")) + pref->setWebUIBanDuration(std::chrono::seconds {it.value().toInt()}); if (hasKey("web_ui_session_timeout")) pref->setWebUISessionTimeout(it.value().toInt()); // Use alternative Web UI diff --git a/src/webui/api/authcontroller.cpp b/src/webui/api/authcontroller.cpp index 132bb0abe..f8446145d 100644 --- a/src/webui/api/authcontroller.cpp +++ b/src/webui/api/authcontroller.cpp @@ -36,8 +36,6 @@ #include "apierror.h" #include "isessionmanager.h" -constexpr int BAN_TIME = 3600000; // 1 hour - void AuthController::loginAction() { if (sessionManager()->session()) { @@ -116,6 +114,6 @@ void AuthController::increaseFailedAttempts() if (failedLogin.failedAttemptsCount >= Preferences::instance()->getWebUIMaxAuthFailCount()) { // Max number of failed attempts reached // Start ban period - failedLogin.banTimer.setRemainingTime(BAN_TIME); + failedLogin.banTimer.setRemainingTime(Preferences::instance()->getWebUIBanDuration()); } } diff --git a/src/webui/www/private/views/preferences.html b/src/webui/www/private/views/preferences.html index 55c9e411a..8f5e1cc8a 100644 --- a/src/webui/www/private/views/preferences.html +++ b/src/webui/www/private/views/preferences.html @@ -733,6 +733,10 @@ + + + QBT_TR(seconds)QBT_TR[CONTEXT=OptionsDialog] + @@ -1725,6 +1729,7 @@ $('bypass_auth_subnet_whitelist_textarea').setProperty('value', pref.bypass_auth_subnet_whitelist); updateBypasssAuthSettings(); $('webUIMaxAuthFailCountInput').setProperty('value', pref.web_ui_max_auth_fail_count.toInt()); + $('webUIBanDurationInput').setProperty('value', pref.web_ui_ban_duration.toInt()); $('webUISessionTimeoutInput').setProperty('value', pref.web_ui_session_timeout.toInt()); // Use alternative Web UI @@ -2089,6 +2094,7 @@ settings.set('bypass_auth_subnet_whitelist_enabled', $('bypass_auth_subnet_whitelist_checkbox').getProperty('checked')); settings.set('bypass_auth_subnet_whitelist', $('bypass_auth_subnet_whitelist_textarea').getProperty('value')); settings.set('web_ui_max_auth_fail_count', $('webUIMaxAuthFailCountInput').getProperty('value')); + settings.set('web_ui_ban_duration', $('webUIBanDurationInput').getProperty('value')); settings.set('web_ui_session_timeout', $('webUISessionTimeoutInput').getProperty('value')); // Use alternative Web UI