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