blob: 9d383a92ab158292b47c1230d4487c6c208eba98 [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>
Joseph Reynolds8fd315a2019-09-12 12:02:33 -050023#include <sessions.hpp>
Ed Tanous770841b2019-02-27 10:25:45 -080024#include <vector>
Ed Tanousa0803ef2018-08-29 13:29:23 -070025
Ed Tanous770841b2019-02-27 10:25:45 -080026#include "crow/http_request.h"
27#include "crow/http_response.h"
Borawski.Lukasz86e1b662018-01-19 14:22:14 +010028
Ed Tanous1abe55e2018-09-05 08:30:59 -070029namespace redfish
30{
Borawski.Lukasz86e1b662018-01-19 14:22:14 +010031
32/**
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020033 * AsyncResp
34 * Gathers data needed for response processing after async calls are done
35 */
Ed Tanous1abe55e2018-09-05 08:30:59 -070036class AsyncResp
37{
38 public:
39 AsyncResp(crow::Response& response) : res(response)
40 {
41 }
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020042
Ed Tanous1abe55e2018-09-05 08:30:59 -070043 ~AsyncResp()
44 {
45 res.end();
46 }
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020047
Ed Tanous1abe55e2018-09-05 08:30:59 -070048 crow::Response& res;
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020049};
50
51/**
Borawski.Lukasz86e1b662018-01-19 14:22:14 +010052 * @brief Abstract class used for implementing Redfish nodes.
53 *
54 */
Ed Tanous1abe55e2018-09-05 08:30:59 -070055class Node
56{
57 public:
58 template <typename... Params>
59 Node(CrowApp& app, std::string&& entityUrl, Params... params)
60 {
Tanousf00032d2018-11-05 01:18:10 -030061 crow::DynamicRule& get = app.routeDynamic(entityUrl.c_str());
62 getRule = &get;
63 get.methods("GET"_method)([this](const crow::Request& req,
64 crow::Response& res,
65 Params... params) {
66 std::vector<std::string> paramVec = {params...};
67 doGet(res, req, paramVec);
68 });
69
70 crow::DynamicRule& patch = app.routeDynamic(entityUrl.c_str());
71 patchRule = &patch;
72 patch.methods("PATCH"_method)([this](const crow::Request& req,
73 crow::Response& res,
74 Params... params) {
75 std::vector<std::string> paramVec = {params...};
76 doPatch(res, req, paramVec);
77 });
78
79 crow::DynamicRule& post = app.routeDynamic(entityUrl.c_str());
80 postRule = &post;
81 post.methods("POST"_method)([this](const crow::Request& req,
82 crow::Response& res,
83 Params... params) {
84 std::vector<std::string> paramVec = {params...};
85 doPost(res, req, paramVec);
86 });
87
88 crow::DynamicRule& delete_ = app.routeDynamic(entityUrl.c_str());
89 deleteRule = &delete_;
90 delete_.methods("DELETE"_method)([this](const crow::Request& req,
91 crow::Response& res,
92 Params... params) {
93 std::vector<std::string> paramVec = {params...};
94 doDelete(res, req, paramVec);
95 });
96 }
97
98 void initPrivileges()
99 {
100 auto it = entityPrivileges.find(boost::beast::http::verb::get);
101 if (it != entityPrivileges.end())
102 {
103 if (getRule != nullptr)
104 {
105 getRule->requires(it->second);
106 }
107 }
108 it = entityPrivileges.find(boost::beast::http::verb::post);
109 if (it != entityPrivileges.end())
110 {
111 if (postRule != nullptr)
112 {
113 postRule->requires(it->second);
114 }
115 }
116 it = entityPrivileges.find(boost::beast::http::verb::patch);
117 if (it != entityPrivileges.end())
118 {
119 if (patchRule != nullptr)
120 {
121 patchRule->requires(it->second);
122 }
123 }
124 it = entityPrivileges.find(boost::beast::http::verb::delete_);
125 if (it != entityPrivileges.end())
126 {
127 if (deleteRule != nullptr)
128 {
129 deleteRule->requires(it->second);
130 }
131 }
Borawski.Lukaszc1a46bd2018-02-08 13:31:59 +0100132 }
Ed Tanouscbbfa962018-03-13 16:46:28 -0700133
Ed Tanous1abe55e2018-09-05 08:30:59 -0700134 virtual ~Node() = default;
Borawski.Lukaszc1a46bd2018-02-08 13:31:59 +0100135
Ed Tanous1abe55e2018-09-05 08:30:59 -0700136 OperationMap entityPrivileges;
Borawski.Lukasz86e1b662018-01-19 14:22:14 +0100137
Tanousf00032d2018-11-05 01:18:10 -0300138 crow::DynamicRule* getRule = nullptr;
139 crow::DynamicRule* postRule = nullptr;
140 crow::DynamicRule* patchRule = nullptr;
141 crow::DynamicRule* deleteRule = nullptr;
142
Ed Tanous1abe55e2018-09-05 08:30:59 -0700143 protected:
144 // Node is designed to be an abstract class, so doGet is pure virtual
145 virtual void doGet(crow::Response& res, const crow::Request& req,
146 const std::vector<std::string>& params)
147 {
148 res.result(boost::beast::http::status::method_not_allowed);
Borawski.Lukasz86e1b662018-01-19 14:22:14 +0100149 res.end();
150 }
Ed Tanous1abe55e2018-09-05 08:30:59 -0700151
152 virtual void doPatch(crow::Response& res, const crow::Request& req,
153 const std::vector<std::string>& params)
154 {
155 res.result(boost::beast::http::status::method_not_allowed);
156 res.end();
157 }
158
159 virtual void doPost(crow::Response& res, const crow::Request& req,
160 const std::vector<std::string>& params)
161 {
162 res.result(boost::beast::http::status::method_not_allowed);
163 res.end();
164 }
165
166 virtual void doDelete(crow::Response& res, const crow::Request& req,
167 const std::vector<std::string>& params)
168 {
169 res.result(boost::beast::http::status::method_not_allowed);
170 res.end();
171 }
Joseph Reynolds8fd315a2019-09-12 12:02:33 -0500172
173 /* @brief Would the operation be allowed if the user did not have
174 * the ConfigureSelf Privilege?
175 *
176 * @param req the request
177 * @param verb the operation's verb
178 *
179 * @returns True if allowed, false otherwise
180 */
181 inline bool isAllowedWithoutConfigureSelf(const crow::Request& req)
182 {
183 const std::string& userRole =
184 crow::persistent_data::UserRoleMap::getInstance().getUserRole(
185 req.session->username);
186 Privileges effectiveUserPrivileges =
187 redfish::getUserPrivileges(userRole);
188 effectiveUserPrivileges.resetSinglePrivilege("ConfigureSelf");
189 const auto& requiredPrivilegesIt = entityPrivileges.find(req.method());
190 return (requiredPrivilegesIt != entityPrivileges.end()) and
191 isOperationAllowedWithPrivileges(requiredPrivilegesIt->second,
192 effectiveUserPrivileges);
193 }
Borawski.Lukasz86e1b662018-01-19 14:22:14 +0100194};
195
Ed Tanous1abe55e2018-09-05 08:30:59 -0700196} // namespace redfish