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 27 inline void 28 handleServiceRootHead(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 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 } 112 inline void 113 handleServiceRootGet(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 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