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