mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2024-10-22 02:36:15 +03:00
parent
1c43286616
commit
99afe3c411
6 changed files with 60 additions and 11 deletions
|
@ -764,6 +764,7 @@ void Preferences::setWebUIUsername(const QString &username)
|
|||
return;
|
||||
|
||||
setValue(u"Preferences/WebUI/Username"_s, username);
|
||||
m_credentialsChanged = true;
|
||||
}
|
||||
|
||||
QByteArray Preferences::getWebUIPassword() const
|
||||
|
@ -777,6 +778,7 @@ void Preferences::setWebUIPassword(const QByteArray &password)
|
|||
return;
|
||||
|
||||
setValue(u"Preferences/WebUI/Password_PBKDF2"_s, password);
|
||||
m_credentialsChanged = true;
|
||||
}
|
||||
|
||||
int Preferences::getWebUIMaxAuthFailCount() const
|
||||
|
@ -1977,5 +1979,11 @@ void Preferences::setAddNewTorrentDialogSavePathHistoryLength(const int value)
|
|||
void Preferences::apply()
|
||||
{
|
||||
if (SettingsStorage::instance()->save())
|
||||
{
|
||||
emit changed();
|
||||
if (m_credentialsChanged) {
|
||||
emit webCredentialsChanged();
|
||||
m_credentialsChanged = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -430,7 +430,10 @@ public slots:
|
|||
|
||||
signals:
|
||||
void changed();
|
||||
void webCredentialsChanged();
|
||||
|
||||
private:
|
||||
static Preferences *m_instance;
|
||||
|
||||
bool m_credentialsChanged = false;
|
||||
};
|
||||
|
|
|
@ -81,7 +81,7 @@ void AuthController::loginAction()
|
|||
{
|
||||
m_clientFailedLogins.remove(clientAddr);
|
||||
|
||||
m_sessionManager->sessionStart();
|
||||
m_sessionManager->sessionStart(true);
|
||||
setResult(u"Ok."_s);
|
||||
LogMsg(tr("WebAPI login success. IP: %1").arg(clientAddr));
|
||||
}
|
||||
|
|
|
@ -43,6 +43,6 @@ struct ISessionManager
|
|||
virtual ~ISessionManager() = default;
|
||||
virtual QString clientId() const = 0;
|
||||
virtual ISession *session() = 0;
|
||||
virtual void sessionStart() = 0;
|
||||
virtual void sessionStart(bool authenticated) = 0;
|
||||
virtual void sessionEnd() = 0;
|
||||
};
|
||||
|
|
|
@ -170,6 +170,7 @@ WebApplication::WebApplication(IApplication *app, QObject *parent)
|
|||
|
||||
configure();
|
||||
connect(Preferences::instance(), &Preferences::changed, this, &WebApplication::configure);
|
||||
connect(Preferences::instance(), &Preferences::webCredentialsChanged, this, &WebApplication::logoutAllSessions);
|
||||
|
||||
m_sessionCookieName = Preferences::instance()->getWebAPISessionCookieName();
|
||||
if (!isValidCookieName(m_sessionCookieName))
|
||||
|
@ -435,9 +436,29 @@ void WebApplication::configure()
|
|||
}
|
||||
}
|
||||
|
||||
m_isLocalAuthEnabled = pref->isWebUILocalAuthEnabled();
|
||||
m_isAuthSubnetWhitelistEnabled = pref->isWebUIAuthSubnetWhitelistEnabled();
|
||||
m_authSubnetWhitelist = pref->getWebUIAuthSubnetWhitelist();
|
||||
const bool isLocalAuthEnabled = pref->isWebUILocalAuthEnabled();
|
||||
const bool isAuthSubnetWhitelistEnabled = pref->isWebUIAuthSubnetWhitelistEnabled();
|
||||
const QList<Utils::Net::Subnet> authSubnetWhitelist = pref->getWebUIAuthSubnetWhitelist();
|
||||
if ((isLocalAuthEnabled && (isLocalAuthEnabled != m_isLocalAuthEnabled))
|
||||
|| (!isAuthSubnetWhitelistEnabled && (isAuthSubnetWhitelistEnabled != m_isAuthSubnetWhitelistEnabled))
|
||||
|| (!m_authSubnetWhitelist.isEmpty() && (authSubnetWhitelist != m_authSubnetWhitelist)))
|
||||
{
|
||||
// remove sessions which bypassed authentication
|
||||
Algorithm::removeIf(m_sessions, [](const QString &, const WebSession *session)
|
||||
{
|
||||
if (!session->isAuthenticated())
|
||||
{
|
||||
delete session;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
m_isLocalAuthEnabled = isLocalAuthEnabled;
|
||||
m_isAuthSubnetWhitelistEnabled = isAuthSubnetWhitelistEnabled;
|
||||
m_authSubnetWhitelist = authSubnetWhitelist;
|
||||
m_sessionTimeout = pref->getWebUISessionTimeout();
|
||||
|
||||
m_domainList = pref->getServerDomains().split(u';', Qt::SkipEmptyParts);
|
||||
|
@ -525,6 +546,12 @@ void WebApplication::configure()
|
|||
}
|
||||
}
|
||||
|
||||
void WebApplication::logoutAllSessions()
|
||||
{
|
||||
qDeleteAll(m_sessions);
|
||||
m_sessions.clear();
|
||||
}
|
||||
|
||||
void WebApplication::declarePublicAPI(const QString &apiPath)
|
||||
{
|
||||
m_publicAPIs << apiPath;
|
||||
|
@ -677,7 +704,7 @@ void WebApplication::sessionInitialize()
|
|||
}
|
||||
|
||||
if (!m_currentSession && !isAuthNeeded())
|
||||
sessionStart();
|
||||
sessionStart(false);
|
||||
}
|
||||
|
||||
QString WebApplication::generateSid() const
|
||||
|
@ -710,7 +737,7 @@ bool WebApplication::isPublicAPI(const QString &scope, const QString &action) co
|
|||
return m_publicAPIs.contains(u"%1/%2"_s.arg(scope, action));
|
||||
}
|
||||
|
||||
void WebApplication::sessionStart()
|
||||
void WebApplication::sessionStart(const bool authenticated)
|
||||
{
|
||||
Q_ASSERT(!m_currentSession);
|
||||
|
||||
|
@ -726,7 +753,7 @@ void WebApplication::sessionStart()
|
|||
return false;
|
||||
});
|
||||
|
||||
m_currentSession = new WebSession(generateSid(), app());
|
||||
m_currentSession = new WebSession(generateSid(), app(), authenticated);
|
||||
m_sessions[m_currentSession->id()] = m_currentSession;
|
||||
|
||||
m_currentSession->registerAPIController(u"app"_s, new AppController(app(), this));
|
||||
|
@ -911,9 +938,10 @@ QHostAddress WebApplication::resolveClientAddress() const
|
|||
|
||||
// WebSession
|
||||
|
||||
WebSession::WebSession(const QString &sid, IApplication *app)
|
||||
WebSession::WebSession(const QString &sid, IApplication *app, const bool authenticated)
|
||||
: ApplicationComponent(app)
|
||||
, m_sid {sid}
|
||||
, m_authenticated {authenticated}
|
||||
{
|
||||
updateTimestamp();
|
||||
}
|
||||
|
@ -935,6 +963,11 @@ void WebSession::updateTimestamp()
|
|||
m_timer.start();
|
||||
}
|
||||
|
||||
bool WebSession::isAuthenticated() const
|
||||
{
|
||||
return m_authenticated;
|
||||
}
|
||||
|
||||
void WebSession::registerAPIController(const QString &scope, APIController *controller)
|
||||
{
|
||||
Q_ASSERT(controller);
|
||||
|
|
|
@ -71,12 +71,13 @@ namespace BitTorrent
|
|||
class WebSession final : public ApplicationComponent<QObject>, public ISession
|
||||
{
|
||||
public:
|
||||
explicit WebSession(const QString &sid, IApplication *app);
|
||||
explicit WebSession(const QString &sid, IApplication *app, bool authenticated);
|
||||
|
||||
QString id() const override;
|
||||
|
||||
bool hasExpired(qint64 seconds) const;
|
||||
void updateTimestamp();
|
||||
bool isAuthenticated() const;
|
||||
|
||||
void registerAPIController(const QString &scope, APIController *controller);
|
||||
APIController *getAPIController(const QString &scope) const;
|
||||
|
@ -84,6 +85,7 @@ public:
|
|||
private:
|
||||
const QString m_sid;
|
||||
QElapsedTimer m_timer; // timestamp
|
||||
bool m_authenticated = false;
|
||||
QMap<QString, APIController *> m_apiControllers;
|
||||
};
|
||||
|
||||
|
@ -106,10 +108,13 @@ public:
|
|||
void setUsername(const QString &username);
|
||||
void setPasswordHash(const QByteArray &passwordHash);
|
||||
|
||||
private slots:
|
||||
void logoutAllSessions();
|
||||
|
||||
private:
|
||||
QString clientId() const override;
|
||||
WebSession *session() override;
|
||||
void sessionStart() override;
|
||||
void sessionStart(bool authenticated) override;
|
||||
void sessionEnd() override;
|
||||
|
||||
void doProcessRequest();
|
||||
|
|
Loading…
Reference in a new issue