VOL-1497 : Add more control to kv/memory access

- Added kv locking mechanism (etcd only)
- (watch) control path access whenever possible
- (watch) use a transaction for updates and merge with memory
- cleaned up vendoring
- misc changes to fix exceptions found along the way

Amendments:

- Copyright header got removed in auto-generated file
- Changed default locking to false for KV list operation
- Updated backend api to allow the passing of locking parameter

Change-Id: Ie1a55d3ca8b9d92ae71a85ce42bb22fcf1419e2c
diff --git a/vendor/golang.org/x/oauth2/README.md b/vendor/golang.org/x/oauth2/README.md
index 68f436e..0f443e6 100644
--- a/vendor/golang.org/x/oauth2/README.md
+++ b/vendor/golang.org/x/oauth2/README.md
@@ -19,57 +19,6 @@
 * [godoc.org/golang.org/x/oauth2](http://godoc.org/golang.org/x/oauth2)
 * [godoc.org/golang.org/x/oauth2/google](http://godoc.org/golang.org/x/oauth2/google)
 
-
-## App Engine
-
-In change 96e89be (March 2015), we removed the `oauth2.Context2` type in favor
-of the [`context.Context`](https://golang.org/x/net/context#Context) type from
-the `golang.org/x/net/context` package. Later replaced by the standard `context` package
-of the [`context.Context`](https://golang.org/pkg/context#Context) type.
-
-
-This means it's no longer possible to use the "Classic App Engine"
-`appengine.Context` type with the `oauth2` package. (You're using
-Classic App Engine if you import the package `"appengine"`.)
-
-To work around this, you may use the new `"google.golang.org/appengine"`
-package. This package has almost the same API as the `"appengine"` package,
-but it can be fetched with `go get` and used on "Managed VMs" and well as
-Classic App Engine.
-
-See the [new `appengine` package's readme](https://github.com/golang/appengine#updating-a-go-app-engine-app)
-for information on updating your app.
-
-If you don't want to update your entire app to use the new App Engine packages,
-you may use both sets of packages in parallel, using only the new packages
-with the `oauth2` package.
-
-```go
-import (
-	"context"
-	"golang.org/x/oauth2"
-	"golang.org/x/oauth2/google"
-	newappengine "google.golang.org/appengine"
-	newurlfetch "google.golang.org/appengine/urlfetch"
-
-	"appengine"
-)
-
-func handler(w http.ResponseWriter, r *http.Request) {
-	var c appengine.Context = appengine.NewContext(r)
-	c.Infof("Logging a message with the old package")
-
-	var ctx context.Context = newappengine.NewContext(r)
-	client := &http.Client{
-		Transport: &oauth2.Transport{
-			Source: google.AppEngineTokenSource(ctx, "scope"),
-			Base:   &newurlfetch.Transport{Context: ctx},
-		},
-	}
-	client.Get("...")
-}
-```
-
 ## Policy for new packages
 
 We no longer accept new provider-specific packages in this repo. For
diff --git a/vendor/golang.org/x/oauth2/internal/token.go b/vendor/golang.org/x/oauth2/internal/token.go
index a831b77..955d5a0 100644
--- a/vendor/golang.org/x/oauth2/internal/token.go
+++ b/vendor/golang.org/x/oauth2/internal/token.go
@@ -16,6 +16,7 @@
 	"net/url"
 	"strconv"
 	"strings"
+	"sync"
 	"time"
 
 	"golang.org/x/net/context/ctxhttp"
@@ -77,6 +78,9 @@
 type expirationTime int32
 
 func (e *expirationTime) UnmarshalJSON(b []byte) error {
+	if len(b) == 0 || string(b) == "null" {
+		return nil
+	}
 	var n json.Number
 	err := json.Unmarshal(b, &n)
 	if err != nil {
@@ -90,102 +94,71 @@
 	return nil
 }
 
-var brokenAuthHeaderProviders = []string{
-	"https://accounts.google.com/",
-	"https://api.codeswholesale.com/oauth/token",
-	"https://api.dropbox.com/",
-	"https://api.dropboxapi.com/",
-	"https://api.instagram.com/",
-	"https://api.netatmo.net/",
-	"https://api.odnoklassniki.ru/",
-	"https://api.pushbullet.com/",
-	"https://api.soundcloud.com/",
-	"https://api.twitch.tv/",
-	"https://id.twitch.tv/",
-	"https://app.box.com/",
-	"https://api.box.com/",
-	"https://connect.stripe.com/",
-	"https://login.mailchimp.com/",
-	"https://login.microsoftonline.com/",
-	"https://login.salesforce.com/",
-	"https://login.windows.net",
-	"https://login.live.com/",
-	"https://login.live-int.com/",
-	"https://oauth.sandbox.trainingpeaks.com/",
-	"https://oauth.trainingpeaks.com/",
-	"https://oauth.vk.com/",
-	"https://openapi.baidu.com/",
-	"https://slack.com/",
-	"https://test-sandbox.auth.corp.google.com",
-	"https://test.salesforce.com/",
-	"https://user.gini.net/",
-	"https://www.douban.com/",
-	"https://www.googleapis.com/",
-	"https://www.linkedin.com/",
-	"https://www.strava.com/oauth/",
-	"https://www.wunderlist.com/oauth/",
-	"https://api.patreon.com/",
-	"https://sandbox.codeswholesale.com/oauth/token",
-	"https://api.sipgate.com/v1/authorization/oauth",
-	"https://api.medium.com/v1/tokens",
-	"https://log.finalsurge.com/oauth/token",
-	"https://multisport.todaysplan.com.au/rest/oauth/access_token",
-	"https://whats.todaysplan.com.au/rest/oauth/access_token",
-	"https://stackoverflow.com/oauth/access_token",
-	"https://account.health.nokia.com",
-	"https://accounts.zoho.com",
-	"https://gitter.im/login/oauth/token",
-	"https://openid-connect.onelogin.com/oidc",
-	"https://api.dailymotion.com/oauth/token",
+// RegisterBrokenAuthHeaderProvider previously did something. It is now a no-op.
+//
+// Deprecated: this function no longer does anything. Caller code that
+// wants to avoid potential extra HTTP requests made during
+// auto-probing of the provider's auth style should set
+// Endpoint.AuthStyle.
+func RegisterBrokenAuthHeaderProvider(tokenURL string) {}
+
+// AuthStyle is a copy of the golang.org/x/oauth2 package's AuthStyle type.
+type AuthStyle int
+
+const (
+	AuthStyleUnknown  AuthStyle = 0
+	AuthStyleInParams AuthStyle = 1
+	AuthStyleInHeader AuthStyle = 2
+)
+
+// 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
 }
 
-// brokenAuthHeaderDomains lists broken providers that issue dynamic endpoints.
-var brokenAuthHeaderDomains = []string{
-	".auth0.com",
-	".force.com",
-	".myshopify.com",
-	".okta.com",
-	".oktapreview.com",
+// ResetAuthCache resets the global authentication style cache used
+// for AuthStyleUnknown token requests.
+func ResetAuthCache() {
+	authStyleCache.Lock()
+	defer authStyleCache.Unlock()
+	authStyleCache.m = nil
 }
 
-func RegisterBrokenAuthHeaderProvider(tokenURL string) {
-	brokenAuthHeaderProviders = append(brokenAuthHeaderProviders, 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]
+	return
 }
 
-// providerAuthHeaderWorks reports whether the OAuth2 server identified by the tokenURL
-// implements the OAuth2 spec correctly
-// See https://code.google.com/p/goauth2/issues/detail?id=31 for background.
-// In summary:
-// - Reddit only accepts client secret in the Authorization header
-// - Dropbox accepts either it in URL param or Auth header, but not both.
-// - Google only accepts URL param (not spec compliant?), not Auth header
-// - Stripe only accepts client secret in Auth header with Bearer method, not Basic
-func providerAuthHeaderWorks(tokenURL string) bool {
-	for _, s := range brokenAuthHeaderProviders {
-		if strings.HasPrefix(tokenURL, s) {
-			// Some sites fail to implement the OAuth2 spec fully.
-			return false
-		}
+// 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)
 	}
-
-	if u, err := url.Parse(tokenURL); err == nil {
-		for _, s := range brokenAuthHeaderDomains {
-			if strings.HasSuffix(u.Host, s) {
-				return false
-			}
-		}
-	}
-
-	// Assume the provider implements the spec properly
-	// otherwise. We can add more exceptions as they're
-	// discovered. We will _not_ be adding configurable hooks
-	// to this package to let users select server bugs.
-	return true
+	authStyleCache.m[tokenURL] = v
 }
 
-func RetrieveToken(ctx context.Context, clientID, clientSecret, tokenURL string, v url.Values) (*Token, error) {
-	bustedAuth := !providerAuthHeaderWorks(tokenURL)
-	if bustedAuth {
+// newTokenRequest returns a new *http.Request to retrieve a new token
+// from tokenURL using the provided clientID, clientSecret, and POST
+// body parameters.
+//
+// inParams is whether the clientID & clientSecret should be encoded
+// as the POST body. An 'inParams' value of true means to send it in
+// the POST body (along with any values in v); false means to send it
+// in the Authorization header.
+func newTokenRequest(tokenURL, clientID, clientSecret string, v url.Values, authStyle AuthStyle) (*http.Request, error) {
+	if authStyle == AuthStyleInParams {
+		v = cloneURLValues(v)
 		if clientID != "" {
 			v.Set("client_id", clientID)
 		}
@@ -198,15 +171,70 @@
 		return nil, err
 	}
 	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
-	if !bustedAuth {
+	if authStyle == AuthStyleInHeader {
 		req.SetBasicAuth(url.QueryEscape(clientID), url.QueryEscape(clientSecret))
 	}
+	return req, nil
+}
+
+func cloneURLValues(v url.Values) url.Values {
+	v2 := make(url.Values, len(v))
+	for k, vv := range v {
+		v2[k] = append([]string(nil), vv...)
+	}
+	return v2
+}
+
+func RetrieveToken(ctx context.Context, clientID, clientSecret, tokenURL string, v url.Values, authStyle AuthStyle) (*Token, error) {
+	needsAuthStyleProbe := authStyle == 0
+	if needsAuthStyleProbe {
+		if style, ok := lookupAuthStyle(tokenURL); ok {
+			authStyle = style
+			needsAuthStyleProbe = false
+		} else {
+			authStyle = AuthStyleInHeader // the first way we'll try
+		}
+	}
+	req, err := newTokenRequest(tokenURL, clientID, clientSecret, v, authStyle)
+	if err != nil {
+		return nil, err
+	}
+	token, err := doTokenRoundTrip(ctx, req)
+	if err != nil && needsAuthStyleProbe {
+		// If we get an error, assume the server wants the
+		// clientID & clientSecret in a different form.
+		// See https://code.google.com/p/goauth2/issues/detail?id=31 for background.
+		// In summary:
+		// - Reddit only accepts client secret in the Authorization header
+		// - Dropbox accepts either it in URL param or Auth header, but not both.
+		// - Google only accepts URL param (not spec compliant?), not Auth header
+		// - Stripe only accepts client secret in Auth header with Bearer method, not Basic
+		//
+		// We used to maintain a big table in this code of all the sites and which way
+		// they went, but maintaining it didn't scale & got annoying.
+		// So just try both ways.
+		authStyle = AuthStyleInParams // the second way we'll try
+		req, _ = newTokenRequest(tokenURL, clientID, clientSecret, v, authStyle)
+		token, err = doTokenRoundTrip(ctx, req)
+	}
+	if needsAuthStyleProbe && err == nil {
+		setAuthStyle(tokenURL, authStyle)
+	}
+	// Don't overwrite `RefreshToken` with an empty value
+	// if this was a token refreshing request.
+	if token != nil && token.RefreshToken == "" {
+		token.RefreshToken = v.Get("refresh_token")
+	}
+	return token, err
+}
+
+func doTokenRoundTrip(ctx context.Context, req *http.Request) (*Token, error) {
 	r, err := ctxhttp.Do(ctx, ContextClient(ctx), req)
 	if err != nil {
 		return nil, err
 	}
-	defer r.Body.Close()
 	body, err := ioutil.ReadAll(io.LimitReader(r.Body, 1<<20))
+	r.Body.Close()
 	if err != nil {
 		return nil, fmt.Errorf("oauth2: cannot fetch token: %v", err)
 	}
@@ -232,7 +260,7 @@
 			Raw:          vals,
 		}
 		e := vals.Get("expires_in")
-		if e == "" {
+		if e == "" || e == "null" {
 			// TODO(jbd): Facebook's OAuth2 implementation is broken and
 			// returns expires_in field in expires. Remove the fallback to expires,
 			// when Facebook fixes their implementation.
@@ -256,13 +284,8 @@
 		}
 		json.Unmarshal(body, &token.Raw) // no error checks for optional fields
 	}
-	// Don't overwrite `RefreshToken` with an empty value
-	// if this was a token refreshing request.
-	if token.RefreshToken == "" {
-		token.RefreshToken = v.Get("refresh_token")
-	}
 	if token.AccessToken == "" {
-		return token, errors.New("oauth2: server response missing access_token")
+		return nil, errors.New("oauth2: server response missing access_token")
 	}
 	return token, nil
 }
diff --git a/vendor/golang.org/x/oauth2/oauth2.go b/vendor/golang.org/x/oauth2/oauth2.go
index 3de6331..428283f 100644
--- a/vendor/golang.org/x/oauth2/oauth2.go
+++ b/vendor/golang.org/x/oauth2/oauth2.go
@@ -26,17 +26,13 @@
 // Deprecated: Use context.Background() or context.TODO() instead.
 var NoContext = context.TODO()
 
-// RegisterBrokenAuthHeaderProvider registers an OAuth2 server
-// identified by the tokenURL prefix as an OAuth2 implementation
-// which doesn't support the HTTP Basic authentication
-// scheme to authenticate with the authorization server.
-// Once a server is registered, credentials (client_id and client_secret)
-// will be passed as parameters in the request body rather than being present
-// in the Authorization header.
-// See https://code.google.com/p/goauth2/issues/detail?id=31 for background.
-func RegisterBrokenAuthHeaderProvider(tokenURL string) {
-	internal.RegisterBrokenAuthHeaderProvider(tokenURL)
-}
+// RegisterBrokenAuthHeaderProvider previously did something. It is now a no-op.
+//
+// Deprecated: this function no longer does anything. Caller code that
+// wants to avoid potential extra HTTP requests made during
+// auto-probing of the provider's auth style should set
+// Endpoint.AuthStyle.
+func RegisterBrokenAuthHeaderProvider(tokenURL string) {}
 
 // Config describes a typical 3-legged OAuth2 flow, with both the
 // client application information and the server's endpoint URLs.
@@ -71,13 +67,38 @@
 	Token() (*Token, error)
 }
 
-// Endpoint contains the OAuth 2.0 provider's authorization and token
+// Endpoint represents an OAuth 2.0 provider's authorization and token
 // endpoint URLs.
 type Endpoint struct {
 	AuthURL  string
 	TokenURL string
+
+	// AuthStyle optionally specifies how the endpoint wants the
+	// client ID & client secret sent. The zero value means to
+	// auto-detect.
+	AuthStyle AuthStyle
 }
 
+// AuthStyle represents how requests for tokens are authenticated
+// to the server.
+type AuthStyle int
+
+const (
+	// AuthStyleAutoDetect means to auto-detect which authentication
+	// style the provider wants by trying both ways and caching
+	// the successful way for the future.
+	AuthStyleAutoDetect AuthStyle = 0
+
+	// AuthStyleInParams sends the "client_id" and "client_secret"
+	// in the POST body as application/x-www-form-urlencoded parameters.
+	AuthStyleInParams AuthStyle = 1
+
+	// AuthStyleInHeader sends the client_id and client_password
+	// using HTTP Basic Authorization. This is an optional style
+	// described in the OAuth2 RFC 6749 section 2.3.1.
+	AuthStyleInHeader AuthStyle = 2
+)
+
 var (
 	// AccessTypeOnline and AccessTypeOffline are options passed
 	// to the Options.AuthCodeURL method. They modify the
@@ -124,7 +145,7 @@
 //
 // Opts may include AccessTypeOnline or AccessTypeOffline, as well
 // as ApprovalForce.
-// It can also be used to pass the PKCE challange.
+// It can also be used to pass the PKCE challenge.
 // See https://www.oauth.com/oauth2-servers/pkce/ for more info.
 func (c *Config) AuthCodeURL(state string, opts ...AuthCodeOption) string {
 	var buf bytes.Buffer
diff --git a/vendor/golang.org/x/oauth2/token.go b/vendor/golang.org/x/oauth2/token.go
index ee4be54..8227203 100644
--- a/vendor/golang.org/x/oauth2/token.go
+++ b/vendor/golang.org/x/oauth2/token.go
@@ -154,7 +154,7 @@
 // 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)
+	tk, err := internal.RetrieveToken(ctx, c.ClientID, c.ClientSecret, c.Endpoint.TokenURL, v, internal.AuthStyle(c.Endpoint.AuthStyle))
 	if err != nil {
 		if rErr, ok := err.(*internal.RetrieveError); ok {
 			return nil, (*RetrieveError)(rErr)