mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2026-01-02 05:38:06 -06:00
committed by
GitHub
parent
28b5d7230c
commit
0f40fad74d
@@ -92,7 +92,7 @@ void AppController::buildInfoAction()
|
||||
void AppController::shutdownAction()
|
||||
{
|
||||
// Special handling for shutdown, we
|
||||
// need to reply to the Web UI before
|
||||
// need to reply to the WebUI before
|
||||
// actually shutting down.
|
||||
QTimer::singleShot(100ms, Qt::CoarseTimer, qApp, []
|
||||
{
|
||||
@@ -275,33 +275,33 @@ void AppController::preferencesAction()
|
||||
data[u"add_trackers_enabled"_s] = session->isAddTrackersEnabled();
|
||||
data[u"add_trackers"_s] = session->additionalTrackers();
|
||||
|
||||
// Web UI
|
||||
// WebUI
|
||||
// HTTP Server
|
||||
data[u"web_ui_domain_list"_s] = pref->getServerDomains();
|
||||
data[u"web_ui_address"_s] = pref->getWebUiAddress();
|
||||
data[u"web_ui_port"_s] = pref->getWebUiPort();
|
||||
data[u"web_ui_address"_s] = pref->getWebUIAddress();
|
||||
data[u"web_ui_port"_s] = pref->getWebUIPort();
|
||||
data[u"web_ui_upnp"_s] = pref->useUPnPForWebUIPort();
|
||||
data[u"use_https"_s] = pref->isWebUiHttpsEnabled();
|
||||
data[u"use_https"_s] = pref->isWebUIHttpsEnabled();
|
||||
data[u"web_ui_https_cert_path"_s] = pref->getWebUIHttpsCertificatePath().toString();
|
||||
data[u"web_ui_https_key_path"_s] = pref->getWebUIHttpsKeyPath().toString();
|
||||
// Authentication
|
||||
data[u"web_ui_username"_s] = pref->getWebUiUsername();
|
||||
data[u"bypass_local_auth"_s] = !pref->isWebUiLocalAuthEnabled();
|
||||
data[u"bypass_auth_subnet_whitelist_enabled"_s] = pref->isWebUiAuthSubnetWhitelistEnabled();
|
||||
data[u"web_ui_username"_s] = pref->getWebUIUsername();
|
||||
data[u"bypass_local_auth"_s] = !pref->isWebUILocalAuthEnabled();
|
||||
data[u"bypass_auth_subnet_whitelist_enabled"_s] = pref->isWebUIAuthSubnetWhitelistEnabled();
|
||||
QStringList authSubnetWhitelistStringList;
|
||||
for (const Utils::Net::Subnet &subnet : asConst(pref->getWebUiAuthSubnetWhitelist()))
|
||||
for (const Utils::Net::Subnet &subnet : asConst(pref->getWebUIAuthSubnetWhitelist()))
|
||||
authSubnetWhitelistStringList << Utils::Net::subnetToString(subnet);
|
||||
data[u"bypass_auth_subnet_whitelist"_s] = authSubnetWhitelistStringList.join(u'\n');
|
||||
data[u"web_ui_max_auth_fail_count"_s] = pref->getWebUIMaxAuthFailCount();
|
||||
data[u"web_ui_ban_duration"_s] = static_cast<int>(pref->getWebUIBanDuration().count());
|
||||
data[u"web_ui_session_timeout"_s] = pref->getWebUISessionTimeout();
|
||||
// Use alternative Web UI
|
||||
data[u"alternative_webui_enabled"_s] = pref->isAltWebUiEnabled();
|
||||
data[u"alternative_webui_path"_s] = pref->getWebUiRootFolder().toString();
|
||||
// Use alternative WebUI
|
||||
data[u"alternative_webui_enabled"_s] = pref->isAltWebUIEnabled();
|
||||
data[u"alternative_webui_path"_s] = pref->getWebUIRootFolder().toString();
|
||||
// Security
|
||||
data[u"web_ui_clickjacking_protection_enabled"_s] = pref->isWebUiClickjackingProtectionEnabled();
|
||||
data[u"web_ui_csrf_protection_enabled"_s] = pref->isWebUiCSRFProtectionEnabled();
|
||||
data[u"web_ui_secure_cookie_enabled"_s] = pref->isWebUiSecureCookieEnabled();
|
||||
data[u"web_ui_clickjacking_protection_enabled"_s] = pref->isWebUIClickjackingProtectionEnabled();
|
||||
data[u"web_ui_csrf_protection_enabled"_s] = pref->isWebUICSRFProtectionEnabled();
|
||||
data[u"web_ui_secure_cookie_enabled"_s] = pref->isWebUISecureCookieEnabled();
|
||||
data[u"web_ui_host_header_validation_enabled"_s] = pref->isWebUIHostHeaderValidationEnabled();
|
||||
// Custom HTTP headers
|
||||
data[u"web_ui_use_custom_http_headers_enabled"_s] = pref->isWebUICustomHTTPHeadersEnabled();
|
||||
@@ -788,35 +788,35 @@ void AppController::setPreferencesAction()
|
||||
if (hasKey(u"add_trackers"_s))
|
||||
session->setAdditionalTrackers(it.value().toString());
|
||||
|
||||
// Web UI
|
||||
// WebUI
|
||||
// HTTP Server
|
||||
if (hasKey(u"web_ui_domain_list"_s))
|
||||
pref->setServerDomains(it.value().toString());
|
||||
if (hasKey(u"web_ui_address"_s))
|
||||
pref->setWebUiAddress(it.value().toString());
|
||||
pref->setWebUIAddress(it.value().toString());
|
||||
if (hasKey(u"web_ui_port"_s))
|
||||
pref->setWebUiPort(it.value().value<quint16>());
|
||||
pref->setWebUIPort(it.value().value<quint16>());
|
||||
if (hasKey(u"web_ui_upnp"_s))
|
||||
pref->setUPnPForWebUIPort(it.value().toBool());
|
||||
if (hasKey(u"use_https"_s))
|
||||
pref->setWebUiHttpsEnabled(it.value().toBool());
|
||||
pref->setWebUIHttpsEnabled(it.value().toBool());
|
||||
if (hasKey(u"web_ui_https_cert_path"_s))
|
||||
pref->setWebUIHttpsCertificatePath(Path(it.value().toString()));
|
||||
if (hasKey(u"web_ui_https_key_path"_s))
|
||||
pref->setWebUIHttpsKeyPath(Path(it.value().toString()));
|
||||
// Authentication
|
||||
if (hasKey(u"web_ui_username"_s))
|
||||
pref->setWebUiUsername(it.value().toString());
|
||||
pref->setWebUIUsername(it.value().toString());
|
||||
if (hasKey(u"web_ui_password"_s))
|
||||
pref->setWebUIPassword(Utils::Password::PBKDF2::generate(it.value().toByteArray()));
|
||||
if (hasKey(u"bypass_local_auth"_s))
|
||||
pref->setWebUiLocalAuthEnabled(!it.value().toBool());
|
||||
pref->setWebUILocalAuthEnabled(!it.value().toBool());
|
||||
if (hasKey(u"bypass_auth_subnet_whitelist_enabled"_s))
|
||||
pref->setWebUiAuthSubnetWhitelistEnabled(it.value().toBool());
|
||||
pref->setWebUIAuthSubnetWhitelistEnabled(it.value().toBool());
|
||||
if (hasKey(u"bypass_auth_subnet_whitelist"_s))
|
||||
{
|
||||
// recognize new lines and commas as delimiters
|
||||
pref->setWebUiAuthSubnetWhitelist(it.value().toString().split(QRegularExpression(u"\n|,"_s), Qt::SkipEmptyParts));
|
||||
pref->setWebUIAuthSubnetWhitelist(it.value().toString().split(QRegularExpression(u"\n|,"_s), Qt::SkipEmptyParts));
|
||||
}
|
||||
if (hasKey(u"web_ui_max_auth_fail_count"_s))
|
||||
pref->setWebUIMaxAuthFailCount(it.value().toInt());
|
||||
@@ -824,18 +824,18 @@ void AppController::setPreferencesAction()
|
||||
pref->setWebUIBanDuration(std::chrono::seconds {it.value().toInt()});
|
||||
if (hasKey(u"web_ui_session_timeout"_s))
|
||||
pref->setWebUISessionTimeout(it.value().toInt());
|
||||
// Use alternative Web UI
|
||||
// Use alternative WebUI
|
||||
if (hasKey(u"alternative_webui_enabled"_s))
|
||||
pref->setAltWebUiEnabled(it.value().toBool());
|
||||
pref->setAltWebUIEnabled(it.value().toBool());
|
||||
if (hasKey(u"alternative_webui_path"_s))
|
||||
pref->setWebUiRootFolder(Path(it.value().toString()));
|
||||
pref->setWebUIRootFolder(Path(it.value().toString()));
|
||||
// Security
|
||||
if (hasKey(u"web_ui_clickjacking_protection_enabled"_s))
|
||||
pref->setWebUiClickjackingProtectionEnabled(it.value().toBool());
|
||||
pref->setWebUIClickjackingProtectionEnabled(it.value().toBool());
|
||||
if (hasKey(u"web_ui_csrf_protection_enabled"_s))
|
||||
pref->setWebUiCSRFProtectionEnabled(it.value().toBool());
|
||||
pref->setWebUICSRFProtectionEnabled(it.value().toBool());
|
||||
if (hasKey(u"web_ui_secure_cookie_enabled"_s))
|
||||
pref->setWebUiSecureCookieEnabled(it.value().toBool());
|
||||
pref->setWebUISecureCookieEnabled(it.value().toBool());
|
||||
if (hasKey(u"web_ui_host_header_validation_enabled"_s))
|
||||
pref->setWebUIHostHeaderValidationEnabled(it.value().toBool());
|
||||
// Custom HTTP headers
|
||||
|
||||
@@ -43,6 +43,16 @@ AuthController::AuthController(ISessionManager *sessionManager, IApplication *ap
|
||||
{
|
||||
}
|
||||
|
||||
void AuthController::setUsername(const QString &username)
|
||||
{
|
||||
m_username = username;
|
||||
}
|
||||
|
||||
void AuthController::setPasswordHash(const QByteArray &passwordHash)
|
||||
{
|
||||
m_passwordHash = passwordHash;
|
||||
}
|
||||
|
||||
void AuthController::loginAction()
|
||||
{
|
||||
if (m_sessionManager->session())
|
||||
@@ -51,9 +61,9 @@ void AuthController::loginAction()
|
||||
return;
|
||||
}
|
||||
|
||||
const QString clientAddr {m_sessionManager->clientId()};
|
||||
const QString usernameFromWeb {params()[u"username"_s]};
|
||||
const QString passwordFromWeb {params()[u"password"_s]};
|
||||
const QString clientAddr = m_sessionManager->clientId();
|
||||
const QString usernameFromWeb = params()[u"username"_s];
|
||||
const QString passwordFromWeb = params()[u"password"_s];
|
||||
|
||||
if (isBanned())
|
||||
{
|
||||
@@ -61,15 +71,11 @@ void AuthController::loginAction()
|
||||
.arg(clientAddr, usernameFromWeb)
|
||||
, Log::WARNING);
|
||||
throw APIError(APIErrorType::AccessDenied
|
||||
, tr("Your IP address has been banned after too many failed authentication attempts."));
|
||||
, tr("Your IP address has been banned after too many failed authentication attempts."));
|
||||
}
|
||||
|
||||
const Preferences *pref = Preferences::instance();
|
||||
|
||||
const QString username {pref->getWebUiUsername()};
|
||||
const QByteArray secret {pref->getWebUIPassword()};
|
||||
const bool usernameEqual = Utils::Password::slowEquals(usernameFromWeb.toUtf8(), username.toUtf8());
|
||||
const bool passwordEqual = Utils::Password::PBKDF2::verify(secret, passwordFromWeb);
|
||||
const bool usernameEqual = Utils::Password::slowEquals(usernameFromWeb.toUtf8(), m_username.toUtf8());
|
||||
const bool passwordEqual = Utils::Password::PBKDF2::verify(m_passwordHash, passwordFromWeb);
|
||||
|
||||
if (usernameEqual && passwordEqual)
|
||||
{
|
||||
|
||||
@@ -28,8 +28,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QDeadlineTimer>
|
||||
#include <QHash>
|
||||
#include <QString>
|
||||
|
||||
#include "apicontroller.h"
|
||||
|
||||
@@ -45,6 +47,9 @@ class AuthController : public APIController
|
||||
public:
|
||||
explicit AuthController(ISessionManager *sessionManager, IApplication *app, QObject *parent = nullptr);
|
||||
|
||||
void setUsername(const QString &username);
|
||||
void setPasswordHash(const QByteArray &passwordHash);
|
||||
|
||||
private slots:
|
||||
void loginAction();
|
||||
void logoutAction() const;
|
||||
@@ -56,6 +61,9 @@ private:
|
||||
|
||||
ISessionManager *m_sessionManager = nullptr;
|
||||
|
||||
QString m_username;
|
||||
QByteArray m_passwordHash;
|
||||
|
||||
struct FailedLogin
|
||||
{
|
||||
int failedAttemptsCount = 0;
|
||||
|
||||
@@ -290,6 +290,16 @@ const Http::Environment &WebApplication::env() const
|
||||
return m_env;
|
||||
}
|
||||
|
||||
void WebApplication::setUsername(const QString &username)
|
||||
{
|
||||
m_authController->setUsername(username);
|
||||
}
|
||||
|
||||
void WebApplication::setPasswordHash(const QByteArray &passwordHash)
|
||||
{
|
||||
m_authController->setPasswordHash(passwordHash);
|
||||
}
|
||||
|
||||
void WebApplication::doProcessRequest()
|
||||
{
|
||||
const QRegularExpressionMatch match = m_apiPathPattern.match(request().path);
|
||||
@@ -378,17 +388,17 @@ void WebApplication::configure()
|
||||
{
|
||||
const auto *pref = Preferences::instance();
|
||||
|
||||
const bool isAltUIUsed = pref->isAltWebUiEnabled();
|
||||
const Path rootFolder = (!isAltUIUsed ? Path(WWW_FOLDER) : pref->getWebUiRootFolder());
|
||||
const bool isAltUIUsed = pref->isAltWebUIEnabled();
|
||||
const Path rootFolder = (!isAltUIUsed ? Path(WWW_FOLDER) : pref->getWebUIRootFolder());
|
||||
if ((isAltUIUsed != m_isAltUIUsed) || (rootFolder != m_rootFolder))
|
||||
{
|
||||
m_isAltUIUsed = isAltUIUsed;
|
||||
m_rootFolder = rootFolder;
|
||||
m_translatedFiles.clear();
|
||||
if (!m_isAltUIUsed)
|
||||
LogMsg(tr("Using built-in Web UI."));
|
||||
LogMsg(tr("Using built-in WebUI."));
|
||||
else
|
||||
LogMsg(tr("Using custom Web UI. Location: \"%1\".").arg(m_rootFolder.toString()));
|
||||
LogMsg(tr("Using custom WebUI. Location: \"%1\".").arg(m_rootFolder.toString()));
|
||||
}
|
||||
|
||||
const QString newLocale = pref->getLocale();
|
||||
@@ -400,27 +410,27 @@ void WebApplication::configure()
|
||||
m_translationFileLoaded = m_translator.load((m_rootFolder / Path(u"translations/webui_"_s) + newLocale).data());
|
||||
if (m_translationFileLoaded)
|
||||
{
|
||||
LogMsg(tr("Web UI translation for selected locale (%1) has been successfully loaded.")
|
||||
LogMsg(tr("WebUI translation for selected locale (%1) has been successfully loaded.")
|
||||
.arg(newLocale));
|
||||
}
|
||||
else
|
||||
{
|
||||
LogMsg(tr("Couldn't load Web UI translation for selected locale (%1).").arg(newLocale), Log::WARNING);
|
||||
LogMsg(tr("Couldn't load WebUI translation for selected locale (%1).").arg(newLocale), Log::WARNING);
|
||||
}
|
||||
}
|
||||
|
||||
m_isLocalAuthEnabled = pref->isWebUiLocalAuthEnabled();
|
||||
m_isAuthSubnetWhitelistEnabled = pref->isWebUiAuthSubnetWhitelistEnabled();
|
||||
m_authSubnetWhitelist = pref->getWebUiAuthSubnetWhitelist();
|
||||
m_isLocalAuthEnabled = pref->isWebUILocalAuthEnabled();
|
||||
m_isAuthSubnetWhitelistEnabled = pref->isWebUIAuthSubnetWhitelistEnabled();
|
||||
m_authSubnetWhitelist = pref->getWebUIAuthSubnetWhitelist();
|
||||
m_sessionTimeout = pref->getWebUISessionTimeout();
|
||||
|
||||
m_domainList = pref->getServerDomains().split(u';', Qt::SkipEmptyParts);
|
||||
std::for_each(m_domainList.begin(), m_domainList.end(), [](QString &entry) { entry = entry.trimmed(); });
|
||||
|
||||
m_isCSRFProtectionEnabled = pref->isWebUiCSRFProtectionEnabled();
|
||||
m_isSecureCookieEnabled = pref->isWebUiSecureCookieEnabled();
|
||||
m_isCSRFProtectionEnabled = pref->isWebUICSRFProtectionEnabled();
|
||||
m_isSecureCookieEnabled = pref->isWebUISecureCookieEnabled();
|
||||
m_isHostHeaderValidationEnabled = pref->isWebUIHostHeaderValidationEnabled();
|
||||
m_isHttpsEnabled = pref->isWebUiHttpsEnabled();
|
||||
m_isHttpsEnabled = pref->isWebUIHttpsEnabled();
|
||||
|
||||
m_prebuiltHeaders.clear();
|
||||
m_prebuiltHeaders.push_back({Http::HEADER_X_XSS_PROTECTION, u"1; mode=block"_s});
|
||||
@@ -432,7 +442,7 @@ void WebApplication::configure()
|
||||
m_prebuiltHeaders.push_back({Http::HEADER_REFERRER_POLICY, u"same-origin"_s});
|
||||
}
|
||||
|
||||
const bool isClickjackingProtectionEnabled = pref->isWebUiClickjackingProtectionEnabled();
|
||||
const bool isClickjackingProtectionEnabled = pref->isWebUIClickjackingProtectionEnabled();
|
||||
if (isClickjackingProtectionEnabled)
|
||||
m_prebuiltHeaders.push_back({Http::HEADER_X_FRAME_OPTIONS, u"SAMEORIGIN"_s});
|
||||
|
||||
|
||||
@@ -105,6 +105,9 @@ public:
|
||||
const Http::Request &request() const;
|
||||
const Http::Environment &env() const;
|
||||
|
||||
void setUsername(const QString &username);
|
||||
void setPasswordHash(const QByteArray &passwordHash);
|
||||
|
||||
private:
|
||||
QString clientId() const override;
|
||||
WebSession *session() override;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2015 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2015, 2023 Vladimir Golovnev <glassez@yandex.ru>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
#include "webui.h"
|
||||
|
||||
#include "base/global.h"
|
||||
#include "base/http/server.h"
|
||||
#include "base/logger.h"
|
||||
#include "base/net/dnsupdater.h"
|
||||
@@ -36,10 +37,12 @@
|
||||
#include "base/preferences.h"
|
||||
#include "base/utils/io.h"
|
||||
#include "base/utils/net.h"
|
||||
#include "base/utils/password.h"
|
||||
#include "webapplication.h"
|
||||
|
||||
WebUI::WebUI(IApplication *app)
|
||||
WebUI::WebUI(IApplication *app, const QByteArray &tempPasswordHash)
|
||||
: ApplicationComponent(app)
|
||||
, m_passwordHash {tempPasswordHash}
|
||||
{
|
||||
configure();
|
||||
connect(Preferences::instance(), &Preferences::changed, this, &WebUI::configure);
|
||||
@@ -50,13 +53,23 @@ void WebUI::configure()
|
||||
m_isErrored = false; // clear previous error state
|
||||
m_errorMsg.clear();
|
||||
|
||||
const QString portForwardingProfile = u"webui"_s;
|
||||
const Preferences *pref = Preferences::instance();
|
||||
const quint16 port = pref->getWebUiPort();
|
||||
m_isEnabled = pref->isWebUiEnabled();
|
||||
m_isEnabled = pref->isWebUIEnabled();
|
||||
const QString username = pref->getWebUIUsername();
|
||||
if (const QByteArray passwordHash = pref->getWebUIPassword(); !passwordHash.isEmpty())
|
||||
m_passwordHash = passwordHash;
|
||||
|
||||
if (m_isEnabled)
|
||||
if (m_isEnabled && (username.isEmpty() || m_passwordHash.isEmpty()))
|
||||
{
|
||||
setError(tr("Credentials are not set"));
|
||||
}
|
||||
|
||||
const QString portForwardingProfile = u"webui"_s;
|
||||
|
||||
if (m_isEnabled && !m_isErrored)
|
||||
{
|
||||
const quint16 port = pref->getWebUIPort();
|
||||
|
||||
// Port forwarding
|
||||
auto *portForwarder = Net::PortForwarder::instance();
|
||||
if (pref->useUPnPForWebUIPort())
|
||||
@@ -69,7 +82,7 @@ void WebUI::configure()
|
||||
}
|
||||
|
||||
// http server
|
||||
const QString serverAddressString = pref->getWebUiAddress();
|
||||
const QString serverAddressString = pref->getWebUIAddress();
|
||||
const auto serverAddress = ((serverAddressString == u"*") || serverAddressString.isEmpty())
|
||||
? QHostAddress::Any : QHostAddress(serverAddressString);
|
||||
|
||||
@@ -84,7 +97,10 @@ void WebUI::configure()
|
||||
m_httpServer->close();
|
||||
}
|
||||
|
||||
if (pref->isWebUiHttpsEnabled())
|
||||
m_webapp->setUsername(username);
|
||||
m_webapp->setPasswordHash(m_passwordHash);
|
||||
|
||||
if (pref->isWebUIHttpsEnabled())
|
||||
{
|
||||
const auto readData = [](const Path &path) -> QByteArray
|
||||
{
|
||||
@@ -96,9 +112,9 @@ void WebUI::configure()
|
||||
|
||||
const bool success = m_httpServer->setupHttps(cert, key);
|
||||
if (success)
|
||||
LogMsg(tr("Web UI: HTTPS setup successful"));
|
||||
LogMsg(tr("WebUI: HTTPS setup successful"));
|
||||
else
|
||||
LogMsg(tr("Web UI: HTTPS setup failed, fallback to HTTP"), Log::CRITICAL);
|
||||
LogMsg(tr("WebUI: HTTPS setup failed, fallback to HTTP"), Log::CRITICAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -110,17 +126,12 @@ void WebUI::configure()
|
||||
const bool success = m_httpServer->listen(serverAddress, port);
|
||||
if (success)
|
||||
{
|
||||
LogMsg(tr("Web UI: Now listening on IP: %1, port: %2").arg(serverAddressString).arg(port));
|
||||
LogMsg(tr("WebUI: Now listening on IP: %1, port: %2").arg(serverAddressString).arg(port));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_errorMsg = tr("Web UI: Unable to bind to IP: %1, port: %2. Reason: %3")
|
||||
.arg(serverAddressString).arg(port).arg(m_httpServer->errorString());
|
||||
LogMsg(m_errorMsg, Log::CRITICAL);
|
||||
qCritical() << m_errorMsg;
|
||||
|
||||
m_isErrored = true;
|
||||
emit error(m_errorMsg);
|
||||
setError(tr("Unable to bind to IP: %1, port: %2. Reason: %3")
|
||||
.arg(serverAddressString).arg(port).arg(m_httpServer->errorString()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,6 +158,18 @@ void WebUI::configure()
|
||||
}
|
||||
}
|
||||
|
||||
void WebUI::setError(const QString &message)
|
||||
{
|
||||
m_isErrored = true;
|
||||
m_errorMsg = message;
|
||||
|
||||
const QString logMessage = u"WebUI: " + m_errorMsg;
|
||||
LogMsg(logMessage, Log::CRITICAL);
|
||||
qCritical() << logMessage;
|
||||
|
||||
emit error(m_errorMsg);
|
||||
}
|
||||
|
||||
bool WebUI::isEnabled() const
|
||||
{
|
||||
return m_isEnabled;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2015 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2015, 2023 Vladimir Golovnev <glassez@yandex.ru>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -52,7 +52,7 @@ class WebUI final : public ApplicationComponent<QObject>
|
||||
Q_DISABLE_COPY_MOVE(WebUI)
|
||||
|
||||
public:
|
||||
explicit WebUI(IApplication *app);
|
||||
explicit WebUI(IApplication *app, const QByteArray &tempPasswordHash = {});
|
||||
|
||||
bool isEnabled() const;
|
||||
bool isErrored() const;
|
||||
@@ -68,10 +68,14 @@ private slots:
|
||||
void configure();
|
||||
|
||||
private:
|
||||
void setError(const QString &message);
|
||||
|
||||
bool m_isEnabled = false;
|
||||
bool m_isErrored = false;
|
||||
QString m_errorMsg;
|
||||
QPointer<Http::Server> m_httpServer;
|
||||
QPointer<Net::DNSUpdater> m_dnsUpdater;
|
||||
QPointer<WebApplication> m_webapp;
|
||||
|
||||
QByteArray m_passwordHash;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user