aidantwoods / go-paseto

Platform-Agnostic Security Tokens implementation in Golang.
https://pkg.go.dev/aidanwoods.dev/go-paseto
MIT License
284 stars 16 forks source link

Discussion: Exp time using RFC3339 causes different value to be saved #14

Closed andrei-cdl closed 1 year ago

andrei-cdl commented 1 year ago

Hello, as I was writing a unit test to validate the token data being for used for expiration I ran across an odd scenario.

func Test_something(t *testing.T) {
    token := paseto.NewToken()
    tommorow := time.Now().Add(time.Hour * 24)

    token.SetExpiration(tommorow)

    retreived_exp, err := token.GetExpiration()
    assert.NilError(t, err)
    assert.Assert(t, tommorow.Equal(retreived_exp))
}

So the only way I can see this working is to ensure we first create a time, then we need to format it to RFC3339 and then parse it back to time.

example:

        token := paseto.NewToken()

    expires := time.Now().Add(time.Hour * 24).Format(time.RFC3339);
    expires_rfc3339, _ := time.Parse(time.RFC3339, expires)

        token.SetExpiration(tommorow)

EDIT: another solution is to use truncate

        token := paseto.NewToken()
    expires := time.Now().Add(time.Hour * 24).Truncate(time.Second)

        token.SetExpiration(tommorow)

I think this results in dropping the last values.

relevant snippets:

aidantwoods commented 1 year ago

This falls under expected behaviour because the PASETO spec specifies that RFC 3339 be used for times.

I agree that this creates a somewhat surprising result when running tests to check the time is the same, although in practice I think this is unlikely to cause issues (given it's more interesting to compare orderings of times than their exact value).

If you need to check two times are equal for the purpose of tests, I'd recommend comparing the unix timestamp (which is in seconds) using t.Unix() 🙂