xref: /openbmc/bmcweb/redfish-core/lib/roles.hpp (revision 504af5a0568171b72caf13234cc81380b261fa21)
1 // SPDX-License-Identifier: Apache-2.0
2 // SPDX-FileCopyrightText: Copyright OpenBMC Authors
3 // SPDX-FileCopyrightText: Copyright 2018 Intel Corporation
4 #pragma once
5 
6 #include "app.hpp"
7 #include "async_resp.hpp"
8 #include "dbus_utility.hpp"
9 #include "error_messages.hpp"
10 #include "http_request.hpp"
11 #include "query.hpp"
12 #include "registries/privilege_registry.hpp"
13 
14 #include <boost/beast/http/verb.hpp>
15 #include <boost/url/format.hpp>
16 #include <nlohmann/json.hpp>
17 
18 #include <memory>
19 #include <optional>
20 #include <string>
21 #include <string_view>
22 #include <utility>
23 #include <vector>
24 namespace redfish
25 {
26 
getRoleFromPrivileges(std::string_view priv)27 inline std::string getRoleFromPrivileges(std::string_view priv)
28 {
29     if (priv == "priv-admin")
30     {
31         return "Administrator";
32     }
33     if (priv == "priv-user")
34     {
35         return "ReadOnly";
36     }
37     if (priv == "priv-operator")
38     {
39         return "Operator";
40     }
41     return "";
42 }
43 
getAssignedPrivFromRole(std::string_view role)44 inline std::optional<nlohmann::json::array_t> getAssignedPrivFromRole(
45     std::string_view role)
46 {
47     nlohmann::json::array_t privArray;
48     if (role == "Administrator")
49     {
50         privArray.emplace_back("Login");
51         privArray.emplace_back("ConfigureManager");
52         privArray.emplace_back("ConfigureUsers");
53         privArray.emplace_back("ConfigureSelf");
54         privArray.emplace_back("ConfigureComponents");
55     }
56     else if (role == "Operator")
57     {
58         privArray.emplace_back("Login");
59         privArray.emplace_back("ConfigureSelf");
60         privArray.emplace_back("ConfigureComponents");
61     }
62     else if (role == "ReadOnly")
63     {
64         privArray.emplace_back("Login");
65         privArray.emplace_back("ConfigureSelf");
66     }
67     else
68     {
69         return std::nullopt;
70     }
71     return privArray;
72 }
73 
requestRoutesRoles(App & app)74 inline void requestRoutesRoles(App& app)
75 {
76     BMCWEB_ROUTE(app, "/redfish/v1/AccountService/Roles/<str>/")
77         .privileges(redfish::privileges::getRole)
78         .methods(boost::beast::http::verb::get)(
79             [&app](const crow::Request& req,
80                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
81                    const std::string& roleId) {
82                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
83                 {
84                     return;
85                 }
86 
87                 std::optional<nlohmann::json::array_t> privArray =
88                     getAssignedPrivFromRole(roleId);
89                 if (!privArray)
90                 {
91                     messages::resourceNotFound(asyncResp->res, "Role", roleId);
92 
93                     return;
94                 }
95 
96                 asyncResp->res.jsonValue["@odata.type"] = "#Role.v1_2_2.Role";
97                 asyncResp->res.jsonValue["Name"] = "User Role";
98                 asyncResp->res.jsonValue["Description"] = roleId + " User Role";
99                 asyncResp->res.jsonValue["OemPrivileges"] =
100                     nlohmann::json::array();
101                 asyncResp->res.jsonValue["IsPredefined"] = true;
102                 asyncResp->res.jsonValue["Id"] = roleId;
103                 asyncResp->res.jsonValue["RoleId"] = roleId;
104                 asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
105                     "/redfish/v1/AccountService/Roles/{}", roleId);
106                 asyncResp->res.jsonValue["AssignedPrivileges"] =
107                     std::move(*privArray);
108             });
109 }
110 
requestRoutesRoleCollection(App & app)111 inline void requestRoutesRoleCollection(App& app)
112 {
113     BMCWEB_ROUTE(app, "/redfish/v1/AccountService/Roles/")
114         .privileges(redfish::privileges::getRoleCollection)
115         .methods(boost::beast::http::verb::get)(
116             [&app](const crow::Request& req,
117                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
118                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
119                 {
120                     return;
121                 }
122 
123                 asyncResp->res.jsonValue["@odata.id"] =
124                     "/redfish/v1/AccountService/Roles";
125                 asyncResp->res.jsonValue["@odata.type"] =
126                     "#RoleCollection.RoleCollection";
127                 asyncResp->res.jsonValue["Name"] = "Roles Collection";
128                 asyncResp->res.jsonValue["Description"] = "BMC User Roles";
129 
130                 dbus::utility::getProperty<std::vector<std::string>>(
131                     "xyz.openbmc_project.User.Manager",
132                     "/xyz/openbmc_project/user",
133                     "xyz.openbmc_project.User.Manager", "AllPrivileges",
134                     [asyncResp](const boost::system::error_code& ec,
135                                 const std::vector<std::string>& privList) {
136                         if (ec)
137                         {
138                             messages::internalError(asyncResp->res);
139                             return;
140                         }
141                         nlohmann::json& memberArray =
142                             asyncResp->res.jsonValue["Members"];
143                         memberArray = nlohmann::json::array();
144                         for (const std::string& priv : privList)
145                         {
146                             std::string role = getRoleFromPrivileges(priv);
147                             if (!role.empty())
148                             {
149                                 nlohmann::json::object_t member;
150                                 member["@odata.id"] = boost::urls::format(
151                                     "/redfish/v1/AccountService/Roles/{}",
152                                     role);
153                                 memberArray.emplace_back(std::move(member));
154                             }
155                         }
156                         asyncResp->res.jsonValue["Members@odata.count"] =
157                             memberArray.size();
158                     });
159             });
160 }
161 
162 } // namespace redfish
163