summaryrefslogtreecommitdiff
path: root/include/persistent_data.hpp
diff options
context:
space:
mode:
authorEd Tanous <ed@tanous.net>2020-07-18 23:51:21 +0300
committerEd Tanous <ed@tanous.net>2020-08-17 23:54:37 +0300
commit52cc112d962920b035c870127784bcbd98948fad (patch)
treecef270a89373ad55b15578d9a52c5956aa5d3f7e /include/persistent_data.hpp
parentd6c414f36c66b03f272f0cfc3a2e2d5dc0df1271 (diff)
downloadbmcweb-52cc112d962920b035c870127784bcbd98948fad.tar.xz
Remove middlewares
Middlewares, while kinda cool from an academic standpoint, make our build times even worse than they already are. Given that we only really use 1 real middleware today (token auth) and it needs to move into the parser mode anyway (for security limiting buffer sizes), we might as well use this as an opportunity to delete some code. Some other things that happen: 1. Persistent data now moves out of the crow namespace 2. App is no longer a template 3. All request_routes implementations no longer become templates. This should be a decent (unmeasured) win on compile times. This commit was part of a commit previously called "various cleanups". This separates ONLY the middleware deletion part of that. Note, this also deletes about 400 lines of hard to understand code. Change-Id: I4c19e25491a153a2aa2e4ef46fc797bcb5b3581a Signed-off-by: Ed Tanous <ed@tanous.net>
Diffstat (limited to 'include/persistent_data.hpp')
-rw-r--r--include/persistent_data.hpp173
1 files changed, 173 insertions, 0 deletions
diff --git a/include/persistent_data.hpp b/include/persistent_data.hpp
new file mode 100644
index 0000000000..5d4661c503
--- /dev/null
+++ b/include/persistent_data.hpp
@@ -0,0 +1,173 @@
+#pragma once
+
+#include <app.h>
+#include <http_request.h>
+#include <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>
+#include <nlohmann/json.hpp>
+#include <pam_authenticate.hpp>
+#include <sessions.hpp>
+
+#include <filesystem>
+#include <fstream>
+#include <random>
+
+namespace persistent_data
+{
+
+class ConfigFile
+{
+ uint64_t jsonRevision = 1;
+
+ public:
+ // todo(ed) should read this from a fixed location somewhere, not CWD
+ static constexpr const char* filename = "bmcweb_persistent_data.json";
+
+ ConfigFile()
+ {
+ readData();
+ }
+
+ ~ConfigFile()
+ {
+ if (persistent_data::SessionStore::getInstance().needsWrite())
+ {
+ writeData();
+ }
+ }
+
+ // 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 readData()
+ {
+ std::ifstream persistentFile(filename);
+ uint64_t fileRevision = 0;
+ if (persistentFile.is_open())
+ {
+ // call with exceptions disabled
+ auto data = nlohmann::json::parse(persistentFile, nullptr, false);
+ if (data.is_discarded())
+ {
+ BMCWEB_LOG_ERROR
+ << "Error parsing persistent data in json file.";
+ }
+ else
+ {
+ for (const auto& item : data.items())
+ {
+ if (item.key() == "revision")
+ {
+ fileRevision = 0;
+
+ const uint64_t* uintPtr =
+ item.value().get_ptr<const uint64_t*>();
+ if (uintPtr == nullptr)
+ {
+ BMCWEB_LOG_ERROR << "Failed to read revision flag";
+ }
+ else
+ {
+ fileRevision = *uintPtr;
+ }
+ }
+ else if (item.key() == "system_uuid")
+ {
+ const std::string* jSystemUuid =
+ item.value().get_ptr<const std::string*>();
+ if (jSystemUuid != nullptr)
+ {
+ systemUuid = *jSystemUuid;
+ }
+ }
+ else if (item.key() == "auth_config")
+ {
+ SessionStore::getInstance()
+ .getAuthMethodsConfig()
+ .fromJson(item.value());
+ }
+ else if (item.key() == "sessions")
+ {
+ for (const auto& elem : item.value())
+ {
+ std::shared_ptr<UserSession> newSession =
+ UserSession::fromJson(elem);
+
+ if (newSession == nullptr)
+ {
+ BMCWEB_LOG_ERROR << "Problem reading session "
+ "from persistent store";
+ continue;
+ }
+
+ BMCWEB_LOG_DEBUG
+ << "Restored session: " << newSession->csrfToken
+ << " " << newSession->uniqueId << " "
+ << newSession->sessionToken;
+ SessionStore::getInstance().authTokens.emplace(
+ newSession->sessionToken, newSession);
+ }
+ }
+ else
+ {
+ // Do nothing in the case of extra fields. We may have
+ // cases where fields are added in the future, and we
+ // want to at least attempt to gracefully support
+ // downgrades in that case, even if we don't officially
+ // support it
+ }
+ }
+ }
+ }
+ bool needWrite = false;
+
+ if (systemUuid.empty())
+ {
+ systemUuid =
+ boost::uuids::to_string(boost::uuids::random_generator()());
+ needWrite = true;
+ }
+ if (fileRevision < jsonRevision)
+ {
+ needWrite = true;
+ }
+ // write revision changes or system uuid changes immediately
+ if (needWrite)
+ {
+ writeData();
+ }
+ }
+
+ void writeData()
+ {
+ std::ofstream persistentFile(filename);
+
+ // set the permission of the file to 640
+ std::filesystem::perms permission =
+ std::filesystem::perms::owner_read |
+ std::filesystem::perms::owner_write |
+ std::filesystem::perms::group_read;
+ std::filesystem::permissions(filename, permission);
+
+ nlohmann::json data{
+ {"sessions", SessionStore::getInstance().authTokens},
+ {"auth_config", SessionStore::getInstance().getAuthMethodsConfig()},
+ {"system_uuid", systemUuid},
+ {"revision", jsonRevision}};
+ persistentFile << data;
+ }
+
+ std::string systemUuid{""};
+};
+
+inline ConfigFile& getConfig()
+{
+ static ConfigFile f;
+ return f;
+}
+
+} // namespace persistent_data