blob: d13eb130e3abce13c289584d7c8e8beec2e29d8b [file] [log] [blame]
Ed Tanous911ac312017-08-15 09:37:42 -07001#pragma once
2
Ed Tanous3dac7492017-08-02 13:46:20 -07003#include <crow/app.h>
Ed Tanous911ac312017-08-15 09:37:42 -07004
5#include <dbus/connection.hpp>
6#include <dbus/endpoint.hpp>
7#include <dbus/filter.hpp>
8#include <dbus/match.hpp>
9#include <dbus/message.hpp>
Ed Tanousba9f9a62017-10-11 16:40:35 -070010#include <persistent_data_middleware.hpp>
11#include <token_authorization_middleware.hpp>
Ed Tanous911ac312017-08-15 09:37:42 -070012#include <fstream>
Ed Tanousba9f9a62017-10-11 16:40:35 -070013#include <streambuf>
14#include <string>
Ed Tanous911ac312017-08-15 09:37:42 -070015
Ed Tanous3dac7492017-08-02 13:46:20 -070016namespace crow {
17namespace redfish {
18
19template <typename... Middlewares>
Ed Tanousba9f9a62017-10-11 16:40:35 -070020void get_redfish_sub_routes(Crow<Middlewares...>& app, const std::string& url,
21 nlohmann::json& j) {
22 auto routes = app.get_routes(url);
23 for (auto& route : routes) {
24 auto redfish_sub_route =
25 route.substr(url.size(), route.size() - url.size() - 1);
26 // check if the route is at this level, and we didn't find and exact match
27 // also, filter out resources that start with $ to remove $metadata
28 if (!redfish_sub_route.empty() && redfish_sub_route[0] != '$' &&
29 redfish_sub_route.find('/') == std::string::npos) {
30 j[redfish_sub_route] = nlohmann::json{{"@odata.id", route}};
Ed Tanous911ac312017-08-15 09:37:42 -070031 }
Ed Tanousba9f9a62017-10-11 16:40:35 -070032 }
33}
Ed Tanous911ac312017-08-15 09:37:42 -070034
Ed Tanousba9f9a62017-10-11 16:40:35 -070035template <typename... Middlewares>
36void request_routes(Crow<Middlewares...>& app) {
37 CROW_ROUTE(app, "/redfish/")
Ed Tanous911ac312017-08-15 09:37:42 -070038 .methods("GET"_method)([](const crow::request& req, crow::response& res) {
Ed Tanousba9f9a62017-10-11 16:40:35 -070039 res.json_value = {{"v1", "/redfish/v1/"}};
40 res.end();
41 });
42
43 CROW_ROUTE(app, "/redfish/v1/")
44 .methods(
45 "GET"_method)([&](const crow::request& req, crow::response& res) {
46 res.json_value = {
47 {"@odata.context", "/redfish/v1/$metadata#ServiceRoot.ServiceRoot"},
48 {"@odata.id", "/redfish/v1/"},
49 {"@odata.type", "#ServiceRoot.v1_1_1.ServiceRoot"},
50 {"Id", "RootService"},
51 {"Name", "Root Service"},
52 {"RedfishVersion", "1.1.0"},
53 {"Links",
54 {{"Sessions",
55 {{"@odata.id", "/redfish/v1/SessionService/Sessions/"}}}}}};
56
57 res.json_value["UUID"] =
58 app.template get_middleware<PersistentData::Middleware>()
59 .system_uuid;
60 get_redfish_sub_routes(app, "/redfish/v1/", res.json_value);
61 res.end();
62 });
63
64 CROW_ROUTE(app, "/redfish/v1/$metadata/")
65 .methods(
66 "GET"_method)([&](const crow::request& req, crow::response& res) {
67 const char* response_text = R"(<?xml version="1.0" encoding="UTF-8"?>
68 <edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
69 <edmx:Reference Uri="/redfish/v1/schema/ServiceRoot_v1.xml">
70 <edmx:Include Namespace="ServiceRoot"/>
71 <edmx:Include Namespace="ServiceRoot.v1_0_4"/>
72 <edmx:Include Namespace="ServiceRoot.v1_1_1"/>
73 </edmx:Reference>
74 <edmx:Reference Uri="/redfish/v1/schema/AccountService_v1.xml">
75 <edmx:Include Namespace="AccountService"/>
76 <edmx:Include Namespace="AccountService.v1_0_3"/>
77 <edmx:Include Namespace="AccountService.v1_1_0"/>
78 </edmx:Reference>
79 <edmx:Reference Uri="/redfish/v1/schema/Chassis_v1.xml">
80 <edmx:Include Namespace="Chassis"/>
81 <edmx:Include Namespace="Chassis.v1_0_3"/>
82 <edmx:Include Namespace="Chassis.v1_1_3"/>
83 <edmx:Include Namespace="Chassis.v1_2_1"/>
84 <edmx:Include Namespace="Chassis.v1_3_1"/>
85 <edmx:Include Namespace="Chassis.v1_4_0"/>
86 </edmx:Reference>
87 <edmx:Reference Uri="/redfish/v1/schema/ChassisCollection_v1.xml">
88 <edmx:Include Namespace="ChassisCollection"/>
89 </edmx:Reference>
90 <edmx:Reference Uri="/redfish/v1/schema/ComputerSystem_v1.xml">
91 <edmx:Include Namespace="ComputerSystem"/>
92 <edmx:Include Namespace="ComputerSystem.v1_0_4"/>
93 <edmx:Include Namespace="ComputerSystem.v1_1_2"/>
94 <edmx:Include Namespace="ComputerSystem.v1_2_1"/>
95 <edmx:Include Namespace="ComputerSystem.v1_3_0"/>
96 </edmx:Reference>
97 <edmx:Reference Uri="/redfish/v1/schema/ComputerSystemCollection_v1.xml">
98 <edmx:Include Namespace="ComputerSystemCollection"/>
99 </edmx:Reference>
100 <edmx:Reference Uri="/redfish/v1/schema/EthernetInterface_v1.xml">
101 <edmx:Include Namespace="EthernetInterface"/>
102 <edmx:Include Namespace="EthernetInterface.v1_0_3"/>
103 <edmx:Include Namespace="EthernetInterface.v1_1_1"/>
104 <edmx:Include Namespace="EthernetInterface.v1_2_0"/>
105 </edmx:Reference>
106 <edmx:Reference Uri="/redfish/v1/schema/EthernetInterfaceCollection_v1.xml">
107 <edmx:Include Namespace="EthernetInterfaceCollection"/>
108 </edmx:Reference>
109 <edmx:Reference Uri="/redfish/v1/schema/LogEntry_v1.xml">
110 <edmx:Include Namespace="LogEntry"/>
111 <edmx:Include Namespace="LogEntry.v1_0_3"/>
112 <edmx:Include Namespace="LogEntry.v1_1_1"/>
113 </edmx:Reference>
114 <edmx:Reference Uri="/redfish/v1/schema/LogEntryCollection_v1.xml">
115 <edmx:Include Namespace="LogEntryCollection"/>
116 </edmx:Reference>
117 <edmx:Reference Uri="/redfish/v1/schema/LogService_v1.xml">
118 <edmx:Include Namespace="LogService"/>
119 <edmx:Include Namespace="LogService.v1_0_3"/>
120 </edmx:Reference>
121 <edmx:Reference Uri="/redfish/v1/schema/LogServiceCollection_v1.xml">
122 <edmx:Include Namespace="LogServiceCollection"/>
123 </edmx:Reference>
124 <edmx:Reference Uri="/redfish/v1/schema/Manager_v1.xml">
125 <edmx:Include Namespace="Manager"/>
126 <edmx:Include Namespace="Manager.v1_0_3"/>
127 <edmx:Include Namespace="Manager.v1_1_1"/>
128 <edmx:Include Namespace="Manager.v1_2_1"/>
129 <edmx:Include Namespace="Manager.v1_3_0"/>
130 </edmx:Reference>
131 <edmx:Reference Uri="/redfish/v1/schema/ManagerAccount_v1.xml">
132 <edmx:Include Namespace="ManagerAccount"/>
133 <edmx:Include Namespace="ManagerAccount.v1_0_3"/>
134 </edmx:Reference>
135 <edmx:Reference Uri="/redfish/v1/schema/ManagerNetworkProtocol_v1.xml">
136 <edmx:Include Namespace="ManagerNetworkProtocol"/>
137 <edmx:Include Namespace="ManagerNetworkProtocol.v1_0_3"/>
138 <edmx:Include Namespace="ManagerNetworkProtocol.v1_1_0"/>
139 </edmx:Reference>
140 <edmx:Reference Uri="/redfish/v1/schema/ManagerAccountCollection_v1.xml">
141 <edmx:Include Namespace="ManagerAccountCollection"/>
142 </edmx:Reference>
143 <edmx:Reference Uri="/redfish/v1/schema/ManagerCollection_v1.xml">
144 <edmx:Include Namespace="ManagerCollection"/>
145 </edmx:Reference>
146 <edmx:Reference Uri="/redfish/v1/schema/Power_v1.xml">
147 <edmx:Include Namespace="Power"/>
148 <edmx:Include Namespace="Power.v1_0_3"/>
149 <edmx:Include Namespace="Power.v1_1_1"/>
150 <edmx:Include Namespace="Power.v1_2_1"/>
151 </edmx:Reference>
152 <edmx:Reference Uri="/redfish/v1/schema/Processor_v1.xml">
153 <edmx:Include Namespace="Processor"/>
154 <edmx:Include Namespace="Processor.v1_0_3"/>
155 </edmx:Reference>
156 <edmx:Reference Uri="/redfish/v1/schema/ProcessorCollection_v1.xml">
157 <edmx:Include Namespace="ProcessorCollection"/>
158 </edmx:Reference>
159 <edmx:Reference Uri="/redfish/v1/schema/Role_v1.xml">
160 <edmx:Include Namespace="Role"/>
161 <edmx:Include Namespace="Role.v1_0_2"/>
162 </edmx:Reference>
163 <edmx:Reference Uri="/redfish/v1/schema/RoleCollection_v1.xml">
164 <edmx:Include Namespace="RoleCollection"/>
165 </edmx:Reference>
166 <edmx:Reference Uri="/redfish/v1/schema/Session_v1.xml">
167 <edmx:Include Namespace="Session"/>
168 <edmx:Include Namespace="Session.v1_0_3"/>
169 </edmx:Reference>
170 <edmx:Reference Uri="/redfish/v1/schema/SessionCollection_v1.xml">
171 <edmx:Include Namespace="SessionCollection"/>
172 </edmx:Reference>
173 <edmx:Reference Uri="/redfish/v1/schema/SessionService_v1.xml">
174 <edmx:Include Namespace="SessionService"/>
175 <edmx:Include Namespace="SessionService.v1_0_3"/>
176 <edmx:Include Namespace="SessionService.v1_1_1"/>
177 </edmx:Reference>
178 <edmx:Reference Uri="/redfish/v1/schema/Thermal_v1.xml">
179 <edmx:Include Namespace="Thermal"/>
180 <edmx:Include Namespace="Thermal.v1_0_3"/>
181 <edmx:Include Namespace="Thermal.v1_1_1"/>
182 <edmx:Include Namespace="Thermal.v1_2_0"/>
183 </edmx:Reference>
184 <edmx:Reference Uri="/redfish/v1/schema/RedfishExtensions_v1.xml">
185 <edmx:Include Namespace="RedfishExtensions.v1_0_0" Alias="Redfish"/>
186 </edmx:Reference>
187 <edmx:Reference Uri="/redfish/v1/schema/IPAddresses_v1.xml">
188 <edmx:Include Namespace="IPAddresses"/>
189 <edmx:Include Namespace="IPAddresses.v1_0_4"/>
190 </edmx:Reference>
191 <edmx:Reference Uri="/redfish/v1/schema/MemoryCollection_v1.xml">
192 <edmx:Include Namespace="MemoryCollection"/>
193 </edmx:Reference>
194 <edmx:Reference Uri="/redfish/v1/schema/MemoryMetrics_v1.xml">
195 <edmx:Include Namespace="MemoryMetrics"/>
196 <edmx:Include Namespace="MemoryMetrics.v1_0_1"/>
197 <edmx:Include Namespace="MemoryMetrics.v1_1_1"/>
198 </edmx:Reference>
199 <edmx:Reference Uri="/redfish/v1/schema/Memory_v1.xml">
200 <edmx:Include Namespace="Memory"/>
201 <edmx:Include Namespace="Memory.v1_0_1"/>
202 <edmx:Include Namespace="Memory.v1_1_0"/>
203 </edmx:Reference>
204 <edmx:Reference Uri="/redfish/v1/schema/PhysicalContext_v1.xml">
205 <edmx:Include Namespace="PhysicalContext"/>
206 <edmx:Include Namespace="PhysicalContext.v1_0_3"/>
207 </edmx:Reference>
208 <edmx:Reference Uri="/redfish/v1/schema/Privileges_v1.xml">
209 <edmx:Include Namespace="Privileges"/>
210 <edmx:Include Namespace="Privileges.v1_0_3"/>
211 </edmx:Reference>
212 <edmx:Reference Uri="/redfish/v1/schema/Redundancy_v1.xml">
213 <edmx:Include Namespace="Redundancy"/>
214 <edmx:Include Namespace="Redundancy.v1_0_3"/>
215 <edmx:Include Namespace="Redundancy.v1_1_1"/>
216 </edmx:Reference>
217 <edmx:Reference Uri="/redfish/v1/schema/Resource_v1.xml">
218 <edmx:Include Namespace="Resource"/>
219 <edmx:Include Namespace="Resource.v1_0_3"/>
220 <edmx:Include Namespace="Resource.v1_1_2"/>
221 <edmx:Include Namespace="Resource.v1_2_1"/>
222 <edmx:Include Namespace="Resource.v1_3_0"/>
223 </edmx:Reference>
224 <edmx:Reference Uri="/redfish/v1/schema/VirtualMediaCollection_v1.xml">
225 <edmx:Include Namespace="VirtualMediaCollection"/>
226 </edmx:Reference>
227 <edmx:Reference Uri="/redfish/v1/schema/VirtualMedia_v1.xml">
228 <edmx:Include Namespace="VirtualMedia"/>
229 <edmx:Include Namespace="VirtualMedia.v1_0_3"/>
230 </edmx:Reference>
231 <edmx:Reference Uri="/redfish/v1/schema/VLanNetworkInterfaceCollection_v1.xml">
232 <edmx:Include Namespace="VLanNetworkInterfaceCollection"/>
233 </edmx:Reference>
234 <edmx:Reference Uri="/redfish/v1/schema/VLanNetworkInterface_v1.xml">
235 <edmx:Include Namespace="VLanNetworkInterface"/>
236 <edmx:Include Namespace="VLanNetworkInterface.v1_0_3"/>
237 </edmx:Reference>
238 <edmx:Reference Uri="/redfish/v1/schema/StorageCollection_v1.xml">
239 <edmx:Include Namespace="StorageCollection"/>
240 </edmx:Reference>
241 <edmx:Reference Uri="/redfish/v1/schema/Storage_v1.xml">
242 <edmx:Include Namespace="Storage"/>
243 <edmx:Include Namespace="Storage.v1_0_2"/>
244 <edmx:Include Namespace="Storage.v1_1_1"/>
245 </edmx:Reference>
246 <edmx:Reference Uri="/redfish/v1/schema/Drive_v1.xml">
247 <edmx:Include Namespace="Drive"/>
248 <edmx:Include Namespace="Drive.v1_0_2"/>
249 <edmx:Include Namespace="Drive.v1_1_1"/>
250 </edmx:Reference>
251 <edmx:Reference Uri="/redfish/v1/schema/SoftwareInventoryCollection_v1.xml">
252 <edmx:Include Namespace="SoftwareInventoryCollection"/>
253 </edmx:Reference>
254 <edmx:Reference Uri="/redfish/v1/schema/SoftwareInventory_v1.xml">
255 <edmx:Include Namespace="SoftwareInventory"/>
256 <edmx:Include Namespace="SoftwareInventory.v1_0_1"/>
257 <edmx:Include Namespace="SoftwareInventory.v1_1_1"/>
258 </edmx:Reference>
259 <edmx:Reference Uri="/redfish/v1/schema/UpdateService_v1.xml">
260 <edmx:Include Namespace="UpdateService"/>
261 <edmx:Include Namespace="UpdateService.v1_0_1"/>
262 <edmx:Include Namespace="UpdateService.v1_1_0"/>
263 </edmx:Reference>
264 <edmx:Reference Uri="/redfish/v1/schema/Message_v1.xml">
265 <edmx:Include Namespace="Message"/>
266 <edmx:Include Namespace="Message.v1_0_4"/>
267 </edmx:Reference>
268 <edmx:Reference Uri="/redfish/v1/schema/EndpointCollection_v1.xml">
269 <edmx:Include Namespace="EndpointCollection"/>
270 </edmx:Reference>
271 <edmx:Reference Uri="/redfish/v1/schema/Endpoint_v1.xml">
272 <edmx:Include Namespace="Endpoint"/>
273 <edmx:Include Namespace="Endpoint.v1_0_1"/>
274 </edmx:Reference>
275 <edmx:Reference Uri="/redfish/v1/schema/HostInterfaceCollection_v1.xml">
276 <edmx:Include Namespace="HostInterfaceCollection"/>
277 </edmx:Reference>
278 <edmx:Reference Uri="/redfish/v1/schema/HostInterface_v1.xml">
279 <edmx:Include Namespace="HostInterface"/>
280 <edmx:Include Namespace="HostInterface.v1_0_0"/>
281 </edmx:Reference>
282 <edmx:Reference Uri="/redfish/v1/schema/MessageRegistryFileCollection_v1.xml">
283 <edmx:Include Namespace="MessageRegistryFileCollection"/>
284 </edmx:Reference>
285 <edmx:Reference Uri="/redfish/v1/schema/MessageRegistryFile_v1.xml">
286 <edmx:Include Namespace="MessageRegistryFile"/>
287 <edmx:Include Namespace="MessageRegistryFile.v1_0_3"/>
288 </edmx:Reference>
289 <edmx:Reference Uri="/redfish/v1/schema/EventService_v1.xml">
290 <edmx:Include Namespace="EventService"/>
291 <edmx:Include Namespace="EventService.v1_0_3"/>
292 </edmx:Reference>
293 <edmx:Reference Uri="/redfish/v1/schema/EventDestinationCollection_v1.xml">
294 <edmx:Include Namespace="EventDestinationCollection"/>
295 </edmx:Reference>
296 <edmx:Reference Uri="/redfish/v1/schema/EventDestination_v1.xml">
297 <edmx:Include Namespace="EventDestination"/>
298 <edmx:Include Namespace="EventDestination.v1_0_3"/>
299 <edmx:Include Namespace="EventDestination.v1_1_1"/>
300 </edmx:Reference>
301 <edmx:Reference Uri="/redfish/v1/schema/Event_v1.xml">
302 <edmx:Include Namespace="Event"/>
303 <edmx:Include Namespace="Event.v1_0_4"/>
304 <edmx:Include Namespace="Event.v1_1_2"/>
305 </edmx:Reference>
306 <edmx:DataServices>
307 <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Service">
308 <EntityContainer Name="Service" Extends="ServiceRoot.v1_0_0.ServiceContainer"/>
309 </Schema>
310 </edmx:DataServices>
311 </edmx:Edmx>)";
312
313 res.body = response_text;
314 res.add_header("Content-Type", "application/xml");
315 res.end();
316 });
317
318 CROW_ROUTE(app, "/redfish/v1/Chassis/")
319 .methods("GET"_method)(
320 [&](const crow::request& req, crow::response& res) {
321 std::vector<std::string> entities;
322 /*std::ifstream f("~/system.json");
323
324 nlohmann::json input = nlohmann::json::parse(f);
325 for (auto it = input.begin(); it != input.end(); it++) {
326 auto value = it.value();
327 if (value["type"] == "Chassis") {
328 std::string str = value["name"];
329 entities.emplace_back(str);
330 }
331 }
332 */
333 res.json_value = {
334 {"@odata.context",
335 "/redfish/v1/$metadata#ChassisCollection.ChassisCollection"},
336 {"@odata.id", "/redfish/v1/Chassis"},
337 {"@odata.type", "#ChassisCollection.ChassisCollection"},
338 {"Name", "Chassis Collection"},
339 {"Members@odata.count", entities.size()}};
340
341 get_redfish_sub_routes(app, "/redfish/v1/Chassis", res.json_value);
342 res.end();
343 });
344
345 CROW_ROUTE(app, "/redfish/v1/AccountService/")
346 .methods(
347 "GET"_method)([&](const crow::request& req, crow::response& res) {
348 res.json_value = {
349 {"@odata.context",
350 "/redfish/v1/$metadata#AccountService.AccountService"},
351 {"@odata.id", "/redfish/v1/AccountService"},
352 {"@odata.type", "#AccountService.v1_1_0.AccountService"},
353 {"Id", "AccountService"},
354 {"Name", "Account Service"},
355 {"Description", "BMC User Accounts"},
356 {"Status",
357 // TODO(ed) health rollup
358 {{"State", "Enabled"}, {"Health", "OK"}, {"HealthRollup", "OK"}}},
359 {"ServiceEnabled", true},
360 {"MinPasswordLength", 1},
361 {"MaxPasswordLength", 20},
362 };
363 get_redfish_sub_routes(app, "/redfish/v1/AccountService",
364 res.json_value);
365 res.end();
366 });
367
368 CROW_ROUTE(app, "/redfish/v1/AccountService/Roles/")
369 .methods("GET"_method)(
370 [&](const crow::request& req, crow::response& res) {
371 res.json_value = {
372 {"@odata.context",
373 "/redfish/v1/$metadata#RoleCollection.RoleCollection"},
374 {"@odata.id", "/redfish/v1/AccountService/Roles"},
375 {"@odata.type", "#RoleCollection.RoleCollection"},
376 {"Name", "Account Service"},
377 {"Description", "BMC User Roles"},
378 {"Members@odata.count", 1},
379 {"Members",
380 {{"@odata.id",
381 "/redfish/v1/AccountService/Roles/Administrator"}}}};
382 get_redfish_sub_routes(app, "/redfish/v1/AccountService",
383 res.json_value);
384 res.end();
385 });
386
387 CROW_ROUTE(app, "/redfish/v1/AccountService/Roles/Administrator/")
388 .methods("GET"_method)(
389 [&](const crow::request& req, crow::response& res) {
390 res.json_value = {
391 {"@odata.context", "/redfish/v1/$metadata#Role.Role"},
392 {"@odata.id", "/redfish/v1/AccountService/Roles/Administrator"},
393 {"@odata.type", "#Role.v1_0_2.Role"},
394 {"Id", "Administrator"},
395 {"Name", "User Role"},
396 {"Description", "Administrator User Role"},
397 {"IsPredefined", true},
398 {"AssignedPrivileges",
399 {"Login", "ConfigureManager", "ConfigureUsers",
400 "ConfigureSelf", "ConfigureComponents"}}};
401 res.end();
402 });
403
404 CROW_ROUTE(app, "/redfish/v1/AccountService/Accounts/")
405 .methods(
406 "GET"_method)([&](const crow::request& req, crow::response& res) {
Ed Tanous911ac312017-08-15 09:37:42 -0700407 boost::asio::io_service io;
408 auto bus = std::make_shared<dbus::connection>(io, dbus::bus::session);
409 dbus::endpoint user_list("org.openbmc.UserManager",
410 "/org/openbmc/UserManager/Users",
411 "org.openbmc.Enrol", "UserList");
412 bus->async_method_call(
413 [&](const boost::system::error_code ec,
Ed Tanousba9f9a62017-10-11 16:40:35 -0700414 const std::vector<std::string>& users) {
Ed Tanous911ac312017-08-15 09:37:42 -0700415 if (ec) {
416 res.code = 500;
417 } else {
Ed Tanousba9f9a62017-10-11 16:40:35 -0700418 res.json_value = {
Ed Tanous911ac312017-08-15 09:37:42 -0700419 {"@odata.context",
420 "/redfish/v1/"
421 "$metadata#ManagerAccountCollection."
422 "ManagerAccountCollection"},
423 {"@odata.id", "/redfish/v1/AccountService/Accounts"},
424 {"@odata.type",
425 "#ManagerAccountCollection.ManagerAccountCollection"},
426 {"Name", "Accounts Collection"},
427 {"Description", "BMC User Accounts"},
428 {"Members@odata.count", users.size()}};
Ed Tanousba9f9a62017-10-11 16:40:35 -0700429 nlohmann::json member_array = nlohmann::json::array();
Ed Tanous911ac312017-08-15 09:37:42 -0700430 int user_index = 0;
431 for (auto& user : users) {
432 member_array.push_back(
Ed Tanousba9f9a62017-10-11 16:40:35 -0700433 {{"@odata.id",
434 "/redfish/v1/AccountService/Accounts/" +
435 std::to_string(++user_index)}});
Ed Tanous911ac312017-08-15 09:37:42 -0700436 }
Ed Tanousba9f9a62017-10-11 16:40:35 -0700437 res.json_value["Members"] = member_array;
Ed Tanous911ac312017-08-15 09:37:42 -0700438 }
439 res.end();
Ed Tanousba9f9a62017-10-11 16:40:35 -0700440 },
441 user_list);
Ed Tanous3dac7492017-08-02 13:46:20 -0700442 });
443
444 CROW_ROUTE(app, "/redfish/v1/AccountService/Accounts/<int>/")
Ed Tanousba9f9a62017-10-11 16:40:35 -0700445 .methods("GET"_method)([](const crow::request& req, crow::response& res,
446 int account_index) {
447 res.json_value = {
Ed Tanous3dac7492017-08-02 13:46:20 -0700448 {"@odata.context",
449 "/redfish/v1/$metadata#ManagerAccount.ManagerAccount"},
450 {"@odata.id", "/redfish/v1/AccountService/Accounts/1"},
451 {"@odata.type", "#ManagerAccount.v1_0_3.ManagerAccount"},
452 {"Id", "1"},
453 {"Name", "User Account"},
454 {"Description", "User Account"},
455 {"Enabled", false},
456 {"Password", nullptr},
457 {"UserName", "anonymous"},
458 {"RoleId", "NoAccess"},
459 {"Links",
460 {{"Role",
461 {{"@odata.id", "/redfish/v1/AccountService/Roles/NoAccess"}}}}}};
Ed Tanousba9f9a62017-10-11 16:40:35 -0700462 res.end();
463 });
464
465 CROW_ROUTE(app, "/redfish/v1/SessionService/")
466 .methods(
467 "GET"_method)([&](const crow::request& req, crow::response& res) {
468 res.json_value = {
469 {"@odata.context",
470 "/redfish/v1/$metadata#SessionService.SessionService"},
471 {"@odata.id", "/redfish/v1/SessionService"},
472 {"@odata.type", "#SessionService.v1_1_1.SessionService"},
473 {"Id", "SessionService"},
474 {"Name", "SessionService"},
475 {"Description", "SessionService"},
476 {"Status",
477 {{"State", "Enabled"}, {"Health", "OK"}, {"HealthRollup", "OK"}}},
478 {"ServiceEnabled", true},
479 // TODO(ed) converge with session timeouts once they exist
480 // Bogus number for now
481 {"SessionTimeout", 1800}};
482 get_redfish_sub_routes(app, "/redfish/v1/AccountService",
483 res.json_value);
484 res.end();
485 });
486
487 CROW_ROUTE(app, "/redfish/v1/SessionService/Sessions/")
488 .methods("POST"_method, "GET"_method)([&](const crow::request& req,
489 crow::response& res) {
490 auto& data_middleware =
491 app.template get_middleware<PersistentData::Middleware>();
492 if (req.method == "POST"_method) {
493 // call with exceptions disabled
494 auto login_credentials =
495 nlohmann::json::parse(req.body, nullptr, false);
496 if (login_credentials.is_discarded()) {
497 res.code = 400;
498 res.end();
499 return;
500 }
501 // check for username/password in the root object
502 auto user_it = login_credentials.find("UserName");
503 auto pass_it = login_credentials.find("Password");
504 if (user_it == login_credentials.end() ||
505 pass_it == login_credentials.end()) {
506 res.code = 400;
507 res.end();
508 return;
509 }
510
511 std::string username = user_it->get<const std::string>();
512 std::string password = pass_it->get<const std::string>();
513 if (username.empty() || password.empty()) {
514 res.code = 400;
515 res.end();
516 return;
517 }
518
519 if (!pam_authenticate_user(username, password)) {
520 res.code = 401;
521 res.end();
522 return;
523 }
524 auto session = data_middleware.generate_user_session(username);
525 res.code = 200;
526 res.add_header("X-Auth-Token", session.session_token);
527 res.json_value = {
528 {"@odata.context", "/redfish/v1/$metadata#Session"},
529 {"@odata.id",
530 "/redfish/v1/SessionService/Sessions/" + session.unique_id},
531 {"@odata.type", "#Session.v1_0_3.Session"},
532 {"Id", session.unique_id},
533 {"Name", "User Session"},
534 {"Description", "Manager User Session"},
535 {"UserName", username}};
536 } else { // assume get
537 res.json_value = {
538 {"@odata.context",
539 "/redfish/v1/$metadata#SessionCollection.SessionCollection"},
540 {"@odata.id", "/redfish/v1/SessionService/Sessions"},
541 {"@odata.type", "#SessionCollection.SessionCollection"},
542 {"Name", "Session Collection"},
543 {"Description", "Session Collection"},
544 {"Members@odata.count", data_middleware.auth_tokens.size()}
545
546 };
547 nlohmann::json member_array = nlohmann::json::array();
548 for (auto& session : data_middleware.auth_tokens) {
549 member_array.push_back({{"@odata.id",
550 "/redfish/v1/SessionService/Sessions/" +
551 session.second.unique_id}});
552 }
553 res.json_value["Members"] = member_array;
554 }
555 res.end();
556 });
557
558 CROW_ROUTE(app, "/redfish/v1/SessionService/Sessions/<str>/")
559 .methods("GET"_method, "DELETE"_method)([&](const crow::request& req,
560 crow::response& res,
561 const std::string& session) {
562 auto& data_middleware =
563 app.template get_middleware<PersistentData::Middleware>();
564 auto session_it = data_middleware.auth_tokens.find(session);
565 if (session_it == data_middleware.auth_tokens.end()) {
566 res.code = 404;
567 res.end();
568 return;
569 }
570 if (req.method == "DELETE"_method) {
571 data_middleware.auth_tokens.erase(session_it);
572 res.code = 200;
573 } else { // assume get
574 res.json_value = {
575 {"@odata.context", "/redfish/v1/$metadata#Session.Session"},
576 {"@odata.id", "/redfish/v1/SessionService/Sessions/" + session},
577 {"@odata.type", "#Session.v1_0_3.Session"},
578 {"Id", session_it->second.unique_id},
579 {"Name", "User Session"},
580 {"Description", "Manager User Session"},
581 {"UserName", session_it->second.username}};
582 }
583 res.end();
Ed Tanous3dac7492017-08-02 13:46:20 -0700584 });
585}
Ed Tanous911ac312017-08-15 09:37:42 -0700586} // namespace redfish
587} // namespace crow