summaryrefslogtreecommitdiff
path: root/vendor/github.com/bufbuild/protocompile/walk
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/bufbuild/protocompile/walk
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/bufbuild/protocompile/walk')
-rw-r--r--vendor/github.com/bufbuild/protocompile/walk/walk.go446
1 files changed, 446 insertions, 0 deletions
diff --git a/vendor/github.com/bufbuild/protocompile/walk/walk.go b/vendor/github.com/bufbuild/protocompile/walk/walk.go
new file mode 100644
index 0000000..244fa72
--- /dev/null
+++ b/vendor/github.com/bufbuild/protocompile/walk/walk.go
@@ -0,0 +1,446 @@
+// Copyright 2020-2024 Buf Technologies, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package walk provides helper functions for traversing all elements in a
+// protobuf file descriptor. There are versions both for traversing "rich"
+// descriptors (protoreflect.Descriptor) and for traversing the underlying
+// "raw" descriptor protos.
+//
+// # Enter And Exit
+//
+// This package includes variants of the functions that accept two callback
+// functions. These variants have names ending with "EnterAndExit". One function
+// is called as each element is visited ("enter") and the other is called after
+// the element and all of its descendants have been visited ("exit"). This
+// can be useful when you need to track state that is scoped to the visitation
+// of a single element.
+//
+// # Source Path
+//
+// When traversing raw descriptor protos, this package include variants whose
+// callback accepts a protoreflect.SourcePath. These variants have names that
+// include "WithPath". This path can be used to locate corresponding data in the
+// file's source code info (if present).
+package walk
+
+import (
+ "google.golang.org/protobuf/proto"
+ "google.golang.org/protobuf/reflect/protoreflect"
+ "google.golang.org/protobuf/types/descriptorpb"
+
+ "github.com/bufbuild/protocompile/internal"
+)
+
+// Descriptors walks all descriptors in the given file using a depth-first
+// traversal, calling the given function for each descriptor in the hierarchy.
+// The walk ends when traversal is complete or when the function returns an
+// error. If the function returns an error, that is returned as the result of the
+// walk operation.
+//
+// Descriptors are visited using a pre-order traversal, where the function is
+// called for a descriptor before it is called for any of its descendants.
+func Descriptors(file protoreflect.FileDescriptor, fn func(protoreflect.Descriptor) error) error {
+ return DescriptorsEnterAndExit(file, fn, nil)
+}
+
+// DescriptorsEnterAndExit walks all descriptors in the given file using a
+// depth-first traversal, calling the given functions on entry and on exit
+// for each descriptor in the hierarchy. The walk ends when traversal is
+// complete or when a function returns an error. If a function returns an error,
+// that is returned as the result of the walk operation.
+//
+// The enter function is called using a pre-order traversal, where the function
+// is called for a descriptor before it is called for any of its descendants.
+// The exit function is called using a post-order traversal, where the function
+// is called for a descriptor only after it is called for any descendants.
+func DescriptorsEnterAndExit(file protoreflect.FileDescriptor, enter, exit func(protoreflect.Descriptor) error) error {
+ if err := walkContainer(file, enter, exit); err != nil {
+ return err
+ }
+ services := file.Services()
+ for i, length := 0, services.Len(); i < length; i++ {
+ svc := services.Get(i)
+ if err := enter(svc); err != nil {
+ return err
+ }
+ methods := svc.Methods()
+ for i, length := 0, methods.Len(); i < length; i++ {
+ mtd := methods.Get(i)
+ if err := enter(mtd); err != nil {
+ return err
+ }
+ if exit != nil {
+ if err := exit(mtd); err != nil {
+ return err
+ }
+ }
+ }
+ if exit != nil {
+ if err := exit(svc); err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+}
+
+type container interface {
+ Messages() protoreflect.MessageDescriptors
+ Enums() protoreflect.EnumDescriptors
+ Extensions() protoreflect.ExtensionDescriptors
+}
+
+func walkContainer(container container, enter, exit func(protoreflect.Descriptor) error) error {
+ messages := container.Messages()
+ for i, length := 0, messages.Len(); i < length; i++ {
+ msg := messages.Get(i)
+ if err := messageDescriptor(msg, enter, exit); err != nil {
+ return err
+ }
+ }
+ enums := container.Enums()
+ for i, length := 0, enums.Len(); i < length; i++ {
+ en := enums.Get(i)
+ if err := enumDescriptor(en, enter, exit); err != nil {
+ return err
+ }
+ }
+ exts := container.Extensions()
+ for i, length := 0, exts.Len(); i < length; i++ {
+ ext := exts.Get(i)
+ if err := enter(ext); err != nil {
+ return err
+ }
+ if exit != nil {
+ if err := exit(ext); err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+}
+
+func messageDescriptor(msg protoreflect.MessageDescriptor, enter, exit func(protoreflect.Descriptor) error) error {
+ if err := enter(msg); err != nil {
+ return err
+ }
+ fields := msg.Fields()
+ for i, length := 0, fields.Len(); i < length; i++ {
+ fld := fields.Get(i)
+ if err := enter(fld); err != nil {
+ return err
+ }
+ if exit != nil {
+ if err := exit(fld); err != nil {
+ return err
+ }
+ }
+ }
+ oneofs := msg.Oneofs()
+ for i, length := 0, oneofs.Len(); i < length; i++ {
+ oo := oneofs.Get(i)
+ if err := enter(oo); err != nil {
+ return err
+ }
+ if exit != nil {
+ if err := exit(oo); err != nil {
+ return err
+ }
+ }
+ }
+ if err := walkContainer(msg, enter, exit); err != nil {
+ return err
+ }
+ if exit != nil {
+ if err := exit(msg); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func enumDescriptor(en protoreflect.EnumDescriptor, enter, exit func(protoreflect.Descriptor) error) error {
+ if err := enter(en); err != nil {
+ return err
+ }
+ vals := en.Values()
+ for i, length := 0, vals.Len(); i < length; i++ {
+ enVal := vals.Get(i)
+ if err := enter(enVal); err != nil {
+ return err
+ }
+ if exit != nil {
+ if err := exit(enVal); err != nil {
+ return err
+ }
+ }
+ }
+ if exit != nil {
+ if err := exit(en); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// DescriptorProtosWithPath walks all descriptor protos in the given file using
+// a depth-first traversal. This is the same as DescriptorProtos except that the
+// callback function, fn, receives a protoreflect.SourcePath, that indicates the
+// path for the element in the file's source code info.
+func DescriptorProtosWithPath(file *descriptorpb.FileDescriptorProto, fn func(protoreflect.FullName, protoreflect.SourcePath, proto.Message) error) error {
+ return DescriptorProtosWithPathEnterAndExit(file, fn, nil)
+}
+
+// DescriptorProtosWithPathEnterAndExit walks all descriptor protos in the given
+// file using a depth-first traversal. This is the same as
+// DescriptorProtosEnterAndExit except that the callback function, fn, receives
+// a protoreflect.SourcePath, that indicates the path for the element in the
+// file's source code info.
+func DescriptorProtosWithPathEnterAndExit(file *descriptorpb.FileDescriptorProto, enter, exit func(protoreflect.FullName, protoreflect.SourcePath, proto.Message) error) error {
+ w := &protoWalker{usePath: true, enter: enter, exit: exit}
+ return w.walkDescriptorProtos(file)
+}
+
+// DescriptorProtos walks all descriptor protos in the given file using a
+// depth-first traversal, calling the given function for each descriptor proto
+// in the hierarchy. The walk ends when traversal is complete or when the
+// function returns an error. If the function returns an error, that is
+// returned as the result of the walk operation.
+//
+// Descriptor protos are visited using a pre-order traversal, where the function
+// is called for a descriptor before it is called for any of its descendants.
+func DescriptorProtos(file *descriptorpb.FileDescriptorProto, fn func(protoreflect.FullName, proto.Message) error) error {
+ return DescriptorProtosEnterAndExit(file, fn, nil)
+}
+
+// DescriptorProtosEnterAndExit walks all descriptor protos in the given file
+// using a depth-first traversal, calling the given functions on entry and on
+// exit for each descriptor in the hierarchy. The walk ends when traversal is
+// complete or when a function returns an error. If a function returns an error,
+// that is returned as the result of the walk operation.
+//
+// The enter function is called using a pre-order traversal, where the function
+// is called for a descriptor proto before it is called for any of its
+// descendants. The exit function is called using a post-order traversal, where
+// the function is called for a descriptor proto only after it is called for any
+// descendants.
+func DescriptorProtosEnterAndExit(file *descriptorpb.FileDescriptorProto, enter, exit func(protoreflect.FullName, proto.Message) error) error {
+ enterWithPath := func(n protoreflect.FullName, _ protoreflect.SourcePath, m proto.Message) error {
+ return enter(n, m)
+ }
+ var exitWithPath func(protoreflect.FullName, protoreflect.SourcePath, proto.Message) error
+ if exit != nil {
+ exitWithPath = func(n protoreflect.FullName, _ protoreflect.SourcePath, m proto.Message) error {
+ return exit(n, m)
+ }
+ }
+ w := &protoWalker{
+ enter: enterWithPath,
+ exit: exitWithPath,
+ }
+ return w.walkDescriptorProtos(file)
+}
+
+type protoWalker struct {
+ usePath bool
+ enter, exit func(protoreflect.FullName, protoreflect.SourcePath, proto.Message) error
+}
+
+func (w *protoWalker) walkDescriptorProtos(file *descriptorpb.FileDescriptorProto) error {
+ prefix := file.GetPackage()
+ if prefix != "" {
+ prefix += "."
+ }
+ var path protoreflect.SourcePath
+ for i, msg := range file.MessageType {
+ var p protoreflect.SourcePath
+ if w.usePath {
+ p = path
+ p = append(p, internal.FileMessagesTag, int32(i))
+ }
+ if err := w.walkDescriptorProto(prefix, p, msg); err != nil {
+ return err
+ }
+ }
+ for i, en := range file.EnumType {
+ var p protoreflect.SourcePath
+ if w.usePath {
+ p = path
+ p = append(p, internal.FileEnumsTag, int32(i))
+ }
+ if err := w.walkEnumDescriptorProto(prefix, p, en); err != nil {
+ return err
+ }
+ }
+ for i, ext := range file.Extension {
+ var p protoreflect.SourcePath
+ if w.usePath {
+ p = path
+ p = append(p, internal.FileExtensionsTag, int32(i))
+ }
+ fqn := prefix + ext.GetName()
+ if err := w.enter(protoreflect.FullName(fqn), p, ext); err != nil {
+ return err
+ }
+ if w.exit != nil {
+ if err := w.exit(protoreflect.FullName(fqn), p, ext); err != nil {
+ return err
+ }
+ }
+ }
+ for i, svc := range file.Service {
+ var p protoreflect.SourcePath
+ if w.usePath {
+ p = path
+ p = append(p, internal.FileServicesTag, int32(i))
+ }
+ fqn := prefix + svc.GetName()
+ if err := w.enter(protoreflect.FullName(fqn), p, svc); err != nil {
+ return err
+ }
+ for j, mtd := range svc.Method {
+ var mp protoreflect.SourcePath
+ if w.usePath {
+ mp = p
+ mp = append(mp, internal.ServiceMethodsTag, int32(j))
+ }
+ mtdFqn := fqn + "." + mtd.GetName()
+ if err := w.enter(protoreflect.FullName(mtdFqn), mp, mtd); err != nil {
+ return err
+ }
+ if w.exit != nil {
+ if err := w.exit(protoreflect.FullName(mtdFqn), mp, mtd); err != nil {
+ return err
+ }
+ }
+ }
+ if w.exit != nil {
+ if err := w.exit(protoreflect.FullName(fqn), p, svc); err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+}
+
+func (w *protoWalker) walkDescriptorProto(prefix string, path protoreflect.SourcePath, msg *descriptorpb.DescriptorProto) error {
+ fqn := prefix + msg.GetName()
+ if err := w.enter(protoreflect.FullName(fqn), path, msg); err != nil {
+ return err
+ }
+ prefix = fqn + "."
+ for i, fld := range msg.Field {
+ var p protoreflect.SourcePath
+ if w.usePath {
+ p = path
+ p = append(p, internal.MessageFieldsTag, int32(i))
+ }
+ fqn := prefix + fld.GetName()
+ if err := w.enter(protoreflect.FullName(fqn), p, fld); err != nil {
+ return err
+ }
+ if w.exit != nil {
+ if err := w.exit(protoreflect.FullName(fqn), p, fld); err != nil {
+ return err
+ }
+ }
+ }
+ for i, oo := range msg.OneofDecl {
+ var p protoreflect.SourcePath
+ if w.usePath {
+ p = path
+ p = append(p, internal.MessageOneofsTag, int32(i))
+ }
+ fqn := prefix + oo.GetName()
+ if err := w.enter(protoreflect.FullName(fqn), p, oo); err != nil {
+ return err
+ }
+ if w.exit != nil {
+ if err := w.exit(protoreflect.FullName(fqn), p, oo); err != nil {
+ return err
+ }
+ }
+ }
+ for i, nested := range msg.NestedType {
+ var p protoreflect.SourcePath
+ if w.usePath {
+ p = path
+ p = append(p, internal.MessageNestedMessagesTag, int32(i))
+ }
+ if err := w.walkDescriptorProto(prefix, p, nested); err != nil {
+ return err
+ }
+ }
+ for i, en := range msg.EnumType {
+ var p protoreflect.SourcePath
+ if w.usePath {
+ p = path
+ p = append(p, internal.MessageEnumsTag, int32(i))
+ }
+ if err := w.walkEnumDescriptorProto(prefix, p, en); err != nil {
+ return err
+ }
+ }
+ for i, ext := range msg.Extension {
+ var p protoreflect.SourcePath
+ if w.usePath {
+ p = path
+ p = append(p, internal.MessageExtensionsTag, int32(i))
+ }
+ fqn := prefix + ext.GetName()
+ if err := w.enter(protoreflect.FullName(fqn), p, ext); err != nil {
+ return err
+ }
+ if w.exit != nil {
+ if err := w.exit(protoreflect.FullName(fqn), p, ext); err != nil {
+ return err
+ }
+ }
+ }
+ if w.exit != nil {
+ if err := w.exit(protoreflect.FullName(fqn), path, msg); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (w *protoWalker) walkEnumDescriptorProto(prefix string, path protoreflect.SourcePath, en *descriptorpb.EnumDescriptorProto) error {
+ fqn := prefix + en.GetName()
+ if err := w.enter(protoreflect.FullName(fqn), path, en); err != nil {
+ return err
+ }
+ for i, val := range en.Value {
+ var p protoreflect.SourcePath
+ if w.usePath {
+ p = path
+ p = append(p, internal.EnumValuesTag, int32(i))
+ }
+ fqn := prefix + val.GetName()
+ if err := w.enter(protoreflect.FullName(fqn), p, val); err != nil {
+ return err
+ }
+ if w.exit != nil {
+ if err := w.exit(protoreflect.FullName(fqn), p, val); err != nil {
+ return err
+ }
+ }
+ }
+ if w.exit != nil {
+ if err := w.exit(protoreflect.FullName(fqn), path, en); err != nil {
+ return err
+ }
+ }
+ return nil
+}