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