Skip to content

Commit

Permalink
fix: allow RFC3339 encoded time strings
Browse files Browse the repository at this point in the history
Fixes #292
  • Loading branch information
muhlemmer committed Mar 10, 2023
1 parent dea8bc9 commit 80dbc32
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 0 deletions.
29 changes: 29 additions & 0 deletions pkg/oidc/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,35 @@ func NowTime() Time {
return FromTime(time.Now())
}

func (ts *Time) UnmarshalJSON(data []byte) error {
var v any
if err := json.Unmarshal(data, &v); err != nil {
return fmt.Errorf("oidc.Time: %w", err)
}

switch x := v.(type) {
case float64:
*ts = Time(x)

case string:
// Compatibility with Auth0:
// https://github.com/zitadel/oidc/issues/292
tt, err := time.Parse(time.RFC3339, x)
if err != nil {
return fmt.Errorf("oidc.Time: %w", err)
}
*ts = FromTime(tt)

case nil:
*ts = 0

default:
return fmt.Errorf("oidc.Time: unable to parse type %T with value %v", x, x)
}

return nil
}

type RequestObject struct {
Issuer string `json:"iss"`
Audience Audience `json:"aud"`
Expand Down
54 changes: 54 additions & 0 deletions pkg/oidc/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -466,3 +466,57 @@ func TestNewEncoder(t *testing.T) {
schema.NewDecoder().Decode(&b, values)
assert.Equal(t, a, b)
}

func TestTime_UnmarshalJSON(t *testing.T) {
type dst struct {
UpdatedAt Time `json:"updated_at"`
}
tests := []struct {
name string
json string
want dst
wantErr bool
}{
{
name: "RFC3339", // https://github.com/zitadel/oidc/issues/292
json: `{"updated_at": "2021-05-11T21:13:25.566Z"}`,
want: dst{UpdatedAt: 1620767605},
},
{
name: "int",
json: `{"updated_at":1620767605}`,
want: dst{UpdatedAt: 1620767605},
},
{
name: "time parse error",
json: `{"updated_at":"foo"}`,
wantErr: true,
},
{
name: "null",
json: `{"updated_at":null}`,
},
{
name: "invalid type",
json: `{"updated_at":["foo","bar"]}`,
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var got dst
err := json.Unmarshal([]byte(tt.json), &got)
if tt.wantErr {
assert.Error(t, err)
} else {
require.NoError(t, err)
}
assert.Equal(t, tt.want, got)
})
}
t.Run("syntax error", func(t *testing.T) {
var ts Time
err := ts.UnmarshalJSON([]byte{'~'})
assert.Error(t, err)
})
}

0 comments on commit 80dbc32

Please sign in to comment.