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"] = 106 nlohmann::json::array(); 107 asyncResp->res.jsonValue["IsPredefined"] = true; 108 asyncResp->res.jsonValue["Id"] = roleId; 109 asyncResp->res.jsonValue["RoleId"] = roleId; 110 asyncResp->res.jsonValue["@odata.id"] = boost::urls::format( 111 "/redfish/v1/AccountService/Roles/{}", roleId); 112 asyncResp->res.jsonValue["AssignedPrivileges"] = 113 std::move(*privArray); 114 }); 115 } 116 117 inline void requestRoutesRoleCollection(App& app) 118 { 119 BMCWEB_ROUTE(app, "/redfish/v1/AccountService/Roles/") 120 .privileges(redfish::privileges::getRoleCollection) 121 .methods(boost::beast::http::verb::get)( 122 [&app](const crow::Request& req, 123 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 124 if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 125 { 126 return; 127 } 128 129 asyncResp->res.jsonValue["@odata.id"] = 130 "/redfish/v1/AccountService/Roles"; 131 asyncResp->res.jsonValue["@odata.type"] = 132 "#RoleCollection.RoleCollection"; 133 asyncResp->res.jsonValue["Name"] = "Roles Collection"; 134 asyncResp->res.jsonValue["Description"] = "BMC User Roles"; 135 136 sdbusplus::asio::getProperty<std::vector<std::string>>( 137 *crow::connections::systemBus, 138 "xyz.openbmc_project.User.Manager", 139 "/xyz/openbmc_project/user", 140 "xyz.openbmc_project.User.Manager", "AllPrivileges", 141 [asyncResp](const boost::system::error_code& ec, 142 const std::vector<std::string>& privList) { 143 if (ec) 144 { 145 messages::internalError(asyncResp->res); 146 return; 147 } 148 nlohmann::json& memberArray = 149 asyncResp->res.jsonValue["Members"]; 150 memberArray = nlohmann::json::array(); 151 for (const std::string& priv : privList) 152 { 153 std::string role = getRoleFromPrivileges(priv); 154 if (!role.empty()) 155 { 156 nlohmann::json::object_t member; 157 member["@odata.id"] = boost::urls::format( 158 "/redfish/v1/AccountService/Roles/{}", 159 role); 160 memberArray.emplace_back(std::move(member)); 161 } 162 } 163 asyncResp->res.jsonValue["Members@odata.count"] = 164 memberArray.size(); 165 }); 166 }); 167 } 168 169 } // namespace redfish 170