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