summaryrefslogtreecommitdiff
path: root/redfish-core/lib
diff options
context:
space:
mode:
authorEd Tanous <edtanous@google.com>2022-04-05 19:58:00 +0300
committerEd Tanous <ed@tanous.net>2022-04-28 20:55:32 +0300
commitc937d2bfefa3ff91b7175d9684f99712ec9b88e5 (patch)
treec693a8426d6a8100ade6aea8f28c42833554952d /redfish-core/lib
parent5e52870bbadc7e35ff47325ffa668a6b82bf9c4a (diff)
downloadbmcweb-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.hpp151
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);
});
}