oauth2/internal/token_test.go

78 lines
2.3 KiB
Go
Raw Normal View History

// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package internal
import (
"context"
"fmt"
"io"
"math"
"net/http"
"net/http/httptest"
"net/url"
"testing"
)
func TestRetrieveToken_InParams(t *testing.T) {
oauth2: move global auth style cache to be per-Config In 80673b4a4 (https://go.dev/cl/157820) I added a never-shrinking package-global cache to remember which auto-detected auth style (HTTP headers vs POST) was supported by a certain OAuth2 server, keyed by its URL. Unfortunately, some multi-tenant SaaS OIDC servers behave poorly and have one global OpenID configuration document for all of their customers which says ("we support all auth styles! you pick!") but then give each customer control of which style they specifically accept. This is bogus behavior on their part, but the oauth2 package's global caching per URL isn't helping. (It's also bad to have a package-global cache that can never be GC'ed) So, this change moves the cache to hang off the oauth *Configs instead. Unfortunately, it does so with some backwards compatiblity compromises (an atomic.Value hack), lest people are using old versions of Go still or copying a Config by value, both of which this package previously accidentally supported, even though they weren't tested. This change also means that anybody that's repeatedly making ephemeral oauth.Configs without an explicit auth style will be losing & reinitializing their cache on any auth style failures + fallbacks to the other style. I think that should be pretty rare. People seem to make an oauth2.Config once earlier and stash it away somewhere (often deep in a token fetcher or HTTP client/transport). Change-Id: I91f107368ab3c3d77bc425eeef65372a589feb7b Signed-off-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-on: https://go-review.googlesource.com/c/oauth2/+/515675 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Roland Shoemaker <roland@golang.org> Reviewed-by: Adrian Dewhurst <adrian@tailscale.com> Reviewed-by: Michael Knyszek <mknyszek@google.com>
2023-08-03 12:40:32 -04:00
styleCache := new(AuthStyleCache)
const clientID = "client-id"
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if got, want := r.FormValue("client_id"), clientID; got != want {
t.Errorf("client_id = %q; want %q", got, want)
}
if got, want := r.FormValue("client_secret"), ""; got != want {
t.Errorf("client_secret = %q; want empty", got)
}
w.Header().Set("Content-Type", "application/json")
io.WriteString(w, `{"access_token": "ACCESS_TOKEN", "token_type": "bearer"}`)
}))
defer ts.Close()
oauth2: move global auth style cache to be per-Config In 80673b4a4 (https://go.dev/cl/157820) I added a never-shrinking package-global cache to remember which auto-detected auth style (HTTP headers vs POST) was supported by a certain OAuth2 server, keyed by its URL. Unfortunately, some multi-tenant SaaS OIDC servers behave poorly and have one global OpenID configuration document for all of their customers which says ("we support all auth styles! you pick!") but then give each customer control of which style they specifically accept. This is bogus behavior on their part, but the oauth2 package's global caching per URL isn't helping. (It's also bad to have a package-global cache that can never be GC'ed) So, this change moves the cache to hang off the oauth *Configs instead. Unfortunately, it does so with some backwards compatiblity compromises (an atomic.Value hack), lest people are using old versions of Go still or copying a Config by value, both of which this package previously accidentally supported, even though they weren't tested. This change also means that anybody that's repeatedly making ephemeral oauth.Configs without an explicit auth style will be losing & reinitializing their cache on any auth style failures + fallbacks to the other style. I think that should be pretty rare. People seem to make an oauth2.Config once earlier and stash it away somewhere (often deep in a token fetcher or HTTP client/transport). Change-Id: I91f107368ab3c3d77bc425eeef65372a589feb7b Signed-off-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-on: https://go-review.googlesource.com/c/oauth2/+/515675 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Roland Shoemaker <roland@golang.org> Reviewed-by: Adrian Dewhurst <adrian@tailscale.com> Reviewed-by: Michael Knyszek <mknyszek@google.com>
2023-08-03 12:40:32 -04:00
_, err := RetrieveToken(context.Background(), clientID, "", ts.URL, url.Values{}, AuthStyleInParams, styleCache)
if err != nil {
t.Errorf("RetrieveToken = %v; want no error", err)
}
}
func TestRetrieveTokenWithContexts(t *testing.T) {
oauth2: move global auth style cache to be per-Config In 80673b4a4 (https://go.dev/cl/157820) I added a never-shrinking package-global cache to remember which auto-detected auth style (HTTP headers vs POST) was supported by a certain OAuth2 server, keyed by its URL. Unfortunately, some multi-tenant SaaS OIDC servers behave poorly and have one global OpenID configuration document for all of their customers which says ("we support all auth styles! you pick!") but then give each customer control of which style they specifically accept. This is bogus behavior on their part, but the oauth2 package's global caching per URL isn't helping. (It's also bad to have a package-global cache that can never be GC'ed) So, this change moves the cache to hang off the oauth *Configs instead. Unfortunately, it does so with some backwards compatiblity compromises (an atomic.Value hack), lest people are using old versions of Go still or copying a Config by value, both of which this package previously accidentally supported, even though they weren't tested. This change also means that anybody that's repeatedly making ephemeral oauth.Configs without an explicit auth style will be losing & reinitializing their cache on any auth style failures + fallbacks to the other style. I think that should be pretty rare. People seem to make an oauth2.Config once earlier and stash it away somewhere (often deep in a token fetcher or HTTP client/transport). Change-Id: I91f107368ab3c3d77bc425eeef65372a589feb7b Signed-off-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-on: https://go-review.googlesource.com/c/oauth2/+/515675 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Roland Shoemaker <roland@golang.org> Reviewed-by: Adrian Dewhurst <adrian@tailscale.com> Reviewed-by: Michael Knyszek <mknyszek@google.com>
2023-08-03 12:40:32 -04:00
styleCache := new(AuthStyleCache)
const clientID = "client-id"
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
io.WriteString(w, `{"access_token": "ACCESS_TOKEN", "token_type": "bearer"}`)
}))
defer ts.Close()
oauth2: move global auth style cache to be per-Config In 80673b4a4 (https://go.dev/cl/157820) I added a never-shrinking package-global cache to remember which auto-detected auth style (HTTP headers vs POST) was supported by a certain OAuth2 server, keyed by its URL. Unfortunately, some multi-tenant SaaS OIDC servers behave poorly and have one global OpenID configuration document for all of their customers which says ("we support all auth styles! you pick!") but then give each customer control of which style they specifically accept. This is bogus behavior on their part, but the oauth2 package's global caching per URL isn't helping. (It's also bad to have a package-global cache that can never be GC'ed) So, this change moves the cache to hang off the oauth *Configs instead. Unfortunately, it does so with some backwards compatiblity compromises (an atomic.Value hack), lest people are using old versions of Go still or copying a Config by value, both of which this package previously accidentally supported, even though they weren't tested. This change also means that anybody that's repeatedly making ephemeral oauth.Configs without an explicit auth style will be losing & reinitializing their cache on any auth style failures + fallbacks to the other style. I think that should be pretty rare. People seem to make an oauth2.Config once earlier and stash it away somewhere (often deep in a token fetcher or HTTP client/transport). Change-Id: I91f107368ab3c3d77bc425eeef65372a589feb7b Signed-off-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-on: https://go-review.googlesource.com/c/oauth2/+/515675 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Roland Shoemaker <roland@golang.org> Reviewed-by: Adrian Dewhurst <adrian@tailscale.com> Reviewed-by: Michael Knyszek <mknyszek@google.com>
2023-08-03 12:40:32 -04:00
_, err := RetrieveToken(context.Background(), clientID, "", ts.URL, url.Values{}, AuthStyleUnknown, styleCache)
if err != nil {
t.Errorf("RetrieveToken (with background context) = %v; want no error", err)
}
retrieved := make(chan struct{})
cancellingts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
<-retrieved
}))
defer cancellingts.Close()
ctx, cancel := context.WithCancel(context.Background())
cancel()
oauth2: move global auth style cache to be per-Config In 80673b4a4 (https://go.dev/cl/157820) I added a never-shrinking package-global cache to remember which auto-detected auth style (HTTP headers vs POST) was supported by a certain OAuth2 server, keyed by its URL. Unfortunately, some multi-tenant SaaS OIDC servers behave poorly and have one global OpenID configuration document for all of their customers which says ("we support all auth styles! you pick!") but then give each customer control of which style they specifically accept. This is bogus behavior on their part, but the oauth2 package's global caching per URL isn't helping. (It's also bad to have a package-global cache that can never be GC'ed) So, this change moves the cache to hang off the oauth *Configs instead. Unfortunately, it does so with some backwards compatiblity compromises (an atomic.Value hack), lest people are using old versions of Go still or copying a Config by value, both of which this package previously accidentally supported, even though they weren't tested. This change also means that anybody that's repeatedly making ephemeral oauth.Configs without an explicit auth style will be losing & reinitializing their cache on any auth style failures + fallbacks to the other style. I think that should be pretty rare. People seem to make an oauth2.Config once earlier and stash it away somewhere (often deep in a token fetcher or HTTP client/transport). Change-Id: I91f107368ab3c3d77bc425eeef65372a589feb7b Signed-off-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-on: https://go-review.googlesource.com/c/oauth2/+/515675 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Roland Shoemaker <roland@golang.org> Reviewed-by: Adrian Dewhurst <adrian@tailscale.com> Reviewed-by: Michael Knyszek <mknyszek@google.com>
2023-08-03 12:40:32 -04:00
_, err = RetrieveToken(ctx, clientID, "", cancellingts.URL, url.Values{}, AuthStyleUnknown, styleCache)
close(retrieved)
if err == nil {
t.Errorf("RetrieveToken (with cancelled context) = nil; want error")
}
}
func TestExpiresInUpperBound(t *testing.T) {
var e expirationTime
if err := e.UnmarshalJSON([]byte(fmt.Sprint(int64(math.MaxInt32) + 1))); err != nil {
t.Fatal(err)
}
const want = math.MaxInt32
if e != want {
t.Errorf("expiration time = %v; want %v", e, want)
}
}