xref: /openbmc/bmcweb/features/redfish/lib/account_service.hpp (revision b9b2e0b2119e6d589f5f6981f853dbcc231cd899)
188d16c9aSLewanczyk, Dawid /*
288d16c9aSLewanczyk, Dawid // Copyright (c) 2018 Intel Corporation
388d16c9aSLewanczyk, Dawid //
488d16c9aSLewanczyk, Dawid // Licensed under the Apache License, Version 2.0 (the "License");
588d16c9aSLewanczyk, Dawid // you may not use this file except in compliance with the License.
688d16c9aSLewanczyk, Dawid // You may obtain a copy of the License at
788d16c9aSLewanczyk, Dawid //
888d16c9aSLewanczyk, Dawid //      http://www.apache.org/licenses/LICENSE-2.0
988d16c9aSLewanczyk, Dawid //
1088d16c9aSLewanczyk, Dawid // Unless required by applicable law or agreed to in writing, software
1188d16c9aSLewanczyk, Dawid // distributed under the License is distributed on an "AS IS" BASIS,
1288d16c9aSLewanczyk, Dawid // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1388d16c9aSLewanczyk, Dawid // See the License for the specific language governing permissions and
1488d16c9aSLewanczyk, Dawid // limitations under the License.
1588d16c9aSLewanczyk, Dawid */
1688d16c9aSLewanczyk, Dawid #pragma once
1788d16c9aSLewanczyk, Dawid #include "node.hpp"
1888d16c9aSLewanczyk, Dawid 
19*b9b2e0b2SEd Tanous #include <openbmc_dbus_rest.hpp>
20*b9b2e0b2SEd Tanous 
211abe55efSEd Tanous namespace redfish
221abe55efSEd Tanous {
2388d16c9aSLewanczyk, Dawid 
24*b9b2e0b2SEd Tanous using ManagedObjectType = std::vector<std::pair<
25*b9b2e0b2SEd Tanous     sdbusplus::message::object_path,
26*b9b2e0b2SEd Tanous     boost::container::flat_map<
27*b9b2e0b2SEd Tanous         std::string, boost::container::flat_map<
28*b9b2e0b2SEd Tanous                          std::string, sdbusplus::message::variant<bool>>>>>;
29*b9b2e0b2SEd Tanous 
301abe55efSEd Tanous class AccountService : public Node
311abe55efSEd Tanous {
3288d16c9aSLewanczyk, Dawid   public:
331abe55efSEd Tanous     AccountService(CrowApp& app) : Node(app, "/redfish/v1/AccountService/")
341abe55efSEd Tanous     {
35c1a46bd2SBorawski.Lukasz         Node::json["@odata.id"] = "/redfish/v1/AccountService";
36c1a46bd2SBorawski.Lukasz         Node::json["@odata.type"] = "#AccountService.v1_1_0.AccountService";
37c1a46bd2SBorawski.Lukasz         Node::json["@odata.context"] =
3888d16c9aSLewanczyk, Dawid             "/redfish/v1/$metadata#AccountService.AccountService";
39c1a46bd2SBorawski.Lukasz         Node::json["Id"] = "AccountService";
40c1a46bd2SBorawski.Lukasz         Node::json["Description"] = "BMC User Accounts";
41c1a46bd2SBorawski.Lukasz         Node::json["Name"] = "Account Service";
42c1a46bd2SBorawski.Lukasz         Node::json["ServiceEnabled"] = true;
43c1a46bd2SBorawski.Lukasz         Node::json["MinPasswordLength"] = 1;
44c1a46bd2SBorawski.Lukasz         Node::json["MaxPasswordLength"] = 20;
451abe55efSEd Tanous         Node::json["Accounts"]["@odata.id"] =
461abe55efSEd Tanous             "/redfish/v1/AccountService/Accounts";
47c1a46bd2SBorawski.Lukasz         Node::json["Roles"]["@odata.id"] = "/redfish/v1/AccountService/Roles";
483ebd75f7SEd Tanous 
493ebd75f7SEd Tanous         entityPrivileges = {
504b1b8683SBorawski.Lukasz             {boost::beast::http::verb::get,
514b1b8683SBorawski.Lukasz              {{"ConfigureUsers"}, {"ConfigureManager"}}},
52e0d918bcSEd Tanous             {boost::beast::http::verb::head, {{"Login"}}},
53e0d918bcSEd Tanous             {boost::beast::http::verb::patch, {{"ConfigureUsers"}}},
54e0d918bcSEd Tanous             {boost::beast::http::verb::put, {{"ConfigureUsers"}}},
55e0d918bcSEd Tanous             {boost::beast::http::verb::delete_, {{"ConfigureUsers"}}},
56e0d918bcSEd Tanous             {boost::beast::http::verb::post, {{"ConfigureUsers"}}}};
5788d16c9aSLewanczyk, Dawid     }
5888d16c9aSLewanczyk, Dawid 
5988d16c9aSLewanczyk, Dawid   private:
6055c7b7a2SEd Tanous     void doGet(crow::Response& res, const crow::Request& req,
611abe55efSEd Tanous                const std::vector<std::string>& params) override
621abe55efSEd Tanous     {
6355c7b7a2SEd Tanous         res.jsonValue = Node::json;
6488d16c9aSLewanczyk, Dawid         res.end();
6588d16c9aSLewanczyk, Dawid     }
6688d16c9aSLewanczyk, Dawid };
67*b9b2e0b2SEd Tanous class AccountsCollection : public Node
68*b9b2e0b2SEd Tanous {
69*b9b2e0b2SEd Tanous   public:
70*b9b2e0b2SEd Tanous     AccountsCollection(CrowApp& app) :
71*b9b2e0b2SEd Tanous         Node(app, "/redfish/v1/AccountService/Accounts/")
72*b9b2e0b2SEd Tanous     {
73*b9b2e0b2SEd Tanous 
74*b9b2e0b2SEd Tanous         Node::json = {{"@odata.context", "/redfish/v1/"
75*b9b2e0b2SEd Tanous                                          "$metadata#ManagerAccountCollection."
76*b9b2e0b2SEd Tanous                                          "ManagerAccountCollection"},
77*b9b2e0b2SEd Tanous                       {"@odata.id", "/redfish/v1/AccountService/Accounts"},
78*b9b2e0b2SEd Tanous                       {"@odata.type", "#ManagerAccountCollection."
79*b9b2e0b2SEd Tanous                                       "ManagerAccountCollection"},
80*b9b2e0b2SEd Tanous                       {"Name", "Accounts Collection"},
81*b9b2e0b2SEd Tanous                       {"Description", "BMC User Accounts"}};
82*b9b2e0b2SEd Tanous 
83*b9b2e0b2SEd Tanous         entityPrivileges = {
84*b9b2e0b2SEd Tanous             {boost::beast::http::verb::get,
85*b9b2e0b2SEd Tanous              {{"ConfigureUsers"}, {"ConfigureManager"}}},
86*b9b2e0b2SEd Tanous             {boost::beast::http::verb::head, {{"Login"}}},
87*b9b2e0b2SEd Tanous             {boost::beast::http::verb::patch, {{"ConfigureUsers"}}},
88*b9b2e0b2SEd Tanous             {boost::beast::http::verb::put, {{"ConfigureUsers"}}},
89*b9b2e0b2SEd Tanous             {boost::beast::http::verb::delete_, {{"ConfigureUsers"}}},
90*b9b2e0b2SEd Tanous             {boost::beast::http::verb::post, {{"ConfigureUsers"}}}};
91*b9b2e0b2SEd Tanous     }
92*b9b2e0b2SEd Tanous 
93*b9b2e0b2SEd Tanous   private:
94*b9b2e0b2SEd Tanous     void doGet(crow::Response& res, const crow::Request& req,
95*b9b2e0b2SEd Tanous                const std::vector<std::string>& params) override
96*b9b2e0b2SEd Tanous     {
97*b9b2e0b2SEd Tanous         res.jsonValue = Node::json;
98*b9b2e0b2SEd Tanous         auto asyncResp = std::make_shared<AsyncResp>(res);
99*b9b2e0b2SEd Tanous         crow::connections::systemBus->async_method_call(
100*b9b2e0b2SEd Tanous             [asyncResp](const boost::system::error_code ec,
101*b9b2e0b2SEd Tanous                         const ManagedObjectType& users) {
102*b9b2e0b2SEd Tanous                 if (ec)
103*b9b2e0b2SEd Tanous                 {
104*b9b2e0b2SEd Tanous                     asyncResp->res.result(
105*b9b2e0b2SEd Tanous                         boost::beast::http::status::internal_server_error);
106*b9b2e0b2SEd Tanous                     return;
107*b9b2e0b2SEd Tanous                 }
108*b9b2e0b2SEd Tanous 
109*b9b2e0b2SEd Tanous                 nlohmann::json& memberArray =
110*b9b2e0b2SEd Tanous                     asyncResp->res.jsonValue["Members"];
111*b9b2e0b2SEd Tanous                 memberArray = nlohmann::json::array();
112*b9b2e0b2SEd Tanous 
113*b9b2e0b2SEd Tanous                 asyncResp->res.jsonValue["Members@odata.count"] = users.size();
114*b9b2e0b2SEd Tanous                 for (auto& user : users)
115*b9b2e0b2SEd Tanous                 {
116*b9b2e0b2SEd Tanous                     const std::string& path =
117*b9b2e0b2SEd Tanous                         static_cast<const std::string&>(user.first);
118*b9b2e0b2SEd Tanous                     std::size_t lastIndex = path.rfind("/");
119*b9b2e0b2SEd Tanous                     if (lastIndex == std::string::npos)
120*b9b2e0b2SEd Tanous                     {
121*b9b2e0b2SEd Tanous                         lastIndex = 0;
122*b9b2e0b2SEd Tanous                     }
123*b9b2e0b2SEd Tanous                     else
124*b9b2e0b2SEd Tanous                     {
125*b9b2e0b2SEd Tanous                         lastIndex += 1;
126*b9b2e0b2SEd Tanous                     }
127*b9b2e0b2SEd Tanous                     memberArray.push_back(
128*b9b2e0b2SEd Tanous                         {{"@odata.id", "/redfish/v1/AccountService/Accounts/" +
129*b9b2e0b2SEd Tanous                                            path.substr(lastIndex)}});
130*b9b2e0b2SEd Tanous                 }
131*b9b2e0b2SEd Tanous             },
132*b9b2e0b2SEd Tanous             "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
133*b9b2e0b2SEd Tanous             "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
134*b9b2e0b2SEd Tanous     }
135*b9b2e0b2SEd Tanous };
136*b9b2e0b2SEd Tanous 
137*b9b2e0b2SEd Tanous class ManagerAccount : public Node
138*b9b2e0b2SEd Tanous {
139*b9b2e0b2SEd Tanous   public:
140*b9b2e0b2SEd Tanous     ManagerAccount(CrowApp& app) :
141*b9b2e0b2SEd Tanous         Node(app, "/redfish/v1/AccountService/Accounts/<str>/", std::string())
142*b9b2e0b2SEd Tanous     {
143*b9b2e0b2SEd Tanous         Node::json = {{"@odata.context",
144*b9b2e0b2SEd Tanous                        "/redfish/v1/$metadata#ManagerAccount.ManagerAccount"},
145*b9b2e0b2SEd Tanous                       {"@odata.type", "#ManagerAccount.v1_0_3.ManagerAccount"},
146*b9b2e0b2SEd Tanous 
147*b9b2e0b2SEd Tanous                       {"Name", "User Account"},
148*b9b2e0b2SEd Tanous                       {"Description", "User Account"},
149*b9b2e0b2SEd Tanous                       {"Enabled", false},
150*b9b2e0b2SEd Tanous                       {"Password", nullptr},
151*b9b2e0b2SEd Tanous                       {"RoleId", "Administrator"},
152*b9b2e0b2SEd Tanous                       {"Links",
153*b9b2e0b2SEd Tanous                        {{"Role",
154*b9b2e0b2SEd Tanous                          {{"@odata.id", "/redfish/v1/AccountService/Roles/"
155*b9b2e0b2SEd Tanous                                         "Administrator"}}}}}};
156*b9b2e0b2SEd Tanous 
157*b9b2e0b2SEd Tanous         entityPrivileges = {
158*b9b2e0b2SEd Tanous             {boost::beast::http::verb::get,
159*b9b2e0b2SEd Tanous              {{"ConfigureUsers"}, {"ConfigureManager"}, {"ConfigureSelf"}}},
160*b9b2e0b2SEd Tanous             {boost::beast::http::verb::head, {{"Login"}}},
161*b9b2e0b2SEd Tanous             {boost::beast::http::verb::patch, {{"ConfigureUsers"}}},
162*b9b2e0b2SEd Tanous             {boost::beast::http::verb::put, {{"ConfigureUsers"}}},
163*b9b2e0b2SEd Tanous             {boost::beast::http::verb::delete_, {{"ConfigureUsers"}}},
164*b9b2e0b2SEd Tanous             {boost::beast::http::verb::post, {{"ConfigureUsers"}}}};
165*b9b2e0b2SEd Tanous     }
166*b9b2e0b2SEd Tanous 
167*b9b2e0b2SEd Tanous   private:
168*b9b2e0b2SEd Tanous     void doGet(crow::Response& res, const crow::Request& req,
169*b9b2e0b2SEd Tanous                const std::vector<std::string>& params) override
170*b9b2e0b2SEd Tanous     {
171*b9b2e0b2SEd Tanous         res.jsonValue = Node::json;
172*b9b2e0b2SEd Tanous         auto asyncResp = std::make_shared<AsyncResp>(res);
173*b9b2e0b2SEd Tanous 
174*b9b2e0b2SEd Tanous         if (params.size() != 1)
175*b9b2e0b2SEd Tanous         {
176*b9b2e0b2SEd Tanous             res.result(boost::beast::http::status::internal_server_error);
177*b9b2e0b2SEd Tanous             return;
178*b9b2e0b2SEd Tanous         }
179*b9b2e0b2SEd Tanous 
180*b9b2e0b2SEd Tanous         crow::connections::systemBus->async_method_call(
181*b9b2e0b2SEd Tanous             [asyncResp, accountName{std::string(params[0])}](
182*b9b2e0b2SEd Tanous                 const boost::system::error_code ec,
183*b9b2e0b2SEd Tanous                 const ManagedObjectType& users) {
184*b9b2e0b2SEd Tanous                 if (ec)
185*b9b2e0b2SEd Tanous                 {
186*b9b2e0b2SEd Tanous                     asyncResp->res.result(
187*b9b2e0b2SEd Tanous                         boost::beast::http::status::internal_server_error);
188*b9b2e0b2SEd Tanous                     return;
189*b9b2e0b2SEd Tanous                 }
190*b9b2e0b2SEd Tanous 
191*b9b2e0b2SEd Tanous                 for (auto& user : users)
192*b9b2e0b2SEd Tanous                 {
193*b9b2e0b2SEd Tanous                     const std::string& path =
194*b9b2e0b2SEd Tanous                         static_cast<const std::string&>(user.first);
195*b9b2e0b2SEd Tanous                     std::size_t lastIndex = path.rfind("/");
196*b9b2e0b2SEd Tanous                     if (lastIndex == std::string::npos)
197*b9b2e0b2SEd Tanous                     {
198*b9b2e0b2SEd Tanous                         lastIndex = 0;
199*b9b2e0b2SEd Tanous                     }
200*b9b2e0b2SEd Tanous                     else
201*b9b2e0b2SEd Tanous                     {
202*b9b2e0b2SEd Tanous                         lastIndex += 1;
203*b9b2e0b2SEd Tanous                     }
204*b9b2e0b2SEd Tanous                     if (path.substr(lastIndex) == accountName)
205*b9b2e0b2SEd Tanous                     {
206*b9b2e0b2SEd Tanous                         asyncResp->res.jsonValue["@odata.id"] =
207*b9b2e0b2SEd Tanous                             "/redfish/v1/AccountService/Accounts/" +
208*b9b2e0b2SEd Tanous                             accountName;
209*b9b2e0b2SEd Tanous                         asyncResp->res.jsonValue["Id"] = accountName;
210*b9b2e0b2SEd Tanous                         asyncResp->res.jsonValue["UserName"] = accountName;
211*b9b2e0b2SEd Tanous 
212*b9b2e0b2SEd Tanous                         return;
213*b9b2e0b2SEd Tanous                     }
214*b9b2e0b2SEd Tanous                 }
215*b9b2e0b2SEd Tanous 
216*b9b2e0b2SEd Tanous                 asyncResp->res.result(boost::beast::http::status::not_found);
217*b9b2e0b2SEd Tanous             },
218*b9b2e0b2SEd Tanous             "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
219*b9b2e0b2SEd Tanous             "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
220*b9b2e0b2SEd Tanous     }
221*b9b2e0b2SEd Tanous };
22288d16c9aSLewanczyk, Dawid 
22388d16c9aSLewanczyk, Dawid } // namespace redfish
224