mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
Feat: Protect db against pw/token tests
This commit is contained in:
parent
5553199cc4
commit
4595ae8e2d
@ -110,6 +110,18 @@ public:
|
|||||||
///
|
///
|
||||||
bool isUserTokenAuthorized(const QString& usr, const QString& token);
|
bool isUserTokenAuthorized(const QString& usr, const QString& token);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Check if user auth is temporary blocked due to failed attempts
|
||||||
|
/// @return True on blocked and no further Auth requests will be accepted
|
||||||
|
///
|
||||||
|
bool isUserAuthBlocked(){ return (_userAuthAttempts.length() >= 10); };
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Check if token auth is temporary blocked due to failed attempts
|
||||||
|
/// @return True on blocked and no further Auth requests will be accepted
|
||||||
|
///
|
||||||
|
bool isTokenAuthBlocked(){ return (_tokenAuthAttempts.length() >= 25); };
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @brief Change password of user
|
/// @brief Change password of user
|
||||||
/// @param user The username
|
/// @param user The username
|
||||||
@ -186,6 +198,12 @@ signals:
|
|||||||
void tokenResponse(const bool& success, QObject* caller, const QString& token, const QString& comment, const QString& id);
|
void tokenResponse(const bool& success, QObject* caller, const QString& token, const QString& comment, const QString& id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
///
|
||||||
|
/// @brief Increment counter for token/user auth
|
||||||
|
/// @param user If true we increment USER auth instead of token
|
||||||
|
///
|
||||||
|
void setAuthBlock(const bool& user = false);
|
||||||
|
|
||||||
/// Database interface for auth table
|
/// Database interface for auth table
|
||||||
AuthTable* _authTable;
|
AuthTable* _authTable;
|
||||||
|
|
||||||
@ -210,9 +228,23 @@ private:
|
|||||||
/// Timer for counting against pendingRequest timeouts
|
/// Timer for counting against pendingRequest timeouts
|
||||||
QTimer* _timer;
|
QTimer* _timer;
|
||||||
|
|
||||||
|
// Timer which cleans up the block counter
|
||||||
|
QTimer* _authBlockTimer;
|
||||||
|
|
||||||
|
// Contains timestamps of failed user login attempts
|
||||||
|
QVector<uint64_t> _userAuthAttempts;
|
||||||
|
|
||||||
|
// Contains timestamps of failed token login attempts
|
||||||
|
QVector<uint64_t> _tokenAuthAttempts;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
///
|
///
|
||||||
/// @brief Check timeout of pending requests
|
/// @brief Check timeout of pending requests
|
||||||
///
|
///
|
||||||
void checkTimeout();
|
void checkTimeout();
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Check if there are timeouts for failed login attempts
|
||||||
|
///
|
||||||
|
void checkAuthBlockTimeout();
|
||||||
};
|
};
|
||||||
|
@ -17,9 +17,11 @@ AuthManager::AuthManager(QObject* parent)
|
|||||||
, _pendingRequests()
|
, _pendingRequests()
|
||||||
, _authRequired(true)
|
, _authRequired(true)
|
||||||
, _timer(new QTimer(this))
|
, _timer(new QTimer(this))
|
||||||
|
, _authBlockTimer(new QTimer(this))
|
||||||
{
|
{
|
||||||
AuthManager::manager = this;
|
AuthManager::manager = this;
|
||||||
|
|
||||||
|
|
||||||
// get uuid
|
// get uuid
|
||||||
_uuid = _metaTable->getUUID();
|
_uuid = _metaTable->getUUID();
|
||||||
|
|
||||||
@ -27,6 +29,10 @@ AuthManager::AuthManager(QObject* parent)
|
|||||||
_timer->setInterval(1000);
|
_timer->setInterval(1000);
|
||||||
connect(_timer, &QTimer::timeout, this, &AuthManager::checkTimeout);
|
connect(_timer, &QTimer::timeout, this, &AuthManager::checkTimeout);
|
||||||
|
|
||||||
|
// setup authBlockTimer
|
||||||
|
_authBlockTimer->setInterval(60000);
|
||||||
|
connect(_authBlockTimer, &QTimer::timeout, this, &AuthManager::checkAuthBlockTimeout);
|
||||||
|
|
||||||
// init with default user and password
|
// init with default user and password
|
||||||
if(!_authTable->userExist("Hyperion"))
|
if(!_authTable->userExist("Hyperion"))
|
||||||
{
|
{
|
||||||
@ -72,22 +78,54 @@ const QVector<AuthManager::AuthDefinition> AuthManager::getTokenList()
|
|||||||
|
|
||||||
const QString AuthManager::getUserToken(const QString & usr)
|
const QString AuthManager::getUserToken(const QString & usr)
|
||||||
{
|
{
|
||||||
return QString(_authTable->getUserToken("Hyperion"));
|
return QString(_authTable->getUserToken(usr));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AuthManager::setAuthBlock(const bool& user)
|
||||||
|
{
|
||||||
|
// current timestamp +10 minutes
|
||||||
|
if(user)
|
||||||
|
_userAuthAttempts.append(QDateTime::currentMSecsSinceEpoch()+600000);
|
||||||
|
else
|
||||||
|
_tokenAuthAttempts.append(QDateTime::currentMSecsSinceEpoch()+600000);
|
||||||
|
|
||||||
|
QMetaObject::invokeMethod(_authBlockTimer, "start", Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AuthManager::isUserAuthorized(const QString& user, const QString& pw)
|
bool AuthManager::isUserAuthorized(const QString& user, const QString& pw)
|
||||||
{
|
{
|
||||||
return _authTable->isUserAuthorized(user, pw);
|
if(isUserAuthBlocked())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(!_authTable->isUserAuthorized(user, pw)){
|
||||||
|
setAuthBlock(true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AuthManager::isTokenAuthorized(const QString& token)
|
bool AuthManager::isTokenAuthorized(const QString& token)
|
||||||
{
|
{
|
||||||
return _authTable->tokenExist(token);
|
if(isTokenAuthBlocked())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(!_authTable->tokenExist(token)){
|
||||||
|
setAuthBlock();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AuthManager::isUserTokenAuthorized(const QString& usr, const QString& token)
|
bool AuthManager::isUserTokenAuthorized(const QString& usr, const QString& token)
|
||||||
{
|
{
|
||||||
return _authTable->isUserTokenAuthorized(usr, token);
|
if(isUserAuthBlocked())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(!_authTable->isUserTokenAuthorized(usr, token)){
|
||||||
|
setAuthBlock(true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AuthManager::updateUserPassword(const QString& user, const QString& pw, const QString& newPw)
|
bool AuthManager::updateUserPassword(const QString& user, const QString& pw, const QString& newPw)
|
||||||
@ -184,3 +222,25 @@ void AuthManager::checkTimeout()
|
|||||||
if(_pendingRequests.isEmpty())
|
if(_pendingRequests.isEmpty())
|
||||||
_timer->stop();
|
_timer->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AuthManager::checkAuthBlockTimeout(){
|
||||||
|
// handle user auth block
|
||||||
|
for (auto it = _userAuthAttempts.begin(); it != _userAuthAttempts.end(); it++) {
|
||||||
|
// after 10 minutes, we remove the entry
|
||||||
|
if (*it < (uint64_t)QDateTime::currentMSecsSinceEpoch()) {
|
||||||
|
_userAuthAttempts.erase(it--);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle token auth block
|
||||||
|
for (auto it = _tokenAuthAttempts.begin(); it != _tokenAuthAttempts.end(); it++) {
|
||||||
|
// after 10 minutes, we remove the entry
|
||||||
|
if (*it < (uint64_t)QDateTime::currentMSecsSinceEpoch()) {
|
||||||
|
_tokenAuthAttempts.erase(it--);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the lists are empty we stop
|
||||||
|
if(_userAuthAttempts.empty() && _tokenAuthAttempts.empty())
|
||||||
|
_authBlockTimer->stop();
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user