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
getRoleFromPrivileges(std::string_view priv)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>
getAssignedPrivFromRole(std::string_view role)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
requestRoutesRoles(App & app)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
requestRoutesRoleCollection(App & app)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