[oauth2] oauth2: add ReuseTokenSourceWithExpiry

0 views
Skip to first unread message

Roland Shoemaker (Gerrit)

unread,
Mar 28, 2023, 2:36:15 PM3/28/23
to goph...@pubsubhelper.golang.org, golang-...@googlegroups.com, Gopher Robot, Cody Oss, golang-co...@googlegroups.com

Roland Shoemaker submitted this change.

View Change



2 is the latest approved patch-set.
The change was submitted with unreviewed changes in the following files:

```
The name of the file: oauth2.go
Insertions: 4, Deletions: 1.

@@ -395,12 +395,15 @@
if rt, ok := src.(*reuseTokenSource); ok {
if t == nil {
// Just use it directly, but set the expiryDelta to earlyExpiry,
- // so the behavior matches what the use expects.
+ // so the behavior matches what the user expects.
rt.expiryDelta = earlyExpiry
return rt
}
src = rt.new
}
+ if t != nil {
+ t.expiryDelta = earlyExpiry
+ }
return &reuseTokenSource{
t: t,
new: src,
```

Approvals: Cody Oss: Looks good to me, approved Roland Shoemaker: Run TryBots Gopher Robot: TryBots succeeded
oauth2: add ReuseTokenSourceWithExpiry

Add a constructor which allows for the configuration of the expiryDelta
buffer. Due to the construction of reuseTokenSource and Token we need
to store the new delta in both places, so the behavior of Valid is
consistent regardless of where it is called from.

Fixes #623

Change-Id: I89f9c206a9cc16bb473b8c619605c8410a82fff0
Reviewed-on: https://go-review.googlesource.com/c/oauth2/+/479676
Run-TryBot: Roland Shoemaker <rol...@golang.org>
Reviewed-by: Cody Oss <cod...@google.com>
TryBot-Result: Gopher Robot <go...@golang.org>
---
M oauth2.go
M token.go
M token_test.go
3 files changed, 49 insertions(+), 4 deletions(-)

diff --git a/oauth2.go b/oauth2.go
index de52304..9085fab 100644
--- a/oauth2.go
+++ b/oauth2.go
@@ -16,6 +16,7 @@
"net/url"
"strings"
"sync"
+ "time"

"golang.org/x/oauth2/internal"
)
@@ -290,6 +291,8 @@

mu sync.Mutex // guards t
t *Token
+
+ expiryDelta time.Duration
}

// Token returns the current token if it's still valid, else will
@@ -305,6 +308,7 @@
if err != nil {
return nil, err
}
+ t.expiryDelta = s.expiryDelta
s.t = t
return t, nil
}
@@ -379,3 +383,30 @@
new: src,
}
}
+
+// ReuseTokenSource returns a TokenSource that acts in the same manner as the
+// TokenSource returned by ReuseTokenSource, except the expiry buffer is
+// configurable. The expiration time of a token is calculated as
+// t.Expiry.Add(-earlyExpiry).
+func ReuseTokenSourceWithExpiry(t *Token, src TokenSource, earlyExpiry time.Duration) TokenSource {
+ // Don't wrap a reuseTokenSource in itself. That would work,
+ // but cause an unnecessary number of mutex operations.
+ // Just build the equivalent one.
+ if rt, ok := src.(*reuseTokenSource); ok {
+ if t == nil {
+ // Just use it directly, but set the expiryDelta to earlyExpiry,
+ // so the behavior matches what the user expects.
+ rt.expiryDelta = earlyExpiry
+ return rt
+ }
+ src = rt.new
+ }
+ if t != nil {
+ t.expiryDelta = earlyExpiry
+ }
+ return &reuseTokenSource{
+ t: t,
+ new: src,
+ expiryDelta: earlyExpiry,
+ }
+}
diff --git a/token.go b/token.go
index 8227203..7c64006 100644
--- a/token.go
+++ b/token.go
@@ -16,10 +16,10 @@
"golang.org/x/oauth2/internal"
)

-// expiryDelta determines how earlier a token should be considered
+// defaultExpiryDelta determines how earlier a token should be considered
// expired than its actual expiration time. It is used to avoid late
// expirations due to client-server time mismatches.
-const expiryDelta = 10 * time.Second
+const defaultExpiryDelta = 10 * time.Second

// Token represents the credentials used to authorize
// the requests to access protected resources on the OAuth 2.0
@@ -52,6 +52,11 @@
// raw optionally contains extra metadata from the server
// when updating a token.
raw interface{}
+
+ // expiryDelta is used to calculate when a token is considered
+ // expired, by subtracting from Expiry. If zero, defaultExpiryDelta
+ // is used.
+ expiryDelta time.Duration
}

// Type returns t.TokenType if non-empty, else "Bearer".
@@ -127,6 +132,11 @@
if t.Expiry.IsZero() {
return false
}
+
+ expiryDelta := defaultExpiryDelta
+ if t.expiryDelta != 0 {
+ expiryDelta = t.expiryDelta
+ }
return t.Expiry.Round(0).Add(-expiryDelta).Before(timeNow())
}

diff --git a/token_test.go b/token_test.go
index ee97b4f..0d8c7df 100644
--- a/token_test.go
+++ b/token_test.go
@@ -43,9 +43,13 @@
want bool
}{
{name: "12 seconds", tok: &Token{Expiry: now.Add(12 * time.Second)}, want: false},
- {name: "10 seconds", tok: &Token{Expiry: now.Add(expiryDelta)}, want: false},
- {name: "10 seconds-1ns", tok: &Token{Expiry: now.Add(expiryDelta - 1*time.Nanosecond)}, want: true},
+ {name: "10 seconds", tok: &Token{Expiry: now.Add(defaultExpiryDelta)}, want: false},
+ {name: "10 seconds-1ns", tok: &Token{Expiry: now.Add(defaultExpiryDelta - 1*time.Nanosecond)}, want: true},
{name: "-1 hour", tok: &Token{Expiry: now.Add(-1 * time.Hour)}, want: true},
+ {name: "12 seconds, custom expiryDelta", tok: &Token{Expiry: now.Add(12 * time.Second), expiryDelta: time.Second * 5}, want: false},
+ {name: "5 seconds, custom expiryDelta", tok: &Token{Expiry: now.Add(time.Second * 5), expiryDelta: time.Second * 5}, want: false},
+ {name: "5 seconds-1ns, custom expiryDelta", tok: &Token{Expiry: now.Add(time.Second*5 - 1*time.Nanosecond), expiryDelta: time.Second * 5}, want: true},
+ {name: "-1 hour, custom expiryDelta", tok: &Token{Expiry: now.Add(-1 * time.Hour), expiryDelta: time.Second * 5}, want: true},
}
for _, tc := range cases {
if got, want := tc.tok.expired(), tc.want; got != want {

To view, visit change 479676. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: oauth2
Gerrit-Branch: master
Gerrit-Change-Id: I89f9c206a9cc16bb473b8c619605c8410a82fff0
Gerrit-Change-Number: 479676
Gerrit-PatchSet: 5
Gerrit-Owner: Roland Shoemaker <rol...@golang.org>
Gerrit-Reviewer: Cody Oss <cod...@google.com>
Gerrit-Reviewer: Gopher Robot <go...@golang.org>
Gerrit-Reviewer: Roland Shoemaker <rol...@golang.org>
Gerrit-MessageType: merged
Reply all
Reply to author
Forward
0 new messages