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