From d8658a765c568d62cfeb3e5bac6d2a55969c9e65 Mon Sep 17 00:00:00 2001 From: Marcus Efraimsson Date: Wed, 6 Feb 2019 08:30:14 +0100 Subject: [PATCH] enhanced expiration logic for lookup token tokens are not expired if created_at > now - LoginMaxLifetimeDays and rotated_at > now - LoginMaxInactiveLifetimeDays --- pkg/services/auth/authtoken/auth_token.go | 7 +- .../auth/authtoken/auth_token_test.go | 70 +++++++++++++++++-- 2 files changed, 69 insertions(+), 8 deletions(-) diff --git a/pkg/services/auth/authtoken/auth_token.go b/pkg/services/auth/authtoken/auth_token.go index 1fdad4dbea5..47aa925fd4d 100644 --- a/pkg/services/auth/authtoken/auth_token.go +++ b/pkg/services/auth/authtoken/auth_token.go @@ -81,10 +81,13 @@ func (s *UserAuthTokenServiceImpl) LookupToken(unhashedToken string) (auth.UserT s.log.Debug("looking up token", "unhashed", unhashedToken, "hashed", hashedToken) } - expireBefore := getTime().Add(time.Duration(-86400*s.Cfg.LoginMaxInactiveLifetimeDays) * time.Second).Unix() + tokenMaxLifetime := time.Duration(s.Cfg.LoginMaxLifetimeDays) * 24 * time.Hour + tokenMaxInactiveLifetime := time.Duration(s.Cfg.LoginMaxInactiveLifetimeDays) * 24 * time.Hour + createdAfter := getTime().Add(-tokenMaxLifetime).Unix() + rotatedAfter := getTime().Add(-tokenMaxInactiveLifetime).Unix() var model userAuthToken - exists, err := s.SQLStore.NewSession().Where("(auth_token = ? OR prev_auth_token = ?) AND created_at > ?", hashedToken, hashedToken, expireBefore).Get(&model) + exists, err := s.SQLStore.NewSession().Where("(auth_token = ? OR prev_auth_token = ?) AND created_at > ? AND rotated_at > ?", hashedToken, hashedToken, createdAfter, rotatedAfter).Get(&model) if err != nil { return nil, err } diff --git a/pkg/services/auth/authtoken/auth_token_test.go b/pkg/services/auth/authtoken/auth_token_test.go index 51d361a9f4f..7ecb67b2ebf 100644 --- a/pkg/services/auth/authtoken/auth_token_test.go +++ b/pkg/services/auth/authtoken/auth_token_test.go @@ -105,12 +105,56 @@ func TestUserAuthToken(t *testing.T) { So(err, ShouldBeNil) So(stillGood, ShouldNotBeNil) - getTime = func() time.Time { - return t.Add(24 * 7 * time.Hour) - } - notGood, err := userAuthTokenService.LookupToken(model.UnhashedToken) - So(err, ShouldEqual, ErrAuthTokenNotFound) - So(notGood, ShouldBeNil) + model, err = ctx.getAuthTokenByID(model.Id) + So(err, ShouldBeNil) + + Convey("when rotated_at is 6:59:59 ago should find token", func() { + getTime = func() time.Time { + return time.Unix(model.RotatedAt, 0).Add(24 * 7 * time.Hour).Add(-time.Second) + } + + stillGood, err = userAuthTokenService.LookupToken(stillGood.GetToken()) + So(err, ShouldBeNil) + So(stillGood, ShouldNotBeNil) + }) + + Convey("when rotated_at is 7:00:00 ago should not find token", func() { + getTime = func() time.Time { + return time.Unix(model.RotatedAt, 0).Add(24 * 7 * time.Hour) + } + + notGood, err := userAuthTokenService.LookupToken(userToken.GetToken()) + So(err, ShouldEqual, ErrAuthTokenNotFound) + So(notGood, ShouldBeNil) + }) + + Convey("when rotated_at is 5 days ago and created_at is 29 days and 23:59:59 ago should not find token", func() { + updated, err := ctx.updateRotatedAt(model.Id, time.Unix(model.CreatedAt, 0).Add(24*25*time.Hour).Unix()) + So(err, ShouldBeNil) + So(updated, ShouldBeTrue) + + getTime = func() time.Time { + return time.Unix(model.CreatedAt, 0).Add(24 * 30 * time.Hour).Add(-time.Second) + } + + stillGood, err = userAuthTokenService.LookupToken(stillGood.GetToken()) + So(err, ShouldBeNil) + So(stillGood, ShouldNotBeNil) + }) + + Convey("when rotated_at is 5 days ago and created_at is 30 days ago should not find token", func() { + updated, err := ctx.updateRotatedAt(model.Id, time.Unix(model.CreatedAt, 0).Add(24*25*time.Hour).Unix()) + So(err, ShouldBeNil) + So(updated, ShouldBeTrue) + + getTime = func() time.Time { + return time.Unix(model.CreatedAt, 0).Add(24 * 30 * time.Hour) + } + + notGood, err := userAuthTokenService.LookupToken(userToken.GetToken()) + So(err, ShouldEqual, ErrAuthTokenNotFound) + So(notGood, ShouldBeNil) + }) }) Convey("can properly rotate tokens", func() { @@ -384,3 +428,17 @@ func (c *testContext) markAuthTokenAsSeen(id int64) (bool, error) { } return rowsAffected == 1, nil } + +func (c *testContext) updateRotatedAt(id, rotatedAt int64) (bool, error) { + sess := c.sqlstore.NewSession() + res, err := sess.Exec("UPDATE user_auth_token SET rotated_at = ? WHERE id = ?", rotatedAt, id) + if err != nil { + return false, err + } + + rowsAffected, err := res.RowsAffected() + if err != nil { + return false, err + } + return rowsAffected == 1, nil +}