mirror of
https://gitee.com/milvus-io/milvus.git
synced 2025-12-06 17:18:35 +08:00
test: add cases for go client rbac APIs (#40352)
issue: #33419 - add cases for go client rbac APIs - add dbName params for grant/revoke v1 & v2 api - add dbName in GrantItem --------- Signed-off-by: ThreadDao <yufen.zong@zilliz.com>
This commit is contained in:
parent
b2a8694686
commit
aaf8ddcec6
@ -32,6 +32,7 @@ type GrantItem struct {
|
||||
RoleName string
|
||||
Grantor string
|
||||
Privilege string
|
||||
DbName string
|
||||
}
|
||||
|
||||
type UserInfo struct {
|
||||
|
||||
@ -155,6 +155,7 @@ func (c *Client) DescribeRole(ctx context.Context, option DescribeRoleOption, ca
|
||||
RoleName: g.GetRole().GetName(),
|
||||
Grantor: g.GetGrantor().GetUser().GetName(),
|
||||
Privilege: g.GetGrantor().GetPrivilege().GetName(),
|
||||
DbName: g.GetDbName(),
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@ -242,6 +242,7 @@ type DescribeRoleOption interface {
|
||||
|
||||
type describeRoleOption struct {
|
||||
roleName string
|
||||
dbName string
|
||||
}
|
||||
|
||||
func (opt *describeRoleOption) SelectRoleRequest() *milvuspb.SelectRoleRequest {
|
||||
@ -255,7 +256,8 @@ func (opt *describeRoleOption) SelectRoleRequest() *milvuspb.SelectRoleRequest {
|
||||
func (opt *describeRoleOption) Request() *milvuspb.SelectGrantRequest {
|
||||
return &milvuspb.SelectGrantRequest{
|
||||
Entity: &milvuspb.GrantEntity{
|
||||
Role: &milvuspb.RoleEntity{Name: opt.roleName},
|
||||
Role: &milvuspb.RoleEntity{Name: opt.roleName},
|
||||
DbName: opt.dbName,
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -266,6 +268,11 @@ func NewDescribeRoleOption(roleName string) *describeRoleOption {
|
||||
}
|
||||
}
|
||||
|
||||
func (opt *describeRoleOption) WithDbName(dbName string) *describeRoleOption {
|
||||
opt.dbName = dbName
|
||||
return opt
|
||||
}
|
||||
|
||||
type GrantPrivilegeOption interface {
|
||||
Request() *milvuspb.OperatePrivilegeRequest
|
||||
}
|
||||
@ -275,6 +282,7 @@ type grantPrivilegeOption struct {
|
||||
privilegeName string
|
||||
objectName string
|
||||
objectType string
|
||||
dbName string
|
||||
}
|
||||
|
||||
func (opt *grantPrivilegeOption) Request() *milvuspb.OperatePrivilegeRequest {
|
||||
@ -288,6 +296,7 @@ func (opt *grantPrivilegeOption) Request() *milvuspb.OperatePrivilegeRequest {
|
||||
Name: opt.objectType,
|
||||
},
|
||||
ObjectName: opt.objectName,
|
||||
DbName: opt.dbName,
|
||||
},
|
||||
|
||||
Type: milvuspb.OperatePrivilegeType_Grant,
|
||||
@ -303,6 +312,11 @@ func NewGrantPrivilegeOption(roleName, objectType, privilegeName, objectName str
|
||||
}
|
||||
}
|
||||
|
||||
func (opt *grantPrivilegeOption) WithDbName(dbName string) *grantPrivilegeOption {
|
||||
opt.dbName = dbName
|
||||
return opt
|
||||
}
|
||||
|
||||
type RevokePrivilegeOption interface {
|
||||
Request() *milvuspb.OperatePrivilegeRequest
|
||||
}
|
||||
@ -312,6 +326,7 @@ type revokePrivilegeOption struct {
|
||||
privilegeName string
|
||||
objectName string
|
||||
objectType string
|
||||
dbName string
|
||||
}
|
||||
|
||||
func (opt *revokePrivilegeOption) Request() *milvuspb.OperatePrivilegeRequest {
|
||||
@ -325,6 +340,7 @@ func (opt *revokePrivilegeOption) Request() *milvuspb.OperatePrivilegeRequest {
|
||||
Name: opt.objectType,
|
||||
},
|
||||
ObjectName: opt.objectName,
|
||||
DbName: opt.dbName,
|
||||
},
|
||||
|
||||
Type: milvuspb.OperatePrivilegeType_Revoke,
|
||||
@ -340,6 +356,11 @@ func NewRevokePrivilegeOption(roleName, objectType, privilegeName, objectName st
|
||||
}
|
||||
}
|
||||
|
||||
func (opt *revokePrivilegeOption) WithDbName(dbName string) *revokePrivilegeOption {
|
||||
opt.dbName = dbName
|
||||
return opt
|
||||
}
|
||||
|
||||
type GrantV2Option GrantPrivilegeV2Option
|
||||
|
||||
// GrantPrivilegeV2Option is the interface builds OperatePrivilegeV2Request
|
||||
@ -368,10 +389,6 @@ func (opt *grantPrivilegeV2Option) Request() *milvuspb.OperatePrivilegeV2Request
|
||||
|
||||
// Deprecated, use `NewGrantPrivilegeV2Option` instead
|
||||
func NewGrantV2Option(roleName, privilegeName, dbName, collectionName string) *grantPrivilegeV2Option {
|
||||
return NewGrantPrivilegeV2Option(roleName, privilegeName, dbName, collectionName)
|
||||
}
|
||||
|
||||
func NewGrantPrivilegeV2Option(roleName, privilegeName, dbName, collectionName string) *grantPrivilegeV2Option {
|
||||
return &grantPrivilegeV2Option{
|
||||
roleName: roleName,
|
||||
privilegeName: privilegeName,
|
||||
@ -380,6 +397,19 @@ func NewGrantPrivilegeV2Option(roleName, privilegeName, dbName, collectionName s
|
||||
}
|
||||
}
|
||||
|
||||
func NewGrantPrivilegeV2Option(roleName, privilegeName, collectionName string) *grantPrivilegeV2Option {
|
||||
return &grantPrivilegeV2Option{
|
||||
roleName: roleName,
|
||||
privilegeName: privilegeName,
|
||||
collectionName: collectionName,
|
||||
}
|
||||
}
|
||||
|
||||
func (opt *grantPrivilegeV2Option) WithDbName(dbName string) *grantPrivilegeV2Option {
|
||||
opt.dbName = dbName
|
||||
return opt
|
||||
}
|
||||
|
||||
type RevokeV2Option RevokePrivilegeV2Option
|
||||
|
||||
// RevokePrivilegeV2Option is the interface builds OperatePrivilegeV2Request
|
||||
@ -406,6 +436,7 @@ func (opt *revokePrivilegeV2Option) Request() *milvuspb.OperatePrivilegeV2Reques
|
||||
}
|
||||
}
|
||||
|
||||
// Deprecated, use `NewRevokePrivilegeV2Option` instead
|
||||
func NewRevokeV2Option(roleName, privilegeName, dbName, collectionName string) *revokePrivilegeV2Option {
|
||||
return &revokePrivilegeV2Option{
|
||||
roleName: roleName,
|
||||
@ -415,6 +446,19 @@ func NewRevokeV2Option(roleName, privilegeName, dbName, collectionName string) *
|
||||
}
|
||||
}
|
||||
|
||||
func NewRevokePrivilegeV2Option(roleName, privilegeName, collectionName string) *revokePrivilegeV2Option {
|
||||
return &revokePrivilegeV2Option{
|
||||
roleName: roleName,
|
||||
privilegeName: privilegeName,
|
||||
collectionName: collectionName,
|
||||
}
|
||||
}
|
||||
|
||||
func (opt *revokePrivilegeV2Option) WithDbName(dbName string) *revokePrivilegeV2Option {
|
||||
opt.dbName = dbName
|
||||
return opt
|
||||
}
|
||||
|
||||
// CreatePrivilegeGroupOption is the interface builds CreatePrivilegeGroupRequest
|
||||
type CreatePrivilegeGroupOption interface {
|
||||
Request() *milvuspb.CreatePrivilegeGroupRequest
|
||||
|
||||
@ -320,6 +320,7 @@ func (s *RoleSuite) TestDescribeRole() {
|
||||
},
|
||||
Role: &milvuspb.RoleEntity{Name: roleName},
|
||||
Grantor: &milvuspb.GrantorEntity{User: &milvuspb.UserEntity{Name: "admin"}, Privilege: &milvuspb.PrivilegeEntity{Name: "Insert"}},
|
||||
DbName: "aaa",
|
||||
},
|
||||
{
|
||||
ObjectName: "*",
|
||||
@ -432,14 +433,14 @@ func (s *PrivilegeGroupSuite) TestGrantV2() {
|
||||
return merr.Success(), nil
|
||||
}).Once()
|
||||
|
||||
err := s.client.GrantV2(ctx, NewGrantV2Option(roleName, privilegeName, dbName, collectionName))
|
||||
err := s.client.GrantPrivilegeV2(ctx, NewGrantPrivilegeV2Option(roleName, privilegeName, collectionName).WithDbName(dbName))
|
||||
s.NoError(err)
|
||||
})
|
||||
|
||||
s.Run("failure", func() {
|
||||
s.mock.EXPECT().OperatePrivilegeV2(mock.Anything, mock.Anything).Return(nil, merr.WrapErrServiceInternal("mocked")).Once()
|
||||
|
||||
err := s.client.GrantV2(ctx, NewGrantV2Option(roleName, privilegeName, dbName, collectionName))
|
||||
err := s.client.GrantPrivilegeV2(ctx, NewGrantPrivilegeV2Option(roleName, privilegeName, collectionName).WithDbName(dbName))
|
||||
s.Error(err)
|
||||
})
|
||||
}
|
||||
@ -462,14 +463,14 @@ func (s *PrivilegeGroupSuite) TestRevokeV2() {
|
||||
return merr.Success(), nil
|
||||
}).Once()
|
||||
|
||||
err := s.client.RevokeV2(ctx, NewRevokeV2Option(roleName, privilegeName, dbName, collectionName))
|
||||
err := s.client.RevokePrivilegeV2(ctx, NewRevokePrivilegeV2Option(roleName, privilegeName, collectionName).WithDbName(dbName))
|
||||
s.NoError(err)
|
||||
})
|
||||
|
||||
s.Run("failure", func() {
|
||||
s.mock.EXPECT().OperatePrivilegeV2(mock.Anything, mock.Anything).Return(nil, merr.WrapErrServiceInternal("mocked")).Once()
|
||||
|
||||
err := s.client.RevokeV2(ctx, NewRevokeV2Option(roleName, privilegeName, dbName, collectionName))
|
||||
err := s.client.RevokePrivilegeV2(ctx, NewRevokePrivilegeV2Option(roleName, privilegeName, collectionName).WithDbName(dbName))
|
||||
s.Error(err)
|
||||
})
|
||||
}
|
||||
|
||||
@ -358,3 +358,98 @@ func (mc *MilvusClient) TransferReplica(ctx context.Context, option client.Trans
|
||||
err := mc.mClient.TransferReplica(ctx, option, callOptions...)
|
||||
return err
|
||||
}
|
||||
|
||||
func (mc *MilvusClient) CreateUser(ctx context.Context, option client.CreateUserOption, callOptions ...grpc.CallOption) error {
|
||||
err := mc.mClient.CreateUser(ctx, option, callOptions...)
|
||||
return err
|
||||
}
|
||||
|
||||
func (mc *MilvusClient) UpdatePassword(ctx context.Context, option client.UpdatePasswordOption, callOptions ...grpc.CallOption) error {
|
||||
err := mc.mClient.UpdatePassword(ctx, option, callOptions...)
|
||||
return err
|
||||
}
|
||||
|
||||
func (mc *MilvusClient) DropUser(ctx context.Context, option client.DropUserOption, callOptions ...grpc.CallOption) error {
|
||||
err := mc.mClient.DropUser(ctx, option, callOptions...)
|
||||
return err
|
||||
}
|
||||
|
||||
func (mc *MilvusClient) ListUsers(ctx context.Context, option client.ListUserOption, callOptions ...grpc.CallOption) ([]string, error) {
|
||||
users, err := mc.mClient.ListUsers(ctx, option, callOptions...)
|
||||
return users, err
|
||||
}
|
||||
|
||||
func (mc *MilvusClient) DescribeUser(ctx context.Context, option client.DescribeUserOption, callOptions ...grpc.CallOption) (*entity.User, error) {
|
||||
user, err := mc.mClient.DescribeUser(ctx, option, callOptions...)
|
||||
return user, err
|
||||
}
|
||||
|
||||
func (mc *MilvusClient) ListRoles(ctx context.Context, option client.ListRoleOption, callOptions ...grpc.CallOption) ([]string, error) {
|
||||
roles, err := mc.mClient.ListRoles(ctx, option, callOptions...)
|
||||
return roles, err
|
||||
}
|
||||
|
||||
func (mc *MilvusClient) CreateRole(ctx context.Context, option client.CreateRoleOption, callOptions ...grpc.CallOption) error {
|
||||
err := mc.mClient.CreateRole(ctx, option, callOptions...)
|
||||
return err
|
||||
}
|
||||
|
||||
func (mc *MilvusClient) GrantRole(ctx context.Context, option client.GrantRoleOption, callOptions ...grpc.CallOption) error {
|
||||
err := mc.mClient.GrantRole(ctx, option, callOptions...)
|
||||
return err
|
||||
}
|
||||
|
||||
func (mc *MilvusClient) RevokeRole(ctx context.Context, option client.RevokeRoleOption, callOptions ...grpc.CallOption) error {
|
||||
err := mc.mClient.RevokeRole(ctx, option, callOptions...)
|
||||
return err
|
||||
}
|
||||
|
||||
func (mc *MilvusClient) DropRole(ctx context.Context, option client.DropRoleOption, callOptions ...grpc.CallOption) error {
|
||||
err := mc.mClient.DropRole(ctx, option, callOptions...)
|
||||
return err
|
||||
}
|
||||
|
||||
func (mc *MilvusClient) DescribeRole(ctx context.Context, option client.DescribeRoleOption, callOptions ...grpc.CallOption) (*entity.Role, error) {
|
||||
role, err := mc.mClient.DescribeRole(ctx, option, callOptions...)
|
||||
return role, err
|
||||
}
|
||||
|
||||
func (mc *MilvusClient) GrantPrivilege(ctx context.Context, option client.GrantPrivilegeOption, callOptions ...grpc.CallOption) error {
|
||||
err := mc.mClient.GrantPrivilege(ctx, option, callOptions...)
|
||||
return err
|
||||
}
|
||||
|
||||
func (mc *MilvusClient) RevokePrivilege(ctx context.Context, option client.RevokePrivilegeOption, callOptions ...grpc.CallOption) error {
|
||||
err := mc.mClient.RevokePrivilege(ctx, option, callOptions...)
|
||||
return err
|
||||
}
|
||||
|
||||
func (mc *MilvusClient) GrantPrivilegeV2(ctx context.Context, option client.GrantPrivilegeV2Option, callOptions ...grpc.CallOption) error {
|
||||
err := mc.mClient.GrantPrivilegeV2(ctx, option, callOptions...)
|
||||
return err
|
||||
}
|
||||
|
||||
func (mc *MilvusClient) RevokePrivilegeV2(ctx context.Context, option client.RevokePrivilegeV2Option, callOptions ...grpc.CallOption) error {
|
||||
err := mc.mClient.RevokePrivilegeV2(ctx, option, callOptions...)
|
||||
return err
|
||||
}
|
||||
|
||||
func (mc *MilvusClient) CreatePrivilegeGroup(ctx context.Context, option client.CreatePrivilegeGroupOption, callOptions ...grpc.CallOption) error {
|
||||
err := mc.mClient.CreatePrivilegeGroup(ctx, option, callOptions...)
|
||||
return err
|
||||
}
|
||||
|
||||
func (mc *MilvusClient) DropPrivilegeGroup(ctx context.Context, option client.DropPrivilegeGroupOption, callOptions ...grpc.CallOption) error {
|
||||
err := mc.mClient.DropPrivilegeGroup(ctx, option, callOptions...)
|
||||
return err
|
||||
}
|
||||
|
||||
func (mc *MilvusClient) ListPrivilegeGroups(ctx context.Context, option client.ListPrivilegeGroupsOption, callOptions ...grpc.CallOption) ([]*entity.PrivilegeGroup, error) {
|
||||
privilegeGroups, err := mc.mClient.ListPrivilegeGroups(ctx, option, callOptions...)
|
||||
return privilegeGroups, err
|
||||
}
|
||||
|
||||
func (mc *MilvusClient) OperatePrivilegeGroup(ctx context.Context, option client.OperatePrivilegeGroupOption, callOptions ...grpc.CallOption) error {
|
||||
err := mc.mClient.OperatePrivilegeGroup(ctx, option, callOptions...)
|
||||
return err
|
||||
}
|
||||
|
||||
@ -94,7 +94,14 @@ const (
|
||||
DatabaseDiskQuotaMb = "database.diskQuota.mb"
|
||||
)
|
||||
|
||||
// const for full text search
|
||||
// DefaultTextLang const for full text search
|
||||
const (
|
||||
DefaultTextLang = "en"
|
||||
)
|
||||
|
||||
const (
|
||||
RootUser = "root"
|
||||
RootPwd = "Milvus"
|
||||
AdminRole = "admin"
|
||||
PublicRole = "public"
|
||||
)
|
||||
|
||||
@ -61,10 +61,14 @@ func GenInvalidNames() []string {
|
||||
" ",
|
||||
"(mn)",
|
||||
"中文",
|
||||
"シャオミン",
|
||||
"샤오밍",
|
||||
"ಸೂರ್ಯ",
|
||||
"%$#",
|
||||
"1",
|
||||
"[10]",
|
||||
"a b",
|
||||
"user@name",
|
||||
DefaultDynamicFieldName,
|
||||
GenLongString(MaxCollectionNameLen + 1),
|
||||
}
|
||||
|
||||
769
tests/go_client/testcases/advcases/rbac_test.go
Normal file
769
tests/go_client/testcases/advcases/rbac_test.go
Normal file
@ -0,0 +1,769 @@
|
||||
//go:build rbac
|
||||
|
||||
package advcases
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/samber/lo"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/milvus-io/milvus/client/v2/entity"
|
||||
"github.com/milvus-io/milvus/client/v2/index"
|
||||
client "github.com/milvus-io/milvus/client/v2/milvusclient"
|
||||
"github.com/milvus-io/milvus/pkg/v2/log"
|
||||
"github.com/milvus-io/milvus/tests/go_client/base"
|
||||
"github.com/milvus-io/milvus/tests/go_client/common"
|
||||
hp "github.com/milvus-io/milvus/tests/go_client/testcases/helper"
|
||||
)
|
||||
|
||||
const (
|
||||
CollectionObjectType = "Collection"
|
||||
GlobalObjectType = "Global"
|
||||
AllObjectName = "*"
|
||||
)
|
||||
|
||||
func resetRbac(t *testing.T, ctx context.Context, mc *base.MilvusClient) {
|
||||
t.Helper()
|
||||
userNames, _ := mc.ListUsers(ctx, client.NewListUserOption())
|
||||
for _, userName := range userNames {
|
||||
if userName != common.RootUser {
|
||||
err := mc.DropUser(ctx, client.NewDropUserOption(userName))
|
||||
common.CheckErr(t, err, true)
|
||||
}
|
||||
}
|
||||
roleNames, _ := mc.ListRoles(ctx, client.NewListRoleOption())
|
||||
for _, roleName := range roleNames {
|
||||
if lo.Contains([]string{common.AdminRole, common.PublicRole}, roleName) {
|
||||
continue
|
||||
}
|
||||
role, err := mc.DescribeRole(ctx, client.NewDescribeRoleOption(roleName).WithDbName("*"))
|
||||
common.CheckErr(t, err, true)
|
||||
if role.Privileges != nil {
|
||||
for _, grantItem := range role.Privileges {
|
||||
err := mc.RevokePrivilegeV2(ctx, client.NewRevokePrivilegeV2Option(roleName, grantItem.Privilege, grantItem.ObjectName).WithDbName(grantItem.DbName))
|
||||
common.CheckErr(t, err, true)
|
||||
}
|
||||
}
|
||||
err = mc.DropRole(ctx, client.NewDropRoleOption(roleName))
|
||||
common.CheckErr(t, err, true)
|
||||
}
|
||||
}
|
||||
|
||||
func setupTest(t *testing.T, ctx context.Context, mc *base.MilvusClient) {
|
||||
resetRbac(t, ctx, mc)
|
||||
t.Cleanup(func() {
|
||||
resetRbac(t, ctx, mc)
|
||||
})
|
||||
}
|
||||
|
||||
func TestRbacDefault(t *testing.T) {
|
||||
ctx := hp.CreateContext(t, time.Second*common.DefaultTimeout)
|
||||
mc := hp.CreateMilvusClient(ctx, t, &client.ClientConfig{Address: hp.GetAddr(), Username: hp.GetUser(), Password: hp.GetPassword()})
|
||||
_, schema := hp.CollPrepare.CreateCollection(ctx, t, mc, hp.NewCreateCollectionParams(hp.Int64Vec), hp.TNewFieldsOption(), hp.TNewSchemaOption())
|
||||
setupTest(t, ctx, mc)
|
||||
|
||||
// create user & list user
|
||||
userName := common.GenRandomString("user", 6)
|
||||
pwd := common.GenRandomString("pwd", 6)
|
||||
log.Info(t.Name(), zap.String("pwd", pwd))
|
||||
err := mc.CreateUser(ctx, client.NewCreateUserOption(userName, pwd))
|
||||
common.CheckErr(t, err, true)
|
||||
users, err := mc.ListUsers(ctx, client.NewListUserOption())
|
||||
common.CheckErr(t, err, true)
|
||||
require.Contains(t, users, userName)
|
||||
|
||||
// create role and list role
|
||||
roleName := common.GenRandomString("role", 6)
|
||||
errRole := mc.CreateRole(ctx, client.NewCreateRoleOption(roleName))
|
||||
common.CheckErr(t, errRole, true)
|
||||
roles, _ := mc.ListRoles(ctx, client.NewListRoleOption())
|
||||
require.Contains(t, roles, roleName)
|
||||
|
||||
// grant role to a user
|
||||
errGrant := mc.GrantRole(ctx, client.NewGrantRoleOption(userName, roleName))
|
||||
common.CheckErr(t, errGrant, true)
|
||||
|
||||
// create index not permission deny
|
||||
mcUser := hp.CreateMilvusClient(ctx, t, &client.ClientConfig{Address: hp.GetAddr(), Username: userName, Password: pwd})
|
||||
_, errIndex := mcUser.CreateIndex(ctx, client.NewCreateIndexOption(schema.CollectionName, common.DefaultFloatVecFieldName, index.NewAutoIndex(entity.COSINE)))
|
||||
log.Info("TestRbacDefault", zap.Error(errIndex))
|
||||
common.CheckErr(t, errIndex, false, fmt.Sprintf("permission deny to %s in the `default` database", userName))
|
||||
|
||||
// grant privilege to role
|
||||
errGrant = mc.GrantPrivilege(ctx, client.NewGrantPrivilegeOption(roleName, CollectionObjectType, "CreateIndex", AllObjectName))
|
||||
common.CheckErr(t, errGrant, true)
|
||||
log.Info("TestRbacDefault", zap.Error(errGrant))
|
||||
|
||||
// describe role
|
||||
role, _ := mc.DescribeRole(ctx, client.NewDescribeRoleOption(roleName))
|
||||
require.Equal(t, roleName, role.RoleName)
|
||||
expPrivilege := entity.GrantItem{
|
||||
Object: CollectionObjectType,
|
||||
ObjectName: AllObjectName,
|
||||
RoleName: roleName,
|
||||
Grantor: hp.GetUser(),
|
||||
Privilege: "CreateIndex",
|
||||
DbName: common.DefaultDb,
|
||||
}
|
||||
require.ElementsMatch(t, []entity.GrantItem{expPrivilege}, role.Privileges)
|
||||
|
||||
// describe user
|
||||
user, _ := mc.DescribeUser(ctx, client.NewDescribeUserOption(userName))
|
||||
common.CheckErr(t, err, true)
|
||||
require.Equal(t, &entity.User{UserName: userName, Roles: []string{roleName}}, user)
|
||||
|
||||
// check privilege effect
|
||||
require.Eventuallyf(t, func() bool {
|
||||
_, errIndex = mcUser.CreateIndex(ctx, client.NewCreateIndexOption(schema.CollectionName, common.DefaultFloatVecFieldName, index.NewAutoIndex(entity.COSINE)))
|
||||
return errIndex == nil
|
||||
}, time.Second*10, 2*time.Second, "Waiting for permission to take effect timed out")
|
||||
_, err = mcUser.LoadCollection(ctx, client.NewLoadCollectionOption(schema.CollectionName))
|
||||
common.CheckErr(t, err, false, fmt.Sprintf("permission deny to %s in the `default` database", userName))
|
||||
|
||||
// drop user, role, privilege
|
||||
errDrop := mc.DropUser(ctx, client.NewDropUserOption(userName))
|
||||
common.CheckErr(t, errDrop, true)
|
||||
errRevoke := mc.RevokePrivilege(ctx, client.NewRevokePrivilegeOption(roleName, CollectionObjectType, "CreateIndex", AllObjectName))
|
||||
common.CheckErr(t, errRevoke, true)
|
||||
errDrop = mc.DropRole(ctx, client.NewDropRoleOption(roleName))
|
||||
common.CheckErr(t, errDrop, true)
|
||||
}
|
||||
|
||||
func TestRbacDefaultV2(t *testing.T) {
|
||||
ctx := hp.CreateContext(t, time.Second*common.DefaultTimeout)
|
||||
mc := hp.CreateMilvusClient(ctx, t, &client.ClientConfig{Address: hp.GetAddr(), Username: hp.GetUser(), Password: hp.GetPassword()})
|
||||
_, schema := hp.CollPrepare.CreateCollection(ctx, t, mc, hp.NewCreateCollectionParams(hp.Int64Vec), hp.TNewFieldsOption(), hp.TNewSchemaOption())
|
||||
setupTest(t, ctx, mc)
|
||||
|
||||
// create user & list user
|
||||
userName := common.GenRandomString("user", 6)
|
||||
pwd := common.GenRandomString("pwd", 6)
|
||||
err := mc.CreateUser(ctx, client.NewCreateUserOption(userName, pwd))
|
||||
common.CheckErr(t, err, true)
|
||||
users, err := mc.ListUsers(ctx, client.NewListUserOption())
|
||||
common.CheckErr(t, err, true)
|
||||
require.Contains(t, users, userName)
|
||||
|
||||
// create role and list role
|
||||
roleName := common.GenRandomString("role", 6)
|
||||
errRole := mc.CreateRole(ctx, client.NewCreateRoleOption(roleName))
|
||||
common.CheckErr(t, errRole, true)
|
||||
roles, _ := mc.ListRoles(ctx, client.NewListRoleOption())
|
||||
require.Contains(t, roles, roleName)
|
||||
|
||||
// grant role to a user
|
||||
errGrant := mc.GrantRole(ctx, client.NewGrantRoleOption(userName, roleName))
|
||||
common.CheckErr(t, errGrant, true)
|
||||
|
||||
// describe collection but permission deny
|
||||
mcUser := hp.CreateMilvusClient(ctx, t, &client.ClientConfig{Address: hp.GetAddr(), Username: userName, Password: pwd})
|
||||
_, errFlush := mcUser.Flush(ctx, client.NewFlushOption(schema.CollectionName))
|
||||
log.Info("TestRbacDefault", zap.Error(errFlush))
|
||||
common.CheckErr(t, errFlush, false, fmt.Sprintf("permission deny to %s in the `default` database", userName))
|
||||
|
||||
// grant privilege to role
|
||||
errGrant = mc.GrantPrivilegeV2(ctx, client.NewGrantPrivilegeV2Option(roleName, "CollectionAdmin", AllObjectName))
|
||||
common.CheckErr(t, errGrant, true)
|
||||
|
||||
// describe role
|
||||
role, _ := mc.DescribeRole(ctx, client.NewDescribeRoleOption(roleName))
|
||||
require.Equal(t, roleName, role.RoleName)
|
||||
expPrivilege := entity.GrantItem{
|
||||
Object: GlobalObjectType,
|
||||
ObjectName: AllObjectName,
|
||||
RoleName: roleName,
|
||||
Grantor: hp.GetUser(),
|
||||
Privilege: "CollectionAdmin",
|
||||
DbName: common.DefaultDb,
|
||||
}
|
||||
require.ElementsMatch(t, []entity.GrantItem{expPrivilege}, role.Privileges)
|
||||
|
||||
// describe user
|
||||
user, _ := mc.DescribeUser(ctx, client.NewDescribeUserOption(userName))
|
||||
common.CheckErr(t, err, true)
|
||||
require.Equal(t, userName, user.UserName)
|
||||
require.ElementsMatch(t, []string{roleName}, user.Roles)
|
||||
|
||||
// check privilege effect
|
||||
require.Eventuallyf(t, func() bool {
|
||||
_, errFlush = mcUser.Flush(ctx, client.NewFlushOption(schema.CollectionName))
|
||||
return errFlush == nil
|
||||
}, time.Second*10, 2*time.Second, "Waiting for permission to take effect timed out")
|
||||
errDb := mcUser.CreateDatabase(ctx, client.NewCreateDatabaseOption("db1"))
|
||||
common.CheckErr(t, errDb, false, fmt.Sprintf("permission deny to %s in the `default` database", userName))
|
||||
|
||||
// drop user, role, privilege
|
||||
errDrop := mc.DropUser(ctx, client.NewDropUserOption(userName))
|
||||
common.CheckErr(t, errDrop, true)
|
||||
errRevoke := mc.RevokePrivilegeV2(ctx, client.NewRevokePrivilegeV2Option(roleName, "CollectionAdmin", "*"))
|
||||
common.CheckErr(t, errRevoke, true)
|
||||
errDrop = mc.DropRole(ctx, client.NewDropRoleOption(roleName))
|
||||
common.CheckErr(t, errDrop, true)
|
||||
}
|
||||
|
||||
func TestCreateInvalidUser(t *testing.T) {
|
||||
// root user & username must contain only numbers, letters and underscores
|
||||
ctx := hp.CreateContext(t, time.Second*common.DefaultTimeout)
|
||||
mc := hp.CreateMilvusClient(ctx, t, &client.ClientConfig{Address: hp.GetAddr(), Username: hp.GetUser(), Password: hp.GetPassword()})
|
||||
setupTest(t, ctx, mc)
|
||||
|
||||
invalidUserNames := common.GenInvalidNames()
|
||||
invalidUserNames = append(invalidUserNames, common.RootUser)
|
||||
// create user & list user
|
||||
for _, invalidName := range invalidUserNames {
|
||||
log.Info("name", zap.String("name", invalidName))
|
||||
err := mc.CreateUser(ctx, client.NewCreateUserOption(invalidName, "ccccccc"))
|
||||
common.CheckErr(t, err, false,
|
||||
"username must contain only numbers, letters and underscores",
|
||||
"username must be not empty", "user already exists",
|
||||
"the first character must be a letter",
|
||||
"the length of username must be less than %!d(string=32)")
|
||||
}
|
||||
|
||||
// user exists
|
||||
err := mc.CreateUser(ctx, client.NewCreateUserOption("user1", common.GenRandomString("p", 6)))
|
||||
common.CheckErr(t, err, true)
|
||||
err = mc.CreateUser(ctx, client.NewCreateUserOption("user1", common.GenRandomString("p", 6)))
|
||||
common.CheckErr(t, err, false, "user already exists")
|
||||
|
||||
// invalid password: range 6 <= value <= 256
|
||||
for _, invalidPwd := range []string{
|
||||
common.GenRandomString("p", 3),
|
||||
common.GenRandomString("p", 72),
|
||||
} {
|
||||
err := mc.CreateUser(ctx, client.NewCreateUserOption("aaa", invalidPwd))
|
||||
common.CheckErr(t, err, false, "out of range 6 <= value <= 72")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateUserLimit(t *testing.T) {
|
||||
ctx := hp.CreateContext(t, time.Second*common.DefaultTimeout)
|
||||
mc := hp.CreateMilvusClient(ctx, t, &client.ClientConfig{Address: hp.GetAddr(), Username: hp.GetUser(), Password: hp.GetPassword()})
|
||||
setupTest(t, ctx, mc)
|
||||
|
||||
// Limit to 100 users, including root
|
||||
userNumLimit := 100
|
||||
for i := 0; i < userNumLimit-1; i++ {
|
||||
err := mc.CreateUser(ctx, client.NewCreateUserOption(common.GenRandomString("user", 4), common.GenRandomString("p", 6)))
|
||||
common.CheckErr(t, err, true)
|
||||
}
|
||||
|
||||
err := mc.CreateUser(ctx, client.NewCreateUserOption(common.GenRandomString("user", 4), common.GenRandomString("p", 6)))
|
||||
common.CheckErr(t, err, false, "unable to add user because the number of users has reached the limit")
|
||||
|
||||
users, errList := mc.ListUsers(ctx, client.NewListUserOption())
|
||||
common.CheckErr(t, errList, true)
|
||||
require.Equal(t, userNumLimit, len(users))
|
||||
}
|
||||
|
||||
func TestUpdatePassword(t *testing.T) {
|
||||
ctx := hp.CreateContext(t, time.Second*common.DefaultTimeout)
|
||||
mc := hp.CreateMilvusClient(ctx, t, &client.ClientConfig{Address: hp.GetAddr(), Username: hp.GetUser(), Password: hp.GetPassword()})
|
||||
setupTest(t, ctx, mc)
|
||||
|
||||
userName := common.GenRandomString("user", 6)
|
||||
pwd := common.GenRandomString("pwd", 6)
|
||||
newPwd := common.GenRandomString("pwd", 6)
|
||||
err := mc.CreateUser(ctx, client.NewCreateUserOption(userName, pwd))
|
||||
common.CheckErr(t, err, true)
|
||||
|
||||
err = mc.UpdatePassword(ctx, client.NewUpdatePasswordOption(userName, pwd, newPwd))
|
||||
common.CheckErr(t, err, true)
|
||||
|
||||
mcUser := hp.CreateMilvusClient(ctx, t, &client.ClientConfig{Address: hp.GetAddr(), Username: userName, Password: newPwd})
|
||||
_, err = mcUser.ListCollections(ctx, client.NewListCollectionOption())
|
||||
common.CheckErr(t, err, true)
|
||||
|
||||
// update multi times with multi language
|
||||
oldPwd := newPwd
|
||||
passwords := []string{"中文", "シャオミン", "샤오밍", "ಸೂರ್ಯ", "myPwd@aa.com", "φεγγάρι", "mặt trăng"}
|
||||
for i := 0; i < len(passwords); i++ {
|
||||
log.Info(t.Name(), zap.String("pwd", passwords[i]))
|
||||
err = mc.UpdatePassword(ctx, client.NewUpdatePasswordOption(userName, oldPwd, passwords[i]))
|
||||
common.CheckErr(t, err, true)
|
||||
oldPwd = passwords[i]
|
||||
}
|
||||
|
||||
mcNewClient := hp.CreateMilvusClient(ctx, t, &client.ClientConfig{Address: hp.GetAddr(), Username: userName, Password: passwords[len(passwords)-1]})
|
||||
_, err = mcNewClient.ListCollections(ctx, client.NewListCollectionOption())
|
||||
common.CheckErr(t, err, true)
|
||||
}
|
||||
|
||||
func TestUpdatePasswordInvalid(t *testing.T) {
|
||||
ctx := hp.CreateContext(t, time.Second*common.DefaultTimeout)
|
||||
mc := hp.CreateMilvusClient(ctx, t, &client.ClientConfig{Address: hp.GetAddr(), Username: hp.GetUser(), Password: hp.GetPassword()})
|
||||
setupTest(t, ctx, mc)
|
||||
|
||||
userName := common.GenRandomString("user", 6)
|
||||
pwd := common.GenRandomString("pwd", 6)
|
||||
newPwd := common.GenRandomString("pwd", 6)
|
||||
err := mc.CreateUser(ctx, client.NewCreateUserOption(userName, pwd))
|
||||
common.CheckErr(t, err, true)
|
||||
|
||||
for _, invalidPwd := range []string{"", "_", "(mn)", "1 ", "]]", "*&%@"} {
|
||||
err := mc.UpdatePassword(ctx, client.NewUpdatePasswordOption(userName, pwd, invalidPwd))
|
||||
common.CheckErr(t, err, false,
|
||||
"out of range 6 <= value <= 72")
|
||||
}
|
||||
// not existed user
|
||||
err = mc.UpdatePassword(ctx, client.NewUpdatePasswordOption(common.GenRandomString("user", 6), pwd, newPwd))
|
||||
common.CheckErr(t, err, false, "old password not correct for")
|
||||
|
||||
// wrong old pwd
|
||||
err = mc.UpdatePassword(ctx, client.NewUpdatePasswordOption(userName, newPwd, newPwd))
|
||||
common.CheckErr(t, err, false, "old password not correct for")
|
||||
|
||||
// new pwd = old pwd
|
||||
err = mc.UpdatePassword(ctx, client.NewUpdatePasswordOption(userName, pwd, pwd))
|
||||
common.CheckErr(t, err, true)
|
||||
}
|
||||
|
||||
func TestDropUser(t *testing.T) {
|
||||
ctx := hp.CreateContext(t, time.Second*common.DefaultTimeout)
|
||||
mc := hp.CreateMilvusClient(ctx, t, &client.ClientConfig{Address: hp.GetAddr(), Username: hp.GetUser(), Password: hp.GetPassword()})
|
||||
setupTest(t, ctx, mc)
|
||||
|
||||
userName := common.GenRandomString("user", 6)
|
||||
pwd := common.GenRandomString("pwd", 6)
|
||||
roleName := common.GenRandomString("role", 6)
|
||||
err := mc.CreateUser(ctx, client.NewCreateUserOption(userName, pwd))
|
||||
common.CheckErr(t, err, true)
|
||||
err = mc.CreateRole(ctx, client.NewCreateRoleOption(roleName))
|
||||
common.CheckErr(t, err, true)
|
||||
err = mc.GrantRole(ctx, client.NewGrantRoleOption(userName, roleName))
|
||||
common.CheckErr(t, err, true)
|
||||
err = mc.GrantPrivilegeV2(ctx, client.NewGrantPrivilegeV2Option(roleName, "CollectionAdmin", AllObjectName))
|
||||
common.CheckErr(t, err, true)
|
||||
|
||||
// drop user that bind with role
|
||||
err = mc.DropUser(ctx, client.NewDropUserOption(userName))
|
||||
common.CheckErr(t, err, true)
|
||||
|
||||
// drop not existed user
|
||||
err = mc.DropUser(ctx, client.NewDropUserOption(userName))
|
||||
common.CheckErr(t, err, true)
|
||||
|
||||
// delete root user
|
||||
err = mc.DropUser(ctx, client.NewDropUserOption(common.RootUser))
|
||||
common.CheckErr(t, err, false, "root user cannot be deleted")
|
||||
}
|
||||
|
||||
func TestCreateRoleLimit(t *testing.T) {
|
||||
ctx := hp.CreateContext(t, time.Second*common.DefaultTimeout)
|
||||
mc := hp.CreateMilvusClient(ctx, t, &client.ClientConfig{Address: hp.GetAddr(), Username: hp.GetUser(), Password: hp.GetPassword()})
|
||||
setupTest(t, ctx, mc)
|
||||
|
||||
// Limit to 10 roles, including admin & public
|
||||
roleNumLimit := 10
|
||||
for i := 0; i < roleNumLimit-2; i++ {
|
||||
err := mc.CreateRole(ctx, client.NewCreateRoleOption(common.GenRandomString("role", 4)))
|
||||
common.CheckErr(t, err, true)
|
||||
}
|
||||
err := mc.CreateRole(ctx, client.NewCreateRoleOption(common.GenRandomString("role", 4)))
|
||||
common.CheckErr(t, err, false, "unable to create role because the number of roles has reached the limit")
|
||||
|
||||
roles, errList := mc.ListRoles(ctx, client.NewListRoleOption())
|
||||
common.CheckErr(t, errList, true)
|
||||
require.Equal(t, roleNumLimit, len(roles))
|
||||
}
|
||||
|
||||
func TestCreateInvalidRole(t *testing.T) {
|
||||
ctx := hp.CreateContext(t, time.Second*common.DefaultTimeout)
|
||||
mc := hp.CreateMilvusClient(ctx, t, &client.ClientConfig{Address: hp.GetAddr(), Username: hp.GetUser(), Password: hp.GetPassword()})
|
||||
setupTest(t, ctx, mc)
|
||||
|
||||
invalidNames := common.GenInvalidNames()
|
||||
|
||||
// create user & list user
|
||||
for _, invalidName := range invalidNames {
|
||||
log.Info("name", zap.String("name", invalidName))
|
||||
err := mc.CreateRole(ctx, client.NewCreateRoleOption(invalidName))
|
||||
common.CheckErr(t, err, false,
|
||||
"role name can only contain numbers, letters, dollars and underscores",
|
||||
"role name should be not empty",
|
||||
"the first character of role name must be an underscore or letter",
|
||||
"the length of role name must be not greater than limit")
|
||||
}
|
||||
|
||||
// role exists
|
||||
roleName := common.GenRandomString("role", 4)
|
||||
err := mc.CreateRole(ctx, client.NewCreateRoleOption(roleName))
|
||||
common.CheckErr(t, err, true)
|
||||
err = mc.CreateRole(ctx, client.NewCreateRoleOption(roleName))
|
||||
common.CheckErr(t, err, false, "already exists")
|
||||
|
||||
// create admin or public role
|
||||
for _, roleName := range []string{common.AdminRole, common.PublicRole} {
|
||||
err := mc.CreateRole(ctx, client.NewCreateRoleOption(roleName))
|
||||
common.CheckErr(t, err, false, "already exists")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDropRoleBindUser(t *testing.T) {
|
||||
ctx := hp.CreateContext(t, time.Second*common.DefaultTimeout)
|
||||
mc := hp.CreateMilvusClient(ctx, t, &client.ClientConfig{Address: hp.GetAddr(), Username: hp.GetUser(), Password: hp.GetPassword()})
|
||||
setupTest(t, ctx, mc)
|
||||
|
||||
userName := common.GenRandomString("user", 6)
|
||||
err := mc.CreateUser(ctx, client.NewCreateUserOption(userName, common.GenRandomString("pwd", 6)))
|
||||
common.CheckErr(t, err, true)
|
||||
|
||||
roleName := common.GenRandomString("role", 6)
|
||||
err = mc.CreateRole(ctx, client.NewCreateRoleOption(roleName))
|
||||
common.CheckErr(t, err, true)
|
||||
|
||||
err = mc.DropRole(ctx, client.NewDropRoleOption(roleName))
|
||||
common.CheckErr(t, err, true)
|
||||
|
||||
// drop not existed role
|
||||
err = mc.DropRole(ctx, client.NewDropRoleOption(roleName))
|
||||
common.CheckErr(t, err, false, "not found the role, maybe the role isn't existed or internal system error")
|
||||
|
||||
// drop admin or public role
|
||||
for _, roleName := range []string{common.AdminRole, common.PublicRole} {
|
||||
err = mc.DropRole(ctx, client.NewDropRoleOption(roleName))
|
||||
common.CheckErr(t, err, false, "is a default role, which can't be dropped")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDropRoleBindPrivilege(t *testing.T) {
|
||||
ctx := hp.CreateContext(t, time.Second*common.DefaultTimeout)
|
||||
mc := hp.CreateMilvusClient(ctx, t, &client.ClientConfig{Address: hp.GetAddr(), Username: hp.GetUser(), Password: hp.GetPassword()})
|
||||
setupTest(t, ctx, mc)
|
||||
|
||||
roleName := common.GenRandomString("role", 6)
|
||||
err := mc.CreateRole(ctx, client.NewCreateRoleOption(roleName))
|
||||
common.CheckErr(t, err, true)
|
||||
|
||||
err = mc.GrantPrivilegeV2(ctx, client.NewGrantPrivilegeV2Option(roleName, "CollectionAdmin", AllObjectName))
|
||||
common.CheckErr(t, err, true)
|
||||
|
||||
err = mc.DropRole(ctx, client.NewDropRoleOption(roleName))
|
||||
common.CheckErr(t, err, false, "fail to drop the role that it has privileges")
|
||||
|
||||
// revoke privilege -> drop role
|
||||
err = mc.RevokePrivilegeV2(ctx, client.NewRevokePrivilegeV2Option(roleName, "CollectionAdmin", AllObjectName))
|
||||
common.CheckErr(t, err, true)
|
||||
|
||||
err = mc.DropRole(ctx, client.NewDropRoleOption(roleName))
|
||||
common.CheckErr(t, err, true)
|
||||
}
|
||||
|
||||
func TestDescribeRole(t *testing.T) {
|
||||
ctx := hp.CreateContext(t, time.Second*common.DefaultTimeout)
|
||||
mc := hp.CreateMilvusClient(ctx, t, &client.ClientConfig{Address: hp.GetAddr(), Username: hp.GetUser(), Password: hp.GetPassword()})
|
||||
resetRbac(t, ctx, mc)
|
||||
|
||||
// describe role that no grants
|
||||
roleName := common.GenRandomString("role", 6)
|
||||
err := mc.CreateRole(ctx, client.NewCreateRoleOption(roleName))
|
||||
common.CheckErr(t, err, true)
|
||||
role, err := mc.DescribeRole(ctx, client.NewDescribeRoleOption(roleName))
|
||||
common.CheckErr(t, err, true)
|
||||
require.Equal(t, &entity.Role{RoleName: roleName, Privileges: []entity.GrantItem{}}, role)
|
||||
|
||||
// describe role that has grants
|
||||
err = mc.GrantPrivilegeV2(ctx, client.NewGrantPrivilegeV2Option(roleName, "DatabaseAdmin", AllObjectName))
|
||||
common.CheckErr(t, err, true)
|
||||
|
||||
err = mc.GrantPrivilegeV2(ctx, client.NewGrantPrivilegeV2Option(roleName, "ClusterAdmin", AllObjectName).WithDbName(AllObjectName))
|
||||
common.CheckErr(t, err, true)
|
||||
|
||||
role, err = mc.DescribeRole(ctx, client.NewDescribeRoleOption(roleName))
|
||||
common.CheckErr(t, err, true)
|
||||
expRole := &entity.Role{
|
||||
RoleName: roleName,
|
||||
Privileges: []entity.GrantItem{
|
||||
{
|
||||
Object: GlobalObjectType,
|
||||
ObjectName: AllObjectName,
|
||||
RoleName: roleName,
|
||||
Grantor: hp.GetUser(),
|
||||
Privilege: "ClusterAdmin",
|
||||
DbName: AllObjectName,
|
||||
},
|
||||
{
|
||||
Object: GlobalObjectType,
|
||||
ObjectName: AllObjectName,
|
||||
RoleName: roleName,
|
||||
Grantor: hp.GetUser(),
|
||||
Privilege: "DatabaseAdmin",
|
||||
DbName: common.DefaultDb,
|
||||
},
|
||||
},
|
||||
}
|
||||
require.EqualValues(t, expRole, role)
|
||||
|
||||
// describe a not existed role
|
||||
role, err = mc.DescribeRole(ctx, client.NewDescribeRoleOption(common.GenRandomString("role", 6)))
|
||||
common.CheckErr(t, err, false, "role not found")
|
||||
}
|
||||
|
||||
// grant v2 use connected db as default db
|
||||
func TestGrantV2PrivilegeConnectedDb(t *testing.T) {
|
||||
t.Skip("https://github.com/milvus-io/milvus/issues/40340")
|
||||
ctx := hp.CreateContext(t, time.Second*common.DefaultTimeout)
|
||||
mc := hp.CreateMilvusClient(ctx, t, &client.ClientConfig{Address: hp.GetAddr(), Username: hp.GetUser(), Password: hp.GetPassword()})
|
||||
resetRbac(t, ctx, mc)
|
||||
|
||||
// create a user
|
||||
userName := common.GenRandomString("user", 6)
|
||||
pwd := common.GenRandomString("pwd", 6)
|
||||
err := mc.CreateUser(ctx, client.NewCreateUserOption(userName, pwd))
|
||||
common.CheckErr(t, err, true)
|
||||
|
||||
// create a database
|
||||
dbName := common.GenRandomString("db", 6)
|
||||
err = mc.CreateDatabase(ctx, client.NewCreateDatabaseOption(dbName))
|
||||
common.CheckErr(t, err, true)
|
||||
|
||||
// init client with new db
|
||||
mcDb := hp.CreateMilvusClient(ctx, t, &client.ClientConfig{Address: hp.GetAddr(), Username: hp.GetUser(), Password: hp.GetPassword(), DBName: dbName})
|
||||
|
||||
// create a role
|
||||
roleName := common.GenRandomString("role", 6)
|
||||
err = mcDb.CreateRole(ctx, client.NewCreateRoleOption(roleName))
|
||||
common.CheckErr(t, err, true)
|
||||
|
||||
err = mcDb.GrantPrivilegeV2(ctx, client.NewGrantPrivilegeV2Option(roleName, "CollectionAdmin", AllObjectName))
|
||||
common.CheckErr(t, err, true)
|
||||
|
||||
// describe role and check privilege
|
||||
role, err := mcDb.DescribeRole(ctx, client.NewDescribeRoleOption(roleName))
|
||||
common.CheckErr(t, err, true)
|
||||
require.Equal(t, &entity.Role{
|
||||
RoleName: roleName,
|
||||
Privileges: []entity.GrantItem{
|
||||
{
|
||||
Object: GlobalObjectType,
|
||||
ObjectName: AllObjectName,
|
||||
RoleName: roleName,
|
||||
Grantor: hp.GetUser(),
|
||||
Privilege: "CollectionAdmin",
|
||||
DbName: dbName,
|
||||
},
|
||||
},
|
||||
}, role)
|
||||
}
|
||||
|
||||
// grant v2 use connected db as default db
|
||||
func TestGrantV2PrivilegeSpecifyDb(t *testing.T) {
|
||||
ctx := hp.CreateContext(t, time.Second*common.DefaultTimeout)
|
||||
mc := hp.CreateMilvusClient(ctx, t, &client.ClientConfig{Address: hp.GetAddr(), Username: hp.GetUser(), Password: hp.GetPassword()})
|
||||
resetRbac(t, ctx, mc)
|
||||
|
||||
// create a user
|
||||
userName := common.GenRandomString("user", 6)
|
||||
pwd := common.GenRandomString("pwd", 6)
|
||||
err := mc.CreateUser(ctx, client.NewCreateUserOption(userName, pwd))
|
||||
common.CheckErr(t, err, true)
|
||||
|
||||
// create a database
|
||||
dbName := common.GenRandomString("db", 6)
|
||||
err = mc.CreateDatabase(ctx, client.NewCreateDatabaseOption(dbName))
|
||||
common.CheckErr(t, err, true)
|
||||
|
||||
// create a role
|
||||
roleName := common.GenRandomString("role", 6)
|
||||
err = mc.CreateRole(ctx, client.NewCreateRoleOption(roleName))
|
||||
common.CheckErr(t, err, true)
|
||||
|
||||
err = mc.GrantPrivilegeV2(ctx, client.NewGrantPrivilegeV2Option(roleName, "CollectionAdmin", AllObjectName).WithDbName(dbName))
|
||||
common.CheckErr(t, err, true)
|
||||
|
||||
// describe role and check privilege
|
||||
role, err := mc.DescribeRole(ctx, client.NewDescribeRoleOption(roleName))
|
||||
common.CheckErr(t, err, true)
|
||||
require.Equal(t, role, &entity.Role{RoleName: roleName, Privileges: []entity.GrantItem{}})
|
||||
|
||||
roleDb, errDb := mc.DescribeRole(ctx, client.NewDescribeRoleOption(roleName).WithDbName(dbName))
|
||||
common.CheckErr(t, errDb, true)
|
||||
require.Equal(t, &entity.Role{
|
||||
RoleName: roleName,
|
||||
Privileges: []entity.GrantItem{
|
||||
{
|
||||
Object: GlobalObjectType,
|
||||
ObjectName: AllObjectName,
|
||||
RoleName: roleName,
|
||||
Grantor: hp.GetUser(),
|
||||
Privilege: "CollectionAdmin",
|
||||
DbName: dbName,
|
||||
},
|
||||
},
|
||||
}, roleDb)
|
||||
}
|
||||
|
||||
// grant use connected db as default db
|
||||
func TestGrantPrivilegeConnectedDb(t *testing.T) {
|
||||
ctx := hp.CreateContext(t, time.Second*common.DefaultTimeout)
|
||||
mc := hp.CreateMilvusClient(ctx, t, &client.ClientConfig{Address: hp.GetAddr(), Username: hp.GetUser(), Password: hp.GetPassword()})
|
||||
resetRbac(t, ctx, mc)
|
||||
|
||||
// create a user
|
||||
userName := common.GenRandomString("user", 6)
|
||||
pwd := common.GenRandomString("pwd", 6)
|
||||
err := mc.CreateUser(ctx, client.NewCreateUserOption(userName, pwd))
|
||||
common.CheckErr(t, err, true)
|
||||
|
||||
// create a database
|
||||
dbName := common.GenRandomString("db", 6)
|
||||
err = mc.CreateDatabase(ctx, client.NewCreateDatabaseOption(dbName))
|
||||
common.CheckErr(t, err, true)
|
||||
|
||||
// init client with new db
|
||||
mcDb := hp.CreateMilvusClient(ctx, t, &client.ClientConfig{Address: hp.GetAddr(), Username: hp.GetUser(), Password: hp.GetPassword(), DBName: dbName})
|
||||
|
||||
// create a role
|
||||
roleName := common.GenRandomString("role", 6)
|
||||
err = mcDb.CreateRole(ctx, client.NewCreateRoleOption(roleName))
|
||||
common.CheckErr(t, err, true)
|
||||
|
||||
err = mcDb.GrantPrivilege(ctx, client.NewGrantPrivilegeOption(roleName, "Collection", "Insert", "*"))
|
||||
common.CheckErr(t, err, true)
|
||||
|
||||
// describe role and check privilege
|
||||
role, err := mcDb.DescribeRole(ctx, client.NewDescribeRoleOption(roleName))
|
||||
common.CheckErr(t, err, true)
|
||||
require.Equal(t, &entity.Role{
|
||||
RoleName: roleName,
|
||||
Privileges: []entity.GrantItem{
|
||||
{
|
||||
Object: CollectionObjectType,
|
||||
ObjectName: AllObjectName,
|
||||
RoleName: roleName,
|
||||
Grantor: hp.GetUser(),
|
||||
Privilege: "Insert",
|
||||
DbName: dbName,
|
||||
},
|
||||
},
|
||||
}, role)
|
||||
}
|
||||
|
||||
// grant v2 use connected db as default db
|
||||
func TestGrantPrivilegeSpecifyDb(t *testing.T) {
|
||||
ctx := hp.CreateContext(t, time.Second*common.DefaultTimeout)
|
||||
mc := hp.CreateMilvusClient(ctx, t, &client.ClientConfig{Address: hp.GetAddr(), Username: hp.GetUser(), Password: hp.GetPassword()})
|
||||
resetRbac(t, ctx, mc)
|
||||
|
||||
// create a user
|
||||
userName := common.GenRandomString("user", 6)
|
||||
pwd := common.GenRandomString("pwd", 6)
|
||||
err := mc.CreateUser(ctx, client.NewCreateUserOption(userName, pwd))
|
||||
common.CheckErr(t, err, true)
|
||||
|
||||
// create a database
|
||||
dbName := common.GenRandomString("db", 6)
|
||||
err = mc.CreateDatabase(ctx, client.NewCreateDatabaseOption(dbName))
|
||||
common.CheckErr(t, err, true)
|
||||
|
||||
// create a role
|
||||
roleName := common.GenRandomString("role", 6)
|
||||
err = mc.CreateRole(ctx, client.NewCreateRoleOption(roleName))
|
||||
common.CheckErr(t, err, true)
|
||||
|
||||
err = mc.GrantPrivilege(ctx, client.NewGrantPrivilegeOption(roleName, "Collection", "Insert", "*").WithDbName(dbName))
|
||||
common.CheckErr(t, err, true)
|
||||
|
||||
// describe role and check privilege
|
||||
role, err := mc.DescribeRole(ctx, client.NewDescribeRoleOption(roleName))
|
||||
common.CheckErr(t, err, true)
|
||||
require.Equal(t, role, &entity.Role{RoleName: roleName, Privileges: []entity.GrantItem{}})
|
||||
|
||||
roleDb, errDb := mc.DescribeRole(ctx, client.NewDescribeRoleOption(roleName).WithDbName(dbName))
|
||||
common.CheckErr(t, errDb, true)
|
||||
require.Equal(t, &entity.Role{
|
||||
RoleName: roleName,
|
||||
Privileges: []entity.GrantItem{
|
||||
{
|
||||
Object: CollectionObjectType,
|
||||
ObjectName: AllObjectName,
|
||||
RoleName: roleName,
|
||||
Grantor: hp.GetUser(),
|
||||
Privilege: "Insert",
|
||||
DbName: dbName,
|
||||
},
|
||||
},
|
||||
}, roleDb)
|
||||
}
|
||||
|
||||
func TestGrantPrivilegeInvalid(t *testing.T) {
|
||||
ctx := hp.CreateContext(t, time.Second*common.DefaultTimeout)
|
||||
mc := hp.CreateMilvusClient(ctx, t, &client.ClientConfig{Address: hp.GetAddr(), Username: hp.GetUser(), Password: hp.GetPassword()})
|
||||
// resetRbac(t, ctx, mc)
|
||||
|
||||
// create a role
|
||||
roleName := common.GenRandomString("role", 6)
|
||||
err := mc.CreateRole(ctx, client.NewCreateRoleOption(roleName))
|
||||
common.CheckErr(t, err, true)
|
||||
|
||||
// grant privilege to a not existed role
|
||||
err = mc.GrantPrivilege(ctx, client.NewGrantPrivilegeOption(common.GenRandomString("role", 6), "Collection", "Insert", "*"))
|
||||
common.CheckErr(t, err, false, "not found the role")
|
||||
err = mc.GrantPrivilegeV2(ctx, client.NewGrantPrivilegeV2Option(common.GenRandomString("role", 6), "CollectionAdmin", "*"))
|
||||
common.CheckErr(t, err, false, "not found the role")
|
||||
|
||||
// grant privilege to a not existed objectName
|
||||
err = mc.GrantPrivilege(ctx, client.NewGrantPrivilegeOption(roleName, "Collection", "Insert", common.GenRandomString("collection", 6)))
|
||||
common.CheckErr(t, err, true)
|
||||
err = mc.GrantPrivilegeV2(ctx, client.NewGrantPrivilegeV2Option(roleName, "CollectionAdmin", common.GenRandomString("collection", 6)))
|
||||
common.CheckErr(t, err, true)
|
||||
|
||||
// grant privilege to a not existed privilege
|
||||
err = mc.GrantPrivilege(ctx, client.NewGrantPrivilegeOption(roleName, "Collection", "aaa", "*"))
|
||||
common.CheckErr(t, err, false, "not found the privilege name")
|
||||
err = mc.GrantPrivilegeV2(ctx, client.NewGrantPrivilegeV2Option(roleName, "aaa", "*"))
|
||||
common.CheckErr(t, err, false, "not found the privilege name")
|
||||
|
||||
// grant privilege to a not existed objectType
|
||||
err = mc.GrantPrivilege(ctx, client.NewGrantPrivilegeOption(roleName, "aaa", "Insert", "*"))
|
||||
common.CheckErr(t, err, false, "the object entity in the request is nil or invalid")
|
||||
|
||||
// grant privilege to a not existed db
|
||||
err = mc.GrantPrivilege(ctx, client.NewGrantPrivilegeOption(roleName, "Collection", "Insert", "*").WithDbName(common.GenRandomString("db", 6)))
|
||||
common.CheckErr(t, err, true)
|
||||
err = mc.GrantPrivilegeV2(ctx, client.NewGrantPrivilegeV2Option(roleName, "CollectionAdmin", "*").WithDbName(common.GenRandomString("db", 6)))
|
||||
common.CheckErr(t, err, true)
|
||||
}
|
||||
|
||||
func TestRevokePrivilegeInvalid(t *testing.T) {
|
||||
ctx := hp.CreateContext(t, time.Second*common.DefaultTimeout)
|
||||
mc := hp.CreateMilvusClient(ctx, t, &client.ClientConfig{Address: hp.GetAddr(), Username: hp.GetUser(), Password: hp.GetPassword()})
|
||||
resetRbac(t, ctx, mc)
|
||||
|
||||
roleName := common.GenRandomString("role", 6)
|
||||
err := mc.CreateRole(ctx, client.NewCreateRoleOption(roleName))
|
||||
common.CheckErr(t, err, true)
|
||||
|
||||
// revoke privilege to a not existed role
|
||||
err = mc.RevokePrivilege(ctx, client.NewRevokePrivilegeOption(common.GenRandomString("role", 6), "Collection", "Insert", "*"))
|
||||
common.CheckErr(t, err, false, "not found the role")
|
||||
err = mc.RevokePrivilegeV2(ctx, client.NewRevokePrivilegeV2Option(common.GenRandomString("role", 6), "CollectionAdmin", "*"))
|
||||
common.CheckErr(t, err, false, "not found the role")
|
||||
|
||||
// revoke privilege to a not existed objectName
|
||||
err = mc.RevokePrivilege(ctx, client.NewRevokePrivilegeOption(roleName, "Collection", "Insert", "*"))
|
||||
common.CheckErr(t, err, true)
|
||||
err = mc.RevokePrivilegeV2(ctx, client.NewRevokePrivilegeV2Option(roleName, "CollectionAdmin", common.GenRandomString("collection", 6)))
|
||||
common.CheckErr(t, err, true)
|
||||
|
||||
// revoke privilege to a not existed privilege
|
||||
err = mc.RevokePrivilege(ctx, client.NewRevokePrivilegeOption(roleName, "Collection", "aaa", "*"))
|
||||
common.CheckErr(t, err, false, "not found the privilege name")
|
||||
err = mc.RevokePrivilegeV2(ctx, client.NewRevokePrivilegeV2Option(roleName, "aaa", "*"))
|
||||
common.CheckErr(t, err, false, "not found the privilege name")
|
||||
|
||||
// revoke privilege to a not existed objectType
|
||||
err = mc.RevokePrivilege(ctx, client.NewRevokePrivilegeOption(roleName, "aaa", "Insert", "*"))
|
||||
common.CheckErr(t, err, false, "the object entity in the request is nil or invalid")
|
||||
|
||||
// revoke privilege to a not existed db
|
||||
err = mc.RevokePrivilege(ctx, client.NewRevokePrivilegeOption(roleName, "Collection", "Insert", "*").WithDbName(common.GenRandomString("db", 6)))
|
||||
common.CheckErr(t, err, true)
|
||||
err = mc.RevokePrivilegeV2(ctx, client.NewRevokePrivilegeV2Option(roleName, "CollectionAdmin", "*").WithDbName(common.GenRandomString("db", 6)))
|
||||
common.CheckErr(t, err, true)
|
||||
}
|
||||
@ -16,6 +16,8 @@ import (
|
||||
|
||||
var (
|
||||
addr = flag.String("addr", "localhost:19530", "server host and port")
|
||||
user = flag.String("user", "root", "user")
|
||||
password = flag.String("password", "Milvus", "password")
|
||||
logLevel = flag.String("log.level", "info", "log level for test")
|
||||
defaultClientConfig *client.ClientConfig
|
||||
)
|
||||
@ -32,6 +34,14 @@ func GetAddr() string {
|
||||
return *addr
|
||||
}
|
||||
|
||||
func GetUser() string {
|
||||
return *user
|
||||
}
|
||||
|
||||
func GetPassword() string {
|
||||
return *password
|
||||
}
|
||||
|
||||
func parseLogConfig() {
|
||||
log.Info("Parser Log Level", zap.String("logLevel", *logLevel))
|
||||
switch *logLevel {
|
||||
@ -63,7 +73,7 @@ func teardown() {
|
||||
log.Info("Start to tear down all.....")
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*common.DefaultTimeout)
|
||||
defer cancel()
|
||||
mc, err := base.NewMilvusClient(ctx, defaultClientConfig)
|
||||
mc, err := base.NewMilvusClient(ctx, &client.ClientConfig{Address: GetAddr(), Username: GetUser(), Password: GetPassword()})
|
||||
if err != nil {
|
||||
log.Error("teardown failed to connect milvus with error", zap.Error(err))
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user