blob: fcab52fa61769d49eebd912a039acb642217f502 [file] [log] [blame]
#pragma once
#include <nlohmann/json.hpp>
#include <pam_authenticate.hpp>
#include <webassets.hpp>
#include <random>
#include "session_storage_singleton.hpp"
#include <crow/app.h>
#include <crow/http_request.h>
#include <crow/http_response.h>
#include <boost/container/flat_map.hpp>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
namespace crow {
namespace PersistentData {
class Middleware {
// todo(ed) should read this from a fixed location somewhere, not CWD
static constexpr const char* filename = "bmcweb_persistent_data.json";
int json_revision = 1;
public:
struct context {};
Middleware() { read_data(); }
~Middleware() {
if (PersistentData::session_store->needs_write()) {
write_data();
}
}
void before_handle(crow::request& req, response& res, context& ctx) {}
void after_handle(request& req, response& res, context& ctx) {}
// TODO(ed) this should really use protobuf, or some other serialization
// library, but adding another dependency is somewhat outside the scope of
// this application for the moment
void read_data() {
std::ifstream persistent_file(filename);
int file_revision = 0;
if (persistent_file.is_open()) {
// call with exceptions disabled
auto data = nlohmann::json::parse(persistent_file, nullptr, false);
if (!data.is_discarded()) {
auto jRevision = data.find("revision");
auto jUuid = data.find("system_uuid");
auto jSessions = data.find("sessions");
file_revision = 0;
if (jRevision != data.end()) {
if (jRevision->is_number_integer()) {
file_revision = jRevision->get<int>();
}
}
system_uuid = "";
if (jUuid != data.end()) {
if (jUuid->is_string()) {
system_uuid = jUuid->get<std::string>();
}
}
if (jSessions != data.end()) {
if (jSessions->is_object()) {
for (const auto& elem : *jSessions) {
UserSession newSession;
if (newSession.fromJson(elem)) {
session_store->auth_tokens.emplace(newSession.unique_id,
std::move(newSession));
}
}
}
}
}
}
bool need_write = false;
if (system_uuid.empty()) {
system_uuid = boost::uuids::to_string(boost::uuids::random_generator()());
need_write = true;
}
if (file_revision < json_revision) {
need_write = true;
}
// write revision changes or system uuid changes immediately
if (need_write) {
write_data();
}
}
void write_data() {
std::ofstream persistent_file(filename);
nlohmann::json data;
data["sessions"] = PersistentData::session_store->auth_tokens;
data["system_uuid"] = system_uuid;
data["revision"] = json_revision;
persistent_file << data;
}
std::string system_uuid;
};
} // namespaec PersistentData
} // namespace crow