blob: a76e5b370e7f61b994d5e0ccc3a0aca36f492174 [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>
Borawski.Lukasz43a095a2018-02-19 15:39:01 +010031 Node(CrowApp& app, EntityPrivileges&& entityPrivileges,
32 std::string&& entityUrl, Params... params)
33 : entityPrivileges(std::move(entityPrivileges)) {
Borawski.Lukaszaecb47a2018-01-25 12:14:14 +010034 app.route_dynamic(entityUrl.c_str())
Borawski.Lukasz86e1b662018-01-19 14:22:14 +010035 .methods("GET"_method, "PATCH"_method, "POST"_method,
36 "DELETE"_method)([&](const crow::request& req,
37 crow::response& res, Params... params) {
38 std::vector<std::string> paramVec = {params...};
39 dispatchRequest(app, req, res, paramVec);
40 });
41 }
42
Borawski.Lukaszaecb47a2018-01-25 12:14:14 +010043 virtual ~Node() = default;
44
45 protected:
46 // Node is designed to be an abstract class, so doGet is pure virtual
47 virtual void doGet(crow::response& res, const crow::request& req,
48 const std::vector<std::string>& params) = 0;
49
50 virtual void doPatch(crow::response& res, const crow::request& req,
51 const std::vector<std::string>& params) {
52 res.code = static_cast<int>(HttpRespCode::METHOD_NOT_ALLOWED);
53 res.end();
54 }
55
56 virtual void doPost(crow::response& res, const crow::request& req,
57 const std::vector<std::string>& params) {
58 res.code = static_cast<int>(HttpRespCode::METHOD_NOT_ALLOWED);
59 res.end();
60 }
61
62 virtual void doDelete(crow::response& res, const crow::request& req,
63 const std::vector<std::string>& params) {
64 res.code = static_cast<int>(HttpRespCode::METHOD_NOT_ALLOWED);
65 res.end();
66 }
67
68 private:
Borawski.Lukasz86e1b662018-01-19 14:22:14 +010069 template <typename CrowApp>
70 void dispatchRequest(CrowApp& app, const crow::request& req,
71 crow::response& res,
72 const std::vector<std::string>& params) {
Borawski.Lukasz86e1b662018-01-19 14:22:14 +010073 auto ctx =
74 app.template get_context<crow::TokenAuthorization::Middleware>(req);
75
Borawski.Lukaszaecb47a2018-01-25 12:14:14 +010076 if (!entityPrivileges.isMethodAllowedForUser(req.method,
77 ctx.session->username)) {
Borawski.Lukasz86e1b662018-01-19 14:22:14 +010078 res.code = static_cast<int>(HttpRespCode::METHOD_NOT_ALLOWED);
79 res.end();
80 return;
81 }
82
83 switch (req.method) {
84 case "GET"_method:
85 doGet(res, req, params);
86 break;
87
88 case "PATCH"_method:
89 doPatch(res, req, params);
90 break;
91
92 case "POST"_method:
93 doPost(res, req, params);
94 break;
95
96 case "DELETE"_method:
97 doDelete(res, req, params);
98 break;
99
100 default:
101 res.code = static_cast<int>(HttpRespCode::NOT_FOUND);
102 res.end();
103 }
104 return;
105 }
106
Borawski.Lukasz43a095a2018-02-19 15:39:01 +0100107 EntityPrivileges entityPrivileges;
Borawski.Lukasz86e1b662018-01-19 14:22:14 +0100108};
109
Borawski.Lukaszb6df6dc2018-01-24 10:20:45 +0100110template <typename CrowApp>
111void getRedfishSubRoutes(CrowApp& app, const std::string& url,
112 nlohmann::json& j) {
113 std::vector<const std::string*> routes = app.get_routes(url);
114
115 for (auto route : routes) {
116 auto redfishSubRoute =
117 route->substr(url.size(), route->size() - url.size() - 1);
118
119 // Exclude: - exact matches,
120 // - metadata urls starting with "$",
121 // - urls at the same level
122 if (!redfishSubRoute.empty() && redfishSubRoute[0] != '$' &&
123 redfishSubRoute.find('/') == std::string::npos) {
124 j[redfishSubRoute] = nlohmann::json{{"@odata.id", *route}};
125 }
126 }
127}
128
Borawski.Lukasz86e1b662018-01-19 14:22:14 +0100129} // namespace redfish
130