From 777bd9ea1845893739fac9549bc4cbb0cdcc913e Mon Sep 17 00:00:00 2001 From: bergquist Date: Mon, 21 Jan 2019 17:05:42 +0100 Subject: [PATCH] adds cleanup job for old session tokens --- pkg/services/auth/auth_token.go | 8 +++-- pkg/services/auth/session_cleanup.go | 38 +++++++++++++++++++++++ pkg/services/auth/session_cleanup_test.go | 37 ++++++++++++++++++++++ 3 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 pkg/services/auth/session_cleanup.go create mode 100644 pkg/services/auth/session_cleanup_test.go diff --git a/pkg/services/auth/auth_token.go b/pkg/services/auth/auth_token.go index 1fb3543d354..3e3bd75869d 100644 --- a/pkg/services/auth/auth_token.go +++ b/pkg/services/auth/auth_token.go @@ -8,6 +8,7 @@ import ( "time" "github.com/grafana/grafana/pkg/bus" + "github.com/grafana/grafana/pkg/infra/serverlock" "github.com/grafana/grafana/pkg/log" "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/registry" @@ -29,8 +30,9 @@ var ( // UserAuthTokenService are used for generating and validating user auth tokens type UserAuthTokenService struct { - SQLStore *sqlstore.SqlStore `inject:""` - log log.Logger + SQLStore *sqlstore.SqlStore `inject:""` + ServerLockService *serverlock.ServerLockService `inject:""` + log log.Logger } // Init this service @@ -239,7 +241,7 @@ func (s *UserAuthTokenService) RefreshToken(token *models.UserAuthToken, clientI } affected, _ := res.RowsAffected() - s.log.Debug("rotated", "affected", affected, "auth_token_id", token.Id, "userId", token.UserId, "user_agent", userAgent, "client_ip", clientIP) + s.log.Debug("rotated", "affected", affected, "auth_token_id", token.Id, "userId", token.UserId) if affected > 0 { token.UnhashedToken = newToken return true, nil diff --git a/pkg/services/auth/session_cleanup.go b/pkg/services/auth/session_cleanup.go new file mode 100644 index 00000000000..16f6deb9005 --- /dev/null +++ b/pkg/services/auth/session_cleanup.go @@ -0,0 +1,38 @@ +package auth + +import ( + "context" + "time" +) + +func (srv *UserAuthTokenService) Run(ctx context.Context) error { + ticker := time.NewTicker(time.Hour * 12) + deleteSessionAfter := time.Hour * 24 * 7 * 30 + + for { + select { + case <-ticker.C: + srv.ServerLockService.LockAndExecute(ctx, "delete old sessions", time.Hour*12, func() { + srv.deleteOldSession(deleteSessionAfter) + }) + + case <-ctx.Done(): + return ctx.Err() + } + } +} + +func (srv *UserAuthTokenService) deleteOldSession(deleteSessionAfter time.Duration) (int64, error) { + sql := `DELETE from user_auth_token WHERE rotated_at < ?` + + deleteBefore := getTime().Add(-deleteSessionAfter) + res, err := srv.SQLStore.NewSession().Exec(sql, deleteBefore.Unix()) + if err != nil { + return 0, err + } + + affected, err := res.RowsAffected() + srv.log.Info("deleted old sessions", "count", affected) + + return affected, err +} diff --git a/pkg/services/auth/session_cleanup_test.go b/pkg/services/auth/session_cleanup_test.go new file mode 100644 index 00000000000..1f3b7ad0c7d --- /dev/null +++ b/pkg/services/auth/session_cleanup_test.go @@ -0,0 +1,37 @@ +package auth + +import ( + "fmt" + "testing" + "time" + + "github.com/grafana/grafana/pkg/models" + . "github.com/smartystreets/goconvey/convey" +) + +func TestUserAuthTokenCleanup(t *testing.T) { + + Convey("Test user auth token cleanup", t, func() { + ctx := createTestContext(t) + + insertToken := func(token string, prev string, rotatedAt int64) { + ut := models.UserAuthToken{AuthToken: token, PrevAuthToken: prev, RotatedAt: rotatedAt, UserAgent: "", ClientIp: ""} + _, err := ctx.sqlstore.NewSession().Insert(&ut) + So(err, ShouldBeNil) + } + + // insert three old tokens that should be deleted + for i := 0; i < 3; i++ { + insertToken(fmt.Sprintf("oldA%d", i), fmt.Sprintf("oldB%d", i), int64(i)) + } + + // insert three active tokens that should not be deleted + for i := 0; i < 3; i++ { + insertToken(fmt.Sprintf("newA%d", i), fmt.Sprintf("newB%d", i), getTime().Unix()) + } + + affected, err := ctx.tokenService.deleteOldSession(time.Hour) + So(err, ShouldBeNil) + So(affected, ShouldEqual, 3) + }) +}