This is an automated email from the ASF dual-hosted git repository.

humingcheng pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/servicecomb-service-center.git


The following commit(s) were added to refs/heads/dev by this push:
     new fe5ff175 validate root's role (#1507)
fe5ff175 is described below

commit fe5ff175c2741331986913523497c9d3241873cf
Author: Wanghb1 <[email protected]>
AuthorDate: Wed Jun 25 21:06:40 2025 +0800

    validate root's role (#1507)
    
    * validate root's role
---
 datasource/rbac/role.go                     |  1 +
 server/service/rbac/account_service.go      | 27 +++++++++++++++++----------
 server/service/rbac/account_service_test.go | 13 ++++++++++++-
 3 files changed, 30 insertions(+), 11 deletions(-)

diff --git a/datasource/rbac/role.go b/datasource/rbac/role.go
index 6b640a1c..4b05b967 100644
--- a/datasource/rbac/role.go
+++ b/datasource/rbac/role.go
@@ -28,6 +28,7 @@ var (
        ErrRoleDuplicated = errors.New("role is duplicated")
        ErrRoleCanNotEdit = errors.New("role can not be edited")
        ErrRoleNotExist   = errors.New("role not exist")
+       ErrRootMustAdmin  = errors.New("root must only have admin")
 )
 
 // RoleManager contains the RBAC CRUD
diff --git a/server/service/rbac/account_service.go 
b/server/service/rbac/account_service.go
index 24a609f0..3d19b886 100644
--- a/server/service/rbac/account_service.go
+++ b/server/service/rbac/account_service.go
@@ -24,6 +24,11 @@ import (
        "strconv"
        "time"
 
+       "github.com/go-chassis/cari/discovery"
+       "github.com/go-chassis/cari/dlock"
+       "github.com/go-chassis/cari/pkg/errsvc"
+       rbacmodel "github.com/go-chassis/cari/rbac"
+
        "github.com/apache/servicecomb-service-center/datasource/rbac"
        errorsEx "github.com/apache/servicecomb-service-center/pkg/errors"
        "github.com/apache/servicecomb-service-center/pkg/log"
@@ -31,10 +36,6 @@ import (
        "github.com/apache/servicecomb-service-center/pkg/util"
        quotasvc 
"github.com/apache/servicecomb-service-center/server/service/quota"
        "github.com/apache/servicecomb-service-center/server/service/validator"
-       "github.com/go-chassis/cari/discovery"
-       "github.com/go-chassis/cari/dlock"
-       "github.com/go-chassis/cari/pkg/errsvc"
-       rbacmodel "github.com/go-chassis/cari/rbac"
 )
 
 // CreateAccount save account info
@@ -56,7 +57,7 @@ func CreateAccount(ctx context.Context, a *rbacmodel.Account) 
error {
                log.Error(fmt.Sprintf("create account [%s] failed", a.Name), 
err)
                return discovery.NewError(discovery.ErrInvalidParams, 
err.Error())
        }
-       if err = checkRoleNames(ctx, a.Roles); err != nil {
+       if err = checkRoles(ctx, a); err != nil {
                return rbacmodel.NewError(rbacmodel.ErrAccountHasInvalidRole, 
err.Error())
        }
 
@@ -122,7 +123,7 @@ func UpdateAccount(ctx context.Context, name string, a 
*rbacmodel.Account) error
        if len(a.Roles) != 0 {
                oldAccount.Roles = a.Roles
        }
-       if err = checkRoleNames(ctx, oldAccount.Roles); err != nil {
+       if err = checkRoles(ctx, oldAccount); err != nil {
                return rbacmodel.NewError(rbacmodel.ErrAccountHasInvalidRole, 
err.Error())
        }
        err = rbac.Instance().UpdateAccount(ctx, name, oldAccount)
@@ -188,11 +189,17 @@ func EditAccount(ctx context.Context, a 
*rbacmodel.Account) error {
        return nil
 }
 
-func checkRoleNames(ctx context.Context, roles []string) error {
-       for _, name := range roles {
-               exist, err := RoleExist(ctx, name)
+func checkRoles(ctx context.Context, a *rbacmodel.Account) error {
+       // root must have the only role admin
+       if a.Name == RootName && (len(a.Roles) == 0 || len(a.Roles) >= 2 || 
a.Roles[0] != rbacmodel.RoleAdmin) {
+               log.Error(fmt.Sprintf("root has non-admin role %v", a.Roles), 
rbac.ErrRootMustAdmin)
+               return rbac.ErrRootMustAdmin
+       }
+
+       for _, roleName := range a.Roles {
+               exist, err := RoleExist(ctx, roleName)
                if err != nil {
-                       log.Error(fmt.Sprintf("check role [%s] exist failed", 
name), err)
+                       log.Error(fmt.Sprintf("check role [%s] exist failed", 
roleName), err)
                        return err
                }
                if !exist {
diff --git a/server/service/rbac/account_service_test.go 
b/server/service/rbac/account_service_test.go
index 7d9f3bc5..66a83fc4 100644
--- a/server/service/rbac/account_service_test.go
+++ b/server/service/rbac/account_service_test.go
@@ -26,7 +26,6 @@ import (
        "github.com/go-chassis/cari/pkg/errsvc"
 
        rbacsvc 
"github.com/apache/servicecomb-service-center/server/service/rbac"
-
        _ "github.com/apache/servicecomb-service-center/test"
 
        beego "github.com/beego/beego/v2/server/web"
@@ -92,6 +91,18 @@ func TestCreateAccount(t *testing.T) {
                assert.NoError(t, err)
                assert.Equal(t, "specifyID", account.ID)
        })
+       t.Run("create root with non-admin roles, should fail", func(t 
*testing.T) {
+               accountName := "root"
+               a := newAdminAccount(accountName)
+               a.Roles = append(a.Roles, rbac.RoleDeveloper)
+               a.ID = "specifyID"
+               err := rbacsvc.CreateAccount(ctx, a)
+               svcErr := err.(*errsvc.Error)
+               assert.Equal(t, rbac.ErrAccountHasInvalidRole, svcErr.Code)
+               assert.Equal(t, err.Error(), `Account has invalid role(s)(root 
must only have admin)`)
+
+               defer rbacsvc.DeleteAccount(ctx, accountName)
+       })
 }
 
 func TestDeleteAccount(t *testing.T) {

Reply via email to