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"; 35*37cce918SMarri Devender Rao constexpr char const *ldapObjectPath = "/xyz/openbmc_project/certs/client/ldap"; 36*37cce918SMarri Devender Rao constexpr char const *httpsServiceName = 37*37cce918SMarri Devender Rao "xyz.openbmc_project.Certs.Manager.Server.Https"; 38*37cce918SMarri Devender Rao constexpr char const *ldapServiceName = 39*37cce918SMarri 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 88*37cce918SMarri 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); 107*37cce918SMarri 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, 246*37cce918SMarri Devender Rao const std::string &service, long certId, const std::string &certURL, 247*37cce918SMarri 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( 255*37cce918SMarri 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; 2605968caeeSMarri Devender Rao messages::internalError(asyncResp->res); 2615968caeeSMarri Devender Rao return; 2625968caeeSMarri Devender Rao } 2635968caeeSMarri Devender Rao asyncResp->res.jsonValue = { 2645968caeeSMarri Devender Rao {"@odata.id", certURL}, 2655968caeeSMarri Devender Rao {"@odata.type", "#Certificate.v1_0_0.Certificate"}, 2665968caeeSMarri Devender Rao {"@odata.context", 2675968caeeSMarri Devender Rao "/redfish/v1/$metadata#Certificate.Certificate"}, 2685968caeeSMarri Devender Rao {"Id", std::to_string(certId)}, 2695968caeeSMarri Devender Rao {"Name", name}, 2705968caeeSMarri Devender Rao {"Description", name}}; 2715968caeeSMarri Devender Rao for (const auto &property : properties) 2725968caeeSMarri Devender Rao { 2735968caeeSMarri Devender Rao if (property.first == "CertificateString") 2745968caeeSMarri Devender Rao { 2755968caeeSMarri Devender Rao asyncResp->res.jsonValue["CertificateString"] = ""; 2765968caeeSMarri Devender Rao const std::string *value = 2775968caeeSMarri Devender Rao std::get_if<std::string>(&property.second); 2785968caeeSMarri Devender Rao if (value) 2795968caeeSMarri Devender Rao { 280*37cce918SMarri Devender Rao asyncResp->res.jsonValue["CertificateString"] = *value; 2815968caeeSMarri Devender Rao } 2825968caeeSMarri Devender Rao } 2835968caeeSMarri Devender Rao else if (property.first == "KeyUsage") 2845968caeeSMarri Devender Rao { 2855968caeeSMarri Devender Rao nlohmann::json &keyUsage = 2865968caeeSMarri Devender Rao asyncResp->res.jsonValue["KeyUsage"]; 2875968caeeSMarri Devender Rao keyUsage = nlohmann::json::array(); 2885968caeeSMarri Devender Rao const std::vector<std::string> *value = 289*37cce918SMarri Devender Rao std::get_if<std::vector<std::string>>(&property.second); 2905968caeeSMarri Devender Rao if (value) 2915968caeeSMarri Devender Rao { 2925968caeeSMarri Devender Rao for (const std::string &usage : *value) 2935968caeeSMarri Devender Rao { 2945968caeeSMarri Devender Rao keyUsage.push_back(usage); 2955968caeeSMarri Devender Rao } 2965968caeeSMarri Devender Rao } 2975968caeeSMarri Devender Rao } 2985968caeeSMarri Devender Rao else if (property.first == "Issuer") 2995968caeeSMarri Devender Rao { 3005968caeeSMarri Devender Rao const std::string *value = 3015968caeeSMarri Devender Rao std::get_if<std::string>(&property.second); 3025968caeeSMarri Devender Rao if (value) 3035968caeeSMarri Devender Rao { 3045968caeeSMarri Devender Rao updateCertIssuerOrSubject( 3055968caeeSMarri Devender Rao asyncResp->res.jsonValue["Issuer"], *value); 3065968caeeSMarri Devender Rao } 3075968caeeSMarri Devender Rao } 3085968caeeSMarri Devender Rao else if (property.first == "Subject") 3095968caeeSMarri Devender Rao { 3105968caeeSMarri Devender Rao const std::string *value = 3115968caeeSMarri Devender Rao std::get_if<std::string>(&property.second); 3125968caeeSMarri Devender Rao if (value) 3135968caeeSMarri Devender Rao { 3145968caeeSMarri Devender Rao updateCertIssuerOrSubject( 315*37cce918SMarri Devender Rao asyncResp->res.jsonValue["Subject"], *value); 3165968caeeSMarri Devender Rao } 3175968caeeSMarri Devender Rao } 3185968caeeSMarri Devender Rao else if (property.first == "ValidNotAfter") 3195968caeeSMarri Devender Rao { 3205968caeeSMarri Devender Rao const uint64_t *value = 3215968caeeSMarri Devender Rao std::get_if<uint64_t>(&property.second); 3225968caeeSMarri Devender Rao if (value) 3235968caeeSMarri Devender Rao { 324*37cce918SMarri Devender Rao std::time_t time = static_cast<std::time_t>(*value); 3255968caeeSMarri Devender Rao asyncResp->res.jsonValue["ValidNotAfter"] = 3265968caeeSMarri Devender Rao crow::utility::getDateTime(time); 3275968caeeSMarri Devender Rao } 3285968caeeSMarri Devender Rao } 3295968caeeSMarri Devender Rao else if (property.first == "ValidNotBefore") 3305968caeeSMarri Devender Rao { 3315968caeeSMarri Devender Rao const uint64_t *value = 3325968caeeSMarri Devender Rao std::get_if<uint64_t>(&property.second); 3335968caeeSMarri Devender Rao if (value) 3345968caeeSMarri Devender Rao { 335*37cce918SMarri Devender Rao std::time_t time = static_cast<std::time_t>(*value); 3365968caeeSMarri Devender Rao asyncResp->res.jsonValue["ValidNotBefore"] = 3375968caeeSMarri Devender Rao crow::utility::getDateTime(time); 3385968caeeSMarri Devender Rao } 3395968caeeSMarri Devender Rao } 3405968caeeSMarri Devender Rao } 3415968caeeSMarri Devender Rao asyncResp->res.addHeader("Location", certURL); 3425968caeeSMarri Devender Rao }, 3435968caeeSMarri Devender Rao service, objectPath, certs::dbusPropIntf, "GetAll", 3445968caeeSMarri Devender Rao certs::certPropIntf); 3455968caeeSMarri Devender Rao } 3465968caeeSMarri Devender Rao 3475968caeeSMarri Devender Rao using GetObjectType = 3485968caeeSMarri Devender Rao std::vector<std::pair<std::string, std::vector<std::string>>>; 3495968caeeSMarri Devender Rao 3505968caeeSMarri Devender Rao /** 3515968caeeSMarri Devender Rao * Action to replace an existing certificate 3525968caeeSMarri Devender Rao */ 3535968caeeSMarri Devender Rao class CertificateActionsReplaceCertificate : public Node 3545968caeeSMarri Devender Rao { 3555968caeeSMarri Devender Rao public: 3565968caeeSMarri Devender Rao CertificateActionsReplaceCertificate(CrowApp &app) : 3575968caeeSMarri Devender Rao Node(app, "/redfish/v1/CertificateService/Actions/" 3585968caeeSMarri Devender Rao "CertificateService.ReplaceCertificate/") 3595968caeeSMarri Devender Rao { 3605968caeeSMarri Devender Rao entityPrivileges = { 3615968caeeSMarri Devender Rao {boost::beast::http::verb::get, {{"Login"}}}, 3625968caeeSMarri Devender Rao {boost::beast::http::verb::head, {{"Login"}}}, 3635968caeeSMarri Devender Rao {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 3645968caeeSMarri Devender Rao {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 3655968caeeSMarri Devender Rao {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 3665968caeeSMarri Devender Rao {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 3675968caeeSMarri Devender Rao } 3685968caeeSMarri Devender Rao 3695968caeeSMarri Devender Rao private: 3705968caeeSMarri Devender Rao void doPost(crow::Response &res, const crow::Request &req, 3715968caeeSMarri Devender Rao const std::vector<std::string> ¶ms) override 3725968caeeSMarri Devender Rao { 3735968caeeSMarri Devender Rao std::string certificate; 3745968caeeSMarri Devender Rao nlohmann::json certificateUri; 3755968caeeSMarri Devender Rao std::optional<std::string> certificateType = "PEM"; 3765968caeeSMarri Devender Rao auto asyncResp = std::make_shared<AsyncResp>(res); 3775968caeeSMarri Devender Rao if (!json_util::readJson(req, asyncResp->res, "CertificateString", 3785968caeeSMarri Devender Rao certificate, "CertificateUri", certificateUri, 3795968caeeSMarri Devender Rao "CertificateType", certificateType)) 3805968caeeSMarri Devender Rao { 3815968caeeSMarri Devender Rao BMCWEB_LOG_ERROR << "Required parameters are missing"; 3825968caeeSMarri Devender Rao messages::internalError(asyncResp->res); 3835968caeeSMarri Devender Rao return; 3845968caeeSMarri Devender Rao } 3855968caeeSMarri Devender Rao 3865968caeeSMarri Devender Rao if (!certificateType) 3875968caeeSMarri Devender Rao { 3885968caeeSMarri Devender Rao // should never happen, but it never hurts to be paranoid. 3895968caeeSMarri Devender Rao return; 3905968caeeSMarri Devender Rao } 3915968caeeSMarri Devender Rao if (certificateType != "PEM") 3925968caeeSMarri Devender Rao { 3935968caeeSMarri Devender Rao messages::actionParameterNotSupported( 3945968caeeSMarri Devender Rao asyncResp->res, "CertificateType", "ReplaceCertificate"); 3955968caeeSMarri Devender Rao return; 3965968caeeSMarri Devender Rao } 3975968caeeSMarri Devender Rao 3985968caeeSMarri Devender Rao std::string certURI; 3995968caeeSMarri Devender Rao if (!redfish::json_util::readJson(certificateUri, asyncResp->res, 4005968caeeSMarri Devender Rao "@odata.id", certURI)) 4015968caeeSMarri Devender Rao { 4025968caeeSMarri Devender Rao messages::actionParameterMissing( 4035968caeeSMarri Devender Rao asyncResp->res, "ReplaceCertificate", "CertificateUri"); 4045968caeeSMarri Devender Rao return; 4055968caeeSMarri Devender Rao } 4065968caeeSMarri Devender Rao 4075968caeeSMarri Devender Rao BMCWEB_LOG_INFO << "Certificate URI to replace" << certURI; 4085968caeeSMarri Devender Rao long id = getIDFromURL(certURI); 4095968caeeSMarri Devender Rao if (id < 0) 4105968caeeSMarri Devender Rao { 4115968caeeSMarri Devender Rao messages::actionParameterValueFormatError(asyncResp->res, certURI, 4125968caeeSMarri Devender Rao "CertificateUri", 4135968caeeSMarri Devender Rao "ReplaceCertificate"); 4145968caeeSMarri Devender Rao return; 4155968caeeSMarri Devender Rao } 4165968caeeSMarri Devender Rao std::string objectPath; 4175968caeeSMarri Devender Rao std::string name; 418*37cce918SMarri Devender Rao std::string service; 4195968caeeSMarri Devender Rao if (boost::starts_with( 4205968caeeSMarri Devender Rao certURI, 4215968caeeSMarri Devender Rao "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/")) 4225968caeeSMarri Devender Rao { 4235968caeeSMarri Devender Rao objectPath = 4245968caeeSMarri Devender Rao std::string(certs::httpsObjectPath) + "/" + std::to_string(id); 4255968caeeSMarri Devender Rao name = "HTTPS certificate"; 426*37cce918SMarri Devender Rao service = certs::httpsServiceName; 427*37cce918SMarri Devender Rao } 428*37cce918SMarri Devender Rao else if (boost::starts_with( 429*37cce918SMarri Devender Rao certURI, "/redfish/v1/AccountService/LDAP/Certificates/")) 430*37cce918SMarri Devender Rao { 431*37cce918SMarri Devender Rao objectPath = 432*37cce918SMarri Devender Rao std::string(certs::ldapObjectPath) + "/" + std::to_string(id); 433*37cce918SMarri Devender Rao name = "LDAP certificate"; 434*37cce918SMarri Devender Rao service = certs::ldapServiceName; 4355968caeeSMarri Devender Rao } 4365968caeeSMarri Devender Rao else 4375968caeeSMarri Devender Rao { 4385968caeeSMarri Devender Rao messages::actionParameterNotSupported( 4395968caeeSMarri Devender Rao asyncResp->res, "CertificateUri", "ReplaceCertificate"); 4405968caeeSMarri Devender Rao return; 4415968caeeSMarri Devender Rao } 4425968caeeSMarri Devender Rao 4435968caeeSMarri Devender Rao std::shared_ptr<CertificateFile> certFile = 4445968caeeSMarri Devender Rao std::make_shared<CertificateFile>(certificate); 4455968caeeSMarri Devender Rao crow::connections::systemBus->async_method_call( 446*37cce918SMarri Devender Rao [asyncResp, certFile, objectPath, service, certURI, id, 4475968caeeSMarri Devender Rao name](const boost::system::error_code ec) { 4485968caeeSMarri Devender Rao if (ec) 4495968caeeSMarri Devender Rao { 4505968caeeSMarri Devender Rao BMCWEB_LOG_ERROR << "DBUS response error: " << ec; 4515968caeeSMarri Devender Rao messages::internalError(asyncResp->res); 4525968caeeSMarri Devender Rao return; 4535968caeeSMarri Devender Rao } 454*37cce918SMarri Devender Rao getCertificateProperties(asyncResp, objectPath, service, id, 4555968caeeSMarri Devender Rao certURI, name); 4565968caeeSMarri Devender Rao BMCWEB_LOG_DEBUG << "HTTPS certificate install file=" 4575968caeeSMarri Devender Rao << certFile->getCertFilePath(); 4585968caeeSMarri Devender Rao }, 4595968caeeSMarri Devender Rao service, objectPath, certs::certReplaceIntf, "Replace", 4605968caeeSMarri Devender Rao certFile->getCertFilePath()); 4615968caeeSMarri Devender Rao } 4625968caeeSMarri Devender Rao }; // CertificateActionsReplaceCertificate 4635968caeeSMarri Devender Rao 4645968caeeSMarri Devender Rao /** 4655968caeeSMarri Devender Rao * Certificate resource describes a certificate used to prove the identity 4665968caeeSMarri Devender Rao * of a component, account or service. 4675968caeeSMarri Devender Rao */ 4685968caeeSMarri Devender Rao class HTTPSCertificate : public Node 4695968caeeSMarri Devender Rao { 4705968caeeSMarri Devender Rao public: 4715968caeeSMarri Devender Rao template <typename CrowApp> 4725968caeeSMarri Devender Rao HTTPSCertificate(CrowApp &app) : 4735968caeeSMarri Devender Rao Node(app, 4745968caeeSMarri Devender Rao "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/" 4755968caeeSMarri Devender Rao "<str>/", 4765968caeeSMarri Devender Rao std::string()) 4775968caeeSMarri Devender Rao { 4785968caeeSMarri Devender Rao entityPrivileges = { 4795968caeeSMarri Devender Rao {boost::beast::http::verb::get, {{"Login"}}}, 4805968caeeSMarri Devender Rao {boost::beast::http::verb::head, {{"Login"}}}, 4815968caeeSMarri Devender Rao {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 4825968caeeSMarri Devender Rao {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 4835968caeeSMarri Devender Rao {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 4845968caeeSMarri Devender Rao {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 4855968caeeSMarri Devender Rao } 4865968caeeSMarri Devender Rao 4875968caeeSMarri Devender Rao void doGet(crow::Response &res, const crow::Request &req, 4885968caeeSMarri Devender Rao const std::vector<std::string> ¶ms) override 4895968caeeSMarri Devender Rao { 4905968caeeSMarri Devender Rao auto asyncResp = std::make_shared<AsyncResp>(res); 4915968caeeSMarri Devender Rao if (params.size() != 1) 4925968caeeSMarri Devender Rao { 4935968caeeSMarri Devender Rao messages::internalError(asyncResp->res); 4945968caeeSMarri Devender Rao return; 4955968caeeSMarri Devender Rao } 4965968caeeSMarri Devender Rao long id = getIDFromURL(req.url); 4975968caeeSMarri Devender Rao 4985968caeeSMarri Devender Rao BMCWEB_LOG_DEBUG << "HTTPSCertificate::doGet ID=" << std::to_string(id); 4995968caeeSMarri Devender Rao std::string certURL = 5005968caeeSMarri Devender Rao "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/" + 5015968caeeSMarri Devender Rao std::to_string(id); 5025968caeeSMarri Devender Rao std::string objectPath = certs::httpsObjectPath; 5035968caeeSMarri Devender Rao objectPath += "/"; 5045968caeeSMarri Devender Rao objectPath += std::to_string(id); 505*37cce918SMarri Devender Rao getCertificateProperties(asyncResp, objectPath, certs::httpsServiceName, 506*37cce918SMarri Devender Rao id, certURL, "HTTPS Certificate"); 5075968caeeSMarri Devender Rao } 5085968caeeSMarri Devender Rao 5095968caeeSMarri Devender Rao }; // namespace redfish 5105968caeeSMarri Devender Rao 5115968caeeSMarri Devender Rao /** 5125968caeeSMarri Devender Rao * Collection of HTTPS certificates 5135968caeeSMarri Devender Rao */ 5145968caeeSMarri Devender Rao class HTTPSCertificateCollection : public Node 5155968caeeSMarri Devender Rao { 5165968caeeSMarri Devender Rao public: 5175968caeeSMarri Devender Rao template <typename CrowApp> 5185968caeeSMarri Devender Rao HTTPSCertificateCollection(CrowApp &app) : 5195968caeeSMarri Devender Rao Node(app, 5205968caeeSMarri Devender Rao "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/") 5215968caeeSMarri Devender Rao { 5225968caeeSMarri Devender Rao entityPrivileges = { 5235968caeeSMarri Devender Rao {boost::beast::http::verb::get, {{"Login"}}}, 5245968caeeSMarri Devender Rao {boost::beast::http::verb::head, {{"Login"}}}, 5255968caeeSMarri Devender Rao {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 5265968caeeSMarri Devender Rao {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 5275968caeeSMarri Devender Rao {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 5285968caeeSMarri Devender Rao {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 5295968caeeSMarri Devender Rao } 5305968caeeSMarri Devender Rao void doGet(crow::Response &res, const crow::Request &req, 5315968caeeSMarri Devender Rao const std::vector<std::string> ¶ms) override 5325968caeeSMarri Devender Rao { 5335968caeeSMarri Devender Rao res.jsonValue = { 5345968caeeSMarri Devender Rao {"@odata.id", 5355968caeeSMarri Devender Rao "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates"}, 5365968caeeSMarri Devender Rao {"@odata.type", "#CertificateCollection.CertificateCollection"}, 5375968caeeSMarri Devender Rao {"@odata.context", 5385968caeeSMarri Devender Rao "/redfish/v1/" 5395968caeeSMarri Devender Rao "$metadata#CertificateCollection.CertificateCollection"}, 5405968caeeSMarri Devender Rao {"Name", "HTTPS Certificates Collection"}, 5415968caeeSMarri Devender Rao {"Description", "A Collection of HTTPS certificate instances"}}; 5425968caeeSMarri Devender Rao auto asyncResp = std::make_shared<AsyncResp>(res); 5435968caeeSMarri Devender Rao crow::connections::systemBus->async_method_call( 5445968caeeSMarri Devender Rao [asyncResp](const boost::system::error_code ec, 5455968caeeSMarri Devender Rao const ManagedObjectType &certs) { 5465968caeeSMarri Devender Rao if (ec) 5475968caeeSMarri Devender Rao { 5485968caeeSMarri Devender Rao BMCWEB_LOG_ERROR << "DBUS response error: " << ec; 5495968caeeSMarri Devender Rao messages::internalError(asyncResp->res); 5505968caeeSMarri Devender Rao return; 5515968caeeSMarri Devender Rao } 552*37cce918SMarri Devender Rao nlohmann::json &members = asyncResp->res.jsonValue["Members"]; 5535968caeeSMarri Devender Rao members = nlohmann::json::array(); 5545968caeeSMarri Devender Rao for (const auto &cert : certs) 5555968caeeSMarri Devender Rao { 5565968caeeSMarri Devender Rao long id = getIDFromURL(cert.first.str); 557*37cce918SMarri Devender Rao if (id >= 0) 5585968caeeSMarri Devender Rao { 5595968caeeSMarri Devender Rao members.push_back( 5605968caeeSMarri Devender Rao {{"@odata.id", 5615968caeeSMarri Devender Rao "/redfish/v1/Managers/bmc/" 5625968caeeSMarri Devender Rao "NetworkProtocol/HTTPS/Certificates/" + 5635968caeeSMarri Devender Rao std::to_string(id)}}); 5645968caeeSMarri Devender Rao } 5655968caeeSMarri Devender Rao } 5665968caeeSMarri Devender Rao asyncResp->res.jsonValue["Members@odata.count"] = 5675968caeeSMarri Devender Rao members.size(); 5685968caeeSMarri Devender Rao }, 569*37cce918SMarri Devender Rao certs::httpsServiceName, certs::httpsObjectPath, 570*37cce918SMarri Devender Rao certs::dbusObjManagerIntf, "GetManagedObjects"); 5715968caeeSMarri Devender Rao } 5725968caeeSMarri Devender Rao 5735968caeeSMarri Devender Rao void doPost(crow::Response &res, const crow::Request &req, 5745968caeeSMarri Devender Rao const std::vector<std::string> ¶ms) override 5755968caeeSMarri Devender Rao { 5765968caeeSMarri Devender Rao BMCWEB_LOG_DEBUG << "HTTPSCertificateCollection::doPost"; 5775968caeeSMarri Devender Rao auto asyncResp = std::make_shared<AsyncResp>(res); 5785968caeeSMarri Devender Rao asyncResp->res.jsonValue = {{"Name", "HTTPS Certificate"}, 5795968caeeSMarri Devender Rao {"Description", "HTTPS Certificate"}}; 5805968caeeSMarri Devender Rao 5815968caeeSMarri Devender Rao std::shared_ptr<CertificateFile> certFile = 5825968caeeSMarri Devender Rao std::make_shared<CertificateFile>(req.body); 5835968caeeSMarri Devender Rao 5845968caeeSMarri Devender Rao crow::connections::systemBus->async_method_call( 5855968caeeSMarri Devender Rao [asyncResp, certFile](const boost::system::error_code ec) { 5865968caeeSMarri Devender Rao if (ec) 5875968caeeSMarri Devender Rao { 5885968caeeSMarri Devender Rao BMCWEB_LOG_ERROR << "DBUS response error: " << ec; 5895968caeeSMarri Devender Rao messages::internalError(asyncResp->res); 5905968caeeSMarri Devender Rao return; 5915968caeeSMarri Devender Rao } 5925968caeeSMarri Devender Rao // TODO: Issue#84 supporting only 1 certificate 5935968caeeSMarri Devender Rao long certId = 1; 5945968caeeSMarri Devender Rao std::string certURL = 5955968caeeSMarri Devender Rao "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/" 5965968caeeSMarri Devender Rao "Certificates/" + 5975968caeeSMarri Devender Rao std::to_string(certId); 598*37cce918SMarri Devender Rao std::string objectPath = std::string(certs::httpsObjectPath) + 599*37cce918SMarri Devender Rao "/" + std::to_string(certId); 600*37cce918SMarri Devender Rao getCertificateProperties(asyncResp, objectPath, 601*37cce918SMarri Devender Rao certs::httpsServiceName, certId, 6025968caeeSMarri Devender Rao certURL, "HTTPS Certificate"); 6035968caeeSMarri Devender Rao BMCWEB_LOG_DEBUG << "HTTPS certificate install file=" 6045968caeeSMarri Devender Rao << certFile->getCertFilePath(); 6055968caeeSMarri Devender Rao }, 606*37cce918SMarri Devender Rao certs::httpsServiceName, certs::httpsObjectPath, 607*37cce918SMarri Devender Rao certs::certInstallIntf, "Install", certFile->getCertFilePath()); 6085968caeeSMarri Devender Rao } 6095968caeeSMarri Devender Rao }; // HTTPSCertificateCollection 6105968caeeSMarri Devender Rao 6115968caeeSMarri Devender Rao /** 6125968caeeSMarri Devender Rao * The certificate location schema defines a resource that an administrator 6135968caeeSMarri Devender Rao * can use in order to locate all certificates installed on a given service. 6145968caeeSMarri Devender Rao */ 6155968caeeSMarri Devender Rao class CertificateLocations : public Node 6165968caeeSMarri Devender Rao { 6175968caeeSMarri Devender Rao public: 6185968caeeSMarri Devender Rao template <typename CrowApp> 6195968caeeSMarri Devender Rao CertificateLocations(CrowApp &app) : 6205968caeeSMarri Devender Rao Node(app, "/redfish/v1/CertificateService/CertificateLocations/") 6215968caeeSMarri Devender Rao { 6225968caeeSMarri Devender Rao entityPrivileges = { 6235968caeeSMarri Devender Rao {boost::beast::http::verb::get, {{"Login"}}}, 6245968caeeSMarri Devender Rao {boost::beast::http::verb::head, {{"Login"}}}, 6255968caeeSMarri Devender Rao {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 6265968caeeSMarri Devender Rao {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 6275968caeeSMarri Devender Rao {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 6285968caeeSMarri Devender Rao {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 6295968caeeSMarri Devender Rao } 6305968caeeSMarri Devender Rao 6315968caeeSMarri Devender Rao private: 6325968caeeSMarri Devender Rao void doGet(crow::Response &res, const crow::Request &req, 6335968caeeSMarri Devender Rao const std::vector<std::string> ¶ms) override 6345968caeeSMarri Devender Rao { 6355968caeeSMarri Devender Rao res.jsonValue = { 6365968caeeSMarri Devender Rao {"@odata.id", 6375968caeeSMarri Devender Rao "/redfish/v1/CertificateService/CertificateLocations"}, 6385968caeeSMarri Devender Rao {"@odata.type", 6395968caeeSMarri Devender Rao "#CertificateLocations.v1_0_0.CertificateLocations"}, 6405968caeeSMarri Devender Rao {"@odata.context", 6415968caeeSMarri Devender Rao "/redfish/v1/$metadata#CertificateLocations.CertificateLocations"}, 6425968caeeSMarri Devender Rao {"Name", "Certificate Locations"}, 6435968caeeSMarri Devender Rao {"Id", "CertificateLocations"}, 6445968caeeSMarri Devender Rao {"Description", 6455968caeeSMarri Devender Rao "Defines a resource that an administrator can use in order to " 6465968caeeSMarri Devender Rao "locate all certificates installed on a given service"}}; 6475968caeeSMarri Devender Rao auto asyncResp = std::make_shared<AsyncResp>(res); 6485968caeeSMarri Devender Rao nlohmann::json &links = 6495968caeeSMarri Devender Rao asyncResp->res.jsonValue["Links"]["Certificates"]; 6505968caeeSMarri Devender Rao links = nlohmann::json::array(); 6515968caeeSMarri Devender Rao getCertificateLocations( 6525968caeeSMarri Devender Rao asyncResp, 6535968caeeSMarri Devender Rao "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/", 654*37cce918SMarri Devender Rao certs::httpsObjectPath, certs::httpsServiceName); 655*37cce918SMarri Devender Rao getCertificateLocations(asyncResp, 656*37cce918SMarri Devender Rao "/redfish/v1/AccountService/LDAP/Certificates/", 657*37cce918SMarri Devender Rao certs::ldapObjectPath, certs::ldapServiceName); 658*37cce918SMarri Devender Rao } 659*37cce918SMarri Devender Rao /** 660*37cce918SMarri Devender Rao * @brief Retrieve the certificates installed list and append to the 661*37cce918SMarri Devender Rao * response 662*37cce918SMarri Devender Rao * 663*37cce918SMarri Devender Rao * @param[in] asyncResp Shared pointer to the response message 664*37cce918SMarri Devender Rao * @param[in] certURL Path of the certificate object 665*37cce918SMarri Devender Rao * @param[in] path Path of the D-Bus service object 666*37cce918SMarri Devender Rao * @return None 667*37cce918SMarri Devender Rao */ 668*37cce918SMarri Devender Rao void getCertificateLocations(std::shared_ptr<AsyncResp> &asyncResp, 669*37cce918SMarri Devender Rao const std::string &certURL, 670*37cce918SMarri Devender Rao const std::string &path, 671*37cce918SMarri Devender Rao const std::string &service) 672*37cce918SMarri Devender Rao { 673*37cce918SMarri Devender Rao BMCWEB_LOG_DEBUG << "getCertificateLocations URI=" << certURL 674*37cce918SMarri Devender Rao << " Path=" << path << " service= " << service; 675*37cce918SMarri Devender Rao crow::connections::systemBus->async_method_call( 676*37cce918SMarri Devender Rao [asyncResp, certURL](const boost::system::error_code ec, 677*37cce918SMarri Devender Rao const ManagedObjectType &certs) { 678*37cce918SMarri Devender Rao if (ec) 679*37cce918SMarri Devender Rao { 680*37cce918SMarri Devender Rao BMCWEB_LOG_ERROR << "DBUS response error: " << ec; 681*37cce918SMarri Devender Rao messages::internalError(asyncResp->res); 682*37cce918SMarri Devender Rao return; 683*37cce918SMarri Devender Rao } 684*37cce918SMarri Devender Rao nlohmann::json &links = 685*37cce918SMarri Devender Rao asyncResp->res.jsonValue["Links"]["Certificates"]; 686*37cce918SMarri Devender Rao for (auto &cert : certs) 687*37cce918SMarri Devender Rao { 688*37cce918SMarri Devender Rao long id = getIDFromURL(cert.first.str); 689*37cce918SMarri Devender Rao if (id >= 0) 690*37cce918SMarri Devender Rao { 691*37cce918SMarri Devender Rao links.push_back( 692*37cce918SMarri Devender Rao {{"@odata.id", certURL + std::to_string(id)}}); 693*37cce918SMarri Devender Rao } 694*37cce918SMarri Devender Rao } 695*37cce918SMarri Devender Rao asyncResp->res.jsonValue["Links"]["Certificates@odata.count"] = 696*37cce918SMarri Devender Rao links.size(); 697*37cce918SMarri Devender Rao }, 698*37cce918SMarri Devender Rao service, path, certs::dbusObjManagerIntf, "GetManagedObjects"); 6995968caeeSMarri Devender Rao } 7005968caeeSMarri Devender Rao }; // CertificateLocations 701*37cce918SMarri Devender Rao 702*37cce918SMarri Devender Rao /** 703*37cce918SMarri Devender Rao * Collection of LDAP certificates 704*37cce918SMarri Devender Rao */ 705*37cce918SMarri Devender Rao class LDAPCertificateCollection : public Node 706*37cce918SMarri Devender Rao { 707*37cce918SMarri Devender Rao public: 708*37cce918SMarri Devender Rao template <typename CrowApp> 709*37cce918SMarri Devender Rao LDAPCertificateCollection(CrowApp &app) : 710*37cce918SMarri Devender Rao Node(app, "/redfish/v1/AccountService/LDAP/Certificates/") 711*37cce918SMarri Devender Rao { 712*37cce918SMarri Devender Rao entityPrivileges = { 713*37cce918SMarri Devender Rao {boost::beast::http::verb::get, {{"Login"}}}, 714*37cce918SMarri Devender Rao {boost::beast::http::verb::head, {{"Login"}}}, 715*37cce918SMarri Devender Rao {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 716*37cce918SMarri Devender Rao {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 717*37cce918SMarri Devender Rao {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 718*37cce918SMarri Devender Rao {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 719*37cce918SMarri Devender Rao } 720*37cce918SMarri Devender Rao void doGet(crow::Response &res, const crow::Request &req, 721*37cce918SMarri Devender Rao const std::vector<std::string> ¶ms) override 722*37cce918SMarri Devender Rao { 723*37cce918SMarri Devender Rao res.jsonValue = { 724*37cce918SMarri Devender Rao {"@odata.id", "/redfish/v1/AccountService/LDAP/Certificates"}, 725*37cce918SMarri Devender Rao {"@odata.type", "#CertificateCollection.CertificateCollection"}, 726*37cce918SMarri Devender Rao {"@odata.context", 727*37cce918SMarri Devender Rao "/redfish/v1/" 728*37cce918SMarri Devender Rao "$metadata#CertificateCollection.CertificateCollection"}, 729*37cce918SMarri Devender Rao {"Name", "LDAP Certificates Collection"}, 730*37cce918SMarri Devender Rao {"Description", "A Collection of LDAP certificate instances"}}; 731*37cce918SMarri Devender Rao auto asyncResp = std::make_shared<AsyncResp>(res); 732*37cce918SMarri Devender Rao crow::connections::systemBus->async_method_call( 733*37cce918SMarri Devender Rao [asyncResp](const boost::system::error_code ec, 734*37cce918SMarri Devender Rao const ManagedObjectType &certs) { 735*37cce918SMarri Devender Rao if (ec) 736*37cce918SMarri Devender Rao { 737*37cce918SMarri Devender Rao BMCWEB_LOG_ERROR << "DBUS response error: " << ec; 738*37cce918SMarri Devender Rao messages::internalError(asyncResp->res); 739*37cce918SMarri Devender Rao return; 740*37cce918SMarri Devender Rao } 741*37cce918SMarri Devender Rao nlohmann::json &members = asyncResp->res.jsonValue["Members"]; 742*37cce918SMarri Devender Rao members = nlohmann::json::array(); 743*37cce918SMarri Devender Rao for (const auto &cert : certs) 744*37cce918SMarri Devender Rao { 745*37cce918SMarri Devender Rao long id = getIDFromURL(cert.first.str); 746*37cce918SMarri Devender Rao if (id >= 0) 747*37cce918SMarri Devender Rao { 748*37cce918SMarri Devender Rao members.push_back( 749*37cce918SMarri Devender Rao {{"@odata.id", "/redfish/v1/AccountService/" 750*37cce918SMarri Devender Rao "LDAP/Certificates/" + 751*37cce918SMarri Devender Rao std::to_string(id)}}); 752*37cce918SMarri Devender Rao } 753*37cce918SMarri Devender Rao } 754*37cce918SMarri Devender Rao asyncResp->res.jsonValue["Members@odata.count"] = 755*37cce918SMarri Devender Rao members.size(); 756*37cce918SMarri Devender Rao }, 757*37cce918SMarri Devender Rao certs::ldapServiceName, certs::ldapObjectPath, 758*37cce918SMarri Devender Rao certs::dbusObjManagerIntf, "GetManagedObjects"); 759*37cce918SMarri Devender Rao } 760*37cce918SMarri Devender Rao 761*37cce918SMarri Devender Rao void doPost(crow::Response &res, const crow::Request &req, 762*37cce918SMarri Devender Rao const std::vector<std::string> ¶ms) override 763*37cce918SMarri Devender Rao { 764*37cce918SMarri Devender Rao std::shared_ptr<CertificateFile> certFile = 765*37cce918SMarri Devender Rao std::make_shared<CertificateFile>(req.body); 766*37cce918SMarri Devender Rao auto asyncResp = std::make_shared<AsyncResp>(res); 767*37cce918SMarri Devender Rao crow::connections::systemBus->async_method_call( 768*37cce918SMarri Devender Rao [asyncResp, certFile](const boost::system::error_code ec) { 769*37cce918SMarri Devender Rao if (ec) 770*37cce918SMarri Devender Rao { 771*37cce918SMarri Devender Rao BMCWEB_LOG_ERROR << "DBUS response error: " << ec; 772*37cce918SMarri Devender Rao messages::internalError(asyncResp->res); 773*37cce918SMarri Devender Rao return; 774*37cce918SMarri Devender Rao } 775*37cce918SMarri Devender Rao //// TODO: Issue#84 supporting only 1 certificate 776*37cce918SMarri Devender Rao long certId = 1; 777*37cce918SMarri Devender Rao std::string certURL = 778*37cce918SMarri Devender Rao "/redfish/v1/AccountService/LDAP/Certificates/" + 779*37cce918SMarri Devender Rao std::to_string(certId); 780*37cce918SMarri Devender Rao std::string objectPath = std::string(certs::ldapObjectPath) + 781*37cce918SMarri Devender Rao "/" + std::to_string(certId); 782*37cce918SMarri Devender Rao getCertificateProperties(asyncResp, objectPath, 783*37cce918SMarri Devender Rao certs::ldapServiceName, certId, 784*37cce918SMarri Devender Rao certURL, "LDAP Certificate"); 785*37cce918SMarri Devender Rao BMCWEB_LOG_DEBUG << "LDAP certificate install file=" 786*37cce918SMarri Devender Rao << certFile->getCertFilePath(); 787*37cce918SMarri Devender Rao }, 788*37cce918SMarri Devender Rao certs::ldapServiceName, certs::ldapObjectPath, 789*37cce918SMarri Devender Rao certs::certInstallIntf, "Install", certFile->getCertFilePath()); 790*37cce918SMarri Devender Rao } 791*37cce918SMarri Devender Rao }; // LDAPCertificateCollection 792*37cce918SMarri Devender Rao 793*37cce918SMarri Devender Rao /** 794*37cce918SMarri Devender Rao * Certificate resource describes a certificate used to prove the identity 795*37cce918SMarri Devender Rao * of a component, account or service. 796*37cce918SMarri Devender Rao */ 797*37cce918SMarri Devender Rao class LDAPCertificate : public Node 798*37cce918SMarri Devender Rao { 799*37cce918SMarri Devender Rao public: 800*37cce918SMarri Devender Rao template <typename CrowApp> 801*37cce918SMarri Devender Rao LDAPCertificate(CrowApp &app) : 802*37cce918SMarri Devender Rao Node(app, "/redfish/v1/AccountService/LDAP/Certificates/<str>/", 803*37cce918SMarri Devender Rao std::string()) 804*37cce918SMarri Devender Rao { 805*37cce918SMarri Devender Rao entityPrivileges = { 806*37cce918SMarri Devender Rao {boost::beast::http::verb::get, {{"Login"}}}, 807*37cce918SMarri Devender Rao {boost::beast::http::verb::head, {{"Login"}}}, 808*37cce918SMarri Devender Rao {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 809*37cce918SMarri Devender Rao {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 810*37cce918SMarri Devender Rao {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 811*37cce918SMarri Devender Rao {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 812*37cce918SMarri Devender Rao } 813*37cce918SMarri Devender Rao 814*37cce918SMarri Devender Rao void doGet(crow::Response &res, const crow::Request &req, 815*37cce918SMarri Devender Rao const std::vector<std::string> ¶ms) override 816*37cce918SMarri Devender Rao { 817*37cce918SMarri Devender Rao auto asyncResp = std::make_shared<AsyncResp>(res); 818*37cce918SMarri Devender Rao long id = getIDFromURL(req.url); 819*37cce918SMarri Devender Rao if (id < 0) 820*37cce918SMarri Devender Rao { 821*37cce918SMarri Devender Rao BMCWEB_LOG_ERROR << "Invalid url value" << req.url; 822*37cce918SMarri Devender Rao messages::internalError(asyncResp->res); 823*37cce918SMarri Devender Rao return; 824*37cce918SMarri Devender Rao } 825*37cce918SMarri Devender Rao BMCWEB_LOG_DEBUG << "LDAP Certificate ID=" << std::to_string(id); 826*37cce918SMarri Devender Rao std::string certURL = "/redfish/v1/AccountService/LDAP/Certificates/" + 827*37cce918SMarri Devender Rao std::to_string(id); 828*37cce918SMarri Devender Rao std::string objectPath = certs::ldapObjectPath; 829*37cce918SMarri Devender Rao objectPath += "/"; 830*37cce918SMarri Devender Rao objectPath += std::to_string(id); 831*37cce918SMarri Devender Rao getCertificateProperties(asyncResp, objectPath, certs::ldapServiceName, 832*37cce918SMarri Devender Rao id, certURL, "LDAP Certificate"); 833*37cce918SMarri Devender Rao } 834*37cce918SMarri Devender Rao }; // LDAPCertificate 8355968caeeSMarri Devender Rao } // namespace redfish 836