From 2bafdf8c5331835a595bc67597367694be0eead1 Mon Sep 17 00:00:00 2001 From: SimFG Date: Mon, 5 Sep 2022 21:05:11 +0800 Subject: [PATCH] Fix the `Flush` privilege can't be granted (#19020) Signed-off-by: SimFG Signed-off-by: SimFG --- internal/proxy/privilege_interceptor.go | 49 +++++++++++--------- internal/proxy/privilege_interceptor_test.go | 14 ++++++ internal/util/funcutil/policy.go | 7 +-- 3 files changed, 44 insertions(+), 26 deletions(-) diff --git a/internal/proxy/privilege_interceptor.go b/internal/proxy/privilege_interceptor.go index 9842435f1..2071defaa 100644 --- a/internal/proxy/privilege_interceptor.go +++ b/internal/proxy/privilege_interceptor.go @@ -39,7 +39,7 @@ p = sub, obj, act e = some(where (p.eft == allow)) [matchers] -m = r.sub == p.sub && globMatch(r.obj, p.obj) && globMatch(r.act, p.act) || r.sub == "admin" || r.act == "All" +m = r.sub == p.sub && globMatch(r.obj, p.obj) && globMatch(r.act, p.act) || r.sub == "admin" || (r.sub == p.sub && p.act == "PrivilegeAll") ` ModelKey = "casbin" ) @@ -109,7 +109,7 @@ func PrivilegeInterceptor(ctx context.Context, req interface{}) (context.Context log.Debug("current request info", zap.String("username", username), zap.Strings("role_names", roleNames), zap.String("object_type", objectType), zap.String("object_privilege", objectPrivilege), zap.Int32("object_index", objectNameIndex), zap.String("object_name", objectName), - zap.Strings("object_names", objectNames), + zap.Int32("object_indexs", objectNameIndexs), zap.Strings("object_names", objectNames), zap.String("policy_info", policyInfo)) policy := fmt.Sprintf("[%s]", policyInfo) @@ -128,43 +128,46 @@ func PrivilegeInterceptor(ctx context.Context, req interface{}) (context.Context } for _, roleName := range roleNames { permitFunc := func(resName string) (bool, error) { - object := funcutil.PolicyForResource(objectType, objectName) + object := funcutil.PolicyForResource(objectType, resName) isPermit, err := e.Enforce(roleName, object, objectPrivilege) if err != nil { - log.Error("Enforce fail", zap.String("role", roleName), zap.String("object", object), zap.String("privilege", objectPrivilege), zap.Error(err)) return false, err } return isPermit, nil } - // handle the api which refers one resource - permitObject, err := permitFunc(objectName) - if err != nil { - return ctx, err - } - if permitObject { - return ctx, nil - } - - // handle the api which refers many resources - permitObjects := true - for _, name := range objectNames { - p, err := permitFunc(name) + if objectNameIndex != 0 { + // handle the api which refers one resource + permitObject, err := permitFunc(objectName) if err != nil { return ctx, err } - if !p { - permitObjects = false - break + if permitObject { + return ctx, nil } } - if permitObjects && len(objectNames) != 0 { - return ctx, nil + + if objectNameIndexs != 0 { + // handle the api which refers many resources + permitObjects := true + for _, name := range objectNames { + p, err := permitFunc(name) + if err != nil { + return ctx, err + } + if !p { + permitObjects = false + break + } + } + if permitObjects && len(objectNames) != 0 { + return ctx, nil + } } } log.Debug("permission deny", zap.String("policy", policy), zap.Strings("roles", roleNames)) - return ctx, status.Error(codes.PermissionDenied, "permission deny") + return ctx, status.Error(codes.PermissionDenied, fmt.Sprintf("%s: permission deny", objectPrivilege)) } // isCurUserObject Determine whether it is an Object of type User that operates on its own user information, diff --git a/internal/proxy/privilege_interceptor_test.go b/internal/proxy/privilege_interceptor_test.go index e045b46b4..7ca3547e9 100644 --- a/internal/proxy/privilege_interceptor_test.go +++ b/internal/proxy/privilege_interceptor_test.go @@ -52,9 +52,12 @@ func TestPrivilegeInterceptor(t *testing.T) { }, PolicyInfos: []string{ funcutil.PolicyForPrivilege("role1", commonpb.ObjectType_Collection.String(), "col1", commonpb.ObjectPrivilege_PrivilegeLoad.String()), + funcutil.PolicyForPrivilege("role1", commonpb.ObjectType_Collection.String(), "col1", commonpb.ObjectPrivilege_PrivilegeFlush.String()), + funcutil.PolicyForPrivilege("role2", commonpb.ObjectType_Global.String(), "*", commonpb.ObjectPrivilege_PrivilegeAll.String()), }, UserRoles: []string{ funcutil.EncodeUserRoleCache("alice", "role1"), + funcutil.EncodeUserRoleCache("fooo", "role2"), }, }, nil } @@ -95,6 +98,17 @@ func TestPrivilegeInterceptor(t *testing.T) { }) assert.NotNil(t, err) + _, err = PrivilegeInterceptor(ctx, &milvuspb.FlushRequest{ + DbName: "db_test", + CollectionNames: []string{"col1"}, + }) + assert.Nil(t, err) + + _, err = PrivilegeInterceptor(GetContext(context.Background(), "fooo:123456"), &milvuspb.LoadCollectionRequest{ + DbName: "db_test", + CollectionName: "col1", + }) + assert.Nil(t, err) }) } diff --git a/internal/util/funcutil/policy.go b/internal/util/funcutil/policy.go index a4ee9df70..b20835c37 100644 --- a/internal/util/funcutil/policy.go +++ b/internal/util/funcutil/policy.go @@ -45,9 +45,10 @@ func GetPrivilegeExtObj(m proto.GeneratedMessage) (commonpb.PrivilegeExt, error) privilegeExt := extObj.(*commonpb.PrivilegeExt) log.Debug("GetPrivilegeExtObj success", zap.String("resource_type", privilegeExt.ObjectType.String()), zap.String("resource_privilege", privilegeExt.ObjectPrivilege.String())) return commonpb.PrivilegeExt{ - ObjectType: privilegeExt.ObjectType, - ObjectPrivilege: privilegeExt.ObjectPrivilege, - ObjectNameIndex: privilegeExt.ObjectNameIndex, + ObjectType: privilegeExt.ObjectType, + ObjectPrivilege: privilegeExt.ObjectPrivilege, + ObjectNameIndex: privilegeExt.ObjectNameIndex, + ObjectNameIndexs: privilegeExt.ObjectNameIndexs, }, nil } -- GitLab