Check expired or not when getting token from cache

Check expired or not when getting token from cache

Signed-off-by: Wenkai Yin <yinw@vmware.com>
This commit is contained in:
Wenkai Yin 2020-03-13 14:57:30 +08:00
parent 2e7eb8872e
commit 05255a7ea7
2 changed files with 76 additions and 18 deletions

View File

@ -39,7 +39,15 @@ type cache struct {
func (c *cache) get(scopes []*scope) *token {
c.RLock()
defer c.RUnlock()
return c.cache[c.key(scopes)]
token := c.cache[c.key(scopes)]
if token == nil {
return nil
}
expired, _ := c.expired(token)
if expired {
token = nil
}
return token
}
func (c *cache) set(scopes []*scope, token *token) {
@ -48,22 +56,13 @@ func (c *cache) set(scopes []*scope, token *token) {
// exceed the capacity, empty some elements: all expired token will be removed,
// if no expired token, move the earliest one
if len(c.cache) >= c.capacity {
now := time.Now().UTC()
var candidates []string
var earliestKey string
var earliestExpireTime time.Time
for key, value := range c.cache {
// parse error
issueAt, err := time.Parse(time.RFC3339, value.IssuedAt)
if err != nil {
log.Errorf("failed to parse the issued at time of token %s: %v", token.IssuedAt, err)
candidates = append(candidates, key)
continue
}
expireAt := issueAt.Add(time.Duration(value.ExpiresIn-c.latency) * time.Second)
expired, expireAt := c.expired(value)
// expired
if expireAt.Before(now) {
if expired {
candidates = append(candidates, key)
continue
}
@ -91,3 +90,14 @@ func (c *cache) key(scopes []*scope) string {
}
return strings.Join(strs, "#")
}
// return whether the token is expired or not and the expired time
func (c *cache) expired(token *token) (bool, time.Time) {
issueAt, err := time.Parse(time.RFC3339, token.IssuedAt)
if err != nil {
log.Errorf("failed to parse the issued at time of token %s: %v", token.IssuedAt, err)
return true, time.Time{}
}
expireAt := issueAt.Add(time.Duration(token.ExpiresIn-c.latency) * time.Second)
return expireAt.Before(time.Now()), expireAt
}

View File

@ -64,14 +64,30 @@ func (c *cacheTestSuite) TestKey() {
}
func (c *cacheTestSuite) TestGet() {
token := &token{
Token: "token",
// expired token
tk := &token{
Token: "token",
AccessToken: "",
ExpiresIn: 10,
IssuedAt: "2006-01-02T15:04:05+07:00",
}
c.cache.set(nil, token)
c.cache.set(nil, tk)
tk := c.cache.get(nil)
c.Require().NotNil(tk)
c.Equal(token.Token, tk.Token)
t := c.cache.get(nil)
c.Require().Nil(t)
// valid token
tk = &token{
Token: "token",
AccessToken: "",
ExpiresIn: 60,
IssuedAt: time.Now().Format(time.RFC3339),
}
c.cache.set(nil, tk)
t = c.cache.get(nil)
c.Require().NotNil(t)
c.Equal("token", t.Token)
}
func (c *cacheTestSuite) TestSet() {
@ -148,6 +164,38 @@ func (c *cacheTestSuite) TestSet() {
c.Require().NotNil(c.cache.get(scope4))
}
func (c *cacheTestSuite) TestExpired() {
// invalid time format
tk := &token{
Token: "token",
AccessToken: "",
ExpiresIn: 10,
IssuedAt: "invalid_time_format",
}
expired, _ := c.cache.expired(tk)
c.Assert().True(expired)
// expired token
tk = &token{
Token: "token",
AccessToken: "",
ExpiresIn: 30,
IssuedAt: time.Now().Add(-1 * time.Minute).Format(time.RFC3339),
}
expired, _ = c.cache.expired(tk)
c.Assert().True(expired)
// valid token
tk = &token{
Token: "token",
AccessToken: "",
ExpiresIn: 30,
IssuedAt: time.Now().Format(time.RFC3339),
}
expired, _ = c.cache.expired(tk)
c.Assert().False(expired)
}
func TestCacheTestSuite(t *testing.T) {
suite.Run(t, &cacheTestSuite{})
}