Skip to content

Commit

Permalink
bearer,session: Invert method checking token lifetime validity
Browse files Browse the repository at this point in the history
Previously, bearer and session token types provided `InvalidAt` method
checking whether the token is invalid at the given epoch. This was not a
very good choice, since users are more naturally inclined to work with
affirmative methods. In this case, the validity check, not the
invalidity one.

This extends interface of NeoFS tokens with `ValidAt` method.
`InvalidAt` ones are marked deprecated.

Signed-off-by: Leonard Lyubich <[email protected]>
  • Loading branch information
cthulhu-rider committed Sep 26, 2024
1 parent 192f4cd commit 6ea9f9c
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 17 deletions.
17 changes: 11 additions & 6 deletions bearer/bearer.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ func (b Token) WriteToV2(m *acl.BearerToken) {
//
// Naming is inspired by https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.4.
//
// See also InvalidAt.
// See also [Token.ValidAt].
func (b *Token) SetExp(exp uint64) {
b.exp = exp
}
Expand All @@ -184,7 +184,7 @@ func (b Token) Exp() uint64 {
//
// Naming is inspired by https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.5.
//
// See also InvalidAt.
// See also [Token.ValidAt].
func (b *Token) SetNbf(nbf uint64) {
b.nbf = nbf
}
Expand All @@ -200,7 +200,7 @@ func (b Token) Nbf() uint64 {
//
// Naming is inspired by https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.6.
//
// See also InvalidAt.
// See also [Token.ValidAt].
func (b *Token) SetIat(iat uint64) {
b.iat = iat
}
Expand All @@ -210,14 +210,19 @@ func (b Token) Iat() uint64 {
return b.iat
}

// ValidAt checks whether the Token is still valid at the given epoch according
// to its lifetime claims.
func (b Token) ValidAt(epoch uint64) bool {
return b.Nbf() <= epoch && b.Iat() <= epoch && b.Exp() >= epoch
}

// InvalidAt asserts "exp", "nbf" and "iat" claims for the given epoch.
//
// Zero Container is invalid in any epoch.
//
// See also SetExp, SetNbf, SetIat.
func (b Token) InvalidAt(epoch uint64) bool {
return b.Nbf() > epoch || b.Iat() > epoch || b.Exp() < epoch
}
// Deprecated: use inverse [Token.ValidAt] instead.
func (b Token) InvalidAt(epoch uint64) bool { return !b.ValidAt(epoch) }

// SetEACLTable sets eacl.Table that replaces the one from the issuer's
// container. If table has specified container, bearer token can be used only
Expand Down
10 changes: 9 additions & 1 deletion bearer/bearer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,21 +267,29 @@ func TestToken_SetExp(t *testing.T) {
testLifetimeClaim(t, (*bearer.Token).SetExp, bearer.Token.Exp)
}

func TestToken_InvalidAt(t *testing.T) {
func TestToken_ValidAt(t *testing.T) {
var val bearer.Token

require.True(t, val.ValidAt(0))
require.False(t, val.InvalidAt(0))
require.False(t, val.ValidAt(1))
require.True(t, val.InvalidAt(1))

val.SetIat(1)
val.SetNbf(2)
val.SetExp(4)

require.False(t, val.ValidAt(0))
require.True(t, val.InvalidAt(0))
require.False(t, val.ValidAt(1))
require.True(t, val.InvalidAt(1))
require.True(t, val.ValidAt(2))
require.False(t, val.InvalidAt(2))
require.True(t, val.ValidAt(3))
require.False(t, val.InvalidAt(3))
require.True(t, val.ValidAt(4))
require.False(t, val.InvalidAt(4))
require.False(t, val.ValidAt(5))
require.True(t, val.InvalidAt(5))
}

Expand Down
15 changes: 10 additions & 5 deletions session/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ func (x commonData) Exp() uint64 {
//
// Naming is inspired by https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.5.
//
// See also InvalidAt.
// See also ValidAt.
func (x *commonData) SetNbf(nbf uint64) {
x.nbf = nbf
}
Expand All @@ -260,7 +260,7 @@ func (x commonData) Nbf() uint64 {
//
// Naming is inspired by https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.6.
//
// See also InvalidAt.
// See also ValidAt.
func (x *commonData) SetIat(iat uint64) {
x.iat = iat
}
Expand All @@ -274,14 +274,19 @@ func (x commonData) expiredAt(epoch uint64) bool {
return x.Exp() < epoch
}

// ValidAt checks whether the token is still valid at the given epoch according
// to its lifetime claims.
func (x commonData) ValidAt(epoch uint64) bool {
return x.Nbf() <= epoch && x.Iat() <= epoch && x.Exp() >= epoch
}

// InvalidAt asserts "exp", "nbf" and "iat" claims.
//
// Zero session is invalid in any epoch.
//
// See also SetExp, SetNbf, SetIat.
func (x commonData) InvalidAt(epoch uint64) bool {
return x.expiredAt(epoch) || x.Nbf() > epoch || x.Iat() > epoch
}
// Deprecated: use inverse [Token.ValidAt] instead.
func (x commonData) InvalidAt(epoch uint64) bool { return !x.ValidAt(epoch) }

// SetID sets a unique identifier for the session. The identifier value MUST be
// assigned in a manner that ensures that there is a negligible probability
Expand Down
13 changes: 10 additions & 3 deletions session/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,13 +226,15 @@ func testLifetimeClaim[T session.Container | session.Object](t testing.TB, get f
require.EqualValues(t, 5469830342, get(x))
}

func testInvalidAt[T interface {
func testValidAt[T interface {
*session.Container | *session.Object
SetExp(uint64)
SetIat(uint64)
SetNbf(uint64)
ValidAt(uint64) bool
InvalidAt(uint64) bool
}](t testing.TB, x T) {
require.True(t, x.ValidAt(0))
require.False(t, x.InvalidAt(0))

const iat = 13
Expand All @@ -243,16 +245,21 @@ func testInvalidAt[T interface {
x.SetNbf(nbf)
x.SetExp(exp)

require.False(t, x.ValidAt(iat-1))
require.True(t, x.InvalidAt(iat-1))
require.False(t, x.ValidAt(iat))
require.True(t, x.InvalidAt(iat))
require.True(t, x.ValidAt(nbf))
require.False(t, x.InvalidAt(nbf))
require.True(t, x.ValidAt(exp))
require.False(t, x.InvalidAt(exp))
require.False(t, x.ValidAt(exp+1))
require.True(t, x.InvalidAt(exp+1))
}

func TestInvalidAt(t *testing.T) {
testInvalidAt(t, new(session.Container))
testInvalidAt(t, new(session.Object))
testValidAt(t, new(session.Container))
testValidAt(t, new(session.Object))
}

func testSetAuthKey[T session.Container | session.Object](t testing.TB, set func(*T, neofscrypto.PublicKey), assert func(T, neofscrypto.PublicKey) bool) {
Expand Down
2 changes: 1 addition & 1 deletion session/container_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ func TestContainer_ApplyOnlyTo(t *testing.T) {
}

func TestContainer_InvalidAt(t *testing.T) {
testInvalidAt(t, new(session.Container))
testValidAt(t, new(session.Container))
}

func TestContainer_ID(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion session/object_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,7 @@ func TestObject_LimitByObjects(t *testing.T) {
}

func TestObject_InvalidAt(t *testing.T) {
testInvalidAt(t, new(session.Object))
testValidAt(t, new(session.Object))
}

func TestObject_ID(t *testing.T) {
Expand Down

0 comments on commit 6ea9f9c

Please sign in to comment.