WebUI: Fix reloading page after login
[qBittorrent.git] / src / webui / api / authcontroller.cpp
blobeb1d1baf237626bce80100d6941bf2a24c6ae4a0
1 /*
2 * Bittorrent Client using Qt and libtorrent.
3 * Copyright (C) 2018 Vladimir Golovnev <glassez@yandex.ru>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 * In addition, as a special exception, the copyright holders give permission to
20 * link this program with the OpenSSL project's "OpenSSL" library (or with
21 * modified versions of it that use the same license as the "OpenSSL" library),
22 * and distribute the linked executables. You must obey the GNU General Public
23 * License in all respects for all of the code used other than "OpenSSL". If you
24 * modify file(s), you may extend this exception to your version of the file(s),
25 * but you are not obligated to do so. If you do not wish to do so, delete this
26 * exception statement from your version.
29 #include "authcontroller.h"
31 #include <QString>
33 #include "base/global.h"
34 #include "base/logger.h"
35 #include "base/preferences.h"
36 #include "base/utils/password.h"
37 #include "apierror.h"
38 #include "isessionmanager.h"
40 AuthController::AuthController(ISessionManager *sessionManager, IApplication *app, QObject *parent)
41 : APIController(app, parent)
42 , m_sessionManager {sessionManager}
46 void AuthController::setUsername(const QString &username)
48 m_username = username;
51 void AuthController::setPasswordHash(const QByteArray &passwordHash)
53 m_passwordHash = passwordHash;
56 void AuthController::loginAction()
58 if (m_sessionManager->session())
60 setResult(u"Ok."_s);
61 return;
64 const QString clientAddr = m_sessionManager->clientId();
65 const QString usernameFromWeb = params()[u"username"_s];
66 const QString passwordFromWeb = params()[u"password"_s];
68 if (isBanned())
70 LogMsg(tr("WebAPI login failure. Reason: IP has been banned, IP: %1, username: %2")
71 .arg(clientAddr, usernameFromWeb)
72 , Log::WARNING);
73 throw APIError(APIErrorType::AccessDenied
74 , tr("Your IP address has been banned after too many failed authentication attempts."));
77 const bool usernameEqual = Utils::Password::slowEquals(usernameFromWeb.toUtf8(), m_username.toUtf8());
78 const bool passwordEqual = Utils::Password::PBKDF2::verify(m_passwordHash, passwordFromWeb);
80 if (usernameEqual && passwordEqual)
82 m_clientFailedLogins.remove(clientAddr);
84 m_sessionManager->sessionStart();
85 setResult(u"Ok."_s);
86 LogMsg(tr("WebAPI login success. IP: %1").arg(clientAddr));
88 else
90 if (Preferences::instance()->getWebUIMaxAuthFailCount() > 0)
91 increaseFailedAttempts();
92 setResult(u"Fails."_s);
93 LogMsg(tr("WebAPI login failure. Reason: invalid credentials, attempt count: %1, IP: %2, username: %3")
94 .arg(QString::number(failedAttemptsCount()), clientAddr, usernameFromWeb)
95 , Log::WARNING);
99 void AuthController::logoutAction() const
101 m_sessionManager->sessionEnd();
104 bool AuthController::isBanned() const
106 const auto failedLoginIter = m_clientFailedLogins.find(m_sessionManager->clientId());
107 if (failedLoginIter == m_clientFailedLogins.end())
108 return false;
110 bool isBanned = (failedLoginIter->banTimer.remainingTime() >= 0);
111 if (isBanned && failedLoginIter->banTimer.hasExpired())
113 m_clientFailedLogins.erase(failedLoginIter);
114 isBanned = false;
117 return isBanned;
120 int AuthController::failedAttemptsCount() const
122 return m_clientFailedLogins.value(m_sessionManager->clientId()).failedAttemptsCount;
125 void AuthController::increaseFailedAttempts()
127 Q_ASSERT(Preferences::instance()->getWebUIMaxAuthFailCount() > 0);
129 FailedLogin &failedLogin = m_clientFailedLogins[m_sessionManager->clientId()];
130 ++failedLogin.failedAttemptsCount;
132 if (failedLogin.failedAttemptsCount >= Preferences::instance()->getWebUIMaxAuthFailCount())
134 // Max number of failed attempts reached
135 // Start ban period
136 failedLogin.banTimer.setRemainingTime(Preferences::instance()->getWebUIBanDuration());