blob: d13f09785049cc0ab6dc3a287507a43a0caaeeea [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
Gunnar Mills1214b7e2020-06-04 10:11:30 -050018#include "http_request.h"
19#include "http_response.h"
20
Borawski.Lukasz86e1b662018-01-19 14:22:14 +010021#include "privileges.hpp"
Borawski.Lukaszc1a46bd2018-02-08 13:31:59 +010022#include "webserver_common.hpp"
Ed Tanous1abe55e2018-09-05 08:30:59 -070023
Ed Tanousa0803ef2018-08-29 13:29:23 -070024#include <error_messages.hpp>
25
Gunnar Mills1214b7e2020-06-04 10:11:30 -050026#include <vector>
Borawski.Lukasz86e1b662018-01-19 14:22:14 +010027
Ed Tanous1abe55e2018-09-05 08:30:59 -070028namespace redfish
29{
Borawski.Lukasz86e1b662018-01-19 14:22:14 +010030
31/**
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020032 * AsyncResp
33 * Gathers data needed for response processing after async calls are done
34 */
Ed Tanous1abe55e2018-09-05 08:30:59 -070035class AsyncResp
36{
37 public:
38 AsyncResp(crow::Response& response) : res(response)
Gunnar Mills1214b7e2020-06-04 10:11:30 -050039 {}
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020040
Ed Tanous1abe55e2018-09-05 08:30:59 -070041 ~AsyncResp()
42 {
43 res.end();
44 }
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020045
Ed Tanous1abe55e2018-09-05 08:30:59 -070046 crow::Response& res;
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020047};
48
49/**
Borawski.Lukasz86e1b662018-01-19 14:22:14 +010050 * @brief Abstract class used for implementing Redfish nodes.
51 *
52 */
Ed Tanous1abe55e2018-09-05 08:30:59 -070053class Node
54{
55 public:
56 template <typename... Params>
Ed Tanous271584a2019-07-09 16:24:22 -070057 Node(CrowApp& app, std::string&& entityUrl, Params... paramsIn)
Ed Tanous1abe55e2018-09-05 08:30:59 -070058 {
Tanousf00032d2018-11-05 01:18:10 -030059 crow::DynamicRule& get = app.routeDynamic(entityUrl.c_str());
60 getRule = &get;
Ed Tanousb41187f2019-10-24 16:30:02 -070061 get.methods(boost::beast::http::verb::get)(
62 [this](const crow::Request& req, crow::Response& res,
63 Params... params) {
64 std::vector<std::string> paramVec = {params...};
65 doGet(res, req, paramVec);
66 });
Tanousf00032d2018-11-05 01:18:10 -030067
68 crow::DynamicRule& patch = app.routeDynamic(entityUrl.c_str());
69 patchRule = &patch;
Ed Tanousb41187f2019-10-24 16:30:02 -070070 patch.methods(boost::beast::http::verb::patch)(
71 [this](const crow::Request& req, crow::Response& res,
72 Params... params) {
73 std::vector<std::string> paramVec = {params...};
74 doPatch(res, req, paramVec);
75 });
Tanousf00032d2018-11-05 01:18:10 -030076
77 crow::DynamicRule& post = app.routeDynamic(entityUrl.c_str());
78 postRule = &post;
Ed Tanousb41187f2019-10-24 16:30:02 -070079 post.methods(boost::beast::http::verb::post)(
80 [this](const crow::Request& req, crow::Response& res,
81 Params... params) {
82 std::vector<std::string> paramVec = {params...};
83 doPost(res, req, paramVec);
84 });
Tanousf00032d2018-11-05 01:18:10 -030085
Adrian Ambrożewicz15302612020-07-16 11:24:47 +020086 crow::DynamicRule& put = app.routeDynamic(entityUrl.c_str());
87 putRule = &put;
88 put.methods(boost::beast::http::verb::put)(
89 [this](const crow::Request& req, crow::Response& res,
90 Params... params) {
91 std::vector<std::string> paramVec = {params...};
92 doPut(res, req, paramVec);
93 });
94
Tanousf00032d2018-11-05 01:18:10 -030095 crow::DynamicRule& delete_ = app.routeDynamic(entityUrl.c_str());
96 deleteRule = &delete_;
Ed Tanousb41187f2019-10-24 16:30:02 -070097 delete_.methods(boost::beast::http::verb::delete_)(
98 [this](const crow::Request& req, crow::Response& res,
99 Params... params) {
100 std::vector<std::string> paramVec = {params...};
101 doDelete(res, req, paramVec);
102 });
Tanousf00032d2018-11-05 01:18:10 -0300103 }
104
105 void initPrivileges()
106 {
107 auto it = entityPrivileges.find(boost::beast::http::verb::get);
108 if (it != entityPrivileges.end())
109 {
110 if (getRule != nullptr)
111 {
112 getRule->requires(it->second);
113 }
114 }
115 it = entityPrivileges.find(boost::beast::http::verb::post);
116 if (it != entityPrivileges.end())
117 {
118 if (postRule != nullptr)
119 {
120 postRule->requires(it->second);
121 }
122 }
123 it = entityPrivileges.find(boost::beast::http::verb::patch);
124 if (it != entityPrivileges.end())
125 {
126 if (patchRule != nullptr)
127 {
128 patchRule->requires(it->second);
129 }
130 }
Adrian Ambrożewicz15302612020-07-16 11:24:47 +0200131 it = entityPrivileges.find(boost::beast::http::verb::put);
132 if (it != entityPrivileges.end())
133 {
134 if (putRule != nullptr)
135 {
136 putRule->requires(it->second);
137 }
138 }
Tanousf00032d2018-11-05 01:18:10 -0300139 it = entityPrivileges.find(boost::beast::http::verb::delete_);
140 if (it != entityPrivileges.end())
141 {
142 if (deleteRule != nullptr)
143 {
144 deleteRule->requires(it->second);
145 }
146 }
Borawski.Lukaszc1a46bd2018-02-08 13:31:59 +0100147 }
Ed Tanouscbbfa962018-03-13 16:46:28 -0700148
Ed Tanous1abe55e2018-09-05 08:30:59 -0700149 virtual ~Node() = default;
Borawski.Lukaszc1a46bd2018-02-08 13:31:59 +0100150
Ed Tanous1abe55e2018-09-05 08:30:59 -0700151 OperationMap entityPrivileges;
Borawski.Lukasz86e1b662018-01-19 14:22:14 +0100152
Tanousf00032d2018-11-05 01:18:10 -0300153 crow::DynamicRule* getRule = nullptr;
154 crow::DynamicRule* postRule = nullptr;
155 crow::DynamicRule* patchRule = nullptr;
Adrian Ambrożewicz15302612020-07-16 11:24:47 +0200156 crow::DynamicRule* putRule = nullptr;
Tanousf00032d2018-11-05 01:18:10 -0300157 crow::DynamicRule* deleteRule = nullptr;
158
Ed Tanous1abe55e2018-09-05 08:30:59 -0700159 protected:
160 // Node is designed to be an abstract class, so doGet is pure virtual
161 virtual void doGet(crow::Response& res, const crow::Request& req,
162 const std::vector<std::string>& params)
163 {
164 res.result(boost::beast::http::status::method_not_allowed);
Borawski.Lukasz86e1b662018-01-19 14:22:14 +0100165 res.end();
166 }
Ed Tanous1abe55e2018-09-05 08:30:59 -0700167
168 virtual void doPatch(crow::Response& res, const crow::Request& req,
169 const std::vector<std::string>& params)
170 {
171 res.result(boost::beast::http::status::method_not_allowed);
172 res.end();
173 }
174
175 virtual void doPost(crow::Response& res, const crow::Request& req,
176 const std::vector<std::string>& params)
177 {
178 res.result(boost::beast::http::status::method_not_allowed);
179 res.end();
180 }
181
Adrian Ambrożewicz15302612020-07-16 11:24:47 +0200182 virtual void doPut(crow::Response& res, const crow::Request& req,
183 const std::vector<std::string>& params)
184 {
185 res.result(boost::beast::http::status::method_not_allowed);
186 res.end();
187 }
188
Ed Tanous1abe55e2018-09-05 08:30:59 -0700189 virtual void doDelete(crow::Response& res, const crow::Request& req,
190 const std::vector<std::string>& params)
191 {
192 res.result(boost::beast::http::status::method_not_allowed);
193 res.end();
194 }
Joseph Reynolds900f9492019-11-25 15:37:29 -0600195
Joseph Reynolds3bf4e632020-02-06 14:44:32 -0600196 /* @brief Would the operation be allowed if the user did not have the
197 * ConfigureSelf Privilege? Also honors session.isConfigureSelfOnly.
Joseph Reynolds900f9492019-11-25 15:37:29 -0600198 *
199 * @param req the request
200 *
201 * @returns True if allowed, false otherwise
202 */
203 inline bool isAllowedWithoutConfigureSelf(const crow::Request& req)
204 {
RAJESWARAN THILLAIGOVINDAN61dbeef2019-12-13 04:26:54 -0600205 const std::string& userRole = req.userRole;
206 BMCWEB_LOG_DEBUG << "isAllowedWithoutConfigureSelf for the role "
207 << req.userRole;
Joseph Reynolds3bf4e632020-02-06 14:44:32 -0600208 Privileges effectiveUserPrivileges;
209 if (req.session && req.session->isConfigureSelfOnly)
210 {
211 // The session has no privileges because it is limited to
212 // configureSelfOnly and we are disregarding that privilege.
213 // Note that some operations do not require any privilege.
214 }
215 else
216 {
217 effectiveUserPrivileges = redfish::getUserPrivileges(userRole);
218 effectiveUserPrivileges.resetSinglePrivilege("ConfigureSelf");
219 }
Joseph Reynolds900f9492019-11-25 15:37:29 -0600220 const auto& requiredPrivilegesIt = entityPrivileges.find(req.method());
221 return (requiredPrivilegesIt != entityPrivileges.end()) &&
222 isOperationAllowedWithPrivileges(requiredPrivilegesIt->second,
223 effectiveUserPrivileges);
224 }
Borawski.Lukasz86e1b662018-01-19 14:22:14 +0100225};
226
Ed Tanous1abe55e2018-09-05 08:30:59 -0700227} // namespace redfish