Handling of adding certificates the Redfish way
Added handling for POSTing certificates the Redfish way (as proper JSON).
Currently it was only possible to add certificate as a RAW certificate in
request body. Now user is able to add it as
{
"CertificateType": "PEM",
"CertificateString": "..."
}
as well as previously in RAW form.
Tested:
- Uploading certificates in RAW form
- Uploading certificates in JSON form
- Uploading invalid certificates
- Uploading invalid JSON requests
Change-Id: Icf0f6b928e63fc3cc5cd089b483b3799fbe715de
Signed-off-by: Kowalski, Kamil <kamil.kowalski@intel.com>
diff --git a/redfish-core/lib/certificate_service.hpp b/redfish-core/lib/certificate_service.hpp
index f2cd966..111bcec 100644
--- a/redfish-core/lib/certificate_service.hpp
+++ b/redfish-core/lib/certificate_service.hpp
@@ -117,6 +117,39 @@
return -1;
}
+std::string
+ getCertificateFromReqBody(const std::shared_ptr<AsyncResp> &asyncResp,
+ const crow::Request &req)
+{
+ nlohmann::json reqJson = nlohmann::json::parse(req.body, nullptr, false);
+
+ if (reqJson.is_discarded())
+ {
+ // We did not receive JSON request, proceed as it is RAW data
+ return req.body;
+ }
+
+ std::string certificate;
+ std::optional<std::string> certificateType = "PEM";
+
+ if (!json_util::readJson(reqJson, asyncResp->res, "CertificateString",
+ certificate, "CertificateType", certificateType))
+ {
+ BMCWEB_LOG_ERROR << "Required parameters are missing";
+ messages::internalError(asyncResp->res);
+ return std::string();
+ }
+
+ if (*certificateType != "PEM")
+ {
+ messages::propertyValueNotInList(asyncResp->res, *certificateType,
+ "CertificateType");
+ return std::string();
+ }
+
+ return certificate;
+}
+
/**
* Class to create a temporary certificate file for uploading to system
*/
@@ -897,8 +930,15 @@
asyncResp->res.jsonValue = {{"Name", "HTTPS Certificate"},
{"Description", "HTTPS Certificate"}};
+ std::string certFileBody = getCertificateFromReqBody(asyncResp, req);
+
+ if (certFileBody.empty())
+ {
+ return;
+ }
+
std::shared_ptr<CertificateFile> certFile =
- std::make_shared<CertificateFile>(req.body);
+ std::make_shared<CertificateFile>(certFileBody);
crow::connections::systemBus->async_method_call(
[asyncResp, certFile](const boost::system::error_code ec) {
@@ -1083,9 +1123,17 @@
void doPost(crow::Response &res, const crow::Request &req,
const std::vector<std::string> ¶ms) override
{
- std::shared_ptr<CertificateFile> certFile =
- std::make_shared<CertificateFile>(req.body);
auto asyncResp = std::make_shared<AsyncResp>(res);
+ std::string certFileBody = getCertificateFromReqBody(asyncResp, req);
+
+ if (certFileBody.empty())
+ {
+ return;
+ }
+
+ std::shared_ptr<CertificateFile> certFile =
+ std::make_shared<CertificateFile>(certFileBody);
+
crow::connections::systemBus->async_method_call(
[asyncResp, certFile](const boost::system::error_code ec) {
if (ec)