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 22, 2023
1 parent 95ffcb5 commit a64b97d
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 5 deletions.
25 changes: 20 additions & 5 deletions pkg/oidc/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,27 @@ func (s SpaceDelimitedArray) Value() (driver.Value, error) {

type Time time.Time

func (t *Time) UnmarshalJSON(data []byte) error {
var i int64
if err := json.Unmarshal(data, &i); err != nil {
return err
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(time.Unix(int64(x), 0))
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 = Time(tt.Round(time.Second))
case nil:
*ts = Time{}
default:
return fmt.Errorf("oidc.Time: unable to parse type %T with value %v", x, x)
}
*t = Time(time.Unix(i, 0).UTC())
return nil
}

Expand Down
56 changes: 56 additions & 0 deletions pkg/oidc/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import (
"strconv"
"strings"
"testing"
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/text/language"
)

Expand Down Expand Up @@ -335,3 +337,57 @@ func TestSpaceDelimitatedArray_ValuerNil(t *testing.T) {
assert.Equal(t, SpaceDelimitedArray(nil), reversed, "scan nil")
}
}

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: Time(time.Unix(1620767606, 0))},
},
{
name: "int",
json: `{"updated_at":1620767606}`,
want: dst{UpdatedAt: Time(time.Unix(1620767606, 0))},
},
{
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.WithinDuration(t, time.Time(tt.want.UpdatedAt), time.Time(got.UpdatedAt), 0)
})
}
t.Run("syntax error", func(t *testing.T) {
var ts Time
err := ts.UnmarshalJSON([]byte{'~'})
assert.Error(t, err)
})
}

0 comments on commit a64b97d

Please sign in to comment.