Retrieve userGroups Information ("AccountTypes")
This commit enhances the redfish API to retrieve userGroups information
for each user account.
"Redfish" is always enabled in each user role. That's why it was
hardcoded into JSON response data in the old redfish API, where now it
gets retrieved using dbus interface xyz.openbmc_project.User.Attributes.
UserGroups.
UserGroups retrieve data are "redfish", "ssh", "web", and "ipmi", where
redfish DMTF Schema has predefined enum type as described below.
"AccountTypes": {
"enum":["Redfish", "SNMP", "OEM", "HostConsole", "ManagerConsole",
"IPMI", "KVMIP", "VirtualMedia", "WebUI"]
}
Here UserGroups ssh is mapped with two AccountTypes "HostConsole",
"ManagerConsole".
- Redfish ManagerConsole == SSH to port 22 == Phosphor User manager
Phosphor “ssh” privilege
- Redfish HostConsole == SSH to port 2200 (host console), Which
OpenBMC implements using the Phosphor User manager Phosphor “ssh”
privilege.
The 'web' group does not control access to the web interface, and
doesn't appear to do anything. The 'redfish' in the UserGroups is
mapped to both Redfish and WebUI AccountTypes even when there is
no 'web' group in the UserGroups.
Test:
Pass Redfish Service Validator
$ curl -k -X GET
https://$bmc@r5:18080/redfish/v1/AccountService/Accounts/webuser
{
...
"AccountTypes": [
"Redfish",
"WebUI"
],
...
Signed-off-by: Abhishek Patel <Abhishek.Patel@ibm.com>
Change-Id: Iaa9b6c07b3d26e8994be28a50c22437e0bc9bc8f
Signed-off-by: Shantappa Teekappanavar <shantappa.teekappanavar@ibm.com>
diff --git a/redfish-core/lib/account_service.hpp b/redfish-core/lib/account_service.hpp
index 91bd024..0cef7a3 100644
--- a/redfish-core/lib/account_service.hpp
+++ b/redfish-core/lib/account_service.hpp
@@ -27,6 +27,10 @@
#include <utils/dbus_utils.hpp>
#include <utils/json_utils.hpp>
+#include <optional>
+#include <string>
+#include <vector>
+
namespace redfish
{
@@ -111,6 +115,55 @@
return "";
}
+/**
+ * @brief Maps user group names retrieved from D-Bus object to
+ * Account Types.
+ *
+ * @param[in] userGroups List of User groups
+ * @param[out] res AccountTypes populated
+ *
+ * @return true in case of success, false if UserGroups contains
+ * invalid group name(s).
+ */
+inline bool translateUserGroup(const std::vector<std::string>& userGroups,
+ crow::Response& res)
+{
+ std::vector<std::string> accountTypes;
+ for (const auto& userGroup : userGroups)
+ {
+ if (userGroup == "redfish")
+ {
+ accountTypes.emplace_back("Redfish");
+ accountTypes.emplace_back("WebUI");
+ }
+ else if (userGroup == "ipmi")
+ {
+ accountTypes.emplace_back("IPMI");
+ }
+ else if (userGroup == "ssh")
+ {
+ accountTypes.emplace_back("HostConsole");
+ accountTypes.emplace_back("ManagerConsole");
+ }
+ else if (userGroup == "web")
+ {
+ // 'web' is one of the valid groups in the UserGroups property of
+ // the user account in the D-Bus object. This group is currently not
+ // doing anything, and is considered to be equivalent to 'redfish'.
+ // 'redfish' user group is mapped to 'Redfish'and 'WebUI'
+ // AccountTypes, so do nothing here...
+ }
+ else
+ {
+ // Invalid user group name. Caller throws an excption.
+ return false;
+ }
+ }
+
+ res.jsonValue["AccountTypes"] = std::move(accountTypes);
+ return true;
+}
+
inline void userErrorMessageHandler(
const sd_bus_error* e, const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& newUser, const std::string& username)
@@ -1741,8 +1794,6 @@
asyncResp->res.jsonValue["Name"] = "User Account";
asyncResp->res.jsonValue["Description"] = "User Account";
asyncResp->res.jsonValue["Password"] = nullptr;
- asyncResp->res.jsonValue["AccountTypes"] =
- nlohmann::json::array_t({"Redfish"});
for (const auto& interface : userIt->second)
{
@@ -1818,6 +1869,25 @@
asyncResp->res.jsonValue["PasswordChangeRequired"] =
*userPasswordExpired;
}
+ else if (property.first == "UserGroups")
+ {
+ const std::vector<std::string>* userGroups =
+ std::get_if<std::vector<std::string>>(
+ &property.second);
+ if (userGroups == nullptr)
+ {
+ BMCWEB_LOG_ERROR
+ << "userGroups wasn't a string vector";
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ if (!translateUserGroup(*userGroups, asyncResp->res))
+ {
+ BMCWEB_LOG_ERROR << "userGroups mapping failed";
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ }
}
}
}