Files
cloud-services/pkg/cache/apitokens.go

78 lines
1.4 KiB
Go

package cache
import (
"sync"
"time"
"github.com/fiskerinc/cloud-services/pkg/common"
"github.com/pkg/errors"
"github.com/fiskerinc/cloud-services/pkg/db/queries"
"github.com/ReneKroon/ttlcache/v2"
)
const ApiKeyHeader = "Api-Key"
var (
ErrInvalidToken = errors.New("invalid API token")
ErrTokenExpired = errors.New("token is expired")
)
type APITokenCache struct {
APITokens queries.APITokensInterface
cache *ttlcache.Cache
onceCache sync.Once
}
func (a *APITokenCache) Get(key string) (string, error) {
value, err := a.Cache().Get(key)
if err == nil {
apiToken, ok := value.(*common.APIToken)
if !ok {
return "", ErrInvalidToken
}
if apiToken.ExpiresAt != nil && apiToken.ExpiresAt.Before(time.Now()) {
return "", ErrTokenExpired
}
return apiToken.Roles, nil
} else if !errors.Is(err, ttlcache.ErrNotFound) {
return "", err
}
item, err := a.APITokens.Get(key)
if err != nil {
return "", err
}
if item.ExpiresAt != nil && item.ExpiresAt.Before(time.Now()) {
return "", ErrTokenExpired
}
err = a.Cache().Set(key, item)
if err != nil {
return "", err
}
return item.Roles, nil
}
func (a *APITokenCache) Cache() *ttlcache.Cache {
a.onceCache.Do(func() {
if a.cache == nil {
cache := ttlcache.NewCache()
cache.SetTTL(10 * time.Minute)
cache.SetCacheSizeLimit(10)
a.cache = cache
}
})
return a.cache
}
func (a *APITokenCache) Close() {
a.cache.Close()
a.cache = nil
a.APITokens = nil
}