diff options
| author | Kowalski, Kamil <kamil.kowalski@intel.com> | 2018-02-15 15:26:51 +0100 |
|---|---|---|
| committer | Ed Tanous <ed.tanous@intel.com> | 2018-03-06 22:35:06 +0000 |
| commit | 5cef0f7d3434858e1ba25c209acb606814c20cda (patch) | |
| tree | 06905ed7efc0bfcb099275c1de984dc9fd681779 /include | |
| parent | 7fdc97c3e519ef7921a4654084ea0c63f738a75c (diff) | |
| download | bmcweb-5cef0f7d3434858e1ba25c209acb606814c20cda.tar.gz bmcweb-5cef0f7d3434858e1ba25c209acb606814c20cda.zip | |
Reimplement presistent data loading in no-throw way
Reimplemented persistent data file loading in no-throw approach
to avoid errors during startup when bmcweb_persistent_data.json
has been corrupted. Additionally this will allow to turn off all
exceptions in the project (removed try-catch).
Change-Id: I9bf863ebfd7ce9125d1e7e948f7ac739db94e009
Signed-off-by: Kowalski, Kamil <kamil.kowalski@intel.com>
Signed-off-by: Ed Tanous <ed.tanous@intel.com>
Diffstat (limited to 'include')
| -rw-r--r-- | include/persistent_data_middleware.hpp | 34 | ||||
| -rw-r--r-- | include/sessions.hpp | 60 |
2 files changed, 73 insertions, 21 deletions
diff --git a/include/persistent_data_middleware.hpp b/include/persistent_data_middleware.hpp index 9d6195c..fcab52f 100644 --- a/include/persistent_data_middleware.hpp +++ b/include/persistent_data_middleware.hpp @@ -47,10 +47,36 @@ class Middleware { // call with exceptions disabled auto data = nlohmann::json::parse(persistent_file, nullptr, false); if (!data.is_discarded()) { - file_revision = data.value("revision", 0); - PersistentData::session_store->auth_tokens = - data.value("sessions", decltype(session_store->auth_tokens)()); - system_uuid = data.value("system_uuid", ""); + 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; diff --git a/include/sessions.hpp b/include/sessions.hpp index 6d4ab4d..90df93e 100644 --- a/include/sessions.hpp +++ b/include/sessions.hpp @@ -28,6 +28,49 @@ struct UserSession { std::string csrf_token; std::chrono::time_point<std::chrono::steady_clock> last_updated; PersistenceType persistence; + + /** + * @brief Fills object with data from UserSession's JSON representation + * + * This replaces nlohmann's from_json to ensure no-throw approach + * + * @param[in] j JSON object from which data should be loaded + * + * @return true if data has been loaded properly, false otherwise + */ + bool fromJson(const nlohmann::json& j) { + auto jUid = j.find("unique_id"); + auto jToken = j.find("session_token"); + auto jUsername = j.find("username"); + auto jCsrf = j.find("csrf_token"); + + // Verify existence + if (jUid == j.end() || jToken == j.end() || jUsername == j.end() || + jCsrf == j.end()) { + return false; + } + + // Verify types + if (!jUid->is_string() || !jToken->is_string() || !jUsername->is_string() || + !jCsrf->is_string()) { + return false; + } + + unique_id = jUid->get<std::string>(); + session_token = jToken->get<std::string>(); + username = jUsername->get<std::string>(); + csrf_token = jCsrf->get<std::string>(); + + // For now, sessions that were persisted through a reboot get their timer + // reset. This could probably be overcome with a better understanding of + // wall clock time and steady timer time, possibly persisting values with + // wall clock time instead of steady timer, but the tradeoffs of all the + // corner cases involved are non-trivial, so this is done temporarily + last_updated = std::chrono::steady_clock::now(); + persistence = PersistenceType::TIMEOUT; + + return true; + } }; void to_json(nlohmann::json& j, const UserSession& p) { @@ -39,23 +82,6 @@ void to_json(nlohmann::json& j, const UserSession& p) { } } -void from_json(const nlohmann::json& j, UserSession& p) { - try { - p.unique_id = j.at("unique_id").get<std::string>(); - p.session_token = j.at("session_token").get<std::string>(); - p.username = j.at("username").get<std::string>(); - p.csrf_token = j.at("csrf_token").get<std::string>(); - // For now, sessions that were persisted through a reboot get their timer - // reset. This could probably be overcome with a better understanding of - // wall clock time and steady timer time, possibly persisting values with - // wall clock time instead of steady timer, but the tradeoffs of all the - // corner cases involved are non-trivial, so this is done temporarily - p.last_updated = std::chrono::steady_clock::now(); - } catch (std::out_of_range) { - // do nothing. Session API incompatibility, leave sessions empty - } -} - class Middleware; class SessionStore { |

