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