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