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