blob: 9d5f9171d8b2b2f21c21765adde9d3e27811c38a [file] [log] [blame]
Ed Tanous40e9b922024-09-10 13:50:16 -07001// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright OpenBMC Authors
Ratan Gupta453fed02019-12-14 09:39:47 +05303#pragma once
Ratan Gupta453fed02019-12-14 09:39:47 +05304
Ed Tanous3ccb3ad2023-01-13 17:40:03 -08005#include "app.hpp"
6#include "async_resp.hpp"
7#include "error_messages.hpp"
8#include "event_service_manager.hpp"
Sunitha Harish56d0bb02024-04-06 03:35:34 -05009#include "ibm/utils.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080010#include "resource_messages.hpp"
Ed Tanous18f8f602023-07-18 10:07:23 -070011#include "str_utility.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080012#include "utils/json_utils.hpp"
13
Sunitha Harish97b0e432019-11-21 04:59:29 -060014#include <boost/container/flat_set.hpp>
manojkiraneda0b631ae2019-12-03 17:54:28 +053015#include <nlohmann/json.hpp>
Sunitha Harish97b0e432019-11-21 04:59:29 -060016#include <sdbusplus/message/types.hpp>
17
Gunnar Mills1214b7e2020-06-04 10:11:30 -050018#include <filesystem>
19#include <fstream>
Gunnar Mills1214b7e2020-06-04 10:11:30 -050020
Ratan Gupta453fed02019-12-14 09:39:47 +053021namespace crow
22{
23namespace ibm_mc
24{
Gunnar Mills1214b7e2020-06-04 10:11:30 -050025constexpr const char* methodNotAllowedMsg = "Method Not Allowed";
26constexpr const char* resourceNotFoundMsg = "Resource Not Found";
27constexpr const char* contentNotAcceptableMsg = "Content Not Acceptable";
28constexpr const char* internalServerError = "Internal Server Error";
Sunitha Harish97b0e432019-11-21 04:59:29 -060029
Sunitha Harish7c0bbe72020-07-30 08:25:28 -050030constexpr size_t maxSaveareaDirSize =
Sunitha Harishf8a43472022-08-08 02:07:12 -050031 25000000; // Allow save area dir size to be max 25MB
Sunitha Harish7c0bbe72020-07-30 08:25:28 -050032constexpr size_t minSaveareaFileSize =
Myung Bae41868c62024-10-09 16:36:49 -070033 100; // Allow save area file size of minimum 100B
Asmitha Karunanithi5738de52020-07-17 02:03:31 -050034constexpr size_t maxSaveareaFileSize =
Myung Bae41868c62024-10-09 16:36:49 -070035 500000; // Allow save area file size upto 500KB
Asmitha Karunanithi5738de52020-07-17 02:03:31 -050036constexpr size_t maxBroadcastMsgSize =
Myung Bae41868c62024-10-09 16:36:49 -070037 1000; // Allow Broadcast message size upto 1KB
Asmitha Karunanithi5738de52020-07-17 02:03:31 -050038
Sunitha Harishdb81c072021-01-21 23:33:21 -060039inline void handleFilePut(const crow::Request& req,
40 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous02379d32020-09-15 21:15:44 -070041 const std::string& fileID)
Sunitha Harish97b0e432019-11-21 04:59:29 -060042{
Sunitha Harish7c0bbe72020-07-30 08:25:28 -050043 std::error_code ec;
Sunitha Harish97b0e432019-11-21 04:59:29 -060044 // Check the content-type of the request
Sunitha Harish086d32c2021-02-01 02:11:49 -060045 boost::beast::string_view contentType = req.getHeaderValue("content-type");
Ed Tanous18f8f602023-07-18 10:07:23 -070046 if (!bmcweb::asciiIEquals(contentType, "application/octet-stream"))
Sunitha Harish97b0e432019-11-21 04:59:29 -060047 {
Sunitha Harishdb81c072021-01-21 23:33:21 -060048 asyncResp->res.result(boost::beast::http::status::not_acceptable);
49 asyncResp->res.jsonValue["Description"] = contentNotAcceptableMsg;
Sunitha Harish97b0e432019-11-21 04:59:29 -060050 return;
51 }
Ed Tanous62598e32023-07-17 17:06:25 -070052 BMCWEB_LOG_DEBUG(
53 "File upload in application/octet-stream format. Continue..");
asmithakarun1c7b07c2019-09-09 03:42:59 -050054
Ed Tanous62598e32023-07-17 17:06:25 -070055 BMCWEB_LOG_DEBUG(
56 "handleIbmPut: Request to create/update the save-area file");
Sunitha Harish3e919b52020-10-13 01:21:48 -050057 std::string_view path =
58 "/var/lib/bmcweb/ibm-management-console/configfiles";
59 if (!crow::ibm_utils::createDirectory(path))
Sunitha Harish97b0e432019-11-21 04:59:29 -060060 {
Sunitha Harishdb81c072021-01-21 23:33:21 -060061 asyncResp->res.result(boost::beast::http::status::not_found);
62 asyncResp->res.jsonValue["Description"] = resourceNotFoundMsg;
asmithakarun1c7b07c2019-09-09 03:42:59 -050063 return;
64 }
Sunitha Harish7c0bbe72020-07-30 08:25:28 -050065
asmithakarun1c7b07c2019-09-09 03:42:59 -050066 std::ofstream file;
Sunitha Harish3e919b52020-10-13 01:21:48 -050067 std::filesystem::path loc(
68 "/var/lib/bmcweb/ibm-management-console/configfiles");
Sunitha Harish97b0e432019-11-21 04:59:29 -060069
Sunitha Harish7c0bbe72020-07-30 08:25:28 -050070 // Get the current size of the savearea directory
71 std::filesystem::recursive_directory_iterator iter(loc, ec);
72 if (ec)
73 {
Sunitha Harishdb81c072021-01-21 23:33:21 -060074 asyncResp->res.result(
75 boost::beast::http::status::internal_server_error);
76 asyncResp->res.jsonValue["Description"] = internalServerError;
Ed Tanous62598e32023-07-17 17:06:25 -070077 BMCWEB_LOG_DEBUG("handleIbmPut: Failed to prepare save-area "
78 "directory iterator. ec : {}",
79 ec.message());
Sunitha Harish7c0bbe72020-07-30 08:25:28 -050080 return;
81 }
82 std::uintmax_t saveAreaDirSize = 0;
Ed Tanous9eb808c2022-01-25 10:19:23 -080083 for (const auto& it : iter)
Sunitha Harish7c0bbe72020-07-30 08:25:28 -050084 {
85 if (!std::filesystem::is_directory(it, ec))
86 {
87 if (ec)
88 {
Sunitha Harishdb81c072021-01-21 23:33:21 -060089 asyncResp->res.result(
90 boost::beast::http::status::internal_server_error);
91 asyncResp->res.jsonValue["Description"] = internalServerError;
Ed Tanous62598e32023-07-17 17:06:25 -070092 BMCWEB_LOG_DEBUG("handleIbmPut: Failed to find save-area "
93 "directory . ec : {}",
94 ec.message());
Sunitha Harish7c0bbe72020-07-30 08:25:28 -050095 return;
96 }
97 std::uintmax_t fileSize = std::filesystem::file_size(it, ec);
98 if (ec)
99 {
Sunitha Harishdb81c072021-01-21 23:33:21 -0600100 asyncResp->res.result(
101 boost::beast::http::status::internal_server_error);
102 asyncResp->res.jsonValue["Description"] = internalServerError;
Ed Tanous62598e32023-07-17 17:06:25 -0700103 BMCWEB_LOG_DEBUG("handleIbmPut: Failed to find save-area "
104 "file size inside the directory . ec : {}",
105 ec.message());
Sunitha Harish7c0bbe72020-07-30 08:25:28 -0500106 return;
107 }
108 saveAreaDirSize += fileSize;
109 }
110 }
Ed Tanous62598e32023-07-17 17:06:25 -0700111 BMCWEB_LOG_DEBUG("saveAreaDirSize: {}", saveAreaDirSize);
Sunitha Harish7c0bbe72020-07-30 08:25:28 -0500112
113 // Get the file size getting uploaded
Ed Tanous33c6b582023-02-14 15:05:48 -0800114 const std::string& data = req.body();
Ed Tanous62598e32023-07-17 17:06:25 -0700115 BMCWEB_LOG_DEBUG("data length: {}", data.length());
Sunitha Harish7c0bbe72020-07-30 08:25:28 -0500116
117 if (data.length() < minSaveareaFileSize)
118 {
Sunitha Harishdb81c072021-01-21 23:33:21 -0600119 asyncResp->res.result(boost::beast::http::status::bad_request);
120 asyncResp->res.jsonValue["Description"] =
Sunitha Harish7c0bbe72020-07-30 08:25:28 -0500121 "File size is less than minimum allowed size[100B]";
122 return;
123 }
124 if (data.length() > maxSaveareaFileSize)
asmithakarun1c7b07c2019-09-09 03:42:59 -0500125 {
Sunitha Harishdb81c072021-01-21 23:33:21 -0600126 asyncResp->res.result(boost::beast::http::status::bad_request);
127 asyncResp->res.jsonValue["Description"] =
Ratan Guptae46946a2020-05-11 13:22:59 +0530128 "File size exceeds maximum allowed size[500KB]";
asmithakarun1c7b07c2019-09-09 03:42:59 -0500129 return;
130 }
Sunitha Harish7c0bbe72020-07-30 08:25:28 -0500131
132 // Form the file path
133 loc /= fileID;
Ed Tanous62598e32023-07-17 17:06:25 -0700134 BMCWEB_LOG_DEBUG("Writing to the file: {}", loc.string());
Asmitha Karunanithi10693fa2020-07-27 02:27:49 -0500135
Sunitha Harish7c0bbe72020-07-30 08:25:28 -0500136 // Check if the same file exists in the directory
137 bool fileExists = std::filesystem::exists(loc, ec);
138 if (ec)
Asmitha Karunanithi10693fa2020-07-27 02:27:49 -0500139 {
Sunitha Harishdb81c072021-01-21 23:33:21 -0600140 asyncResp->res.result(
141 boost::beast::http::status::internal_server_error);
142 asyncResp->res.jsonValue["Description"] = internalServerError;
Ed Tanous62598e32023-07-17 17:06:25 -0700143 BMCWEB_LOG_DEBUG("handleIbmPut: Failed to find if file exists. ec : {}",
144 ec.message());
Sunitha Harish7c0bbe72020-07-30 08:25:28 -0500145 return;
Asmitha Karunanithi10693fa2020-07-27 02:27:49 -0500146 }
Sunitha Harish7c0bbe72020-07-30 08:25:28 -0500147
148 std::uintmax_t newSizeToWrite = 0;
149 if (fileExists)
150 {
151 // File exists. Get the current file size
152 std::uintmax_t currentFileSize = std::filesystem::file_size(loc, ec);
153 if (ec)
154 {
Sunitha Harishdb81c072021-01-21 23:33:21 -0600155 asyncResp->res.result(
156 boost::beast::http::status::internal_server_error);
157 asyncResp->res.jsonValue["Description"] = internalServerError;
Ed Tanous62598e32023-07-17 17:06:25 -0700158 BMCWEB_LOG_DEBUG("handleIbmPut: Failed to find file size. ec : {}",
159 ec.message());
Sunitha Harish7c0bbe72020-07-30 08:25:28 -0500160 return;
161 }
162 // Calculate the difference in the file size.
163 // If the data.length is greater than the existing file size, then
164 // calculate the difference. Else consider the delta size as zero -
165 // because there is no increase in the total directory size.
166 // We need to add the diff only if the incoming data is larger than the
167 // existing filesize
168 if (data.length() > currentFileSize)
169 {
170 newSizeToWrite = data.length() - currentFileSize;
171 }
Ed Tanous62598e32023-07-17 17:06:25 -0700172 BMCWEB_LOG_DEBUG("newSizeToWrite: {}", newSizeToWrite);
Sunitha Harish7c0bbe72020-07-30 08:25:28 -0500173 }
174 else
175 {
176 // This is a new file upload
177 newSizeToWrite = data.length();
178 }
179
180 // Calculate the total dir size before writing the new file
Ed Tanous62598e32023-07-17 17:06:25 -0700181 BMCWEB_LOG_DEBUG("total new size: {}", saveAreaDirSize + newSizeToWrite);
Sunitha Harish7c0bbe72020-07-30 08:25:28 -0500182
183 if ((saveAreaDirSize + newSizeToWrite) > maxSaveareaDirSize)
184 {
Sunitha Harishdb81c072021-01-21 23:33:21 -0600185 asyncResp->res.result(boost::beast::http::status::bad_request);
186 asyncResp->res.jsonValue["Description"] =
187 "File size does not fit in the savearea "
Sunitha Harishf8a43472022-08-08 02:07:12 -0500188 "directory maximum allowed size[25MB]";
Sunitha Harish7c0bbe72020-07-30 08:25:28 -0500189 return;
190 }
191
asmithakarun1c7b07c2019-09-09 03:42:59 -0500192 file.open(loc, std::ofstream::out);
Sunitha Harish3e919b52020-10-13 01:21:48 -0500193
194 // set the permission of the file to 600
195 std::filesystem::perms permission = std::filesystem::perms::owner_write |
196 std::filesystem::perms::owner_read;
197 std::filesystem::permissions(loc, permission);
198
asmithakarun1c7b07c2019-09-09 03:42:59 -0500199 if (file.fail())
200 {
Ed Tanous62598e32023-07-17 17:06:25 -0700201 BMCWEB_LOG_DEBUG("Error while opening the file for writing");
Sunitha Harishdb81c072021-01-21 23:33:21 -0600202 asyncResp->res.result(
203 boost::beast::http::status::internal_server_error);
204 asyncResp->res.jsonValue["Description"] =
205 "Error while creating the file";
asmithakarun1c7b07c2019-09-09 03:42:59 -0500206 return;
Sunitha Harish97b0e432019-11-21 04:59:29 -0600207 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700208 file << data;
Sunitha Harish3e919b52020-10-13 01:21:48 -0500209
Ed Tanous3174e4d2020-10-07 11:41:22 -0700210 // Push an event
211 if (fileExists)
212 {
Ed Tanous62598e32023-07-17 17:06:25 -0700213 BMCWEB_LOG_DEBUG("config file is updated");
Sunitha Harishdb81c072021-01-21 23:33:21 -0600214 asyncResp->res.jsonValue["Description"] = "File Updated";
Ed Tanous3174e4d2020-10-07 11:41:22 -0700215 }
Sunitha Harish97b0e432019-11-21 04:59:29 -0600216 else
217 {
Ed Tanous62598e32023-07-17 17:06:25 -0700218 BMCWEB_LOG_DEBUG("config file is created");
Sunitha Harishdb81c072021-01-21 23:33:21 -0600219 asyncResp->res.jsonValue["Description"] = "File Created";
asmithakarun1c7b07c2019-09-09 03:42:59 -0500220 }
Ratan Guptad3630cb2019-12-14 11:21:35 +0530221}
asmithakarun1c7b07c2019-09-09 03:42:59 -0500222
zhanghch058d1b46d2021-04-01 11:18:24 +0800223inline void
224 handleConfigFileList(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ratan Guptad3630cb2019-12-14 11:21:35 +0530225{
226 std::vector<std::string> pathObjList;
Sunitha Harish3e919b52020-10-13 01:21:48 -0500227 std::filesystem::path loc(
228 "/var/lib/bmcweb/ibm-management-console/configfiles");
Ratan Guptad3630cb2019-12-14 11:21:35 +0530229 if (std::filesystem::exists(loc) && std::filesystem::is_directory(loc))
230 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500231 for (const auto& file : std::filesystem::directory_iterator(loc))
Ratan Guptad3630cb2019-12-14 11:21:35 +0530232 {
Ed Tanous3174e4d2020-10-07 11:41:22 -0700233 const std::filesystem::path& pathObj = file.path();
cm-jishnu5a193962022-12-02 03:45:27 -0600234 if (std::filesystem::is_regular_file(pathObj))
235 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400236 pathObjList.emplace_back(
237 "/ibm/v1/Host/ConfigFiles/" + pathObj.filename().string());
cm-jishnu5a193962022-12-02 03:45:27 -0600238 }
Ratan Guptad3630cb2019-12-14 11:21:35 +0530239 }
240 }
Sunitha Harishdb81c072021-01-21 23:33:21 -0600241 asyncResp->res.jsonValue["@odata.type"] =
242 "#IBMConfigFile.v1_0_0.IBMConfigFile";
243 asyncResp->res.jsonValue["@odata.id"] = "/ibm/v1/Host/ConfigFiles/";
244 asyncResp->res.jsonValue["Id"] = "ConfigFiles";
245 asyncResp->res.jsonValue["Name"] = "ConfigFiles";
Ratan Guptad3630cb2019-12-14 11:21:35 +0530246
Sunitha Harishdb81c072021-01-21 23:33:21 -0600247 asyncResp->res.jsonValue["Members"] = std::move(pathObjList);
Ed Tanous20fa6a22024-05-20 18:02:58 -0700248 asyncResp->res.jsonValue["Actions"]["#IBMConfigFiles.DeleteAll"]["target"] =
249 "/ibm/v1/Host/ConfigFiles/Actions/IBMConfigFiles.DeleteAll";
Ratan Guptad3630cb2019-12-14 11:21:35 +0530250}
251
zhanghch058d1b46d2021-04-01 11:18:24 +0800252inline void
253 deleteConfigFiles(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ratan Guptad3630cb2019-12-14 11:21:35 +0530254{
Ratan Guptad3630cb2019-12-14 11:21:35 +0530255 std::error_code ec;
Sunitha Harish3e919b52020-10-13 01:21:48 -0500256 std::filesystem::path loc(
257 "/var/lib/bmcweb/ibm-management-console/configfiles");
Ratan Guptad3630cb2019-12-14 11:21:35 +0530258 if (std::filesystem::exists(loc) && std::filesystem::is_directory(loc))
259 {
260 std::filesystem::remove_all(loc, ec);
261 if (ec)
262 {
Sunitha Harishdb81c072021-01-21 23:33:21 -0600263 asyncResp->res.result(
264 boost::beast::http::status::internal_server_error);
265 asyncResp->res.jsonValue["Description"] = internalServerError;
Ed Tanous62598e32023-07-17 17:06:25 -0700266 BMCWEB_LOG_DEBUG("deleteConfigFiles: Failed to delete the "
267 "config files directory. ec : {}",
268 ec.message());
Ratan Guptad3630cb2019-12-14 11:21:35 +0530269 }
270 }
asmithakarun1c7b07c2019-09-09 03:42:59 -0500271}
272
Sunitha Harishdb81c072021-01-21 23:33:21 -0600273inline void handleFileGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
274 const std::string& fileID)
asmithakarun1c7b07c2019-09-09 03:42:59 -0500275{
Ed Tanous62598e32023-07-17 17:06:25 -0700276 BMCWEB_LOG_DEBUG("HandleGet on SaveArea files on path: {}", fileID);
Sunitha Harish3e919b52020-10-13 01:21:48 -0500277 std::filesystem::path loc(
278 "/var/lib/bmcweb/ibm-management-console/configfiles/" + fileID);
cm-jishnu5a193962022-12-02 03:45:27 -0600279 if (!std::filesystem::exists(loc) || !std::filesystem::is_regular_file(loc))
asmithakarun1c7b07c2019-09-09 03:42:59 -0500280 {
Ed Tanous62598e32023-07-17 17:06:25 -0700281 BMCWEB_LOG_WARNING("{} Not found", loc.string());
Sunitha Harishdb81c072021-01-21 23:33:21 -0600282 asyncResp->res.result(boost::beast::http::status::not_found);
283 asyncResp->res.jsonValue["Description"] = resourceNotFoundMsg;
asmithakarun1c7b07c2019-09-09 03:42:59 -0500284 return;
285 }
286
287 std::ifstream readfile(loc.string());
288 if (!readfile)
289 {
Ed Tanous62598e32023-07-17 17:06:25 -0700290 BMCWEB_LOG_WARNING("{} Not found", loc.string());
Sunitha Harishdb81c072021-01-21 23:33:21 -0600291 asyncResp->res.result(boost::beast::http::status::not_found);
292 asyncResp->res.jsonValue["Description"] = resourceNotFoundMsg;
asmithakarun1c7b07c2019-09-09 03:42:59 -0500293 return;
294 }
295
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400296 std::string contentDispositionParam =
297 "attachment; filename=\"" + fileID + "\"";
Ed Tanousd9f6c622022-03-17 09:12:17 -0700298 asyncResp->res.addHeader(boost::beast::http::field::content_disposition,
299 contentDispositionParam);
asmithakarun1c7b07c2019-09-09 03:42:59 -0500300 std::string fileData;
301 fileData = {std::istreambuf_iterator<char>(readfile),
302 std::istreambuf_iterator<char>()};
Sunitha Harishdb81c072021-01-21 23:33:21 -0600303 asyncResp->res.jsonValue["Data"] = fileData;
asmithakarun1c7b07c2019-09-09 03:42:59 -0500304}
305
Sunitha Harishdb81c072021-01-21 23:33:21 -0600306inline void
307 handleFileDelete(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
308 const std::string& fileID)
asmithakarun1c7b07c2019-09-09 03:42:59 -0500309{
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400310 std::string filePath(
311 "/var/lib/bmcweb/ibm-management-console/configfiles/" + fileID);
Ed Tanous62598e32023-07-17 17:06:25 -0700312 BMCWEB_LOG_DEBUG("Removing the file : {}", filePath);
Ed Tanous2c70f802020-09-28 14:29:23 -0700313 std::ifstream fileOpen(filePath.c_str());
314 if (static_cast<bool>(fileOpen))
Ed Tanous3174e4d2020-10-07 11:41:22 -0700315 {
asmithakarun1c7b07c2019-09-09 03:42:59 -0500316 if (remove(filePath.c_str()) == 0)
317 {
Ed Tanous62598e32023-07-17 17:06:25 -0700318 BMCWEB_LOG_DEBUG("File removed!");
Sunitha Harishdb81c072021-01-21 23:33:21 -0600319 asyncResp->res.jsonValue["Description"] = "File Deleted";
asmithakarun1c7b07c2019-09-09 03:42:59 -0500320 }
321 else
322 {
Ed Tanous62598e32023-07-17 17:06:25 -0700323 BMCWEB_LOG_ERROR("File not removed!");
Sunitha Harishdb81c072021-01-21 23:33:21 -0600324 asyncResp->res.result(
325 boost::beast::http::status::internal_server_error);
326 asyncResp->res.jsonValue["Description"] = internalServerError;
asmithakarun1c7b07c2019-09-09 03:42:59 -0500327 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700328 }
asmithakarun1c7b07c2019-09-09 03:42:59 -0500329 else
330 {
Ed Tanous62598e32023-07-17 17:06:25 -0700331 BMCWEB_LOG_WARNING("File not found!");
Sunitha Harishdb81c072021-01-21 23:33:21 -0600332 asyncResp->res.result(boost::beast::http::status::not_found);
333 asyncResp->res.jsonValue["Description"] = resourceNotFoundMsg;
Sunitha Harish97b0e432019-11-21 04:59:29 -0600334 }
Sunitha Harish97b0e432019-11-21 04:59:29 -0600335}
336
zhanghch058d1b46d2021-04-01 11:18:24 +0800337inline void
338 handleBroadcastService(const crow::Request& req,
339 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Asmitha Karunanithi5738de52020-07-17 02:03:31 -0500340{
341 std::string broadcastMsg;
342
Willy Tu15ed6782021-12-14 11:03:16 -0800343 if (!redfish::json_util::readJsonPatch(req, asyncResp->res, "Message",
344 broadcastMsg))
Asmitha Karunanithi5738de52020-07-17 02:03:31 -0500345 {
Ed Tanous62598e32023-07-17 17:06:25 -0700346 BMCWEB_LOG_DEBUG("Not a Valid JSON");
Sunitha Harishdb81c072021-01-21 23:33:21 -0600347 asyncResp->res.result(boost::beast::http::status::bad_request);
Asmitha Karunanithi5738de52020-07-17 02:03:31 -0500348 return;
349 }
350 if (broadcastMsg.size() > maxBroadcastMsgSize)
351 {
Ed Tanous62598e32023-07-17 17:06:25 -0700352 BMCWEB_LOG_ERROR("Message size exceeds maximum allowed size[1KB]");
Sunitha Harishdb81c072021-01-21 23:33:21 -0600353 asyncResp->res.result(boost::beast::http::status::bad_request);
Asmitha Karunanithi5738de52020-07-17 02:03:31 -0500354 return;
355 }
Asmitha Karunanithi5738de52020-07-17 02:03:31 -0500356}
357
zhanghch058d1b46d2021-04-01 11:18:24 +0800358inline void handleFileUrl(const crow::Request& req,
359 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500360 const std::string& fileID)
Sunitha Harish97b0e432019-11-21 04:59:29 -0600361{
Ed Tanousb41187f2019-10-24 16:30:02 -0700362 if (req.method() == boost::beast::http::verb::put)
Sunitha Harish97b0e432019-11-21 04:59:29 -0600363 {
Sunitha Harishdb81c072021-01-21 23:33:21 -0600364 handleFilePut(req, asyncResp, fileID);
Sunitha Harish97b0e432019-11-21 04:59:29 -0600365 return;
366 }
Ed Tanousb41187f2019-10-24 16:30:02 -0700367 if (req.method() == boost::beast::http::verb::get)
asmithakarun1c7b07c2019-09-09 03:42:59 -0500368 {
Sunitha Harishdb81c072021-01-21 23:33:21 -0600369 handleFileGet(asyncResp, fileID);
asmithakarun1c7b07c2019-09-09 03:42:59 -0500370 return;
371 }
Ed Tanousb41187f2019-10-24 16:30:02 -0700372 if (req.method() == boost::beast::http::verb::delete_)
asmithakarun1c7b07c2019-09-09 03:42:59 -0500373 {
Sunitha Harishdb81c072021-01-21 23:33:21 -0600374 handleFileDelete(asyncResp, fileID);
asmithakarun1c7b07c2019-09-09 03:42:59 -0500375 return;
376 }
Sunitha Harish97b0e432019-11-21 04:59:29 -0600377}
Ratan Gupta453fed02019-12-14 09:39:47 +0530378
Sunitha Harish7c0bbe72020-07-30 08:25:28 -0500379inline bool isValidConfigFileName(const std::string& fileName,
380 crow::Response& res)
381{
382 if (fileName.empty())
383 {
Ed Tanous62598e32023-07-17 17:06:25 -0700384 BMCWEB_LOG_ERROR("Empty filename");
Sunitha Harish7c0bbe72020-07-30 08:25:28 -0500385 res.jsonValue["Description"] = "Empty file path in the url";
386 return false;
387 }
388
389 // ConfigFile name is allowed to take upper and lowercase letters,
390 // numbers and hyphen
391 std::size_t found = fileName.find_first_not_of(
392 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-");
393 if (found != std::string::npos)
394 {
Ed Tanous62598e32023-07-17 17:06:25 -0700395 BMCWEB_LOG_ERROR("Unsupported character in filename: {}", fileName);
Sunitha Harish7c0bbe72020-07-30 08:25:28 -0500396 res.jsonValue["Description"] = "Unsupported character in filename";
397 return false;
398 }
399
400 // Check the filename length
401 if (fileName.length() > 20)
402 {
Ed Tanous62598e32023-07-17 17:06:25 -0700403 BMCWEB_LOG_ERROR("Name must be maximum 20 characters. "
404 "Input filename length is: {}",
405 fileName.length());
Sunitha Harish7c0bbe72020-07-30 08:25:28 -0500406 res.jsonValue["Description"] = "Filename must be maximum 20 characters";
407 return false;
408 }
409
410 return true;
411}
412
Ed Tanous02379d32020-09-15 21:15:44 -0700413inline void requestRoutes(App& app)
Ratan Gupta453fed02019-12-14 09:39:47 +0530414{
Ratan Gupta453fed02019-12-14 09:39:47 +0530415 // allowed only for admin
416 BMCWEB_ROUTE(app, "/ibm/v1/")
Ed Tanous432a8902021-06-14 15:28:56 -0700417 .privileges({{"ConfigureComponents", "ConfigureManager"}})
Ed Tanousb41187f2019-10-24 16:30:02 -0700418 .methods(boost::beast::http::verb::get)(
zhanghch058d1b46d2021-04-01 11:18:24 +0800419 [](const crow::Request&,
420 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400421 asyncResp->res.jsonValue["@odata.type"] =
422 "#ibmServiceRoot.v1_0_0.ibmServiceRoot";
423 asyncResp->res.jsonValue["@odata.id"] = "/ibm/v1/";
424 asyncResp->res.jsonValue["Id"] = "IBM Rest RootService";
425 asyncResp->res.jsonValue["Name"] = "IBM Service Root";
426 asyncResp->res.jsonValue["ConfigFiles"]["@odata.id"] =
427 "/ibm/v1/Host/ConfigFiles";
428 asyncResp->res.jsonValue["BroadcastService"]["@odata.id"] =
429 "/ibm/v1/HMC/BroadcastService";
430 });
Sunitha Harish97b0e432019-11-21 04:59:29 -0600431
Ratan Guptad3630cb2019-12-14 11:21:35 +0530432 BMCWEB_ROUTE(app, "/ibm/v1/Host/ConfigFiles")
Ed Tanous432a8902021-06-14 15:28:56 -0700433 .privileges({{"ConfigureComponents", "ConfigureManager"}})
Ed Tanousb41187f2019-10-24 16:30:02 -0700434 .methods(boost::beast::http::verb::get)(
zhanghch058d1b46d2021-04-01 11:18:24 +0800435 [](const crow::Request&,
436 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400437 handleConfigFileList(asyncResp);
438 });
Ratan Guptad3630cb2019-12-14 11:21:35 +0530439
440 BMCWEB_ROUTE(app,
Sunitha Harishe56f2542020-07-22 02:38:59 -0500441 "/ibm/v1/Host/ConfigFiles/Actions/IBMConfigFiles.DeleteAll")
Ed Tanous432a8902021-06-14 15:28:56 -0700442 .privileges({{"ConfigureComponents", "ConfigureManager"}})
Ed Tanousb41187f2019-10-24 16:30:02 -0700443 .methods(boost::beast::http::verb::post)(
zhanghch058d1b46d2021-04-01 11:18:24 +0800444 [](const crow::Request&,
445 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400446 deleteConfigFiles(asyncResp);
447 });
Ratan Guptad3630cb2019-12-14 11:21:35 +0530448
Sunitha Harish7c0bbe72020-07-30 08:25:28 -0500449 BMCWEB_ROUTE(app, "/ibm/v1/Host/ConfigFiles/<str>")
Ed Tanous432a8902021-06-14 15:28:56 -0700450 .privileges({{"ConfigureComponents", "ConfigureManager"}})
zhanghch058d1b46d2021-04-01 11:18:24 +0800451 .methods(boost::beast::http::verb::put, boost::beast::http::verb::get,
452 boost::beast::http::verb::delete_)(
453 [](const crow::Request& req,
454 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
455 const std::string& fileName) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400456 BMCWEB_LOG_DEBUG("ConfigFile : {}", fileName);
457 // Validate the incoming fileName
458 if (!isValidConfigFileName(fileName, asyncResp->res))
459 {
460 asyncResp->res.result(
461 boost::beast::http::status::bad_request);
462 return;
463 }
464 handleFileUrl(req, asyncResp, fileName);
465 });
Ratan Gupta734a1c32019-12-14 11:53:48 +0530466
Asmitha Karunanithi5738de52020-07-17 02:03:31 -0500467 BMCWEB_ROUTE(app, "/ibm/v1/HMC/BroadcastService")
Ed Tanous432a8902021-06-14 15:28:56 -0700468 .privileges({{"ConfigureComponents", "ConfigureManager"}})
Asmitha Karunanithi5738de52020-07-17 02:03:31 -0500469 .methods(boost::beast::http::verb::post)(
zhanghch058d1b46d2021-04-01 11:18:24 +0800470 [](const crow::Request& req,
471 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400472 handleBroadcastService(req, asyncResp);
473 });
Ratan Gupta453fed02019-12-14 09:39:47 +0530474}
475
476} // namespace ibm_mc
477} // namespace crow