blob: c28208dbe53e3b00e3b665f29510b21491800bac [file] [log] [blame]
Ed Tanous911ac312017-08-15 09:37:42 -07001#pragma once
2
Ed Tanous911ac312017-08-15 09:37:42 -07003#include <dbus/connection.hpp>
4#include <dbus/endpoint.hpp>
5#include <dbus/filter.hpp>
6#include <dbus/match.hpp>
7#include <dbus/message.hpp>
Ed Tanousba9f9a62017-10-11 16:40:35 -07008#include <persistent_data_middleware.hpp>
9#include <token_authorization_middleware.hpp>
Ed Tanous911ac312017-08-15 09:37:42 -070010#include <fstream>
Ed Tanousba9f9a62017-10-11 16:40:35 -070011#include <streambuf>
12#include <string>
Ed Tanous2a866f82017-10-25 17:46:24 -070013#include <crow/app.h>
14#include <boost/algorithm/string.hpp>
Ed Tanous3dac7492017-08-02 13:46:20 -070015namespace crow {
16namespace redfish {
17
18template <typename... Middlewares>
Ed Tanousba9f9a62017-10-11 16:40:35 -070019void get_redfish_sub_routes(Crow<Middlewares...>& app, const std::string& url,
20 nlohmann::json& j) {
Ed Tanous1c74de82017-10-26 13:58:28 -070021 std::vector<const std::string*> routes = app.get_routes(url);
22 for (auto route : routes) {
Ed Tanousba9f9a62017-10-11 16:40:35 -070023 auto redfish_sub_route =
Ed Tanous1c74de82017-10-26 13:58:28 -070024 route->substr(url.size(), route->size() - url.size() - 1);
Ed Tanousba9f9a62017-10-11 16:40:35 -070025 // check if the route is at this level, and we didn't find and exact match
26 // also, filter out resources that start with $ to remove $metadata
27 if (!redfish_sub_route.empty() && redfish_sub_route[0] != '$' &&
28 redfish_sub_route.find('/') == std::string::npos) {
Ed Tanous1c74de82017-10-26 13:58:28 -070029 j[redfish_sub_route] = nlohmann::json{{"@odata.id", *route}};
Ed Tanous911ac312017-08-15 09:37:42 -070030 }
Ed Tanousba9f9a62017-10-11 16:40:35 -070031 }
32}
Ed Tanous911ac312017-08-15 09:37:42 -070033
Ed Tanous2a866f82017-10-25 17:46:24 -070034std::string execute_process(const char* cmd) {
35 std::array<char, 128> buffer;
36 std::string result;
37 std::shared_ptr<FILE> pipe(popen(cmd, "r"), pclose);
38 if (!pipe) throw std::runtime_error("popen() failed!");
39 while (!feof(pipe.get())) {
40 if (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr)
41 result += buffer.data();
42 }
43 return result;
44}
45
Ed Tanous6c233012018-03-15 14:43:56 -070046using ManagedObjectType = std::vector<std::pair<
47 dbus::object_path, boost::container::flat_map<
48 std::string, boost::container::flat_map<
49 std::string, dbus::dbus_variant>>>>;
50
Ed Tanousba9f9a62017-10-11 16:40:35 -070051template <typename... Middlewares>
52void request_routes(Crow<Middlewares...>& app) {
53 CROW_ROUTE(app, "/redfish/")
Ed Tanous911ac312017-08-15 09:37:42 -070054 .methods("GET"_method)([](const crow::request& req, crow::response& res) {
Ed Tanousba9f9a62017-10-11 16:40:35 -070055 res.json_value = {{"v1", "/redfish/v1/"}};
56 res.end();
57 });
58
Ed Tanousba9f9a62017-10-11 16:40:35 -070059 CROW_ROUTE(app, "/redfish/v1/AccountService/Accounts/")
60 .methods(
61 "GET"_method)([&](const crow::request& req, crow::response& res) {
Ed Tanous6c233012018-03-15 14:43:56 -070062 crow::connections::system_bus->async_method_call(
Ed Tanous911ac312017-08-15 09:37:42 -070063 [&](const boost::system::error_code ec,
Ed Tanous6c233012018-03-15 14:43:56 -070064 const ManagedObjectType& users) {
Ed Tanous911ac312017-08-15 09:37:42 -070065 if (ec) {
66 res.code = 500;
67 } else {
Ed Tanousba9f9a62017-10-11 16:40:35 -070068 res.json_value = {
Ed Tanous911ac312017-08-15 09:37:42 -070069 {"@odata.context",
70 "/redfish/v1/"
71 "$metadata#ManagerAccountCollection."
72 "ManagerAccountCollection"},
73 {"@odata.id", "/redfish/v1/AccountService/Accounts"},
74 {"@odata.type",
75 "#ManagerAccountCollection.ManagerAccountCollection"},
76 {"Name", "Accounts Collection"},
77 {"Description", "BMC User Accounts"},
78 {"Members@odata.count", users.size()}};
Ed Tanousba9f9a62017-10-11 16:40:35 -070079 nlohmann::json member_array = nlohmann::json::array();
Ed Tanous911ac312017-08-15 09:37:42 -070080 int user_index = 0;
Ed Tanous6c233012018-03-15 14:43:56 -070081 for (auto& user : users) {
82 const std::string& path = user.first.value;
83 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 Tanous6c233012018-03-15 14:43:56 -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) {
113 const std::string& path = user.first.value;
114 std::size_t last_index = path.rfind("/");
115 if (last_index == std::string::npos) {
116 last_index = 0;
117 } else {
118 last_index += 1;
119 }
120 if (path.substr(last_index) == account_name) {
121 res.json_value = {
122 {"@odata.context",
123 "/redfish/v1/$metadata#ManagerAccount.ManagerAccount"},
124 {"@odata.id", "/redfish/v1/AccountService/Accounts/1"},
125 {"@odata.type",
126 "#ManagerAccount.v1_0_3.ManagerAccount"},
127 {"Id", "1"},
128 {"Name", "User Account"},
129 {"Description", "User Account"},
130 {"Enabled", false},
131 {"Password", nullptr},
132 {"UserName", account_name},
133 {"RoleId", "Administrator"},
134 {"Links",
135 {{"Role",
136 {{"@odata.id",
137 "/redfish/v1/AccountService/Roles/"
138 "Administrator"}}}}}};
139 break;
140 }
141 }
142 if (res.json_value.is_null()) {
143 res.code = 404;
144 }
145 }
146 res.end();
147 },
148 {"xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
149 "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"});
Ed Tanousba9f9a62017-10-11 16:40:35 -0700150 });
Ed Tanous3dac7492017-08-02 13:46:20 -0700151}
Ed Tanous911ac312017-08-15 09:37:42 -0700152} // namespace redfish
153} // namespace crow