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