summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTanous <ed.tanous@intel.com>2018-11-05 01:18:10 -0300
committerEd Tanous <ed.tanous@intel.com>2019-04-01 17:01:41 +0000
commitf00032db72e7ee88946bb4839b5d5311a3e092b3 (patch)
tree5bc236c459831bd33a5e8fcaeb60e74b966798a9
parent20e6ea5dbfaa04f4298116281ddfb997847189ce (diff)
downloadbmcweb-f00032db72e7ee88946bb4839b5d5311a3e092b3.tar.gz
bmcweb-f00032db72e7ee88946bb4839b5d5311a3e092b3.zip
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 f1f3687..95bbaed 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 746e115..e657e2e 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 e2b1a11..b20952b 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 ab35bb2..9f7a855 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 8e94a6f..5819527 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 3b20c9f..ca44551 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 2a61c52..36b50e8 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 9365ebb..a5c501d 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 59805a0..d4085af 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"] =
OpenPOWER on IntegriCloud