// SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: Copyright OpenBMC Authors // SPDX-FileCopyrightText: Copyright 2018 Intel Corporation #pragma once #include "app.hpp" #include "dbus_utility.hpp" #include "query.hpp" #include "registries/privilege_registry.hpp" #include <boost/url/format.hpp> #include <nlohmann/json.hpp> #include <sdbusplus/asio/property.hpp> #include <optional> #include <string_view> #include <variant> namespace redfish { inline std::string getRoleFromPrivileges(std::string_view priv) { if (priv == "priv-admin") { return "Administrator"; } if (priv == "priv-user") { return "ReadOnly"; } if (priv == "priv-operator") { return "Operator"; } return ""; } inline std::optional<nlohmann::json::array_t> getAssignedPrivFromRole(std::string_view role) { nlohmann::json::array_t privArray; if (role == "Administrator") { privArray.emplace_back("Login"); privArray.emplace_back("ConfigureManager"); privArray.emplace_back("ConfigureUsers"); privArray.emplace_back("ConfigureSelf"); privArray.emplace_back("ConfigureComponents"); } else if (role == "Operator") { privArray.emplace_back("Login"); privArray.emplace_back("ConfigureSelf"); privArray.emplace_back("ConfigureComponents"); } else if (role == "ReadOnly") { privArray.emplace_back("Login"); privArray.emplace_back("ConfigureSelf"); } else { return std::nullopt; } return privArray; } inline void requestRoutesRoles(App& app) { BMCWEB_ROUTE(app, "/redfish/v1/AccountService/Roles/<str>/") .privileges(redfish::privileges::getRole) .methods(boost::beast::http::verb::get)( [&app](const crow::Request& req, const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& roleId) { if (!redfish::setUpRedfishRoute(app, req, asyncResp)) { return; } std::optional<nlohmann::json::array_t> privArray = getAssignedPrivFromRole(roleId); if (!privArray) { messages::resourceNotFound(asyncResp->res, "Role", roleId); return; } asyncResp->res.jsonValue["@odata.type"] = "#Role.v1_2_2.Role"; asyncResp->res.jsonValue["Name"] = "User Role"; asyncResp->res.jsonValue["Description"] = roleId + " User Role"; asyncResp->res.jsonValue["OemPrivileges"] = nlohmann::json::array(); asyncResp->res.jsonValue["IsPredefined"] = true; asyncResp->res.jsonValue["Id"] = roleId; asyncResp->res.jsonValue["RoleId"] = roleId; asyncResp->res.jsonValue["@odata.id"] = boost::urls::format( "/redfish/v1/AccountService/Roles/{}", roleId); asyncResp->res.jsonValue["AssignedPrivileges"] = std::move(*privArray); }); } inline void requestRoutesRoleCollection(App& app) { BMCWEB_ROUTE(app, "/redfish/v1/AccountService/Roles/") .privileges(redfish::privileges::getRoleCollection) .methods(boost::beast::http::verb::get)( [&app](const crow::Request& req, const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { if (!redfish::setUpRedfishRoute(app, req, asyncResp)) { return; } asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/AccountService/Roles"; asyncResp->res.jsonValue["@odata.type"] = "#RoleCollection.RoleCollection"; asyncResp->res.jsonValue["Name"] = "Roles Collection"; asyncResp->res.jsonValue["Description"] = "BMC User Roles"; dbus::utility::getProperty<std::vector<std::string>>( "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user", "xyz.openbmc_project.User.Manager", "AllPrivileges", [asyncResp](const boost::system::error_code& ec, const std::vector<std::string>& privList) { if (ec) { messages::internalError(asyncResp->res); return; } nlohmann::json& memberArray = asyncResp->res.jsonValue["Members"]; memberArray = nlohmann::json::array(); for (const std::string& priv : privList) { std::string role = getRoleFromPrivileges(priv); if (!role.empty()) { nlohmann::json::object_t member; member["@odata.id"] = boost::urls::format( "/redfish/v1/AccountService/Roles/{}", role); memberArray.emplace_back(std::move(member)); } } asyncResp->res.jsonValue["Members@odata.count"] = memberArray.size(); }); }); } } // namespace redfish