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 "node.hpp" 19 20 #include <variant> 21 22 namespace redfish 23 { 24 25 inline std::string getRoleFromPrivileges(std::string_view priv) 26 { 27 if (priv == "priv-admin") 28 { 29 return "Administrator"; 30 } 31 if (priv == "priv-user") 32 { 33 return "ReadOnly"; 34 } 35 if (priv == "priv-operator") 36 { 37 return "Operator"; 38 } 39 if (priv == "priv-noaccess") 40 { 41 return "NoAccess"; 42 } 43 return ""; 44 } 45 46 inline bool getAssignedPrivFromRole(std::string_view role, 47 nlohmann::json& privArray) 48 { 49 if (role == "Administrator") 50 { 51 privArray = {"Login", "ConfigureManager", "ConfigureUsers", 52 "ConfigureSelf", "ConfigureComponents"}; 53 } 54 else if (role == "Operator") 55 { 56 privArray = {"Login", "ConfigureSelf", "ConfigureComponents"}; 57 } 58 else if (role == "ReadOnly") 59 { 60 privArray = {"Login", "ConfigureSelf"}; 61 } 62 else if (role == "NoAccess") 63 { 64 privArray = nlohmann::json::array(); 65 } 66 else 67 { 68 return false; 69 } 70 return true; 71 } 72 73 class Roles : public Node 74 { 75 public: 76 Roles(App& app) : 77 Node(app, "/redfish/v1/AccountService/Roles/<str>/", std::string()) 78 { 79 entityPrivileges = { 80 {boost::beast::http::verb::get, {{"Login"}}}, 81 {boost::beast::http::verb::head, {{"Login"}}}, 82 {boost::beast::http::verb::patch, {{"ConfigureManager"}}}, 83 {boost::beast::http::verb::put, {{"ConfigureManager"}}}, 84 {boost::beast::http::verb::delete_, {{"ConfigureManager"}}}, 85 {boost::beast::http::verb::post, {{"ConfigureManager"}}}}; 86 } 87 88 private: 89 void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 90 const crow::Request&, 91 const std::vector<std::string>& params) override 92 { 93 if (params.size() != 1) 94 { 95 messages::internalError(asyncResp->res); 96 97 return; 98 } 99 const std::string& roleId = params[0]; 100 nlohmann::json privArray = nlohmann::json::array(); 101 if (false == getAssignedPrivFromRole(roleId, privArray)) 102 { 103 messages::resourceNotFound(asyncResp->res, "Role", roleId); 104 105 return; 106 } 107 108 asyncResp->res.jsonValue = { 109 {"@odata.type", "#Role.v1_2_2.Role"}, 110 {"Name", "User Role"}, 111 {"Description", roleId + " User Role"}, 112 {"OemPrivileges", nlohmann::json::array()}, 113 {"IsPredefined", true}, 114 {"Id", roleId}, 115 {"RoleId", roleId}, 116 {"@odata.id", "/redfish/v1/AccountService/Roles/" + roleId}, 117 {"AssignedPrivileges", std::move(privArray)}}; 118 } 119 }; 120 121 class RoleCollection : public Node 122 { 123 public: 124 RoleCollection(App& app) : Node(app, "/redfish/v1/AccountService/Roles/") 125 { 126 entityPrivileges = { 127 {boost::beast::http::verb::get, {{"Login"}}}, 128 {boost::beast::http::verb::head, {{"Login"}}}, 129 {boost::beast::http::verb::patch, {{"ConfigureManager"}}}, 130 {boost::beast::http::verb::put, {{"ConfigureManager"}}}, 131 {boost::beast::http::verb::delete_, {{"ConfigureManager"}}}, 132 {boost::beast::http::verb::post, {{"ConfigureManager"}}}}; 133 } 134 135 private: 136 void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 137 const crow::Request&, const std::vector<std::string>&) override 138 { 139 140 asyncResp->res.jsonValue = { 141 {"@odata.id", "/redfish/v1/AccountService/Roles"}, 142 {"@odata.type", "#RoleCollection.RoleCollection"}, 143 {"Name", "Roles Collection"}, 144 {"Description", "BMC User Roles"}}; 145 146 crow::connections::systemBus->async_method_call( 147 [asyncResp](const boost::system::error_code ec, 148 const std::variant<std::vector<std::string>>& resp) { 149 if (ec) 150 { 151 messages::internalError(asyncResp->res); 152 return; 153 } 154 nlohmann::json& memberArray = 155 asyncResp->res.jsonValue["Members"]; 156 memberArray = nlohmann::json::array(); 157 const std::vector<std::string>* privList = 158 std::get_if<std::vector<std::string>>(&resp); 159 if (privList == nullptr) 160 { 161 messages::internalError(asyncResp->res); 162 return; 163 } 164 for (const std::string& priv : *privList) 165 { 166 std::string role = getRoleFromPrivileges(priv); 167 if (!role.empty()) 168 { 169 memberArray.push_back( 170 {{"@odata.id", 171 "/redfish/v1/AccountService/Roles/" + role}}); 172 } 173 } 174 asyncResp->res.jsonValue["Members@odata.count"] = 175 memberArray.size(); 176 }, 177 "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user", 178 "org.freedesktop.DBus.Properties", "Get", 179 "xyz.openbmc_project.User.Manager", "AllPrivileges"); 180 } 181 }; 182 183 } // namespace redfish 184