15968caeeSMarri Devender Rao /* 25968caeeSMarri Devender Rao // Copyright (c) 2018 IBM Corporation 35968caeeSMarri Devender Rao // 45968caeeSMarri Devender Rao // Licensed under the Apache License, Version 2.0 (the "License"); 55968caeeSMarri Devender Rao // you may not use this file except in compliance with the License. 65968caeeSMarri Devender Rao // You may obtain a copy of the License at 75968caeeSMarri Devender Rao // 85968caeeSMarri Devender Rao // http://www.apache.org/licenses/LICENSE-2.0 95968caeeSMarri Devender Rao // 105968caeeSMarri Devender Rao // Unless required by applicable law or agreed to in writing, software 115968caeeSMarri Devender Rao // distributed under the License is distributed on an "AS IS" BASIS, 125968caeeSMarri Devender Rao // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135968caeeSMarri Devender Rao // See the License for the specific language governing permissions and 145968caeeSMarri Devender Rao // limitations under the License. 155968caeeSMarri Devender Rao */ 165968caeeSMarri Devender Rao #pragma once 175968caeeSMarri Devender Rao 185968caeeSMarri Devender Rao #include "node.hpp" 195968caeeSMarri Devender Rao 205968caeeSMarri Devender Rao #include <variant> 215968caeeSMarri Devender Rao namespace redfish 225968caeeSMarri Devender Rao { 235968caeeSMarri Devender Rao namespace certs 245968caeeSMarri Devender Rao { 255968caeeSMarri Devender Rao constexpr char const *httpsObjectPath = 265968caeeSMarri Devender Rao "/xyz/openbmc_project/certs/server/https"; 275968caeeSMarri Devender Rao constexpr char const *certInstallIntf = "xyz.openbmc_project.Certs.Install"; 285968caeeSMarri Devender Rao constexpr char const *certReplaceIntf = "xyz.openbmc_project.Certs.Replace"; 295968caeeSMarri Devender Rao constexpr char const *certPropIntf = "xyz.openbmc_project.Certs.Certificate"; 305968caeeSMarri Devender Rao constexpr char const *dbusPropIntf = "org.freedesktop.DBus.Properties"; 315968caeeSMarri Devender Rao constexpr char const *dbusObjManagerIntf = "org.freedesktop.DBus.ObjectManager"; 325968caeeSMarri Devender Rao constexpr char const *mapperBusName = "xyz.openbmc_project.ObjectMapper"; 335968caeeSMarri Devender Rao constexpr char const *mapperObjectPath = "/xyz/openbmc_project/object_mapper"; 345968caeeSMarri Devender Rao constexpr char const *mapperIntf = "xyz.openbmc_project.ObjectMapper"; 3537cce918SMarri Devender Rao constexpr char const *ldapObjectPath = "/xyz/openbmc_project/certs/client/ldap"; 3637cce918SMarri Devender Rao constexpr char const *httpsServiceName = 3737cce918SMarri Devender Rao "xyz.openbmc_project.Certs.Manager.Server.Https"; 3837cce918SMarri Devender Rao constexpr char const *ldapServiceName = 3937cce918SMarri Devender Rao "xyz.openbmc_project.Certs.Manager.Client.Ldap"; 405968caeeSMarri Devender Rao } // namespace certs 415968caeeSMarri Devender Rao 425968caeeSMarri Devender Rao /** 435968caeeSMarri Devender Rao * The Certificate schema defines a Certificate Service which represents the 445968caeeSMarri Devender Rao * actions available to manage certificates and links to where certificates 455968caeeSMarri Devender Rao * are installed. 465968caeeSMarri Devender Rao */ 475968caeeSMarri Devender Rao class CertificateService : public Node 485968caeeSMarri Devender Rao { 495968caeeSMarri Devender Rao public: 505968caeeSMarri Devender Rao CertificateService(CrowApp &app) : 515968caeeSMarri Devender Rao Node(app, "/redfish/v1/CertificateService/") 525968caeeSMarri Devender Rao { 535968caeeSMarri Devender Rao // TODO: Issue#61 No entries are available for Certificate 545968caeeSMarri Devender Rao // sevice at https://www.dmtf.org/standards/redfish 555968caeeSMarri Devender Rao // "redfish standard registries". Need to modify after DMTF 565968caeeSMarri Devender Rao // publish Privilege details for certificate service 575968caeeSMarri Devender Rao entityPrivileges = { 585968caeeSMarri Devender Rao {boost::beast::http::verb::get, {{"Login"}}}, 595968caeeSMarri Devender Rao {boost::beast::http::verb::head, {{"Login"}}}, 605968caeeSMarri Devender Rao {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 615968caeeSMarri Devender Rao {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 625968caeeSMarri Devender Rao {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 635968caeeSMarri Devender Rao {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 645968caeeSMarri Devender Rao } 655968caeeSMarri Devender Rao 665968caeeSMarri Devender Rao private: 675968caeeSMarri Devender Rao void doGet(crow::Response &res, const crow::Request &req, 685968caeeSMarri Devender Rao const std::vector<std::string> ¶ms) override 695968caeeSMarri Devender Rao { 705968caeeSMarri Devender Rao res.jsonValue = { 715968caeeSMarri Devender Rao {"@odata.type", "#CertificateService.v1_0_0.CertificateService"}, 725968caeeSMarri Devender Rao {"@odata.id", "/redfish/v1/CertificateService"}, 735968caeeSMarri Devender Rao {"@odata.context", 745968caeeSMarri Devender Rao "/redfish/v1/$metadata#CertificateService.CertificateService"}, 755968caeeSMarri Devender Rao {"Id", "CertificateService"}, 765968caeeSMarri Devender Rao {"Name", "Certificate Service"}, 775968caeeSMarri Devender Rao {"Description", "Actions available to manage certificates"}}; 785968caeeSMarri Devender Rao res.jsonValue["CertificateLocations"] = { 795968caeeSMarri Devender Rao {"@odata.id", 805968caeeSMarri Devender Rao "/redfish/v1/CertificateService/CertificateLocations"}}; 815968caeeSMarri Devender Rao res.jsonValue["Actions"]["#CertificateService.ReplaceCertificate"] = { 825968caeeSMarri Devender Rao {"target", "/redfish/v1/CertificateService/Actions/" 835968caeeSMarri Devender Rao "CertificateService.ReplaceCertificate"}, 845968caeeSMarri Devender Rao {"CertificateType@Redfish.AllowableValues", {"PEM"}}}; 855968caeeSMarri Devender Rao res.end(); 865968caeeSMarri Devender Rao } 875968caeeSMarri Devender Rao }; // CertificateService 8837cce918SMarri Devender Rao 895968caeeSMarri Devender Rao /** 905968caeeSMarri Devender Rao * @brief Find the ID specified in the URL 915968caeeSMarri Devender Rao * Finds the numbers specified after the last "/" in the URL and returns. 925968caeeSMarri Devender Rao * @param[in] path URL 935968caeeSMarri Devender Rao * @return -1 on failure and number on success 945968caeeSMarri Devender Rao */ 955968caeeSMarri Devender Rao long getIDFromURL(const std::string_view url) 965968caeeSMarri Devender Rao { 975968caeeSMarri Devender Rao std::size_t found = url.rfind("/"); 985968caeeSMarri Devender Rao if (found == std::string::npos) 995968caeeSMarri Devender Rao { 1005968caeeSMarri Devender Rao return -1; 1015968caeeSMarri Devender Rao } 1025968caeeSMarri Devender Rao if ((found + 1) < url.length()) 1035968caeeSMarri Devender Rao { 1045968caeeSMarri Devender Rao char *endPtr; 1055968caeeSMarri Devender Rao std::string_view str = url.substr(found + 1); 1065968caeeSMarri Devender Rao long value = std::strtol(str.data(), &endPtr, 10); 10737cce918SMarri Devender Rao if (endPtr != str.end()) 1085968caeeSMarri Devender Rao { 1095968caeeSMarri Devender Rao return -1; 1105968caeeSMarri Devender Rao } 1115968caeeSMarri Devender Rao return value; 1125968caeeSMarri Devender Rao } 1135968caeeSMarri Devender Rao return -1; 1145968caeeSMarri Devender Rao } 1155968caeeSMarri Devender Rao 1165968caeeSMarri Devender Rao /** 1175968caeeSMarri Devender Rao * Class to create a temporary certificate file for uploading to system 1185968caeeSMarri Devender Rao */ 1195968caeeSMarri Devender Rao class CertificateFile 1205968caeeSMarri Devender Rao { 1215968caeeSMarri Devender Rao public: 1225968caeeSMarri Devender Rao CertificateFile() = delete; 1235968caeeSMarri Devender Rao CertificateFile(const CertificateFile &) = delete; 1245968caeeSMarri Devender Rao CertificateFile &operator=(const CertificateFile &) = delete; 1255968caeeSMarri Devender Rao CertificateFile(CertificateFile &&) = delete; 1265968caeeSMarri Devender Rao CertificateFile &operator=(CertificateFile &&) = delete; 1275968caeeSMarri Devender Rao CertificateFile(const std::string &certString) 1285968caeeSMarri Devender Rao { 1295968caeeSMarri Devender Rao char dirTemplate[] = "/tmp/Certs.XXXXXX"; 1305968caeeSMarri Devender Rao char *tempDirectory = mkdtemp(dirTemplate); 1315968caeeSMarri Devender Rao if (tempDirectory) 1325968caeeSMarri Devender Rao { 1335968caeeSMarri Devender Rao certDirectory = tempDirectory; 1345968caeeSMarri Devender Rao certificateFile = certDirectory / "cert.pem"; 1355968caeeSMarri Devender Rao std::ofstream out(certificateFile, std::ofstream::out | 1365968caeeSMarri Devender Rao std::ofstream::binary | 1375968caeeSMarri Devender Rao std::ofstream::trunc); 1385968caeeSMarri Devender Rao out << certString; 1395968caeeSMarri Devender Rao out.close(); 1405968caeeSMarri Devender Rao BMCWEB_LOG_DEBUG << "Creating certificate file" << certificateFile; 1415968caeeSMarri Devender Rao } 1425968caeeSMarri Devender Rao } 1435968caeeSMarri Devender Rao ~CertificateFile() 1445968caeeSMarri Devender Rao { 1455968caeeSMarri Devender Rao if (std::filesystem::exists(certDirectory)) 1465968caeeSMarri Devender Rao { 1475968caeeSMarri Devender Rao BMCWEB_LOG_DEBUG << "Removing certificate file" << certificateFile; 1485968caeeSMarri Devender Rao try 1495968caeeSMarri Devender Rao { 1505968caeeSMarri Devender Rao std::filesystem::remove_all(certDirectory); 1515968caeeSMarri Devender Rao } 1525968caeeSMarri Devender Rao catch (const std::filesystem::filesystem_error &e) 1535968caeeSMarri Devender Rao { 1545968caeeSMarri Devender Rao BMCWEB_LOG_ERROR << "Failed to remove temp directory" 1555968caeeSMarri Devender Rao << certDirectory; 1565968caeeSMarri Devender Rao } 1575968caeeSMarri Devender Rao } 1585968caeeSMarri Devender Rao } 1595968caeeSMarri Devender Rao std::string getCertFilePath() 1605968caeeSMarri Devender Rao { 1615968caeeSMarri Devender Rao return certificateFile; 1625968caeeSMarri Devender Rao } 1635968caeeSMarri Devender Rao 1645968caeeSMarri Devender Rao private: 1655968caeeSMarri Devender Rao std::filesystem::path certificateFile; 1665968caeeSMarri Devender Rao std::filesystem::path certDirectory; 1675968caeeSMarri Devender Rao }; 1685968caeeSMarri Devender Rao 1695968caeeSMarri Devender Rao /** 1705968caeeSMarri Devender Rao * @brief Parse and update Certficate Issue/Subject property 1715968caeeSMarri Devender Rao * 1725968caeeSMarri Devender Rao * @param[in] asyncResp Shared pointer to the response message 1735968caeeSMarri Devender Rao * @param[in] str Issuer/Subject value in key=value pairs 1745968caeeSMarri Devender Rao * @param[in] type Issuer/Subject 1755968caeeSMarri Devender Rao * @return None 1765968caeeSMarri Devender Rao */ 1775968caeeSMarri Devender Rao static void updateCertIssuerOrSubject(nlohmann::json &out, 1785968caeeSMarri Devender Rao const std::string_view value) 1795968caeeSMarri Devender Rao { 1805968caeeSMarri Devender Rao // example: O=openbmc-project.xyz,CN=localhost 1815968caeeSMarri Devender Rao std::string_view::iterator i = value.begin(); 1825968caeeSMarri Devender Rao while (i != value.end()) 1835968caeeSMarri Devender Rao { 1845968caeeSMarri Devender Rao std::string_view::iterator tokenBegin = i; 1855968caeeSMarri Devender Rao while (i != value.end() && *i != '=') 1865968caeeSMarri Devender Rao { 1875968caeeSMarri Devender Rao i++; 1885968caeeSMarri Devender Rao } 1895968caeeSMarri Devender Rao if (i == value.end()) 1905968caeeSMarri Devender Rao { 1915968caeeSMarri Devender Rao break; 1925968caeeSMarri Devender Rao } 1935968caeeSMarri Devender Rao const std::string_view key(tokenBegin, i - tokenBegin); 1945968caeeSMarri Devender Rao i++; 1955968caeeSMarri Devender Rao tokenBegin = i; 1965968caeeSMarri Devender Rao while (i != value.end() && *i != ',') 1975968caeeSMarri Devender Rao { 1985968caeeSMarri Devender Rao i++; 1995968caeeSMarri Devender Rao } 2005968caeeSMarri Devender Rao const std::string_view val(tokenBegin, i - tokenBegin); 2015968caeeSMarri Devender Rao if (key == "L") 2025968caeeSMarri Devender Rao { 2035968caeeSMarri Devender Rao out["City"] = val; 2045968caeeSMarri Devender Rao } 2055968caeeSMarri Devender Rao else if (key == "CN") 2065968caeeSMarri Devender Rao { 2075968caeeSMarri Devender Rao out["CommonName"] = val; 2085968caeeSMarri Devender Rao } 2095968caeeSMarri Devender Rao else if (key == "C") 2105968caeeSMarri Devender Rao { 2115968caeeSMarri Devender Rao out["Country"] = val; 2125968caeeSMarri Devender Rao } 2135968caeeSMarri Devender Rao else if (key == "O") 2145968caeeSMarri Devender Rao { 2155968caeeSMarri Devender Rao out["Organization"] = val; 2165968caeeSMarri Devender Rao } 2175968caeeSMarri Devender Rao else if (key == "OU") 2185968caeeSMarri Devender Rao { 2195968caeeSMarri Devender Rao out["OrganizationalUnit"] = val; 2205968caeeSMarri Devender Rao } 2215968caeeSMarri Devender Rao else if (key == "ST") 2225968caeeSMarri Devender Rao { 2235968caeeSMarri Devender Rao out["State"] = val; 2245968caeeSMarri Devender Rao } 2255968caeeSMarri Devender Rao // skip comma character 2265968caeeSMarri Devender Rao if (i != value.end()) 2275968caeeSMarri Devender Rao { 2285968caeeSMarri Devender Rao i++; 2295968caeeSMarri Devender Rao } 2305968caeeSMarri Devender Rao } 2315968caeeSMarri Devender Rao } 2325968caeeSMarri Devender Rao 2335968caeeSMarri Devender Rao /** 2345968caeeSMarri Devender Rao * @brief Retrieve the certificates properties and append to the response 2355968caeeSMarri Devender Rao * message 2365968caeeSMarri Devender Rao * 2375968caeeSMarri Devender Rao * @param[in] asyncResp Shared pointer to the response message 2385968caeeSMarri Devender Rao * @param[in] objectPath Path of the D-Bus service object 2395968caeeSMarri Devender Rao * @param[in] certId Id of the certificate 2405968caeeSMarri Devender Rao * @param[in] certURL URL of the certificate object 2415968caeeSMarri Devender Rao * @param[in] name name of the certificate 2425968caeeSMarri Devender Rao * @return None 2435968caeeSMarri Devender Rao */ 2445968caeeSMarri Devender Rao static void getCertificateProperties( 2455968caeeSMarri Devender Rao const std::shared_ptr<AsyncResp> &asyncResp, const std::string &objectPath, 24637cce918SMarri Devender Rao const std::string &service, long certId, const std::string &certURL, 24737cce918SMarri Devender Rao const std::string &name) 2485968caeeSMarri Devender Rao { 2495968caeeSMarri Devender Rao using PropertyType = 2505968caeeSMarri Devender Rao std::variant<std::string, uint64_t, std::vector<std::string>>; 2515968caeeSMarri Devender Rao using PropertiesMap = boost::container::flat_map<std::string, PropertyType>; 2525968caeeSMarri Devender Rao BMCWEB_LOG_DEBUG << "getCertificateProperties Path=" << objectPath 2535968caeeSMarri Devender Rao << " certId=" << certId << " certURl=" << certURL; 2545968caeeSMarri Devender Rao crow::connections::systemBus->async_method_call( 25537cce918SMarri Devender Rao [asyncResp, certURL, certId, name](const boost::system::error_code ec, 2565968caeeSMarri Devender Rao const PropertiesMap &properties) { 2575968caeeSMarri Devender Rao if (ec) 2585968caeeSMarri Devender Rao { 2595968caeeSMarri Devender Rao BMCWEB_LOG_ERROR << "DBUS response error: " << ec; 260*8aae75adSMarri Devender Rao messages::resourceNotFound(asyncResp->res, name, 261*8aae75adSMarri Devender Rao std::to_string(certId)); 2625968caeeSMarri Devender Rao return; 2635968caeeSMarri Devender Rao } 2645968caeeSMarri Devender Rao asyncResp->res.jsonValue = { 2655968caeeSMarri Devender Rao {"@odata.id", certURL}, 2665968caeeSMarri Devender Rao {"@odata.type", "#Certificate.v1_0_0.Certificate"}, 2675968caeeSMarri Devender Rao {"@odata.context", 2685968caeeSMarri Devender Rao "/redfish/v1/$metadata#Certificate.Certificate"}, 2695968caeeSMarri Devender Rao {"Id", std::to_string(certId)}, 2705968caeeSMarri Devender Rao {"Name", name}, 2715968caeeSMarri Devender Rao {"Description", name}}; 2725968caeeSMarri Devender Rao for (const auto &property : properties) 2735968caeeSMarri Devender Rao { 2745968caeeSMarri Devender Rao if (property.first == "CertificateString") 2755968caeeSMarri Devender Rao { 2765968caeeSMarri Devender Rao asyncResp->res.jsonValue["CertificateString"] = ""; 2775968caeeSMarri Devender Rao const std::string *value = 2785968caeeSMarri Devender Rao std::get_if<std::string>(&property.second); 2795968caeeSMarri Devender Rao if (value) 2805968caeeSMarri Devender Rao { 28137cce918SMarri Devender Rao asyncResp->res.jsonValue["CertificateString"] = *value; 2825968caeeSMarri Devender Rao } 2835968caeeSMarri Devender Rao } 2845968caeeSMarri Devender Rao else if (property.first == "KeyUsage") 2855968caeeSMarri Devender Rao { 2865968caeeSMarri Devender Rao nlohmann::json &keyUsage = 2875968caeeSMarri Devender Rao asyncResp->res.jsonValue["KeyUsage"]; 2885968caeeSMarri Devender Rao keyUsage = nlohmann::json::array(); 2895968caeeSMarri Devender Rao const std::vector<std::string> *value = 29037cce918SMarri Devender Rao std::get_if<std::vector<std::string>>(&property.second); 2915968caeeSMarri Devender Rao if (value) 2925968caeeSMarri Devender Rao { 2935968caeeSMarri Devender Rao for (const std::string &usage : *value) 2945968caeeSMarri Devender Rao { 2955968caeeSMarri Devender Rao keyUsage.push_back(usage); 2965968caeeSMarri Devender Rao } 2975968caeeSMarri Devender Rao } 2985968caeeSMarri Devender Rao } 2995968caeeSMarri Devender Rao else if (property.first == "Issuer") 3005968caeeSMarri Devender Rao { 3015968caeeSMarri Devender Rao const std::string *value = 3025968caeeSMarri Devender Rao std::get_if<std::string>(&property.second); 3035968caeeSMarri Devender Rao if (value) 3045968caeeSMarri Devender Rao { 3055968caeeSMarri Devender Rao updateCertIssuerOrSubject( 3065968caeeSMarri Devender Rao asyncResp->res.jsonValue["Issuer"], *value); 3075968caeeSMarri Devender Rao } 3085968caeeSMarri Devender Rao } 3095968caeeSMarri Devender Rao else if (property.first == "Subject") 3105968caeeSMarri Devender Rao { 3115968caeeSMarri Devender Rao const std::string *value = 3125968caeeSMarri Devender Rao std::get_if<std::string>(&property.second); 3135968caeeSMarri Devender Rao if (value) 3145968caeeSMarri Devender Rao { 3155968caeeSMarri Devender Rao updateCertIssuerOrSubject( 31637cce918SMarri Devender Rao asyncResp->res.jsonValue["Subject"], *value); 3175968caeeSMarri Devender Rao } 3185968caeeSMarri Devender Rao } 3195968caeeSMarri Devender Rao else if (property.first == "ValidNotAfter") 3205968caeeSMarri Devender Rao { 3215968caeeSMarri Devender Rao const uint64_t *value = 3225968caeeSMarri Devender Rao std::get_if<uint64_t>(&property.second); 3235968caeeSMarri Devender Rao if (value) 3245968caeeSMarri Devender Rao { 32537cce918SMarri Devender Rao std::time_t time = static_cast<std::time_t>(*value); 3265968caeeSMarri Devender Rao asyncResp->res.jsonValue["ValidNotAfter"] = 3275968caeeSMarri Devender Rao crow::utility::getDateTime(time); 3285968caeeSMarri Devender Rao } 3295968caeeSMarri Devender Rao } 3305968caeeSMarri Devender Rao else if (property.first == "ValidNotBefore") 3315968caeeSMarri Devender Rao { 3325968caeeSMarri Devender Rao const uint64_t *value = 3335968caeeSMarri Devender Rao std::get_if<uint64_t>(&property.second); 3345968caeeSMarri Devender Rao if (value) 3355968caeeSMarri Devender Rao { 33637cce918SMarri Devender Rao std::time_t time = static_cast<std::time_t>(*value); 3375968caeeSMarri Devender Rao asyncResp->res.jsonValue["ValidNotBefore"] = 3385968caeeSMarri Devender Rao crow::utility::getDateTime(time); 3395968caeeSMarri Devender Rao } 3405968caeeSMarri Devender Rao } 3415968caeeSMarri Devender Rao } 3425968caeeSMarri Devender Rao asyncResp->res.addHeader("Location", certURL); 3435968caeeSMarri Devender Rao }, 3445968caeeSMarri Devender Rao service, objectPath, certs::dbusPropIntf, "GetAll", 3455968caeeSMarri Devender Rao certs::certPropIntf); 3465968caeeSMarri Devender Rao } 3475968caeeSMarri Devender Rao 3485968caeeSMarri Devender Rao using GetObjectType = 3495968caeeSMarri Devender Rao std::vector<std::pair<std::string, std::vector<std::string>>>; 3505968caeeSMarri Devender Rao 3515968caeeSMarri Devender Rao /** 3525968caeeSMarri Devender Rao * Action to replace an existing certificate 3535968caeeSMarri Devender Rao */ 3545968caeeSMarri Devender Rao class CertificateActionsReplaceCertificate : public Node 3555968caeeSMarri Devender Rao { 3565968caeeSMarri Devender Rao public: 3575968caeeSMarri Devender Rao CertificateActionsReplaceCertificate(CrowApp &app) : 3585968caeeSMarri Devender Rao Node(app, "/redfish/v1/CertificateService/Actions/" 3595968caeeSMarri Devender Rao "CertificateService.ReplaceCertificate/") 3605968caeeSMarri Devender Rao { 3615968caeeSMarri Devender Rao entityPrivileges = { 3625968caeeSMarri Devender Rao {boost::beast::http::verb::get, {{"Login"}}}, 3635968caeeSMarri Devender Rao {boost::beast::http::verb::head, {{"Login"}}}, 3645968caeeSMarri Devender Rao {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 3655968caeeSMarri Devender Rao {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 3665968caeeSMarri Devender Rao {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 3675968caeeSMarri Devender Rao {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 3685968caeeSMarri Devender Rao } 3695968caeeSMarri Devender Rao 3705968caeeSMarri Devender Rao private: 3715968caeeSMarri Devender Rao void doPost(crow::Response &res, const crow::Request &req, 3725968caeeSMarri Devender Rao const std::vector<std::string> ¶ms) override 3735968caeeSMarri Devender Rao { 3745968caeeSMarri Devender Rao std::string certificate; 3755968caeeSMarri Devender Rao nlohmann::json certificateUri; 3765968caeeSMarri Devender Rao std::optional<std::string> certificateType = "PEM"; 3775968caeeSMarri Devender Rao auto asyncResp = std::make_shared<AsyncResp>(res); 3785968caeeSMarri Devender Rao if (!json_util::readJson(req, asyncResp->res, "CertificateString", 3795968caeeSMarri Devender Rao certificate, "CertificateUri", certificateUri, 3805968caeeSMarri Devender Rao "CertificateType", certificateType)) 3815968caeeSMarri Devender Rao { 3825968caeeSMarri Devender Rao BMCWEB_LOG_ERROR << "Required parameters are missing"; 3835968caeeSMarri Devender Rao messages::internalError(asyncResp->res); 3845968caeeSMarri Devender Rao return; 3855968caeeSMarri Devender Rao } 3865968caeeSMarri Devender Rao 3875968caeeSMarri Devender Rao if (!certificateType) 3885968caeeSMarri Devender Rao { 3895968caeeSMarri Devender Rao // should never happen, but it never hurts to be paranoid. 3905968caeeSMarri Devender Rao return; 3915968caeeSMarri Devender Rao } 3925968caeeSMarri Devender Rao if (certificateType != "PEM") 3935968caeeSMarri Devender Rao { 3945968caeeSMarri Devender Rao messages::actionParameterNotSupported( 3955968caeeSMarri Devender Rao asyncResp->res, "CertificateType", "ReplaceCertificate"); 3965968caeeSMarri Devender Rao return; 3975968caeeSMarri Devender Rao } 3985968caeeSMarri Devender Rao 3995968caeeSMarri Devender Rao std::string certURI; 4005968caeeSMarri Devender Rao if (!redfish::json_util::readJson(certificateUri, asyncResp->res, 4015968caeeSMarri Devender Rao "@odata.id", certURI)) 4025968caeeSMarri Devender Rao { 4035968caeeSMarri Devender Rao messages::actionParameterMissing( 4045968caeeSMarri Devender Rao asyncResp->res, "ReplaceCertificate", "CertificateUri"); 4055968caeeSMarri Devender Rao return; 4065968caeeSMarri Devender Rao } 4075968caeeSMarri Devender Rao 4085968caeeSMarri Devender Rao BMCWEB_LOG_INFO << "Certificate URI to replace" << certURI; 4095968caeeSMarri Devender Rao long id = getIDFromURL(certURI); 4105968caeeSMarri Devender Rao if (id < 0) 4115968caeeSMarri Devender Rao { 4125968caeeSMarri Devender Rao messages::actionParameterValueFormatError(asyncResp->res, certURI, 4135968caeeSMarri Devender Rao "CertificateUri", 4145968caeeSMarri Devender Rao "ReplaceCertificate"); 4155968caeeSMarri Devender Rao return; 4165968caeeSMarri Devender Rao } 4175968caeeSMarri Devender Rao std::string objectPath; 4185968caeeSMarri Devender Rao std::string name; 41937cce918SMarri Devender Rao std::string service; 4205968caeeSMarri Devender Rao if (boost::starts_with( 4215968caeeSMarri Devender Rao certURI, 4225968caeeSMarri Devender Rao "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/")) 4235968caeeSMarri Devender Rao { 4245968caeeSMarri Devender Rao objectPath = 4255968caeeSMarri Devender Rao std::string(certs::httpsObjectPath) + "/" + std::to_string(id); 4265968caeeSMarri Devender Rao name = "HTTPS certificate"; 42737cce918SMarri Devender Rao service = certs::httpsServiceName; 42837cce918SMarri Devender Rao } 42937cce918SMarri Devender Rao else if (boost::starts_with( 43037cce918SMarri Devender Rao certURI, "/redfish/v1/AccountService/LDAP/Certificates/")) 43137cce918SMarri Devender Rao { 43237cce918SMarri Devender Rao objectPath = 43337cce918SMarri Devender Rao std::string(certs::ldapObjectPath) + "/" + std::to_string(id); 43437cce918SMarri Devender Rao name = "LDAP certificate"; 43537cce918SMarri Devender Rao service = certs::ldapServiceName; 4365968caeeSMarri Devender Rao } 4375968caeeSMarri Devender Rao else 4385968caeeSMarri Devender Rao { 4395968caeeSMarri Devender Rao messages::actionParameterNotSupported( 4405968caeeSMarri Devender Rao asyncResp->res, "CertificateUri", "ReplaceCertificate"); 4415968caeeSMarri Devender Rao return; 4425968caeeSMarri Devender Rao } 4435968caeeSMarri Devender Rao 4445968caeeSMarri Devender Rao std::shared_ptr<CertificateFile> certFile = 4455968caeeSMarri Devender Rao std::make_shared<CertificateFile>(certificate); 4465968caeeSMarri Devender Rao crow::connections::systemBus->async_method_call( 44737cce918SMarri Devender Rao [asyncResp, certFile, objectPath, service, certURI, id, 4485968caeeSMarri Devender Rao name](const boost::system::error_code ec) { 4495968caeeSMarri Devender Rao if (ec) 4505968caeeSMarri Devender Rao { 4515968caeeSMarri Devender Rao BMCWEB_LOG_ERROR << "DBUS response error: " << ec; 452*8aae75adSMarri Devender Rao messages::resourceNotFound(asyncResp->res, name, 453*8aae75adSMarri Devender Rao std::to_string(id)); 4545968caeeSMarri Devender Rao return; 4555968caeeSMarri Devender Rao } 45637cce918SMarri Devender Rao getCertificateProperties(asyncResp, objectPath, service, id, 4575968caeeSMarri Devender Rao certURI, name); 4585968caeeSMarri Devender Rao BMCWEB_LOG_DEBUG << "HTTPS certificate install file=" 4595968caeeSMarri Devender Rao << certFile->getCertFilePath(); 4605968caeeSMarri Devender Rao }, 4615968caeeSMarri Devender Rao service, objectPath, certs::certReplaceIntf, "Replace", 4625968caeeSMarri Devender Rao certFile->getCertFilePath()); 4635968caeeSMarri Devender Rao } 4645968caeeSMarri Devender Rao }; // CertificateActionsReplaceCertificate 4655968caeeSMarri Devender Rao 4665968caeeSMarri Devender Rao /** 4675968caeeSMarri Devender Rao * Certificate resource describes a certificate used to prove the identity 4685968caeeSMarri Devender Rao * of a component, account or service. 4695968caeeSMarri Devender Rao */ 4705968caeeSMarri Devender Rao class HTTPSCertificate : public Node 4715968caeeSMarri Devender Rao { 4725968caeeSMarri Devender Rao public: 4735968caeeSMarri Devender Rao template <typename CrowApp> 4745968caeeSMarri Devender Rao HTTPSCertificate(CrowApp &app) : 4755968caeeSMarri Devender Rao Node(app, 4765968caeeSMarri Devender Rao "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/" 4775968caeeSMarri Devender Rao "<str>/", 4785968caeeSMarri Devender Rao std::string()) 4795968caeeSMarri Devender Rao { 4805968caeeSMarri Devender Rao entityPrivileges = { 4815968caeeSMarri Devender Rao {boost::beast::http::verb::get, {{"Login"}}}, 4825968caeeSMarri Devender Rao {boost::beast::http::verb::head, {{"Login"}}}, 4835968caeeSMarri Devender Rao {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 4845968caeeSMarri Devender Rao {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 4855968caeeSMarri Devender Rao {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 4865968caeeSMarri Devender Rao {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 4875968caeeSMarri Devender Rao } 4885968caeeSMarri Devender Rao 4895968caeeSMarri Devender Rao void doGet(crow::Response &res, const crow::Request &req, 4905968caeeSMarri Devender Rao const std::vector<std::string> ¶ms) override 4915968caeeSMarri Devender Rao { 4925968caeeSMarri Devender Rao auto asyncResp = std::make_shared<AsyncResp>(res); 4935968caeeSMarri Devender Rao if (params.size() != 1) 4945968caeeSMarri Devender Rao { 4955968caeeSMarri Devender Rao messages::internalError(asyncResp->res); 4965968caeeSMarri Devender Rao return; 4975968caeeSMarri Devender Rao } 4985968caeeSMarri Devender Rao long id = getIDFromURL(req.url); 4995968caeeSMarri Devender Rao 5005968caeeSMarri Devender Rao BMCWEB_LOG_DEBUG << "HTTPSCertificate::doGet ID=" << std::to_string(id); 5015968caeeSMarri Devender Rao std::string certURL = 5025968caeeSMarri Devender Rao "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/" + 5035968caeeSMarri Devender Rao std::to_string(id); 5045968caeeSMarri Devender Rao std::string objectPath = certs::httpsObjectPath; 5055968caeeSMarri Devender Rao objectPath += "/"; 5065968caeeSMarri Devender Rao objectPath += std::to_string(id); 50737cce918SMarri Devender Rao getCertificateProperties(asyncResp, objectPath, certs::httpsServiceName, 50837cce918SMarri Devender Rao id, certURL, "HTTPS Certificate"); 5095968caeeSMarri Devender Rao } 5105968caeeSMarri Devender Rao 5115968caeeSMarri Devender Rao }; // namespace redfish 5125968caeeSMarri Devender Rao 5135968caeeSMarri Devender Rao /** 5145968caeeSMarri Devender Rao * Collection of HTTPS certificates 5155968caeeSMarri Devender Rao */ 5165968caeeSMarri Devender Rao class HTTPSCertificateCollection : public Node 5175968caeeSMarri Devender Rao { 5185968caeeSMarri Devender Rao public: 5195968caeeSMarri Devender Rao template <typename CrowApp> 5205968caeeSMarri Devender Rao HTTPSCertificateCollection(CrowApp &app) : 5215968caeeSMarri Devender Rao Node(app, 5225968caeeSMarri Devender Rao "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/") 5235968caeeSMarri Devender Rao { 5245968caeeSMarri Devender Rao entityPrivileges = { 5255968caeeSMarri Devender Rao {boost::beast::http::verb::get, {{"Login"}}}, 5265968caeeSMarri Devender Rao {boost::beast::http::verb::head, {{"Login"}}}, 5275968caeeSMarri Devender Rao {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 5285968caeeSMarri Devender Rao {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 5295968caeeSMarri Devender Rao {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 5305968caeeSMarri Devender Rao {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 5315968caeeSMarri Devender Rao } 5325968caeeSMarri Devender Rao void doGet(crow::Response &res, const crow::Request &req, 5335968caeeSMarri Devender Rao const std::vector<std::string> ¶ms) override 5345968caeeSMarri Devender Rao { 5355968caeeSMarri Devender Rao res.jsonValue = { 5365968caeeSMarri Devender Rao {"@odata.id", 5375968caeeSMarri Devender Rao "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates"}, 5385968caeeSMarri Devender Rao {"@odata.type", "#CertificateCollection.CertificateCollection"}, 5395968caeeSMarri Devender Rao {"@odata.context", 5405968caeeSMarri Devender Rao "/redfish/v1/" 5415968caeeSMarri Devender Rao "$metadata#CertificateCollection.CertificateCollection"}, 5425968caeeSMarri Devender Rao {"Name", "HTTPS Certificates Collection"}, 5435968caeeSMarri Devender Rao {"Description", "A Collection of HTTPS certificate instances"}}; 5445968caeeSMarri Devender Rao auto asyncResp = std::make_shared<AsyncResp>(res); 5455968caeeSMarri Devender Rao crow::connections::systemBus->async_method_call( 5465968caeeSMarri Devender Rao [asyncResp](const boost::system::error_code ec, 5475968caeeSMarri Devender Rao const ManagedObjectType &certs) { 5485968caeeSMarri Devender Rao if (ec) 5495968caeeSMarri Devender Rao { 5505968caeeSMarri Devender Rao BMCWEB_LOG_ERROR << "DBUS response error: " << ec; 5515968caeeSMarri Devender Rao messages::internalError(asyncResp->res); 5525968caeeSMarri Devender Rao return; 5535968caeeSMarri Devender Rao } 55437cce918SMarri Devender Rao nlohmann::json &members = asyncResp->res.jsonValue["Members"]; 5555968caeeSMarri Devender Rao members = nlohmann::json::array(); 5565968caeeSMarri Devender Rao for (const auto &cert : certs) 5575968caeeSMarri Devender Rao { 5585968caeeSMarri Devender Rao long id = getIDFromURL(cert.first.str); 55937cce918SMarri Devender Rao if (id >= 0) 5605968caeeSMarri Devender Rao { 5615968caeeSMarri Devender Rao members.push_back( 5625968caeeSMarri Devender Rao {{"@odata.id", 5635968caeeSMarri Devender Rao "/redfish/v1/Managers/bmc/" 5645968caeeSMarri Devender Rao "NetworkProtocol/HTTPS/Certificates/" + 5655968caeeSMarri Devender Rao std::to_string(id)}}); 5665968caeeSMarri Devender Rao } 5675968caeeSMarri Devender Rao } 5685968caeeSMarri Devender Rao asyncResp->res.jsonValue["Members@odata.count"] = 5695968caeeSMarri Devender Rao members.size(); 5705968caeeSMarri Devender Rao }, 57137cce918SMarri Devender Rao certs::httpsServiceName, certs::httpsObjectPath, 57237cce918SMarri Devender Rao certs::dbusObjManagerIntf, "GetManagedObjects"); 5735968caeeSMarri Devender Rao } 5745968caeeSMarri Devender Rao 5755968caeeSMarri Devender Rao void doPost(crow::Response &res, const crow::Request &req, 5765968caeeSMarri Devender Rao const std::vector<std::string> ¶ms) override 5775968caeeSMarri Devender Rao { 5785968caeeSMarri Devender Rao BMCWEB_LOG_DEBUG << "HTTPSCertificateCollection::doPost"; 5795968caeeSMarri Devender Rao auto asyncResp = std::make_shared<AsyncResp>(res); 5805968caeeSMarri Devender Rao asyncResp->res.jsonValue = {{"Name", "HTTPS Certificate"}, 5815968caeeSMarri Devender Rao {"Description", "HTTPS Certificate"}}; 5825968caeeSMarri Devender Rao 5835968caeeSMarri Devender Rao std::shared_ptr<CertificateFile> certFile = 5845968caeeSMarri Devender Rao std::make_shared<CertificateFile>(req.body); 5855968caeeSMarri Devender Rao 5865968caeeSMarri Devender Rao crow::connections::systemBus->async_method_call( 5875968caeeSMarri Devender Rao [asyncResp, certFile](const boost::system::error_code ec) { 5885968caeeSMarri Devender Rao if (ec) 5895968caeeSMarri Devender Rao { 5905968caeeSMarri Devender Rao BMCWEB_LOG_ERROR << "DBUS response error: " << ec; 5915968caeeSMarri Devender Rao messages::internalError(asyncResp->res); 5925968caeeSMarri Devender Rao return; 5935968caeeSMarri Devender Rao } 5945968caeeSMarri Devender Rao // TODO: Issue#84 supporting only 1 certificate 5955968caeeSMarri Devender Rao long certId = 1; 5965968caeeSMarri Devender Rao std::string certURL = 5975968caeeSMarri Devender Rao "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/" 5985968caeeSMarri Devender Rao "Certificates/" + 5995968caeeSMarri Devender Rao std::to_string(certId); 60037cce918SMarri Devender Rao std::string objectPath = std::string(certs::httpsObjectPath) + 60137cce918SMarri Devender Rao "/" + std::to_string(certId); 60237cce918SMarri Devender Rao getCertificateProperties(asyncResp, objectPath, 60337cce918SMarri Devender Rao certs::httpsServiceName, certId, 6045968caeeSMarri Devender Rao certURL, "HTTPS Certificate"); 6055968caeeSMarri Devender Rao BMCWEB_LOG_DEBUG << "HTTPS certificate install file=" 6065968caeeSMarri Devender Rao << certFile->getCertFilePath(); 6075968caeeSMarri Devender Rao }, 60837cce918SMarri Devender Rao certs::httpsServiceName, certs::httpsObjectPath, 60937cce918SMarri Devender Rao certs::certInstallIntf, "Install", certFile->getCertFilePath()); 6105968caeeSMarri Devender Rao } 6115968caeeSMarri Devender Rao }; // HTTPSCertificateCollection 6125968caeeSMarri Devender Rao 6135968caeeSMarri Devender Rao /** 6145968caeeSMarri Devender Rao * The certificate location schema defines a resource that an administrator 6155968caeeSMarri Devender Rao * can use in order to locate all certificates installed on a given service. 6165968caeeSMarri Devender Rao */ 6175968caeeSMarri Devender Rao class CertificateLocations : public Node 6185968caeeSMarri Devender Rao { 6195968caeeSMarri Devender Rao public: 6205968caeeSMarri Devender Rao template <typename CrowApp> 6215968caeeSMarri Devender Rao CertificateLocations(CrowApp &app) : 6225968caeeSMarri Devender Rao Node(app, "/redfish/v1/CertificateService/CertificateLocations/") 6235968caeeSMarri Devender Rao { 6245968caeeSMarri Devender Rao entityPrivileges = { 6255968caeeSMarri Devender Rao {boost::beast::http::verb::get, {{"Login"}}}, 6265968caeeSMarri Devender Rao {boost::beast::http::verb::head, {{"Login"}}}, 6275968caeeSMarri Devender Rao {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 6285968caeeSMarri Devender Rao {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 6295968caeeSMarri Devender Rao {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 6305968caeeSMarri Devender Rao {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 6315968caeeSMarri Devender Rao } 6325968caeeSMarri Devender Rao 6335968caeeSMarri Devender Rao private: 6345968caeeSMarri Devender Rao void doGet(crow::Response &res, const crow::Request &req, 6355968caeeSMarri Devender Rao const std::vector<std::string> ¶ms) override 6365968caeeSMarri Devender Rao { 6375968caeeSMarri Devender Rao res.jsonValue = { 6385968caeeSMarri Devender Rao {"@odata.id", 6395968caeeSMarri Devender Rao "/redfish/v1/CertificateService/CertificateLocations"}, 6405968caeeSMarri Devender Rao {"@odata.type", 6415968caeeSMarri Devender Rao "#CertificateLocations.v1_0_0.CertificateLocations"}, 6425968caeeSMarri Devender Rao {"@odata.context", 6435968caeeSMarri Devender Rao "/redfish/v1/$metadata#CertificateLocations.CertificateLocations"}, 6445968caeeSMarri Devender Rao {"Name", "Certificate Locations"}, 6455968caeeSMarri Devender Rao {"Id", "CertificateLocations"}, 6465968caeeSMarri Devender Rao {"Description", 6475968caeeSMarri Devender Rao "Defines a resource that an administrator can use in order to " 6485968caeeSMarri Devender Rao "locate all certificates installed on a given service"}}; 6495968caeeSMarri Devender Rao auto asyncResp = std::make_shared<AsyncResp>(res); 6505968caeeSMarri Devender Rao nlohmann::json &links = 6515968caeeSMarri Devender Rao asyncResp->res.jsonValue["Links"]["Certificates"]; 6525968caeeSMarri Devender Rao links = nlohmann::json::array(); 6535968caeeSMarri Devender Rao getCertificateLocations( 6545968caeeSMarri Devender Rao asyncResp, 6555968caeeSMarri Devender Rao "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/", 65637cce918SMarri Devender Rao certs::httpsObjectPath, certs::httpsServiceName); 65737cce918SMarri Devender Rao getCertificateLocations(asyncResp, 65837cce918SMarri Devender Rao "/redfish/v1/AccountService/LDAP/Certificates/", 65937cce918SMarri Devender Rao certs::ldapObjectPath, certs::ldapServiceName); 66037cce918SMarri Devender Rao } 66137cce918SMarri Devender Rao /** 66237cce918SMarri Devender Rao * @brief Retrieve the certificates installed list and append to the 66337cce918SMarri Devender Rao * response 66437cce918SMarri Devender Rao * 66537cce918SMarri Devender Rao * @param[in] asyncResp Shared pointer to the response message 66637cce918SMarri Devender Rao * @param[in] certURL Path of the certificate object 66737cce918SMarri Devender Rao * @param[in] path Path of the D-Bus service object 66837cce918SMarri Devender Rao * @return None 66937cce918SMarri Devender Rao */ 67037cce918SMarri Devender Rao void getCertificateLocations(std::shared_ptr<AsyncResp> &asyncResp, 67137cce918SMarri Devender Rao const std::string &certURL, 67237cce918SMarri Devender Rao const std::string &path, 67337cce918SMarri Devender Rao const std::string &service) 67437cce918SMarri Devender Rao { 67537cce918SMarri Devender Rao BMCWEB_LOG_DEBUG << "getCertificateLocations URI=" << certURL 67637cce918SMarri Devender Rao << " Path=" << path << " service= " << service; 67737cce918SMarri Devender Rao crow::connections::systemBus->async_method_call( 67837cce918SMarri Devender Rao [asyncResp, certURL](const boost::system::error_code ec, 67937cce918SMarri Devender Rao const ManagedObjectType &certs) { 68037cce918SMarri Devender Rao if (ec) 68137cce918SMarri Devender Rao { 68237cce918SMarri Devender Rao BMCWEB_LOG_ERROR << "DBUS response error: " << ec; 68337cce918SMarri Devender Rao messages::internalError(asyncResp->res); 68437cce918SMarri Devender Rao return; 68537cce918SMarri Devender Rao } 68637cce918SMarri Devender Rao nlohmann::json &links = 68737cce918SMarri Devender Rao asyncResp->res.jsonValue["Links"]["Certificates"]; 68837cce918SMarri Devender Rao for (auto &cert : certs) 68937cce918SMarri Devender Rao { 69037cce918SMarri Devender Rao long id = getIDFromURL(cert.first.str); 69137cce918SMarri Devender Rao if (id >= 0) 69237cce918SMarri Devender Rao { 69337cce918SMarri Devender Rao links.push_back( 69437cce918SMarri Devender Rao {{"@odata.id", certURL + std::to_string(id)}}); 69537cce918SMarri Devender Rao } 69637cce918SMarri Devender Rao } 69737cce918SMarri Devender Rao asyncResp->res.jsonValue["Links"]["Certificates@odata.count"] = 69837cce918SMarri Devender Rao links.size(); 69937cce918SMarri Devender Rao }, 70037cce918SMarri Devender Rao service, path, certs::dbusObjManagerIntf, "GetManagedObjects"); 7015968caeeSMarri Devender Rao } 7025968caeeSMarri Devender Rao }; // CertificateLocations 70337cce918SMarri Devender Rao 70437cce918SMarri Devender Rao /** 70537cce918SMarri Devender Rao * Collection of LDAP certificates 70637cce918SMarri Devender Rao */ 70737cce918SMarri Devender Rao class LDAPCertificateCollection : public Node 70837cce918SMarri Devender Rao { 70937cce918SMarri Devender Rao public: 71037cce918SMarri Devender Rao template <typename CrowApp> 71137cce918SMarri Devender Rao LDAPCertificateCollection(CrowApp &app) : 71237cce918SMarri Devender Rao Node(app, "/redfish/v1/AccountService/LDAP/Certificates/") 71337cce918SMarri Devender Rao { 71437cce918SMarri Devender Rao entityPrivileges = { 71537cce918SMarri Devender Rao {boost::beast::http::verb::get, {{"Login"}}}, 71637cce918SMarri Devender Rao {boost::beast::http::verb::head, {{"Login"}}}, 71737cce918SMarri Devender Rao {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 71837cce918SMarri Devender Rao {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 71937cce918SMarri Devender Rao {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 72037cce918SMarri Devender Rao {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 72137cce918SMarri Devender Rao } 72237cce918SMarri Devender Rao void doGet(crow::Response &res, const crow::Request &req, 72337cce918SMarri Devender Rao const std::vector<std::string> ¶ms) override 72437cce918SMarri Devender Rao { 72537cce918SMarri Devender Rao res.jsonValue = { 72637cce918SMarri Devender Rao {"@odata.id", "/redfish/v1/AccountService/LDAP/Certificates"}, 72737cce918SMarri Devender Rao {"@odata.type", "#CertificateCollection.CertificateCollection"}, 72837cce918SMarri Devender Rao {"@odata.context", 72937cce918SMarri Devender Rao "/redfish/v1/" 73037cce918SMarri Devender Rao "$metadata#CertificateCollection.CertificateCollection"}, 73137cce918SMarri Devender Rao {"Name", "LDAP Certificates Collection"}, 73237cce918SMarri Devender Rao {"Description", "A Collection of LDAP certificate instances"}}; 73337cce918SMarri Devender Rao auto asyncResp = std::make_shared<AsyncResp>(res); 73437cce918SMarri Devender Rao crow::connections::systemBus->async_method_call( 73537cce918SMarri Devender Rao [asyncResp](const boost::system::error_code ec, 73637cce918SMarri Devender Rao const ManagedObjectType &certs) { 73737cce918SMarri Devender Rao if (ec) 73837cce918SMarri Devender Rao { 73937cce918SMarri Devender Rao BMCWEB_LOG_ERROR << "DBUS response error: " << ec; 74037cce918SMarri Devender Rao messages::internalError(asyncResp->res); 74137cce918SMarri Devender Rao return; 74237cce918SMarri Devender Rao } 74337cce918SMarri Devender Rao nlohmann::json &members = asyncResp->res.jsonValue["Members"]; 74437cce918SMarri Devender Rao members = nlohmann::json::array(); 74537cce918SMarri Devender Rao for (const auto &cert : certs) 74637cce918SMarri Devender Rao { 74737cce918SMarri Devender Rao long id = getIDFromURL(cert.first.str); 74837cce918SMarri Devender Rao if (id >= 0) 74937cce918SMarri Devender Rao { 75037cce918SMarri Devender Rao members.push_back( 75137cce918SMarri Devender Rao {{"@odata.id", "/redfish/v1/AccountService/" 75237cce918SMarri Devender Rao "LDAP/Certificates/" + 75337cce918SMarri Devender Rao std::to_string(id)}}); 75437cce918SMarri Devender Rao } 75537cce918SMarri Devender Rao } 75637cce918SMarri Devender Rao asyncResp->res.jsonValue["Members@odata.count"] = 75737cce918SMarri Devender Rao members.size(); 75837cce918SMarri Devender Rao }, 75937cce918SMarri Devender Rao certs::ldapServiceName, certs::ldapObjectPath, 76037cce918SMarri Devender Rao certs::dbusObjManagerIntf, "GetManagedObjects"); 76137cce918SMarri Devender Rao } 76237cce918SMarri Devender Rao 76337cce918SMarri Devender Rao void doPost(crow::Response &res, const crow::Request &req, 76437cce918SMarri Devender Rao const std::vector<std::string> ¶ms) override 76537cce918SMarri Devender Rao { 76637cce918SMarri Devender Rao std::shared_ptr<CertificateFile> certFile = 76737cce918SMarri Devender Rao std::make_shared<CertificateFile>(req.body); 76837cce918SMarri Devender Rao auto asyncResp = std::make_shared<AsyncResp>(res); 76937cce918SMarri Devender Rao crow::connections::systemBus->async_method_call( 77037cce918SMarri Devender Rao [asyncResp, certFile](const boost::system::error_code ec) { 77137cce918SMarri Devender Rao if (ec) 77237cce918SMarri Devender Rao { 77337cce918SMarri Devender Rao BMCWEB_LOG_ERROR << "DBUS response error: " << ec; 77437cce918SMarri Devender Rao messages::internalError(asyncResp->res); 77537cce918SMarri Devender Rao return; 77637cce918SMarri Devender Rao } 77737cce918SMarri Devender Rao //// TODO: Issue#84 supporting only 1 certificate 77837cce918SMarri Devender Rao long certId = 1; 77937cce918SMarri Devender Rao std::string certURL = 78037cce918SMarri Devender Rao "/redfish/v1/AccountService/LDAP/Certificates/" + 78137cce918SMarri Devender Rao std::to_string(certId); 78237cce918SMarri Devender Rao std::string objectPath = std::string(certs::ldapObjectPath) + 78337cce918SMarri Devender Rao "/" + std::to_string(certId); 78437cce918SMarri Devender Rao getCertificateProperties(asyncResp, objectPath, 78537cce918SMarri Devender Rao certs::ldapServiceName, certId, 78637cce918SMarri Devender Rao certURL, "LDAP Certificate"); 78737cce918SMarri Devender Rao BMCWEB_LOG_DEBUG << "LDAP certificate install file=" 78837cce918SMarri Devender Rao << certFile->getCertFilePath(); 78937cce918SMarri Devender Rao }, 79037cce918SMarri Devender Rao certs::ldapServiceName, certs::ldapObjectPath, 79137cce918SMarri Devender Rao certs::certInstallIntf, "Install", certFile->getCertFilePath()); 79237cce918SMarri Devender Rao } 79337cce918SMarri Devender Rao }; // LDAPCertificateCollection 79437cce918SMarri Devender Rao 79537cce918SMarri Devender Rao /** 79637cce918SMarri Devender Rao * Certificate resource describes a certificate used to prove the identity 79737cce918SMarri Devender Rao * of a component, account or service. 79837cce918SMarri Devender Rao */ 79937cce918SMarri Devender Rao class LDAPCertificate : public Node 80037cce918SMarri Devender Rao { 80137cce918SMarri Devender Rao public: 80237cce918SMarri Devender Rao template <typename CrowApp> 80337cce918SMarri Devender Rao LDAPCertificate(CrowApp &app) : 80437cce918SMarri Devender Rao Node(app, "/redfish/v1/AccountService/LDAP/Certificates/<str>/", 80537cce918SMarri Devender Rao std::string()) 80637cce918SMarri Devender Rao { 80737cce918SMarri Devender Rao entityPrivileges = { 80837cce918SMarri Devender Rao {boost::beast::http::verb::get, {{"Login"}}}, 80937cce918SMarri Devender Rao {boost::beast::http::verb::head, {{"Login"}}}, 81037cce918SMarri Devender Rao {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 81137cce918SMarri Devender Rao {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 81237cce918SMarri Devender Rao {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 81337cce918SMarri Devender Rao {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 81437cce918SMarri Devender Rao } 81537cce918SMarri Devender Rao 81637cce918SMarri Devender Rao void doGet(crow::Response &res, const crow::Request &req, 81737cce918SMarri Devender Rao const std::vector<std::string> ¶ms) override 81837cce918SMarri Devender Rao { 81937cce918SMarri Devender Rao auto asyncResp = std::make_shared<AsyncResp>(res); 82037cce918SMarri Devender Rao long id = getIDFromURL(req.url); 82137cce918SMarri Devender Rao if (id < 0) 82237cce918SMarri Devender Rao { 82337cce918SMarri Devender Rao BMCWEB_LOG_ERROR << "Invalid url value" << req.url; 82437cce918SMarri Devender Rao messages::internalError(asyncResp->res); 82537cce918SMarri Devender Rao return; 82637cce918SMarri Devender Rao } 82737cce918SMarri Devender Rao BMCWEB_LOG_DEBUG << "LDAP Certificate ID=" << std::to_string(id); 82837cce918SMarri Devender Rao std::string certURL = "/redfish/v1/AccountService/LDAP/Certificates/" + 82937cce918SMarri Devender Rao std::to_string(id); 83037cce918SMarri Devender Rao std::string objectPath = certs::ldapObjectPath; 83137cce918SMarri Devender Rao objectPath += "/"; 83237cce918SMarri Devender Rao objectPath += std::to_string(id); 83337cce918SMarri Devender Rao getCertificateProperties(asyncResp, objectPath, certs::ldapServiceName, 83437cce918SMarri Devender Rao id, certURL, "LDAP Certificate"); 83537cce918SMarri Devender Rao } 83637cce918SMarri Devender Rao }; // LDAPCertificate 8375968caeeSMarri Devender Rao } // namespace redfish 838