blob: 47c5cc6a1e4201db587b80df89236dc251254ea0 [file] [log] [blame]
Borawski.Lukasz86e1b662018-01-19 14:22:14 +01001/*
2// Copyright (c) 2018 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
16#pragma once
17
Ed Tanous04e438c2020-10-03 08:06:26 -070018#include "http_request.hpp"
19#include "http_response.hpp"
Borawski.Lukasz86e1b662018-01-19 14:22:14 +010020#include "privileges.hpp"
Ed Tanous1abe55e2018-09-05 08:30:59 -070021
Ed Tanousa0803ef2018-08-29 13:29:23 -070022#include <error_messages.hpp>
23
Gunnar Mills1214b7e2020-06-04 10:11:30 -050024#include <vector>
Borawski.Lukasz86e1b662018-01-19 14:22:14 +010025
Ed Tanous1abe55e2018-09-05 08:30:59 -070026namespace redfish
27{
Borawski.Lukasz86e1b662018-01-19 14:22:14 +010028
29/**
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020030 * AsyncResp
31 * Gathers data needed for response processing after async calls are done
32 */
Ed Tanous1abe55e2018-09-05 08:30:59 -070033class AsyncResp
34{
35 public:
36 AsyncResp(crow::Response& response) : res(response)
Gunnar Mills1214b7e2020-06-04 10:11:30 -050037 {}
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020038
Ed Tanous1abe55e2018-09-05 08:30:59 -070039 ~AsyncResp()
40 {
41 res.end();
42 }
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020043
Ed Tanous1abe55e2018-09-05 08:30:59 -070044 crow::Response& res;
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020045};
46
47/**
Borawski.Lukasz86e1b662018-01-19 14:22:14 +010048 * @brief Abstract class used for implementing Redfish nodes.
49 *
50 */
Ed Tanous1abe55e2018-09-05 08:30:59 -070051class Node
52{
53 public:
54 template <typename... Params>
Ed Tanouscb13a392020-07-25 19:02:03 +000055 Node(App& app, std::string&& entityUrl, [[maybe_unused]] Params... paramsIn)
Ed Tanous1abe55e2018-09-05 08:30:59 -070056 {
Tanousf00032d2018-11-05 01:18:10 -030057 crow::DynamicRule& get = app.routeDynamic(entityUrl.c_str());
58 getRule = &get;
Ed Tanousb41187f2019-10-24 16:30:02 -070059 get.methods(boost::beast::http::verb::get)(
60 [this](const crow::Request& req, crow::Response& res,
61 Params... params) {
62 std::vector<std::string> paramVec = {params...};
63 doGet(res, req, paramVec);
64 });
Tanousf00032d2018-11-05 01:18:10 -030065
66 crow::DynamicRule& patch = app.routeDynamic(entityUrl.c_str());
67 patchRule = &patch;
Ed Tanousb41187f2019-10-24 16:30:02 -070068 patch.methods(boost::beast::http::verb::patch)(
69 [this](const crow::Request& req, crow::Response& res,
70 Params... params) {
71 std::vector<std::string> paramVec = {params...};
72 doPatch(res, req, paramVec);
73 });
Tanousf00032d2018-11-05 01:18:10 -030074
75 crow::DynamicRule& post = app.routeDynamic(entityUrl.c_str());
76 postRule = &post;
Ed Tanousb41187f2019-10-24 16:30:02 -070077 post.methods(boost::beast::http::verb::post)(
78 [this](const crow::Request& req, crow::Response& res,
79 Params... params) {
80 std::vector<std::string> paramVec = {params...};
81 doPost(res, req, paramVec);
82 });
Tanousf00032d2018-11-05 01:18:10 -030083
Adrian Ambrożewicz15302612020-07-16 11:24:47 +020084 crow::DynamicRule& put = app.routeDynamic(entityUrl.c_str());
85 putRule = &put;
86 put.methods(boost::beast::http::verb::put)(
87 [this](const crow::Request& req, crow::Response& res,
88 Params... params) {
89 std::vector<std::string> paramVec = {params...};
90 doPut(res, req, paramVec);
91 });
92
Ed Tanous2c70f802020-09-28 14:29:23 -070093 crow::DynamicRule& deleteR = app.routeDynamic(entityUrl.c_str());
94 deleteRule = &deleteR;
95 deleteR.methods(boost::beast::http::verb::delete_)(
Ed Tanousb41187f2019-10-24 16:30:02 -070096 [this](const crow::Request& req, crow::Response& res,
97 Params... params) {
98 std::vector<std::string> paramVec = {params...};
99 doDelete(res, req, paramVec);
100 });
Tanousf00032d2018-11-05 01:18:10 -0300101 }
102
103 void initPrivileges()
104 {
105 auto it = entityPrivileges.find(boost::beast::http::verb::get);
106 if (it != entityPrivileges.end())
107 {
108 if (getRule != nullptr)
109 {
Ed Tanous23a21a12020-07-25 04:45:05 +0000110 getRule->privileges(it->second);
Tanousf00032d2018-11-05 01:18:10 -0300111 }
112 }
113 it = entityPrivileges.find(boost::beast::http::verb::post);
114 if (it != entityPrivileges.end())
115 {
116 if (postRule != nullptr)
117 {
Ed Tanous23a21a12020-07-25 04:45:05 +0000118 postRule->privileges(it->second);
Tanousf00032d2018-11-05 01:18:10 -0300119 }
120 }
121 it = entityPrivileges.find(boost::beast::http::verb::patch);
122 if (it != entityPrivileges.end())
123 {
124 if (patchRule != nullptr)
125 {
Ed Tanous23a21a12020-07-25 04:45:05 +0000126 patchRule->privileges(it->second);
Tanousf00032d2018-11-05 01:18:10 -0300127 }
128 }
Adrian Ambrożewicz15302612020-07-16 11:24:47 +0200129 it = entityPrivileges.find(boost::beast::http::verb::put);
130 if (it != entityPrivileges.end())
131 {
132 if (putRule != nullptr)
133 {
Ed Tanous23a21a12020-07-25 04:45:05 +0000134 putRule->privileges(it->second);
Adrian Ambrożewicz15302612020-07-16 11:24:47 +0200135 }
136 }
Tanousf00032d2018-11-05 01:18:10 -0300137 it = entityPrivileges.find(boost::beast::http::verb::delete_);
138 if (it != entityPrivileges.end())
139 {
140 if (deleteRule != nullptr)
141 {
Ed Tanous23a21a12020-07-25 04:45:05 +0000142 deleteRule->privileges(it->second);
Tanousf00032d2018-11-05 01:18:10 -0300143 }
144 }
Borawski.Lukaszc1a46bd2018-02-08 13:31:59 +0100145 }
Ed Tanouscbbfa962018-03-13 16:46:28 -0700146
Ed Tanous1abe55e2018-09-05 08:30:59 -0700147 virtual ~Node() = default;
Borawski.Lukaszc1a46bd2018-02-08 13:31:59 +0100148
Ed Tanous1abe55e2018-09-05 08:30:59 -0700149 OperationMap entityPrivileges;
Borawski.Lukasz86e1b662018-01-19 14:22:14 +0100150
Tanousf00032d2018-11-05 01:18:10 -0300151 crow::DynamicRule* getRule = nullptr;
152 crow::DynamicRule* postRule = nullptr;
153 crow::DynamicRule* patchRule = nullptr;
Adrian Ambrożewicz15302612020-07-16 11:24:47 +0200154 crow::DynamicRule* putRule = nullptr;
Tanousf00032d2018-11-05 01:18:10 -0300155 crow::DynamicRule* deleteRule = nullptr;
156
Ed Tanous1abe55e2018-09-05 08:30:59 -0700157 protected:
158 // Node is designed to be an abstract class, so doGet is pure virtual
Ed Tanouscb13a392020-07-25 19:02:03 +0000159 virtual void doGet(crow::Response& res, const crow::Request&,
160 const std::vector<std::string>&)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700161 {
162 res.result(boost::beast::http::status::method_not_allowed);
Borawski.Lukasz86e1b662018-01-19 14:22:14 +0100163 res.end();
164 }
Ed Tanous1abe55e2018-09-05 08:30:59 -0700165
Ed Tanouscb13a392020-07-25 19:02:03 +0000166 virtual void doPatch(crow::Response& res, const crow::Request&,
167 const std::vector<std::string>&)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700168 {
169 res.result(boost::beast::http::status::method_not_allowed);
170 res.end();
171 }
172
Ed Tanouscb13a392020-07-25 19:02:03 +0000173 virtual void doPost(crow::Response& res, const crow::Request&,
174 const std::vector<std::string>&)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700175 {
176 res.result(boost::beast::http::status::method_not_allowed);
177 res.end();
178 }
179
Ed Tanouscb13a392020-07-25 19:02:03 +0000180 virtual void doPut(crow::Response& res, const crow::Request&,
181 const std::vector<std::string>&)
Adrian Ambrożewicz15302612020-07-16 11:24:47 +0200182 {
183 res.result(boost::beast::http::status::method_not_allowed);
184 res.end();
185 }
186
Ed Tanouscb13a392020-07-25 19:02:03 +0000187 virtual void doDelete(crow::Response& res, const crow::Request&,
188 const std::vector<std::string>&)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700189 {
190 res.result(boost::beast::http::status::method_not_allowed);
191 res.end();
192 }
Joseph Reynolds900f9492019-11-25 15:37:29 -0600193
Joseph Reynolds3bf4e632020-02-06 14:44:32 -0600194 /* @brief Would the operation be allowed if the user did not have the
195 * ConfigureSelf Privilege? Also honors session.isConfigureSelfOnly.
Joseph Reynolds900f9492019-11-25 15:37:29 -0600196 *
197 * @param req the request
198 *
199 * @returns True if allowed, false otherwise
200 */
201 inline bool isAllowedWithoutConfigureSelf(const crow::Request& req)
202 {
RAJESWARAN THILLAIGOVINDAN61dbeef2019-12-13 04:26:54 -0600203 const std::string& userRole = req.userRole;
204 BMCWEB_LOG_DEBUG << "isAllowedWithoutConfigureSelf for the role "
205 << req.userRole;
Joseph Reynolds3bf4e632020-02-06 14:44:32 -0600206 Privileges effectiveUserPrivileges;
207 if (req.session && req.session->isConfigureSelfOnly)
208 {
209 // The session has no privileges because it is limited to
210 // configureSelfOnly and we are disregarding that privilege.
211 // Note that some operations do not require any privilege.
212 }
213 else
214 {
215 effectiveUserPrivileges = redfish::getUserPrivileges(userRole);
216 effectiveUserPrivileges.resetSinglePrivilege("ConfigureSelf");
217 }
Joseph Reynolds900f9492019-11-25 15:37:29 -0600218 const auto& requiredPrivilegesIt = entityPrivileges.find(req.method());
219 return (requiredPrivilegesIt != entityPrivileges.end()) &&
220 isOperationAllowedWithPrivileges(requiredPrivilegesIt->second,
221 effectiveUserPrivileges);
222 }
Borawski.Lukasz86e1b662018-01-19 14:22:14 +0100223};
224
Ed Tanous1abe55e2018-09-05 08:30:59 -0700225} // namespace redfish