summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTanous <ed.tanous@intel.com>2018-11-05 07:18:10 +0300
committerEd Tanous <ed.tanous@intel.com>2019-04-01 20:01:41 +0300
commitf00032db72e7ee88946bb4839b5d5311a3e092b3 (patch)
tree5bc236c459831bd33a5e8fcaeb60e74b966798a9
parent20e6ea5dbfaa04f4298116281ddfb997847189ce (diff)
downloadbmcweb-f00032db72e7ee88946bb4839b5d5311a3e092b3.tar.xz
Allow multiple registrations
This patchset is the beginings of the infrastructure to allow separate registrations, and map privileges to the actual node in the url table rather than having each registration manage privileges manually. Tested by: Running redfish compliance tool. All things still pass. Change-Id: I72d278cc19c60ba5b6e563fbd705b0551faf9a6a Signed-off-by: Ed Tanous <ed.tanous@intel.com>
-rw-r--r--crow/include/crow/app.h2
-rw-r--r--crow/include/crow/routing.h252
-rw-r--r--include/http_utility.hpp2
-rw-r--r--include/openbmc_dbus_rest.hpp29
-rw-r--r--redfish-core/include/node.hpp125
-rw-r--r--redfish-core/include/privileges.hpp4
-rw-r--r--redfish-core/include/redfish.hpp5
-rw-r--r--redfish-core/lib/account_service.hpp1
-rw-r--r--redfish-core/lib/redfish_sessions.hpp1
9 files changed, 292 insertions, 129 deletions
diff --git a/crow/include/crow/app.h b/crow/include/crow/app.h
index f1f3687723..95bbaed0bc 100644
--- a/crow/include/crow/app.h
+++ b/crow/include/crow/app.h
@@ -1,5 +1,7 @@
#pragma once
+#include "privileges.hpp"
+
#include <chrono>
#include <cstdint>
#include <functional>
diff --git a/crow/include/crow/routing.h b/crow/include/crow/routing.h
index 746e115894..e657e2ef1b 100644
--- a/crow/include/crow/routing.h
+++ b/crow/include/crow/routing.h
@@ -1,7 +1,9 @@
#pragma once
-#include "boost/container/flat_map.hpp"
+#include "privileges.hpp"
+#include <boost/container/flat_map.hpp>
+#include <boost/container/small_vector.hpp>
#include <boost/lexical_cast.hpp>
#include <cerrno>
#include <cstdint>
@@ -21,10 +23,14 @@
namespace crow
{
+
+constexpr int maxHttpVerbCount =
+ static_cast<int>(boost::beast::http::verb::unlink);
+
class BaseRule
{
public:
- BaseRule(std::string rule) : rule(std::move(rule))
+ BaseRule(std::string thisRule) : rule(std::move(thisRule))
{
}
@@ -62,9 +68,29 @@ class BaseRule
return methodsBitfield;
}
- protected:
+ bool checkPrivileges(const redfish::Privileges& userPrivileges)
+ {
+ // If there are no privileges assigned, assume no privileges
+ // required
+ if (privilegesSet.empty())
+ {
+ return true;
+ }
+
+ for (const redfish::Privileges& requiredPrivileges : privilegesSet)
+ {
+ if (userPrivileges.isSupersetOf(requiredPrivileges))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
uint32_t methodsBitfield{1 << (int)boost::beast::http::verb::get};
+ std::vector<redfish::Privileges> privilegesSet;
+
std::string rule;
std::string nameStr;
@@ -178,16 +204,11 @@ template <typename Func, typename... ArgsWrapped> struct Wrapped
const Request&>::value,
int>::type = 0)
{
- handler = (
-#ifdef BMCWEB_CAN_USE_CPP14
- [f = std::move(f)]
-#else
- [f]
-#endif
- (const Request&, Response& res, Args... args) {
- res = Response(f(args...));
- res.end();
- });
+ handler = [f = std::move(f)](const Request&, Response& res,
+ Args... args) {
+ res = Response(f(args...));
+ res.end();
+ };
}
template <typename Req, typename... Args> struct ReqHandlerWrapper
@@ -362,7 +383,7 @@ template <typename T> struct RuleParameterTraits
using self_t = T;
WebSocketRule& websocket()
{
- auto p = new WebSocketRule(((self_t*)this)->rule);
+ WebSocketRule* p = new WebSocketRule(((self_t*)this)->rule);
((self_t*)this)->ruleToUpgrade.reset(p);
return *p;
}
@@ -386,6 +407,23 @@ template <typename T> struct RuleParameterTraits
((self_t*)this)->methodsBitfield |= 1 << (int)method;
return (self_t&)*this;
}
+
+ template <typename... MethodArgs>
+ self_t& requires(std::initializer_list<const char*> l)
+ {
+ ((self_t*)this)->privilegesSet.emplace_back(l);
+ return (self_t&)*this;
+ }
+
+ template <typename... MethodArgs>
+ self_t& requires(const std::vector<redfish::Privileges>& p)
+ {
+ for (const redfish::Privileges& privilege : p)
+ {
+ ((self_t*)this)->privilegesSet.emplace_back(privilege);
+ }
+ return (self_t&)*this;
+ }
};
class DynamicRule : public BaseRule, public RuleParameterTraits<DynamicRule>
@@ -547,7 +585,8 @@ class TaggedRule : public BaseRule,
std::is_same<void, decltype(f(std::declval<crow::Request>(),
std::declval<crow::Response&>(),
std::declval<Args>()...))>::value,
- "Handler function with response argument should have void return "
+ "Handler function with response argument should have void "
+ "return "
"type");
handler = std::move(f);
@@ -599,7 +638,7 @@ class Trie
private:
void optimizeNode(Node* node)
{
- for (auto x : node->paramChildrens)
+ for (unsigned int x : node->paramChildrens)
{
if (!x)
continue;
@@ -609,7 +648,7 @@ class Trie
if (node->children.empty())
return;
bool mergeWithChild = true;
- for (auto& kv : node->children)
+ for (const std::pair<std::string, unsigned>& kv : node->children)
{
Node* child = &nodes[kv.second];
if (!child->isSimpleNode())
@@ -621,10 +660,11 @@ class Trie
if (mergeWithChild)
{
decltype(node->children) merged;
- for (auto& kv : node->children)
+ for (const std::pair<std::string, unsigned>& kv : node->children)
{
Node* child = &nodes[kv.second];
- for (auto& childKv : child->children)
+ for (const std::pair<std::string, unsigned>& childKv :
+ child->children)
{
merged[kv.first + childKv.first] = childKv.second;
}
@@ -634,7 +674,7 @@ class Trie
}
else
{
- for (auto& kv : node->children)
+ for (const std::pair<std::string, unsigned>& kv : node->children)
{
Node* child = &nodes[kv.second];
optimizeNode(child);
@@ -658,13 +698,13 @@ class Trie
void findRouteIndexes(const std::string& req_url,
std::vector<unsigned>& route_indexes,
- const Node* node = nullptr, unsigned pos = 0)
+ const Node* node = nullptr, unsigned pos = 0) const
{
if (node == nullptr)
{
node = head();
}
- for (auto& kv : node->children)
+ for (const std::pair<std::string, unsigned>& kv : node->children)
{
const std::string& fragment = kv.first;
const Node* child = &nodes[kv.second];
@@ -725,7 +765,7 @@ class Trie
if (errno != ERANGE && eptr != req_url.data() + pos)
{
params->intParams.push_back(value);
- auto ret =
+ std::pair<unsigned, RoutingParams> ret =
find(req_url,
&nodes[node->paramChildrens[(int)ParamType::INT]],
eptr - req_url.data(), params);
@@ -747,7 +787,7 @@ class Trie
if (errno != ERANGE && eptr != req_url.data() + pos)
{
params->uintParams.push_back(value);
- auto ret =
+ std::pair<unsigned, RoutingParams> ret =
find(req_url,
&nodes[node->paramChildrens[(int)ParamType::UINT]],
eptr - req_url.data(), params);
@@ -768,7 +808,7 @@ class Trie
if (errno != ERANGE && eptr != req_url.data() + pos)
{
params->doubleParams.push_back(value);
- auto ret = find(
+ std::pair<unsigned, RoutingParams> ret = find(
req_url,
&nodes[node->paramChildrens[(int)ParamType::DOUBLE]],
eptr - req_url.data(), params);
@@ -791,7 +831,7 @@ class Trie
{
params->stringParams.emplace_back(
req_url.substr(pos, epos - pos));
- auto ret =
+ std::pair<unsigned, RoutingParams> ret =
find(req_url,
&nodes[node->paramChildrens[(int)ParamType::STRING]],
epos, params);
@@ -808,7 +848,7 @@ class Trie
{
params->stringParams.emplace_back(
req_url.substr(pos, epos - pos));
- auto ret = find(
+ std::pair<unsigned, RoutingParams> ret = find(
req_url, &nodes[node->paramChildrens[(int)ParamType::PATH]],
epos, params);
updateFound(ret);
@@ -816,14 +856,15 @@ class Trie
}
}
- for (auto& kv : node->children)
+ for (const std::pair<std::string, unsigned>& kv : node->children)
{
const std::string& fragment = kv.first;
const Node* child = &nodes[kv.second];
if (req_url.compare(pos, fragment.size(), fragment) == 0)
{
- auto ret = find(req_url, child, pos + fragment.size(), params);
+ std::pair<unsigned, RoutingParams> ret =
+ find(req_url, child, pos + fragment.size(), params);
updateFound(ret);
}
}
@@ -840,31 +881,29 @@ class Trie
char c = url[i];
if (c == '<')
{
- static struct ParamTraits
+ const static std::array<std::pair<ParamType, std::string>, 7>
+ paramTraits = {{
+ {ParamType::INT, "<int>"},
+ {ParamType::UINT, "<uint>"},
+ {ParamType::DOUBLE, "<float>"},
+ {ParamType::DOUBLE, "<double>"},
+ {ParamType::STRING, "<str>"},
+ {ParamType::STRING, "<string>"},
+ {ParamType::PATH, "<path>"},
+ }};
+
+ for (const std::pair<ParamType, std::string>& x : paramTraits)
{
- ParamType type;
- std::string name;
- } paramTraits[] = {
- {ParamType::INT, "<int>"},
- {ParamType::UINT, "<uint>"},
- {ParamType::DOUBLE, "<float>"},
- {ParamType::DOUBLE, "<double>"},
- {ParamType::STRING, "<str>"},
- {ParamType::STRING, "<string>"},
- {ParamType::PATH, "<path>"},
- };
-
- for (auto& x : paramTraits)
- {
- if (url.compare(i, x.name.size(), x.name) == 0)
+ if (url.compare(i, x.second.size(), x.second) == 0)
{
- if (!nodes[idx].paramChildrens[(int)x.type])
+ if (!nodes[idx].paramChildrens[(int)x.first])
{
- auto newNodeIdx = newNode();
- nodes[idx].paramChildrens[(int)x.type] = newNodeIdx;
+ unsigned newNodeIdx = newNode();
+ nodes[idx].paramChildrens[(int)x.first] =
+ newNodeIdx;
}
- idx = nodes[idx].paramChildrens[(int)x.type];
- i += x.name.size();
+ idx = nodes[idx].paramChildrens[(int)x.first];
+ i += x.second.size();
break;
}
}
@@ -876,7 +915,7 @@ class Trie
std::string piece(&c, 1);
if (!nodes[idx].children.count(piece))
{
- auto newNodeIdx = newNode();
+ unsigned newNodeIdx = newNode();
nodes[idx].children.emplace(piece, newNodeIdx);
}
idx = nodes[idx].children[piece];
@@ -921,7 +960,7 @@ class Trie
debugNodePrint(&nodes[n->paramChildrens[i]], level + 1);
}
}
- for (auto& kv : n->children)
+ for (const std::pair<std::string, unsigned>& kv : n->children)
{
BMCWEB_LOG_DEBUG
<< std::string(2 * level, ' ') /*<< "(" << kv.second << ") "*/
@@ -959,7 +998,7 @@ class Trie
class Router
{
public:
- Router() : rules(2)
+ Router()
{
}
@@ -968,7 +1007,7 @@ class Router
std::unique_ptr<DynamicRule> ruleObject =
std::make_unique<DynamicRule>(rule);
DynamicRule* ptr = ruleObject.get();
- internalAddRuleObject(rule, std::move(ruleObject));
+ allRules.emplace_back(std::move(ruleObject));
return *ptr;
}
@@ -981,45 +1020,67 @@ class Router
TaggedRule>;
std::unique_ptr<RuleT> ruleObject = std::make_unique<RuleT>(rule);
RuleT* ptr = ruleObject.get();
-
- internalAddRuleObject(rule, std::move(ruleObject));
+ allRules.emplace_back(std::move(ruleObject));
return *ptr;
}
- void internalAddRuleObject(const std::string& rule,
- std::unique_ptr<BaseRule> ruleObject)
+ void internalAddRuleObject(const std::string& rule, BaseRule* ruleObject)
{
- rules.emplace_back(std::move(ruleObject));
- trie.add(rule, rules.size() - 1);
-
- // directory case:
- // request to `/about' url matches `/about/' rule
- if (rule.size() > 2 && rule.back() == '/')
+ if (ruleObject == nullptr)
+ {
+ return;
+ }
+ for (uint32_t method = 0, method_bit = 1; method < maxHttpVerbCount;
+ method++, method_bit <<= 1)
{
- trie.add(rule.substr(0, rule.size() - 1), rules.size() - 1);
+ if (ruleObject->methodsBitfield & method_bit)
+ {
+ perMethods[method].rules.emplace_back(ruleObject);
+ perMethods[method].trie.add(
+ rule, perMethods[method].rules.size() - 1);
+ // directory case:
+ // request to `/about' url matches `/about/' rule
+ if (rule.size() > 2 && rule.back() == '/')
+ {
+ perMethods[method].trie.add(
+ rule.substr(0, rule.size() - 1),
+ perMethods[method].rules.size() - 1);
+ }
+ }
}
}
void validate()
{
- trie.validate();
- for (auto& rule : rules)
+ for (std::unique_ptr<BaseRule>& rule : allRules)
{
if (rule)
{
- auto upgraded = rule->upgrade();
+ std::unique_ptr<BaseRule> upgraded = rule->upgrade();
if (upgraded)
rule = std::move(upgraded);
rule->validate();
+ internalAddRuleObject(rule->rule, rule.get());
}
}
+ for (PerMethod& perMethod : perMethods)
+ {
+ perMethod.trie.validate();
+ }
}
template <typename Adaptor>
void handleUpgrade(const Request& req, Response& res, Adaptor&& adaptor)
{
- auto found = trie.find(req.url);
+ if (static_cast<int>(req.method()) >= perMethods.size())
+ return;
+
+ PerMethod& perMethod = perMethods[(int)req.method()];
+ Trie& trie = perMethod.trie;
+ std::vector<BaseRule*>& rules = perMethod.rules;
+
+ const std::pair<unsigned, RoutingParams>& found = trie.find(req.url);
unsigned ruleIndex = found.first;
if (!ruleIndex)
{
@@ -1097,7 +1158,13 @@ class Router
void handle(const Request& req, Response& res)
{
- auto found = trie.find(req.url);
+ if ((int)req.method() >= perMethods.size())
+ return;
+ PerMethod& perMethod = perMethods[(int)req.method()];
+ Trie& trie = perMethod.trie;
+ std::vector<BaseRule*>& rules = perMethod.rules;
+
+ const std::pair<unsigned, RoutingParams>& found = trie.find(req.url);
unsigned ruleIndex = found.first;
@@ -1150,6 +1217,19 @@ class Router
<< (uint32_t)req.method() << " / "
<< rules[ruleIndex]->getMethods();
+ // TODO: load user privileges from configuration as soon as its
+ // available now we are granting all privileges to everyone.
+ redfish::Privileges userPrivileges{"Login", "ConfigureManager",
+ "ConfigureSelf", "ConfigureUsers",
+ "ConfigureComponents"};
+
+ if (!rules[ruleIndex]->checkPrivileges(userPrivileges))
+ {
+ res.result(boost::beast::http::status::method_not_allowed);
+ res.end();
+ return;
+ }
+
// any uncaught exceptions become 500s
try
{
@@ -1175,23 +1255,41 @@ class Router
void debugPrint()
{
- trie.debugPrint();
+ for (int i = 0; i < perMethods.size(); i++)
+ {
+ BMCWEB_LOG_DEBUG << methodName((boost::beast::http::verb)i);
+ perMethods[i].trie.debugPrint();
+ }
}
std::vector<const std::string*> getRoutes(const std::string& parent)
{
- std::vector<unsigned> x;
std::vector<const std::string*> ret;
- trie.findRouteIndexes(parent, x);
- for (unsigned index : x)
+
+ for (const PerMethod& pm : perMethods)
{
- ret.push_back(&rules[index]->rule);
+ std::vector<unsigned> x;
+ pm.trie.findRouteIndexes(parent, x);
+ for (unsigned index : x)
+ {
+ ret.push_back(&pm.rules[index]->rule);
+ }
}
return ret;
}
private:
- std::vector<std::unique_ptr<BaseRule>> rules;
- Trie trie;
+ struct PerMethod
+ {
+ std::vector<BaseRule*> rules;
+ Trie trie;
+ // rule index 0, 1 has special meaning; preallocate it to avoid
+ // duplication.
+ PerMethod() : rules(2)
+ {
+ }
+ };
+ std::array<PerMethod, maxHttpVerbCount> perMethods;
+ std::vector<std::unique_ptr<BaseRule>> allRules;
};
} // namespace crow
diff --git a/include/http_utility.hpp b/include/http_utility.hpp
index e2b1a11f64..b20952b438 100644
--- a/include/http_utility.hpp
+++ b/include/http_utility.hpp
@@ -1,6 +1,8 @@
#pragma once
#include <boost/algorithm/string.hpp>
+#include "crow/http_request.h"
+
namespace http_helpers
{
inline bool requestPrefersHtml(const crow::Request& req)
diff --git a/include/openbmc_dbus_rest.hpp b/include/openbmc_dbus_rest.hpp
index ab35bb2efc..9f7a85508b 100644
--- a/include/openbmc_dbus_rest.hpp
+++ b/include/openbmc_dbus_rest.hpp
@@ -1982,6 +1982,7 @@ inline void handleDBusUrl(const crow::Request &req, crow::Response &res,
template <typename... Middlewares> void requestRoutes(Crow<Middlewares...> &app)
{
BMCWEB_ROUTE(app, "/bus/")
+ .requires({"Login"})
.methods("GET"_method)(
[](const crow::Request &req, crow::Response &res) {
res.jsonValue = {{"busses", {{{"name", "system"}}}},
@@ -1990,6 +1991,7 @@ template <typename... Middlewares> void requestRoutes(Crow<Middlewares...> &app)
});
BMCWEB_ROUTE(app, "/bus/system/")
+ .requires({"Login"})
.methods("GET"_method)(
[](const crow::Request &req, crow::Response &res) {
auto myCallback = [&res](const boost::system::error_code ec,
@@ -2018,13 +2020,23 @@ template <typename... Middlewares> void requestRoutes(Crow<Middlewares...> &app)
});
BMCWEB_ROUTE(app, "/list/")
+ .requires({"Login"})
.methods("GET"_method)(
[](const crow::Request &req, crow::Response &res) {
handleList(res, "/");
});
BMCWEB_ROUTE(app, "/xyz/<path>")
- .methods("GET"_method, "PUT"_method, "POST"_method, "DELETE"_method)(
+ .requires({"Login"})
+ .methods("GET"_method)([](const crow::Request &req, crow::Response &res,
+ const std::string &path) {
+ std::string objectPath = "/xyz/" + path;
+ handleDBusUrl(req, res, objectPath);
+ });
+
+ BMCWEB_ROUTE(app, "/xyz/<path>")
+ .requires({"ConfigureComponents", "ConfigureManager"})
+ .methods("PUT"_method, "POST"_method, "DELETE"_method)(
[](const crow::Request &req, crow::Response &res,
const std::string &path) {
std::string objectPath = "/xyz/" + path;
@@ -2032,14 +2044,24 @@ template <typename... Middlewares> void requestRoutes(Crow<Middlewares...> &app)
});
BMCWEB_ROUTE(app, "/org/<path>")
- .methods("GET"_method, "PUT"_method, "POST"_method, "DELETE"_method)(
+ .requires({"Login"})
+ .methods("GET"_method)([](const crow::Request &req, crow::Response &res,
+ const std::string &path) {
+ std::string objectPath = "/xyz/" + path;
+ handleDBusUrl(req, res, objectPath);
+ });
+
+ BMCWEB_ROUTE(app, "/org/<path>")
+ .requires({"ConfigureComponents", "ConfigureManager"})
+ .methods("PUT"_method, "POST"_method, "DELETE"_method)(
[](const crow::Request &req, crow::Response &res,
const std::string &path) {
- std::string objectPath = "/org/" + path;
+ std::string objectPath = "/xyz/" + path;
handleDBusUrl(req, res, objectPath);
});
BMCWEB_ROUTE(app, "/download/dump/<str>/")
+ .requires({"ConfigureManager"})
.methods("GET"_method)([](const crow::Request &req, crow::Response &res,
const std::string &dumpId) {
std::regex validFilename("^[\\w\\- ]+(\\.?[\\w\\- ]*)$");
@@ -2083,6 +2105,7 @@ template <typename... Middlewares> void requestRoutes(Crow<Middlewares...> &app)
});
BMCWEB_ROUTE(app, "/bus/system/<str>/")
+ .requires({"Login"})
.methods("GET"_method)([](const crow::Request &req, crow::Response &res,
const std::string &Connection) {
introspectObjects(Connection, "/",
diff --git a/redfish-core/include/node.hpp b/redfish-core/include/node.hpp
index 8e94a6f011..58195279e1 100644
--- a/redfish-core/include/node.hpp
+++ b/redfish-core/include/node.hpp
@@ -57,20 +57,88 @@ class Node
template <typename... Params>
Node(CrowApp& app, std::string&& entityUrl, Params... params)
{
- app.routeDynamic(entityUrl.c_str())
- .methods("GET"_method, "PATCH"_method, "POST"_method,
- "DELETE"_method)([&](const crow::Request& req,
- crow::Response& res,
- Params... params) {
- std::vector<std::string> paramVec = {params...};
- dispatchRequest(app, req, res, paramVec);
- });
+ crow::DynamicRule& get = app.routeDynamic(entityUrl.c_str());
+ getRule = &get;
+ get.methods("GET"_method)([this](const crow::Request& req,
+ crow::Response& res,
+ Params... params) {
+ std::vector<std::string> paramVec = {params...};
+ doGet(res, req, paramVec);
+ });
+
+ crow::DynamicRule& patch = app.routeDynamic(entityUrl.c_str());
+ patchRule = &patch;
+ patch.methods("PATCH"_method)([this](const crow::Request& req,
+ crow::Response& res,
+ Params... params) {
+ std::vector<std::string> paramVec = {params...};
+ doPatch(res, req, paramVec);
+ });
+
+ crow::DynamicRule& post = app.routeDynamic(entityUrl.c_str());
+ postRule = &post;
+ post.methods("POST"_method)([this](const crow::Request& req,
+ crow::Response& res,
+ Params... params) {
+ std::vector<std::string> paramVec = {params...};
+ doPost(res, req, paramVec);
+ });
+
+ crow::DynamicRule& delete_ = app.routeDynamic(entityUrl.c_str());
+ deleteRule = &delete_;
+ delete_.methods("DELETE"_method)([this](const crow::Request& req,
+ crow::Response& res,
+ Params... params) {
+ std::vector<std::string> paramVec = {params...};
+ doDelete(res, req, paramVec);
+ });
+ }
+
+ void initPrivileges()
+ {
+ auto it = entityPrivileges.find(boost::beast::http::verb::get);
+ if (it != entityPrivileges.end())
+ {
+ if (getRule != nullptr)
+ {
+ getRule->requires(it->second);
+ }
+ }
+ it = entityPrivileges.find(boost::beast::http::verb::post);
+ if (it != entityPrivileges.end())
+ {
+ if (postRule != nullptr)
+ {
+ postRule->requires(it->second);
+ }
+ }
+ it = entityPrivileges.find(boost::beast::http::verb::patch);
+ if (it != entityPrivileges.end())
+ {
+ if (patchRule != nullptr)
+ {
+ patchRule->requires(it->second);
+ }
+ }
+ it = entityPrivileges.find(boost::beast::http::verb::delete_);
+ if (it != entityPrivileges.end())
+ {
+ if (deleteRule != nullptr)
+ {
+ deleteRule->requires(it->second);
+ }
+ }
}
virtual ~Node() = default;
OperationMap entityPrivileges;
+ crow::DynamicRule* getRule = nullptr;
+ crow::DynamicRule* postRule = nullptr;
+ crow::DynamicRule* patchRule = nullptr;
+ crow::DynamicRule* deleteRule = nullptr;
+
protected:
// Node is designed to be an abstract class, so doGet is pure virtual
virtual void doGet(crow::Response& res, const crow::Request& req,
@@ -100,47 +168,6 @@ class Node
res.result(boost::beast::http::status::method_not_allowed);
res.end();
}
-
- private:
- void dispatchRequest(CrowApp& app, const crow::Request& req,
- crow::Response& res,
- const std::vector<std::string>& params)
- {
- auto ctx =
- app.template getContext<crow::token_authorization::Middleware>(req);
-
- if (!isMethodAllowedForUser(req.method(), entityPrivileges,
- ctx.session->username))
- {
- res.result(boost::beast::http::status::method_not_allowed);
- res.end();
- return;
- }
-
- switch (req.method())
- {
- case "GET"_method:
- doGet(res, req, params);
- break;
-
- case "PATCH"_method:
- doPatch(res, req, params);
- break;
-
- case "POST"_method:
- doPost(res, req, params);
- break;
-
- case "DELETE"_method:
- doDelete(res, req, params);
- break;
-
- default:
- res.result(boost::beast::http::status::not_found);
- res.end();
- }
- return;
- }
};
} // namespace redfish
diff --git a/redfish-core/include/privileges.hpp b/redfish-core/include/privileges.hpp
index 3b20c9fda8..ca44551835 100644
--- a/redfish-core/include/privileges.hpp
+++ b/redfish-core/include/privileges.hpp
@@ -15,7 +15,11 @@
*/
#pragma once
+#include <crow/logging.h>
+
+#include <array>
#include <bitset>
+#include <boost/beast/http/verb.hpp>
#include <boost/container/flat_map.hpp>
#include <cstdint>
#include <vector>
diff --git a/redfish-core/include/redfish.hpp b/redfish-core/include/redfish.hpp
index 2a61c52b48..36b50e87c7 100644
--- a/redfish-core/include/redfish.hpp
+++ b/redfish-core/include/redfish.hpp
@@ -103,6 +103,11 @@ class RedfishService
nodes.emplace_back(std::make_unique<SystemsCollection>(app));
nodes.emplace_back(std::make_unique<Systems>(app));
nodes.emplace_back(std::make_unique<SystemActionsReset>(app));
+
+ for (const auto& node : nodes)
+ {
+ node->initPrivileges();
+ }
}
private:
diff --git a/redfish-core/lib/account_service.hpp b/redfish-core/lib/account_service.hpp
index 9365ebb06f..a5c501d1b6 100644
--- a/redfish-core/lib/account_service.hpp
+++ b/redfish-core/lib/account_service.hpp
@@ -224,6 +224,7 @@ class AccountService : public Node
}
}
};
+
class AccountsCollection : public Node
{
public:
diff --git a/redfish-core/lib/redfish_sessions.hpp b/redfish-core/lib/redfish_sessions.hpp
index 59805a0c46..d4085af9a7 100644
--- a/redfish-core/lib/redfish_sessions.hpp
+++ b/redfish-core/lib/redfish_sessions.hpp
@@ -139,6 +139,7 @@ class SessionCollection : public Node
res.jsonValue["Members"].push_back(
{{"@odata.id", "/redfish/v1/SessionService/Sessions/" + *uid}});
}
+ res.jsonValue["Members@odata.count"] = sessionIds.size();
res.jsonValue["@odata.type"] = "#SessionCollection.SessionCollection";
res.jsonValue["@odata.id"] = "/redfish/v1/SessionService/Sessions/";
res.jsonValue["@odata.context"] =