github.com/greenpau/go-authcrunch@v1.0.50/pkg/authz/cache/cache.go (about) 1 // Copyright 2022 Paul Greenberg greenpau@outlook.com 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package cache 16 17 import ( 18 "github.com/greenpau/go-authcrunch/pkg/errors" 19 "github.com/greenpau/go-authcrunch/pkg/user" 20 "sync" 21 "time" 22 ) 23 24 // TokenCache contains cached tokens 25 type TokenCache struct { 26 mu sync.RWMutex 27 Entries map[string]*user.User `json:"entries,omitempty" xml:"entries,omitempty" yaml:"entries,omitempty"` 28 } 29 30 // NewTokenCache returns TokenCache instance. 31 func NewTokenCache(i int) *TokenCache { 32 c := &TokenCache{ 33 Entries: make(map[string]*user.User), 34 } 35 go manageTokenCache(i, c) 36 return c 37 } 38 39 func manageTokenCache(i int, cache *TokenCache) { 40 if i == 0 { 41 i = 300000 42 } 43 // intervals := time.NewTicker(time.Minute * time.Duration(5)) 44 intervals := time.NewTicker(time.Millisecond * time.Duration(i)) 45 for range intervals.C { 46 // if cache == nil { 47 // break 48 // } 49 cache.mu.RLock() 50 if cache.Entries == nil { 51 cache.mu.RUnlock() 52 continue 53 } 54 cache.mu.RUnlock() 55 cache.mu.Lock() 56 for k, usr := range cache.Entries { 57 if err := usr.Claims.Valid(); err != nil { 58 delete(cache.Entries, k) 59 } 60 } 61 cache.mu.Unlock() 62 } 63 } 64 65 // Add adds a token and the associated claim to cache. 66 func (c *TokenCache) Add(usr *user.User) error { 67 if usr == nil { 68 return errors.ErrCacheNilUser 69 } 70 if usr.Token == "" { 71 return errors.ErrCacheEmptyToken 72 } 73 c.mu.Lock() 74 defer c.mu.Unlock() 75 usr.Cached = true 76 c.Entries[usr.Token] = usr 77 return nil 78 } 79 80 // Delete removes cached token from 81 func (c *TokenCache) Delete(token string) error { 82 c.mu.Lock() 83 defer c.mu.Unlock() 84 delete(c.Entries, token) 85 return nil 86 } 87 88 // Get returns User instance if the token associated with 89 // the claim exists in cache. If the token is expired, it 90 // will be removed from the cache. 91 func (c *TokenCache) Get(token string) *user.User { 92 c.mu.RLock() 93 usr, exists := c.Entries[token] 94 c.mu.RUnlock() 95 if !exists { 96 return nil 97 } 98 if usr.Claims.ExpiresAt < time.Now().Unix() { 99 c.Delete(token) 100 return nil 101 } 102 return usr 103 }