Browse Source

Merge pull request #7999 from hexfusion/grpc-gateway-auth

auth: support "authorization" token for grpc-gateway
Xiang Li 8 years ago
parent
commit
44a6c2121b
5 changed files with 429 additions and 330 deletions
  1. 322 327
      Documentation/dev-guide/apispec/swagger/rpc.swagger.json
  2. 7 2
      auth/store.go
  3. 5 0
      e2e/v2_curl_test.go
  4. 84 0
      e2e/v3_curl_test.go
  5. 11 1
      scripts/genproto.sh

File diff suppressed because it is too large
+ 322 - 327
Documentation/dev-guide/apispec/swagger/rpc.swagger.json


+ 7 - 2
auth/store.go

@@ -1000,8 +1000,12 @@ func (as *authStore) AuthInfoFromCtx(ctx context.Context) (*AuthInfo, error) {
 		return nil, nil
 	}
 
-	ts, tok := md["token"]
-	if !tok {
+	//TODO(mitake|hexfusion) review unifying key names
+	ts, ok := md["token"]
+	if !ok {
+		ts, ok = md["authorization"]
+	}
+	if !ok {
 		return nil, nil
 	}
 
@@ -1011,6 +1015,7 @@ func (as *authStore) AuthInfoFromCtx(ctx context.Context) (*AuthInfo, error) {
 		plog.Warningf("invalid auth token: %s", token)
 		return nil, ErrInvalidAuthToken
 	}
+
 	return authInfo, nil
 }
 

+ 5 - 0
e2e/v2_curl_test.go

@@ -127,6 +127,7 @@ type cURLReq struct {
 
 	value    string
 	expected string
+	header   string
 }
 
 // cURLPrefixArgs builds the beginning of a curl command for a given key
@@ -156,6 +157,10 @@ func cURLPrefixArgs(clus *etcdProcessCluster, method string, req cURLReq) []stri
 		cmdArgs = append(cmdArgs, "-m", fmt.Sprintf("%d", req.timeout))
 	}
 
+	if req.header != "" {
+		cmdArgs = append(cmdArgs, "-H", req.header)
+	}
+
 	switch method {
 	case "POST", "PUT":
 		dt := req.value

+ 84 - 0
e2e/v3_curl_test.go

@@ -162,3 +162,87 @@ func TestV3CurlTxn(t *testing.T) {
 		t.Fatalf("failed put with curl (%v)", err)
 	}
 }
+
+func TestV3CurlAuth(t *testing.T) {
+	defer testutil.AfterTest(t)
+	epc, err := newEtcdProcessCluster(&configNoTLS)
+	if err != nil {
+		t.Fatalf("could not start etcd process cluster (%v)", err)
+	}
+	defer func() {
+		if cerr := epc.Close(); err != nil {
+			t.Fatalf("error closing etcd processes (%v)", cerr)
+		}
+	}()
+
+	// create root user
+	userreq, err := json.Marshal(&pb.AuthUserAddRequest{Name: string("root"), Password: string("toor")})
+	testutil.AssertNil(t, err)
+
+	if err = cURLPost(epc, cURLReq{endpoint: "/v3alpha/auth/user/add", value: string(userreq), expected: "revision"}); err != nil {
+		t.Fatalf("failed add user with curl (%v)", err)
+	}
+
+	// create root role
+	rolereq, err := json.Marshal(&pb.AuthRoleAddRequest{Name: string("root")})
+	testutil.AssertNil(t, err)
+
+	if err = cURLPost(epc, cURLReq{endpoint: "/v3alpha/auth/role/add", value: string(rolereq), expected: "revision"}); err != nil {
+		t.Fatalf("failed create role with curl (%v)", err)
+	}
+
+	// grant root role
+	grantrolereq, err := json.Marshal(&pb.AuthUserGrantRoleRequest{User: string("root"), Role: string("root")})
+	testutil.AssertNil(t, err)
+
+	if err = cURLPost(epc, cURLReq{endpoint: "/v3alpha/auth/user/grant", value: string(grantrolereq), expected: "revision"}); err != nil {
+		t.Fatalf("failed grant role with curl (%v)", err)
+	}
+
+	// enable auth
+	if err = cURLPost(epc, cURLReq{endpoint: "/v3alpha/auth/enable", value: string("{}"), expected: "revision"}); err != nil {
+		t.Fatalf("failed enable auth with curl (%v)", err)
+	}
+
+	// put "bar" into "foo"
+	putreq, err := json.Marshal(&pb.PutRequest{Key: []byte("foo"), Value: []byte("bar")})
+	testutil.AssertNil(t, err)
+
+	// fail put no auth
+	if err = cURLPost(epc, cURLReq{endpoint: "/v3alpha/kv/put", value: string(putreq), expected: "error"}); err != nil {
+		t.Fatalf("failed no auth put with curl (%v)", err)
+	}
+
+	// auth request
+	authreq, err := json.Marshal(&pb.AuthenticateRequest{Name: string("root"), Password: string("toor")})
+	testutil.AssertNil(t, err)
+
+	var (
+		authHeader string
+		cmdArgs    []string
+		lineFunc   = func(txt string) bool { return true }
+	)
+
+	cmdArgs = cURLPrefixArgs(epc, "POST", cURLReq{endpoint: "/v3alpha/auth/authenticate", value: string(authreq)})
+	proc, err := spawnCmd(cmdArgs)
+	testutil.AssertNil(t, err)
+
+	cURLRes, err := proc.ExpectFunc(lineFunc)
+	testutil.AssertNil(t, err)
+
+	authRes := make(map[string]interface{})
+	testutil.AssertNil(t, json.Unmarshal([]byte(cURLRes), &authRes))
+
+	token, ok := authRes["token"].(string)
+	if !ok {
+		t.Fatalf("failed invalid token in authenticate response with curl")
+	}
+
+	authHeader = "Authorization : " + token
+
+	// put with auth
+	if err = cURLPost(epc, cURLReq{endpoint: "/v3alpha/kv/put", value: string(putreq), header: authHeader, expected: "revision"}); err != nil {
+		t.Fatalf("failed auth put with curl (%v)", err)
+	}
+
+}

+ 11 - 1
scripts/genproto.sh

@@ -18,9 +18,10 @@ fi
 # directories containing protos to be built
 DIRS="./wal/walpb ./etcdserver/etcdserverpb ./snap/snappb ./raft/raftpb ./mvcc/mvccpb ./lease/leasepb ./auth/authpb ./etcdserver/api/v3lock/v3lockpb ./etcdserver/api/v3election/v3electionpb"
 
-# exact version of protoc-gen-gogo to build
+# exact version of packages to build
 GOGO_PROTO_SHA="100ba4e885062801d56799d78530b73b178a78f3"
 GRPC_GATEWAY_SHA="18d159699f2e83fc5bb9ef2f79465ca3f3122676"
+SCHWAG_SHA="b7d0fc9aadaaae3d61aaadfc12e4a2f945514912"
 
 # set up self-contained GOPATH for building
 export GOPATH=${PWD}/gopath.proto
@@ -30,6 +31,7 @@ export PATH="${GOBIN}:${PATH}"
 COREOS_ROOT="${GOPATH}/src/github.com/coreos"
 ETCD_ROOT="${COREOS_ROOT}/etcd"
 GOGOPROTO_ROOT="${GOPATH}/src/github.com/gogo/protobuf"
+SCHWAG_ROOT="${GOPATH}/src/github.com/hexfusion/schwag"
 GOGOPROTO_PATH="${GOGOPROTO_ROOT}:${GOGOPROTO_ROOT}/protobuf"
 GRPC_GATEWAY_ROOT="${GOPATH}/src/github.com/grpc-ecosystem/grpc-gateway"
 
@@ -101,6 +103,14 @@ for pb in etcdserverpb/rpc api/v3lock/v3lockpb/v3lock api/v3election/v3electionp
 done
 rm -rf Documentation/dev-guide/apispec/swagger/etcdserver/
 
+# append security to swagger spec
+go get -u "github.com/hexfusion/schwag"
+pushd "${SCHWAG_ROOT}"
+	git reset --hard "${SCHWAG_SHA}"
+	go install .
+popd
+schwag -input=Documentation/dev-guide/apispec/swagger/rpc.swagger.json
+
 # install protodoc
 # go get -v -u github.com/coreos/protodoc
 #

Some files were not shown because too many files changed in this diff