summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/webserver_common.hpp24
-rw-r--r--redfish-core/include/node.hpp69
-rw-r--r--redfish-core/include/redfish.hpp6
-rw-r--r--redfish-core/lib/account_service.hpp32
-rw-r--r--redfish-core/lib/redfish_sessions.hpp43
-rw-r--r--redfish-core/lib/roles.hpp48
-rw-r--r--redfish-core/lib/service_root.hpp24
-rw-r--r--src/webserver_main.cpp6
8 files changed, 143 insertions, 109 deletions
diff --git a/include/webserver_common.hpp b/include/webserver_common.hpp
new file mode 100644
index 0000000000..fcfd3218d8
--- /dev/null
+++ b/include/webserver_common.hpp
@@ -0,0 +1,24 @@
+/*
+// Copyright (c) 2018 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+#pragma once
+
+#include "token_authorization_middleware.hpp"
+#include "webserver_common.hpp"
+
+using CrowApp = crow::App<crow::PersistentData::Middleware,
+ crow::TokenAuthorization::Middleware,
+ crow::SecurityHeadersMiddleware>;
+
diff --git a/redfish-core/include/node.hpp b/redfish-core/include/node.hpp
index a76e5b370e..908d1a6a64 100644
--- a/redfish-core/include/node.hpp
+++ b/redfish-core/include/node.hpp
@@ -17,6 +17,7 @@
#include "privileges.hpp"
#include "token_authorization_middleware.hpp"
+#include "webserver_common.hpp"
#include "crow.h"
namespace redfish {
@@ -27,7 +28,7 @@ namespace redfish {
*/
class Node {
public:
- template <typename CrowApp, typename... Params>
+ template <typename... Params>
Node(CrowApp& app, EntityPrivileges&& entityPrivileges,
std::string&& entityUrl, Params... params)
: entityPrivileges(std::move(entityPrivileges)) {
@@ -42,6 +43,49 @@ class Node {
virtual ~Node() = default;
+ std::string getUrl() const {
+ auto odataId = json.find("@odata.id");
+ if (odataId != json.end() && odataId->is_string()) {
+ return odataId->get<std::string>();
+ }
+ return std::string();
+ }
+
+ /**
+ * @brief Inserts subroute fields into for the node's json in the form:
+ * "subroute_name" : { "odata.id": "node_url/subroute_name/" }
+ * Excludes metadata urls starting with "$" and child urls having
+ * more than one level.
+ *
+ * @return None
+ */
+ void getSubRoutes(const std::vector<std::unique_ptr<Node>>& allNodes) {
+ std::string url = getUrl();
+
+ for (const auto& node : allNodes) {
+ auto route = node->getUrl();
+
+ if (boost::starts_with(route, url)) {
+ auto subRoute = route.substr(url.size());
+ if (subRoute.empty()) {
+ continue;
+ }
+
+ if (subRoute.at(0) == '/') {
+ subRoute = subRoute.substr(1);
+ }
+
+ if (subRoute.at(subRoute.size() - 1) == '/') {
+ subRoute = subRoute.substr(0, subRoute.size() - 1);
+ }
+
+ if (subRoute[0] != '$' && subRoute.find('/') == std::string::npos) {
+ json[subRoute] = nlohmann::json{{"@odata.id", route}};
+ }
+ }
+ }
+ }
+
protected:
// Node is designed to be an abstract class, so doGet is pure virtual
virtual void doGet(crow::response& res, const crow::request& req,
@@ -65,8 +109,9 @@ class Node {
res.end();
}
+ nlohmann::json json;
+
private:
- template <typename CrowApp>
void dispatchRequest(CrowApp& app, const crow::request& req,
crow::response& res,
const std::vector<std::string>& params) {
@@ -107,24 +152,4 @@ class Node {
EntityPrivileges entityPrivileges;
};
-template <typename CrowApp>
-void getRedfishSubRoutes(CrowApp& app, const std::string& url,
- nlohmann::json& j) {
- std::vector<const std::string*> routes = app.get_routes(url);
-
- for (auto route : routes) {
- auto redfishSubRoute =
- route->substr(url.size(), route->size() - url.size() - 1);
-
- // Exclude: - exact matches,
- // - metadata urls starting with "$",
- // - urls at the same level
- if (!redfishSubRoute.empty() && redfishSubRoute[0] != '$' &&
- redfishSubRoute.find('/') == std::string::npos) {
- j[redfishSubRoute] = nlohmann::json{{"@odata.id", *route}};
- }
- }
-}
-
} // namespace redfish
-
diff --git a/redfish-core/include/redfish.hpp b/redfish-core/include/redfish.hpp
index 0e059b8678..fc8c0800a6 100644
--- a/redfish-core/include/redfish.hpp
+++ b/redfish-core/include/redfish.hpp
@@ -19,6 +19,7 @@
#include "../lib/redfish_sessions.hpp"
#include "../lib/roles.hpp"
#include "../lib/service_root.hpp"
+#include "webserver_common.hpp"
namespace redfish {
/*
@@ -33,13 +34,16 @@ class RedfishService {
*
* @param[in] app Crow app on which Redfish will initialize
*/
- template <typename CrowApp>
RedfishService(CrowApp& app) {
nodes.emplace_back(std::make_unique<AccountService>(app));
nodes.emplace_back(std::make_unique<SessionCollection>(app));
nodes.emplace_back(std::make_unique<Roles>(app));
nodes.emplace_back(std::make_unique<RoleCollection>(app));
nodes.emplace_back(std::make_unique<ServiceRoot>(app));
+
+ for (auto& node : nodes) {
+ node->getSubRoutes(nodes);
+ }
}
private:
diff --git a/redfish-core/lib/account_service.hpp b/redfish-core/lib/account_service.hpp
index 5cbc034f11..dafa6055a3 100644
--- a/redfish-core/lib/account_service.hpp
+++ b/redfish-core/lib/account_service.hpp
@@ -33,31 +33,29 @@ class AccountService : public Node {
AccountService(CrowApp& app)
: Node(app, EntityPrivileges(std::move(accountServiceOpMap)),
"/redfish/v1/AccountService/") {
- nodeJson["@odata.id"] = "/redfish/v1/AccountService";
- nodeJson["@odata.type"] = "#AccountService.v1_1_0.AccountService";
- nodeJson["@odata.context"] =
+ Node::json["@odata.id"] = "/redfish/v1/AccountService";
+ Node::json["@odata.type"] = "#AccountService.v1_1_0.AccountService";
+ Node::json["@odata.context"] =
"/redfish/v1/$metadata#AccountService.AccountService";
- nodeJson["Id"] = "AccountService";
- nodeJson["Description"] = "BMC User Accounts";
- nodeJson["Name"] = "Account Service";
- nodeJson["Status"]["State"] = "Enabled";
- nodeJson["Status"]["Health"] = "OK";
- nodeJson["Status"]["HealthRollup"] = "OK";
- nodeJson["ServiceEnabled"] = true;
- nodeJson["MinPasswordLength"] = 1;
- nodeJson["MaxPasswordLength"] = 20;
- nodeJson["Accounts"]["@odata.id"] = "/redfish/v1/AccountService/Accounts";
- nodeJson["Roles"]["@odata.id"] = "/redfish/v1/AccountService/Roles";
+ Node::json["Id"] = "AccountService";
+ Node::json["Description"] = "BMC User Accounts";
+ Node::json["Name"] = "Account Service";
+ Node::json["Status"]["State"] = "Enabled";
+ Node::json["Status"]["Health"] = "OK";
+ Node::json["Status"]["HealthRollup"] = "OK";
+ Node::json["ServiceEnabled"] = true;
+ Node::json["MinPasswordLength"] = 1;
+ Node::json["MaxPasswordLength"] = 20;
+ Node::json["Accounts"]["@odata.id"] = "/redfish/v1/AccountService/Accounts";
+ Node::json["Roles"]["@odata.id"] = "/redfish/v1/AccountService/Roles";
}
private:
void doGet(crow::response& res, const crow::request& req,
const std::vector<std::string>& params) override {
- res.json_value = nodeJson;
+ res.json_value = Node::json;
res.end();
}
-
- nlohmann::json nodeJson;
};
} // namespace redfish
diff --git a/redfish-core/lib/redfish_sessions.hpp b/redfish-core/lib/redfish_sessions.hpp
index 58d5b94912..75857a1528 100644
--- a/redfish-core/lib/redfish_sessions.hpp
+++ b/redfish-core/lib/redfish_sessions.hpp
@@ -40,14 +40,13 @@ class SessionCollection;
class Sessions : public Node {
public:
- template <typename CrowApp>
Sessions(CrowApp& app)
: Node(app, EntityPrivileges(std::move(sessionOpMap)),
"/redfish/v1/SessionService/Sessions/<str>", std::string()) {
- nodeJson["@odata.type"] = "#Session.v1_0_2.Session";
- nodeJson["@odata.context"] = "/redfish/v1/$metadata#Session.Session";
- nodeJson["Name"] = "User Session";
- nodeJson["Description"] = "Manager User Session";
+ Node::json["@odata.type"] = "#Session.v1_0_2.Session";
+ Node::json["@odata.context"] = "/redfish/v1/$metadata#Session.Session";
+ Node::json["Name"] = "User Session";
+ Node::json["Description"] = "Manager User Session";
}
private:
@@ -62,12 +61,12 @@ class Sessions : public Node {
return;
}
- nodeJson["Id"] = session->unique_id;
- nodeJson["UserName"] = session->username;
- nodeJson["@odata.id"] =
+ Node::json["Id"] = session->unique_id;
+ Node::json["UserName"] = session->username;
+ Node::json["@odata.id"] =
"/redfish/v1/SessionService/Sessions/" + session->unique_id;
- res.json_value = nodeJson;
+ res.json_value = Node::json;
res.end();
}
@@ -100,25 +99,22 @@ class Sessions : public Node {
* data for created member which should match member's doGet result in 100%
*/
friend SessionCollection;
-
- nlohmann::json nodeJson;
};
class SessionCollection : public Node {
public:
- template <typename CrowApp>
SessionCollection(CrowApp& app)
: Node(app, EntityPrivileges(std::move(sessionCollectionOpMap)),
"/redfish/v1/SessionService/Sessions/"),
memberSession(app) {
- nodeJson["@odata.type"] = "#SessionCollection.SessionCollection";
- nodeJson["@odata.id"] = "/redfish/v1/SessionService/Sessions/";
- nodeJson["@odata.context"] =
+ Node::json["@odata.type"] = "#SessionCollection.SessionCollection";
+ Node::json["@odata.id"] = "/redfish/v1/SessionService/Sessions/";
+ Node::json["@odata.context"] =
"/redfish/v1/$metadata#SessionCollection.SessionCollection";
- nodeJson["Name"] = "Session Collection";
- nodeJson["Description"] = "Session Collection";
- nodeJson["Members@odata.count"] = 0;
- nodeJson["Members"] = nlohmann::json::array();
+ Node::json["Name"] = "Session Collection";
+ Node::json["Description"] = "Session Collection";
+ Node::json["Members@odata.count"] = 0;
+ Node::json["Members"] = nlohmann::json::array();
}
private:
@@ -128,14 +124,14 @@ class SessionCollection : public Node {
crow::PersistentData::session_store->get_unique_ids(
false, crow::PersistentData::PersistenceType::TIMEOUT);
- nodeJson["Members@odata.count"] = session_ids.size();
- nodeJson["Members"] = nlohmann::json::array();
+ Node::json["Members@odata.count"] = session_ids.size();
+ Node::json["Members"] = nlohmann::json::array();
for (const auto& uid : session_ids) {
- nodeJson["Members"].push_back(
+ Node::json["Members"].push_back(
{{"@odata.id", "/redfish/v1/SessionService/Sessions/" + *uid}});
}
- res.json_value = nodeJson;
+ res.json_value = Node::json;
res.end();
}
@@ -235,7 +231,6 @@ class SessionCollection : public Node {
* member's doGet, as they should return 100% matching data
*/
Sessions memberSession;
- nlohmann::json nodeJson;
};
} // namespace redfish
diff --git a/redfish-core/lib/roles.hpp b/redfish-core/lib/roles.hpp
index 6a3c0d704e..f1a1c61b84 100644
--- a/redfish-core/lib/roles.hpp
+++ b/redfish-core/lib/roles.hpp
@@ -37,58 +37,52 @@ static OperationMap roleCollectionOpMap = {
class Roles : public Node {
public:
- template <typename CrowApp>
Roles(CrowApp& app)
: Node(app, EntityPrivileges(std::move(roleOpMap)),
"/redfish/v1/AccountService/Roles/Administrator/") {
- nodeJson["@odata.id"] = "/redfish/v1/AccountService/Roles/Administrator";
- nodeJson["@odata.type"] = "#Role.v1_0_2.Role";
- nodeJson["@odata.context"] = "/redfish/v1/$metadata#Role.Role";
- nodeJson["Id"] = "Administrator";
- nodeJson["Name"] = "User Role";
- nodeJson["Description"] = "Administrator User Role";
- nodeJson["IsPredefined"] = true;
- nodeJson["AssignedPrivileges"] = {"Login", "ConfigureManager",
- "ConfigureUsers", "ConfigureSelf",
- "ConfigureComponents"};
- nodeJson["OemPrivileges"] = nlohmann::json::array();
+ Node::json["@odata.id"] = "/redfish/v1/AccountService/Roles/Administrator";
+ Node::json["@odata.type"] = "#Role.v1_0_2.Role";
+ Node::json["@odata.context"] = "/redfish/v1/$metadata#Role.Role";
+ Node::json["Id"] = "Administrator";
+ Node::json["Name"] = "User Role";
+ Node::json["Description"] = "Administrator User Role";
+ Node::json["IsPredefined"] = true;
+ Node::json["AssignedPrivileges"] = {"Login", "ConfigureManager",
+ "ConfigureUsers", "ConfigureSelf",
+ "ConfigureComponents"};
+ Node::json["OemPrivileges"] = nlohmann::json::array();
}
private:
void doGet(crow::response& res, const crow::request& req,
const std::vector<std::string>& params) override {
- res.json_value = nodeJson;
+ res.json_value = Node::json;
res.end();
}
-
- nlohmann::json nodeJson;
};
class RoleCollection : public Node {
public:
- template <typename CrowApp>
RoleCollection(CrowApp& app)
: Node(app, EntityPrivileges(std::move(roleCollectionOpMap)),
"/redfish/v1/AccountService/Roles/") {
- nodeJson["@odata.id"] = "/redfish/v1/AccountService/Roles";
- nodeJson["@odata.type"] = "#RoleCollection.RoleCollection";
- nodeJson["@odata.context"] =
+ Node::json["@odata.id"] = "/redfish/v1/AccountService/Roles";
+ Node::json["@odata.type"] = "#RoleCollection.RoleCollection";
+ Node::json["@odata.context"] =
"/redfish/v1/$metadata#RoleCollection.RoleCollection";
- nodeJson["Name"] = "Roles Collection";
- nodeJson["Description"] = "BMC User Roles";
- nodeJson["Members@odata.count"] = 1;
- nodeJson["Members"] = {
- {{"@odata.id", "/redfish/v1/AccountService/Roles/Administrator"}}};
+ Node::json["Name"] = "Roles Collection";
+ Node::json["Description"] = "BMC User Roles";
+ Node::json["Members@odata.count"] = 1;
+ Node::json["Members"] = {
+ {"@odata.id", "/redfish/v1/AccountService/Roles/Administrator"}};
}
private:
void doGet(crow::response& res, const crow::request& req,
const std::vector<std::string>& params) override {
- res.json_value = nodeJson;
+ res.json_value = Node::json;
res.end();
}
-
- nlohmann::json nodeJson;
};
} // namespace redfish
diff --git a/redfish-core/lib/service_root.hpp b/redfish-core/lib/service_root.hpp
index 24ad79d308..129d58d85d 100644
--- a/redfish-core/lib/service_root.hpp
+++ b/redfish-core/lib/service_root.hpp
@@ -29,34 +29,30 @@ static OperationMap serviceRootOpMap = {
class ServiceRoot : public Node {
public:
- template <typename CrowApp>
ServiceRoot(CrowApp& app)
: Node(app, EntityPrivileges(std::move(serviceRootOpMap)),
"/redfish/v1/") {
- nodeJson["@odata.type"] = "#ServiceRoot.v1_1_1.ServiceRoot";
- nodeJson["@odata.id"] = "/redfish/v1";
- nodeJson["@odata.context"] =
+ Node::json["@odata.type"] = "#ServiceRoot.v1_1_1.ServiceRoot";
+ Node::json["@odata.id"] = "/redfish/v1/";
+ Node::json["@odata.context"] =
"/redfish/v1/$metadata#ServiceRoot.ServiceRoot";
- nodeJson["Id"] = "RootService";
- nodeJson["Name"] = "Root Service";
- nodeJson["RedfishVersion"] = "1.1.0";
- nodeJson["Links"]["Sessions"] = {
- {"@odata.id", "/redfish/v1/SessionService/Sessions/"}};
- nodeJson["UUID"] =
+ Node::json["Id"] = "RootService";
+ Node::json["Name"] = "Root Service";
+ Node::json["RedfishVersion"] = "1.1.0";
+ Node::json["Links"]["Sessions"] = {
+ {"@odata.id", "/redfish/v1/SessionService/Sessions"}};
+ Node::json["UUID"] =
app.template get_middleware<crow::PersistentData::Middleware>()
.system_uuid;
- getRedfishSubRoutes(app, "/redfish/v1/", nodeJson);
}
private:
void doGet(crow::response& res, const crow::request& req,
const std::vector<std::string>& params) override {
res.add_header("Content-Type", "application/json");
- res.body = nodeJson.dump();
+ res.json_value = Node::json;
res.end();
}
-
- nlohmann::json nodeJson;
};
} // namespace redfish
diff --git a/src/webserver_main.cpp b/src/webserver_main.cpp
index f504cc7ed8..53dd12742b 100644
--- a/src/webserver_main.cpp
+++ b/src/webserver_main.cpp
@@ -13,6 +13,7 @@
#include <memory>
#include <string>
#include "redfish.hpp"
+#include "webserver_common.hpp"
#include <crow/app.h>
#include <boost/asio.hpp>
#include <systemd/sd-daemon.h>
@@ -43,10 +44,7 @@ int main(int argc, char** argv) {
auto io = std::make_shared<boost::asio::io_service>();
crow::PersistentData::session_store =
std::make_shared<crow::PersistentData::SessionStore>();
- crow::App<crow::PersistentData::Middleware,
- crow::TokenAuthorization::Middleware,
- crow::SecurityHeadersMiddleware>
- app(io);
+ CrowApp app(io);
#ifdef CROW_ENABLE_SSL
std::string ssl_pem_file("server.pem");