• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */