diff --git a/pkg/apiserver/domain/service/cloudshell_test.go b/pkg/apiserver/domain/service/cloudshell_test.go index 4804af8d1..bba8e9e07 100644 --- a/pkg/apiserver/domain/service/cloudshell_test.go +++ b/pkg/apiserver/domain/service/cloudshell_test.go @@ -194,7 +194,7 @@ var _ = Describe("Test cloudshell service function", func() { err = cloudShellService.prepareKubeConfig(ctx) Expect(err).Should(BeNil()) - err = k8sClient.Get(context.Background(), types.NamespacedName{Name: "kubevela:writer:application:binding", Namespace: "cloudshell"}, &rb) + err = k8sClient.Get(context.Background(), types.NamespacedName{Name: "kubevela:writer:application:binding", Namespace: "cloudshell-env"}, &rb) Expect(err).Should(BeNil()) Expect(rb.Subjects[0].Name).Should(Equal(utils.KubeVelaProjectGroupPrefix + "cloudshell")) diff --git a/pkg/apiserver/domain/service/project.go b/pkg/apiserver/domain/service/project.go index 063ff06bd..ad4c09b5c 100644 --- a/pkg/apiserver/domain/service/project.go +++ b/pkg/apiserver/domain/service/project.go @@ -75,29 +75,19 @@ func (p *projectServiceImpl) Init(ctx context.Context) error { // the default env and default target both using the `default` namespace in control plane cluster func (p *projectServiceImpl) InitDefaultProjectEnvTarget(ctx context.Context, defaultNamespace string) error { var project = model.Project{} - entities, err := p.Store.List(ctx, &project, &datastore.ListOptions{FilterOptions: datastore.FilterOptions{ - IsNotExist: []datastore.IsNotExistQueryOption{ - { - Key: "owner", - }, - }, - }}) + entities, err := p.Store.List(ctx, &project, &datastore.ListOptions{FilterOptions: datastore.FilterOptions{}}) if err != nil { return fmt.Errorf("initialize project failed %w", err) } if len(entities) > 0 { for _, project := range entities { pro := project.(*model.Project) - var init = pro.Owner == "" pro.Owner = model.DefaultAdminUserName if err := p.Store.Put(ctx, pro); err != nil { return err } - // owner is empty, it is old data - if init { - if err := p.RbacService.InitDefaultRoleAndUsersForProject(ctx, pro); err != nil { - return fmt.Errorf("init default role and users for project %s failure %w", pro.Name, err) - } + if err := p.RbacService.SyncDefaultRoleAndUsersForProject(ctx, pro); err != nil { + return fmt.Errorf("fail to sync the default role and users for the project %s %w", pro.Name, err) } } return nil @@ -343,8 +333,8 @@ func (p *projectServiceImpl) CreateProject(ctx context.Context, req apisv1.Creat return nil, err } - if err := p.RbacService.InitDefaultRoleAndUsersForProject(ctx, newProject); err != nil { - log.Logger.Errorf("init default role and users for project failure %s", err.Error()) + if err := p.RbacService.SyncDefaultRoleAndUsersForProject(ctx, newProject); err != nil { + log.Logger.Errorf("fail to sync the default role and users for the project: %s", err.Error()) } return ConvertProjectModel2Base(newProject, user), nil diff --git a/pkg/apiserver/domain/service/rbac.go b/pkg/apiserver/domain/service/rbac.go index 22c909773..909573d7c 100644 --- a/pkg/apiserver/domain/service/rbac.go +++ b/pkg/apiserver/domain/service/rbac.go @@ -90,10 +90,10 @@ var defaultProjectPermissionTemplate = []*model.PermissionTemplate{ Scope: "project", }, { - Name: "configuration-read", - Alias: "Environment Management", + Name: "config-management", + Alias: "Config Management", Resources: []string{"project:{projectName}/config:*", "project:{projectName}/provider:*"}, - Actions: []string{"list", "detail"}, + Actions: []string{"*"}, Effect: "Allow", Scope: "project", }, @@ -405,7 +405,7 @@ type RBACService interface { ListPermissions(ctx context.Context, projectName string) ([]apisv1.PermissionBase, error) CreatePermission(ctx context.Context, projectName string, req apisv1.CreatePermissionRequest) (*apisv1.PermissionBase, error) DeletePermission(ctx context.Context, projectName, permName string) error - InitDefaultRoleAndUsersForProject(ctx context.Context, project *model.Project) error + SyncDefaultRoleAndUsersForProject(ctx context.Context, project *model.Project) error Init(ctx context.Context) error } @@ -857,7 +857,17 @@ func (p *rbacServiceImpl) CreatePermission(ctx context.Context, projectName stri return assembler.ConvertPermission2DTO(&permission), nil } -func (p *rbacServiceImpl) InitDefaultRoleAndUsersForProject(ctx context.Context, project *model.Project) error { +func (p *rbacServiceImpl) SyncDefaultRoleAndUsersForProject(ctx context.Context, project *model.Project) error { + + permissions, err := p.ListPermissions(ctx, project.Name) + if err != nil { + return err + } + var permissionMap = map[string]apisv1.PermissionBase{} + for i, per := range permissions { + permissionMap[per.Name] = permissions[i] + } + var batchData []datastore.Entity for _, permissionTemp := range defaultProjectPermissionTemplate { var rra = RequestResourceAction{} @@ -871,39 +881,52 @@ func (p *rbacServiceImpl) InitDefaultRoleAndUsersForProject(ctx context.Context, }) formattedResource = append(formattedResource, rra.GetResource().String()) } - batchData = append(batchData, &model.Permission{ + permission := &model.Permission{ Name: permissionTemp.Name, Alias: permissionTemp.Alias, Project: project.Name, Resources: formattedResource, Actions: permissionTemp.Actions, Effect: permissionTemp.Effect, - }) - } - batchData = append(batchData, &model.Role{ - Name: "app-developer", - Alias: "App Developer", - Permissions: []string{"project-view", "app-management", "env-management", "configuration-read"}, - Project: project.Name, - }, &model.Role{ - Name: "project-admin", - Alias: "Project Admin", - Permissions: []string{"project-view", "app-management", "env-management", "role-management", "pipeline-management", "configuration-read"}, - Project: project.Name, - }, &model.Role{ - Name: "project-viewer", - Alias: "Project Viewer", - Permissions: []string{"project-view"}, - Project: project.Name, - }) - if project.Owner != "" { - var projectUser = &model.ProjectUser{ - ProjectName: project.Name, - UserRoles: []string{"project-admin"}, - Username: project.Owner, } - batchData = append(batchData, projectUser) + if perm, exist := permissionMap[permissionTemp.Name]; exist { + if !utils.EqualSlice(perm.Resources, permissionTemp.Resources) || utils.EqualSlice(perm.Actions, permissionTemp.Actions) { + if err := p.Store.Put(ctx, permission); err != nil { + return err + } + } + continue + } + batchData = append(batchData, permission) } + + if len(permissions) == 0 { + batchData = append(batchData, &model.Role{ + Name: "app-developer", + Alias: "App Developer", + Permissions: []string{"project-view", "app-management", "env-management", "config-management", "pipeline-management"}, + Project: project.Name, + }, &model.Role{ + Name: "project-admin", + Alias: "Project Admin", + Permissions: []string{"project-view", "app-management", "env-management", "pipeline-management", "config-management", "role-management"}, + Project: project.Name, + }, &model.Role{ + Name: "project-viewer", + Alias: "Project Viewer", + Permissions: []string{"project-view"}, + Project: project.Name, + }) + if project.Owner != "" { + var projectUser = &model.ProjectUser{ + ProjectName: project.Name, + UserRoles: []string{"project-admin"}, + Username: project.Owner, + } + batchData = append(batchData, projectUser) + } + } + return p.Store.BatchAdd(ctx, batchData) } diff --git a/pkg/apiserver/domain/service/rbac_test.go b/pkg/apiserver/domain/service/rbac_test.go index 3cc73d0ca..fa0769bec 100644 --- a/pkg/apiserver/domain/service/rbac_test.go +++ b/pkg/apiserver/domain/service/rbac_test.go @@ -189,7 +189,7 @@ var _ = Describe("Test rbac service", func() { err = ds.Add(context.TODO(), &model.Project{Name: "init-test", Owner: "test-user"}) Expect(err).Should(BeNil()) - err = rbacService.InitDefaultRoleAndUsersForProject(context.TODO(), &model.Project{Name: "init-test"}) + err = rbacService.SyncDefaultRoleAndUsersForProject(context.TODO(), &model.Project{Name: "init-test"}) Expect(err).Should(BeNil()) roles, err := rbacService.ListRole(context.TODO(), "init-test", 0, 0)