init
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
#include "session.hpp"
|
||||
#include <pgmspace.h> // Required for PROGMEM
|
||||
|
||||
// Definition of the global instance
|
||||
SessionManager sessionManager;
|
||||
|
||||
// The character set is now stored in flash memory to save RAM.
|
||||
const char charset[] PROGMEM = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
|
||||
SessionManager::SessionManager() {
|
||||
session_mutex_ = xSemaphoreCreateMutex();
|
||||
for (size_t i = 0; i < MAX_SESSIONS; ++i) {
|
||||
sessions_[i].username[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
SessionManager::~SessionManager() {
|
||||
vSemaphoreDelete(session_mutex_);
|
||||
}
|
||||
|
||||
const char* SessionManager::createSession(const char* username) {
|
||||
const char* result_token = nullptr;
|
||||
// Lock the mutex to ensure exclusive access to the sessions array.
|
||||
if (xSemaphoreTake(session_mutex_, portMAX_DELAY) == pdTRUE) {
|
||||
for (size_t i = 0; i < MAX_SESSIONS; ++i) {
|
||||
if (sessions_[i].username[0] == '\0') {
|
||||
strncpy(sessions_[i].username, username, sizeof(sessions_[i].username) - 1);
|
||||
sessions_[i].username[sizeof(sessions_[i].username) - 1] = '\0';
|
||||
|
||||
generateToken(sessions_[i].token, sizeof(sessions_[i].token));
|
||||
|
||||
sessions_[i].expiry_time = millis() + (15 * 60 * 1000);
|
||||
|
||||
result_token = sessions_[i].token;
|
||||
break; // Exit loop once a slot is found
|
||||
}
|
||||
}
|
||||
xSemaphoreGive(session_mutex_); // Release the mutex
|
||||
}
|
||||
return result_token;
|
||||
}
|
||||
|
||||
const char* SessionManager::validateSession(const char* token) {
|
||||
if (token == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// We must copy the username to a static buffer, because the session array
|
||||
// could be modified by another task after we release the mutex.
|
||||
static char valid_username[33];
|
||||
valid_username[0] = '\0';
|
||||
|
||||
if (xSemaphoreTake(session_mutex_, portMAX_DELAY) == pdTRUE) {
|
||||
for (size_t i = 0; i < MAX_SESSIONS; ++i) {
|
||||
if (sessions_[i].username[0] != '\0' && strcmp(sessions_[i].token, token) == 0) {
|
||||
if (millis() < sessions_[i].expiry_time) {
|
||||
strcpy(valid_username, sessions_[i].username);
|
||||
} else {
|
||||
sessions_[i].username[0] = '\0'; // Expired, clear it
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
xSemaphoreGive(session_mutex_);
|
||||
}
|
||||
|
||||
return (valid_username[0] != '\0') ? valid_username : nullptr;
|
||||
}
|
||||
|
||||
bool SessionManager::endSession(const char* token) {
|
||||
if (token == nullptr) return false;
|
||||
|
||||
bool found = false;
|
||||
if (xSemaphoreTake(session_mutex_, portMAX_DELAY) == pdTRUE) {
|
||||
for (size_t i = 0; i < MAX_SESSIONS; ++i) {
|
||||
if (sessions_[i].username[0] != '\0' && strcmp(sessions_[i].token, token) == 0) {
|
||||
sessions_[i].username[0] = '\0';
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
xSemaphoreGive(session_mutex_);
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
void SessionManager::cleanupExpiredSessions() {
|
||||
unsigned long current_time = millis();
|
||||
if (xSemaphoreTake(session_mutex_, portMAX_DELAY) == pdTRUE) {
|
||||
for (size_t i = 0; i < MAX_SESSIONS; ++i) {
|
||||
if (sessions_[i].username[0] != '\0') {
|
||||
if (current_time >= sessions_[i].expiry_time) {
|
||||
sessions_[i].username[0] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
xSemaphoreGive(session_mutex_);
|
||||
}
|
||||
}
|
||||
|
||||
void SessionManager::generateToken(char* buffer, size_t buffer_size) {
|
||||
const size_t charset_size = sizeof(charset) - 1;
|
||||
for (size_t i = 0; i < buffer_size - 1; ++i) {
|
||||
// Read the character directly from flash memory (PROGMEM).
|
||||
buffer[i] = pgm_read_byte(&charset[esp_random() % charset_size]);
|
||||
}
|
||||
buffer[buffer_size - 1] = '\0';
|
||||
}
|
||||
Reference in New Issue
Block a user