diff --git a/auth/store.go b/auth/store.go index 8037d6d0c9c..366c54fabef 100644 --- a/auth/store.go +++ b/auth/store.go @@ -177,6 +177,17 @@ type authStore struct { indexWaiter func(uint64) <-chan struct{} } +func newDeleterFunc(as *authStore) func(string) { + return func(t string) { + as.simpleTokensMu.Lock() + defer as.simpleTokensMu.Unlock() + if username, ok := as.simpleTokens[t]; ok { + plog.Infof("deleting token %s for user %s", t, username) + delete(as.simpleTokens, t) + } + } +} + func (as *authStore) AuthEnable() error { as.enabledMu.Lock() defer as.enabledMu.Unlock() @@ -205,15 +216,7 @@ func (as *authStore) AuthEnable() error { as.enabled = true - tokenDeleteFunc := func(t string) { - as.simpleTokensMu.Lock() - defer as.simpleTokensMu.Unlock() - if username, ok := as.simpleTokens[t]; ok { - plog.Infof("deleting token %s for user %s", t, username) - delete(as.simpleTokens, t) - } - } - as.simpleTokenKeeper = NewSimpleTokenTTLKeeper(tokenDeleteFunc) + as.simpleTokenKeeper = NewSimpleTokenTTLKeeper(newDeleterFunc(as)) as.rangePermCache = make(map[string]*unifiedRangePermissions) @@ -887,11 +890,25 @@ func NewAuthStore(be backend.Backend, indexWaiter func(uint64) <-chan struct{}) tx.UnsafeCreateBucket(authUsersBucketName) tx.UnsafeCreateBucket(authRolesBucketName) + enabled := false + _, vs := tx.UnsafeRange(authBucketName, enableFlagKey, nil, 0) + if len(vs) == 1 { + if bytes.Equal(vs[0], authEnabled) { + enabled = true + } + } + as := &authStore{ - be: be, - simpleTokens: make(map[string]string), - revision: 0, - indexWaiter: indexWaiter, + be: be, + simpleTokens: make(map[string]string), + revision: getRevision(tx), + indexWaiter: indexWaiter, + enabled: enabled, + rangePermCache: make(map[string]*unifiedRangePermissions), + } + + if enabled { + as.simpleTokenKeeper = NewSimpleTokenTTLKeeper(newDeleterFunc(as)) } as.commitRevision(tx) @@ -921,7 +938,8 @@ func (as *authStore) commitRevision(tx backend.BatchTx) { func getRevision(tx backend.BatchTx) uint64 { _, vs := tx.UnsafeRange(authBucketName, []byte(revisionKey), nil, 0) if len(vs) != 1 { - plog.Panicf("failed to get the key of auth store revision") + // this can happen in the initialization phase + return 0 } return binary.BigEndian.Uint64(vs[0]) diff --git a/auth/store_test.go b/auth/store_test.go index 747e1b37a53..62ded405f6a 100644 --- a/auth/store_test.go +++ b/auth/store_test.go @@ -305,6 +305,9 @@ func TestRecoverFromSnapshot(t *testing.T) { as.Close() as2 := NewAuthStore(as.be, dummyIndexWaiter) + defer func(a *authStore) { + a.Close() + }(as2) if !as2.isAuthEnabled() { t.Fatal("recovering authStore from existing backend failed")