| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- package json
- import (
- "bytes"
- "sync"
- "sync/atomic"
- "github.com/lestrrat-go/jwx/internal/base64"
- "github.com/pkg/errors"
- )
- var muGlobalConfig sync.RWMutex
- var useNumber bool
- // Sets the global configuration for json decoding
- func DecoderSettings(inUseNumber bool) {
- muGlobalConfig.Lock()
- useNumber = inUseNumber
- muGlobalConfig.Unlock()
- }
- // Unmarshal respects the values specified in DecoderSettings,
- // and uses a Decoder that has certain features turned on/off
- func Unmarshal(b []byte, v interface{}) error {
- dec := NewDecoder(bytes.NewReader(b))
- return dec.Decode(v)
- }
- func AssignNextBytesToken(dst *[]byte, dec *Decoder) error {
- var val string
- if err := dec.Decode(&val); err != nil {
- return errors.Wrap(err, `error reading next value`)
- }
- buf, err := base64.DecodeString(val)
- if err != nil {
- return errors.Errorf(`expected base64 encoded []byte (%T)`, val)
- }
- *dst = buf
- return nil
- }
- func ReadNextStringToken(dec *Decoder) (string, error) {
- var val string
- if err := dec.Decode(&val); err != nil {
- return "", errors.Wrap(err, `error reading next value`)
- }
- return val, nil
- }
- func AssignNextStringToken(dst **string, dec *Decoder) error {
- val, err := ReadNextStringToken(dec)
- if err != nil {
- return err
- }
- *dst = &val
- return nil
- }
- // FlattenAudience is a flag to specify if we should flatten the "aud"
- // entry to a string when there's only one entry.
- // In jwx < 1.1.8 we just dumped everything as an array of strings,
- // but apparently AWS Cognito doesn't handle this well.
- //
- // So now we have the ability to dump "aud" as a string if there's
- // only one entry, but we need to retain the old behavior so that
- // we don't accidentally break somebody else's code. (e.g. messing
- // up how signatures are calculated)
- var FlattenAudience uint32
- func EncodeAudience(enc *Encoder, aud []string) error {
- var val interface{}
- if len(aud) == 1 && atomic.LoadUint32(&FlattenAudience) == 1 {
- val = aud[0]
- } else {
- val = aud
- }
- return enc.Encode(val)
- }
- // DecodeCtx is an interface for objects that needs that extra something
- // when decoding JSON into an object.
- type DecodeCtx interface {
- Registry() *Registry
- }
- // DecodeCtxContainer is used to differentiate objects that can carry extra
- // decoding hints and those who can't.
- type DecodeCtxContainer interface {
- DecodeCtx() DecodeCtx
- SetDecodeCtx(DecodeCtx)
- }
- // stock decodeCtx. should cover 80% of the cases
- type decodeCtx struct {
- registry *Registry
- }
- func NewDecodeCtx(r *Registry) DecodeCtx {
- return &decodeCtx{registry: r}
- }
- func (dc *decodeCtx) Registry() *Registry {
- return dc.registry
- }
|