78 lines
1.4 KiB
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
|
|
}
|