1 // SPDX-License-Identifier: Apache-2.0 2 // SPDX-FileCopyrightText: Copyright OpenBMC Authors 3 // SPDX-FileCopyrightText: Copyright 2018 Intel Corporation 4 #pragma once 5 6 #include "app.hpp" 7 #include "async_resp.hpp" 8 #include "dbus_utility.hpp" 9 #include "error_messages.hpp" 10 #include "http_request.hpp" 11 #include "query.hpp" 12 #include "registries/privilege_registry.hpp" 13 14 #include <boost/beast/http/verb.hpp> 15 #include <boost/url/format.hpp> 16 #include <nlohmann/json.hpp> 17 18 #include <memory> 19 #include <optional> 20 #include <string> 21 #include <string_view> 22 #include <utility> 23 #include <vector> 24 namespace redfish 25 { 26 27 inline std::string getRoleFromPrivileges(std::string_view priv) 28 { 29 if (priv == "priv-admin") 30 { 31 return "Administrator"; 32 } 33 if (priv == "priv-user") 34 { 35 return "ReadOnly"; 36 } 37 if (priv == "priv-operator") 38 { 39 return "Operator"; 40 } 41 return ""; 42 } 43 44 inline std::optional<nlohmann::json::array_t> getAssignedPrivFromRole( 45 std::string_view role) 46 { 47 nlohmann::json::array_t privArray; 48 if (role == "Administrator") 49 { 50 privArray.emplace_back("Login"); 51 privArray.emplace_back("ConfigureManager"); 52 privArray.emplace_back("ConfigureUsers"); 53 privArray.emplace_back("ConfigureSelf"); 54 privArray.emplace_back("ConfigureComponents"); 55 } 56 else if (role == "Operator") 57 { 58 privArray.emplace_back("Login"); 59 privArray.emplace_back("ConfigureSelf"); 60 privArray.emplace_back("ConfigureComponents"); 61 } 62 else if (role == "ReadOnly") 63 { 64 privArray.emplace_back("Login"); 65 privArray.emplace_back("ConfigureSelf"); 66 } 67 else 68 { 69 return std::nullopt; 70 } 71 return privArray; 72 } 73 74 inline void requestRoutesRoles(App& app) 75 { 76 BMCWEB_ROUTE(app, "/redfish/v1/AccountService/Roles/<str>/") 77 .privileges(redfish::privileges::getRole) 78 .methods(boost::beast::http::verb::get)( 79 [&app](const crow::Request& req, 80 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 81 const std::string& roleId) { 82 if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 83 { 84 return; 85 } 86 87 std::optional<nlohmann::json::array_t> privArray = 88 getAssignedPrivFromRole(roleId); 89 if (!privArray) 90 { 91 messages::resourceNotFound(asyncResp->res, "Role", roleId); 92 93 return; 94 } 95 96 asyncResp->res.jsonValue["@odata.type"] = "#Role.v1_2_2.Role"; 97 asyncResp->res.jsonValue["Name"] = "User Role"; 98 asyncResp->res.jsonValue["Description"] = roleId + " User Role"; 99 asyncResp->res.jsonValue["OemPrivileges"] = 100 nlohmann::json::array(); 101 asyncResp->res.jsonValue["IsPredefined"] = true; 102 asyncResp->res.jsonValue["Id"] = roleId; 103 asyncResp->res.jsonValue["RoleId"] = roleId; 104 asyncResp->res.jsonValue["@odata.id"] = boost::urls::format( 105 "/redfish/v1/AccountService/Roles/{}", roleId); 106 asyncResp->res.jsonValue["AssignedPrivileges"] = 107 std::move(*privArray); 108 }); 109 } 110 111 inline void requestRoutesRoleCollection(App& app) 112 { 113 BMCWEB_ROUTE(app, "/redfish/v1/AccountService/Roles/") 114 .privileges(redfish::privileges::getRoleCollection) 115 .methods(boost::beast::http::verb::get)( 116 [&app](const crow::Request& req, 117 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 118 if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 119 { 120 return; 121 } 122 123 asyncResp->res.jsonValue["@odata.id"] = 124 "/redfish/v1/AccountService/Roles"; 125 asyncResp->res.jsonValue["@odata.type"] = 126 "#RoleCollection.RoleCollection"; 127 asyncResp->res.jsonValue["Name"] = "Roles Collection"; 128 asyncResp->res.jsonValue["Description"] = "BMC User Roles"; 129 130 dbus::utility::getProperty<std::vector<std::string>>( 131 "xyz.openbmc_project.User.Manager", 132 "/xyz/openbmc_project/user", 133 "xyz.openbmc_project.User.Manager", "AllPrivileges", 134 [asyncResp](const boost::system::error_code& ec, 135 const std::vector<std::string>& privList) { 136 if (ec) 137 { 138 messages::internalError(asyncResp->res); 139 return; 140 } 141 nlohmann::json& memberArray = 142 asyncResp->res.jsonValue["Members"]; 143 memberArray = nlohmann::json::array(); 144 for (const std::string& priv : privList) 145 { 146 std::string role = getRoleFromPrivileges(priv); 147 if (!role.empty()) 148 { 149 nlohmann::json::object_t member; 150 member["@odata.id"] = boost::urls::format( 151 "/redfish/v1/AccountService/Roles/{}", 152 role); 153 memberArray.emplace_back(std::move(member)); 154 } 155 } 156 asyncResp->res.jsonValue["Members@odata.count"] = 157 memberArray.size(); 158 }); 159 }); 160 } 161 162 } // namespace redfish 163