1 // Copyright 2021 gRPC authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef GRPC_CORE_LIB_SECURITY_AUTHORIZATION_MATCHERS_H 16 #define GRPC_CORE_LIB_SECURITY_AUTHORIZATION_MATCHERS_H 17 18 #include <grpc/support/port_platform.h> 19 20 #include <memory> 21 #include <string> 22 23 #include "absl/status/statusor.h" 24 #include "absl/strings/string_view.h" 25 #include "absl/types/optional.h" 26 27 #include "re2/re2.h" 28 29 namespace grpc_core { 30 31 class StringMatcher { 32 public: 33 enum class Type { 34 EXACT, // value stored in string_matcher_ field 35 PREFIX, // value stored in string_matcher_ field 36 SUFFIX, // value stored in string_matcher_ field 37 SAFE_REGEX, // pattern stored in regex_matcher_ field 38 CONTAINS, // value stored in string_matcher_ field 39 }; 40 41 // Creates StringMatcher instance. Returns error status on failure. 42 static absl::StatusOr<StringMatcher> Create(Type type, 43 const std::string& matcher, 44 bool case_sensitive = true); 45 46 StringMatcher() = default; 47 StringMatcher(const StringMatcher& other); 48 StringMatcher& operator=(const StringMatcher& other); 49 StringMatcher(StringMatcher&& other) noexcept; 50 StringMatcher& operator=(StringMatcher&& other) noexcept; 51 bool operator==(const StringMatcher& other) const; 52 53 bool Match(absl::string_view value) const; 54 55 std::string ToString() const; 56 type()57 Type type() const { return type_; } 58 59 // Valid for EXACT, PREFIX, SUFFIX and CONTAINS string_matcher()60 const std::string& string_matcher() const { return string_matcher_; } 61 62 // Valid for SAFE_REGEX regex_matcher()63 RE2* regex_matcher() const { return regex_matcher_.get(); } 64 case_sensitive()65 bool case_sensitive() const { return case_sensitive_; } 66 67 private: 68 StringMatcher(Type type, const std::string& matcher, bool case_sensitive); 69 StringMatcher(std::unique_ptr<RE2> regex_matcher, bool case_sensitive); 70 71 Type type_ = Type::EXACT; 72 std::string string_matcher_; 73 std::unique_ptr<RE2> regex_matcher_; 74 bool case_sensitive_ = true; 75 }; 76 77 class HeaderMatcher { 78 public: 79 enum class Type { 80 EXACT, // value stored in StringMatcher field 81 PREFIX, // value stored in StringMatcher field 82 SUFFIX, // value stored in StringMatcher field 83 SAFE_REGEX, // value stored in StringMatcher field 84 CONTAINS, // value stored in StringMatcher field 85 RANGE, // uses range_start and range_end fields 86 PRESENT, // uses present_match field 87 }; 88 89 // Make sure that the first five HeaderMatcher::Type enum values match up to 90 // the corresponding StringMatcher::Type enum values, so that it's safe to 91 // convert by casting when delegating to StringMatcher. 92 static_assert(static_cast<StringMatcher::Type>(Type::EXACT) == 93 StringMatcher::Type::EXACT, 94 ""); 95 static_assert(static_cast<StringMatcher::Type>(Type::PREFIX) == 96 StringMatcher::Type::PREFIX, 97 ""); 98 static_assert(static_cast<StringMatcher::Type>(Type::SUFFIX) == 99 StringMatcher::Type::SUFFIX, 100 ""); 101 static_assert(static_cast<StringMatcher::Type>(Type::SAFE_REGEX) == 102 StringMatcher::Type::SAFE_REGEX, 103 ""); 104 static_assert(static_cast<StringMatcher::Type>(Type::CONTAINS) == 105 StringMatcher::Type::CONTAINS, 106 ""); 107 108 // Creates HeaderMatcher instance. Returns error status on failure. 109 static absl::StatusOr<HeaderMatcher> Create( 110 const std::string& name, Type type, const std::string& matcher, 111 int64_t range_start = 0, int64_t range_end = 0, 112 bool present_match = false, bool invert_match = false); 113 114 HeaderMatcher() = default; 115 HeaderMatcher(const HeaderMatcher& other); 116 HeaderMatcher& operator=(const HeaderMatcher& other); 117 HeaderMatcher(HeaderMatcher&& other) noexcept; 118 HeaderMatcher& operator=(HeaderMatcher&& other) noexcept; 119 bool operator==(const HeaderMatcher& other) const; 120 name()121 const std::string& name() const { return name_; } 122 type()123 Type type() const { return type_; } 124 125 // Valid for EXACT, PREFIX, SUFFIX and CONTAINS string_matcher()126 const std::string& string_matcher() const { 127 return matcher_.string_matcher(); 128 } 129 130 // Valid for SAFE_REGEX regex_matcher()131 RE2* regex_matcher() const { return matcher_.regex_matcher(); } 132 133 bool Match(const absl::optional<absl::string_view>& value) const; 134 135 std::string ToString() const; 136 137 private: 138 // For StringMatcher. 139 HeaderMatcher(const std::string& name, Type type, StringMatcher matcher, 140 bool invert_match); 141 // For RangeMatcher. 142 HeaderMatcher(const std::string& name, int64_t range_start, int64_t range_end, 143 bool invert_match); 144 // For PresentMatcher. 145 HeaderMatcher(const std::string& name, bool present_match, bool invert_match); 146 147 std::string name_; 148 Type type_ = Type::EXACT; 149 StringMatcher matcher_; 150 int64_t range_start_; 151 int64_t range_end_; 152 bool present_match_; 153 bool invert_match_ = false; 154 }; 155 156 } // namespace grpc_core 157 158 #endif /* GRPC_CORE_LIB_SECURITY_AUTHORIZATION_MATCHERS_H */