Refresh only last login time when necessary (avoid hammering the db, ref #420)

This commit is contained in:
emeric
2024-03-02 18:11:03 +01:00
parent f9d512ee19
commit f20db00417
4 changed files with 155 additions and 148 deletions
+22 -10
View File
@@ -19,6 +19,7 @@
#include "AuthServiceBase.hpp" #include "AuthServiceBase.hpp"
#include <cstdlib>
#include "database/Db.hpp" #include "database/Db.hpp"
#include "database/Session.hpp" #include "database/Session.hpp"
#include "database/User.hpp" #include "database/User.hpp"
@@ -32,8 +33,7 @@ namespace Auth
: _db{ db } : _db{ db }
{} {}
UserId UserId AuthServiceBase::getOrCreateUser(std::string_view loginName)
AuthServiceBase::getOrCreateUser(std::string_view loginName)
{ {
Session& session{ getDbSession() }; Session& session{ getDbSession() };
auto transaction{ session.createWriteTransaction() }; auto transaction{ session.createWriteTransaction() };
@@ -52,19 +52,31 @@ namespace Auth
return user->getId(); return user->getId();
} }
void void AuthServiceBase::onUserAuthenticated(UserId userId)
AuthServiceBase::onUserAuthenticated(UserId userId)
{ {
Session& session{ getDbSession() }; Session& session{ getDbSession() };
auto transaction {session.createWriteTransaction()};
User::pointer user {User::find(session, userId)}; // Update last login only if relevant (avoid hammering write accesses to the database)
if (user) {
user.modify()->setLastLogin(Wt::WDateTime::currentDateTime()); auto transaction{ session.createReadTransaction() };
const User::pointer user{ User::find(session, userId) };
if (!user)
return;
if (std::abs(Wt::WDateTime::currentDateTime().secsTo(user->getLastLogin())) < 60)
return;
} }
Session& {
AuthServiceBase::getDbSession() auto transaction{ session.createWriteTransaction() };
if (User::pointer user{ User::find(session, userId) })
user.modify()->setLastLogin(Wt::WDateTime::currentDateTime());
}
}
Session& AuthServiceBase::getDbSession()
{ {
return _db.getTLSSession(); return _db.getTLSSession();
} }
@@ -41,8 +41,7 @@ namespace Auth
_validator.setMinimumMatchLength(3); _validator.setMinimumMatchLength(3);
} }
bool bool InternalPasswordService::checkUserPassword(std::string_view loginName, std::string_view password)
InternalPasswordService::checkUserPassword(std::string_view loginName, std::string_view password)
{ {
LMS_LOG(AUTH, DEBUG, "Checking internal password for user '" << loginName << "'"); LMS_LOG(AUTH, DEBUG, "Checking internal password for user '" << loginName << "'");
@@ -73,14 +72,12 @@ namespace Auth
return _hashFunc.verify(std::string{ password }, std::string{ passwordHash.salt }, std::string{ passwordHash.hash }); return _hashFunc.verify(std::string{ password }, std::string{ passwordHash.salt }, std::string{ passwordHash.hash });
} }
bool bool InternalPasswordService::canSetPasswords() const
InternalPasswordService::canSetPasswords() const
{ {
return true; return true;
} }
IPasswordService::PasswordAcceptabilityResult IPasswordService::PasswordAcceptabilityResult InternalPasswordService::checkPasswordAcceptability(std::string_view password, const PasswordValidationContext& context) const
InternalPasswordService::checkPasswordAcceptability(std::string_view password, const PasswordValidationContext& context) const
{ {
switch (context.userType) switch (context.userType)
{ {
@@ -94,8 +91,7 @@ namespace Auth
throw NotImplementedException{}; throw NotImplementedException{};
} }
void void InternalPasswordService::setPassword(Database::UserId userId, std::string_view newPassword)
InternalPasswordService::setPassword(Database::UserId userId, std::string_view newPassword)
{ {
const Database::User::PasswordHash passwordHash{ hashPassword(newPassword) }; const Database::User::PasswordHash passwordHash{ hashPassword(newPassword) };
@@ -120,8 +116,7 @@ namespace Auth
getAuthTokenService().clearAuthTokens(userId); getAuthTokenService().clearAuthTokens(userId);
} }
Database::User::PasswordHash Database::User::PasswordHash InternalPasswordService::hashPassword(std::string_view password) const
InternalPasswordService::hashPassword(std::string_view password) const
{ {
const std::string salt{ Wt::WRandom::generateId(32) }; const std::string salt{ Wt::WRandom::generateId(32) };