diff options
author | Ed Tanous <edtanous@google.com> | 2022-04-05 19:58:00 +0300 |
---|---|---|
committer | Ed Tanous <ed@tanous.net> | 2022-04-28 20:55:32 +0300 |
commit | c937d2bfefa3ff91b7175d9684f99712ec9b88e5 (patch) | |
tree | c693a8426d6a8100ade6aea8f28c42833554952d /redfish-core/lib | |
parent | 5e52870bbadc7e35ff47325ffa668a6b82bf9c4a (diff) | |
download | bmcweb-c937d2bfefa3ff91b7175d9684f99712ec9b88e5.tar.xz |
Make log services use parameter delegation
The commit prior to this one added support for delegation of $expand and
$only query param types; This commit adds support for delegation of top
and skip (which we already have a few handlers for) and moves them to
the new style.
Note, this makes top and skip query params NOT below the
insecure-enable-redfish-query. top and skip have existed for a while,
and are unlikely to have security issues, as they're relatively simple
transforms.
Tested:
curl --insecure --user root:0penBmc https://192.168.7.2/redfish/v1/Managers/bmc/LogServices/Journal/Entries\?\$top\=3\&\$skip\=0
With varying $top between 1-5 and $skip between 0-5 gave the expected
number of log results.
Unit tests pass.
Signed-off-by: Ed Tanous <edtanous@google.com>
Change-Id: Ia213a5e929c40579825eaf251e4b9159bc84c802
Diffstat (limited to 'redfish-core/lib')
-rw-r--r-- | redfish-core/lib/log_services.hpp | 151 |
1 files changed, 47 insertions, 104 deletions
diff --git a/redfish-core/lib/log_services.hpp b/redfish-core/lib/log_services.hpp index 49911f31d4..3a8ce10900 100644 --- a/redfish-core/lib/log_services.hpp +++ b/redfish-core/lib/log_services.hpp @@ -180,49 +180,6 @@ inline static bool getEntryTimestamp(sd_journal* journal, return true; } -static bool getSkipParam(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, - const crow::Request& req, uint64_t& skip) -{ - boost::urls::params_view::iterator it = req.urlView.params().find("$skip"); - if (it != req.urlView.params().end()) - { - std::from_chars_result r = std::from_chars( - (*it).value.data(), (*it).value.data() + (*it).value.size(), skip); - if (r.ec != std::errc()) - { - messages::queryParameterValueTypeError(asyncResp->res, "", "$skip"); - return false; - } - } - return true; -} - -static constexpr const uint64_t maxEntriesPerPage = 1000; -static bool getTopParam(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, - const crow::Request& req, uint64_t& top) -{ - boost::urls::params_view::iterator it = req.urlView.params().find("$top"); - if (it != req.urlView.params().end()) - { - std::from_chars_result r = std::from_chars( - (*it).value.data(), (*it).value.data() + (*it).value.size(), top); - if (r.ec != std::errc()) - { - messages::queryParameterValueTypeError(asyncResp->res, "", "$top"); - return false; - } - if (top < 1U || top > maxEntriesPerPage) - { - - messages::queryParameterOutOfRange( - asyncResp->res, std::to_string(top), "$top", - "1-" + std::to_string(maxEntriesPerPage)); - return false; - } - } - return true; -} - inline static bool getUniqueEntryID(sd_journal* journal, std::string& entryID, const bool firstEntry = true) { @@ -1200,17 +1157,13 @@ inline void requestRoutesJournalEventLogEntryCollection(App& app) const std::shared_ptr< bmcweb::AsyncResp>& asyncResp) { - if (!redfish::setUpRedfishRoute(app, req, asyncResp->res)) - { - return; - } - uint64_t skip = 0; - uint64_t top = maxEntriesPerPage; // Show max entries by default - if (!getSkipParam(asyncResp, req, skip)) - { - return; - } - if (!getTopParam(asyncResp, req, top)) + query_param::QueryCapabilities capabilities = { + .canDelegateTop = true, + .canDelegateSkip = true, + }; + query_param::Query delegatedQuery; + if (!redfish::setUpRedfishRouteWithDelegation( + app, req, asyncResp->res, delegatedQuery, capabilities)) { return; } @@ -1252,7 +1205,8 @@ inline void requestRoutesJournalEventLogEntryCollection(App& app) // Handle paging using skip (number of entries to skip // from the start) and top (number of entries to // display) - if (entryCount <= skip || entryCount > skip + top) + if (entryCount <= delegatedQuery.skip || + entryCount > delegatedQuery.skip + delegatedQuery.top) { continue; } @@ -1279,11 +1233,11 @@ inline void requestRoutesJournalEventLogEntryCollection(App& app) } } asyncResp->res.jsonValue["Members@odata.count"] = entryCount; - if (skip + top < entryCount) + if (delegatedQuery.skip + delegatedQuery.top < entryCount) { asyncResp->res.jsonValue["Members@odata.nextLink"] = "/redfish/v1/Systems/system/LogServices/EventLog/Entries?$skip=" + - std::to_string(skip + top); + std::to_string(delegatedQuery.skip + delegatedQuery.top); } }); } @@ -1861,7 +1815,7 @@ inline bool inline bool getHostLoggerEntries(std::vector<std::filesystem::path>& hostLoggerFiles, - uint64_t& skip, uint64_t& top, + uint64_t skip, uint64_t top, std::vector<std::string>& logEntries, size_t& logCount) { GzFileReader logFile; @@ -1940,19 +1894,13 @@ inline void requestRoutesSystemHostLoggerCollection(App& app) const std::shared_ptr< bmcweb::AsyncResp>& asyncResp) { - if (!redfish::setUpRedfishRoute(app, req, asyncResp->res)) - { - return; - } - uint64_t skip = 0; - uint64_t top = maxEntriesPerPage; // Show max 1000 entries by - // default, allow range 1 to - // 1000 entries per page. - if (!getSkipParam(asyncResp, req, skip)) - { - return; - } - if (!getTopParam(asyncResp, req, top)) + query_param::QueryCapabilities capabilities = { + .canDelegateTop = true, + .canDelegateSkip = true, + }; + query_param::Query delegatedQuery; + if (!redfish::setUpRedfishRouteWithDelegation( + app, req, asyncResp->res, delegatedQuery, capabilities)) { return; } @@ -1978,8 +1926,8 @@ inline void requestRoutesSystemHostLoggerCollection(App& app) // This vector only store the entries we want to expose that // control by skip and top. std::vector<std::string> logEntries; - if (!getHostLoggerEntries(hostLoggerFiles, skip, top, logEntries, - logCount)) + if (!getHostLoggerEntries(hostLoggerFiles, delegatedQuery.skip, + delegatedQuery.top, logEntries, logCount)) { messages::internalError(asyncResp->res); return; @@ -1997,16 +1945,18 @@ inline void requestRoutesSystemHostLoggerCollection(App& app) { logEntryArray.push_back({}); nlohmann::json& hostLogEntry = logEntryArray.back(); - fillHostLoggerEntryJson(std::to_string(skip + i), - logEntries[i], hostLogEntry); + fillHostLoggerEntryJson( + std::to_string(delegatedQuery.skip + i), logEntries[i], + hostLogEntry); } asyncResp->res.jsonValue["Members@odata.count"] = logCount; - if (skip + top < logCount) + if (delegatedQuery.skip + delegatedQuery.top < logCount) { asyncResp->res.jsonValue["Members@odata.nextLink"] = "/redfish/v1/Systems/system/LogServices/HostLogger/Entries?$skip=" + - std::to_string(skip + top); + std::to_string(delegatedQuery.skip + + delegatedQuery.top); } } }); @@ -2219,18 +2169,13 @@ inline void requestRoutesBMCJournalLogEntryCollection(App& app) const std::shared_ptr< bmcweb::AsyncResp>& asyncResp) { - if (!redfish::setUpRedfishRoute(app, req, asyncResp->res)) - { - return; - } - static constexpr const long maxEntriesPerPage = 1000; - uint64_t skip = 0; - uint64_t top = maxEntriesPerPage; // Show max entries by default - if (!getSkipParam(asyncResp, req, skip)) - { - return; - } - if (!getTopParam(asyncResp, req, top)) + query_param::QueryCapabilities capabilities = { + .canDelegateTop = true, + .canDelegateSkip = true, + }; + query_param::Query delegatedQuery; + if (!redfish::setUpRedfishRouteWithDelegation( + app, req, asyncResp->res, delegatedQuery, capabilities)) { return; } @@ -2268,7 +2213,8 @@ inline void requestRoutesBMCJournalLogEntryCollection(App& app) entryCount++; // Handle paging using skip (number of entries to skip from // the start) and top (number of entries to display) - if (entryCount <= skip || entryCount > skip + top) + if (entryCount <= delegatedQuery.skip || + entryCount > delegatedQuery.skip + delegatedQuery.top) { continue; } @@ -2294,11 +2240,11 @@ inline void requestRoutesBMCJournalLogEntryCollection(App& app) } } asyncResp->res.jsonValue["Members@odata.count"] = entryCount; - if (skip + top < entryCount) + if (delegatedQuery.skip + delegatedQuery.top < entryCount) { asyncResp->res.jsonValue["Members@odata.nextLink"] = "/redfish/v1/Managers/bmc/LogServices/Journal/Entries?$skip=" + - std::to_string(skip + top); + std::to_string(delegatedQuery.skip + delegatedQuery.top); } }); } @@ -3478,7 +3424,13 @@ inline void requestRoutesPostCodesEntryCollection(App& app) .methods(boost::beast::http::verb::get)( [&app](const crow::Request& req, const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { - if (!redfish::setUpRedfishRoute(app, req, asyncResp->res)) + query_param::QueryCapabilities capabilities = { + .canDelegateTop = true, + .canDelegateSkip = true, + }; + query_param::Query delegatedQuery; + if (!redfish::setUpRedfishRouteWithDelegation( + app, req, asyncResp->res, delegatedQuery, capabilities)) { return; } @@ -3492,17 +3444,8 @@ inline void requestRoutesPostCodesEntryCollection(App& app) asyncResp->res.jsonValue["Members"] = nlohmann::json::array(); asyncResp->res.jsonValue["Members@odata.count"] = 0; - uint64_t skip = 0; - uint64_t top = maxEntriesPerPage; // Show max entries by default - if (!getSkipParam(asyncResp, req, skip)) - { - return; - } - if (!getTopParam(asyncResp, req, top)) - { - return; - } - getCurrentBootNumber(asyncResp, skip, top); + getCurrentBootNumber(asyncResp, delegatedQuery.skip, + delegatedQuery.top); }); } |