diff options
| author | mo khan <mo@mokhan.ca> | 2025-05-23 17:26:45 -0600 |
|---|---|---|
| committer | mo khan <mo@mokhan.ca> | 2025-05-23 17:26:45 -0600 |
| commit | 2bb5b3ce0e618ab652159b986df252990f3d2f12 (patch) | |
| tree | abecef9153bce0d0787346cb04e373dc107689ad /vendor/github.com/twitchtv/twirp/server_options.go | |
| parent | 15b1699b0ad27c9fc3aa4498d4085b7338bec95a (diff) | |
feat: delegate to the remote authzd to check if the permission is granted
Diffstat (limited to 'vendor/github.com/twitchtv/twirp/server_options.go')
| -rw-r--r-- | vendor/github.com/twitchtv/twirp/server_options.go | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/vendor/github.com/twitchtv/twirp/server_options.go b/vendor/github.com/twitchtv/twirp/server_options.go new file mode 100644 index 0000000..73798fc --- /dev/null +++ b/vendor/github.com/twitchtv/twirp/server_options.go @@ -0,0 +1,242 @@ +// Copyright 2018 Twitch Interactive, Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may not +// use this file except in compliance with the License. A copy of the License is +// located at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// or in the "license" file accompanying this file. This file 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 twirp + +import ( + "context" + "reflect" +) + +// ServerOption is a functional option for extending a Twirp service. +type ServerOption func(*ServerOptions) + +// WithServerHooks defines the hooks for a Twirp server. +func WithServerHooks(hooks *ServerHooks) ServerOption { + return func(opts *ServerOptions) { + opts.Hooks = hooks + } +} + +// WithServerInterceptors defines the interceptors for a Twirp server. +func WithServerInterceptors(interceptors ...Interceptor) ServerOption { + return func(opts *ServerOptions) { + opts.Interceptors = append(opts.Interceptors, interceptors...) + } +} + +// WithServerPathPrefix specifies a different prefix for routing. +// If not specified, the "/twirp" prefix is used by default. +// An empty value "" can be speficied to use no prefix. +// The clients must be configured to send requests using the same prefix. +// URL format: "<baseURL>[<prefix>]/<package>.<Service>/<Method>" +// More info on Twirp docs: https://twitchtv.github.io/twirp/docs/routing.html +func WithServerPathPrefix(prefix string) ServerOption { + return func(opts *ServerOptions) { + opts.setOpt("pathPrefix", prefix) + opts.pathPrefix = &prefix // for code generated before v8.1.0 + } +} + +// WithServerJSONSkipDefaults configures JSON serialization to skip +// unpopulated or default values in JSON responses, which results in +// smaller response sizes. This was the default before v7 and can be +// enabled for full backwards compatibility if required. +// This is now disabled by default, because JSON serialization is +// commonly used for manual debugging, in which case it is useful +// to see the full shape of the response. +// See: https://pkg.go.dev/google.golang.org/protobuf/encoding/protojson +// See: https://developers.google.com/protocol-buffers/docs/proto3#json +func WithServerJSONSkipDefaults(skipDefaults bool) ServerOption { + return func(opts *ServerOptions) { + opts.setOpt("jsonSkipDefaults", skipDefaults) + opts.JSONSkipDefaults = skipDefaults // for code generated before v8.1.0 + } +} + +// WithServerJSONCamelCaseNames configures JSON serialization to use the +// default proto3 JSON encoding (lowerCamelCase) rather than the original +// proto field names. Twirp uses the original proto field names by default, +// because JSON encoding is often used for manual debugging of the API, +// but this option allows better compatibility with other proto-json parsers. +// See: https://pkg.go.dev/google.golang.org/protobuf/encoding/protojson +// See: https://developers.google.com/protocol-buffers/docs/proto3#json +func WithServerJSONCamelCaseNames(jsonCamelCase bool) ServerOption { + return func(opts *ServerOptions) { + opts.setOpt("jsonCamelCase", jsonCamelCase) + } +} + +// ServerHooks is a container for callbacks that can instrument a +// Twirp-generated server. These callbacks all accept a context and return a +// context. They can use this to add to the request context as it threads +// through the system, appending values or deadlines to it. +// +// The RequestReceived and RequestRouted hooks are special: they can return +// errors. If they return a non-nil error, handling for that request will be +// stopped at that point. The Error hook will be triggered, and the error will +// be sent to the client. This can be used for stuff like auth checks before +// deserializing a request. +// +// The RequestReceived hook is always called first, and it is called for every +// request that the Twirp server handles. The last hook to be called in a +// request's lifecycle is always ResponseSent, even in the case of an error. +// +// Details on the timing of each hook are documented as comments on the fields +// of the ServerHooks type. +type ServerHooks struct { + // RequestReceived is called as soon as a request enters the Twirp + // server at the earliest available moment. + RequestReceived func(context.Context) (context.Context, error) + + // RequestRouted is called when a request has been routed to a + // particular method of the Twirp server. + RequestRouted func(context.Context) (context.Context, error) + + // ResponsePrepared is called when a request has been handled and a + // response is ready to be sent to the client. + ResponsePrepared func(context.Context) context.Context + + // ResponseSent is called when all bytes of a response (including an error + // response) have been written. Because the ResponseSent hook is terminal, it + // does not return a context. + ResponseSent func(context.Context) + + // Error hook is called when an error occurs while handling a request. The + // Error is passed as argument to the hook. + Error func(context.Context, Error) context.Context +} + +// ChainHooks creates a new *ServerHooks which chains the callbacks in +// each of the constituent hooks passed in. Each hook function will be +// called in the order of the ServerHooks values passed in. +// +// For the erroring hooks, RequestReceived and RequestRouted, any returned +// errors prevent processing by later hooks. +func ChainHooks(hooks ...*ServerHooks) *ServerHooks { + if len(hooks) == 0 { + return nil + } + if len(hooks) == 1 { + return hooks[0] + } + return &ServerHooks{ + RequestReceived: func(ctx context.Context) (context.Context, error) { + var err error + for _, h := range hooks { + if h != nil && h.RequestReceived != nil { + ctx, err = h.RequestReceived(ctx) + if err != nil { + return ctx, err + } + } + } + return ctx, nil + }, + RequestRouted: func(ctx context.Context) (context.Context, error) { + var err error + for _, h := range hooks { + if h != nil && h.RequestRouted != nil { + ctx, err = h.RequestRouted(ctx) + if err != nil { + return ctx, err + } + } + } + return ctx, nil + }, + ResponsePrepared: func(ctx context.Context) context.Context { + for _, h := range hooks { + if h != nil && h.ResponsePrepared != nil { + ctx = h.ResponsePrepared(ctx) + } + } + return ctx + }, + ResponseSent: func(ctx context.Context) { + for _, h := range hooks { + if h != nil && h.ResponseSent != nil { + h.ResponseSent(ctx) + } + } + }, + Error: func(ctx context.Context, twerr Error) context.Context { + for _, h := range hooks { + if h != nil && h.Error != nil { + ctx = h.Error(ctx, twerr) + } + } + return ctx + }, + } +} + +// ServerOptions encapsulate the configurable parameters on a Twirp server. +// This type is meant to be used only by generated code. +type ServerOptions struct { + // Untyped options map. The methods setOpt and ReadOpt are used to set + // and read options. The options are untyped so when a new option is added, + // newly generated code can still work with older versions of the runtime. + m map[string]interface{} + + Hooks *ServerHooks + Interceptors []Interceptor + + // Properties below are only used by code that was + // generated by older versions of Twirp (before v8.1.0). + // New options with standard types added in the future + // don't need new properties, they should use ReadOpt. + JSONSkipDefaults bool + pathPrefix *string +} + +// ReadOpt extracts an option to a pointer value, +// returns true if the option exists and was extracted. +// This method is meant to be used by generated code, +// keeping the type dependency outside of the runtime. +// +// Usage example: +// +// opts.setOpt("fooOpt", 123) +// var foo int +// ok := opts.ReadOpt("fooOpt", &int) +// +func (opts *ServerOptions) ReadOpt(key string, out interface{}) bool { + val, ok := opts.m[key] + if !ok { + return false + } + + rout := reflect.ValueOf(out) + if rout.Kind() != reflect.Ptr { + panic("ReadOpt(key, out); out must be a pointer but it was not") + } + rout.Elem().Set(reflect.ValueOf(val)) + return true +} + +// setOpt adds an option key/value. It is used by ServerOption helpers. +// The value can be extracted with ReadOpt by passing a pointer to the same type. +func (opts *ServerOptions) setOpt(key string, val interface{}) { + if opts.m == nil { + opts.m = make(map[string]interface{}) + } + opts.m[key] = val +} + +// PathPrefix() is used only by clients generated before v8.1.0 +func (opts *ServerOptions) PathPrefix() string { + if opts.pathPrefix == nil { + return "/twirp" // default prefix + } + return *opts.pathPrefix +} |
