xref: /openbmc/bmcweb/features/redfish/lib/account_service.hpp (revision 06e086d9c5564346edd082fc69ba23b9365bdcee)
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