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