blob: 51437c9ac058e2ed2eeaaa641d9c91cc7ddf690c [file] [log] [blame]
Ratan Gupta453fed02019-12-14 09:39:47 +05301#pragma once
Ratan Gupta453fed02019-12-14 09:39:47 +05302
Ed Tanous3ccb3ad2023-01-13 17:40:03 -08003#include "app.hpp"
4#include "async_resp.hpp"
5#include "error_messages.hpp"
6#include "event_service_manager.hpp"
Sunitha Harish56d0bb02024-04-06 03:35:34 -05007#include "ibm/utils.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -08008#include "resource_messages.hpp"
Ed Tanous18f8f602023-07-18 10:07:23 -07009#include "str_utility.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080010#include "utils/json_utils.hpp"
11
Sunitha Harish97b0e432019-11-21 04:59:29 -060012#include <boost/container/flat_set.hpp>
manojkiraneda0b631ae2019-12-03 17:54:28 +053013#include <nlohmann/json.hpp>
Sunitha Harish97b0e432019-11-21 04:59:29 -060014#include <sdbusplus/message/types.hpp>
15
Gunnar Mills1214b7e2020-06-04 10:11:30 -050016#include <filesystem>
17#include <fstream>
Gunnar Mills1214b7e2020-06-04 10:11:30 -050018
Ratan Gupta453fed02019-12-14 09:39:47 +053019namespace crow
20{
21namespace ibm_mc
22{
Gunnar Mills1214b7e2020-06-04 10:11:30 -050023constexpr const char* methodNotAllowedMsg = "Method Not Allowed";
24constexpr const char* resourceNotFoundMsg = "Resource Not Found";
25constexpr const char* contentNotAcceptableMsg = "Content Not Acceptable";
26constexpr const char* internalServerError = "Internal Server Error";
Sunitha Harish97b0e432019-11-21 04:59:29 -060027
Sunitha Harish7c0bbe72020-07-30 08:25:28 -050028constexpr size_t maxSaveareaDirSize =
Sunitha Harishf8a43472022-08-08 02:07:12 -050029 25000000; // Allow save area dir size to be max 25MB
Sunitha Harish7c0bbe72020-07-30 08:25:28 -050030constexpr size_t minSaveareaFileSize =
Patrick Williams89492a12023-05-10 07:51:34 -050031 100; // Allow save area file size of minimum 100B
Asmitha Karunanithi5738de52020-07-17 02:03:31 -050032constexpr size_t maxSaveareaFileSize =
Patrick Williams89492a12023-05-10 07:51:34 -050033 500000; // Allow save area file size upto 500KB
Asmitha Karunanithi5738de52020-07-17 02:03:31 -050034constexpr size_t maxBroadcastMsgSize =
Patrick Williams89492a12023-05-10 07:51:34 -050035 1000; // Allow Broadcast message size upto 1KB
Asmitha Karunanithi5738de52020-07-17 02:03:31 -050036
Sunitha Harishdb81c072021-01-21 23:33:21 -060037inline void handleFilePut(const crow::Request& req,
38 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous02379d32020-09-15 21:15:44 -070039 const std::string& fileID)
Sunitha Harish97b0e432019-11-21 04:59:29 -060040{
Sunitha Harish7c0bbe72020-07-30 08:25:28 -050041 std::error_code ec;
Sunitha Harish97b0e432019-11-21 04:59:29 -060042 // Check the content-type of the request
Sunitha Harish086d32c2021-02-01 02:11:49 -060043 boost::beast::string_view contentType = req.getHeaderValue("content-type");
Ed Tanous18f8f602023-07-18 10:07:23 -070044 if (!bmcweb::asciiIEquals(contentType, "application/octet-stream"))
Sunitha Harish97b0e432019-11-21 04:59:29 -060045 {
Sunitha Harishdb81c072021-01-21 23:33:21 -060046 asyncResp->res.result(boost::beast::http::status::not_acceptable);
47 asyncResp->res.jsonValue["Description"] = contentNotAcceptableMsg;
Sunitha Harish97b0e432019-11-21 04:59:29 -060048 return;
49 }
Ed Tanous62598e32023-07-17 17:06:25 -070050 BMCWEB_LOG_DEBUG(
51 "File upload in application/octet-stream format. Continue..");
asmithakarun1c7b07c2019-09-09 03:42:59 -050052
Ed Tanous62598e32023-07-17 17:06:25 -070053 BMCWEB_LOG_DEBUG(
54 "handleIbmPut: Request to create/update the save-area file");
Sunitha Harish3e919b52020-10-13 01:21:48 -050055 std::string_view path =
56 "/var/lib/bmcweb/ibm-management-console/configfiles";
57 if (!crow::ibm_utils::createDirectory(path))
Sunitha Harish97b0e432019-11-21 04:59:29 -060058 {
Sunitha Harishdb81c072021-01-21 23:33:21 -060059 asyncResp->res.result(boost::beast::http::status::not_found);
60 asyncResp->res.jsonValue["Description"] = resourceNotFoundMsg;
asmithakarun1c7b07c2019-09-09 03:42:59 -050061 return;
62 }
Sunitha Harish7c0bbe72020-07-30 08:25:28 -050063
asmithakarun1c7b07c2019-09-09 03:42:59 -050064 std::ofstream file;
Sunitha Harish3e919b52020-10-13 01:21:48 -050065 std::filesystem::path loc(
66 "/var/lib/bmcweb/ibm-management-console/configfiles");
Sunitha Harish97b0e432019-11-21 04:59:29 -060067
Sunitha Harish7c0bbe72020-07-30 08:25:28 -050068 // Get the current size of the savearea directory
69 std::filesystem::recursive_directory_iterator iter(loc, ec);
70 if (ec)
71 {
Sunitha Harishdb81c072021-01-21 23:33:21 -060072 asyncResp->res.result(
73 boost::beast::http::status::internal_server_error);
74 asyncResp->res.jsonValue["Description"] = internalServerError;
Ed Tanous62598e32023-07-17 17:06:25 -070075 BMCWEB_LOG_DEBUG("handleIbmPut: Failed to prepare save-area "
76 "directory iterator. ec : {}",
77 ec.message());
Sunitha Harish7c0bbe72020-07-30 08:25:28 -050078 return;
79 }
80 std::uintmax_t saveAreaDirSize = 0;
Ed Tanous9eb808c2022-01-25 10:19:23 -080081 for (const auto& it : iter)
Sunitha Harish7c0bbe72020-07-30 08:25:28 -050082 {
83 if (!std::filesystem::is_directory(it, ec))
84 {
85 if (ec)
86 {
Sunitha Harishdb81c072021-01-21 23:33:21 -060087 asyncResp->res.result(
88 boost::beast::http::status::internal_server_error);
89 asyncResp->res.jsonValue["Description"] = internalServerError;
Ed Tanous62598e32023-07-17 17:06:25 -070090 BMCWEB_LOG_DEBUG("handleIbmPut: Failed to find save-area "
91 "directory . ec : {}",
92 ec.message());
Sunitha Harish7c0bbe72020-07-30 08:25:28 -050093 return;
94 }
95 std::uintmax_t fileSize = std::filesystem::file_size(it, ec);
96 if (ec)
97 {
Sunitha Harishdb81c072021-01-21 23:33:21 -060098 asyncResp->res.result(
99 boost::beast::http::status::internal_server_error);
100 asyncResp->res.jsonValue["Description"] = internalServerError;
Ed Tanous62598e32023-07-17 17:06:25 -0700101 BMCWEB_LOG_DEBUG("handleIbmPut: Failed to find save-area "
102 "file size inside the directory . ec : {}",
103 ec.message());
Sunitha Harish7c0bbe72020-07-30 08:25:28 -0500104 return;
105 }
106 saveAreaDirSize += fileSize;
107 }
108 }
Ed Tanous62598e32023-07-17 17:06:25 -0700109 BMCWEB_LOG_DEBUG("saveAreaDirSize: {}", saveAreaDirSize);
Sunitha Harish7c0bbe72020-07-30 08:25:28 -0500110
111 // Get the file size getting uploaded
Ed Tanous33c6b582023-02-14 15:05:48 -0800112 const std::string& data = req.body();
Ed Tanous62598e32023-07-17 17:06:25 -0700113 BMCWEB_LOG_DEBUG("data length: {}", data.length());
Sunitha Harish7c0bbe72020-07-30 08:25:28 -0500114
115 if (data.length() < minSaveareaFileSize)
116 {
Sunitha Harishdb81c072021-01-21 23:33:21 -0600117 asyncResp->res.result(boost::beast::http::status::bad_request);
118 asyncResp->res.jsonValue["Description"] =
Sunitha Harish7c0bbe72020-07-30 08:25:28 -0500119 "File size is less than minimum allowed size[100B]";
120 return;
121 }
122 if (data.length() > maxSaveareaFileSize)
asmithakarun1c7b07c2019-09-09 03:42:59 -0500123 {
Sunitha Harishdb81c072021-01-21 23:33:21 -0600124 asyncResp->res.result(boost::beast::http::status::bad_request);
125 asyncResp->res.jsonValue["Description"] =
Ratan Guptae46946a2020-05-11 13:22:59 +0530126 "File size exceeds maximum allowed size[500KB]";
asmithakarun1c7b07c2019-09-09 03:42:59 -0500127 return;
128 }
Sunitha Harish7c0bbe72020-07-30 08:25:28 -0500129
130 // Form the file path
131 loc /= fileID;
Ed Tanous62598e32023-07-17 17:06:25 -0700132 BMCWEB_LOG_DEBUG("Writing to the file: {}", loc.string());
Asmitha Karunanithi10693fa2020-07-27 02:27:49 -0500133
Sunitha Harish7c0bbe72020-07-30 08:25:28 -0500134 // Check if the same file exists in the directory
135 bool fileExists = std::filesystem::exists(loc, ec);
136 if (ec)
Asmitha Karunanithi10693fa2020-07-27 02:27:49 -0500137 {
Sunitha Harishdb81c072021-01-21 23:33:21 -0600138 asyncResp->res.result(
139 boost::beast::http::status::internal_server_error);
140 asyncResp->res.jsonValue["Description"] = internalServerError;
Ed Tanous62598e32023-07-17 17:06:25 -0700141 BMCWEB_LOG_DEBUG("handleIbmPut: Failed to find if file exists. ec : {}",
142 ec.message());
Sunitha Harish7c0bbe72020-07-30 08:25:28 -0500143 return;
Asmitha Karunanithi10693fa2020-07-27 02:27:49 -0500144 }
Sunitha Harish7c0bbe72020-07-30 08:25:28 -0500145
146 std::uintmax_t newSizeToWrite = 0;
147 if (fileExists)
148 {
149 // File exists. Get the current file size
150 std::uintmax_t currentFileSize = std::filesystem::file_size(loc, ec);
151 if (ec)
152 {
Sunitha Harishdb81c072021-01-21 23:33:21 -0600153 asyncResp->res.result(
154 boost::beast::http::status::internal_server_error);
155 asyncResp->res.jsonValue["Description"] = internalServerError;
Ed Tanous62598e32023-07-17 17:06:25 -0700156 BMCWEB_LOG_DEBUG("handleIbmPut: Failed to find file size. ec : {}",
157 ec.message());
Sunitha Harish7c0bbe72020-07-30 08:25:28 -0500158 return;
159 }
160 // Calculate the difference in the file size.
161 // If the data.length is greater than the existing file size, then
162 // calculate the difference. Else consider the delta size as zero -
163 // because there is no increase in the total directory size.
164 // We need to add the diff only if the incoming data is larger than the
165 // existing filesize
166 if (data.length() > currentFileSize)
167 {
168 newSizeToWrite = data.length() - currentFileSize;
169 }
Ed Tanous62598e32023-07-17 17:06:25 -0700170 BMCWEB_LOG_DEBUG("newSizeToWrite: {}", newSizeToWrite);
Sunitha Harish7c0bbe72020-07-30 08:25:28 -0500171 }
172 else
173 {
174 // This is a new file upload
175 newSizeToWrite = data.length();
176 }
177
178 // Calculate the total dir size before writing the new file
Ed Tanous62598e32023-07-17 17:06:25 -0700179 BMCWEB_LOG_DEBUG("total new size: {}", saveAreaDirSize + newSizeToWrite);
Sunitha Harish7c0bbe72020-07-30 08:25:28 -0500180
181 if ((saveAreaDirSize + newSizeToWrite) > maxSaveareaDirSize)
182 {
Sunitha Harishdb81c072021-01-21 23:33:21 -0600183 asyncResp->res.result(boost::beast::http::status::bad_request);
184 asyncResp->res.jsonValue["Description"] =
185 "File size does not fit in the savearea "
Sunitha Harishf8a43472022-08-08 02:07:12 -0500186 "directory maximum allowed size[25MB]";
Sunitha Harish7c0bbe72020-07-30 08:25:28 -0500187 return;
188 }
189
asmithakarun1c7b07c2019-09-09 03:42:59 -0500190 file.open(loc, std::ofstream::out);
Sunitha Harish3e919b52020-10-13 01:21:48 -0500191
192 // set the permission of the file to 600
193 std::filesystem::perms permission = std::filesystem::perms::owner_write |
194 std::filesystem::perms::owner_read;
195 std::filesystem::permissions(loc, permission);
196
asmithakarun1c7b07c2019-09-09 03:42:59 -0500197 if (file.fail())
198 {
Ed Tanous62598e32023-07-17 17:06:25 -0700199 BMCWEB_LOG_DEBUG("Error while opening the file for writing");
Sunitha Harishdb81c072021-01-21 23:33:21 -0600200 asyncResp->res.result(
201 boost::beast::http::status::internal_server_error);
202 asyncResp->res.jsonValue["Description"] =
203 "Error while creating the file";
asmithakarun1c7b07c2019-09-09 03:42:59 -0500204 return;
Sunitha Harish97b0e432019-11-21 04:59:29 -0600205 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700206 file << data;
Sunitha Harish3e919b52020-10-13 01:21:48 -0500207
Ed Tanous3174e4d2020-10-07 11:41:22 -0700208 // Push an event
209 if (fileExists)
210 {
Ed Tanous62598e32023-07-17 17:06:25 -0700211 BMCWEB_LOG_DEBUG("config file is updated");
Sunitha Harishdb81c072021-01-21 23:33:21 -0600212 asyncResp->res.jsonValue["Description"] = "File Updated";
Ed Tanous3174e4d2020-10-07 11:41:22 -0700213 }
Sunitha Harish97b0e432019-11-21 04:59:29 -0600214 else
215 {
Ed Tanous62598e32023-07-17 17:06:25 -0700216 BMCWEB_LOG_DEBUG("config file is created");
Sunitha Harishdb81c072021-01-21 23:33:21 -0600217 asyncResp->res.jsonValue["Description"] = "File Created";
asmithakarun1c7b07c2019-09-09 03:42:59 -0500218 }
Ratan Guptad3630cb2019-12-14 11:21:35 +0530219}
asmithakarun1c7b07c2019-09-09 03:42:59 -0500220
zhanghch058d1b46d2021-04-01 11:18:24 +0800221inline void
222 handleConfigFileList(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ratan Guptad3630cb2019-12-14 11:21:35 +0530223{
224 std::vector<std::string> pathObjList;
Sunitha Harish3e919b52020-10-13 01:21:48 -0500225 std::filesystem::path loc(
226 "/var/lib/bmcweb/ibm-management-console/configfiles");
Ratan Guptad3630cb2019-12-14 11:21:35 +0530227 if (std::filesystem::exists(loc) && std::filesystem::is_directory(loc))
228 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500229 for (const auto& file : std::filesystem::directory_iterator(loc))
Ratan Guptad3630cb2019-12-14 11:21:35 +0530230 {
Ed Tanous3174e4d2020-10-07 11:41:22 -0700231 const std::filesystem::path& pathObj = file.path();
cm-jishnu5a193962022-12-02 03:45:27 -0600232 if (std::filesystem::is_regular_file(pathObj))
233 {
Patrick Williamsb2ba3072023-05-12 10:27:39 -0500234 pathObjList.emplace_back("/ibm/v1/Host/ConfigFiles/" +
235 pathObj.filename().string());
cm-jishnu5a193962022-12-02 03:45:27 -0600236 }
Ratan Guptad3630cb2019-12-14 11:21:35 +0530237 }
238 }
Sunitha Harishdb81c072021-01-21 23:33:21 -0600239 asyncResp->res.jsonValue["@odata.type"] =
240 "#IBMConfigFile.v1_0_0.IBMConfigFile";
241 asyncResp->res.jsonValue["@odata.id"] = "/ibm/v1/Host/ConfigFiles/";
242 asyncResp->res.jsonValue["Id"] = "ConfigFiles";
243 asyncResp->res.jsonValue["Name"] = "ConfigFiles";
Ratan Guptad3630cb2019-12-14 11:21:35 +0530244
Sunitha Harishdb81c072021-01-21 23:33:21 -0600245 asyncResp->res.jsonValue["Members"] = std::move(pathObjList);
246 asyncResp->res.jsonValue["Actions"]["#IBMConfigFiles.DeleteAll"] = {
Ratan Guptad3630cb2019-12-14 11:21:35 +0530247 {"target",
Sunitha Harishe56f2542020-07-22 02:38:59 -0500248 "/ibm/v1/Host/ConfigFiles/Actions/IBMConfigFiles.DeleteAll"}};
Ratan Guptad3630cb2019-12-14 11:21:35 +0530249}
250
zhanghch058d1b46d2021-04-01 11:18:24 +0800251inline void
252 deleteConfigFiles(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ratan Guptad3630cb2019-12-14 11:21:35 +0530253{
Ratan Guptad3630cb2019-12-14 11:21:35 +0530254 std::error_code ec;
Sunitha Harish3e919b52020-10-13 01:21:48 -0500255 std::filesystem::path loc(
256 "/var/lib/bmcweb/ibm-management-console/configfiles");
Ratan Guptad3630cb2019-12-14 11:21:35 +0530257 if (std::filesystem::exists(loc) && std::filesystem::is_directory(loc))
258 {
259 std::filesystem::remove_all(loc, ec);
260 if (ec)
261 {
Sunitha Harishdb81c072021-01-21 23:33:21 -0600262 asyncResp->res.result(
263 boost::beast::http::status::internal_server_error);
264 asyncResp->res.jsonValue["Description"] = internalServerError;
Ed Tanous62598e32023-07-17 17:06:25 -0700265 BMCWEB_LOG_DEBUG("deleteConfigFiles: Failed to delete the "
266 "config files directory. ec : {}",
267 ec.message());
Ratan Guptad3630cb2019-12-14 11:21:35 +0530268 }
269 }
asmithakarun1c7b07c2019-09-09 03:42:59 -0500270}
271
Sunitha Harishdb81c072021-01-21 23:33:21 -0600272inline void handleFileGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
273 const std::string& fileID)
asmithakarun1c7b07c2019-09-09 03:42:59 -0500274{
Ed Tanous62598e32023-07-17 17:06:25 -0700275 BMCWEB_LOG_DEBUG("HandleGet on SaveArea files on path: {}", fileID);
Sunitha Harish3e919b52020-10-13 01:21:48 -0500276 std::filesystem::path loc(
277 "/var/lib/bmcweb/ibm-management-console/configfiles/" + fileID);
cm-jishnu5a193962022-12-02 03:45:27 -0600278 if (!std::filesystem::exists(loc) || !std::filesystem::is_regular_file(loc))
asmithakarun1c7b07c2019-09-09 03:42:59 -0500279 {
Ed Tanous62598e32023-07-17 17:06:25 -0700280 BMCWEB_LOG_WARNING("{} Not found", loc.string());
Sunitha Harishdb81c072021-01-21 23:33:21 -0600281 asyncResp->res.result(boost::beast::http::status::not_found);
282 asyncResp->res.jsonValue["Description"] = resourceNotFoundMsg;
asmithakarun1c7b07c2019-09-09 03:42:59 -0500283 return;
284 }
285
286 std::ifstream readfile(loc.string());
287 if (!readfile)
288 {
Ed Tanous62598e32023-07-17 17:06:25 -0700289 BMCWEB_LOG_WARNING("{} Not found", loc.string());
Sunitha Harishdb81c072021-01-21 23:33:21 -0600290 asyncResp->res.result(boost::beast::http::status::not_found);
291 asyncResp->res.jsonValue["Description"] = resourceNotFoundMsg;
asmithakarun1c7b07c2019-09-09 03:42:59 -0500292 return;
293 }
294
Patrick Williams89492a12023-05-10 07:51:34 -0500295 std::string contentDispositionParam = "attachment; filename=\"" + fileID +
296 "\"";
Ed Tanousd9f6c622022-03-17 09:12:17 -0700297 asyncResp->res.addHeader(boost::beast::http::field::content_disposition,
298 contentDispositionParam);
asmithakarun1c7b07c2019-09-09 03:42:59 -0500299 std::string fileData;
300 fileData = {std::istreambuf_iterator<char>(readfile),
301 std::istreambuf_iterator<char>()};
Sunitha Harishdb81c072021-01-21 23:33:21 -0600302 asyncResp->res.jsonValue["Data"] = fileData;
asmithakarun1c7b07c2019-09-09 03:42:59 -0500303}
304
Sunitha Harishdb81c072021-01-21 23:33:21 -0600305inline void
306 handleFileDelete(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
307 const std::string& fileID)
asmithakarun1c7b07c2019-09-09 03:42:59 -0500308{
Sunitha Harish3e919b52020-10-13 01:21:48 -0500309 std::string filePath("/var/lib/bmcweb/ibm-management-console/configfiles/" +
310 fileID);
Ed Tanous62598e32023-07-17 17:06:25 -0700311 BMCWEB_LOG_DEBUG("Removing the file : {}", filePath);
Ed Tanous2c70f802020-09-28 14:29:23 -0700312 std::ifstream fileOpen(filePath.c_str());
313 if (static_cast<bool>(fileOpen))
Ed Tanous3174e4d2020-10-07 11:41:22 -0700314 {
asmithakarun1c7b07c2019-09-09 03:42:59 -0500315 if (remove(filePath.c_str()) == 0)
316 {
Ed Tanous62598e32023-07-17 17:06:25 -0700317 BMCWEB_LOG_DEBUG("File removed!");
Sunitha Harishdb81c072021-01-21 23:33:21 -0600318 asyncResp->res.jsonValue["Description"] = "File Deleted";
asmithakarun1c7b07c2019-09-09 03:42:59 -0500319 }
320 else
321 {
Ed Tanous62598e32023-07-17 17:06:25 -0700322 BMCWEB_LOG_ERROR("File not removed!");
Sunitha Harishdb81c072021-01-21 23:33:21 -0600323 asyncResp->res.result(
324 boost::beast::http::status::internal_server_error);
325 asyncResp->res.jsonValue["Description"] = internalServerError;
asmithakarun1c7b07c2019-09-09 03:42:59 -0500326 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700327 }
asmithakarun1c7b07c2019-09-09 03:42:59 -0500328 else
329 {
Ed Tanous62598e32023-07-17 17:06:25 -0700330 BMCWEB_LOG_WARNING("File not found!");
Sunitha Harishdb81c072021-01-21 23:33:21 -0600331 asyncResp->res.result(boost::beast::http::status::not_found);
332 asyncResp->res.jsonValue["Description"] = resourceNotFoundMsg;
Sunitha Harish97b0e432019-11-21 04:59:29 -0600333 }
Sunitha Harish97b0e432019-11-21 04:59:29 -0600334}
335
zhanghch058d1b46d2021-04-01 11:18:24 +0800336inline void
337 handleBroadcastService(const crow::Request& req,
338 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Asmitha Karunanithi5738de52020-07-17 02:03:31 -0500339{
340 std::string broadcastMsg;
341
Willy Tu15ed6782021-12-14 11:03:16 -0800342 if (!redfish::json_util::readJsonPatch(req, asyncResp->res, "Message",
343 broadcastMsg))
Asmitha Karunanithi5738de52020-07-17 02:03:31 -0500344 {
Ed Tanous62598e32023-07-17 17:06:25 -0700345 BMCWEB_LOG_DEBUG("Not a Valid JSON");
Sunitha Harishdb81c072021-01-21 23:33:21 -0600346 asyncResp->res.result(boost::beast::http::status::bad_request);
Asmitha Karunanithi5738de52020-07-17 02:03:31 -0500347 return;
348 }
349 if (broadcastMsg.size() > maxBroadcastMsgSize)
350 {
Ed Tanous62598e32023-07-17 17:06:25 -0700351 BMCWEB_LOG_ERROR("Message size exceeds maximum allowed size[1KB]");
Sunitha Harishdb81c072021-01-21 23:33:21 -0600352 asyncResp->res.result(boost::beast::http::status::bad_request);
Asmitha Karunanithi5738de52020-07-17 02:03:31 -0500353 return;
354 }
Asmitha Karunanithi5738de52020-07-17 02:03:31 -0500355}
356
zhanghch058d1b46d2021-04-01 11:18:24 +0800357inline void handleFileUrl(const crow::Request& req,
358 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500359 const std::string& fileID)
Sunitha Harish97b0e432019-11-21 04:59:29 -0600360{
Ed Tanousb41187f2019-10-24 16:30:02 -0700361 if (req.method() == boost::beast::http::verb::put)
Sunitha Harish97b0e432019-11-21 04:59:29 -0600362 {
Sunitha Harishdb81c072021-01-21 23:33:21 -0600363 handleFilePut(req, asyncResp, fileID);
Sunitha Harish97b0e432019-11-21 04:59:29 -0600364 return;
365 }
Ed Tanousb41187f2019-10-24 16:30:02 -0700366 if (req.method() == boost::beast::http::verb::get)
asmithakarun1c7b07c2019-09-09 03:42:59 -0500367 {
Sunitha Harishdb81c072021-01-21 23:33:21 -0600368 handleFileGet(asyncResp, fileID);
asmithakarun1c7b07c2019-09-09 03:42:59 -0500369 return;
370 }
Ed Tanousb41187f2019-10-24 16:30:02 -0700371 if (req.method() == boost::beast::http::verb::delete_)
asmithakarun1c7b07c2019-09-09 03:42:59 -0500372 {
Sunitha Harishdb81c072021-01-21 23:33:21 -0600373 handleFileDelete(asyncResp, fileID);
asmithakarun1c7b07c2019-09-09 03:42:59 -0500374 return;
375 }
Sunitha Harish97b0e432019-11-21 04:59:29 -0600376}
Ratan Gupta453fed02019-12-14 09:39:47 +0530377
Sunitha Harish7c0bbe72020-07-30 08:25:28 -0500378inline bool isValidConfigFileName(const std::string& fileName,
379 crow::Response& res)
380{
381 if (fileName.empty())
382 {
Ed Tanous62598e32023-07-17 17:06:25 -0700383 BMCWEB_LOG_ERROR("Empty filename");
Sunitha Harish7c0bbe72020-07-30 08:25:28 -0500384 res.jsonValue["Description"] = "Empty file path in the url";
385 return false;
386 }
387
388 // ConfigFile name is allowed to take upper and lowercase letters,
389 // numbers and hyphen
390 std::size_t found = fileName.find_first_not_of(
391 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-");
392 if (found != std::string::npos)
393 {
Ed Tanous62598e32023-07-17 17:06:25 -0700394 BMCWEB_LOG_ERROR("Unsupported character in filename: {}", fileName);
Sunitha Harish7c0bbe72020-07-30 08:25:28 -0500395 res.jsonValue["Description"] = "Unsupported character in filename";
396 return false;
397 }
398
399 // Check the filename length
400 if (fileName.length() > 20)
401 {
Ed Tanous62598e32023-07-17 17:06:25 -0700402 BMCWEB_LOG_ERROR("Name must be maximum 20 characters. "
403 "Input filename length is: {}",
404 fileName.length());
Sunitha Harish7c0bbe72020-07-30 08:25:28 -0500405 res.jsonValue["Description"] = "Filename must be maximum 20 characters";
406 return false;
407 }
408
409 return true;
410}
411
Ed Tanous02379d32020-09-15 21:15:44 -0700412inline void requestRoutes(App& app)
Ratan Gupta453fed02019-12-14 09:39:47 +0530413{
Ratan Gupta453fed02019-12-14 09:39:47 +0530414 // allowed only for admin
415 BMCWEB_ROUTE(app, "/ibm/v1/")
Ed Tanous432a8902021-06-14 15:28:56 -0700416 .privileges({{"ConfigureComponents", "ConfigureManager"}})
Ed Tanousb41187f2019-10-24 16:30:02 -0700417 .methods(boost::beast::http::verb::get)(
zhanghch058d1b46d2021-04-01 11:18:24 +0800418 [](const crow::Request&,
419 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700420 asyncResp->res.jsonValue["@odata.type"] =
421 "#ibmServiceRoot.v1_0_0.ibmServiceRoot";
422 asyncResp->res.jsonValue["@odata.id"] = "/ibm/v1/";
423 asyncResp->res.jsonValue["Id"] = "IBM Rest RootService";
424 asyncResp->res.jsonValue["Name"] = "IBM Service Root";
425 asyncResp->res.jsonValue["ConfigFiles"]["@odata.id"] =
426 "/ibm/v1/Host/ConfigFiles";
Ed Tanous002d39b2022-05-31 08:59:27 -0700427 asyncResp->res.jsonValue["BroadcastService"]["@odata.id"] =
428 "/ibm/v1/HMC/BroadcastService";
Patrick Williams5a39f772023-10-20 11:20:21 -0500429 });
Sunitha Harish97b0e432019-11-21 04:59:29 -0600430
Ratan Guptad3630cb2019-12-14 11:21:35 +0530431 BMCWEB_ROUTE(app, "/ibm/v1/Host/ConfigFiles")
Ed Tanous432a8902021-06-14 15:28:56 -0700432 .privileges({{"ConfigureComponents", "ConfigureManager"}})
Ed Tanousb41187f2019-10-24 16:30:02 -0700433 .methods(boost::beast::http::verb::get)(
zhanghch058d1b46d2021-04-01 11:18:24 +0800434 [](const crow::Request&,
435 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700436 handleConfigFileList(asyncResp);
Patrick Williams5a39f772023-10-20 11:20:21 -0500437 });
Ratan Guptad3630cb2019-12-14 11:21:35 +0530438
439 BMCWEB_ROUTE(app,
Sunitha Harishe56f2542020-07-22 02:38:59 -0500440 "/ibm/v1/Host/ConfigFiles/Actions/IBMConfigFiles.DeleteAll")
Ed Tanous432a8902021-06-14 15:28:56 -0700441 .privileges({{"ConfigureComponents", "ConfigureManager"}})
Ed Tanousb41187f2019-10-24 16:30:02 -0700442 .methods(boost::beast::http::verb::post)(
zhanghch058d1b46d2021-04-01 11:18:24 +0800443 [](const crow::Request&,
444 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700445 deleteConfigFiles(asyncResp);
Patrick Williams5a39f772023-10-20 11:20:21 -0500446 });
Ratan Guptad3630cb2019-12-14 11:21:35 +0530447
Sunitha Harish7c0bbe72020-07-30 08:25:28 -0500448 BMCWEB_ROUTE(app, "/ibm/v1/Host/ConfigFiles/<str>")
Ed Tanous432a8902021-06-14 15:28:56 -0700449 .privileges({{"ConfigureComponents", "ConfigureManager"}})
zhanghch058d1b46d2021-04-01 11:18:24 +0800450 .methods(boost::beast::http::verb::put, boost::beast::http::verb::get,
451 boost::beast::http::verb::delete_)(
452 [](const crow::Request& req,
453 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
454 const std::string& fileName) {
Ed Tanous62598e32023-07-17 17:06:25 -0700455 BMCWEB_LOG_DEBUG("ConfigFile : {}", fileName);
Ed Tanous002d39b2022-05-31 08:59:27 -0700456 // Validate the incoming fileName
457 if (!isValidConfigFileName(fileName, asyncResp->res))
458 {
459 asyncResp->res.result(boost::beast::http::status::bad_request);
460 return;
461 }
462 handleFileUrl(req, asyncResp, fileName);
Patrick Williams5a39f772023-10-20 11:20:21 -0500463 });
Ratan Gupta734a1c32019-12-14 11:53:48 +0530464
Asmitha Karunanithi5738de52020-07-17 02:03:31 -0500465 BMCWEB_ROUTE(app, "/ibm/v1/HMC/BroadcastService")
Ed Tanous432a8902021-06-14 15:28:56 -0700466 .privileges({{"ConfigureComponents", "ConfigureManager"}})
Asmitha Karunanithi5738de52020-07-17 02:03:31 -0500467 .methods(boost::beast::http::verb::post)(
zhanghch058d1b46d2021-04-01 11:18:24 +0800468 [](const crow::Request& req,
469 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700470 handleBroadcastService(req, asyncResp);
Patrick Williams5a39f772023-10-20 11:20:21 -0500471 });
Ratan Gupta453fed02019-12-14 09:39:47 +0530472}
473
474} // namespace ibm_mc
475} // namespace crow