summaryrefslogtreecommitdiff
path: root/redfish-core/lib/account_service.hpp
diff options
context:
space:
mode:
authorEd Tanous <ed.tanous@intel.com>2018-09-21 01:54:36 +0300
committerEd Tanous <ed.tanous@intel.com>2018-10-08 20:27:18 +0300
commit04ae99ec1fbfea2e07c0db4174712d0873d2e91c (patch)
tree3e41a606d52b6b4d09c36e65ecc8026468ea38cf /redfish-core/lib/account_service.hpp
parent06e086d9c5564346edd082fc69ba23b9365bdcee (diff)
downloadbmcweb-04ae99ec1fbfea2e07c0db4174712d0873d2e91c.tar.xz
Implement AccountService POST
This commit implements POST events for AccountService/Accounts to aid in the creation of users. It utilizes the DBus User manager API to do its work, as well as PAM to set the password. Tested By: Created users of varying field counts to test all cases. {"UserName": "foobar", "Password": "superpassword", "RoleId": "Administrator"} Observed a user get enabled as Administrator {"UserName": "foobar", "Password": "superpassword"} Observed user created enabled, with default user level of "User" {"UserName": "foobar", "Password": "superpassword", "Enabled": false} observed a user get created as disabled {"UserName": "foobar", "Password": "password"} Observed error due to bad password security Change-Id: I09522c1ddd0f531e6201e7786c6d376d3b0a89e6 Signed-off-by: Ed Tanous <ed.tanous@intel.com>
Diffstat (limited to 'redfish-core/lib/account_service.hpp')
-rw-r--r--redfish-core/lib/account_service.hpp191
1 files changed, 191 insertions, 0 deletions
diff --git a/redfish-core/lib/account_service.hpp b/redfish-core/lib/account_service.hpp
index d44d4a3b8f..3d442789e6 100644
--- a/redfish-core/lib/account_service.hpp
+++ b/redfish-core/lib/account_service.hpp
@@ -134,6 +134,197 @@ class AccountsCollection : public Node
"xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
"org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
}
+ void doPost(crow::Response& res, const crow::Request& req,
+ const std::vector<std::string>& params) override
+ {
+ auto asyncResp = std::make_shared<AsyncResp>(res);
+
+ nlohmann::json patchRequest;
+ if (!json_util::processJsonFromRequest(res, req, patchRequest))
+ {
+ return;
+ }
+
+ const std::string* username = nullptr;
+ const std::string* password = nullptr;
+ // Default to user
+ std::string privilege = "priv-user";
+ // default to enabled
+ bool enabled = true;
+ for (const auto& item : patchRequest.items())
+ {
+ if (item.key() == "UserName")
+ {
+ username = item.value().get_ptr<const std::string*>();
+ if (username == nullptr)
+ {
+ messages::addMessageToErrorJson(
+ asyncResp->res.jsonValue,
+ messages::propertyValueFormatError(item.value().dump(),
+ item.key()));
+ asyncResp->res.result(
+ boost::beast::http::status::bad_request);
+ return;
+ }
+ }
+ else if (item.key() == "Enabled")
+ {
+ const bool* enabledJson = item.value().get_ptr<const bool*>();
+ if (enabledJson == nullptr)
+ {
+ messages::addMessageToErrorJson(
+ asyncResp->res.jsonValue,
+ messages::propertyValueFormatError(item.value().dump(),
+ item.key()));
+ asyncResp->res.result(
+ boost::beast::http::status::bad_request);
+ return;
+ }
+ enabled = *enabledJson;
+ }
+ else if (item.key() == "Password")
+ {
+ password = item.value().get_ptr<const std::string*>();
+ if (password == nullptr)
+ {
+ messages::addMessageToErrorJson(
+ asyncResp->res.jsonValue,
+ messages::propertyValueFormatError(item.value().dump(),
+ item.key()));
+ asyncResp->res.result(
+ boost::beast::http::status::bad_request);
+ return;
+ }
+ }
+ else if (item.key() == "RoleId")
+ {
+ const std::string* roleIdJson =
+ item.value().get_ptr<const std::string*>();
+ if (roleIdJson == nullptr)
+ {
+ messages::addMessageToErrorJson(
+ asyncResp->res.jsonValue,
+ messages::propertyValueFormatError(item.value().dump(),
+ item.key()));
+ asyncResp->res.result(
+ boost::beast::http::status::bad_request);
+ return;
+ }
+ const char* priv = getRoleIdFromPrivilege(*roleIdJson);
+ if (priv == nullptr)
+ {
+ messages::addMessageToErrorJson(
+ asyncResp->res.jsonValue,
+ messages::propertyValueNotInList(*roleIdJson,
+ item.key()));
+ asyncResp->res.result(
+ boost::beast::http::status::bad_request);
+ return;
+ }
+ privilege = priv;
+ }
+ else
+ {
+ messages::addMessageToErrorJson(
+ asyncResp->res.jsonValue,
+ messages::propertyNotWritable(item.key()));
+ asyncResp->res.result(boost::beast::http::status::bad_request);
+ return;
+ }
+ }
+
+ if (username == nullptr)
+ {
+ messages::addMessageToErrorJson(
+ asyncResp->res.jsonValue,
+ messages::createFailedMissingReqProperties("UserName"));
+ asyncResp->res.result(boost::beast::http::status::bad_request);
+ return;
+ }
+
+ if (password == nullptr)
+ {
+ messages::addMessageToErrorJson(
+ asyncResp->res.jsonValue,
+ messages::createFailedMissingReqProperties("Password"));
+ asyncResp->res.result(boost::beast::http::status::bad_request);
+ return;
+ }
+
+ crow::connections::systemBus->async_method_call(
+ [asyncResp, username{std::string(*username)},
+ password{std::string(*password)}](
+ const boost::system::error_code ec) {
+ if (ec)
+ {
+ messages::addMessageToErrorJson(
+ asyncResp->res.jsonValue,
+ messages::resourceAlreadyExists(
+ "#ManagerAccount.v1_0_3.ManagerAccount", "UserName",
+ username));
+ asyncResp->res.result(
+ boost::beast::http::status::bad_request);
+ return;
+ }
+
+ if (!pamUpdatePassword(username, password))
+ {
+ // At this point we have a user that's been created, but the
+ // password set failed. Something is wrong, so delete the
+ // user that we've already created
+ crow::connections::systemBus->async_method_call(
+ [asyncResp](const boost::system::error_code ec) {
+ if (ec)
+ {
+ asyncResp->res.result(
+ boost::beast::http::status::
+ internal_server_error);
+ return;
+ }
+
+ asyncResp->res.result(
+ boost::beast::http::status::bad_request);
+ },
+ "xyz.openbmc_project.User.Manager",
+ "/xyz/openbmc_project/user/" + username,
+ "xyz.openbmc_project.Object.Delete", "Delete");
+
+ BMCWEB_LOG_ERROR << "pamUpdatePassword Failed";
+ return;
+ }
+
+ messages::addMessageToJsonRoot(asyncResp->res.jsonValue,
+ messages::created());
+ asyncResp->res.addHeader(
+ "Location",
+ "/redfish/v1/AccountService/Accounts/" + username);
+ },
+ "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
+ "xyz.openbmc_project.User.Manager", "CreateUser", *username,
+ std::array<const char*, 4>{"ipmi", "redfish", "ssh", "web"},
+ privilege, enabled);
+ }
+
+ static const char* getRoleIdFromPrivilege(boost::beast::string_view role)
+ {
+ if (role == "Administrator")
+ {
+ return "priv-admin";
+ }
+ else if (role == "Callback")
+ {
+ return "priv-callback";
+ }
+ else if (role == "User")
+ {
+ return "priv-user";
+ }
+ else if (role == "Operator")
+ {
+ return "priv-operator";
+ }
+ return nullptr;
+ }
};
template <typename Callback>