xref: /openbmc/bmcweb/http/routing/baserule.hpp (revision 504af5a0568171b72caf13234cc81380b261fa21)
1 // SPDX-License-Identifier: Apache-2.0
2 // SPDX-FileCopyrightText: Copyright OpenBMC Authors
3 #pragma once
4 
5 #include "async_resp.hpp"
6 #include "http_request.hpp"
7 #include "privileges.hpp"
8 #include "verb.hpp"
9 
10 #include <boost/asio/ip/tcp.hpp>
11 #include <boost/asio/ssl/stream.hpp>
12 #include <boost/beast/http/status.hpp>
13 
14 #include <cstddef>
15 #include <limits>
16 #include <memory>
17 #include <string>
18 #include <utility>
19 #include <vector>
20 
21 namespace crow
22 {
23 class BaseRule
24 {
25   public:
BaseRule(const std::string & thisRule)26     explicit BaseRule(const std::string& thisRule) : rule(thisRule) {}
27 
28     virtual ~BaseRule() = default;
29 
30     BaseRule(const BaseRule&) = delete;
31     BaseRule(BaseRule&&) = delete;
32     BaseRule& operator=(const BaseRule&) = delete;
33     BaseRule& operator=(const BaseRule&&) = delete;
34 
35     virtual void validate() = 0;
upgrade()36     std::unique_ptr<BaseRule> upgrade()
37     {
38         if (ruleToUpgrade)
39         {
40             return std::move(ruleToUpgrade);
41         }
42         return {};
43     }
44 
45     virtual void handle(const Request& /*req*/,
46                         const std::shared_ptr<bmcweb::AsyncResp>&,
47                         const std::vector<std::string>&) = 0;
handleUpgrade(const Request &,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,boost::asio::ip::tcp::socket &&)48     virtual void handleUpgrade(
49         const Request& /*req*/,
50         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
51         boost::asio::ip::tcp::socket&& /*adaptor*/)
52     {
53         asyncResp->res.result(boost::beast::http::status::not_found);
54     }
55 
handleUpgrade(const Request &,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,boost::asio::ssl::stream<boost::asio::ip::tcp::socket> &&)56     virtual void handleUpgrade(
57         const Request& /*req*/,
58         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
59         boost::asio::ssl::stream<boost::asio::ip::tcp::socket>&& /*adaptor*/)
60     {
61         asyncResp->res.result(boost::beast::http::status::not_found);
62     }
63 
getMethods() const64     size_t getMethods() const
65     {
66         return methodsBitfield;
67     }
68 
checkPrivileges(const redfish::Privileges & userPrivileges)69     bool checkPrivileges(const redfish::Privileges& userPrivileges)
70     {
71         // If there are no privileges assigned, assume no privileges
72         // required
73         if (privilegesSet.empty())
74         {
75             return true;
76         }
77 
78         for (const redfish::Privileges& requiredPrivileges : privilegesSet)
79         {
80             if (userPrivileges.isSupersetOf(requiredPrivileges))
81             {
82                 return true;
83             }
84         }
85         return false;
86     }
87 
88     size_t methodsBitfield{1 << static_cast<size_t>(HttpVerb::Get)};
89     static_assert(std::numeric_limits<decltype(methodsBitfield)>::digits >
90                       static_cast<int>(HttpVerb::Max),
91                   "Not enough bits to store bitfield");
92 
93     bool isNotFound = false;
94     bool isMethodNotAllowed = false;
95     bool isUpgrade = false;
96 
97     std::vector<redfish::Privileges> privilegesSet;
98 
99     std::string rule;
100 
101     std::unique_ptr<BaseRule> ruleToUpgrade;
102 
103     friend class Router;
104     template <typename T>
105     friend struct RuleParameterTraits;
106 };
107 
108 } // namespace crow
109