14c25d66eSEd Tanous #pragma once 24c25d66eSEd Tanous 33ccb3adbSEd Tanous #include "app.hpp" 481d523a7SEd Tanous #include "error_messages.hpp" 53ccb3adbSEd Tanous #include "http_request.hpp" 63ccb3adbSEd Tanous #include "http_response.hpp" 73ccb3adbSEd Tanous #include "query.hpp" 83ccb3adbSEd Tanous #include "registries/privilege_registry.hpp" 93ccb3adbSEd Tanous #include "schemas.hpp" 1081d523a7SEd Tanous #include "utility.hpp" 1181d523a7SEd Tanous 12ef4c65b7SEd Tanous #include <boost/url/format.hpp> 13ef4c65b7SEd Tanous 14*3544d2a7SEd Tanous #include <ranges> 154c25d66eSEd Tanous #include <string> 164c25d66eSEd Tanous 174c25d66eSEd Tanous namespace redfish 184c25d66eSEd Tanous { 194c25d66eSEd Tanous 20d3355c5cSEd Tanous inline void redfishGet(App& app, const crow::Request& req, 21d3355c5cSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 224c25d66eSEd Tanous { 233ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 241e925c84SEd Tanous { 251e925c84SEd Tanous return; 261e925c84SEd Tanous } 271476687dSEd Tanous asyncResp->res.jsonValue["v1"] = "/redfish/v1/"; 28d3355c5cSEd Tanous } 29d3355c5cSEd Tanous 308c623a96SEd Tanous inline void redfish404(App& app, const crow::Request& req, 318c623a96SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 328c623a96SEd Tanous const std::string& path) 338c623a96SEd Tanous { 348c623a96SEd Tanous asyncResp->res.addHeader(boost::beast::http::field::allow, ""); 358c623a96SEd Tanous 368c623a96SEd Tanous // If we fall to this route, we didn't have a more specific route, so return 378c623a96SEd Tanous // 404 38686b7093SNan Zhou if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 398c623a96SEd Tanous { 408c623a96SEd Tanous return; 418c623a96SEd Tanous } 428c623a96SEd Tanous 4362598e31SEd Tanous BMCWEB_LOG_WARNING("404 on path {}", path); 448c623a96SEd Tanous 4539662a3bSEd Tanous std::string name = req.url().segments().back(); 468c623a96SEd Tanous // Note, if we hit the wildcard route, we don't know the "type" the user was 478c623a96SEd Tanous // actually requesting, but giving them a return with an empty string is 488c623a96SEd Tanous // still better than nothing. 49079360aeSEd Tanous messages::resourceNotFound(asyncResp->res, "", name); 508c623a96SEd Tanous } 518c623a96SEd Tanous 5244c70412SEd Tanous inline void redfish405(App& app, const crow::Request& req, 5344c70412SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 5444c70412SEd Tanous const std::string& path) 5544c70412SEd Tanous { 5644c70412SEd Tanous // If we fall to this route, we didn't have a more specific route, so return 5744c70412SEd Tanous // 405 5844c70412SEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 5944c70412SEd Tanous { 6044c70412SEd Tanous return; 6144c70412SEd Tanous } 6244c70412SEd Tanous 6362598e31SEd Tanous BMCWEB_LOG_WARNING("405 on path {}", path); 6444c70412SEd Tanous asyncResp->res.result(boost::beast::http::status::method_not_allowed); 6544c70412SEd Tanous if (req.method() == boost::beast::http::verb::delete_) 6644c70412SEd Tanous { 6744c70412SEd Tanous messages::resourceCannotBeDeleted(asyncResp->res); 6844c70412SEd Tanous } 6944c70412SEd Tanous else 7044c70412SEd Tanous { 7144c70412SEd Tanous messages::operationNotAllowed(asyncResp->res); 7244c70412SEd Tanous } 7344c70412SEd Tanous } 7444c70412SEd Tanous 7581d523a7SEd Tanous inline void 7681d523a7SEd Tanous jsonSchemaIndexGet(App& app, const crow::Request& req, 7781d523a7SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 7881d523a7SEd Tanous { 7981d523a7SEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 8081d523a7SEd Tanous { 8181d523a7SEd Tanous return; 8281d523a7SEd Tanous } 8381d523a7SEd Tanous nlohmann::json& json = asyncResp->res.jsonValue; 8481d523a7SEd Tanous json["@odata.id"] = "/redfish/v1/JsonSchemas"; 8581d523a7SEd Tanous json["@odata.type"] = "#JsonSchemaFileCollection.JsonSchemaFileCollection"; 8681d523a7SEd Tanous json["Name"] = "JsonSchemaFile Collection"; 8781d523a7SEd Tanous json["Description"] = "Collection of JsonSchemaFiles"; 8881d523a7SEd Tanous nlohmann::json::array_t members; 8926ccae32SEd Tanous for (std::string_view schema : schemas) 9081d523a7SEd Tanous { 9181d523a7SEd Tanous nlohmann::json::object_t member; 92ef4c65b7SEd Tanous member["@odata.id"] = boost::urls::format("/redfish/v1/JsonSchemas/{}", 93ef4c65b7SEd Tanous schema); 94ad539545SPatrick Williams members.emplace_back(std::move(member)); 9581d523a7SEd Tanous } 9681d523a7SEd Tanous json["Members"] = std::move(members); 9781d523a7SEd Tanous json["Members@odata.count"] = schemas.size(); 9881d523a7SEd Tanous } 9981d523a7SEd Tanous 10081d523a7SEd Tanous inline void jsonSchemaGet(App& app, const crow::Request& req, 10181d523a7SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 10281d523a7SEd Tanous const std::string& schema) 10381d523a7SEd Tanous { 10481d523a7SEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 10581d523a7SEd Tanous { 10681d523a7SEd Tanous return; 10781d523a7SEd Tanous } 10881d523a7SEd Tanous 109*3544d2a7SEd Tanous if (std::ranges::find(schemas, schema) == schemas.end()) 11081d523a7SEd Tanous { 111d8a5d5d8SJiaqing Zhao messages::resourceNotFound(asyncResp->res, "JsonSchemaFile", schema); 11281d523a7SEd Tanous return; 11381d523a7SEd Tanous } 11481d523a7SEd Tanous 11581d523a7SEd Tanous nlohmann::json& json = asyncResp->res.jsonValue; 116ef4c65b7SEd Tanous json["@odata.id"] = boost::urls::format("/redfish/v1/JsonSchemas/{}", 117ef4c65b7SEd Tanous schema); 11881d523a7SEd Tanous json["@odata.type"] = "#JsonSchemaFile.v1_0_2.JsonSchemaFile"; 11981d523a7SEd Tanous json["Name"] = schema + " Schema File"; 12081d523a7SEd Tanous json["Description"] = schema + " Schema File Location"; 12181d523a7SEd Tanous json["Id"] = schema; 12281d523a7SEd Tanous std::string schemaName = "#"; 12381d523a7SEd Tanous schemaName += schema; 12481d523a7SEd Tanous schemaName += "."; 12581d523a7SEd Tanous schemaName += schema; 12681d523a7SEd Tanous json["Schema"] = std::move(schemaName); 12781d523a7SEd Tanous constexpr std::array<std::string_view, 1> languages{"en"}; 12881d523a7SEd Tanous json["Languages"] = languages; 12981d523a7SEd Tanous json["Languages@odata.count"] = languages.size(); 13081d523a7SEd Tanous 13181d523a7SEd Tanous nlohmann::json::array_t locationArray; 13281d523a7SEd Tanous nlohmann::json::object_t locationEntry; 13381d523a7SEd Tanous locationEntry["Language"] = "en"; 13489492a15SPatrick Williams locationEntry["PublicationUri"] = "http://redfish.dmtf.org/schemas/v1/" + 13589492a15SPatrick Williams schema + ".json"; 136ef4c65b7SEd Tanous locationEntry["Uri"] = boost::urls::format( 137ef4c65b7SEd Tanous "/redfish/v1/JsonSchemas/{}/{}", schema, std::string(schema) + ".json"); 13881d523a7SEd Tanous 13981d523a7SEd Tanous locationArray.emplace_back(locationEntry); 14081d523a7SEd Tanous 14181d523a7SEd Tanous json["Location"] = std::move(locationArray); 14281d523a7SEd Tanous json["Location@odata.count"] = 1; 14381d523a7SEd Tanous } 14481d523a7SEd Tanous 145f65fca6aSEd Tanous inline void requestRoutesRedfish(App& app) 146d3355c5cSEd Tanous { 147d3355c5cSEd Tanous BMCWEB_ROUTE(app, "/redfish/") 148d3355c5cSEd Tanous .methods(boost::beast::http::verb::get)( 149d3355c5cSEd Tanous std::bind_front(redfishGet, std::ref(app))); 1508c623a96SEd Tanous 15181d523a7SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/JsonSchemas/<str>/") 1520ea4b4e2SEd Tanous .privileges(redfish::privileges::getJsonSchemaFileCollection) 15381d523a7SEd Tanous .methods(boost::beast::http::verb::get)( 15481d523a7SEd Tanous std::bind_front(jsonSchemaGet, std::ref(app))); 15581d523a7SEd Tanous 15681d523a7SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/JsonSchemas/") 1570ea4b4e2SEd Tanous .privileges(redfish::privileges::getJsonSchemaFile) 15881d523a7SEd Tanous .methods(boost::beast::http::verb::get)( 15981d523a7SEd Tanous std::bind_front(jsonSchemaIndexGet, std::ref(app))); 160e9dd1d31SEd Tanous 161e9dd1d31SEd Tanous // Note, this route must always be registered last 162e9dd1d31SEd Tanous BMCWEB_ROUTE(app, "/redfish/<path>") 1630ea4b4e2SEd Tanous .notFound() 1640ea4b4e2SEd Tanous .privileges(redfish::privileges::privilegeSetLogin)( 1650ea4b4e2SEd Tanous std::bind_front(redfish404, std::ref(app))); 16644c70412SEd Tanous 16744c70412SEd Tanous BMCWEB_ROUTE(app, "/redfish/<path>") 1680ea4b4e2SEd Tanous .methodNotAllowed() 1690ea4b4e2SEd Tanous .privileges(redfish::privileges::privilegeSetLogin)( 1700ea4b4e2SEd Tanous std::bind_front(redfish405, std::ref(app))); 1714c25d66eSEd Tanous } 172f65fca6aSEd Tanous 1734c25d66eSEd Tanous } // namespace redfish 174