feat: Authorize users to query grant info of their roles (#29747)

Once a role is granted to a user, the user should automatically possess
the privilege information associated with that role.

issue: #29710

Signed-off-by: zhenshan.cao <zhenshan.cao@zilliz.com>
pull/29683/head
zhenshan.cao 2024-01-08 15:10:49 +08:00 committed by GitHub
parent fe47deebf3
commit 7e6f73a12d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 37 additions and 1 deletions

View File

@ -15,6 +15,7 @@ import (
"google.golang.org/grpc/status"
"github.com/milvus-io/milvus-proto/go-api/v2/commonpb"
"github.com/milvus-io/milvus-proto/go-api/v2/milvuspb"
"github.com/milvus-io/milvus/pkg/log"
"github.com/milvus-io/milvus/pkg/util"
"github.com/milvus-io/milvus/pkg/util/funcutil"
@ -113,6 +114,11 @@ func PrivilegeInterceptor(ctx context.Context, req interface{}) (context.Context
if isCurUserObject(objectType, username, objectName) {
return ctx, nil
}
if isSelectMyRoleGrants(req, roleNames) {
return ctx, nil
}
objectNameIndexs := privilegeExt.ObjectNameIndexs
objectNames := funcutil.GetObjectNames(req, objectNameIndexs)
objectPrivilege := privilegeExt.ObjectPrivilege.String()
@ -181,6 +187,16 @@ func isCurUserObject(objectType string, curUser string, object string) bool {
return curUser == object
}
func isSelectMyRoleGrants(req interface{}, roleNames []string) bool {
selectGrantReq, ok := req.(*milvuspb.SelectGrantRequest)
if !ok {
return false
}
filterGrantEntity := selectGrantReq.GetEntity()
roleName := filterGrantEntity.GetRole().GetName()
return funcutil.SliceContain(roleNames, roleName)
}
func DBMatchFunc(args ...interface{}) (interface{}, error) {
name1 := args[0].(string)
name2 := args[1].(string)

View File

@ -3004,6 +3004,9 @@ class TestUtilityRBAC(TestcaseBase):
r_name = cf.gen_unique_str(prefix)
c_name = cf.gen_unique_str(prefix)
u, _ = self.utility_wrap.create_user(user=user, password=password)
user2 = cf.gen_unique_str(prefix)
u2, _ = self.utility_wrap.create_user(user=user2, password=password)
self.utility_wrap.init_role(r_name)
self.utility_wrap.create_role()
@ -3019,10 +3022,27 @@ class TestUtilityRBAC(TestcaseBase):
self.utility_wrap.role_grant(grant_item["object"], grant_item["object_name"], grant_item["privilege"],
**db_kwargs)
# list grants
# list grants with default user
g_list, _ = self.utility_wrap.role_list_grants(**db_kwargs)
assert len(g_list.groups) == len(grant_list)
self.connection_wrap.disconnect(alias=DefaultConfig.DEFAULT_USING)
self.connection_wrap.connect(host=host, port=port, user=user,
password=password, check_task=ct.CheckTasks.ccr, **db_kwargs)
# list grants with user
g_list, _ = self.utility_wrap.role_list_grants(**db_kwargs)
assert len(g_list.groups) == len(grant_list)
self.connection_wrap.disconnect(alias=DefaultConfig.DEFAULT_USING)
self.connection_wrap.connect(host=host, port=port, user=user2,
password=password, check_task=ct.CheckTasks.ccr, **db_kwargs)
# user2 can not list grants of role
self.utility_wrap.role_list_grants(**db_kwargs,
check_task=CheckTasks.check_permission_deny)
@pytest.mark.tags(CaseLabel.RBAC)
def test_drop_role_which_bind_user(self, host, port):
"""