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