diff options
| author | mo khan <mo@mokhan.ca> | 2025-05-20 14:28:06 -0600 |
|---|---|---|
| committer | mo khan <mo@mokhan.ca> | 2025-05-23 14:49:19 -0600 |
| commit | 4beee46dc6c7642316e118a4d3aa51e4b407256e (patch) | |
| tree | 039bdf57b99061844aeb0fe55ad0bc1c864166af /vendor/github.com/jhump/protoreflect/internal/codec/buffer.go | |
| parent | 0ba49bfbde242920d8675a193d7af89420456fc0 (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/jhump/protoreflect/internal/codec/buffer.go')
| -rw-r--r-- | vendor/github.com/jhump/protoreflect/internal/codec/buffer.go | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/vendor/github.com/jhump/protoreflect/internal/codec/buffer.go b/vendor/github.com/jhump/protoreflect/internal/codec/buffer.go new file mode 100644 index 0000000..09f8849 --- /dev/null +++ b/vendor/github.com/jhump/protoreflect/internal/codec/buffer.go @@ -0,0 +1,118 @@ +package codec + +import ( + "fmt" + "io" +) + +// Buffer is a reader and a writer that wraps a slice of bytes and also +// provides API for decoding and encoding the protobuf binary format. +// +// Its operation is similar to that of a bytes.Buffer: writing pushes +// data to the end of the buffer while reading pops data from the head +// of the buffer. So the same buffer can be used to both read and write. +type Buffer struct { + buf []byte + index int + + // tmp is used when another byte slice is needed, such as when + // serializing messages, since we need to know the length before + // we can write the length prefix; by caching this, including + // after it is grown by serialization operations, we reduce the + // number of allocations needed + tmp []byte + + deterministic bool +} + +// NewBuffer creates a new buffer with the given slice of bytes as the +// buffer's initial contents. +func NewBuffer(buf []byte) *Buffer { + return &Buffer{buf: buf} +} + +// SetDeterministic sets this buffer to encode messages deterministically. This +// is useful for tests. But the overhead is non-zero, so it should not likely be +// used outside of tests. When true, map fields in a message must have their +// keys sorted before serialization to ensure deterministic output. Otherwise, +// values in a map field will be serialized in map iteration order. +func (cb *Buffer) SetDeterministic(deterministic bool) { + cb.deterministic = deterministic +} + +// IsDeterministic returns whether or not this buffer is configured to encode +// messages deterministically. +func (cb *Buffer) IsDeterministic() bool { + return cb.deterministic +} + +// Reset resets this buffer back to empty. Any subsequent writes/encodes +// to the buffer will allocate a new backing slice of bytes. +func (cb *Buffer) Reset() { + cb.buf = []byte(nil) + cb.index = 0 +} + +// Bytes returns the slice of bytes remaining in the buffer. Note that +// this does not perform a copy: if the contents of the returned slice +// are modified, the modifications will be visible to subsequent reads +// via the buffer. +func (cb *Buffer) Bytes() []byte { + return cb.buf[cb.index:] +} + +// String returns the remaining bytes in the buffer as a string. +func (cb *Buffer) String() string { + return string(cb.Bytes()) +} + +// EOF returns true if there are no more bytes remaining to read. +func (cb *Buffer) EOF() bool { + return cb.index >= len(cb.buf) +} + +// Skip attempts to skip the given number of bytes in the input. If +// the input has fewer bytes than the given count, io.ErrUnexpectedEOF +// is returned and the buffer is unchanged. Otherwise, the given number +// of bytes are skipped and nil is returned. +func (cb *Buffer) Skip(count int) error { + if count < 0 { + return fmt.Errorf("proto: bad byte length %d", count) + } + newIndex := cb.index + count + if newIndex < cb.index || newIndex > len(cb.buf) { + return io.ErrUnexpectedEOF + } + cb.index = newIndex + return nil +} + +// Len returns the remaining number of bytes in the buffer. +func (cb *Buffer) Len() int { + return len(cb.buf) - cb.index +} + +// Read implements the io.Reader interface. If there are no bytes +// remaining in the buffer, it will return 0, io.EOF. Otherwise, +// it reads max(len(dest), cb.Len()) bytes from input and copies +// them into dest. It returns the number of bytes copied and a nil +// error in this case. +func (cb *Buffer) Read(dest []byte) (int, error) { + if cb.index == len(cb.buf) { + return 0, io.EOF + } + copied := copy(dest, cb.buf[cb.index:]) + cb.index += copied + return copied, nil +} + +var _ io.Reader = (*Buffer)(nil) + +// Write implements the io.Writer interface. It always returns +// len(data), nil. +func (cb *Buffer) Write(data []byte) (int, error) { + cb.buf = append(cb.buf, data...) + return len(data), nil +} + +var _ io.Writer = (*Buffer)(nil) |
