Skip to content

Commit

Permalink
Merge pull request #12992 from awly/client-auth-bundle-overwrite
Browse files Browse the repository at this point in the history
client/v3: do not overwrite authTokenBundle on dial
  • Loading branch information
ptabor authored Jul 1, 2021
2 parents 0d0b6f0 + ab8e5a4 commit 7271ade
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 3 deletions.
4 changes: 2 additions & 2 deletions client/v3/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,8 +283,7 @@ func (c *Client) dial(creds grpccredentials.TransportCredentials, dopts ...grpc.
if err != nil {
return nil, fmt.Errorf("failed to configure dialer: %v", err)
}
if c.Username != "" && c.Password != "" {
c.authTokenBundle = credentials.NewBundle(credentials.Config{})
if c.authTokenBundle != nil {
opts = append(opts, grpc.WithPerRPCCredentials(c.authTokenBundle.PerRPCCredentials()))
}

Expand Down Expand Up @@ -365,6 +364,7 @@ func newClient(cfg *Config) (*Client, error) {
if cfg.Username != "" && cfg.Password != "" {
client.Username = cfg.Username
client.Password = cfg.Password
client.authTokenBundle = credentials.NewBundle(credentials.Config{})
}
if cfg.MaxCallSendMsgSize > 0 || cfg.MaxCallRecvMsgSize > 0 {
if cfg.MaxCallRecvMsgSize > 0 && cfg.MaxCallSendMsgSize > cfg.MaxCallRecvMsgSize {
Expand Down
53 changes: 52 additions & 1 deletion client/v3/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@ package clientv3
import (
"context"
"fmt"
"go.uber.org/zap"
"net"
"path/filepath"
"testing"
"time"

"go.etcd.io/etcd/api/v3/etcdserverpb"
"go.etcd.io/etcd/api/v3/v3rpc/rpctypes"
"go.etcd.io/etcd/client/pkg/v3/testutil"
"go.uber.org/zap"
"go.uber.org/zap/zaptest"

"google.golang.org/grpc"
Expand Down Expand Up @@ -200,3 +202,52 @@ func TestZapWithLogger(t *testing.T) {
t.Errorf("WithZapLogger should modify *zap.Logger")
}
}

func TestAuthTokenBundleNoOverwrite(t *testing.T) {
// Create a mock AuthServer to handle Authenticate RPCs.
lis, err := net.Listen("unix", filepath.Join(t.TempDir(), "etcd-auth-test:0"))
if err != nil {
t.Fatal(err)
}
defer lis.Close()
addr := "unix://" + lis.Addr().String()
srv := grpc.NewServer()
etcdserverpb.RegisterAuthServer(srv, mockAuthServer{})
go srv.Serve(lis)
defer srv.Stop()

// Create a client, which should call Authenticate on the mock server to
// exchange username/password for an auth token.
c, err := NewClient(t, Config{
DialTimeout: 5 * time.Second,
Endpoints: []string{addr},
Username: "foo",
Password: "bar",
})
if err != nil {
t.Fatal(err)
}
defer c.Close()
oldTokenBundle := c.authTokenBundle

// Call the public Dial again, which should preserve the original
// authTokenBundle.
gc, err := c.Dial(addr)
if err != nil {
t.Fatal(err)
}
defer gc.Close()
newTokenBundle := c.authTokenBundle

if oldTokenBundle != newTokenBundle {
t.Error("Client.authTokenBundle has been overwritten during Client.Dial")
}
}

type mockAuthServer struct {
*etcdserverpb.UnimplementedAuthServer
}

func (mockAuthServer) Authenticate(context.Context, *etcdserverpb.AuthenticateRequest) (*etcdserverpb.AuthenticateResponse, error) {
return &etcdserverpb.AuthenticateResponse{Token: "mock-token"}, nil
}

0 comments on commit 7271ade

Please sign in to comment.