From d87fd3250ebcb3e014780fe332c13067aa665174 Mon Sep 17 00:00:00 2001 From: Preston Baxter Date: Sun, 12 Nov 2023 17:29:23 -0600 Subject: [PATCH] Add public TokenRefresher --- oauth2.go | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/oauth2.go b/oauth2.go index 90a2c3d..bcefc11 100644 --- a/oauth2.go +++ b/oauth2.go @@ -260,6 +260,37 @@ func (c *Config) TokenSource(ctx context.Context, t *Token) TokenSource { } } +// TokenRefresher is a TokenSource that makes "grant_type"=="refresh_token" +// HTTP requests to renew a token using a RefreshToken. +type TokenRefresher struct { + ctx context.Context // used to get HTTP requests + conf *Config + refreshToken string +} + +// WARNING: Token is not safe for concurrent access, as it +// updates the tokenRefresher's refreshToken field. +// Within this package, it is used by reuseTokenSource which +// synchronizes calls to this method with its own mutex. +func (tf *TokenRefresher) Token() (*Token, error) { + if tf.refreshToken == "" { + return nil, errors.New("oauth2: token expired and refresh token is not set") + } + + tk, err := retrieveToken(tf.ctx, tf.conf, url.Values{ + "grant_type": {"refresh_token"}, + "refresh_token": {tf.refreshToken}, + }) + + if err != nil { + return nil, err + } + if tf.refreshToken != tk.RefreshToken { + tf.refreshToken = tk.RefreshToken + } + return tk, err +} + // tokenRefresher is a TokenSource that makes "grant_type"=="refresh_token" // HTTP requests to renew a token using a RefreshToken. type tokenRefresher struct {