xref: /openbmc/bmcweb/redfish-core/lib/roles.hpp (revision 80e6e25e7d721fa03fcc2b194881d8d8a64fe416)
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