mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
*: don't use string literals directly in grpc metadata
Current etcd code uses the string literals ("token", "authorization") as field names of grpc and swappger metadata for passing token. It is difficult to maintain so this commit introduces new constants for the purpose.
This commit is contained in:
parent
718d0d045c
commit
b1dd19a7aa
@ -25,6 +25,7 @@ import (
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/coreos/etcd/auth/authpb"
|
||||
"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
|
||||
pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
|
||||
"github.com/coreos/etcd/mvcc/backend"
|
||||
|
||||
@ -999,9 +1000,9 @@ func (as *authStore) AuthInfoFromCtx(ctx context.Context) (*AuthInfo, error) {
|
||||
}
|
||||
|
||||
//TODO(mitake|hexfusion) review unifying key names
|
||||
ts, ok := md["token"]
|
||||
ts, ok := md[rpctypes.TokenFieldNameGRPC]
|
||||
if !ok {
|
||||
ts, ok = md["authorization"]
|
||||
ts, ok = md[rpctypes.TokenFieldNameSwagger]
|
||||
}
|
||||
if !ok {
|
||||
return nil, nil
|
||||
@ -1092,7 +1093,7 @@ func (as *authStore) WithRoot(ctx context.Context) context.Context {
|
||||
}
|
||||
|
||||
mdMap := map[string]string{
|
||||
"token": token,
|
||||
rpctypes.TokenFieldNameGRPC: token,
|
||||
}
|
||||
tokenMD := metadata.New(mdMap)
|
||||
|
||||
|
@ -25,6 +25,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/coreos/etcd/auth/authpb"
|
||||
"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
|
||||
pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
|
||||
"github.com/coreos/etcd/mvcc/backend"
|
||||
|
||||
@ -467,19 +468,19 @@ func TestAuthInfoFromCtx(t *testing.T) {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
ctx = metadata.NewIncomingContext(context.Background(), metadata.New(map[string]string{"token": "Invalid Token"}))
|
||||
ctx = metadata.NewIncomingContext(context.Background(), metadata.New(map[string]string{rpctypes.TokenFieldNameGRPC: "Invalid Token"}))
|
||||
_, err = as.AuthInfoFromCtx(ctx)
|
||||
if err != ErrInvalidAuthToken {
|
||||
t.Errorf("expected %v, got %v", ErrInvalidAuthToken, err)
|
||||
}
|
||||
|
||||
ctx = metadata.NewIncomingContext(context.Background(), metadata.New(map[string]string{"token": "Invalid.Token"}))
|
||||
ctx = metadata.NewIncomingContext(context.Background(), metadata.New(map[string]string{rpctypes.TokenFieldNameGRPC: "Invalid.Token"}))
|
||||
_, err = as.AuthInfoFromCtx(ctx)
|
||||
if err != ErrInvalidAuthToken {
|
||||
t.Errorf("expected %v, got %v", ErrInvalidAuthToken, err)
|
||||
}
|
||||
|
||||
ctx = metadata.NewIncomingContext(context.Background(), metadata.New(map[string]string{"token": resp.Token}))
|
||||
ctx = metadata.NewIncomingContext(context.Background(), metadata.New(map[string]string{rpctypes.TokenFieldNameGRPC: resp.Token}))
|
||||
ai, err = as.AuthInfoFromCtx(ctx)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
@ -523,7 +524,7 @@ func TestAuthInfoFromCtxRace(t *testing.T) {
|
||||
donec := make(chan struct{})
|
||||
go func() {
|
||||
defer close(donec)
|
||||
ctx := metadata.NewIncomingContext(context.Background(), metadata.New(map[string]string{"token": "test"}))
|
||||
ctx := metadata.NewIncomingContext(context.Background(), metadata.New(map[string]string{rpctypes.TokenFieldNameGRPC: "test"}))
|
||||
as.AuthInfoFromCtx(ctx)
|
||||
}()
|
||||
as.UserAdd(&pb.AuthUserAddRequest{Name: "test"})
|
||||
|
@ -100,70 +100,70 @@ type Auth interface {
|
||||
RoleDelete(ctx context.Context, role string) (*AuthRoleDeleteResponse, error)
|
||||
}
|
||||
|
||||
type auth struct {
|
||||
type authClient struct {
|
||||
remote pb.AuthClient
|
||||
callOpts []grpc.CallOption
|
||||
}
|
||||
|
||||
func NewAuth(c *Client) Auth {
|
||||
api := &auth{remote: RetryAuthClient(c)}
|
||||
api := &authClient{remote: RetryAuthClient(c)}
|
||||
if c != nil {
|
||||
api.callOpts = c.callOpts
|
||||
}
|
||||
return api
|
||||
}
|
||||
|
||||
func (auth *auth) AuthEnable(ctx context.Context) (*AuthEnableResponse, error) {
|
||||
func (auth *authClient) AuthEnable(ctx context.Context) (*AuthEnableResponse, error) {
|
||||
resp, err := auth.remote.AuthEnable(ctx, &pb.AuthEnableRequest{}, auth.callOpts...)
|
||||
return (*AuthEnableResponse)(resp), toErr(ctx, err)
|
||||
}
|
||||
|
||||
func (auth *auth) AuthDisable(ctx context.Context) (*AuthDisableResponse, error) {
|
||||
func (auth *authClient) AuthDisable(ctx context.Context) (*AuthDisableResponse, error) {
|
||||
resp, err := auth.remote.AuthDisable(ctx, &pb.AuthDisableRequest{}, auth.callOpts...)
|
||||
return (*AuthDisableResponse)(resp), toErr(ctx, err)
|
||||
}
|
||||
|
||||
func (auth *auth) UserAdd(ctx context.Context, name string, password string) (*AuthUserAddResponse, error) {
|
||||
func (auth *authClient) UserAdd(ctx context.Context, name string, password string) (*AuthUserAddResponse, error) {
|
||||
resp, err := auth.remote.UserAdd(ctx, &pb.AuthUserAddRequest{Name: name, Password: password}, auth.callOpts...)
|
||||
return (*AuthUserAddResponse)(resp), toErr(ctx, err)
|
||||
}
|
||||
|
||||
func (auth *auth) UserDelete(ctx context.Context, name string) (*AuthUserDeleteResponse, error) {
|
||||
func (auth *authClient) UserDelete(ctx context.Context, name string) (*AuthUserDeleteResponse, error) {
|
||||
resp, err := auth.remote.UserDelete(ctx, &pb.AuthUserDeleteRequest{Name: name}, auth.callOpts...)
|
||||
return (*AuthUserDeleteResponse)(resp), toErr(ctx, err)
|
||||
}
|
||||
|
||||
func (auth *auth) UserChangePassword(ctx context.Context, name string, password string) (*AuthUserChangePasswordResponse, error) {
|
||||
func (auth *authClient) UserChangePassword(ctx context.Context, name string, password string) (*AuthUserChangePasswordResponse, error) {
|
||||
resp, err := auth.remote.UserChangePassword(ctx, &pb.AuthUserChangePasswordRequest{Name: name, Password: password}, auth.callOpts...)
|
||||
return (*AuthUserChangePasswordResponse)(resp), toErr(ctx, err)
|
||||
}
|
||||
|
||||
func (auth *auth) UserGrantRole(ctx context.Context, user string, role string) (*AuthUserGrantRoleResponse, error) {
|
||||
func (auth *authClient) UserGrantRole(ctx context.Context, user string, role string) (*AuthUserGrantRoleResponse, error) {
|
||||
resp, err := auth.remote.UserGrantRole(ctx, &pb.AuthUserGrantRoleRequest{User: user, Role: role}, auth.callOpts...)
|
||||
return (*AuthUserGrantRoleResponse)(resp), toErr(ctx, err)
|
||||
}
|
||||
|
||||
func (auth *auth) UserGet(ctx context.Context, name string) (*AuthUserGetResponse, error) {
|
||||
func (auth *authClient) UserGet(ctx context.Context, name string) (*AuthUserGetResponse, error) {
|
||||
resp, err := auth.remote.UserGet(ctx, &pb.AuthUserGetRequest{Name: name}, auth.callOpts...)
|
||||
return (*AuthUserGetResponse)(resp), toErr(ctx, err)
|
||||
}
|
||||
|
||||
func (auth *auth) UserList(ctx context.Context) (*AuthUserListResponse, error) {
|
||||
func (auth *authClient) UserList(ctx context.Context) (*AuthUserListResponse, error) {
|
||||
resp, err := auth.remote.UserList(ctx, &pb.AuthUserListRequest{}, auth.callOpts...)
|
||||
return (*AuthUserListResponse)(resp), toErr(ctx, err)
|
||||
}
|
||||
|
||||
func (auth *auth) UserRevokeRole(ctx context.Context, name string, role string) (*AuthUserRevokeRoleResponse, error) {
|
||||
func (auth *authClient) UserRevokeRole(ctx context.Context, name string, role string) (*AuthUserRevokeRoleResponse, error) {
|
||||
resp, err := auth.remote.UserRevokeRole(ctx, &pb.AuthUserRevokeRoleRequest{Name: name, Role: role}, auth.callOpts...)
|
||||
return (*AuthUserRevokeRoleResponse)(resp), toErr(ctx, err)
|
||||
}
|
||||
|
||||
func (auth *auth) RoleAdd(ctx context.Context, name string) (*AuthRoleAddResponse, error) {
|
||||
func (auth *authClient) RoleAdd(ctx context.Context, name string) (*AuthRoleAddResponse, error) {
|
||||
resp, err := auth.remote.RoleAdd(ctx, &pb.AuthRoleAddRequest{Name: name}, auth.callOpts...)
|
||||
return (*AuthRoleAddResponse)(resp), toErr(ctx, err)
|
||||
}
|
||||
|
||||
func (auth *auth) RoleGrantPermission(ctx context.Context, name string, key, rangeEnd string, permType PermissionType) (*AuthRoleGrantPermissionResponse, error) {
|
||||
func (auth *authClient) RoleGrantPermission(ctx context.Context, name string, key, rangeEnd string, permType PermissionType) (*AuthRoleGrantPermissionResponse, error) {
|
||||
perm := &authpb.Permission{
|
||||
Key: []byte(key),
|
||||
RangeEnd: []byte(rangeEnd),
|
||||
@ -173,22 +173,22 @@ func (auth *auth) RoleGrantPermission(ctx context.Context, name string, key, ran
|
||||
return (*AuthRoleGrantPermissionResponse)(resp), toErr(ctx, err)
|
||||
}
|
||||
|
||||
func (auth *auth) RoleGet(ctx context.Context, role string) (*AuthRoleGetResponse, error) {
|
||||
func (auth *authClient) RoleGet(ctx context.Context, role string) (*AuthRoleGetResponse, error) {
|
||||
resp, err := auth.remote.RoleGet(ctx, &pb.AuthRoleGetRequest{Role: role}, auth.callOpts...)
|
||||
return (*AuthRoleGetResponse)(resp), toErr(ctx, err)
|
||||
}
|
||||
|
||||
func (auth *auth) RoleList(ctx context.Context) (*AuthRoleListResponse, error) {
|
||||
func (auth *authClient) RoleList(ctx context.Context) (*AuthRoleListResponse, error) {
|
||||
resp, err := auth.remote.RoleList(ctx, &pb.AuthRoleListRequest{}, auth.callOpts...)
|
||||
return (*AuthRoleListResponse)(resp), toErr(ctx, err)
|
||||
}
|
||||
|
||||
func (auth *auth) RoleRevokePermission(ctx context.Context, role string, key, rangeEnd string) (*AuthRoleRevokePermissionResponse, error) {
|
||||
func (auth *authClient) RoleRevokePermission(ctx context.Context, role string, key, rangeEnd string) (*AuthRoleRevokePermissionResponse, error) {
|
||||
resp, err := auth.remote.RoleRevokePermission(ctx, &pb.AuthRoleRevokePermissionRequest{Role: role, Key: []byte(key), RangeEnd: []byte(rangeEnd)}, auth.callOpts...)
|
||||
return (*AuthRoleRevokePermissionResponse)(resp), toErr(ctx, err)
|
||||
}
|
||||
|
||||
func (auth *auth) RoleDelete(ctx context.Context, role string) (*AuthRoleDeleteResponse, error) {
|
||||
func (auth *authClient) RoleDelete(ctx context.Context, role string) (*AuthRoleDeleteResponse, error) {
|
||||
resp, err := auth.remote.RoleDelete(ctx, &pb.AuthRoleDeleteRequest{Role: role}, auth.callOpts...)
|
||||
return (*AuthRoleDeleteResponse)(resp), toErr(ctx, err)
|
||||
}
|
||||
|
@ -185,7 +185,7 @@ func (cred authTokenCredential) GetRequestMetadata(ctx context.Context, s ...str
|
||||
cred.tokenMu.RLock()
|
||||
defer cred.tokenMu.RUnlock()
|
||||
return map[string]string{
|
||||
"token": cred.token,
|
||||
rpctypes.TokenFieldNameGRPC: cred.token,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@ import (
|
||||
"testing"
|
||||
|
||||
epb "github.com/coreos/etcd/etcdserver/api/v3election/v3electionpb"
|
||||
"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
|
||||
pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
|
||||
"github.com/coreos/etcd/pkg/testutil"
|
||||
|
||||
@ -236,7 +237,7 @@ func testV3CurlAuth(cx ctlCtx) {
|
||||
authRes := make(map[string]interface{})
|
||||
testutil.AssertNil(cx.t, json.Unmarshal([]byte(cURLRes), &authRes))
|
||||
|
||||
token, ok := authRes["token"].(string)
|
||||
token, ok := authRes[rpctypes.TokenFieldNameGRPC].(string)
|
||||
if !ok {
|
||||
cx.t.Fatalf("failed invalid token in authenticate response with curl")
|
||||
}
|
||||
|
20
etcdserver/api/v3rpc/rpctypes/metadatafields.go
Normal file
20
etcdserver/api/v3rpc/rpctypes/metadatafields.go
Normal file
@ -0,0 +1,20 @@
|
||||
// Copyright 2018 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 rpctypes
|
||||
|
||||
var (
|
||||
TokenFieldNameGRPC = "token"
|
||||
TokenFieldNameSwagger = "authorization"
|
||||
)
|
@ -17,6 +17,8 @@ package grpcproxy
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/metadata"
|
||||
)
|
||||
@ -24,7 +26,7 @@ import (
|
||||
func getAuthTokenFromClient(ctx context.Context) string {
|
||||
md, ok := metadata.FromIncomingContext(ctx)
|
||||
if ok {
|
||||
ts, ok := md["token"]
|
||||
ts, ok := md[rpctypes.TokenFieldNameGRPC]
|
||||
if ok {
|
||||
return ts[0]
|
||||
}
|
||||
@ -35,7 +37,7 @@ func getAuthTokenFromClient(ctx context.Context) string {
|
||||
func withClientAuthToken(ctx context.Context, ctxWithToken context.Context) context.Context {
|
||||
token := getAuthTokenFromClient(ctxWithToken)
|
||||
if token != "" {
|
||||
ctx = context.WithValue(ctx, "token", token)
|
||||
ctx = context.WithValue(ctx, rpctypes.TokenFieldNameGRPC, token)
|
||||
}
|
||||
return ctx
|
||||
}
|
||||
@ -50,7 +52,7 @@ func (cred *proxyTokenCredential) RequireTransportSecurity() bool {
|
||||
|
||||
func (cred *proxyTokenCredential) GetRequestMetadata(ctx context.Context, s ...string) (map[string]string, error) {
|
||||
return map[string]string{
|
||||
"token": cred.token,
|
||||
rpctypes.TokenFieldNameGRPC: cred.token,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -64,7 +66,7 @@ func AuthUnaryClientInterceptor(ctx context.Context, method string, req, reply i
|
||||
}
|
||||
|
||||
func AuthStreamClientInterceptor(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {
|
||||
tokenif := ctx.Value("token")
|
||||
tokenif := ctx.Value(rpctypes.TokenFieldNameGRPC)
|
||||
if tokenif != nil {
|
||||
tokenCred := &proxyTokenCredential{tokenif.(string)}
|
||||
opts = append(opts, grpc.PerRPCCredentials(tokenCred))
|
||||
|
Loading…
x
Reference in New Issue
Block a user