Skip to content

Commit

Permalink
Merge pull request #9018 from gyuho/auth-ctx
Browse files Browse the repository at this point in the history
*: fix server-side lease expire when auth is enabled
  • Loading branch information
gyuho authored Dec 15, 2017
2 parents 014c375 + 9fb7bbd commit b0f0ba7
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 2 deletions.
4 changes: 3 additions & 1 deletion auth/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -1090,7 +1090,9 @@ func (as *authStore) WithRoot(ctx context.Context) context.Context {
"token": token,
}
tokenMD := metadata.New(mdMap)
return metadata.NewOutgoingContext(ctx, tokenMD)

// use "mdIncomingKey{}" since it's called from local etcdserver
return metadata.NewIncomingContext(ctx, tokenMD)
}

func (as *authStore) HasRole(user, role string) bool {
Expand Down
31 changes: 31 additions & 0 deletions auth/store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -701,3 +701,34 @@ func TestRolesOrder(t *testing.T) {
}
}
}

// TestAuthInfoFromCtxWithRoot ensures "WithRoot" properly embeds token in the context.
func TestAuthInfoFromCtxWithRoot(t *testing.T) {
b, tPath := backend.NewDefaultTmpBackend()
defer os.Remove(tPath)

tp, err := NewTokenProvider("simple", dummyIndexWaiter)
if err != nil {
t.Fatal(err)
}
as := NewAuthStore(b, tp)
defer as.Close()

if err = enableAuthAndCreateRoot(as); err != nil {
t.Fatal(err)
}

ctx := context.Background()
ctx = as.WithRoot(ctx)

ai, aerr := as.AuthInfoFromCtx(ctx)
if aerr != nil {
t.Error(err)
}
if ai == nil {
t.Error("expected non-nil *AuthInfo")
}
if ai.Username != "root" {
t.Errorf("expected user name 'root', got %+v", ai)
}
}
4 changes: 3 additions & 1 deletion etcdserver/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -770,7 +770,9 @@ func (s *EtcdServer) run() {
lid := lease.ID
s.goAttach(func() {
ctx := s.authStore.WithRoot(s.ctx)
s.LeaseRevoke(ctx, &pb.LeaseRevokeRequest{ID: int64(lid)})
if _, lerr := s.LeaseRevoke(ctx, &pb.LeaseRevokeRequest{ID: int64(lid)}); lerr != nil {
plog.Warningf("failed to revoke %016x (%q)", lid, lerr.Error())
}
leaseExpired.Inc()
<-c
})
Expand Down
52 changes: 52 additions & 0 deletions integration/v3_auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,58 @@ func TestV3AuthRevision(t *testing.T) {
}
}

// TestV3AuthWithLeaseRevokeWithRoot ensures that granted leases
// with root user be revoked after TTL.
func TestV3AuthWithLeaseRevokeWithRoot(t *testing.T) {
defer testutil.AfterTest(t)

clus := NewClusterV3(t, &ClusterConfig{Size: 1})
defer clus.Terminate(t)

api := toGRPC(clus.Client(0))
authSetupRoot(t, api.Auth)

rootc, cerr := clientv3.New(clientv3.Config{
Endpoints: clus.Client(0).Endpoints(),
Username: "root",
Password: "123",
})
if cerr != nil {
t.Fatal(cerr)
}
defer rootc.Close()

leaseResp, err := rootc.Grant(context.TODO(), 2)
if err != nil {
t.Fatal(err)
}
leaseID := leaseResp.ID

if _, err = rootc.Put(context.TODO(), "foo", "bar", clientv3.WithLease(leaseID)); err != nil {
t.Fatal(err)
}

// wait for lease expire
time.Sleep(3 * time.Second)

tresp, terr := api.Lease.LeaseTimeToLive(
context.TODO(),
&pb.LeaseTimeToLiveRequest{
ID: int64(leaseID),
Keys: true,
},
)
if terr != nil {
t.Error(terr)
}
if len(tresp.Keys) > 0 || tresp.GrantedTTL != 0 {
t.Errorf("lease %016x should have been revoked, got %+v", leaseID, tresp)
}
if tresp.TTL != -1 {
t.Errorf("lease %016x should have been expired, got %+v", leaseID, tresp)
}
}

type user struct {
name string
password string
Expand Down

0 comments on commit b0f0ba7

Please sign in to comment.