blob: 8958290d0b94769808fbef970acce0276f693e57 [file] [log] [blame]
Lewanczyk, Dawid88d16c92018-02-02 14:51:09 +01001/*
2// Copyright (c) 2018 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
16#pragma once
Lewanczyk, Dawid88d16c92018-02-02 14:51:09 +010017#include "node.hpp"
18
Ed Tanous65b0dc32018-09-19 16:04:03 -070019#include <error_messages.hpp>
Ed Tanousb9b2e0b2018-09-13 13:47:50 -070020#include <openbmc_dbus_rest.hpp>
Ed Tanousa8408792018-09-05 16:08:38 -070021#include <utils/json_utils.hpp>
Ed Tanousb9b2e0b2018-09-13 13:47:50 -070022
Ed Tanous1abe55e2018-09-05 08:30:59 -070023namespace redfish
24{
Lewanczyk, Dawid88d16c92018-02-02 14:51:09 +010025
Ed Tanousb9b2e0b2018-09-13 13:47:50 -070026using ManagedObjectType = std::vector<std::pair<
27 sdbusplus::message::object_path,
28 boost::container::flat_map<
AppaRao Puli84e12cb2018-10-11 01:28:15 +053029 std::string,
30 boost::container::flat_map<
31 std::string, sdbusplus::message::variant<bool, std::string>>>>>;
32
33inline std::string getPrivilegeFromRoleId(boost::beast::string_view role)
34{
35 if (role == "priv-admin")
36 {
37 return "Administrator";
38 }
39 else if (role == "priv-callback")
40 {
41 return "Callback";
42 }
43 else if (role == "priv-user")
44 {
45 return "User";
46 }
47 else if (role == "priv-operator")
48 {
49 return "Operator";
50 }
51 return "";
52}
53inline std::string getRoleIdFromPrivilege(boost::beast::string_view role)
54{
55 if (role == "Administrator")
56 {
57 return "priv-admin";
58 }
59 else if (role == "Callback")
60 {
61 return "priv-callback";
62 }
63 else if (role == "User")
64 {
65 return "priv-user";
66 }
67 else if (role == "Operator")
68 {
69 return "priv-operator";
70 }
71 return "";
72}
Ed Tanousb9b2e0b2018-09-13 13:47:50 -070073
Ed Tanous1abe55e2018-09-05 08:30:59 -070074class AccountService : public Node
75{
76 public:
77 AccountService(CrowApp& app) : Node(app, "/redfish/v1/AccountService/")
78 {
Ed Tanous1abe55e2018-09-05 08:30:59 -070079 entityPrivileges = {
80 {boost::beast::http::verb::get,
81 {{"ConfigureUsers"}, {"ConfigureManager"}}},
82 {boost::beast::http::verb::head, {{"Login"}}},
83 {boost::beast::http::verb::patch, {{"ConfigureUsers"}}},
84 {boost::beast::http::verb::put, {{"ConfigureUsers"}}},
85 {boost::beast::http::verb::delete_, {{"ConfigureUsers"}}},
86 {boost::beast::http::verb::post, {{"ConfigureUsers"}}}};
87 }
Lewanczyk, Dawid88d16c92018-02-02 14:51:09 +010088
Ed Tanous1abe55e2018-09-05 08:30:59 -070089 private:
90 void doGet(crow::Response& res, const crow::Request& req,
91 const std::vector<std::string>& params) override
92 {
AppaRao Puli3d958bb2018-12-25 12:45:54 +053093 auto asyncResp = std::make_shared<AsyncResp>(res);
94 res.jsonValue = {
95 {"@odata.context", "/redfish/v1/"
96 "$metadata#AccountService.AccountService"},
97 {"@odata.id", "/redfish/v1/AccountService"},
98 {"@odata.type", "#AccountService."
99 "v1_1_0.AccountService"},
100 {"Id", "AccountService"},
101 {"Name", "Account Service"},
102 {"Description", "Account Service"},
103 {"ServiceEnabled", true},
104 {"MaxPasswordLength", 31},
105 {"Accounts",
106 {{"@odata.id", "/redfish/v1/AccountService/Accounts"}}},
107 {"Roles", {{"@odata.id", "/redfish/v1/AccountService/Roles"}}}};
Ed Tanous0f74e642018-11-12 15:17:05 -0800108
AppaRao Puli3d958bb2018-12-25 12:45:54 +0530109 crow::connections::systemBus->async_method_call(
110 [asyncResp](
111 const boost::system::error_code ec,
112 const std::vector<std::pair<
113 std::string,
114 sdbusplus::message::variant<uint32_t, uint16_t, uint8_t>>>&
115 propertiesList) {
116 if (ec)
117 {
118 messages::internalError(asyncResp->res);
119 return;
120 }
121 BMCWEB_LOG_DEBUG << "Got " << propertiesList.size()
122 << "properties for AccountService";
123 for (const std::pair<std::string,
124 sdbusplus::message::variant<
125 uint32_t, uint16_t, uint8_t>>&
126 property : propertiesList)
127 {
128 if (property.first == "MinPasswordLength")
129 {
130 const uint8_t* value =
131 sdbusplus::message::variant_ns::get_if<uint8_t>(
132 &property.second);
133 if (value != nullptr)
134 {
135 asyncResp->res.jsonValue["MinPasswordLength"] =
136 *value;
137 }
138 }
139 if (property.first == "AccountUnlockTimeout")
140 {
141 const uint32_t* value =
142 sdbusplus::message::variant_ns::get_if<uint32_t>(
143 &property.second);
144 if (value != nullptr)
145 {
146 asyncResp->res.jsonValue["AccountLockoutDuration"] =
147 *value;
148 }
149 }
150 if (property.first == "MaxLoginAttemptBeforeLockout")
151 {
152 const uint16_t* value =
153 sdbusplus::message::variant_ns::get_if<uint16_t>(
154 &property.second);
155 if (value != nullptr)
156 {
157 asyncResp->res
158 .jsonValue["AccountLockoutThreshold"] = *value;
159 }
160 }
161 }
162 },
163 "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
164 "org.freedesktop.DBus.Properties", "GetAll",
165 "xyz.openbmc_project.User.AccountPolicy");
166 }
167 void doPatch(crow::Response& res, const crow::Request& req,
168 const std::vector<std::string>& params) override
169 {
170 auto asyncResp = std::make_shared<AsyncResp>(res);
171
172 std::optional<uint32_t> unlockTimeout;
173 std::optional<uint16_t> lockoutThreshold;
174 if (!json_util::readJson(req, res, "AccountLockoutDuration",
175 unlockTimeout, "AccountLockoutThreshold",
176 lockoutThreshold))
177 {
178 return;
179 }
180 if (unlockTimeout)
181 {
182 crow::connections::systemBus->async_method_call(
183 [asyncResp](const boost::system::error_code ec) {
184 if (ec)
185 {
186 messages::internalError(asyncResp->res);
187 return;
188 }
189 },
190 "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
191 "org.freedesktop.DBus.Properties", "Set",
192 "xyz.openbmc_project.User.AccountPolicy",
193 "AccountUnlockTimeout",
194 sdbusplus::message::variant<uint32_t>(*unlockTimeout));
195 }
196 if (lockoutThreshold)
197 {
198 crow::connections::systemBus->async_method_call(
199 [asyncResp](const boost::system::error_code ec) {
200 if (ec)
201 {
202 messages::internalError(asyncResp->res);
203 return;
204 }
205 },
206 "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
207 "org.freedesktop.DBus.Properties", "Set",
208 "xyz.openbmc_project.User.AccountPolicy",
209 "MaxLoginAttemptBeforeLockout",
210 sdbusplus::message::variant<uint16_t>(*lockoutThreshold));
211 }
Ed Tanous1abe55e2018-09-05 08:30:59 -0700212 }
Lewanczyk, Dawid88d16c92018-02-02 14:51:09 +0100213};
Ed Tanousb9b2e0b2018-09-13 13:47:50 -0700214class AccountsCollection : public Node
215{
216 public:
217 AccountsCollection(CrowApp& app) :
218 Node(app, "/redfish/v1/AccountService/Accounts/")
219 {
Ed Tanousb9b2e0b2018-09-13 13:47:50 -0700220 entityPrivileges = {
221 {boost::beast::http::verb::get,
222 {{"ConfigureUsers"}, {"ConfigureManager"}}},
223 {boost::beast::http::verb::head, {{"Login"}}},
224 {boost::beast::http::verb::patch, {{"ConfigureUsers"}}},
225 {boost::beast::http::verb::put, {{"ConfigureUsers"}}},
226 {boost::beast::http::verb::delete_, {{"ConfigureUsers"}}},
227 {boost::beast::http::verb::post, {{"ConfigureUsers"}}}};
228 }
229
230 private:
231 void doGet(crow::Response& res, const crow::Request& req,
232 const std::vector<std::string>& params) override
233 {
Ed Tanousb9b2e0b2018-09-13 13:47:50 -0700234 auto asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous0f74e642018-11-12 15:17:05 -0800235 res.jsonValue = {{"@odata.context",
236 "/redfish/v1/"
237 "$metadata#ManagerAccountCollection."
238 "ManagerAccountCollection"},
239 {"@odata.id", "/redfish/v1/AccountService/Accounts"},
240 {"@odata.type", "#ManagerAccountCollection."
241 "ManagerAccountCollection"},
242 {"Name", "Accounts Collection"},
243 {"Description", "BMC User Accounts"}};
244
Ed Tanousb9b2e0b2018-09-13 13:47:50 -0700245 crow::connections::systemBus->async_method_call(
246 [asyncResp](const boost::system::error_code ec,
247 const ManagedObjectType& users) {
248 if (ec)
249 {
Jason M. Billsf12894f2018-10-09 12:45:45 -0700250 messages::internalError(asyncResp->res);
Ed Tanousb9b2e0b2018-09-13 13:47:50 -0700251 return;
252 }
253
254 nlohmann::json& memberArray =
255 asyncResp->res.jsonValue["Members"];
256 memberArray = nlohmann::json::array();
257
258 asyncResp->res.jsonValue["Members@odata.count"] = users.size();
259 for (auto& user : users)
260 {
261 const std::string& path =
262 static_cast<const std::string&>(user.first);
263 std::size_t lastIndex = path.rfind("/");
264 if (lastIndex == std::string::npos)
265 {
266 lastIndex = 0;
267 }
268 else
269 {
270 lastIndex += 1;
271 }
272 memberArray.push_back(
273 {{"@odata.id", "/redfish/v1/AccountService/Accounts/" +
274 path.substr(lastIndex)}});
275 }
276 },
277 "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
278 "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
279 }
Ed Tanous04ae99e2018-09-20 15:54:36 -0700280 void doPost(crow::Response& res, const crow::Request& req,
281 const std::vector<std::string>& params) override
282 {
283 auto asyncResp = std::make_shared<AsyncResp>(res);
284
Ed Tanous9712f8a2018-09-21 13:38:49 -0700285 std::string username;
286 std::string password;
Ed Tanousa24526d2018-12-10 15:17:59 -0800287 std::optional<std::string> roleId("User");
288 std::optional<bool> enabled = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -0700289 if (!json_util::readJson(req, res, "UserName", username, "Password",
290 password, "RoleId", roleId, "Enabled",
291 enabled))
Ed Tanous04ae99e2018-09-20 15:54:36 -0700292 {
293 return;
294 }
295
AppaRao Puli84e12cb2018-10-11 01:28:15 +0530296 std::string priv = getRoleIdFromPrivilege(*roleId);
297 if (priv.empty())
Ed Tanous04ae99e2018-09-20 15:54:36 -0700298 {
Jason M. Billsf12894f2018-10-09 12:45:45 -0700299 messages::propertyValueNotInList(asyncResp->res, *roleId, "RoleId");
Ed Tanous04ae99e2018-09-20 15:54:36 -0700300 return;
301 }
Ed Tanous9712f8a2018-09-21 13:38:49 -0700302 roleId = priv;
Ed Tanous04ae99e2018-09-20 15:54:36 -0700303
304 crow::connections::systemBus->async_method_call(
Ed Tanous9712f8a2018-09-21 13:38:49 -0700305 [asyncResp, username, password{std::move(password)}](
Ed Tanous04ae99e2018-09-20 15:54:36 -0700306 const boost::system::error_code ec) {
307 if (ec)
308 {
Jason M. Billsf12894f2018-10-09 12:45:45 -0700309 messages::resourceAlreadyExists(
310 asyncResp->res, "#ManagerAccount.v1_0_3.ManagerAccount",
311 "UserName", username);
Ed Tanous04ae99e2018-09-20 15:54:36 -0700312 return;
313 }
314
315 if (!pamUpdatePassword(username, password))
316 {
317 // At this point we have a user that's been created, but the
318 // password set failed. Something is wrong, so delete the
319 // user that we've already created
320 crow::connections::systemBus->async_method_call(
321 [asyncResp](const boost::system::error_code ec) {
322 if (ec)
323 {
Jason M. Billsf12894f2018-10-09 12:45:45 -0700324 messages::internalError(asyncResp->res);
Ed Tanous04ae99e2018-09-20 15:54:36 -0700325 return;
326 }
327
Jason M. Billsf12894f2018-10-09 12:45:45 -0700328 messages::invalidObject(asyncResp->res, "Password");
Ed Tanous04ae99e2018-09-20 15:54:36 -0700329 },
330 "xyz.openbmc_project.User.Manager",
331 "/xyz/openbmc_project/user/" + username,
332 "xyz.openbmc_project.Object.Delete", "Delete");
333
334 BMCWEB_LOG_ERROR << "pamUpdatePassword Failed";
335 return;
336 }
337
Jason M. Billsf12894f2018-10-09 12:45:45 -0700338 messages::created(asyncResp->res);
Ed Tanous04ae99e2018-09-20 15:54:36 -0700339 asyncResp->res.addHeader(
340 "Location",
341 "/redfish/v1/AccountService/Accounts/" + username);
342 },
343 "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
Ed Tanous9712f8a2018-09-21 13:38:49 -0700344 "xyz.openbmc_project.User.Manager", "CreateUser", username,
Ed Tanous04ae99e2018-09-20 15:54:36 -0700345 std::array<const char*, 4>{"ipmi", "redfish", "ssh", "web"},
Ed Tanous9712f8a2018-09-21 13:38:49 -0700346 *roleId, *enabled);
Ed Tanous04ae99e2018-09-20 15:54:36 -0700347 }
Ed Tanousb9b2e0b2018-09-13 13:47:50 -0700348};
349
Ed Tanousa8408792018-09-05 16:08:38 -0700350template <typename Callback>
351inline void checkDbusPathExists(const std::string& path, Callback&& callback)
352{
353 using GetObjectType =
354 std::vector<std::pair<std::string, std::vector<std::string>>>;
355
356 crow::connections::systemBus->async_method_call(
357 [callback{std::move(callback)}](const boost::system::error_code ec,
358 const GetObjectType& object_names) {
AppaRao Puli84e12cb2018-10-11 01:28:15 +0530359 callback(!ec && object_names.size() != 0);
Ed Tanousa8408792018-09-05 16:08:38 -0700360 },
361 "xyz.openbmc_project.ObjectMapper",
362 "/xyz/openbmc_project/object_mapper",
363 "xyz.openbmc_project.ObjectMapper", "GetObject", path,
364 std::array<std::string, 0>());
365}
366
Ed Tanousb9b2e0b2018-09-13 13:47:50 -0700367class ManagerAccount : public Node
368{
369 public:
370 ManagerAccount(CrowApp& app) :
371 Node(app, "/redfish/v1/AccountService/Accounts/<str>/", std::string())
372 {
Ed Tanousb9b2e0b2018-09-13 13:47:50 -0700373 entityPrivileges = {
374 {boost::beast::http::verb::get,
375 {{"ConfigureUsers"}, {"ConfigureManager"}, {"ConfigureSelf"}}},
376 {boost::beast::http::verb::head, {{"Login"}}},
377 {boost::beast::http::verb::patch, {{"ConfigureUsers"}}},
378 {boost::beast::http::verb::put, {{"ConfigureUsers"}}},
379 {boost::beast::http::verb::delete_, {{"ConfigureUsers"}}},
380 {boost::beast::http::verb::post, {{"ConfigureUsers"}}}};
381 }
382
383 private:
384 void doGet(crow::Response& res, const crow::Request& req,
385 const std::vector<std::string>& params) override
386 {
Ed Tanous0f74e642018-11-12 15:17:05 -0800387 res.jsonValue = {
388 {"@odata.context",
389 "/redfish/v1/$metadata#ManagerAccount.ManagerAccount"},
390 {"@odata.type", "#ManagerAccount.v1_0_3.ManagerAccount"},
Ed Tanous0f74e642018-11-12 15:17:05 -0800391 {"Name", "User Account"},
392 {"Description", "User Account"},
393 {"Password", nullptr},
AppaRao Puli84e12cb2018-10-11 01:28:15 +0530394 {"RoleId", "Administrator"}};
Ed Tanous0f74e642018-11-12 15:17:05 -0800395
Ed Tanousb9b2e0b2018-09-13 13:47:50 -0700396 auto asyncResp = std::make_shared<AsyncResp>(res);
397
398 if (params.size() != 1)
399 {
Jason M. Billsf12894f2018-10-09 12:45:45 -0700400 messages::internalError(asyncResp->res);
Ed Tanousb9b2e0b2018-09-13 13:47:50 -0700401 return;
402 }
403
404 crow::connections::systemBus->async_method_call(
405 [asyncResp, accountName{std::string(params[0])}](
406 const boost::system::error_code ec,
407 const ManagedObjectType& users) {
408 if (ec)
409 {
Jason M. Billsf12894f2018-10-09 12:45:45 -0700410 messages::internalError(asyncResp->res);
Ed Tanousb9b2e0b2018-09-13 13:47:50 -0700411 return;
412 }
AppaRao Puli84e12cb2018-10-11 01:28:15 +0530413 auto userIt = users.begin();
Ed Tanousb9b2e0b2018-09-13 13:47:50 -0700414
AppaRao Puli84e12cb2018-10-11 01:28:15 +0530415 for (; userIt != users.end(); userIt++)
Ed Tanousb9b2e0b2018-09-13 13:47:50 -0700416 {
AppaRao Puli84e12cb2018-10-11 01:28:15 +0530417 if (boost::ends_with(userIt->first.str, "/" + accountName))
Ed Tanousb9b2e0b2018-09-13 13:47:50 -0700418 {
AppaRao Puli84e12cb2018-10-11 01:28:15 +0530419 break;
Ed Tanousb9b2e0b2018-09-13 13:47:50 -0700420 }
AppaRao Puli84e12cb2018-10-11 01:28:15 +0530421 }
422 if (userIt == users.end())
423 {
424 messages::resourceNotFound(asyncResp->res, "ManagerAccount",
425 accountName);
426 return;
427 }
428 for (const auto& interface : userIt->second)
429 {
430 if (interface.first ==
431 "xyz.openbmc_project.User.Attributes")
Ed Tanousb9b2e0b2018-09-13 13:47:50 -0700432 {
AppaRao Puli84e12cb2018-10-11 01:28:15 +0530433 for (const auto& property : interface.second)
Ed Tanous65b0dc32018-09-19 16:04:03 -0700434 {
AppaRao Puli84e12cb2018-10-11 01:28:15 +0530435 if (property.first == "UserEnabled")
Ed Tanous65b0dc32018-09-19 16:04:03 -0700436 {
AppaRao Puli84e12cb2018-10-11 01:28:15 +0530437 const bool* userEnabled =
438 sdbusplus::message::variant_ns::get_if<
439 bool>(&property.second);
440 if (userEnabled == nullptr)
Ed Tanous65b0dc32018-09-19 16:04:03 -0700441 {
AppaRao Puli84e12cb2018-10-11 01:28:15 +0530442 BMCWEB_LOG_ERROR
443 << "UserEnabled wasn't a bool";
444 messages::internalError(asyncResp->res);
445 return;
Ed Tanous65b0dc32018-09-19 16:04:03 -0700446 }
AppaRao Puli84e12cb2018-10-11 01:28:15 +0530447 asyncResp->res.jsonValue["Enabled"] =
448 *userEnabled;
449 }
450 else if (property.first ==
451 "UserLockedForFailedAttempt")
452 {
453 const bool* userLocked =
454 sdbusplus::message::variant_ns::get_if<
455 bool>(&property.second);
456 if (userLocked == nullptr)
457 {
458 BMCWEB_LOG_ERROR << "UserLockedForF"
459 "ailedAttempt "
460 "wasn't a bool";
461 messages::internalError(asyncResp->res);
462 return;
463 }
464 asyncResp->res.jsonValue["Locked"] =
465 *userLocked;
466 }
467 else if (property.first == "UserPrivilege")
468 {
469 const std::string* userRolePtr =
470 sdbusplus::message::variant_ns::get_if<
471 std::string>(&property.second);
472 if (userRolePtr == nullptr)
473 {
474 BMCWEB_LOG_ERROR
475 << "UserPrivilege wasn't a "
476 "string";
477 messages::internalError(asyncResp->res);
478 return;
479 }
480 std::string priv =
481 getPrivilegeFromRoleId(*userRolePtr);
482 if (priv.empty())
483 {
484 BMCWEB_LOG_ERROR << "Invalid user role";
485 messages::internalError(asyncResp->res);
486 return;
487 }
488 asyncResp->res.jsonValue["RoleId"] = priv;
489
490 asyncResp->res.jsonValue["Links"]["Role"] = {
491 {"@odata.id", "/redfish/v1/AccountService/"
492 "Roles/" +
493 priv}};
Ed Tanous65b0dc32018-09-19 16:04:03 -0700494 }
495 }
Ed Tanousb9b2e0b2018-09-13 13:47:50 -0700496 }
497 }
498
AppaRao Puli84e12cb2018-10-11 01:28:15 +0530499 asyncResp->res.jsonValue["@odata.id"] =
500 "/redfish/v1/AccountService/Accounts/" + accountName;
501 asyncResp->res.jsonValue["Id"] = accountName;
502 asyncResp->res.jsonValue["UserName"] = accountName;
Ed Tanousb9b2e0b2018-09-13 13:47:50 -0700503 },
504 "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
505 "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
506 }
Ed Tanousa8408792018-09-05 16:08:38 -0700507
508 void doPatch(crow::Response& res, const crow::Request& req,
509 const std::vector<std::string>& params) override
510 {
511 auto asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanousa8408792018-09-05 16:08:38 -0700512 if (params.size() != 1)
513 {
Jason M. Billsf12894f2018-10-09 12:45:45 -0700514 messages::internalError(asyncResp->res);
Ed Tanousa8408792018-09-05 16:08:38 -0700515 return;
516 }
517
Ed Tanousa24526d2018-12-10 15:17:59 -0800518 std::optional<std::string> newUserName;
519 std::optional<std::string> password;
520 std::optional<bool> enabled;
521 std::optional<std::string> roleId;
AppaRao Puli84e12cb2018-10-11 01:28:15 +0530522 if (!json_util::readJson(req, res, "UserName", newUserName, "Password",
523 password, "RoleId", roleId, "Enabled",
Ed Tanous9712f8a2018-09-21 13:38:49 -0700524 enabled))
Ed Tanousa8408792018-09-05 16:08:38 -0700525 {
526 return;
527 }
528
AppaRao Puli84e12cb2018-10-11 01:28:15 +0530529 const std::string& username = params[0];
Ed Tanousa8408792018-09-05 16:08:38 -0700530
AppaRao Puli84e12cb2018-10-11 01:28:15 +0530531 if (!newUserName)
532 {
533 // If the username isn't being updated, we can update the properties
534 // directly
535 updateUserProperties(asyncResp, username, password, enabled,
536 roleId);
537 return;
538 }
539 else
540 {
541 crow::connections::systemBus->async_method_call(
542 [this, asyncResp, username, password(std::move(password)),
543 roleId(std::move(roleId)), enabled(std::move(enabled)),
544 newUser{std::string(*newUserName)}](
545 const boost::system::error_code ec) {
546 if (ec)
Ed Tanousa8408792018-09-05 16:08:38 -0700547 {
AppaRao Puli84e12cb2018-10-11 01:28:15 +0530548 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
549 messages::resourceNotFound(
550 asyncResp->res,
551 "#ManagerAccount.v1_0_3.ManagerAccount", username);
552 return;
553 }
554
555 updateUserProperties(asyncResp, newUser, password, enabled,
556 roleId);
557 },
558 "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
559 "xyz.openbmc_project.User.Manager", "RenameUser", username,
560 *newUserName);
561 }
562 }
563
564 void updateUserProperties(std::shared_ptr<AsyncResp> asyncResp,
565 const std::string& username,
Ed Tanousa24526d2018-12-10 15:17:59 -0800566 std::optional<std::string> password,
567 std::optional<bool> enabled,
568 std::optional<std::string> roleId)
AppaRao Puli84e12cb2018-10-11 01:28:15 +0530569 {
570 if (password)
571 {
572 if (!pamUpdatePassword(username, *password))
573 {
574 BMCWEB_LOG_ERROR << "pamUpdatePassword Failed";
575 messages::internalError(asyncResp->res);
576 return;
577 }
578 }
579
580 if (enabled)
581 {
582 crow::connections::systemBus->async_method_call(
583 [asyncResp](const boost::system::error_code ec) {
584 if (ec)
585 {
586 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700587 messages::internalError(asyncResp->res);
Ed Tanousa8408792018-09-05 16:08:38 -0700588 return;
589 }
AppaRao Puli84e12cb2018-10-11 01:28:15 +0530590 messages::success(asyncResp->res);
591 return;
592 },
593 "xyz.openbmc_project.User.Manager",
594 "/xyz/openbmc_project/user/" + username,
595 "org.freedesktop.DBus.Properties", "Set",
596 "xyz.openbmc_project.User.Attributes", "UserEnabled",
597 sdbusplus::message::variant<bool>{*enabled});
598 }
Ed Tanous9712f8a2018-09-21 13:38:49 -0700599
AppaRao Puli84e12cb2018-10-11 01:28:15 +0530600 if (roleId)
601 {
602 std::string priv = getRoleIdFromPrivilege(*roleId);
603 if (priv.empty())
604 {
605 messages::propertyValueNotInList(asyncResp->res, *roleId,
606 "RoleId");
607 return;
608 }
609
610 crow::connections::systemBus->async_method_call(
611 [asyncResp](const boost::system::error_code ec) {
612 if (ec)
613 {
614 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
615 messages::internalError(asyncResp->res);
616 return;
617 }
618 messages::success(asyncResp->res);
619 },
620 "xyz.openbmc_project.User.Manager",
621 "/xyz/openbmc_project/user/" + username,
622 "org.freedesktop.DBus.Properties", "Set",
623 "xyz.openbmc_project.User.Attributes", "UserPrivilege",
624 sdbusplus::message::variant<std::string>{priv});
625 }
Ed Tanousa8408792018-09-05 16:08:38 -0700626 }
Ed Tanous06e086d2018-09-19 17:19:52 -0700627
628 void doDelete(crow::Response& res, const crow::Request& req,
629 const std::vector<std::string>& params) override
630 {
631 auto asyncResp = std::make_shared<AsyncResp>(res);
632
633 if (params.size() != 1)
634 {
Jason M. Billsf12894f2018-10-09 12:45:45 -0700635 messages::internalError(asyncResp->res);
Ed Tanous06e086d2018-09-19 17:19:52 -0700636 return;
637 }
638
639 const std::string userPath = "/xyz/openbmc_project/user/" + params[0];
640
641 crow::connections::systemBus->async_method_call(
642 [asyncResp, username{std::move(params[0])}](
643 const boost::system::error_code ec) {
644 if (ec)
645 {
Jason M. Billsf12894f2018-10-09 12:45:45 -0700646 messages::resourceNotFound(
647 asyncResp->res, "#ManagerAccount.v1_0_3.ManagerAccount",
648 username);
Ed Tanous06e086d2018-09-19 17:19:52 -0700649 return;
650 }
651
Jason M. Billsf12894f2018-10-09 12:45:45 -0700652 messages::accountRemoved(asyncResp->res);
Ed Tanous06e086d2018-09-19 17:19:52 -0700653 },
654 "xyz.openbmc_project.User.Manager", userPath,
655 "xyz.openbmc_project.Object.Delete", "Delete");
656 }
AppaRao Puli84e12cb2018-10-11 01:28:15 +0530657};
Lewanczyk, Dawid88d16c92018-02-02 14:51:09 +0100658
Ed Tanous1abe55e2018-09-05 08:30:59 -0700659} // namespace redfish