blob: bbda45bcdd1d1fdf20634385fd236a91a33b792f [file] [log] [blame]
Ed Tanous911ac312017-08-15 09:37:42 -07001#pragma once
2
Ed Tanous3ccb3ad2023-01-13 17:40:03 -08003#include "app.hpp"
Ed Tanous81d523a2022-05-25 12:00:51 -07004#include "error_messages.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -08005#include "http_request.hpp"
6#include "http_response.hpp"
7#include "query.hpp"
8#include "registries/privilege_registry.hpp"
9#include "schemas.hpp"
Ed Tanous81d523a2022-05-25 12:00:51 -070010#include "utility.hpp"
11
Ed Tanousef4c65b2023-04-24 15:28:50 -070012#include <boost/url/format.hpp>
13
Ed Tanous3544d2a2023-08-06 18:12:20 -070014#include <ranges>
Ed Tanousa8c4ce92021-03-24 08:44:51 -070015#include <string>
Ed Tanous1abe55e2018-09-05 08:30:59 -070016
Ed Tanous1abe55e2018-09-05 08:30:59 -070017namespace redfish
18{
Ed Tanousa8c4ce92021-03-24 08:44:51 -070019
Ed Tanousd3355c52022-05-11 14:40:49 -070020inline void redfishGet(App& app, const crow::Request& req,
21 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
22{
Carson Labrado3ba00072022-06-06 19:40:56 +000023 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanousd3355c52022-05-11 14:40:49 -070024 {
25 return;
26 }
27 asyncResp->res.jsonValue["v1"] = "/redfish/v1/";
28}
29
Ed Tanous8c623a92022-05-24 11:54:51 -070030inline void redfish404(App& app, const crow::Request& req,
31 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
32 const std::string& path)
33{
34 asyncResp->res.addHeader(boost::beast::http::field::allow, "");
35
36 // If we fall to this route, we didn't have a more specific route, so return
37 // 404
Nan Zhou686b7092022-06-15 20:02:27 +000038 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous8c623a92022-05-24 11:54:51 -070039 {
40 return;
41 }
42
Ed Tanous62598e32023-07-17 17:06:25 -070043 BMCWEB_LOG_WARNING("404 on path {}", path);
Ed Tanous8c623a92022-05-24 11:54:51 -070044
Ed Tanous39662a32023-02-06 15:09:46 -080045 std::string name = req.url().segments().back();
Ed Tanous8c623a92022-05-24 11:54:51 -070046 // Note, if we hit the wildcard route, we don't know the "type" the user was
47 // actually requesting, but giving them a return with an empty string is
48 // still better than nothing.
Ed Tanous079360a2022-06-29 10:05:19 -070049 messages::resourceNotFound(asyncResp->res, "", name);
Ed Tanous8c623a92022-05-24 11:54:51 -070050}
51
Ed Tanous44c70412022-07-31 16:48:29 -070052inline void redfish405(App& app, const crow::Request& req,
53 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
54 const std::string& path)
55{
56 // If we fall to this route, we didn't have a more specific route, so return
57 // 405
58 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
59 {
60 return;
61 }
62
Ed Tanous62598e32023-07-17 17:06:25 -070063 BMCWEB_LOG_WARNING("405 on path {}", path);
Ed Tanous44c70412022-07-31 16:48:29 -070064 asyncResp->res.result(boost::beast::http::status::method_not_allowed);
65 if (req.method() == boost::beast::http::verb::delete_)
66 {
67 messages::resourceCannotBeDeleted(asyncResp->res);
68 }
69 else
70 {
71 messages::operationNotAllowed(asyncResp->res);
72 }
73}
74
Ed Tanous81d523a2022-05-25 12:00:51 -070075inline void
76 jsonSchemaIndexGet(App& app, const crow::Request& req,
77 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
78{
79 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
80 {
81 return;
82 }
83 nlohmann::json& json = asyncResp->res.jsonValue;
84 json["@odata.id"] = "/redfish/v1/JsonSchemas";
Ed Tanous81d523a2022-05-25 12:00:51 -070085 json["@odata.type"] = "#JsonSchemaFileCollection.JsonSchemaFileCollection";
86 json["Name"] = "JsonSchemaFile Collection";
87 json["Description"] = "Collection of JsonSchemaFiles";
88 nlohmann::json::array_t members;
Ed Tanous26ccae32023-02-16 10:28:44 -080089 for (std::string_view schema : schemas)
Ed Tanous81d523a2022-05-25 12:00:51 -070090 {
91 nlohmann::json::object_t member;
Ed Tanousef4c65b2023-04-24 15:28:50 -070092 member["@odata.id"] = boost::urls::format("/redfish/v1/JsonSchemas/{}",
93 schema);
Patrick Williamsad539542023-05-12 10:10:08 -050094 members.emplace_back(std::move(member));
Ed Tanous81d523a2022-05-25 12:00:51 -070095 }
96 json["Members"] = std::move(members);
97 json["Members@odata.count"] = schemas.size();
98}
99
100inline void jsonSchemaGet(App& app, const crow::Request& req,
101 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
102 const std::string& schema)
103{
104 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
105 {
106 return;
107 }
108
Ed Tanous3544d2a2023-08-06 18:12:20 -0700109 if (std::ranges::find(schemas, schema) == schemas.end())
Ed Tanous81d523a2022-05-25 12:00:51 -0700110 {
Jiaqing Zhaod8a5d5d2022-08-05 16:21:51 +0800111 messages::resourceNotFound(asyncResp->res, "JsonSchemaFile", schema);
Ed Tanous81d523a2022-05-25 12:00:51 -0700112 return;
113 }
114
115 nlohmann::json& json = asyncResp->res.jsonValue;
Ed Tanousef4c65b2023-04-24 15:28:50 -0700116 json["@odata.id"] = boost::urls::format("/redfish/v1/JsonSchemas/{}",
117 schema);
Ed Tanous81d523a2022-05-25 12:00:51 -0700118 json["@odata.type"] = "#JsonSchemaFile.v1_0_2.JsonSchemaFile";
119 json["Name"] = schema + " Schema File";
120 json["Description"] = schema + " Schema File Location";
121 json["Id"] = schema;
122 std::string schemaName = "#";
123 schemaName += schema;
124 schemaName += ".";
125 schemaName += schema;
126 json["Schema"] = std::move(schemaName);
127 constexpr std::array<std::string_view, 1> languages{"en"};
128 json["Languages"] = languages;
129 json["Languages@odata.count"] = languages.size();
130
131 nlohmann::json::array_t locationArray;
132 nlohmann::json::object_t locationEntry;
133 locationEntry["Language"] = "en";
Patrick Williams89492a12023-05-10 07:51:34 -0500134 locationEntry["PublicationUri"] = "http://redfish.dmtf.org/schemas/v1/" +
135 schema + ".json";
Ed Tanousef4c65b2023-04-24 15:28:50 -0700136 locationEntry["Uri"] = boost::urls::format(
137 "/redfish/v1/JsonSchemas/{}/{}", schema, std::string(schema) + ".json");
Ed Tanous81d523a2022-05-25 12:00:51 -0700138
139 locationArray.emplace_back(locationEntry);
140
141 json["Location"] = std::move(locationArray);
142 json["Location@odata.count"] = 1;
143}
144
Ed Tanousf65fca62022-05-24 12:49:41 -0700145inline void requestRoutesRedfish(App& app)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700146{
147 BMCWEB_ROUTE(app, "/redfish/")
Ed Tanousb41187f2019-10-24 16:30:02 -0700148 .methods(boost::beast::http::verb::get)(
Ed Tanousd3355c52022-05-11 14:40:49 -0700149 std::bind_front(redfishGet, std::ref(app)));
Ed Tanous8c623a92022-05-24 11:54:51 -0700150
Ed Tanous81d523a2022-05-25 12:00:51 -0700151 BMCWEB_ROUTE(app, "/redfish/v1/JsonSchemas/<str>/")
Ed Tanous0ea4b4e2022-08-29 14:30:16 -0700152 .privileges(redfish::privileges::getJsonSchemaFileCollection)
Ed Tanous81d523a2022-05-25 12:00:51 -0700153 .methods(boost::beast::http::verb::get)(
154 std::bind_front(jsonSchemaGet, std::ref(app)));
155
156 BMCWEB_ROUTE(app, "/redfish/v1/JsonSchemas/")
Ed Tanous0ea4b4e2022-08-29 14:30:16 -0700157 .privileges(redfish::privileges::getJsonSchemaFile)
Ed Tanous81d523a2022-05-25 12:00:51 -0700158 .methods(boost::beast::http::verb::get)(
159 std::bind_front(jsonSchemaIndexGet, std::ref(app)));
Ed Tanouse9dd1d32022-06-17 11:56:00 -0700160
161 // Note, this route must always be registered last
162 BMCWEB_ROUTE(app, "/redfish/<path>")
Ed Tanous0ea4b4e2022-08-29 14:30:16 -0700163 .notFound()
164 .privileges(redfish::privileges::privilegeSetLogin)(
165 std::bind_front(redfish404, std::ref(app)));
Ed Tanous44c70412022-07-31 16:48:29 -0700166
167 BMCWEB_ROUTE(app, "/redfish/<path>")
Ed Tanous0ea4b4e2022-08-29 14:30:16 -0700168 .methodNotAllowed()
169 .privileges(redfish::privileges::privilegeSetLogin)(
170 std::bind_front(redfish405, std::ref(app)));
Ed Tanous3dac7492017-08-02 13:46:20 -0700171}
Ed Tanousf65fca62022-05-24 12:49:41 -0700172
Ed Tanous1abe55e2018-09-05 08:30:59 -0700173} // namespace redfish