mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-11-04 01:53:42 +08:00 
			
		
		
		
	vendor: update buildkit to 664c2b469f19
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
This commit is contained in:
		
							
								
								
									
										198
									
								
								vendor/golang.org/x/oauth2/deviceauth.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										198
									
								
								vendor/golang.org/x/oauth2/deviceauth.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,198 @@
 | 
			
		||||
package oauth2
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"net/url"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"golang.org/x/oauth2/internal"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// https://datatracker.ietf.org/doc/html/rfc8628#section-3.5
 | 
			
		||||
const (
 | 
			
		||||
	errAuthorizationPending = "authorization_pending"
 | 
			
		||||
	errSlowDown             = "slow_down"
 | 
			
		||||
	errAccessDenied         = "access_denied"
 | 
			
		||||
	errExpiredToken         = "expired_token"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// DeviceAuthResponse describes a successful RFC 8628 Device Authorization Response
 | 
			
		||||
// https://datatracker.ietf.org/doc/html/rfc8628#section-3.2
 | 
			
		||||
type DeviceAuthResponse struct {
 | 
			
		||||
	// DeviceCode
 | 
			
		||||
	DeviceCode string `json:"device_code"`
 | 
			
		||||
	// UserCode is the code the user should enter at the verification uri
 | 
			
		||||
	UserCode string `json:"user_code"`
 | 
			
		||||
	// VerificationURI is where user should enter the user code
 | 
			
		||||
	VerificationURI string `json:"verification_uri"`
 | 
			
		||||
	// VerificationURIComplete (if populated) includes the user code in the verification URI. This is typically shown to the user in non-textual form, such as a QR code.
 | 
			
		||||
	VerificationURIComplete string `json:"verification_uri_complete,omitempty"`
 | 
			
		||||
	// Expiry is when the device code and user code expire
 | 
			
		||||
	Expiry time.Time `json:"expires_in,omitempty"`
 | 
			
		||||
	// Interval is the duration in seconds that Poll should wait between requests
 | 
			
		||||
	Interval int64 `json:"interval,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d DeviceAuthResponse) MarshalJSON() ([]byte, error) {
 | 
			
		||||
	type Alias DeviceAuthResponse
 | 
			
		||||
	var expiresIn int64
 | 
			
		||||
	if !d.Expiry.IsZero() {
 | 
			
		||||
		expiresIn = int64(time.Until(d.Expiry).Seconds())
 | 
			
		||||
	}
 | 
			
		||||
	return json.Marshal(&struct {
 | 
			
		||||
		ExpiresIn int64 `json:"expires_in,omitempty"`
 | 
			
		||||
		*Alias
 | 
			
		||||
	}{
 | 
			
		||||
		ExpiresIn: expiresIn,
 | 
			
		||||
		Alias:     (*Alias)(&d),
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *DeviceAuthResponse) UnmarshalJSON(data []byte) error {
 | 
			
		||||
	type Alias DeviceAuthResponse
 | 
			
		||||
	aux := &struct {
 | 
			
		||||
		ExpiresIn int64 `json:"expires_in"`
 | 
			
		||||
		// workaround misspelling of verification_uri
 | 
			
		||||
		VerificationURL string `json:"verification_url"`
 | 
			
		||||
		*Alias
 | 
			
		||||
	}{
 | 
			
		||||
		Alias: (*Alias)(c),
 | 
			
		||||
	}
 | 
			
		||||
	if err := json.Unmarshal(data, &aux); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	if aux.ExpiresIn != 0 {
 | 
			
		||||
		c.Expiry = time.Now().UTC().Add(time.Second * time.Duration(aux.ExpiresIn))
 | 
			
		||||
	}
 | 
			
		||||
	if c.VerificationURI == "" {
 | 
			
		||||
		c.VerificationURI = aux.VerificationURL
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DeviceAuth returns a device auth struct which contains a device code
 | 
			
		||||
// and authorization information provided for users to enter on another device.
 | 
			
		||||
func (c *Config) DeviceAuth(ctx context.Context, opts ...AuthCodeOption) (*DeviceAuthResponse, error) {
 | 
			
		||||
	// https://datatracker.ietf.org/doc/html/rfc8628#section-3.1
 | 
			
		||||
	v := url.Values{
 | 
			
		||||
		"client_id": {c.ClientID},
 | 
			
		||||
	}
 | 
			
		||||
	if len(c.Scopes) > 0 {
 | 
			
		||||
		v.Set("scope", strings.Join(c.Scopes, " "))
 | 
			
		||||
	}
 | 
			
		||||
	for _, opt := range opts {
 | 
			
		||||
		opt.setValue(v)
 | 
			
		||||
	}
 | 
			
		||||
	return retrieveDeviceAuth(ctx, c, v)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func retrieveDeviceAuth(ctx context.Context, c *Config, v url.Values) (*DeviceAuthResponse, error) {
 | 
			
		||||
	if c.Endpoint.DeviceAuthURL == "" {
 | 
			
		||||
		return nil, errors.New("endpoint missing DeviceAuthURL")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	req, err := http.NewRequest("POST", c.Endpoint.DeviceAuthURL, strings.NewReader(v.Encode()))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
 | 
			
		||||
	req.Header.Set("Accept", "application/json")
 | 
			
		||||
 | 
			
		||||
	t := time.Now()
 | 
			
		||||
	r, err := internal.ContextClient(ctx).Do(req)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	body, err := io.ReadAll(io.LimitReader(r.Body, 1<<20))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, fmt.Errorf("oauth2: cannot auth device: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
	if code := r.StatusCode; code < 200 || code > 299 {
 | 
			
		||||
		return nil, &RetrieveError{
 | 
			
		||||
			Response: r,
 | 
			
		||||
			Body:     body,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	da := &DeviceAuthResponse{}
 | 
			
		||||
	err = json.Unmarshal(body, &da)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, fmt.Errorf("unmarshal %s", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if !da.Expiry.IsZero() {
 | 
			
		||||
		// Make a small adjustment to account for time taken by the request
 | 
			
		||||
		da.Expiry = da.Expiry.Add(-time.Since(t))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return da, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DeviceAccessToken polls the server to exchange a device code for a token.
 | 
			
		||||
func (c *Config) DeviceAccessToken(ctx context.Context, da *DeviceAuthResponse, opts ...AuthCodeOption) (*Token, error) {
 | 
			
		||||
	if !da.Expiry.IsZero() {
 | 
			
		||||
		var cancel context.CancelFunc
 | 
			
		||||
		ctx, cancel = context.WithDeadline(ctx, da.Expiry)
 | 
			
		||||
		defer cancel()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// https://datatracker.ietf.org/doc/html/rfc8628#section-3.4
 | 
			
		||||
	v := url.Values{
 | 
			
		||||
		"client_id":   {c.ClientID},
 | 
			
		||||
		"grant_type":  {"urn:ietf:params:oauth:grant-type:device_code"},
 | 
			
		||||
		"device_code": {da.DeviceCode},
 | 
			
		||||
	}
 | 
			
		||||
	if len(c.Scopes) > 0 {
 | 
			
		||||
		v.Set("scope", strings.Join(c.Scopes, " "))
 | 
			
		||||
	}
 | 
			
		||||
	for _, opt := range opts {
 | 
			
		||||
		opt.setValue(v)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// "If no value is provided, clients MUST use 5 as the default."
 | 
			
		||||
	// https://datatracker.ietf.org/doc/html/rfc8628#section-3.2
 | 
			
		||||
	interval := da.Interval
 | 
			
		||||
	if interval == 0 {
 | 
			
		||||
		interval = 5
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ticker := time.NewTicker(time.Duration(interval) * time.Second)
 | 
			
		||||
	defer ticker.Stop()
 | 
			
		||||
	for {
 | 
			
		||||
		select {
 | 
			
		||||
		case <-ctx.Done():
 | 
			
		||||
			return nil, ctx.Err()
 | 
			
		||||
		case <-ticker.C:
 | 
			
		||||
			tok, err := retrieveToken(ctx, c, v)
 | 
			
		||||
			if err == nil {
 | 
			
		||||
				return tok, nil
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			e, ok := err.(*RetrieveError)
 | 
			
		||||
			if !ok {
 | 
			
		||||
				return nil, err
 | 
			
		||||
			}
 | 
			
		||||
			switch e.ErrorCode {
 | 
			
		||||
			case errSlowDown:
 | 
			
		||||
				// https://datatracker.ietf.org/doc/html/rfc8628#section-3.5
 | 
			
		||||
				// "the interval MUST be increased by 5 seconds for this and all subsequent requests"
 | 
			
		||||
				interval += 5
 | 
			
		||||
				ticker.Reset(time.Duration(interval) * time.Second)
 | 
			
		||||
			case errAuthorizationPending:
 | 
			
		||||
				// Do nothing.
 | 
			
		||||
			case errAccessDenied, errExpiredToken:
 | 
			
		||||
				fallthrough
 | 
			
		||||
			default:
 | 
			
		||||
				return tok, err
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										70
									
								
								vendor/golang.org/x/oauth2/internal/token.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										70
									
								
								vendor/golang.org/x/oauth2/internal/token.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -18,6 +18,7 @@ import (
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"sync/atomic"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -115,41 +116,60 @@ const (
 | 
			
		||||
	AuthStyleInHeader AuthStyle = 2
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// authStyleCache is the set of tokenURLs we've successfully used via
 | 
			
		||||
// LazyAuthStyleCache is a backwards compatibility compromise to let Configs
 | 
			
		||||
// have a lazily-initialized AuthStyleCache.
 | 
			
		||||
//
 | 
			
		||||
// The two users of this, oauth2.Config and oauth2/clientcredentials.Config,
 | 
			
		||||
// both would ideally just embed an unexported AuthStyleCache but because both
 | 
			
		||||
// were historically allowed to be copied by value we can't retroactively add an
 | 
			
		||||
// uncopyable Mutex to them.
 | 
			
		||||
//
 | 
			
		||||
// We could use an atomic.Pointer, but that was added recently enough (in Go
 | 
			
		||||
// 1.18) that we'd break Go 1.17 users where the tests as of 2023-08-03
 | 
			
		||||
// still pass. By using an atomic.Value, it supports both Go 1.17 and
 | 
			
		||||
// copying by value, even if that's not ideal.
 | 
			
		||||
type LazyAuthStyleCache struct {
 | 
			
		||||
	v atomic.Value // of *AuthStyleCache
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (lc *LazyAuthStyleCache) Get() *AuthStyleCache {
 | 
			
		||||
	if c, ok := lc.v.Load().(*AuthStyleCache); ok {
 | 
			
		||||
		return c
 | 
			
		||||
	}
 | 
			
		||||
	c := new(AuthStyleCache)
 | 
			
		||||
	if !lc.v.CompareAndSwap(nil, c) {
 | 
			
		||||
		c = lc.v.Load().(*AuthStyleCache)
 | 
			
		||||
	}
 | 
			
		||||
	return c
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AuthStyleCache is the set of tokenURLs we've successfully used via
 | 
			
		||||
// RetrieveToken and which style auth we ended up using.
 | 
			
		||||
// It's called a cache, but it doesn't (yet?) shrink. It's expected that
 | 
			
		||||
// the set of OAuth2 servers a program contacts over time is fixed and
 | 
			
		||||
// small.
 | 
			
		||||
var authStyleCache struct {
 | 
			
		||||
	sync.Mutex
 | 
			
		||||
	m map[string]AuthStyle // keyed by tokenURL
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ResetAuthCache resets the global authentication style cache used
 | 
			
		||||
// for AuthStyleUnknown token requests.
 | 
			
		||||
func ResetAuthCache() {
 | 
			
		||||
	authStyleCache.Lock()
 | 
			
		||||
	defer authStyleCache.Unlock()
 | 
			
		||||
	authStyleCache.m = nil
 | 
			
		||||
type AuthStyleCache struct {
 | 
			
		||||
	mu sync.Mutex
 | 
			
		||||
	m  map[string]AuthStyle // keyed by tokenURL
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// lookupAuthStyle reports which auth style we last used with tokenURL
 | 
			
		||||
// when calling RetrieveToken and whether we have ever done so.
 | 
			
		||||
func lookupAuthStyle(tokenURL string) (style AuthStyle, ok bool) {
 | 
			
		||||
	authStyleCache.Lock()
 | 
			
		||||
	defer authStyleCache.Unlock()
 | 
			
		||||
	style, ok = authStyleCache.m[tokenURL]
 | 
			
		||||
func (c *AuthStyleCache) lookupAuthStyle(tokenURL string) (style AuthStyle, ok bool) {
 | 
			
		||||
	c.mu.Lock()
 | 
			
		||||
	defer c.mu.Unlock()
 | 
			
		||||
	style, ok = c.m[tokenURL]
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// setAuthStyle adds an entry to authStyleCache, documented above.
 | 
			
		||||
func setAuthStyle(tokenURL string, v AuthStyle) {
 | 
			
		||||
	authStyleCache.Lock()
 | 
			
		||||
	defer authStyleCache.Unlock()
 | 
			
		||||
	if authStyleCache.m == nil {
 | 
			
		||||
		authStyleCache.m = make(map[string]AuthStyle)
 | 
			
		||||
func (c *AuthStyleCache) setAuthStyle(tokenURL string, v AuthStyle) {
 | 
			
		||||
	c.mu.Lock()
 | 
			
		||||
	defer c.mu.Unlock()
 | 
			
		||||
	if c.m == nil {
 | 
			
		||||
		c.m = make(map[string]AuthStyle)
 | 
			
		||||
	}
 | 
			
		||||
	authStyleCache.m[tokenURL] = v
 | 
			
		||||
	c.m[tokenURL] = v
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// newTokenRequest returns a new *http.Request to retrieve a new token
 | 
			
		||||
@@ -189,10 +209,10 @@ func cloneURLValues(v url.Values) url.Values {
 | 
			
		||||
	return v2
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func RetrieveToken(ctx context.Context, clientID, clientSecret, tokenURL string, v url.Values, authStyle AuthStyle) (*Token, error) {
 | 
			
		||||
func RetrieveToken(ctx context.Context, clientID, clientSecret, tokenURL string, v url.Values, authStyle AuthStyle, styleCache *AuthStyleCache) (*Token, error) {
 | 
			
		||||
	needsAuthStyleProbe := authStyle == 0
 | 
			
		||||
	if needsAuthStyleProbe {
 | 
			
		||||
		if style, ok := lookupAuthStyle(tokenURL); ok {
 | 
			
		||||
		if style, ok := styleCache.lookupAuthStyle(tokenURL); ok {
 | 
			
		||||
			authStyle = style
 | 
			
		||||
			needsAuthStyleProbe = false
 | 
			
		||||
		} else {
 | 
			
		||||
@@ -222,7 +242,7 @@ func RetrieveToken(ctx context.Context, clientID, clientSecret, tokenURL string,
 | 
			
		||||
		token, err = doTokenRoundTrip(ctx, req)
 | 
			
		||||
	}
 | 
			
		||||
	if needsAuthStyleProbe && err == nil {
 | 
			
		||||
		setAuthStyle(tokenURL, authStyle)
 | 
			
		||||
		styleCache.setAuthStyle(tokenURL, authStyle)
 | 
			
		||||
	}
 | 
			
		||||
	// Don't overwrite `RefreshToken` with an empty value
 | 
			
		||||
	// if this was a token refreshing request.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										33
									
								
								vendor/golang.org/x/oauth2/oauth2.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										33
									
								
								vendor/golang.org/x/oauth2/oauth2.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -58,6 +58,10 @@ type Config struct {
 | 
			
		||||
 | 
			
		||||
	// Scope specifies optional requested permissions.
 | 
			
		||||
	Scopes []string
 | 
			
		||||
 | 
			
		||||
	// authStyleCache caches which auth style to use when Endpoint.AuthStyle is
 | 
			
		||||
	// the zero value (AuthStyleAutoDetect).
 | 
			
		||||
	authStyleCache internal.LazyAuthStyleCache
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// A TokenSource is anything that can return a token.
 | 
			
		||||
@@ -71,8 +75,9 @@ type TokenSource interface {
 | 
			
		||||
// Endpoint represents an OAuth 2.0 provider's authorization and token
 | 
			
		||||
// endpoint URLs.
 | 
			
		||||
type Endpoint struct {
 | 
			
		||||
	AuthURL  string
 | 
			
		||||
	TokenURL string
 | 
			
		||||
	AuthURL       string
 | 
			
		||||
	DeviceAuthURL string
 | 
			
		||||
	TokenURL      string
 | 
			
		||||
 | 
			
		||||
	// AuthStyle optionally specifies how the endpoint wants the
 | 
			
		||||
	// client ID & client secret sent. The zero value means to
 | 
			
		||||
@@ -139,15 +144,19 @@ func SetAuthURLParam(key, value string) AuthCodeOption {
 | 
			
		||||
// AuthCodeURL returns a URL to OAuth 2.0 provider's consent page
 | 
			
		||||
// that asks for permissions for the required scopes explicitly.
 | 
			
		||||
//
 | 
			
		||||
// State is a token to protect the user from CSRF attacks. You must
 | 
			
		||||
// always provide a non-empty string and validate that it matches the
 | 
			
		||||
// state query parameter on your redirect callback.
 | 
			
		||||
// See http://tools.ietf.org/html/rfc6749#section-10.12 for more info.
 | 
			
		||||
// State is an opaque value used by the client to maintain state between the
 | 
			
		||||
// request and callback. The authorization server includes this value when
 | 
			
		||||
// redirecting the user agent back to the client.
 | 
			
		||||
//
 | 
			
		||||
// Opts may include AccessTypeOnline or AccessTypeOffline, as well
 | 
			
		||||
// as ApprovalForce.
 | 
			
		||||
// It can also be used to pass the PKCE challenge.
 | 
			
		||||
// See https://www.oauth.com/oauth2-servers/pkce/ for more info.
 | 
			
		||||
//
 | 
			
		||||
// To protect against CSRF attacks, opts should include a PKCE challenge
 | 
			
		||||
// (S256ChallengeOption). Not all servers support PKCE. An alternative is to
 | 
			
		||||
// generate a random state parameter and verify it after exchange.
 | 
			
		||||
// See https://datatracker.ietf.org/doc/html/rfc6749#section-10.12 (predating
 | 
			
		||||
// PKCE), https://www.oauth.com/oauth2-servers/pkce/ and
 | 
			
		||||
// https://www.ietf.org/archive/id/draft-ietf-oauth-v2-1-09.html#name-cross-site-request-forgery (describing both approaches)
 | 
			
		||||
func (c *Config) AuthCodeURL(state string, opts ...AuthCodeOption) string {
 | 
			
		||||
	var buf bytes.Buffer
 | 
			
		||||
	buf.WriteString(c.Endpoint.AuthURL)
 | 
			
		||||
@@ -162,7 +171,6 @@ func (c *Config) AuthCodeURL(state string, opts ...AuthCodeOption) string {
 | 
			
		||||
		v.Set("scope", strings.Join(c.Scopes, " "))
 | 
			
		||||
	}
 | 
			
		||||
	if state != "" {
 | 
			
		||||
		// TODO(light): Docs say never to omit state; don't allow empty.
 | 
			
		||||
		v.Set("state", state)
 | 
			
		||||
	}
 | 
			
		||||
	for _, opt := range opts {
 | 
			
		||||
@@ -207,10 +215,11 @@ func (c *Config) PasswordCredentialsToken(ctx context.Context, username, passwor
 | 
			
		||||
// The provided context optionally controls which HTTP client is used. See the HTTPClient variable.
 | 
			
		||||
//
 | 
			
		||||
// The code will be in the *http.Request.FormValue("code"). Before
 | 
			
		||||
// calling Exchange, be sure to validate FormValue("state").
 | 
			
		||||
// calling Exchange, be sure to validate FormValue("state") if you are
 | 
			
		||||
// using it to protect against CSRF attacks.
 | 
			
		||||
//
 | 
			
		||||
// Opts may include the PKCE verifier code if previously used in AuthCodeURL.
 | 
			
		||||
// See https://www.oauth.com/oauth2-servers/pkce/ for more info.
 | 
			
		||||
// If using PKCE to protect against CSRF attacks, opts should include a
 | 
			
		||||
// VerifierOption.
 | 
			
		||||
func (c *Config) Exchange(ctx context.Context, code string, opts ...AuthCodeOption) (*Token, error) {
 | 
			
		||||
	v := url.Values{
 | 
			
		||||
		"grant_type": {"authorization_code"},
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										68
									
								
								vendor/golang.org/x/oauth2/pkce.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								vendor/golang.org/x/oauth2/pkce.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,68 @@
 | 
			
		||||
// Copyright 2023 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 oauth2
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"crypto/rand"
 | 
			
		||||
	"crypto/sha256"
 | 
			
		||||
	"encoding/base64"
 | 
			
		||||
	"net/url"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	codeChallengeKey       = "code_challenge"
 | 
			
		||||
	codeChallengeMethodKey = "code_challenge_method"
 | 
			
		||||
	codeVerifierKey        = "code_verifier"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// GenerateVerifier generates a PKCE code verifier with 32 octets of randomness.
 | 
			
		||||
// This follows recommendations in RFC 7636.
 | 
			
		||||
//
 | 
			
		||||
// A fresh verifier should be generated for each authorization.
 | 
			
		||||
// S256ChallengeOption(verifier) should then be passed to Config.AuthCodeURL
 | 
			
		||||
// (or Config.DeviceAccess) and VerifierOption(verifier) to Config.Exchange
 | 
			
		||||
// (or Config.DeviceAccessToken).
 | 
			
		||||
func GenerateVerifier() string {
 | 
			
		||||
	// "RECOMMENDED that the output of a suitable random number generator be
 | 
			
		||||
	// used to create a 32-octet sequence.  The octet sequence is then
 | 
			
		||||
	// base64url-encoded to produce a 43-octet URL-safe string to use as the
 | 
			
		||||
	// code verifier."
 | 
			
		||||
	// https://datatracker.ietf.org/doc/html/rfc7636#section-4.1
 | 
			
		||||
	data := make([]byte, 32)
 | 
			
		||||
	if _, err := rand.Read(data); err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
	return base64.RawURLEncoding.EncodeToString(data)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// VerifierOption returns a PKCE code verifier AuthCodeOption. It should be
 | 
			
		||||
// passed to Config.Exchange or Config.DeviceAccessToken only.
 | 
			
		||||
func VerifierOption(verifier string) AuthCodeOption {
 | 
			
		||||
	return setParam{k: codeVerifierKey, v: verifier}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// S256ChallengeFromVerifier returns a PKCE code challenge derived from verifier with method S256.
 | 
			
		||||
//
 | 
			
		||||
// Prefer to use S256ChallengeOption where possible.
 | 
			
		||||
func S256ChallengeFromVerifier(verifier string) string {
 | 
			
		||||
	sha := sha256.Sum256([]byte(verifier))
 | 
			
		||||
	return base64.RawURLEncoding.EncodeToString(sha[:])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// S256ChallengeOption derives a PKCE code challenge derived from verifier with
 | 
			
		||||
// method S256. It should be passed to Config.AuthCodeURL or Config.DeviceAccess
 | 
			
		||||
// only.
 | 
			
		||||
func S256ChallengeOption(verifier string) AuthCodeOption {
 | 
			
		||||
	return challengeOption{
 | 
			
		||||
		challenge_method: "S256",
 | 
			
		||||
		challenge:        S256ChallengeFromVerifier(verifier),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type challengeOption struct{ challenge_method, challenge string }
 | 
			
		||||
 | 
			
		||||
func (p challengeOption) setValue(m url.Values) {
 | 
			
		||||
	m.Set(codeChallengeMethodKey, p.challenge_method)
 | 
			
		||||
	m.Set(codeChallengeKey, p.challenge)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										2
									
								
								vendor/golang.org/x/oauth2/token.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/golang.org/x/oauth2/token.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -164,7 +164,7 @@ func tokenFromInternal(t *internal.Token) *Token {
 | 
			
		||||
// This token is then mapped from *internal.Token into an *oauth2.Token which is returned along
 | 
			
		||||
// with an error..
 | 
			
		||||
func retrieveToken(ctx context.Context, c *Config, v url.Values) (*Token, error) {
 | 
			
		||||
	tk, err := internal.RetrieveToken(ctx, c.ClientID, c.ClientSecret, c.Endpoint.TokenURL, v, internal.AuthStyle(c.Endpoint.AuthStyle))
 | 
			
		||||
	tk, err := internal.RetrieveToken(ctx, c.ClientID, c.ClientSecret, c.Endpoint.TokenURL, v, internal.AuthStyle(c.Endpoint.AuthStyle), c.authStyleCache.Get())
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		if rErr, ok := err.(*internal.RetrieveError); ok {
 | 
			
		||||
			return nil, (*RetrieveError)(rErr)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user