IAM: Skip token rotation if it has been rotated recently (#106075)
This commit is contained in:
@@ -20,6 +20,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
"github.com/grafana/grafana/pkg/services/auth"
|
||||
"github.com/grafana/grafana/pkg/services/auth/authtest"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/quota"
|
||||
"github.com/grafana/grafana/pkg/services/secrets/fakes"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
@@ -491,6 +492,13 @@ func TestIntegrationUserAuthToken(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("RotateToken", func(t *testing.T) {
|
||||
advanceTime := func(d time.Duration) {
|
||||
currentTime := getTime()
|
||||
getTime = func() time.Time {
|
||||
return currentTime.Add(d)
|
||||
}
|
||||
}
|
||||
|
||||
var prev string
|
||||
token, err := ctx.tokenService.CreateToken(context.Background(), &auth.CreateTokenCommand{
|
||||
User: usr,
|
||||
@@ -499,6 +507,7 @@ func TestIntegrationUserAuthToken(t *testing.T) {
|
||||
})
|
||||
require.NoError(t, err)
|
||||
t.Run("should rotate token when called with current auth token", func(t *testing.T) {
|
||||
advanceTime(SkipRotationTime + 1*time.Second)
|
||||
prev = token.UnhashedToken
|
||||
token, err = ctx.tokenService.RotateToken(context.Background(), auth.RotateCommand{UnHashedToken: token.UnhashedToken})
|
||||
require.NoError(t, err)
|
||||
@@ -507,6 +516,7 @@ func TestIntegrationUserAuthToken(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("should rotate token when called with previous", func(t *testing.T) {
|
||||
advanceTime(SkipRotationTime + 1*time.Second)
|
||||
newPrev := token.UnhashedToken
|
||||
token, err = ctx.tokenService.RotateToken(context.Background(), auth.RotateCommand{UnHashedToken: prev})
|
||||
require.NoError(t, err)
|
||||
@@ -514,10 +524,33 @@ func TestIntegrationUserAuthToken(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("should not rotate token when called with old previous", func(t *testing.T) {
|
||||
advanceTime(SkipRotationTime + 1*time.Second)
|
||||
_, err = ctx.tokenService.RotateToken(context.Background(), auth.RotateCommand{UnHashedToken: prev})
|
||||
require.ErrorIs(t, err, auth.ErrUserTokenNotFound)
|
||||
})
|
||||
|
||||
t.Run("should not rotate token when last rotation happened recently", func(t *testing.T) {
|
||||
advanceTime(SkipRotationTime + 1*time.Second)
|
||||
prevToken, err := ctx.tokenService.CreateToken(context.Background(), &auth.CreateTokenCommand{
|
||||
User: usr,
|
||||
ClientIP: nil,
|
||||
UserAgent: "",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
advanceTime(SkipRotationTime + 1*time.Second)
|
||||
rotatedToken, err := ctx.tokenService.RotateToken(context.Background(), auth.RotateCommand{UnHashedToken: prevToken.UnhashedToken})
|
||||
require.NoError(t, err)
|
||||
assert.True(t, rotatedToken.UnhashedToken != prevToken.UnhashedToken)
|
||||
assert.True(t, rotatedToken.PrevAuthToken == hashToken("", prevToken.UnhashedToken))
|
||||
|
||||
// Should not rotate because it already rotated less than 5s ago
|
||||
skippedToken, err := ctx.tokenService.RotateToken(context.Background(), auth.RotateCommand{UnHashedToken: rotatedToken.UnhashedToken})
|
||||
require.NoError(t, err)
|
||||
assert.True(t, skippedToken.UnhashedToken == rotatedToken.UnhashedToken)
|
||||
assert.True(t, skippedToken.PrevAuthToken == hashToken("", prevToken.UnhashedToken))
|
||||
})
|
||||
|
||||
t.Run("should return error when token is revoked", func(t *testing.T) {
|
||||
revokedToken, err := ctx.tokenService.CreateToken(context.Background(), &auth.CreateTokenCommand{
|
||||
User: usr,
|
||||
@@ -669,6 +702,7 @@ func createTestContext(t *testing.T) *testContext {
|
||||
maxInactiveDurationVal, _ := time.ParseDuration("168h")
|
||||
maxLifetimeDurationVal, _ := time.ParseDuration("720h")
|
||||
sqlstore := db.InitTestDB(t)
|
||||
tracer := tracing.InitializeTracerForTest()
|
||||
|
||||
cfg := &setting.Cfg{
|
||||
LoginMaxInactiveLifetime: maxInactiveDurationVal,
|
||||
@@ -676,7 +710,7 @@ func createTestContext(t *testing.T) *testContext {
|
||||
TokenRotationIntervalMinutes: 10,
|
||||
}
|
||||
|
||||
extSessionStore := provideExternalSessionStore(sqlstore, &fakes.FakeSecretsService{}, tracing.InitializeTracerForTest())
|
||||
extSessionStore := provideExternalSessionStore(sqlstore, &fakes.FakeSecretsService{}, tracer)
|
||||
|
||||
tokenService := &UserAuthTokenService{
|
||||
sqlStore: sqlstore,
|
||||
@@ -684,6 +718,8 @@ func createTestContext(t *testing.T) *testContext {
|
||||
log: log.New("test-logger"),
|
||||
singleflight: new(singleflight.Group),
|
||||
externalSessionStore: extSessionStore,
|
||||
features: featuremgmt.WithFeatures(featuremgmt.FlagSkipTokenRotationIfRecent),
|
||||
tracer: tracer,
|
||||
}
|
||||
|
||||
return &testContext{
|
||||
|
||||
Reference in New Issue
Block a user