78 lines
2.3 KiB
C++
78 lines
2.3 KiB
C++
#include "SessionHandler.hpp"
|
|
#include <random>
|
|
#include <thread>
|
|
#include "crow/logging.h"
|
|
|
|
using namespace login;
|
|
|
|
// generate random string
|
|
std::string randomString(size_t length) {
|
|
static const char charset[] =
|
|
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
std::string result;
|
|
result.resize(length);
|
|
std::mt19937 rng(std::random_device{}());
|
|
std::uniform_int_distribution<> dist(0, sizeof(charset)-2);
|
|
for (size_t i = 0; i < length; ++i) result[i] = charset[dist(rng)];
|
|
return result;
|
|
}
|
|
|
|
SessionHandler::SessionHandler()
|
|
: cleanupThread(std::thread(&SessionHandler::cleanupWorker, this))
|
|
, stopCleanupThread(false)
|
|
{
|
|
}
|
|
|
|
SessionHandler::~SessionHandler() {
|
|
stopCleanupThread = true;
|
|
if (cleanupThread.joinable())
|
|
cleanupThread.join();
|
|
}
|
|
|
|
void SessionHandler::cleanupWorker(){
|
|
while (!stopCleanupThread) {
|
|
std::this_thread::sleep_for(std::chrono::minutes(5));
|
|
auto now = std::chrono::steady_clock::now();
|
|
{
|
|
std::lock_guard<std::mutex> lock(sessionMutex);
|
|
for (auto it = sessions.begin(); it != sessions.end();) {
|
|
if (it->second.isExpired(now)){
|
|
CROW_LOG_INFO << "Session " << it->first << " expired for userId: " << it->second.userId();
|
|
it = sessions.erase(it);
|
|
}
|
|
else {
|
|
++it;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
std::optional<std::string> SessionHandler::createSession(int userId){
|
|
std::string sessionId = randomString(Session::SESSION_ID_SIZE);
|
|
std::lock_guard<std::mutex> lock(sessionMutex);
|
|
if (!sessions.emplace(sessionId, Session(userId)).second){
|
|
return {};
|
|
}
|
|
return sessionId;
|
|
}
|
|
|
|
std::optional<int> SessionHandler::isSessionValid(const std::string& sessionId){
|
|
auto now = std::chrono::steady_clock::now();
|
|
std::lock_guard<std::mutex> lock(sessionMutex);
|
|
|
|
auto it = sessions.find(sessionId);
|
|
if(it != sessions.end()){
|
|
if (it->second.isExpired(now)){
|
|
CROW_LOG_INFO << "Session " << it->first << " expired for userId: " << it->second.userId();
|
|
it = sessions.erase(it);
|
|
return {};
|
|
}
|
|
it->second.extend(now); // extend session life time
|
|
return it->second.userId();
|
|
}
|
|
return {};
|
|
}
|
|
|
|
|