blob: 70b8522252e014c20ee8cc32b902c48e3c6da149 [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.Lukaszb6df6dc2018-01-24 10:20:45 +010020#include "crow.h"
Borawski.Lukasz86e1b662018-01-19 14:22:14 +010021
22namespace redfish {
23
24/**
25 * @brief Abstract class used for implementing Redfish nodes.
26 *
27 */
28class Node {
29 public:
30 template <typename CrowApp, typename... Params>
31 Node(CrowApp& app, PrivilegeProvider& provider, std::string odataType,
32 std::string odataId, Params... params)
33 : odataType(odataType), odataId(odataId) {
Borawski.Lukasz86e1b662018-01-19 14:22:14 +010034 // privileges for the node as defined in the privileges_registry.json
35 entityPrivileges = provider.getPrivileges(odataId, odataType);
36
37 app.route_dynamic(std::move(odataId))
38 .methods("GET"_method, "PATCH"_method, "POST"_method,
39 "DELETE"_method)([&](const crow::request& req,
40 crow::response& res, Params... params) {
41 std::vector<std::string> paramVec = {params...};
42 dispatchRequest(app, req, res, paramVec);
43 });
44 }
45
46 template <typename CrowApp>
47 void dispatchRequest(CrowApp& app, const crow::request& req,
48 crow::response& res,
49 const std::vector<std::string>& params) {
50 // drop requests without required privileges
51 auto ctx =
52 app.template get_context<crow::TokenAuthorization::Middleware>(req);
53
54 if (!entityPrivileges.isMethodAllowed(req.method, ctx.session->username)) {
55 res.code = static_cast<int>(HttpRespCode::METHOD_NOT_ALLOWED);
56 res.end();
57 return;
58 }
59
60 switch (req.method) {
61 case "GET"_method:
62 doGet(res, req, params);
63 break;
64
65 case "PATCH"_method:
66 doPatch(res, req, params);
67 break;
68
69 case "POST"_method:
70 doPost(res, req, params);
71 break;
72
73 case "DELETE"_method:
74 doDelete(res, req, params);
75 break;
76
77 default:
78 res.code = static_cast<int>(HttpRespCode::NOT_FOUND);
79 res.end();
80 }
81 return;
82 }
83
84 protected:
85 const std::string odataType;
86 const std::string odataId;
87
88 // Node is designed to be an abstract class, so doGet is pure virutal
89 virtual void doGet(crow::response& res, const crow::request& req,
90 const std::vector<std::string>& params) = 0;
91
92 virtual void doPatch(crow::response& res, const crow::request& req,
93 const std::vector<std::string>& params) {
94 res.code = static_cast<int>(HttpRespCode::METHOD_NOT_ALLOWED);
95 res.end();
96 }
97
98 virtual void doPost(crow::response& res, const crow::request& req,
99 const std::vector<std::string>& params) {
100 res.code = static_cast<int>(HttpRespCode::METHOD_NOT_ALLOWED);
101 res.end();
102 }
103
104 virtual void doDelete(crow::response& res, const crow::request& req,
105 const std::vector<std::string>& params) {
106 res.code = static_cast<int>(HttpRespCode::METHOD_NOT_ALLOWED);
107 res.end();
108 }
109
110 EntityPrivileges entityPrivileges;
111};
112
Borawski.Lukaszb6df6dc2018-01-24 10:20:45 +0100113template <typename CrowApp>
114void getRedfishSubRoutes(CrowApp& app, const std::string& url,
115 nlohmann::json& j) {
116 std::vector<const std::string*> routes = app.get_routes(url);
117
118 for (auto route : routes) {
119 auto redfishSubRoute =
120 route->substr(url.size(), route->size() - url.size() - 1);
121
122 // Exclude: - exact matches,
123 // - metadata urls starting with "$",
124 // - urls at the same level
125 if (!redfishSubRoute.empty() && redfishSubRoute[0] != '$' &&
126 redfishSubRoute.find('/') == std::string::npos) {
127 j[redfishSubRoute] = nlohmann::json{{"@odata.id", *route}};
128 }
129 }
130}
131
Borawski.Lukasz86e1b662018-01-19 14:22:14 +0100132} // namespace redfish
133