oneandone-billing-mailer/pkg/auth/authcache/tokensource.go

72 lines
1.8 KiB
Go
Raw Permalink Normal View History

2022-08-17 01:34:18 +00:00
package authcache
import (
"context"
"github.com/go-logr/logr"
"golang.org/x/oauth2"
)
type cacheTokenSource struct {
cache Cache
tokenSource oauth2.TokenSource
ctx context.Context
}
func NewCacheTokenSource(ctx context.Context, cache Cache, tokenSource oauth2.TokenSource) oauth2.TokenSource {
// Avoid dupe wrapping
if rts, ok := tokenSource.(*cacheTokenSource); ok {
return rts
}
return &cacheTokenSource{
cache: cache,
tokenSource: tokenSource,
ctx: ctx,
}
}
func (ts *cacheTokenSource) Token() (*oauth2.Token, error) {
log := logr.FromContextOrDiscard(ts.ctx).WithName("cacheTokenSource")
token, err := ts.cache.Fetch()
if err != nil {
log.V(1).Info("Failed to fetch token", "err", err.Error())
return nil, err
}
oldToken := token
// Do we have a cached token?
if token == nil || token.RefreshToken == "" {
// We are starting fresh
log.V(1).Info("No existing token, requesting fresh one")
newToken, err := ts.tokenSource.Token()
if err != nil {
log.V(1).Info("Failed to request fresh token", "err", err.Error())
return nil, err
}
token = newToken
} else if !token.Valid() /*|| token.Expiry.Add(-5*time.Minute).Before(time.Now())*/ {
// Our existing token has expired, refresh
log.V(1).Info("Existing token has expired or is about to expire, requesting refresh")
newToken, err := ts.tokenSource.Token()
if err != nil {
log.V(1).Info("Failed to refresh token", "err", err.Error())
return nil, err
}
token = newToken
}
// Persist token if changed/fresh
if oldToken == nil || oldToken.AccessToken != token.AccessToken {
log.V(1).Info("Persisting new token")
if err := ts.cache.Persist(token); err != nil {
return nil, err
}
}
log.V(1).Info("Returning token")
return token, nil
}