github.com/timstclair/heapster@v0.20.0-alpha1/Godeps/_workspace/src/golang.org/x/oauth2/token.go (about)

     1  // Copyright 2014 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package oauth2
     6  
     7  import (
     8  	"net/http"
     9  	"net/url"
    10  	"strconv"
    11  	"strings"
    12  	"time"
    13  
    14  	"golang.org/x/net/context"
    15  	"golang.org/x/oauth2/internal"
    16  )
    17  
    18  // expiryDelta determines how earlier a token should be considered
    19  // expired than its actual expiration time. It is used to avoid late
    20  // expirations due to client-server time mismatches.
    21  const expiryDelta = 10 * time.Second
    22  
    23  // Token represents the crendentials used to authorize
    24  // the requests to access protected resources on the OAuth 2.0
    25  // provider's backend.
    26  //
    27  // Most users of this package should not access fields of Token
    28  // directly. They're exported mostly for use by related packages
    29  // implementing derivative OAuth2 flows.
    30  type Token struct {
    31  	// AccessToken is the token that authorizes and authenticates
    32  	// the requests.
    33  	AccessToken string `json:"access_token"`
    34  
    35  	// TokenType is the type of token.
    36  	// The Type method returns either this or "Bearer", the default.
    37  	TokenType string `json:"token_type,omitempty"`
    38  
    39  	// RefreshToken is a token that's used by the application
    40  	// (as opposed to the user) to refresh the access token
    41  	// if it expires.
    42  	RefreshToken string `json:"refresh_token,omitempty"`
    43  
    44  	// Expiry is the optional expiration time of the access token.
    45  	//
    46  	// If zero, TokenSource implementations will reuse the same
    47  	// token forever and RefreshToken or equivalent
    48  	// mechanisms for that TokenSource will not be used.
    49  	Expiry time.Time `json:"expiry,omitempty"`
    50  
    51  	// raw optionally contains extra metadata from the server
    52  	// when updating a token.
    53  	raw interface{}
    54  }
    55  
    56  // Type returns t.TokenType if non-empty, else "Bearer".
    57  func (t *Token) Type() string {
    58  	if strings.EqualFold(t.TokenType, "bearer") {
    59  		return "Bearer"
    60  	}
    61  	if strings.EqualFold(t.TokenType, "mac") {
    62  		return "MAC"
    63  	}
    64  	if strings.EqualFold(t.TokenType, "basic") {
    65  		return "Basic"
    66  	}
    67  	if t.TokenType != "" {
    68  		return t.TokenType
    69  	}
    70  	return "Bearer"
    71  }
    72  
    73  // SetAuthHeader sets the Authorization header to r using the access
    74  // token in t.
    75  //
    76  // This method is unnecessary when using Transport or an HTTP Client
    77  // returned by this package.
    78  func (t *Token) SetAuthHeader(r *http.Request) {
    79  	r.Header.Set("Authorization", t.Type()+" "+t.AccessToken)
    80  }
    81  
    82  // WithExtra returns a new Token that's a clone of t, but using the
    83  // provided raw extra map. This is only intended for use by packages
    84  // implementing derivative OAuth2 flows.
    85  func (t *Token) WithExtra(extra interface{}) *Token {
    86  	t2 := new(Token)
    87  	*t2 = *t
    88  	t2.raw = extra
    89  	return t2
    90  }
    91  
    92  // Extra returns an extra field.
    93  // Extra fields are key-value pairs returned by the server as a
    94  // part of the token retrieval response.
    95  func (t *Token) Extra(key string) interface{} {
    96  	if raw, ok := t.raw.(map[string]interface{}); ok {
    97  		return raw[key]
    98  	}
    99  
   100  	vals, ok := t.raw.(url.Values)
   101  	if !ok {
   102  		return nil
   103  	}
   104  
   105  	v := vals.Get(key)
   106  	switch s := strings.TrimSpace(v); strings.Count(s, ".") {
   107  	case 0: // Contains no "."; try to parse as int
   108  		if i, err := strconv.ParseInt(s, 10, 64); err == nil {
   109  			return i
   110  		}
   111  	case 1: // Contains a single "."; try to parse as float
   112  		if f, err := strconv.ParseFloat(s, 64); err == nil {
   113  			return f
   114  		}
   115  	}
   116  
   117  	return v
   118  }
   119  
   120  // expired reports whether the token is expired.
   121  // t must be non-nil.
   122  func (t *Token) expired() bool {
   123  	if t.Expiry.IsZero() {
   124  		return false
   125  	}
   126  	return t.Expiry.Add(-expiryDelta).Before(time.Now())
   127  }
   128  
   129  // Valid reports whether t is non-nil, has an AccessToken, and is not expired.
   130  func (t *Token) Valid() bool {
   131  	return t != nil && t.AccessToken != "" && !t.expired()
   132  }
   133  
   134  // tokenFromInternal maps an *internal.Token struct into
   135  // a *Token struct.
   136  func tokenFromInternal(t *internal.Token) *Token {
   137  	if t == nil {
   138  		return nil
   139  	}
   140  	return &Token{
   141  		AccessToken:  t.AccessToken,
   142  		TokenType:    t.TokenType,
   143  		RefreshToken: t.RefreshToken,
   144  		Expiry:       t.Expiry,
   145  		raw:          t.Raw,
   146  	}
   147  }
   148  
   149  // retrieveToken takes a *Config and uses that to retrieve an *internal.Token.
   150  // This token is then mapped from *internal.Token into an *oauth2.Token which is returned along
   151  // with an error..
   152  func retrieveToken(ctx context.Context, c *Config, v url.Values) (*Token, error) {
   153  	tk, err := internal.RetrieveToken(ctx, c.ClientID, c.ClientSecret, c.Endpoint.TokenURL, v)
   154  	if err != nil {
   155  		return nil, err
   156  	}
   157  	return tokenFromInternal(tk), nil
   158  }