mirror of
https://github.com/goharbor/harbor.git
synced 2025-02-24 07:41:40 +01:00
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:
parent
2e7eb8872e
commit
05255a7ea7
@ -39,7 +39,15 @@ type cache struct {
|
|||||||
func (c *cache) get(scopes []*scope) *token {
|
func (c *cache) get(scopes []*scope) *token {
|
||||||
c.RLock()
|
c.RLock()
|
||||||
defer c.RUnlock()
|
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) {
|
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,
|
// exceed the capacity, empty some elements: all expired token will be removed,
|
||||||
// if no expired token, move the earliest one
|
// if no expired token, move the earliest one
|
||||||
if len(c.cache) >= c.capacity {
|
if len(c.cache) >= c.capacity {
|
||||||
now := time.Now().UTC()
|
|
||||||
var candidates []string
|
var candidates []string
|
||||||
var earliestKey string
|
var earliestKey string
|
||||||
var earliestExpireTime time.Time
|
var earliestExpireTime time.Time
|
||||||
for key, value := range c.cache {
|
for key, value := range c.cache {
|
||||||
// parse error
|
expired, expireAt := c.expired(value)
|
||||||
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
|
// expired
|
||||||
if expireAt.Before(now) {
|
if expired {
|
||||||
candidates = append(candidates, key)
|
candidates = append(candidates, key)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -91,3 +90,14 @@ func (c *cache) key(scopes []*scope) string {
|
|||||||
}
|
}
|
||||||
return strings.Join(strs, "#")
|
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
|
||||||
|
}
|
||||||
|
@ -64,14 +64,30 @@ func (c *cacheTestSuite) TestKey() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *cacheTestSuite) TestGet() {
|
func (c *cacheTestSuite) TestGet() {
|
||||||
token := &token{
|
// expired token
|
||||||
Token: "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)
|
t := c.cache.get(nil)
|
||||||
c.Require().NotNil(tk)
|
c.Require().Nil(t)
|
||||||
c.Equal(token.Token, tk.Token)
|
|
||||||
|
// 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() {
|
func (c *cacheTestSuite) TestSet() {
|
||||||
@ -148,6 +164,38 @@ func (c *cacheTestSuite) TestSet() {
|
|||||||
c.Require().NotNil(c.cache.get(scope4))
|
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) {
|
func TestCacheTestSuite(t *testing.T) {
|
||||||
suite.Run(t, &cacheTestSuite{})
|
suite.Run(t, &cacheTestSuite{})
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user