[VOL-4291] Rw-core updates for gRPC migration

Change-Id: I8d5a554409115b29318089671ca4e1ab3fa98810
diff --git a/vendor/github.com/coreos/etcd/auth/jwt.go b/vendor/github.com/coreos/etcd/auth/jwt.go
new file mode 100644
index 0000000..99b2d6b
--- /dev/null
+++ b/vendor/github.com/coreos/etcd/auth/jwt.go
@@ -0,0 +1,139 @@
+// Copyright 2017 The etcd Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package auth
+
+import (
+	"context"
+	"crypto/rsa"
+	"io/ioutil"
+
+	jwt "github.com/dgrijalva/jwt-go"
+)
+
+type tokenJWT struct {
+	signMethod string
+	signKey    *rsa.PrivateKey
+	verifyKey  *rsa.PublicKey
+}
+
+func (t *tokenJWT) enable()                         {}
+func (t *tokenJWT) disable()                        {}
+func (t *tokenJWT) invalidateUser(string)           {}
+func (t *tokenJWT) genTokenPrefix() (string, error) { return "", nil }
+
+func (t *tokenJWT) info(ctx context.Context, token string, rev uint64) (*AuthInfo, bool) {
+	// rev isn't used in JWT, it is only used in simple token
+	var (
+		username string
+		revision uint64
+	)
+
+	parsed, err := jwt.Parse(token, func(token *jwt.Token) (interface{}, error) {
+		return t.verifyKey, nil
+	})
+
+	switch err.(type) {
+	case nil:
+		if !parsed.Valid {
+			plog.Warningf("invalid jwt token: %s", token)
+			return nil, false
+		}
+
+		claims := parsed.Claims.(jwt.MapClaims)
+
+		username = claims["username"].(string)
+		revision = uint64(claims["revision"].(float64))
+	default:
+		plog.Warningf("failed to parse jwt token: %s", err)
+		return nil, false
+	}
+
+	return &AuthInfo{Username: username, Revision: revision}, true
+}
+
+func (t *tokenJWT) assign(ctx context.Context, username string, revision uint64) (string, error) {
+	// Future work: let a jwt token include permission information would be useful for
+	// permission checking in proxy side.
+	tk := jwt.NewWithClaims(jwt.GetSigningMethod(t.signMethod),
+		jwt.MapClaims{
+			"username": username,
+			"revision": revision,
+		})
+
+	token, err := tk.SignedString(t.signKey)
+	if err != nil {
+		plog.Debugf("failed to sign jwt token: %s", err)
+		return "", err
+	}
+
+	plog.Debugf("jwt token: %s", token)
+
+	return token, err
+}
+
+func prepareOpts(opts map[string]string) (jwtSignMethod, jwtPubKeyPath, jwtPrivKeyPath string, err error) {
+	for k, v := range opts {
+		switch k {
+		case "sign-method":
+			jwtSignMethod = v
+		case "pub-key":
+			jwtPubKeyPath = v
+		case "priv-key":
+			jwtPrivKeyPath = v
+		default:
+			plog.Errorf("unknown token specific option: %s", k)
+			return "", "", "", ErrInvalidAuthOpts
+		}
+	}
+	if len(jwtSignMethod) == 0 {
+		return "", "", "", ErrInvalidAuthOpts
+	}
+	return jwtSignMethod, jwtPubKeyPath, jwtPrivKeyPath, nil
+}
+
+func newTokenProviderJWT(opts map[string]string) (*tokenJWT, error) {
+	jwtSignMethod, jwtPubKeyPath, jwtPrivKeyPath, err := prepareOpts(opts)
+	if err != nil {
+		return nil, ErrInvalidAuthOpts
+	}
+
+	t := &tokenJWT{}
+
+	t.signMethod = jwtSignMethod
+
+	verifyBytes, err := ioutil.ReadFile(jwtPubKeyPath)
+	if err != nil {
+		plog.Errorf("failed to read public key (%s) for jwt: %s", jwtPubKeyPath, err)
+		return nil, err
+	}
+	t.verifyKey, err = jwt.ParseRSAPublicKeyFromPEM(verifyBytes)
+	if err != nil {
+		plog.Errorf("failed to parse public key (%s): %s", jwtPubKeyPath, err)
+		return nil, err
+	}
+
+	signBytes, err := ioutil.ReadFile(jwtPrivKeyPath)
+	if err != nil {
+		plog.Errorf("failed to read private key (%s) for jwt: %s", jwtPrivKeyPath, err)
+		return nil, err
+	}
+	t.signKey, err = jwt.ParseRSAPrivateKeyFromPEM(signBytes)
+	if err != nil {
+		plog.Errorf("failed to parse private key (%s): %s", jwtPrivKeyPath, err)
+		return nil, err
+	}
+
+	return t, nil
+}