blob: 49a5a15e813b6dffcd7f3e74571a61274a18d8cf [file] [log] [blame]
Ed Tanous911ac312017-08-15 09:37:42 -07001#pragma once
2
Ed Tanousaa2e59c2018-04-12 12:17:20 -07003#include <dbus_singleton.hpp>
Ed Tanousba9f9a62017-10-11 16:40:35 -07004#include <persistent_data_middleware.hpp>
5#include <token_authorization_middleware.hpp>
Ed Tanous911ac312017-08-15 09:37:42 -07006#include <fstream>
Ed Tanousba9f9a62017-10-11 16:40:35 -07007#include <streambuf>
8#include <string>
Ed Tanous2a866f82017-10-25 17:46:24 -07009#include <crow/app.h>
10#include <boost/algorithm/string.hpp>
Ed Tanous3dac7492017-08-02 13:46:20 -070011namespace crow {
12namespace redfish {
13
14template <typename... Middlewares>
Ed Tanousba9f9a62017-10-11 16:40:35 -070015void get_redfish_sub_routes(Crow<Middlewares...>& app, const std::string& url,
16 nlohmann::json& j) {
Ed Tanous1c74de82017-10-26 13:58:28 -070017 std::vector<const std::string*> routes = app.get_routes(url);
18 for (auto route : routes) {
Ed Tanousba9f9a62017-10-11 16:40:35 -070019 auto redfish_sub_route =
Ed Tanous1c74de82017-10-26 13:58:28 -070020 route->substr(url.size(), route->size() - url.size() - 1);
Ed Tanousba9f9a62017-10-11 16:40:35 -070021 // check if the route is at this level, and we didn't find and exact match
22 // also, filter out resources that start with $ to remove $metadata
23 if (!redfish_sub_route.empty() && redfish_sub_route[0] != '$' &&
24 redfish_sub_route.find('/') == std::string::npos) {
Ed Tanous1c74de82017-10-26 13:58:28 -070025 j[redfish_sub_route] = nlohmann::json{{"@odata.id", *route}};
Ed Tanous911ac312017-08-15 09:37:42 -070026 }
Ed Tanousba9f9a62017-10-11 16:40:35 -070027 }
28}
Ed Tanous911ac312017-08-15 09:37:42 -070029
Ed Tanous2a866f82017-10-25 17:46:24 -070030std::string execute_process(const char* cmd) {
31 std::array<char, 128> buffer;
32 std::string result;
33 std::shared_ptr<FILE> pipe(popen(cmd, "r"), pclose);
34 if (!pipe) throw std::runtime_error("popen() failed!");
35 while (!feof(pipe.get())) {
36 if (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr)
37 result += buffer.data();
38 }
39 return result;
40}
41
Ed Tanousaa2e59c2018-04-12 12:17:20 -070042// GetManagedObjects unpack type. Observe that variant has only one bool type,
43// because we don't actually use the values it provides
Ed Tanous6c233012018-03-15 14:43:56 -070044using ManagedObjectType = std::vector<std::pair<
Ed Tanousaa2e59c2018-04-12 12:17:20 -070045 sdbusplus::message::object_path,
46 boost::container::flat_map<
47 std::string, boost::container::flat_map<
48 std::string, sdbusplus::message::variant<bool>>>>>;
Ed Tanous6c233012018-03-15 14:43:56 -070049
Ed Tanousba9f9a62017-10-11 16:40:35 -070050template <typename... Middlewares>
51void request_routes(Crow<Middlewares...>& app) {
52 CROW_ROUTE(app, "/redfish/")
Ed Tanous911ac312017-08-15 09:37:42 -070053 .methods("GET"_method)([](const crow::request& req, crow::response& res) {
Ed Tanousba9f9a62017-10-11 16:40:35 -070054 res.json_value = {{"v1", "/redfish/v1/"}};
55 res.end();
56 });
57
Ed Tanousba9f9a62017-10-11 16:40:35 -070058 CROW_ROUTE(app, "/redfish/v1/AccountService/Accounts/")
59 .methods(
60 "GET"_method)([&](const crow::request& req, crow::response& res) {
Ed Tanous6c233012018-03-15 14:43:56 -070061 crow::connections::system_bus->async_method_call(
Ed Tanous911ac312017-08-15 09:37:42 -070062 [&](const boost::system::error_code ec,
Ed Tanous6c233012018-03-15 14:43:56 -070063 const ManagedObjectType& users) {
Ed Tanous911ac312017-08-15 09:37:42 -070064 if (ec) {
65 res.code = 500;
66 } else {
Ed Tanousba9f9a62017-10-11 16:40:35 -070067 res.json_value = {
Ed Tanous911ac312017-08-15 09:37:42 -070068 {"@odata.context",
69 "/redfish/v1/"
70 "$metadata#ManagerAccountCollection."
71 "ManagerAccountCollection"},
72 {"@odata.id", "/redfish/v1/AccountService/Accounts"},
73 {"@odata.type",
74 "#ManagerAccountCollection.ManagerAccountCollection"},
75 {"Name", "Accounts Collection"},
76 {"Description", "BMC User Accounts"},
77 {"Members@odata.count", users.size()}};
Ed Tanousba9f9a62017-10-11 16:40:35 -070078 nlohmann::json member_array = nlohmann::json::array();
Ed Tanous911ac312017-08-15 09:37:42 -070079 int user_index = 0;
Ed Tanous6c233012018-03-15 14:43:56 -070080 for (auto& user : users) {
Ed Tanousaa2e59c2018-04-12 12:17:20 -070081 const std::string& path =
Ed Tanousdaf36e22018-04-20 16:01:36 -070082 static_cast<const std::string&>(user.first);
Ed Tanous6c233012018-03-15 14:43:56 -070083 std::size_t last_index = path.rfind("/");
84 if (last_index == std::string::npos) {
85 last_index = 0;
86 } else {
87 last_index += 1;
88 }
Ed Tanous911ac312017-08-15 09:37:42 -070089 member_array.push_back(
Kowalski, Kamil2b7981f2018-01-31 13:24:59 +010090 {{"@odata.id", "/redfish/v1/AccountService/Accounts/" +
Ed Tanous6c233012018-03-15 14:43:56 -070091 path.substr(last_index)}});
Ed Tanous911ac312017-08-15 09:37:42 -070092 }
Ed Tanousba9f9a62017-10-11 16:40:35 -070093 res.json_value["Members"] = member_array;
Ed Tanous911ac312017-08-15 09:37:42 -070094 }
95 res.end();
Ed Tanousba9f9a62017-10-11 16:40:35 -070096 },
Ed Tanousaa2e59c2018-04-12 12:17:20 -070097 "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
98 "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
Ed Tanous3dac7492017-08-02 13:46:20 -070099 });
100
Ed Tanous6c233012018-03-15 14:43:56 -0700101 CROW_ROUTE(app, "/redfish/v1/AccountService/Accounts/<str>/")
Ed Tanousba9f9a62017-10-11 16:40:35 -0700102 .methods("GET"_method)([](const crow::request& req, crow::response& res,
Ed Tanous6c233012018-03-15 14:43:56 -0700103 const std::string& account_name) {
104
105 crow::connections::system_bus->async_method_call(
106 [&, account_name{std::move(account_name)} ](
107 const boost::system::error_code ec,
108 const ManagedObjectType& users) {
109 if (ec) {
110 res.code = 500;
111 } else {
112 for (auto& user : users) {
Ed Tanousaa2e59c2018-04-12 12:17:20 -0700113 const std::string& path =
Ed Tanousdaf36e22018-04-20 16:01:36 -0700114 static_cast<const std::string&>(user.first);
Ed Tanous6c233012018-03-15 14:43:56 -0700115 std::size_t last_index = path.rfind("/");
116 if (last_index == std::string::npos) {
117 last_index = 0;
118 } else {
119 last_index += 1;
120 }
121 if (path.substr(last_index) == account_name) {
122 res.json_value = {
123 {"@odata.context",
124 "/redfish/v1/$metadata#ManagerAccount.ManagerAccount"},
125 {"@odata.id", "/redfish/v1/AccountService/Accounts/1"},
126 {"@odata.type",
127 "#ManagerAccount.v1_0_3.ManagerAccount"},
128 {"Id", "1"},
129 {"Name", "User Account"},
130 {"Description", "User Account"},
131 {"Enabled", false},
132 {"Password", nullptr},
133 {"UserName", account_name},
134 {"RoleId", "Administrator"},
135 {"Links",
136 {{"Role",
137 {{"@odata.id",
138 "/redfish/v1/AccountService/Roles/"
139 "Administrator"}}}}}};
140 break;
141 }
142 }
143 if (res.json_value.is_null()) {
144 res.code = 404;
145 }
146 }
147 res.end();
148 },
Ed Tanousaa2e59c2018-04-12 12:17:20 -0700149 "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
150 "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
Ed Tanousba9f9a62017-10-11 16:40:35 -0700151 });
Ed Tanous3dac7492017-08-02 13:46:20 -0700152}
Ed Tanous911ac312017-08-15 09:37:42 -0700153} // namespace redfish
154} // namespace crow