diff --git a/pkg/apis/identity/consts.go b/pkg/apis/identity/consts.go index 3f44bc39cb..78eecb2da8 100644 --- a/pkg/apis/identity/consts.go +++ b/pkg/apis/identity/consts.go @@ -84,6 +84,9 @@ const ( IdentitySyncStatusIdle = "idle" MinimalSyncIntervalSeconds = 5 * 60 // 5 minutes + + MaxUserRolesInProject = 10 + MaxGroupRolesInProject = 5 ) var ( diff --git a/pkg/keystone/models/assignments.go b/pkg/keystone/models/assignments.go index 88a19c8e35..c532326916 100644 --- a/pkg/keystone/models/assignments.go +++ b/pkg/keystone/models/assignments.go @@ -132,6 +132,16 @@ func (manager *SAssignmentManager) initSysAssignment(ctx context.Context) error return nil } +func (manager *SAssignmentManager) fetchUserProjectRoleCount(userId, projId string) (int, error) { + q := manager.fetchUserProjectRoleIdsQuery(userId, projId) + return q.CountWithError() +} + +func (manager *SAssignmentManager) fetchGroupProjectRoleCount(grpId, projId string) (int, error) { + q := manager.fetchGroupProjectRoleIdsQuery(grpId, projId) + return q.CountWithError() +} + func (manager *SAssignmentManager) FetchUserProjectRoles(userId, projId string) ([]SRole, error) { subq := manager.fetchUserProjectRoleIdsQuery(userId, projId) q := RoleManager.Query().In("id", subq.SubQuery()) @@ -321,6 +331,13 @@ func (manager *SAssignmentManager) ProjectAddUser(ctx context.Context, userCred return httperrors.NewForbiddenError("not enough privilege") } } + roleCnt, err := manager.fetchUserProjectRoleCount(user.Id, project.Id) + if err != nil { + return errors.Wrap(err, "FetchUserProjectRoleCount") + } + if roleCnt >= api.MaxUserRolesInProject { + return errors.Wrapf(httperrors.ErrTooLarge, "user %s has joined project %s more than %d roles", user.Name, project.Name, roleCnt) + } err = manager.add(ctx, api.AssignmentUserProject, user.Id, project.Id, role.Id) if err != nil { return errors.Wrap(err, "manager.add") @@ -422,6 +439,13 @@ func (manager *SAssignmentManager) projectAddGroup(ctx context.Context, userCred return httperrors.NewForbiddenError("not enough privilege") } } + roleCnt, err := manager.fetchGroupProjectRoleCount(group.Id, project.Id) + if err != nil { + return errors.Wrap(err, "fetchGroupProjectRoleCount") + } + if roleCnt >= api.MaxGroupRolesInProject { + return errors.Wrapf(httperrors.ErrTooLarge, "group %s has joined project %s more than %d roles", group.Name, project.Name, roleCnt) + } err = manager.add(ctx, api.AssignmentGroupProject, group.Id, project.Id, role.Id) if err != nil { return errors.Wrap(err, "manager.add")