blob: 9863794e6206a93c60e3e87bdca7621bae8e9508 [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"
Ed Tanous1abe55e2018-09-05 08:30:59 -070022
Ed Tanousa0803ef2018-08-29 13:29:23 -070023#include <error_messages.hpp>
24
Gunnar Mills1214b7e2020-06-04 10:11:30 -050025#include <vector>
Borawski.Lukasz86e1b662018-01-19 14:22:14 +010026
Ed Tanous1abe55e2018-09-05 08:30:59 -070027namespace redfish
28{
Borawski.Lukasz86e1b662018-01-19 14:22:14 +010029
30/**
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020031 * AsyncResp
32 * Gathers data needed for response processing after async calls are done
33 */
Ed Tanous1abe55e2018-09-05 08:30:59 -070034class AsyncResp
35{
36 public:
37 AsyncResp(crow::Response& response) : res(response)
Gunnar Mills1214b7e2020-06-04 10:11:30 -050038 {}
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020039
Ed Tanous1abe55e2018-09-05 08:30:59 -070040 ~AsyncResp()
41 {
42 res.end();
43 }
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020044
Ed Tanous1abe55e2018-09-05 08:30:59 -070045 crow::Response& res;
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020046};
47
48/**
Borawski.Lukasz86e1b662018-01-19 14:22:14 +010049 * @brief Abstract class used for implementing Redfish nodes.
50 *
51 */
Ed Tanous1abe55e2018-09-05 08:30:59 -070052class Node
53{
54 public:
55 template <typename... Params>
Ed Tanouscb13a392020-07-25 19:02:03 +000056 Node(App& app, std::string&& entityUrl, [[maybe_unused]] Params... paramsIn)
Ed Tanous1abe55e2018-09-05 08:30:59 -070057 {
Tanousf00032d2018-11-05 01:18:10 -030058 crow::DynamicRule& get = app.routeDynamic(entityUrl.c_str());
59 getRule = &get;
Ed Tanousb41187f2019-10-24 16:30:02 -070060 get.methods(boost::beast::http::verb::get)(
61 [this](const crow::Request& req, crow::Response& res,
62 Params... params) {
63 std::vector<std::string> paramVec = {params...};
64 doGet(res, req, paramVec);
65 });
Tanousf00032d2018-11-05 01:18:10 -030066
67 crow::DynamicRule& patch = app.routeDynamic(entityUrl.c_str());
68 patchRule = &patch;
Ed Tanousb41187f2019-10-24 16:30:02 -070069 patch.methods(boost::beast::http::verb::patch)(
70 [this](const crow::Request& req, crow::Response& res,
71 Params... params) {
72 std::vector<std::string> paramVec = {params...};
73 doPatch(res, req, paramVec);
74 });
Tanousf00032d2018-11-05 01:18:10 -030075
76 crow::DynamicRule& post = app.routeDynamic(entityUrl.c_str());
77 postRule = &post;
Ed Tanousb41187f2019-10-24 16:30:02 -070078 post.methods(boost::beast::http::verb::post)(
79 [this](const crow::Request& req, crow::Response& res,
80 Params... params) {
81 std::vector<std::string> paramVec = {params...};
82 doPost(res, req, paramVec);
83 });
Tanousf00032d2018-11-05 01:18:10 -030084
Adrian Ambrożewicz15302612020-07-16 11:24:47 +020085 crow::DynamicRule& put = app.routeDynamic(entityUrl.c_str());
86 putRule = &put;
87 put.methods(boost::beast::http::verb::put)(
88 [this](const crow::Request& req, crow::Response& res,
89 Params... params) {
90 std::vector<std::string> paramVec = {params...};
91 doPut(res, req, paramVec);
92 });
93
Ed Tanous2c70f802020-09-28 14:29:23 -070094 crow::DynamicRule& deleteR = app.routeDynamic(entityUrl.c_str());
95 deleteRule = &deleteR;
96 deleteR.methods(boost::beast::http::verb::delete_)(
Ed Tanousb41187f2019-10-24 16:30:02 -070097 [this](const crow::Request& req, crow::Response& res,
98 Params... params) {
99 std::vector<std::string> paramVec = {params...};
100 doDelete(res, req, paramVec);
101 });
Tanousf00032d2018-11-05 01:18:10 -0300102 }
103
104 void initPrivileges()
105 {
106 auto it = entityPrivileges.find(boost::beast::http::verb::get);
107 if (it != entityPrivileges.end())
108 {
109 if (getRule != nullptr)
110 {
Ed Tanous23a21a12020-07-25 04:45:05 +0000111 getRule->privileges(it->second);
Tanousf00032d2018-11-05 01:18:10 -0300112 }
113 }
114 it = entityPrivileges.find(boost::beast::http::verb::post);
115 if (it != entityPrivileges.end())
116 {
117 if (postRule != nullptr)
118 {
Ed Tanous23a21a12020-07-25 04:45:05 +0000119 postRule->privileges(it->second);
Tanousf00032d2018-11-05 01:18:10 -0300120 }
121 }
122 it = entityPrivileges.find(boost::beast::http::verb::patch);
123 if (it != entityPrivileges.end())
124 {
125 if (patchRule != nullptr)
126 {
Ed Tanous23a21a12020-07-25 04:45:05 +0000127 patchRule->privileges(it->second);
Tanousf00032d2018-11-05 01:18:10 -0300128 }
129 }
Adrian Ambrożewicz15302612020-07-16 11:24:47 +0200130 it = entityPrivileges.find(boost::beast::http::verb::put);
131 if (it != entityPrivileges.end())
132 {
133 if (putRule != nullptr)
134 {
Ed Tanous23a21a12020-07-25 04:45:05 +0000135 putRule->privileges(it->second);
Adrian Ambrożewicz15302612020-07-16 11:24:47 +0200136 }
137 }
Tanousf00032d2018-11-05 01:18:10 -0300138 it = entityPrivileges.find(boost::beast::http::verb::delete_);
139 if (it != entityPrivileges.end())
140 {
141 if (deleteRule != nullptr)
142 {
Ed Tanous23a21a12020-07-25 04:45:05 +0000143 deleteRule->privileges(it->second);
Tanousf00032d2018-11-05 01:18:10 -0300144 }
145 }
Borawski.Lukaszc1a46bd2018-02-08 13:31:59 +0100146 }
Ed Tanouscbbfa962018-03-13 16:46:28 -0700147
Ed Tanous1abe55e2018-09-05 08:30:59 -0700148 virtual ~Node() = default;
Borawski.Lukaszc1a46bd2018-02-08 13:31:59 +0100149
Ed Tanous1abe55e2018-09-05 08:30:59 -0700150 OperationMap entityPrivileges;
Borawski.Lukasz86e1b662018-01-19 14:22:14 +0100151
Tanousf00032d2018-11-05 01:18:10 -0300152 crow::DynamicRule* getRule = nullptr;
153 crow::DynamicRule* postRule = nullptr;
154 crow::DynamicRule* patchRule = nullptr;
Adrian Ambrożewicz15302612020-07-16 11:24:47 +0200155 crow::DynamicRule* putRule = nullptr;
Tanousf00032d2018-11-05 01:18:10 -0300156 crow::DynamicRule* deleteRule = nullptr;
157
Ed Tanous1abe55e2018-09-05 08:30:59 -0700158 protected:
159 // Node is designed to be an abstract class, so doGet is pure virtual
Ed Tanouscb13a392020-07-25 19:02:03 +0000160 virtual void doGet(crow::Response& res, const crow::Request&,
161 const std::vector<std::string>&)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700162 {
163 res.result(boost::beast::http::status::method_not_allowed);
Borawski.Lukasz86e1b662018-01-19 14:22:14 +0100164 res.end();
165 }
Ed Tanous1abe55e2018-09-05 08:30:59 -0700166
Ed Tanouscb13a392020-07-25 19:02:03 +0000167 virtual void doPatch(crow::Response& res, const crow::Request&,
168 const std::vector<std::string>&)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700169 {
170 res.result(boost::beast::http::status::method_not_allowed);
171 res.end();
172 }
173
Ed Tanouscb13a392020-07-25 19:02:03 +0000174 virtual void doPost(crow::Response& res, const crow::Request&,
175 const std::vector<std::string>&)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700176 {
177 res.result(boost::beast::http::status::method_not_allowed);
178 res.end();
179 }
180
Ed Tanouscb13a392020-07-25 19:02:03 +0000181 virtual void doPut(crow::Response& res, const crow::Request&,
182 const std::vector<std::string>&)
Adrian Ambrożewicz15302612020-07-16 11:24:47 +0200183 {
184 res.result(boost::beast::http::status::method_not_allowed);
185 res.end();
186 }
187
Ed Tanouscb13a392020-07-25 19:02:03 +0000188 virtual void doDelete(crow::Response& res, const crow::Request&,
189 const std::vector<std::string>&)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700190 {
191 res.result(boost::beast::http::status::method_not_allowed);
192 res.end();
193 }
Joseph Reynolds900f9492019-11-25 15:37:29 -0600194
Joseph Reynolds3bf4e632020-02-06 14:44:32 -0600195 /* @brief Would the operation be allowed if the user did not have the
196 * ConfigureSelf Privilege? Also honors session.isConfigureSelfOnly.
Joseph Reynolds900f9492019-11-25 15:37:29 -0600197 *
198 * @param req the request
199 *
200 * @returns True if allowed, false otherwise
201 */
202 inline bool isAllowedWithoutConfigureSelf(const crow::Request& req)
203 {
RAJESWARAN THILLAIGOVINDAN61dbeef2019-12-13 04:26:54 -0600204 const std::string& userRole = req.userRole;
205 BMCWEB_LOG_DEBUG << "isAllowedWithoutConfigureSelf for the role "
206 << req.userRole;
Joseph Reynolds3bf4e632020-02-06 14:44:32 -0600207 Privileges effectiveUserPrivileges;
208 if (req.session && req.session->isConfigureSelfOnly)
209 {
210 // The session has no privileges because it is limited to
211 // configureSelfOnly and we are disregarding that privilege.
212 // Note that some operations do not require any privilege.
213 }
214 else
215 {
216 effectiveUserPrivileges = redfish::getUserPrivileges(userRole);
217 effectiveUserPrivileges.resetSinglePrivilege("ConfigureSelf");
218 }
Joseph Reynolds900f9492019-11-25 15:37:29 -0600219 const auto& requiredPrivilegesIt = entityPrivileges.find(req.method());
220 return (requiredPrivilegesIt != entityPrivileges.end()) &&
221 isOperationAllowedWithPrivileges(requiredPrivilegesIt->second,
222 effectiveUserPrivileges);
223 }
Borawski.Lukasz86e1b662018-01-19 14:22:14 +0100224};
225
Ed Tanous1abe55e2018-09-05 08:30:59 -0700226} // namespace redfish