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 dbus::utility::getProperty<std::vector<std::string>>( 137 "xyz.openbmc_project.User.Manager", 138 "/xyz/openbmc_project/user", 139 "xyz.openbmc_project.User.Manager", "AllPrivileges", 140 [asyncResp](const boost::system::error_code& ec, 141 const std::vector<std::string>& privList) { 142 if (ec) 143 { 144 messages::internalError(asyncResp->res); 145 return; 146 } 147 nlohmann::json& memberArray = 148 asyncResp->res.jsonValue["Members"]; 149 memberArray = nlohmann::json::array(); 150 for (const std::string& priv : privList) 151 { 152 std::string role = getRoleFromPrivileges(priv); 153 if (!role.empty()) 154 { 155 nlohmann::json::object_t member; 156 member["@odata.id"] = boost::urls::format( 157 "/redfish/v1/AccountService/Roles/{}", 158 role); 159 memberArray.emplace_back(std::move(member)); 160 } 161 } 162 asyncResp->res.jsonValue["Members@odata.count"] = 163 memberArray.size(); 164 }); 165 }); 166 } 167 168 } // namespace redfish 169