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