blob: 74d511fcb688c292301d10a361dbdee7d24caf72 [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
86 crow::DynamicRule& delete_ = app.routeDynamic(entityUrl.c_str());
87 deleteRule = &delete_;
Ed Tanousb41187f2019-10-24 16:30:02 -070088 delete_.methods(boost::beast::http::verb::delete_)(
89 [this](const crow::Request& req, crow::Response& res,
90 Params... params) {
91 std::vector<std::string> paramVec = {params...};
92 doDelete(res, req, paramVec);
93 });
Tanousf00032d2018-11-05 01:18:10 -030094 }
95
96 void initPrivileges()
97 {
98 auto it = entityPrivileges.find(boost::beast::http::verb::get);
99 if (it != entityPrivileges.end())
100 {
101 if (getRule != nullptr)
102 {
103 getRule->requires(it->second);
104 }
105 }
106 it = entityPrivileges.find(boost::beast::http::verb::post);
107 if (it != entityPrivileges.end())
108 {
109 if (postRule != nullptr)
110 {
111 postRule->requires(it->second);
112 }
113 }
114 it = entityPrivileges.find(boost::beast::http::verb::patch);
115 if (it != entityPrivileges.end())
116 {
117 if (patchRule != nullptr)
118 {
119 patchRule->requires(it->second);
120 }
121 }
122 it = entityPrivileges.find(boost::beast::http::verb::delete_);
123 if (it != entityPrivileges.end())
124 {
125 if (deleteRule != nullptr)
126 {
127 deleteRule->requires(it->second);
128 }
129 }
Borawski.Lukaszc1a46bd2018-02-08 13:31:59 +0100130 }
Ed Tanouscbbfa962018-03-13 16:46:28 -0700131
Ed Tanous1abe55e2018-09-05 08:30:59 -0700132 virtual ~Node() = default;
Borawski.Lukaszc1a46bd2018-02-08 13:31:59 +0100133
Ed Tanous1abe55e2018-09-05 08:30:59 -0700134 OperationMap entityPrivileges;
Borawski.Lukasz86e1b662018-01-19 14:22:14 +0100135
Tanousf00032d2018-11-05 01:18:10 -0300136 crow::DynamicRule* getRule = nullptr;
137 crow::DynamicRule* postRule = nullptr;
138 crow::DynamicRule* patchRule = nullptr;
139 crow::DynamicRule* deleteRule = nullptr;
140
Ed Tanous1abe55e2018-09-05 08:30:59 -0700141 protected:
142 // Node is designed to be an abstract class, so doGet is pure virtual
143 virtual void doGet(crow::Response& res, const crow::Request& req,
144 const std::vector<std::string>& params)
145 {
146 res.result(boost::beast::http::status::method_not_allowed);
Borawski.Lukasz86e1b662018-01-19 14:22:14 +0100147 res.end();
148 }
Ed Tanous1abe55e2018-09-05 08:30:59 -0700149
150 virtual void doPatch(crow::Response& res, const crow::Request& req,
151 const std::vector<std::string>& params)
152 {
153 res.result(boost::beast::http::status::method_not_allowed);
154 res.end();
155 }
156
157 virtual void doPost(crow::Response& res, const crow::Request& req,
158 const std::vector<std::string>& params)
159 {
160 res.result(boost::beast::http::status::method_not_allowed);
161 res.end();
162 }
163
164 virtual void doDelete(crow::Response& res, const crow::Request& req,
165 const std::vector<std::string>& params)
166 {
167 res.result(boost::beast::http::status::method_not_allowed);
168 res.end();
169 }
Joseph Reynolds900f9492019-11-25 15:37:29 -0600170
Joseph Reynolds3bf4e632020-02-06 14:44:32 -0600171 /* @brief Would the operation be allowed if the user did not have the
172 * ConfigureSelf Privilege? Also honors session.isConfigureSelfOnly.
Joseph Reynolds900f9492019-11-25 15:37:29 -0600173 *
174 * @param req the request
175 *
176 * @returns True if allowed, false otherwise
177 */
178 inline bool isAllowedWithoutConfigureSelf(const crow::Request& req)
179 {
RAJESWARAN THILLAIGOVINDAN61dbeef2019-12-13 04:26:54 -0600180 const std::string& userRole = req.userRole;
181 BMCWEB_LOG_DEBUG << "isAllowedWithoutConfigureSelf for the role "
182 << req.userRole;
Joseph Reynolds3bf4e632020-02-06 14:44:32 -0600183 Privileges effectiveUserPrivileges;
184 if (req.session && req.session->isConfigureSelfOnly)
185 {
186 // The session has no privileges because it is limited to
187 // configureSelfOnly and we are disregarding that privilege.
188 // Note that some operations do not require any privilege.
189 }
190 else
191 {
192 effectiveUserPrivileges = redfish::getUserPrivileges(userRole);
193 effectiveUserPrivileges.resetSinglePrivilege("ConfigureSelf");
194 }
Joseph Reynolds900f9492019-11-25 15:37:29 -0600195 const auto& requiredPrivilegesIt = entityPrivileges.find(req.method());
196 return (requiredPrivilegesIt != entityPrivileges.end()) &&
197 isOperationAllowedWithPrivileges(requiredPrivilegesIt->second,
198 effectiveUserPrivileges);
199 }
Borawski.Lukasz86e1b662018-01-19 14:22:14 +0100200};
201
Ed Tanous1abe55e2018-09-05 08:30:59 -0700202} // namespace redfish