1 // SPDX-License-Identifier: Apache-2.0
2 // SPDX-FileCopyrightText: Copyright OpenBMC Authors
3 // SPDX-FileCopyrightText: Copyright 2018 Intel Corporation
4 #pragma once
5
6 #include "bmcweb_config.h"
7
8 #include "app.hpp"
9 #include "async_resp.hpp"
10 #include "http_request.hpp"
11 #include "persistent_data.hpp"
12 #include "query.hpp"
13 #include "registries/privilege_registry.hpp"
14
15 #include <boost/beast/http/field.hpp>
16 #include <boost/beast/http/verb.hpp>
17 #include <boost/url/format.hpp>
18 #include <nlohmann/json.hpp>
19
20 #include <functional>
21 #include <memory>
22 #include <string>
23
24 namespace redfish
25 {
26
handleServiceRootHead(App & app,const crow::Request & req,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp)27 inline void handleServiceRootHead(
28 App& app, const crow::Request& req,
29 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
30 {
31 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
32 {
33 return;
34 }
35
36 asyncResp->res.addHeader(
37 boost::beast::http::field::link,
38 "</redfish/v1/JsonSchemas/ServiceRoot/ServiceRoot.json>; rel=describedby");
39 }
40
handleServiceRootGetImpl(const std::shared_ptr<bmcweb::AsyncResp> & asyncResp)41 inline void handleServiceRootGetImpl(
42 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
43 {
44 asyncResp->res.addHeader(
45 boost::beast::http::field::link,
46 "</redfish/v1/JsonSchemas/ServiceRoot/ServiceRoot.json>; rel=describedby");
47
48 std::string uuid = persistent_data::getConfig().systemUuid;
49 asyncResp->res.jsonValue["@odata.type"] =
50 "#ServiceRoot.v1_15_0.ServiceRoot";
51 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1";
52 asyncResp->res.jsonValue["Id"] = "RootService";
53 asyncResp->res.jsonValue["Name"] = "Root Service";
54 asyncResp->res.jsonValue["RedfishVersion"] = "1.17.0";
55 asyncResp->res.jsonValue["Links"]["Sessions"]["@odata.id"] =
56 "/redfish/v1/SessionService/Sessions";
57 asyncResp->res.jsonValue["AccountService"]["@odata.id"] =
58 "/redfish/v1/AccountService";
59 if constexpr (BMCWEB_REDFISH_AGGREGATION)
60 {
61 asyncResp->res.jsonValue["AggregationService"]["@odata.id"] =
62 "/redfish/v1/AggregationService";
63 }
64 asyncResp->res.jsonValue["Chassis"]["@odata.id"] = "/redfish/v1/Chassis";
65 asyncResp->res.jsonValue["JsonSchemas"]["@odata.id"] =
66 "/redfish/v1/JsonSchemas";
67 asyncResp->res.jsonValue["Managers"]["@odata.id"] = "/redfish/v1/Managers";
68 asyncResp->res.jsonValue["SessionService"]["@odata.id"] =
69 "/redfish/v1/SessionService";
70 asyncResp->res.jsonValue["Systems"]["@odata.id"] = "/redfish/v1/Systems";
71 asyncResp->res.jsonValue["Registries"]["@odata.id"] =
72 "/redfish/v1/Registries";
73 asyncResp->res.jsonValue["UpdateService"]["@odata.id"] =
74 "/redfish/v1/UpdateService";
75 asyncResp->res.jsonValue["UUID"] = uuid;
76 asyncResp->res.jsonValue["CertificateService"]["@odata.id"] =
77 "/redfish/v1/CertificateService";
78 asyncResp->res.jsonValue["Tasks"]["@odata.id"] = "/redfish/v1/TaskService";
79 asyncResp->res.jsonValue["EventService"]["@odata.id"] =
80 "/redfish/v1/EventService";
81 asyncResp->res.jsonValue["TelemetryService"]["@odata.id"] =
82 "/redfish/v1/TelemetryService";
83 asyncResp->res.jsonValue["Cables"]["@odata.id"] = "/redfish/v1/Cables";
84
85 asyncResp->res.jsonValue["Links"]["ManagerProvidingService"]["@odata.id"] =
86 boost::urls::format("/redfish/v1/Managers/{}",
87 BMCWEB_REDFISH_MANAGER_URI_NAME);
88
89 nlohmann::json& protocolFeatures =
90 asyncResp->res.jsonValue["ProtocolFeaturesSupported"];
91 protocolFeatures["ExcerptQuery"] = false;
92
93 protocolFeatures["ExpandQuery"]["ExpandAll"] =
94 BMCWEB_INSECURE_ENABLE_REDFISH_QUERY;
95 // This is the maximum level defined in ServiceRoot.v1_13_0.json
96 if constexpr (BMCWEB_INSECURE_ENABLE_REDFISH_QUERY)
97 {
98 protocolFeatures["ExpandQuery"]["MaxLevels"] = 6;
99 }
100 protocolFeatures["ExpandQuery"]["Levels"] =
101 BMCWEB_INSECURE_ENABLE_REDFISH_QUERY;
102 protocolFeatures["ExpandQuery"]["Links"] =
103 BMCWEB_INSECURE_ENABLE_REDFISH_QUERY;
104 protocolFeatures["ExpandQuery"]["NoLinks"] =
105 BMCWEB_INSECURE_ENABLE_REDFISH_QUERY;
106 protocolFeatures["FilterQuery"] = BMCWEB_INSECURE_ENABLE_REDFISH_QUERY;
107 protocolFeatures["OnlyMemberQuery"] = true;
108 protocolFeatures["SelectQuery"] = true;
109 protocolFeatures["DeepOperations"]["DeepPOST"] = false;
110 protocolFeatures["DeepOperations"]["DeepPATCH"] = false;
111 }
handleServiceRootGet(App & app,const crow::Request & req,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp)112 inline void handleServiceRootGet(
113 App& app, const crow::Request& req,
114 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
115 {
116 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
117 {
118 return;
119 }
120
121 handleServiceRootGetImpl(asyncResp);
122 }
123
requestRoutesServiceRoot(App & app)124 inline void requestRoutesServiceRoot(App& app)
125 {
126 BMCWEB_ROUTE(app, "/redfish/v1/")
127 .privileges(redfish::privileges::headServiceRoot)
128 .methods(boost::beast::http::verb::head)(
129 std::bind_front(handleServiceRootHead, std::ref(app)));
130 BMCWEB_ROUTE(app, "/redfish/v1/")
131 .privileges(redfish::privileges::getServiceRoot)
132 .methods(boost::beast::http::verb::get)(
133 std::bind_front(handleServiceRootGet, std::ref(app)));
134 }
135
136 } // namespace redfish
137