Skip to content

Commit

Permalink
fix: [2.5] fix privilege group list and list collections (#38738)
Browse files Browse the repository at this point in the history
cherry-pick from: #38684
related: #37031

Signed-off-by: shaoting-huang <[email protected]>
  • Loading branch information
shaoting-huang authored Dec 25, 2024
1 parent f441ccd commit a4901ef
Show file tree
Hide file tree
Showing 11 changed files with 265 additions and 212 deletions.
16 changes: 8 additions & 8 deletions client/milvusclient/rbac_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -399,11 +399,11 @@ func TestRoleRBAC(t *testing.T) {
suite.Run(t, new(RoleSuite))
}

type PrivilgeGroupSuite struct {
type PrivilegeGroupSuite struct {
MockSuiteBase
}

func (s *PrivilgeGroupSuite) TestGrantV2() {
func (s *PrivilegeGroupSuite) TestGrantV2() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

Expand Down Expand Up @@ -433,7 +433,7 @@ func (s *PrivilgeGroupSuite) TestGrantV2() {
})
}

func (s *PrivilgeGroupSuite) TestRevokeV2() {
func (s *PrivilegeGroupSuite) TestRevokeV2() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

Expand Down Expand Up @@ -463,7 +463,7 @@ func (s *PrivilgeGroupSuite) TestRevokeV2() {
})
}

func (s *PrivilgeGroupSuite) TestCreatePrivilegeGroup() {
func (s *PrivilegeGroupSuite) TestCreatePrivilegeGroup() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

Expand All @@ -487,7 +487,7 @@ func (s *PrivilgeGroupSuite) TestCreatePrivilegeGroup() {
})
}

func (s *PrivilgeGroupSuite) TestDropPrivilegeGroup() {
func (s *PrivilegeGroupSuite) TestDropPrivilegeGroup() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

Expand All @@ -511,7 +511,7 @@ func (s *PrivilgeGroupSuite) TestDropPrivilegeGroup() {
})
}

func (s *PrivilgeGroupSuite) TestListPrivilegeGroups() {
func (s *PrivilegeGroupSuite) TestListPrivilegeGroups() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

Expand Down Expand Up @@ -548,7 +548,7 @@ func (s *PrivilgeGroupSuite) TestListPrivilegeGroups() {
})
}

func (s *PrivilgeGroupSuite) TestOperatePrivilegeGroup() {
func (s *PrivilegeGroupSuite) TestOperatePrivilegeGroup() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

Expand All @@ -575,5 +575,5 @@ func (s *PrivilgeGroupSuite) TestOperatePrivilegeGroup() {
}

func TestPrivilegeGroup(t *testing.T) {
suite.Run(t, new(PrivilgeGroupSuite))
suite.Run(t, new(PrivilegeGroupSuite))
}
2 changes: 1 addition & 1 deletion configs/milvus.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -829,7 +829,7 @@ common:
superUsers:
defaultRootPassword: "Milvus" # default password for root user. The maximum length is 72 characters, and double quotes are required.
rbac:
overrideBuiltInPrivilgeGroups:
overrideBuiltInPrivilegeGroups:
enabled: false # Whether to override build-in privilege groups
cluster:
readonly:
Expand Down
6 changes: 3 additions & 3 deletions internal/proxy/privilege_interceptor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -576,9 +576,9 @@ func TestBuiltinPrivilegeGroup(t *testing.T) {
mgr := newShardClientMgr()

policies := []string{}
for _, priv := range util.BuiltinPrivilegeGroups["ClusterReadOnly"] {
objectType := util.GetObjectType(priv)
policies = append(policies, funcutil.PolicyForPrivilege("role1", objectType, "*", util.PrivilegeNameForMetastore(priv), "default"))
for _, priv := range Params.RbacConfig.GetDefaultPrivilegeGroup("ClusterReadOnly").Privileges {
objectType := util.GetObjectType(priv.Name)
policies = append(policies, funcutil.PolicyForPrivilege("role1", objectType, "*", util.PrivilegeNameForMetastore(priv.Name), "default"))
}
client.listPolicy = func(ctx context.Context, in *internalpb.ListPolicyRequest) (*internalpb.ListPolicyResponse, error) {
return &internalpb.ListPolicyResponse{
Expand Down
59 changes: 3 additions & 56 deletions internal/rootcoord/root_coord.go
Original file line number Diff line number Diff line change
Expand Up @@ -638,50 +638,6 @@ func (c *Core) initPublicRolePrivilege() error {
return nil
}

func (c *Core) initBuiltinPrivilegeGroups() []*milvuspb.PrivilegeGroupInfo {
// init built in privilege groups, override by config if rbac config enabled
builtinGroups := make([]*milvuspb.PrivilegeGroupInfo, 0)
for groupName, privileges := range util.BuiltinPrivilegeGroups {
if Params.RbacConfig.Enabled.GetAsBool() {
var confPrivs []string
switch groupName {
case "ClusterReadOnly":
confPrivs = Params.RbacConfig.ClusterReadOnlyPrivileges.GetAsStrings()
case "ClusterReadWrite":
confPrivs = Params.RbacConfig.ClusterReadWritePrivileges.GetAsStrings()
case "ClusterAdmin":
confPrivs = Params.RbacConfig.ClusterAdminPrivileges.GetAsStrings()
case "DatabaseReadOnly":
confPrivs = Params.RbacConfig.DBReadOnlyPrivileges.GetAsStrings()
case "DatabaseReadWrite":
confPrivs = Params.RbacConfig.DBReadWritePrivileges.GetAsStrings()
case "DatabaseAdmin":
confPrivs = Params.RbacConfig.DBAdminPrivileges.GetAsStrings()
case "CollectionReadOnly":
confPrivs = Params.RbacConfig.CollectionReadOnlyPrivileges.GetAsStrings()
case "CollectionReadWrite":
confPrivs = Params.RbacConfig.CollectionReadWritePrivileges.GetAsStrings()
case "CollectionAdmin":
confPrivs = Params.RbacConfig.CollectionAdminPrivileges.GetAsStrings()
default:
return nil
}
if len(confPrivs) > 0 {
privileges = confPrivs
}
}

privs := lo.Map(privileges, func(name string, _ int) *milvuspb.PrivilegeEntity {
return &milvuspb.PrivilegeEntity{Name: name}
})
builtinGroups = append(builtinGroups, &milvuspb.PrivilegeGroupInfo{
GroupName: groupName,
Privileges: privs,
})
}
return builtinGroups
}

func (c *Core) initBuiltinRoles() error {
log := log.Ctx(c.ctx)
rolePrivilegesMap := Params.RoleCfg.Roles.GetAsRoleDetails()
Expand Down Expand Up @@ -2648,7 +2604,7 @@ func (c *Core) isValidPrivilege(ctx context.Context, privilegeName string, objec
if customPrivGroup {
return fmt.Errorf("can not operate the custom privilege group [%s]", privilegeName)
}
if lo.Contains(lo.Keys(util.BuiltinPrivilegeGroups), privilegeName) {
if lo.Contains(Params.RbacConfig.GetDefaultPrivilegeGroupNames(), privilegeName) {
return fmt.Errorf("can not operate the built-in privilege group [%s]", privilegeName)
}
// check object privileges for built-in privileges
Expand Down Expand Up @@ -2757,7 +2713,7 @@ func (c *Core) OperatePrivilege(ctx context.Context, in *milvuspb.OperatePrivile
grants := []*milvuspb.GrantEntity{in.Entity}

allGroups, err := c.meta.ListPrivilegeGroups(ctx)
allGroups = append(allGroups, c.initBuiltinPrivilegeGroups()...)
allGroups = append(allGroups, Params.RbacConfig.GetDefaultPrivilegeGroups()...)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -3243,16 +3199,7 @@ func (c *Core) ListPrivilegeGroups(ctx context.Context, in *milvuspb.ListPrivile
metrics.RootCoordDDLReqLatency.WithLabelValues(method).Observe(float64(tr.ElapseSpan().Milliseconds()))

// append built in privilege groups
for groupName, privileges := range util.BuiltinPrivilegeGroups {
privGroups = append(privGroups, &milvuspb.PrivilegeGroupInfo{
GroupName: groupName,
Privileges: lo.Map(privileges, func(p string, _ int) *milvuspb.PrivilegeEntity {
return &milvuspb.PrivilegeEntity{
Name: p,
}
}),
})
}
privGroups = append(privGroups, Params.RbacConfig.GetDefaultPrivilegeGroups()...)
return &milvuspb.ListPrivilegeGroupsResponse{
Status: merr.Success(),
PrivilegeGroups: privGroups,
Expand Down
23 changes: 0 additions & 23 deletions internal/rootcoord/root_coord_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2037,29 +2037,6 @@ func TestCore_InitRBAC(t *testing.T) {
err := c.initRbac()
assert.NoError(t, err)
})

t.Run("init default privilege groups", func(t *testing.T) {
clusterReadWrite := `SelectOwnership,SelectUser,DescribeResourceGroup`
meta := mockrootcoord.NewIMetaTable(t)
c := newTestCore(withHealthyCode(), withMeta(meta))

Params.Save(Params.RbacConfig.Enabled.Key, "true")
Params.Save(Params.RbacConfig.ClusterReadWritePrivileges.Key, clusterReadWrite)

defer func() {
Params.Reset(Params.RbacConfig.Enabled.Key)
Params.Reset(Params.RbacConfig.ClusterReadWritePrivileges.Key)
}()

builtinGroups := c.initBuiltinPrivilegeGroups()
fmt.Println(builtinGroups)
assert.Equal(t, len(util.BuiltinPrivilegeGroups), len(builtinGroups))
for _, group := range builtinGroups {
if group.GroupName == "ClusterReadWrite" {
assert.Equal(t, len(group.Privileges), 3)
}
}
})
}

func TestCore_BackupRBAC(t *testing.T) {
Expand Down
7 changes: 5 additions & 2 deletions internal/rootcoord/show_collection_task.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,15 @@ func (t *showCollectionTask) Execute(ctx context.Context) error {
}
for _, entity := range entities {
objectType := entity.GetObject().GetName()
priv := entity.GetGrantor().GetPrivilege().GetName()
if objectType == commonpb.ObjectType_Global.String() &&
entity.GetGrantor().GetPrivilege().GetName() == util.PrivilegeNameForAPI(commonpb.ObjectPrivilege_PrivilegeAll.String()) {
priv == util.PrivilegeNameForAPI(commonpb.ObjectPrivilege_PrivilegeAll.String()) {
privilegeColls.Insert(util.AnyWord)
return privilegeColls, nil
}
if objectType != commonpb.ObjectType_Collection.String() {
// should list collection level built-in privilege group objects
if objectType != commonpb.ObjectType_Collection.String() &&
!Params.RbacConfig.IsCollectionPrivilegeGroup(priv) {
continue
}
collectionName := entity.GetObjectName()
Expand Down
51 changes: 51 additions & 0 deletions internal/rootcoord/show_collection_task_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,57 @@ func TestShowCollectionsAuth(t *testing.T) {
assert.Equal(t, "foo", task.Rsp.GetCollectionNames()[0])
})

t.Run("collection level privilege group", func(t *testing.T) {
Params.Save(Params.CommonCfg.AuthorizationEnabled.Key, "true")
defer Params.Reset(Params.CommonCfg.AuthorizationEnabled.Key)
meta := mockrootcoord.NewIMetaTable(t)
core := newTestCore(withMeta(meta))

meta.EXPECT().SelectUser(mock.Anything, mock.Anything, mock.Anything, mock.Anything).
Return([]*milvuspb.UserResult{
{
User: &milvuspb.UserEntity{
Name: "foo",
},
Roles: []*milvuspb.RoleEntity{
{
Name: "hoooo",
},
},
},
}, nil).Once()
meta.EXPECT().SelectGrant(mock.Anything, mock.Anything, mock.Anything).Return([]*milvuspb.GrantEntity{
{
Object: &milvuspb.ObjectEntity{Name: commonpb.ObjectType_Global.String()},
Grantor: &milvuspb.GrantorEntity{
Privilege: &milvuspb.PrivilegeEntity{
Name: util.PrivilegeNameForAPI(commonpb.ObjectPrivilege_PrivilegeGroupCollectionReadOnly.String()),
},
},
ObjectName: util.AnyWord,
},
}, nil).Once()
meta.EXPECT().ListCollections(mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]*model.Collection{
{
DBID: 1,
CollectionID: 100,
Name: "foo",
CreateTime: tsoutil.GetCurrentTime(),
},
}, nil).Once()

task := &showCollectionTask{
baseTask: newBaseTask(context.Background(), core),
Req: &milvuspb.ShowCollectionsRequest{DbName: "default"},
Rsp: &milvuspb.ShowCollectionsResponse{},
}
ctx := GetContext(context.Background(), "foo:root")
err := task.Execute(ctx)
assert.NoError(t, err)
assert.Equal(t, 1, len(task.Rsp.GetCollectionNames()))
assert.Equal(t, "foo", task.Rsp.GetCollectionNames()[0])
})

t.Run("all collection", func(t *testing.T) {
Params.Save(Params.CommonCfg.AuthorizationEnabled.Key, "true")
defer Params.Reset(Params.CommonCfg.AuthorizationEnabled.Key)
Expand Down
95 changes: 0 additions & 95 deletions pkg/util/constant.go
Original file line number Diff line number Diff line change
Expand Up @@ -290,101 +290,6 @@ var (
commonpb.ObjectPrivilege_PrivilegeAlterDatabase.String(),
commonpb.ObjectPrivilege_PrivilegeFlush.String(),
}

BuiltinPrivilegeGroups = map[string][]string{
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGroupCollectionReadOnly.String()): CollectionReadOnlyPrivilegeGroup,
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGroupCollectionReadWrite.String()): CollectionReadWritePrivilegeGroup,
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGroupCollectionAdmin.String()): CollectionAdminPrivilegeGroup,
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGroupDatabaseReadOnly.String()): DatabaseReadOnlyPrivilegeGroup,
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGroupDatabaseReadWrite.String()): DatabaseReadWritePrivilegeGroup,
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGroupDatabaseAdmin.String()): DatabaseAdminPrivilegeGroup,
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGroupClusterReadOnly.String()): ClusterReadOnlyPrivilegeGroup,
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGroupClusterReadWrite.String()): ClusterReadWritePrivilegeGroup,
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGroupClusterAdmin.String()): ClusterAdminPrivilegeGroup,
}

CollectionReadOnlyPrivilegeGroup = []string{
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeQuery.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeSearch.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeIndexDetail.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGetFlushState.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGetLoadState.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGetLoadingProgress.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeHasPartition.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeShowPartitions.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDescribeCollection.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDescribeAlias.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGetStatistics.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeListAliases.String()),
}

CollectionReadWritePrivilegeGroup = append(CollectionReadOnlyPrivilegeGroup,
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeLoad.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeRelease.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeInsert.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDelete.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeUpsert.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeImport.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeFlush.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeCompaction.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeLoadBalance.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeCreateIndex.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDropIndex.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeCreatePartition.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDropPartition.String()),
)

CollectionAdminPrivilegeGroup = append(CollectionReadWritePrivilegeGroup,
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeCreateAlias.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDropAlias.String()),
)

DatabaseReadOnlyPrivilegeGroup = []string{
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeShowCollections.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDescribeDatabase.String()),
}

DatabaseReadWritePrivilegeGroup = append(DatabaseReadOnlyPrivilegeGroup,
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeAlterDatabase.String()),
)

DatabaseAdminPrivilegeGroup = append(DatabaseReadWritePrivilegeGroup,
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeCreateCollection.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDropCollection.String()),
)

ClusterReadOnlyPrivilegeGroup = []string{
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeListDatabases.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeSelectOwnership.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeSelectUser.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDescribeResourceGroup.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeListResourceGroups.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeListPrivilegeGroups.String()),
}

ClusterReadWritePrivilegeGroup = append(ClusterReadOnlyPrivilegeGroup,
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeFlushAll.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeTransferNode.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeTransferReplica.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeUpdateResourceGroups.String()),
)

ClusterAdminPrivilegeGroup = append(ClusterReadWritePrivilegeGroup,
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeBackupRBAC.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeRestoreRBAC.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeCreateDatabase.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDropDatabase.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeCreateOwnership.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDropOwnership.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeManageOwnership.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeCreateResourceGroup.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDropResourceGroup.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeUpdateUser.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeRenameCollection.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeCreatePrivilegeGroup.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDropPrivilegeGroup.String()),
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeOperatePrivilegeGroup.String()),
)
)

// StringSet convert array to map for conveniently check if the array contains an element
Expand Down
Loading

0 comments on commit a4901ef

Please sign in to comment.