From 992805fa7d90a14482879c8faa0bfc8593779262 Mon Sep 17 00:00:00 2001 From: horizonzy <1060026287@qq.com> Date: Wed, 19 May 2021 23:30:49 +0800 Subject: [PATCH] Enhance the root permission, when root role exist, it always return rootPerm. etcdctl role grant-permission root readwrite foo. see etcdctl role get root output. Before: Role root KV Read: foo KV Write: foo After: Role root KV Read: [, KV Write: [, --- etcdctl/ctlv3/command/printer_simple.go | 2 +- server/auth/store.go | 12 ++++++--- server/auth/store_test.go | 34 +++++++++++++++++++++++++ tests/e2e/ctl_v3_role_test.go | 2 +- 4 files changed, 45 insertions(+), 5 deletions(-) diff --git a/etcdctl/ctlv3/command/printer_simple.go b/etcdctl/ctlv3/command/printer_simple.go index e9a0b410305a..14028c614457 100644 --- a/etcdctl/ctlv3/command/printer_simple.go +++ b/etcdctl/ctlv3/command/printer_simple.go @@ -200,7 +200,7 @@ func (s *simplePrinter) RoleGet(role string, r v3.AuthRoleGetResponse) { } else { fmt.Printf("\t[%s, ", sKey) } - if v3.GetPrefixRangeEnd(sKey) == sRangeEnd { + if v3.GetPrefixRangeEnd(sKey) == sRangeEnd && len(sKey) > 0 { fmt.Printf(" (prefix %s)", sKey) } fmt.Printf("\n") diff --git a/server/auth/store.go b/server/auth/store.go index 2843de8cd29b..63ea7a76ad24 100644 --- a/server/auth/store.go +++ b/server/auth/store.go @@ -46,6 +46,8 @@ var ( revisionKey = []byte("authRevision") + rootPerm = authpb.Permission{PermType: authpb.READWRITE, Key: []byte{}, RangeEnd: []byte{0}} + ErrRootUserNotExist = errors.New("auth: root user does not exist") ErrRootRoleNotExist = errors.New("auth: root user does not have root role") ErrUserAlreadyExist = errors.New("auth: user already exists") @@ -631,7 +633,11 @@ func (as *authStore) RoleGet(r *pb.AuthRoleGetRequest) (*pb.AuthRoleGetResponse, if role == nil { return nil, ErrRoleNotFound } - resp.Perm = append(resp.Perm, role.KeyPermission...) + if rootRole == string(role.Name) { + resp.Perm = append(resp.Perm, &rootPerm) + } else { + resp.Perm = append(resp.Perm, role.KeyPermission...) + } return &resp, nil } @@ -950,8 +956,8 @@ func delUser(tx backend.BatchTx, username string) { tx.UnsafeDelete(buckets.AuthUsers, []byte(username)) } -func getRole(lg *zap.Logger, tx backend.BatchTx, rolename string) *authpb.Role { - _, vs := tx.UnsafeRange(buckets.AuthRoles, []byte(rolename), nil, 0) +func getRole(lg *zap.Logger, tx backend.BatchTx, roleName string) *authpb.Role { + _, vs := tx.UnsafeRange(buckets.AuthRoles, []byte(roleName), nil, 0) if len(vs) == 0 { return nil } diff --git a/server/auth/store_test.go b/server/auth/store_test.go index c530ffe8861d..6618c7e806d0 100644 --- a/server/auth/store_test.go +++ b/server/auth/store_test.go @@ -450,6 +450,40 @@ func TestRoleGrantPermission(t *testing.T) { } } +func TestRootRoleGrantPermission(t *testing.T) { + as, tearDown := setupAuthStore(t) + defer tearDown(t) + + perm := &authpb.Permission{ + PermType: authpb.WRITE, + Key: []byte("Keys"), + RangeEnd: []byte("RangeEnd"), + } + _, err := as.RoleGrantPermission(&pb.AuthRoleGrantPermissionRequest{ + Name: "root", + Perm: perm, + }) + + if err != nil { + t.Error(err) + } + + r, err := as.RoleGet(&pb.AuthRoleGetRequest{Role: "root"}) + if err != nil { + t.Fatal(err) + } + + //whatever grant permission to root, it always return root permission. + expectPerm := &authpb.Permission{ + PermType: authpb.READWRITE, + RangeEnd: []byte{0}, + } + + if !reflect.DeepEqual(expectPerm, r.Perm[0]) { + t.Errorf("expected %v, got %v", expectPerm, r.Perm[0]) + } +} + func TestRoleRevokePermission(t *testing.T) { as, tearDown := setupAuthStore(t) defer tearDown(t) diff --git a/tests/e2e/ctl_v3_role_test.go b/tests/e2e/ctl_v3_role_test.go index c0779b49bd3e..820b64783909 100644 --- a/tests/e2e/ctl_v3_role_test.go +++ b/tests/e2e/ctl_v3_role_test.go @@ -76,7 +76,7 @@ func rootRoleGetTest(cx ctlCtx) { }, { args: []string{"get", "root"}, - expectedStr: []string{"Role root\r\n", "KV Read:\r\n", "\tfoo\r\n", "KV Write:\r\n", "\tfoo\r\n"}, + expectedStr: []string{"Role root\r\n", "KV Read:\r\n", "\t[, \r\n", "KV Write:\r\n", "\t[, \r\n"}, }, }