summaryrefslogtreecommitdiff
path: root/vendor/github.com/envoyproxy/protoc-gen-validate/validate/validate.h
diff options
context:
space:
mode:
authormo khan <mo@mokhan.ca>2025-05-20 14:28:06 -0600
committermo khan <mo@mokhan.ca>2025-05-23 14:49:19 -0600
commit4beee46dc6c7642316e118a4d3aa51e4b407256e (patch)
tree039bdf57b99061844aeb0fe55ad0bc1c864166af /vendor/github.com/envoyproxy/protoc-gen-validate/validate/validate.h
parent0ba49bfbde242920d8675a193d7af89420456fc0 (diff)
feat: add external authorization service (authzd) with JWT authentication
- Add new authzd gRPC service implementing Envoy's external authorization API - Integrate JWT authentication filter in Envoy configuration with claim extraction - Update middleware to support both cookie-based and header-based user authentication - Add comprehensive test coverage for authorization service and server - Configure proper service orchestration with authzd, sparkled, and Envoy - Update build system and Docker configuration for multi-service deployment - Add grpcurl tool for gRPC service debugging and testing This enables fine-grained authorization control through Envoy's ext_authz filter while maintaining backward compatibility with existing cookie-based authentication.
Diffstat (limited to 'vendor/github.com/envoyproxy/protoc-gen-validate/validate/validate.h')
-rw-r--r--vendor/github.com/envoyproxy/protoc-gen-validate/validate/validate.h183
1 files changed, 183 insertions, 0 deletions
diff --git a/vendor/github.com/envoyproxy/protoc-gen-validate/validate/validate.h b/vendor/github.com/envoyproxy/protoc-gen-validate/validate/validate.h
new file mode 100644
index 0000000..d6cf6c9
--- /dev/null
+++ b/vendor/github.com/envoyproxy/protoc-gen-validate/validate/validate.h
@@ -0,0 +1,183 @@
+#ifndef _VALIDATE_H
+#define _VALIDATE_H
+
+#include <functional>
+#include <regex>
+#include <stdexcept>
+#include <string>
+#include <typeindex>
+#include <typeinfo>
+#include <unordered_map>
+
+#if !defined(_WIN32)
+#include <arpa/inet.h>
+#else
+#include <winsock2.h>
+#include <ws2tcpip.h>
+
+// <windows.h> uses macros to #define a ton of symbols,
+// many of which interfere with our code here and down
+// the line in various extensions.
+#undef DELETE
+#undef ERROR
+#undef GetMessage
+#undef interface
+#undef TRUE
+#undef min
+
+#endif
+
+#include "google/protobuf/message.h"
+
+namespace pgv {
+using std::string;
+
+class UnimplementedException : public std::runtime_error {
+public:
+ UnimplementedException() : std::runtime_error("not yet implemented") {}
+ UnimplementedException(const std::string& message) : std::runtime_error(message) {}
+ // Thrown by C++ validation code that is not yet implemented.
+};
+
+using ValidationMsg = std::string;
+
+class BaseValidator {
+public:
+ /**
+ * Validate/check a generic message object with a registered validator for the concrete message
+ * type.
+ * @param m supplies the message to check.
+ * @param err supplies the place to return error information.
+ * @return true if the validation passes OR there is no registered validator for the concrete
+ * message type. false is returned if validation explicitly fails.
+ */
+ static bool AbstractCheckMessage(const google::protobuf::Message& m, ValidationMsg* err) {
+ // Polymorphic lookup is used to see if there is a matching concrete validator. If so, call it.
+ // Otherwise return success.
+ auto it = abstractValidators().find(std::type_index(typeid(m)));
+ if (it == abstractValidators().end()) {
+ return true;
+ }
+ return it->second(m, err);
+ }
+
+protected:
+ // Used to implement AbstractCheckMessage() above. Every message that is linked into the binary
+ // will register itself by type_index, allowing for polymorphic lookup later.
+ static std::unordered_map<std::type_index,
+ std::function<bool(const google::protobuf::Message&, ValidationMsg*)>>&
+ abstractValidators() {
+ static auto* validator_map = new std::unordered_map<
+ std::type_index, std::function<bool(const google::protobuf::Message&, ValidationMsg*)>>();
+ return *validator_map;
+ }
+};
+
+template <typename T> class Validator : public BaseValidator {
+public:
+ Validator(std::function<bool(const T&, ValidationMsg*)> check) : check_(check) {
+ abstractValidators()[std::type_index(typeid(T))] = [this](const google::protobuf::Message& m,
+ ValidationMsg* err) -> bool {
+ return check_(dynamic_cast<const T&>(m), err);
+ };
+ }
+
+private:
+ std::function<bool(const T&, ValidationMsg*)> check_;
+};
+
+static inline std::string String(const ValidationMsg& msg) { return std::string(msg); }
+
+static inline bool IsPrefix(const string& maybe_prefix, const string& search_in) {
+ return search_in.compare(0, maybe_prefix.size(), maybe_prefix) == 0;
+}
+
+static inline bool IsSuffix(const string& maybe_suffix, const string& search_in) {
+ return maybe_suffix.size() <= search_in.size() &&
+ search_in.compare(search_in.size() - maybe_suffix.size(), maybe_suffix.size(),
+ maybe_suffix) == 0;
+}
+
+static inline bool Contains(const string& search_in, const string& to_find) {
+ return search_in.find(to_find) != string::npos;
+}
+
+static inline bool NotContains(const string& search_in, const string& to_find) {
+ return !Contains(search_in, to_find);
+}
+
+static inline bool IsIpv4(const string& to_validate) {
+ struct sockaddr_in sa;
+ return !(inet_pton(AF_INET, to_validate.c_str(), &sa.sin_addr) < 1);
+}
+
+static inline bool IsIpv6(const string& to_validate) {
+ struct sockaddr_in6 sa_six;
+ return !(inet_pton(AF_INET6, to_validate.c_str(), &sa_six.sin6_addr) < 1);
+}
+
+static inline bool IsIp(const string& to_validate) {
+ return IsIpv4(to_validate) || IsIpv6(to_validate);
+}
+
+static inline bool IsHostname(const string& to_validate) {
+ if (to_validate.length() > 253) {
+ return false;
+ }
+
+ const std::regex dot_regex{"\\."};
+ const auto iter_end = std::sregex_token_iterator();
+ auto iter = std::sregex_token_iterator(to_validate.begin(), to_validate.end(), dot_regex, -1);
+ for (; iter != iter_end; ++iter) {
+ const std::string& part = *iter;
+ if (part.empty() || part.length() > 63) {
+ return false;
+ }
+ if (part.at(0) == '-') {
+ return false;
+ }
+ if (part.at(part.length() - 1) == '-') {
+ return false;
+ }
+ for (const auto& character : part) {
+ if ((character < 'A' || character > 'Z') && (character < 'a' || character > 'z') &&
+ (character < '0' || character > '9') && character != '-') {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+namespace {
+
+inline int OneCharLen(const char* src) {
+ return "\1\1\1\1\1\1\1\1\1\1\1\1\2\2\3\4"[(*src & 0xFF) >> 4];
+}
+
+inline int UTF8FirstLetterNumBytes(const char *utf8_str, int str_len) {
+ if (str_len == 0)
+ return 0;
+ return OneCharLen(utf8_str);
+}
+
+inline size_t Utf8Len(const string& narrow_string) {
+ const char* str_char = narrow_string.c_str();
+ ptrdiff_t byte_len = narrow_string.length();
+ size_t unicode_len = 0;
+ int char_len = 1;
+ while (byte_len > 0 && char_len > 0) {
+ char_len = UTF8FirstLetterNumBytes(str_char, byte_len);
+ str_char += char_len;
+ byte_len -= char_len;
+ ++unicode_len;
+ }
+ return unicode_len;
+}
+
+} // namespace
+
+} // namespace pgv
+
+#endif // _VALIDATE_H