blob: a6e1e27ed960b3d593852d97adb11b6042586c12 [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
Borawski.Lukasz86e1b662018-01-19 14:22:14 +010018#include "privileges.hpp"
19#include "token_authorization_middleware.hpp"
Borawski.Lukaszc1a46bd2018-02-08 13:31:59 +010020#include "webserver_common.hpp"
Ed Tanous1abe55e2018-09-05 08:30:59 -070021
Ed Tanousa0803ef2018-08-29 13:29:23 -070022#include <error_messages.hpp>
Ed Tanous770841b2019-02-27 10:25:45 -080023#include <vector>
Ed Tanousa0803ef2018-08-29 13:29:23 -070024
Ed Tanousc94ad492019-10-10 15:39:33 -070025#include "http_request.h"
26#include "http_response.h"
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)
39 {
40 }
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020041
Ed Tanous1abe55e2018-09-05 08:30:59 -070042 ~AsyncResp()
43 {
44 res.end();
45 }
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020046
Ed Tanous1abe55e2018-09-05 08:30:59 -070047 crow::Response& res;
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020048};
49
50/**
Borawski.Lukasz86e1b662018-01-19 14:22:14 +010051 * @brief Abstract class used for implementing Redfish nodes.
52 *
53 */
Ed Tanous1abe55e2018-09-05 08:30:59 -070054class Node
55{
56 public:
57 template <typename... Params>
Ed Tanous271584a2019-07-09 16:24:22 -070058 Node(CrowApp& app, std::string&& entityUrl, Params... paramsIn)
Ed Tanous1abe55e2018-09-05 08:30:59 -070059 {
Tanousf00032d2018-11-05 01:18:10 -030060 crow::DynamicRule& get = app.routeDynamic(entityUrl.c_str());
61 getRule = &get;
62 get.methods("GET"_method)([this](const crow::Request& req,
63 crow::Response& res,
64 Params... params) {
65 std::vector<std::string> paramVec = {params...};
66 doGet(res, req, paramVec);
67 });
68
69 crow::DynamicRule& patch = app.routeDynamic(entityUrl.c_str());
70 patchRule = &patch;
71 patch.methods("PATCH"_method)([this](const crow::Request& req,
72 crow::Response& res,
73 Params... params) {
74 std::vector<std::string> paramVec = {params...};
75 doPatch(res, req, paramVec);
76 });
77
78 crow::DynamicRule& post = app.routeDynamic(entityUrl.c_str());
79 postRule = &post;
80 post.methods("POST"_method)([this](const crow::Request& req,
81 crow::Response& res,
82 Params... params) {
83 std::vector<std::string> paramVec = {params...};
84 doPost(res, req, paramVec);
85 });
86
87 crow::DynamicRule& delete_ = app.routeDynamic(entityUrl.c_str());
88 deleteRule = &delete_;
89 delete_.methods("DELETE"_method)([this](const crow::Request& req,
90 crow::Response& res,
91 Params... params) {
92 std::vector<std::string> paramVec = {params...};
93 doDelete(res, req, paramVec);
94 });
95 }
96
97 void initPrivileges()
98 {
99 auto it = entityPrivileges.find(boost::beast::http::verb::get);
100 if (it != entityPrivileges.end())
101 {
102 if (getRule != nullptr)
103 {
104 getRule->requires(it->second);
105 }
106 }
107 it = entityPrivileges.find(boost::beast::http::verb::post);
108 if (it != entityPrivileges.end())
109 {
110 if (postRule != nullptr)
111 {
112 postRule->requires(it->second);
113 }
114 }
115 it = entityPrivileges.find(boost::beast::http::verb::patch);
116 if (it != entityPrivileges.end())
117 {
118 if (patchRule != nullptr)
119 {
120 patchRule->requires(it->second);
121 }
122 }
123 it = entityPrivileges.find(boost::beast::http::verb::delete_);
124 if (it != entityPrivileges.end())
125 {
126 if (deleteRule != nullptr)
127 {
128 deleteRule->requires(it->second);
129 }
130 }
Borawski.Lukaszc1a46bd2018-02-08 13:31:59 +0100131 }
Ed Tanouscbbfa962018-03-13 16:46:28 -0700132
Ed Tanous1abe55e2018-09-05 08:30:59 -0700133 virtual ~Node() = default;
Borawski.Lukaszc1a46bd2018-02-08 13:31:59 +0100134
Ed Tanous1abe55e2018-09-05 08:30:59 -0700135 OperationMap entityPrivileges;
Borawski.Lukasz86e1b662018-01-19 14:22:14 +0100136
Tanousf00032d2018-11-05 01:18:10 -0300137 crow::DynamicRule* getRule = nullptr;
138 crow::DynamicRule* postRule = nullptr;
139 crow::DynamicRule* patchRule = nullptr;
140 crow::DynamicRule* deleteRule = nullptr;
141
Ed Tanous1abe55e2018-09-05 08:30:59 -0700142 protected:
143 // Node is designed to be an abstract class, so doGet is pure virtual
144 virtual void doGet(crow::Response& res, const crow::Request& req,
145 const std::vector<std::string>& params)
146 {
147 res.result(boost::beast::http::status::method_not_allowed);
Borawski.Lukasz86e1b662018-01-19 14:22:14 +0100148 res.end();
149 }
Ed Tanous1abe55e2018-09-05 08:30:59 -0700150
151 virtual void doPatch(crow::Response& res, const crow::Request& req,
152 const std::vector<std::string>& params)
153 {
154 res.result(boost::beast::http::status::method_not_allowed);
155 res.end();
156 }
157
158 virtual void doPost(crow::Response& res, const crow::Request& req,
159 const std::vector<std::string>& params)
160 {
161 res.result(boost::beast::http::status::method_not_allowed);
162 res.end();
163 }
164
165 virtual void doDelete(crow::Response& res, const crow::Request& req,
166 const std::vector<std::string>& params)
167 {
168 res.result(boost::beast::http::status::method_not_allowed);
169 res.end();
170 }
Joseph Reynolds900f9492019-11-25 15:37:29 -0600171
Joseph Reynolds3bf4e632020-02-06 14:44:32 -0600172 /* @brief Would the operation be allowed if the user did not have the
173 * ConfigureSelf Privilege? Also honors session.isConfigureSelfOnly.
Joseph Reynolds900f9492019-11-25 15:37:29 -0600174 *
175 * @param req the request
176 *
177 * @returns True if allowed, false otherwise
178 */
179 inline bool isAllowedWithoutConfigureSelf(const crow::Request& req)
180 {
RAJESWARAN THILLAIGOVINDAN61dbeef2019-12-13 04:26:54 -0600181 const std::string& userRole = req.userRole;
182 BMCWEB_LOG_DEBUG << "isAllowedWithoutConfigureSelf for the role "
183 << req.userRole;
Joseph Reynolds3bf4e632020-02-06 14:44:32 -0600184 Privileges effectiveUserPrivileges;
185 if (req.session && req.session->isConfigureSelfOnly)
186 {
187 // The session has no privileges because it is limited to
188 // configureSelfOnly and we are disregarding that privilege.
189 // Note that some operations do not require any privilege.
190 }
191 else
192 {
193 effectiveUserPrivileges = redfish::getUserPrivileges(userRole);
194 effectiveUserPrivileges.resetSinglePrivilege("ConfigureSelf");
195 }
Joseph Reynolds900f9492019-11-25 15:37:29 -0600196 const auto& requiredPrivilegesIt = entityPrivileges.find(req.method());
197 return (requiredPrivilegesIt != entityPrivileges.end()) &&
198 isOperationAllowedWithPrivileges(requiredPrivilegesIt->second,
199 effectiveUserPrivileges);
200 }
Borawski.Lukasz86e1b662018-01-19 14:22:14 +0100201};
202
Ed Tanous1abe55e2018-09-05 08:30:59 -0700203} // namespace redfish