Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions pagination/keysetpagination_v2/page_token.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
"github.com/ory/herodot"
)

var fallbackEncryptionKey = &[32]byte{}

type (
PageToken struct {
testNow func() time.Time
Expand All @@ -34,10 +36,11 @@ func (t PageToken) Columns() []Column { return t.cols }
// Encrypt encrypts the page token using the first key in the provided keyset.
// It panics if no keys are provided.
func (t PageToken) Encrypt(keys [][32]byte) string {
if len(keys) == 0 {
panic("keyset pagination: cannot encrypt page token with no keys")
key := fallbackEncryptionKey
if len(keys) > 0 {
key = &keys[0]
}
return hyrumtoken.Marshal(&keys[0], t)
return hyrumtoken.Marshal(key, t)
}

func (t PageToken) MarshalJSON() ([]byte, error) {
Expand Down
9 changes: 6 additions & 3 deletions pagination/keysetpagination_v2/page_token_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,11 @@ func TestPageToken_Encrypt(t *testing.T) {
assert.ErrorContains(t, err, "decrypt token")
})

t.Run("panics with no keys", func(t *testing.T) {
assert.PanicsWithValue(t, "keyset pagination: cannot encrypt page token with no keys", func() { token.Encrypt(nil) })
assert.PanicsWithValue(t, "keyset pagination: cannot encrypt page token with no keys", func() { token.Encrypt([][32]byte{}) })
t.Run("uses fallback key", func(t *testing.T) {
for _, encrypted := range []string{token.Encrypt(nil), token.Encrypt([][32]byte{})} {
decrypted, err := ParsePageToken([][32]byte{*fallbackEncryptionKey}, encrypted)
require.NoError(t, err)
assert.Equal(t, token, decrypted)
}
})
}
7 changes: 3 additions & 4 deletions pagination/keysetpagination_v2/request_params.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,13 @@ func ParseQueryParams(keys [][32]byte, q url.Values) ([]Option, error) {
// ParsePageToken parses a page token from the given raw string using the provided keys.
// It panics if no keys are provided.
func ParsePageToken(keys [][32]byte, raw string) (t PageToken, err error) {
if len(keys) == 0 {
panic("keysetpagination: cannot parse page token with no keys")
}
for i := range keys {
err = errors.WithStack(hyrumtoken.Unmarshal(&keys[i], raw, &t))
if err == nil {
return
}
}
return
// as a last resort, try the fallback key
err = hyrumtoken.Unmarshal(fallbackEncryptionKey, raw, &t)
return t, errors.WithStack(err)
}
9 changes: 9 additions & 0 deletions pagination/keysetpagination_v2/request_params_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,15 @@ func TestParsePageToken(t *testing.T) {
require.ErrorContains(t, err, "decrypt token")
assert.Zero(t, token)
})

t.Run("uses fallback key", func(t *testing.T) {
fallbackEncryptedToken := expectedToken.Encrypt(nil)
for _, noKeys := range [][][32]byte{nil, {}} {
token, err := ParsePageToken(noKeys, fallbackEncryptedToken)
require.NoError(t, err)
assert.Equal(t, expectedToken, token)
}
})
}

func TestParse(t *testing.T) {
Expand Down
Loading