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