188d16c9aSLewanczyk, Dawid /* 288d16c9aSLewanczyk, Dawid // Copyright (c) 2018 Intel Corporation 388d16c9aSLewanczyk, Dawid // 488d16c9aSLewanczyk, Dawid // Licensed under the Apache License, Version 2.0 (the "License"); 588d16c9aSLewanczyk, Dawid // you may not use this file except in compliance with the License. 688d16c9aSLewanczyk, Dawid // You may obtain a copy of the License at 788d16c9aSLewanczyk, Dawid // 888d16c9aSLewanczyk, Dawid // http://www.apache.org/licenses/LICENSE-2.0 988d16c9aSLewanczyk, Dawid // 1088d16c9aSLewanczyk, Dawid // Unless required by applicable law or agreed to in writing, software 1188d16c9aSLewanczyk, Dawid // distributed under the License is distributed on an "AS IS" BASIS, 1288d16c9aSLewanczyk, Dawid // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1388d16c9aSLewanczyk, Dawid // See the License for the specific language governing permissions and 1488d16c9aSLewanczyk, Dawid // limitations under the License. 1588d16c9aSLewanczyk, Dawid */ 1688d16c9aSLewanczyk, Dawid #pragma once 1788d16c9aSLewanczyk, Dawid #include "node.hpp" 1888d16c9aSLewanczyk, Dawid 1965b0dc32SEd Tanous #include <error_messages.hpp> 20b9b2e0b2SEd Tanous #include <openbmc_dbus_rest.hpp> 21a840879dSEd Tanous #include <utils/json_utils.hpp> 22b9b2e0b2SEd Tanous 231abe55efSEd Tanous namespace redfish 241abe55efSEd Tanous { 2588d16c9aSLewanczyk, Dawid 26b9b2e0b2SEd Tanous using ManagedObjectType = std::vector<std::pair< 27b9b2e0b2SEd Tanous sdbusplus::message::object_path, 28b9b2e0b2SEd Tanous boost::container::flat_map< 29b9b2e0b2SEd Tanous std::string, boost::container::flat_map< 30b9b2e0b2SEd Tanous std::string, sdbusplus::message::variant<bool>>>>>; 31b9b2e0b2SEd Tanous 321abe55efSEd Tanous class AccountService : public Node 331abe55efSEd Tanous { 3488d16c9aSLewanczyk, Dawid public: 351abe55efSEd Tanous AccountService(CrowApp& app) : Node(app, "/redfish/v1/AccountService/") 361abe55efSEd Tanous { 37c1a46bd2SBorawski.Lukasz Node::json["@odata.id"] = "/redfish/v1/AccountService"; 38c1a46bd2SBorawski.Lukasz Node::json["@odata.type"] = "#AccountService.v1_1_0.AccountService"; 39c1a46bd2SBorawski.Lukasz Node::json["@odata.context"] = 4088d16c9aSLewanczyk, Dawid "/redfish/v1/$metadata#AccountService.AccountService"; 41c1a46bd2SBorawski.Lukasz Node::json["Id"] = "AccountService"; 42c1a46bd2SBorawski.Lukasz Node::json["Description"] = "BMC User Accounts"; 43c1a46bd2SBorawski.Lukasz Node::json["Name"] = "Account Service"; 44c1a46bd2SBorawski.Lukasz Node::json["ServiceEnabled"] = true; 45c1a46bd2SBorawski.Lukasz Node::json["MinPasswordLength"] = 1; 46c1a46bd2SBorawski.Lukasz Node::json["MaxPasswordLength"] = 20; 471abe55efSEd Tanous Node::json["Accounts"]["@odata.id"] = 481abe55efSEd Tanous "/redfish/v1/AccountService/Accounts"; 49c1a46bd2SBorawski.Lukasz Node::json["Roles"]["@odata.id"] = "/redfish/v1/AccountService/Roles"; 503ebd75f7SEd Tanous 513ebd75f7SEd Tanous entityPrivileges = { 524b1b8683SBorawski.Lukasz {boost::beast::http::verb::get, 534b1b8683SBorawski.Lukasz {{"ConfigureUsers"}, {"ConfigureManager"}}}, 54e0d918bcSEd Tanous {boost::beast::http::verb::head, {{"Login"}}}, 55e0d918bcSEd Tanous {boost::beast::http::verb::patch, {{"ConfigureUsers"}}}, 56e0d918bcSEd Tanous {boost::beast::http::verb::put, {{"ConfigureUsers"}}}, 57e0d918bcSEd Tanous {boost::beast::http::verb::delete_, {{"ConfigureUsers"}}}, 58e0d918bcSEd Tanous {boost::beast::http::verb::post, {{"ConfigureUsers"}}}}; 5988d16c9aSLewanczyk, Dawid } 6088d16c9aSLewanczyk, Dawid 6188d16c9aSLewanczyk, Dawid private: 6255c7b7a2SEd Tanous void doGet(crow::Response& res, const crow::Request& req, 631abe55efSEd Tanous const std::vector<std::string>& params) override 641abe55efSEd Tanous { 6555c7b7a2SEd Tanous res.jsonValue = Node::json; 6688d16c9aSLewanczyk, Dawid res.end(); 6788d16c9aSLewanczyk, Dawid } 6888d16c9aSLewanczyk, Dawid }; 69b9b2e0b2SEd Tanous class AccountsCollection : public Node 70b9b2e0b2SEd Tanous { 71b9b2e0b2SEd Tanous public: 72b9b2e0b2SEd Tanous AccountsCollection(CrowApp& app) : 73b9b2e0b2SEd Tanous Node(app, "/redfish/v1/AccountService/Accounts/") 74b9b2e0b2SEd Tanous { 75b9b2e0b2SEd Tanous 76b9b2e0b2SEd Tanous Node::json = {{"@odata.context", "/redfish/v1/" 77b9b2e0b2SEd Tanous "$metadata#ManagerAccountCollection." 78b9b2e0b2SEd Tanous "ManagerAccountCollection"}, 79b9b2e0b2SEd Tanous {"@odata.id", "/redfish/v1/AccountService/Accounts"}, 80b9b2e0b2SEd Tanous {"@odata.type", "#ManagerAccountCollection." 81b9b2e0b2SEd Tanous "ManagerAccountCollection"}, 82b9b2e0b2SEd Tanous {"Name", "Accounts Collection"}, 83b9b2e0b2SEd Tanous {"Description", "BMC User Accounts"}}; 84b9b2e0b2SEd Tanous 85b9b2e0b2SEd Tanous entityPrivileges = { 86b9b2e0b2SEd Tanous {boost::beast::http::verb::get, 87b9b2e0b2SEd Tanous {{"ConfigureUsers"}, {"ConfigureManager"}}}, 88b9b2e0b2SEd Tanous {boost::beast::http::verb::head, {{"Login"}}}, 89b9b2e0b2SEd Tanous {boost::beast::http::verb::patch, {{"ConfigureUsers"}}}, 90b9b2e0b2SEd Tanous {boost::beast::http::verb::put, {{"ConfigureUsers"}}}, 91b9b2e0b2SEd Tanous {boost::beast::http::verb::delete_, {{"ConfigureUsers"}}}, 92b9b2e0b2SEd Tanous {boost::beast::http::verb::post, {{"ConfigureUsers"}}}}; 93b9b2e0b2SEd Tanous } 94b9b2e0b2SEd Tanous 95b9b2e0b2SEd Tanous private: 96b9b2e0b2SEd Tanous void doGet(crow::Response& res, const crow::Request& req, 97b9b2e0b2SEd Tanous const std::vector<std::string>& params) override 98b9b2e0b2SEd Tanous { 99b9b2e0b2SEd Tanous res.jsonValue = Node::json; 100b9b2e0b2SEd Tanous auto asyncResp = std::make_shared<AsyncResp>(res); 101b9b2e0b2SEd Tanous crow::connections::systemBus->async_method_call( 102b9b2e0b2SEd Tanous [asyncResp](const boost::system::error_code ec, 103b9b2e0b2SEd Tanous const ManagedObjectType& users) { 104b9b2e0b2SEd Tanous if (ec) 105b9b2e0b2SEd Tanous { 106b9b2e0b2SEd Tanous asyncResp->res.result( 107b9b2e0b2SEd Tanous boost::beast::http::status::internal_server_error); 108b9b2e0b2SEd Tanous return; 109b9b2e0b2SEd Tanous } 110b9b2e0b2SEd Tanous 111b9b2e0b2SEd Tanous nlohmann::json& memberArray = 112b9b2e0b2SEd Tanous asyncResp->res.jsonValue["Members"]; 113b9b2e0b2SEd Tanous memberArray = nlohmann::json::array(); 114b9b2e0b2SEd Tanous 115b9b2e0b2SEd Tanous asyncResp->res.jsonValue["Members@odata.count"] = users.size(); 116b9b2e0b2SEd Tanous for (auto& user : users) 117b9b2e0b2SEd Tanous { 118b9b2e0b2SEd Tanous const std::string& path = 119b9b2e0b2SEd Tanous static_cast<const std::string&>(user.first); 120b9b2e0b2SEd Tanous std::size_t lastIndex = path.rfind("/"); 121b9b2e0b2SEd Tanous if (lastIndex == std::string::npos) 122b9b2e0b2SEd Tanous { 123b9b2e0b2SEd Tanous lastIndex = 0; 124b9b2e0b2SEd Tanous } 125b9b2e0b2SEd Tanous else 126b9b2e0b2SEd Tanous { 127b9b2e0b2SEd Tanous lastIndex += 1; 128b9b2e0b2SEd Tanous } 129b9b2e0b2SEd Tanous memberArray.push_back( 130b9b2e0b2SEd Tanous {{"@odata.id", "/redfish/v1/AccountService/Accounts/" + 131b9b2e0b2SEd Tanous path.substr(lastIndex)}}); 132b9b2e0b2SEd Tanous } 133b9b2e0b2SEd Tanous }, 134b9b2e0b2SEd Tanous "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user", 135b9b2e0b2SEd Tanous "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"); 136b9b2e0b2SEd Tanous } 137b9b2e0b2SEd Tanous }; 138b9b2e0b2SEd Tanous 139a840879dSEd Tanous template <typename Callback> 140a840879dSEd Tanous inline void checkDbusPathExists(const std::string& path, Callback&& callback) 141a840879dSEd Tanous { 142a840879dSEd Tanous using GetObjectType = 143a840879dSEd Tanous std::vector<std::pair<std::string, std::vector<std::string>>>; 144a840879dSEd Tanous 145a840879dSEd Tanous crow::connections::systemBus->async_method_call( 146a840879dSEd Tanous [callback{std::move(callback)}](const boost::system::error_code ec, 147a840879dSEd Tanous const GetObjectType& object_names) { 148a840879dSEd Tanous callback(ec || object_names.size() == 0); 149a840879dSEd Tanous }, 150a840879dSEd Tanous "xyz.openbmc_project.ObjectMapper", 151a840879dSEd Tanous "/xyz/openbmc_project/object_mapper", 152a840879dSEd Tanous "xyz.openbmc_project.ObjectMapper", "GetObject", path, 153a840879dSEd Tanous std::array<std::string, 0>()); 154a840879dSEd Tanous } 155a840879dSEd Tanous 156b9b2e0b2SEd Tanous class ManagerAccount : public Node 157b9b2e0b2SEd Tanous { 158b9b2e0b2SEd Tanous public: 159b9b2e0b2SEd Tanous ManagerAccount(CrowApp& app) : 160b9b2e0b2SEd Tanous Node(app, "/redfish/v1/AccountService/Accounts/<str>/", std::string()) 161b9b2e0b2SEd Tanous { 162b9b2e0b2SEd Tanous Node::json = {{"@odata.context", 163b9b2e0b2SEd Tanous "/redfish/v1/$metadata#ManagerAccount.ManagerAccount"}, 164b9b2e0b2SEd Tanous {"@odata.type", "#ManagerAccount.v1_0_3.ManagerAccount"}, 165b9b2e0b2SEd Tanous 166b9b2e0b2SEd Tanous {"Name", "User Account"}, 167b9b2e0b2SEd Tanous {"Description", "User Account"}, 168b9b2e0b2SEd Tanous {"Password", nullptr}, 169b9b2e0b2SEd Tanous {"RoleId", "Administrator"}, 170b9b2e0b2SEd Tanous {"Links", 171b9b2e0b2SEd Tanous {{"Role", 172b9b2e0b2SEd Tanous {{"@odata.id", "/redfish/v1/AccountService/Roles/" 173b9b2e0b2SEd Tanous "Administrator"}}}}}}; 174b9b2e0b2SEd Tanous 175b9b2e0b2SEd Tanous entityPrivileges = { 176b9b2e0b2SEd Tanous {boost::beast::http::verb::get, 177b9b2e0b2SEd Tanous {{"ConfigureUsers"}, {"ConfigureManager"}, {"ConfigureSelf"}}}, 178b9b2e0b2SEd Tanous {boost::beast::http::verb::head, {{"Login"}}}, 179b9b2e0b2SEd Tanous {boost::beast::http::verb::patch, {{"ConfigureUsers"}}}, 180b9b2e0b2SEd Tanous {boost::beast::http::verb::put, {{"ConfigureUsers"}}}, 181b9b2e0b2SEd Tanous {boost::beast::http::verb::delete_, {{"ConfigureUsers"}}}, 182b9b2e0b2SEd Tanous {boost::beast::http::verb::post, {{"ConfigureUsers"}}}}; 183b9b2e0b2SEd Tanous } 184b9b2e0b2SEd Tanous 185b9b2e0b2SEd Tanous private: 186b9b2e0b2SEd Tanous void doGet(crow::Response& res, const crow::Request& req, 187b9b2e0b2SEd Tanous const std::vector<std::string>& params) override 188b9b2e0b2SEd Tanous { 189b9b2e0b2SEd Tanous res.jsonValue = Node::json; 190b9b2e0b2SEd Tanous auto asyncResp = std::make_shared<AsyncResp>(res); 191b9b2e0b2SEd Tanous 192b9b2e0b2SEd Tanous if (params.size() != 1) 193b9b2e0b2SEd Tanous { 194b9b2e0b2SEd Tanous res.result(boost::beast::http::status::internal_server_error); 195b9b2e0b2SEd Tanous return; 196b9b2e0b2SEd Tanous } 197b9b2e0b2SEd Tanous 198b9b2e0b2SEd Tanous crow::connections::systemBus->async_method_call( 199b9b2e0b2SEd Tanous [asyncResp, accountName{std::string(params[0])}]( 200b9b2e0b2SEd Tanous const boost::system::error_code ec, 201b9b2e0b2SEd Tanous const ManagedObjectType& users) { 202b9b2e0b2SEd Tanous if (ec) 203b9b2e0b2SEd Tanous { 204b9b2e0b2SEd Tanous asyncResp->res.result( 205b9b2e0b2SEd Tanous boost::beast::http::status::internal_server_error); 206b9b2e0b2SEd Tanous return; 207b9b2e0b2SEd Tanous } 208b9b2e0b2SEd Tanous 209b9b2e0b2SEd Tanous for (auto& user : users) 210b9b2e0b2SEd Tanous { 211b9b2e0b2SEd Tanous const std::string& path = 212b9b2e0b2SEd Tanous static_cast<const std::string&>(user.first); 213b9b2e0b2SEd Tanous std::size_t lastIndex = path.rfind("/"); 214b9b2e0b2SEd Tanous if (lastIndex == std::string::npos) 215b9b2e0b2SEd Tanous { 216b9b2e0b2SEd Tanous lastIndex = 0; 217b9b2e0b2SEd Tanous } 218b9b2e0b2SEd Tanous else 219b9b2e0b2SEd Tanous { 220b9b2e0b2SEd Tanous lastIndex += 1; 221b9b2e0b2SEd Tanous } 222b9b2e0b2SEd Tanous if (path.substr(lastIndex) == accountName) 223b9b2e0b2SEd Tanous { 22465b0dc32SEd Tanous for (const auto& interface : user.second) 22565b0dc32SEd Tanous { 22665b0dc32SEd Tanous if (interface.first == 22765b0dc32SEd Tanous "xyz.openbmc_project.User.Attributes") 22865b0dc32SEd Tanous { 22965b0dc32SEd Tanous for (const auto& property : interface.second) 23065b0dc32SEd Tanous { 23165b0dc32SEd Tanous if (property.first == "UserEnabled") 23265b0dc32SEd Tanous { 23365b0dc32SEd Tanous const bool* userEnabled = 23465b0dc32SEd Tanous mapbox::getPtr<const bool>( 23565b0dc32SEd Tanous property.second); 23665b0dc32SEd Tanous if (userEnabled == nullptr) 23765b0dc32SEd Tanous { 23865b0dc32SEd Tanous BMCWEB_LOG_ERROR 23965b0dc32SEd Tanous << "UserEnabled wasn't a bool"; 24065b0dc32SEd Tanous continue; 24165b0dc32SEd Tanous } 24265b0dc32SEd Tanous asyncResp->res.jsonValue["Enabled"] = 24365b0dc32SEd Tanous *userEnabled; 24465b0dc32SEd Tanous } 24565b0dc32SEd Tanous else if (property.first == 24665b0dc32SEd Tanous "UserLockedForFailedAttempt") 24765b0dc32SEd Tanous { 24865b0dc32SEd Tanous const bool* userLocked = 24965b0dc32SEd Tanous mapbox::getPtr<const bool>( 25065b0dc32SEd Tanous property.second); 25165b0dc32SEd Tanous if (userLocked == nullptr) 25265b0dc32SEd Tanous { 25365b0dc32SEd Tanous BMCWEB_LOG_ERROR 25465b0dc32SEd Tanous << "UserEnabled wasn't a bool"; 25565b0dc32SEd Tanous continue; 25665b0dc32SEd Tanous } 25765b0dc32SEd Tanous asyncResp->res.jsonValue["Locked"] = 25865b0dc32SEd Tanous *userLocked; 25965b0dc32SEd Tanous } 26065b0dc32SEd Tanous } 26165b0dc32SEd Tanous } 26265b0dc32SEd Tanous } 26365b0dc32SEd Tanous 264b9b2e0b2SEd Tanous asyncResp->res.jsonValue["@odata.id"] = 265b9b2e0b2SEd Tanous "/redfish/v1/AccountService/Accounts/" + 266b9b2e0b2SEd Tanous accountName; 267b9b2e0b2SEd Tanous asyncResp->res.jsonValue["Id"] = accountName; 268b9b2e0b2SEd Tanous asyncResp->res.jsonValue["UserName"] = accountName; 269b9b2e0b2SEd Tanous 270b9b2e0b2SEd Tanous return; 271b9b2e0b2SEd Tanous } 272b9b2e0b2SEd Tanous } 273b9b2e0b2SEd Tanous 274b9b2e0b2SEd Tanous asyncResp->res.result(boost::beast::http::status::not_found); 275b9b2e0b2SEd Tanous }, 276b9b2e0b2SEd Tanous "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user", 277b9b2e0b2SEd Tanous "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"); 278b9b2e0b2SEd Tanous } 279a840879dSEd Tanous 280a840879dSEd Tanous void doPatch(crow::Response& res, const crow::Request& req, 281a840879dSEd Tanous const std::vector<std::string>& params) override 282a840879dSEd Tanous { 283a840879dSEd Tanous auto asyncResp = std::make_shared<AsyncResp>(res); 284a840879dSEd Tanous 285a840879dSEd Tanous if (params.size() != 1) 286a840879dSEd Tanous { 287a840879dSEd Tanous res.result(boost::beast::http::status::internal_server_error); 288a840879dSEd Tanous return; 289a840879dSEd Tanous } 290a840879dSEd Tanous 291a840879dSEd Tanous nlohmann::json patchRequest; 292a840879dSEd Tanous if (!json_util::processJsonFromRequest(res, req, patchRequest)) 293a840879dSEd Tanous { 294a840879dSEd Tanous return; 295a840879dSEd Tanous } 296a840879dSEd Tanous 297a840879dSEd Tanous // Check the user exists before updating the fields 298a840879dSEd Tanous checkDbusPathExists( 299a840879dSEd Tanous "/xyz/openbmc_project/users/" + params[0], 300a840879dSEd Tanous [username{std::string(params[0])}, 301a840879dSEd Tanous patchRequest(std::move(patchRequest)), 302a840879dSEd Tanous asyncResp](bool userExists) { 303a840879dSEd Tanous if (!userExists) 304a840879dSEd Tanous { 305a840879dSEd Tanous messages::addMessageToErrorJson( 306a840879dSEd Tanous asyncResp->res.jsonValue, 307a840879dSEd Tanous messages::resourceNotFound( 308a840879dSEd Tanous "#ManagerAccount.v1_0_3.ManagerAccount", username)); 309a840879dSEd Tanous 310a840879dSEd Tanous asyncResp->res.result( 311a840879dSEd Tanous boost::beast::http::status::not_found); 312a840879dSEd Tanous return; 313a840879dSEd Tanous } 314a840879dSEd Tanous 315a840879dSEd Tanous for (const auto& item : patchRequest.items()) 316a840879dSEd Tanous { 317a840879dSEd Tanous if (item.key() == "Password") 318a840879dSEd Tanous { 319a840879dSEd Tanous const std::string* passStr = 320a840879dSEd Tanous item.value().get_ptr<const std::string*>(); 321a840879dSEd Tanous if (passStr == nullptr) 322a840879dSEd Tanous { 323a840879dSEd Tanous messages::addMessageToErrorJson( 324a840879dSEd Tanous asyncResp->res.jsonValue, 325a840879dSEd Tanous messages::propertyValueFormatError( 326a840879dSEd Tanous item.value().dump(), "Password")); 327a840879dSEd Tanous return; 328a840879dSEd Tanous } 329a840879dSEd Tanous BMCWEB_LOG_DEBUG << "Updating user: " << username 330a840879dSEd Tanous << " to password " << *passStr; 331a840879dSEd Tanous if (!pamUpdatePassword(username, *passStr)) 332a840879dSEd Tanous { 333a840879dSEd Tanous BMCWEB_LOG_ERROR << "pamUpdatePassword Failed"; 334a840879dSEd Tanous asyncResp->res.result(boost::beast::http::status:: 335a840879dSEd Tanous internal_server_error); 336a840879dSEd Tanous return; 337a840879dSEd Tanous } 338a840879dSEd Tanous } 339a840879dSEd Tanous else if (item.key() == "Enabled") 340a840879dSEd Tanous { 341a840879dSEd Tanous const bool* enabledBool = 342a840879dSEd Tanous item.value().get_ptr<const bool*>(); 343a840879dSEd Tanous 344a840879dSEd Tanous if (enabledBool == nullptr) 345a840879dSEd Tanous { 346a840879dSEd Tanous messages::addMessageToErrorJson( 347a840879dSEd Tanous asyncResp->res.jsonValue, 348a840879dSEd Tanous messages::propertyValueFormatError( 349a840879dSEd Tanous item.value().dump(), "Enabled")); 350a840879dSEd Tanous return; 351a840879dSEd Tanous } 352a840879dSEd Tanous crow::connections::systemBus->async_method_call( 353a840879dSEd Tanous [asyncResp](const boost::system::error_code ec) { 354a840879dSEd Tanous if (ec) 355a840879dSEd Tanous { 356a840879dSEd Tanous BMCWEB_LOG_ERROR 357a840879dSEd Tanous << "D-Bus responses error: " << ec; 358a840879dSEd Tanous asyncResp->res.result( 359a840879dSEd Tanous boost::beast::http::status:: 360a840879dSEd Tanous internal_server_error); 361a840879dSEd Tanous return; 362a840879dSEd Tanous } 363a840879dSEd Tanous // TODO Consider support polling mechanism to 364a840879dSEd Tanous // verify status of host and chassis after 365a840879dSEd Tanous // execute the requested action. 366a840879dSEd Tanous BMCWEB_LOG_DEBUG << "Response with no content"; 367a840879dSEd Tanous asyncResp->res.result( 368a840879dSEd Tanous boost::beast::http::status::no_content); 369a840879dSEd Tanous }, 370a840879dSEd Tanous "xyz.openbmc_project.User.Manager", 371a840879dSEd Tanous "/xyz/openbmc_project/users/" + username, 372a840879dSEd Tanous "org.freedesktop.DBus.Properties", "Set", 373a840879dSEd Tanous "xyz.openbmc_project.User.Attributes" 374a840879dSEd Tanous "UserEnabled", 375a840879dSEd Tanous sdbusplus::message::variant<bool>{*enabledBool}); 376a840879dSEd Tanous } 377a840879dSEd Tanous else 378a840879dSEd Tanous { 379a840879dSEd Tanous messages::addMessageToErrorJson( 380a840879dSEd Tanous asyncResp->res.jsonValue, 381a840879dSEd Tanous messages::propertyNotWritable(item.key())); 382a840879dSEd Tanous asyncResp->res.result( 383a840879dSEd Tanous boost::beast::http::status::bad_request); 384a840879dSEd Tanous return; 385a840879dSEd Tanous } 386a840879dSEd Tanous } 387a840879dSEd Tanous }); 388a840879dSEd Tanous } 389*06e086d9SEd Tanous 390*06e086d9SEd Tanous void doDelete(crow::Response& res, const crow::Request& req, 391*06e086d9SEd Tanous const std::vector<std::string>& params) override 392*06e086d9SEd Tanous { 393*06e086d9SEd Tanous auto asyncResp = std::make_shared<AsyncResp>(res); 394*06e086d9SEd Tanous 395*06e086d9SEd Tanous if (params.size() != 1) 396*06e086d9SEd Tanous { 397*06e086d9SEd Tanous res.result(boost::beast::http::status::internal_server_error); 398*06e086d9SEd Tanous return; 399*06e086d9SEd Tanous } 400*06e086d9SEd Tanous 401*06e086d9SEd Tanous const std::string userPath = "/xyz/openbmc_project/user/" + params[0]; 402*06e086d9SEd Tanous 403*06e086d9SEd Tanous crow::connections::systemBus->async_method_call( 404*06e086d9SEd Tanous [asyncResp, username{std::move(params[0])}]( 405*06e086d9SEd Tanous const boost::system::error_code ec) { 406*06e086d9SEd Tanous if (ec) 407*06e086d9SEd Tanous { 408*06e086d9SEd Tanous messages::addMessageToErrorJson( 409*06e086d9SEd Tanous asyncResp->res.jsonValue, 410*06e086d9SEd Tanous messages::resourceNotFound( 411*06e086d9SEd Tanous "#ManagerAccount.v1_0_3.ManagerAccount", username)); 412*06e086d9SEd Tanous asyncResp->res.result( 413*06e086d9SEd Tanous boost::beast::http::status::not_found); 414*06e086d9SEd Tanous return; 415*06e086d9SEd Tanous } 416*06e086d9SEd Tanous 417*06e086d9SEd Tanous messages::addMessageToJsonRoot(asyncResp->res.jsonValue, 418*06e086d9SEd Tanous messages::accountRemoved()); 419*06e086d9SEd Tanous }, 420*06e086d9SEd Tanous "xyz.openbmc_project.User.Manager", userPath, 421*06e086d9SEd Tanous "xyz.openbmc_project.Object.Delete", "Delete"); 422*06e086d9SEd Tanous } 423b9b2e0b2SEd Tanous }; 42488d16c9aSLewanczyk, Dawid 42588d16c9aSLewanczyk, Dawid } // namespace redfish 426