mirror of
https://github.com/therootcompany/golib.git
synced 2026-03-28 18:15:30 +00:00
fix(jwt): accept JSON array for SpaceDelimited scope claim
Some issuers (e.g. PaperOS) emit `scope` as a JSON array (`[]` or `["openid","profile"]`) instead of the RFC 6749 space-delimited string. SpaceDelimited.UnmarshalJSON now accepts both forms; a JSON array is converted to the equivalent slice. Other non-string, non-array values still return an error. Adds test cases: array_values and array_empty.
This commit is contained in:
parent
690cf90d67
commit
2a9cec75ef
@ -220,6 +220,23 @@ func TestCov_SpaceDelimited_UnmarshalJSON(t *testing.T) {
|
|||||||
t.Fatalf("expected empty, got %v", s)
|
t.Fatalf("expected empty, got %v", s)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
t.Run("array_values", func(t *testing.T) {
|
||||||
|
var s SpaceDelimited
|
||||||
|
json.Unmarshal([]byte(`["openid","profile"]`), &s)
|
||||||
|
if len(s) != 2 || s[0] != "openid" || s[1] != "profile" {
|
||||||
|
t.Fatalf("got %v", s)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.Run("array_empty", func(t *testing.T) {
|
||||||
|
var s SpaceDelimited
|
||||||
|
json.Unmarshal([]byte(`[]`), &s)
|
||||||
|
if s == nil {
|
||||||
|
t.Fatal("expected non-nil empty SpaceDelimited, got nil")
|
||||||
|
}
|
||||||
|
if len(s) != 0 {
|
||||||
|
t.Fatalf("expected empty, got %v", s)
|
||||||
|
}
|
||||||
|
})
|
||||||
t.Run("invalid", func(t *testing.T) {
|
t.Run("invalid", func(t *testing.T) {
|
||||||
var s SpaceDelimited
|
var s SpaceDelimited
|
||||||
if err := json.Unmarshal([]byte(`123`), &s); err == nil {
|
if err := json.Unmarshal([]byte(`123`), &s); err == nil {
|
||||||
|
|||||||
@ -89,16 +89,30 @@ type SpaceDelimited []string
|
|||||||
// UnmarshalJSON decodes a space-separated string into a slice.
|
// UnmarshalJSON decodes a space-separated string into a slice.
|
||||||
// An empty string "" unmarshals to a non-nil empty SpaceDelimited{},
|
// An empty string "" unmarshals to a non-nil empty SpaceDelimited{},
|
||||||
// preserving the distinction from a nil (absent) SpaceDelimited.
|
// preserving the distinction from a nil (absent) SpaceDelimited.
|
||||||
|
//
|
||||||
|
// As a compatibility extension, it also accepts a JSON array of strings,
|
||||||
|
// because some issuers (e.g. PaperOS) emit scope as [] instead of "".
|
||||||
func (s *SpaceDelimited) UnmarshalJSON(data []byte) error {
|
func (s *SpaceDelimited) UnmarshalJSON(data []byte) error {
|
||||||
var str string
|
var str string
|
||||||
if err := json.Unmarshal(data, &str); err != nil {
|
if err := json.Unmarshal(data, &str); err == nil {
|
||||||
return fmt.Errorf("space-delimited must be a string: %w: %w", ErrInvalidPayload, err)
|
if str == "" {
|
||||||
}
|
*s = SpaceDelimited{}
|
||||||
if str == "" {
|
return nil
|
||||||
*s = SpaceDelimited{}
|
}
|
||||||
|
*s = strings.Fields(str)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
*s = strings.Fields(str)
|
|
||||||
|
// Fallback: accept a JSON array of strings (non-standard but used in the wild).
|
||||||
|
var ss []string
|
||||||
|
if err := json.Unmarshal(data, &ss); err != nil {
|
||||||
|
return fmt.Errorf("space-delimited must be a string or array of strings: %w: %w", ErrInvalidPayload, err)
|
||||||
|
}
|
||||||
|
if ss == nil {
|
||||||
|
*s = SpaceDelimited{}
|
||||||
|
} else {
|
||||||
|
*s = SpaceDelimited(ss)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user