auth/vendor/github.com/lestrrat-go/jwx/jwk/option.go

198 lines
6.8 KiB
Go

package jwk
import (
"crypto"
"time"
"github.com/lestrrat-go/backoff/v2"
"github.com/lestrrat-go/jwx/internal/json"
"github.com/lestrrat-go/option"
)
type Option = option.Interface
type identHTTPClient struct{}
type identThumbprintHash struct{}
type identRefreshInterval struct{}
type identMinRefreshInterval struct{}
type identFetchBackoff struct{}
type identPEM struct{}
type identTypedField struct{}
type identLocalRegistry struct{}
type identFetchWhitelist struct{}
type identIgnoreParseError struct{}
// AutoRefreshOption is a type of Option that can be passed to the
// AutoRefresh object.
type AutoRefreshOption interface {
Option
autoRefreshOption()
}
type autoRefreshOption struct {
Option
}
func (*autoRefreshOption) autoRefreshOption() {}
// FetchOption is a type of Option that can be passed to `jwk.Fetch()`
// FetchOption also implements the `AutoRefreshOption`, and thus can
// safely be passed to `(*jwk.AutoRefresh).Configure()`
type FetchOption interface {
AutoRefreshOption
fetchOption()
}
type fetchOption struct {
Option
}
func (*fetchOption) autoRefreshOption() {}
func (*fetchOption) fetchOption() {}
// ParseOption is a type of Option that can be passed to `jwk.Parse()`
// ParseOption also implmentsthe `ReadFileOPtion` and `AutoRefreshOption`,
// and thus safely be passed to `jwk.ReadFile` and `(*jwk.AutoRefresh).Configure()`
type ParseOption interface {
ReadFileOption
AutoRefreshOption
parseOption()
}
type parseOption struct {
Option
}
func (*parseOption) autoRefreshOption() {}
func (*parseOption) parseOption() {}
func (*parseOption) readFileOption() {}
// WithHTTPClient allows users to specify the "net/http".Client object that
// is used when fetching jwk.Set objects.
func WithHTTPClient(cl HTTPClient) FetchOption {
return &fetchOption{option.New(identHTTPClient{}, cl)}
}
// WithFetchBackoff specifies the backoff policy to use when
// refreshing a JWKS from a remote server fails.
//
// This does not have any effect on initial `Fetch()`, or any of the `Refresh()` calls --
// the backoff is applied ONLY on the background refreshing goroutine.
func WithFetchBackoff(v backoff.Policy) FetchOption {
return &fetchOption{option.New(identFetchBackoff{}, v)}
}
func WithThumbprintHash(h crypto.Hash) Option {
return option.New(identThumbprintHash{}, h)
}
// WithRefreshInterval specifies the static interval between refreshes
// of jwk.Set objects controlled by jwk.AutoRefresh.
//
// Providing this option overrides the adaptive token refreshing based
// on Cache-Control/Expires header (and jwk.WithMinRefreshInterval),
// and refreshes will *always* happen in this interval.
func WithRefreshInterval(d time.Duration) AutoRefreshOption {
return &autoRefreshOption{
option.New(identRefreshInterval{}, d),
}
}
// WithMinRefreshInterval specifies the minimum refresh interval to be used
// when using AutoRefresh. This value is ONLY used if you did not specify
// a user-supplied static refresh interval via `WithRefreshInterval`.
//
// This value is used as a fallback value when tokens are refreshed.
//
// When we fetch the key from a remote URL, we first look at the max-age
// directive from Cache-Control response header. If this value is present,
// we compare the max-age value and the value specified by this option
// and take the larger one.
//
// Next we check for the Expires header, and similarly if the header is
// present, we compare it against the value specified by this option,
// and take the larger one.
//
// Finally, if neither of the above headers are present, we use the
// value specified by this option as the next refresh timing
//
// If unspecified, the minimum refresh interval is 1 hour
func WithMinRefreshInterval(d time.Duration) AutoRefreshOption {
return &autoRefreshOption{
option.New(identMinRefreshInterval{}, d),
}
}
// WithPEM specifies that the input to `Parse()` is a PEM encoded key.
func WithPEM(v bool) ParseOption {
return &parseOption{
option.New(identPEM{}, v),
}
}
type typedFieldPair struct {
Name string
Value interface{}
}
// WithTypedField allows a private field to be parsed into the object type of
// your choice. It works much like the RegisterCustomField, but the effect
// is only applicable to the jwt.Parse function call which receives this option.
//
// While this can be extremely useful, this option should be used with caution:
// There are many caveats that your entire team/user-base needs to be aware of,
// and therefore in general its use is discouraged. Only use it when you know
// what you are doing, and you document its use clearly for others.
//
// First and foremost, this is a "per-object" option. Meaning that given the same
// serialized format, it is possible to generate two objects whose internal
// representations may differ. That is, if you parse one _WITH_ the option,
// and the other _WITHOUT_, their internal representation may completely differ.
// This could potentially lead to problems.
//
// Second, specifying this option will slightly slow down the decoding process
// as it needs to consult multiple definitions sources (global and local), so
// be careful if you are decoding a large number of tokens, as the effects will stack up.
func WithTypedField(name string, object interface{}) ParseOption {
return &parseOption{
option.New(identTypedField{},
typedFieldPair{Name: name, Value: object},
),
}
}
// This option is only available for internal code. Users don't get to play with it
func withLocalRegistry(r *json.Registry) ParseOption {
return &parseOption{option.New(identLocalRegistry{}, r)}
}
// WithFetchWhitelist specifies the Whitelist object to use when
// fetching JWKs from a remote source. This option can be passed
// to both `jwk.Fetch()`, `jwk.NewAutoRefresh()`, and `(*jwk.AutoRefresh).Configure()`
func WithFetchWhitelist(w Whitelist) FetchOption {
return &fetchOption{option.New(identFetchWhitelist{}, w)}
}
// WithIgnoreParseError is only applicable when used with `jwk.Parse()`
// (i.e. to parse JWK sets). If passed to `jwk.ParseKey()`, the function
// will return an error no matter what the input is.
//
// DO NOT USE WITHOUT EXHAUSTING ALL OTHER ROUTES FIRST.
//
// The option specifies that errors found during parsing of individual
// keys are ignored. For example, if you had keys A, B, C where B is
// invalid (e.g. it does not contain the required fields), then the
// resulting JWKS will contain keys A and C only.
//
// This options exists as an escape hatch for those times when a
// key in a JWKS that is irrelevant for your use case is causing
// your JWKS parsing to fail, and you want to get to the rest of the
// keys in the JWKS.
//
// Again, DO NOT USE unless you have exhausted all other routes.
// When you use this option, you will not be able to tell if you are
// using a faulty JWKS, except for when there are JSON syntax errors.
func WithIgnoreParseError(b bool) ParseOption {
return &parseOption{option.New(identIgnoreParseError{}, b)}
}