feat(系统设置): 添加超级管理员用户组

--story=1010746 --user=李玉号 【系统设置】添加超级管理员用户组
https://www.tapd.cn/55049933/s/1314273
This commit is contained in:
shiziyuan9527 2022-12-02 17:44:10 +08:00 committed by 刘瑞斌
parent e0e8d66f44
commit 0a01ed4903
28 changed files with 364 additions and 169 deletions

View File

@ -2,10 +2,8 @@ package io.metersphere.gateway.service;
import io.metersphere.base.domain.*; import io.metersphere.base.domain.*;
import io.metersphere.base.mapper.*; import io.metersphere.base.mapper.*;
import io.metersphere.commons.constants.SessionConstants; import io.metersphere.base.mapper.ext.BaseProjectMapper;
import io.metersphere.commons.constants.UserGroupType; import io.metersphere.commons.constants.*;
import io.metersphere.commons.constants.UserSource;
import io.metersphere.commons.constants.UserStatus;
import io.metersphere.commons.exception.MSException; import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.user.SessionUser; import io.metersphere.commons.user.SessionUser;
import io.metersphere.commons.utils.CodingUtil; import io.metersphere.commons.utils.CodingUtil;
@ -39,6 +37,8 @@ public class UserLoginService {
private UserGroupPermissionMapper userGroupPermissionMapper; private UserGroupPermissionMapper userGroupPermissionMapper;
@Resource @Resource
private ProjectMapper projectMapper; private ProjectMapper projectMapper;
@Resource
private BaseProjectMapper baseProjectMapper;
public Optional<SessionUser> login(LoginRequest request, WebSession session, Locale locale) { public Optional<SessionUser> login(LoginRequest request, WebSession session, Locale locale) {
UserDTO userDTO; UserDTO userDTO;
@ -173,31 +173,55 @@ public class UserLoginService {
private void checkNewWorkspaceAndProject(WebSession session, UserDTO user) { private void checkNewWorkspaceAndProject(WebSession session, UserDTO user) {
List<UserGroup> userGroups = user.getUserGroups(); List<UserGroup> userGroups = user.getUserGroups();
List<String> projectGroupIds = user.getGroups() List<Group> groups = user.getGroups();
.stream().filter(ug -> StringUtils.equals(ug.getType(), UserGroupType.PROJECT))
List<String> projectGroupIds = groups
.stream()
.filter(ug -> StringUtils.equals(ug.getType(), UserGroupType.PROJECT))
.map(Group::getId) .map(Group::getId)
.collect(Collectors.toList()); .collect(Collectors.toList());
List<UserGroup> project = userGroups.stream().filter(ug -> projectGroupIds.contains(ug.getGroupId()))
List<UserGroup> projects = userGroups
.stream()
.filter(ug -> projectGroupIds.contains(ug.getGroupId()))
.collect(Collectors.toList()); .collect(Collectors.toList());
if (CollectionUtils.isEmpty(project)) {
List<String> workspaceIds = user.getGroups() if (CollectionUtils.isEmpty(projects)) {
List<String> workspaceIds = groups
.stream() .stream()
.filter(ug -> StringUtils.equals(ug.getType(), UserGroupType.WORKSPACE)) .filter(ug -> StringUtils.equals(ug.getType(), UserGroupType.WORKSPACE))
.map(Group::getId) .map(Group::getId)
.collect(Collectors.toList()); .collect(Collectors.toList());
List<UserGroup> workspaces = userGroups.stream().filter(ug -> workspaceIds.contains(ug.getGroupId()))
List<UserGroup> workspaces = userGroups
.stream()
.filter(ug -> workspaceIds.contains(ug.getGroupId()))
.collect(Collectors.toList()); .collect(Collectors.toList());
if (workspaces.size() > 0) { if (workspaces.size() > 0) {
String wsId = workspaces.get(0).getSourceId(); String wsId = workspaces.get(0).getSourceId();
switchUserResource(session, "workspace", wsId, user); switchUserResource(session, "workspace", wsId, user);
} else { } else {
// 用户登录之后没有项目和工作空间的权限就把值清空 List<String> superGroupIds = groups
user.setLastWorkspaceId(""); .stream()
user.setLastProjectId(""); .map(Group::getId)
updateUser(user); .filter(id -> StringUtils.equals(id, UserGroupConstants.SUPER_GROUP))
.collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(superGroupIds)) {
Project p = baseProjectMapper.selectOne();
if (p != null) {
switchSuperUserResource(session, p.getId(), p.getWorkspaceId(), user);
} }
} else { } else {
UserGroup userGroup = project.stream().filter(p -> StringUtils.isNotBlank(p.getSourceId())) // 用户登录之后没有项目和工作空间的权限就把值清空
user.setLastWorkspaceId(StringUtils.EMPTY);
user.setLastProjectId(StringUtils.EMPTY);
updateUser(user);
}
}
} else {
UserGroup userGroup = projects.stream()
.filter(p -> StringUtils.isNotBlank(p.getSourceId()))
.collect(Collectors.toList()).get(0); .collect(Collectors.toList()).get(0);
String projectId = userGroup.getSourceId(); String projectId = userGroup.getSourceId();
Project p = projectMapper.selectByPrimaryKey(projectId); Project p = projectMapper.selectByPrimaryKey(projectId);
@ -231,6 +255,20 @@ public class UserLoginService {
userMapper.updateByPrimaryKeySelective(newUser); userMapper.updateByPrimaryKeySelective(newUser);
} }
private void switchSuperUserResource(WebSession session, String projectId, String workspaceId, UserDTO sessionUser) {
// 获取最新UserDTO
UserDTO user = getUserDTO(sessionUser.getId());
User newUser = new User();
user.setLastWorkspaceId(workspaceId);
sessionUser.setLastWorkspaceId(workspaceId);
user.setLastProjectId(projectId);
BeanUtils.copyProperties(user, newUser);
// 切换工作空间或组织之后更新 session 里的 user
session.getAttributes().put(SessionConstants.ATTR_USER, SessionUser.fromUser(user, session.getId()));
session.getAttributes().put(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, sessionUser.getId());
userMapper.updateByPrimaryKeySelective(newUser);
}
public UserDTO getLoginUser(String userId, List<String> list) { public UserDTO getLoginUser(String userId, List<String> list) {
UserExample example = new UserExample(); UserExample example = new UserExample();
example.createCriteria().andIdEqualTo(userId).andSourceIn(list); example.createCriteria().andIdEqualTo(userId).andSourceIn(list);

View File

@ -13,6 +13,20 @@ export function hasPermission(permission) {
}); });
}); });
let superGroupPermissions = user.userGroups.filter(ug => ug.group && ug.group.id === 'super_group')
.flatMap(ug => ug.userGroupPermissions)
.map(g => g.permissionId)
.reduce((total, current) => {
total.add(current);
return total;
}, new Set);
for (const p of superGroupPermissions) {
if (p === permission) {
return true;
}
}
// todo 权限验证 // todo 权限验证
let currentProjectPermissions = user.userGroups.filter(ug => ug.group && ug.group.type === 'PROJECT') let currentProjectPermissions = user.userGroups.filter(ug => ug.group && ug.group.type === 'PROJECT')
.filter(ug => ug.sourceId === getCurrentProjectID()) .filter(ug => ug.sourceId === getCurrentProjectID())

View File

@ -20,6 +20,7 @@ public class PermissionConfig implements ApplicationRunner {
@Override @Override
public void run(ApplicationArguments args) { public void run(ApplicationArguments args) {
LogUtil.info("load permission form {} service permission.json file", service);
try (InputStream inputStream = PermissionConfig.class.getResourceAsStream("/permission.json")){ try (InputStream inputStream = PermissionConfig.class.getResourceAsStream("/permission.json")){
String permission = IOUtils.toString(inputStream, StandardCharsets.UTF_8); String permission = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
stringRedisTemplate.opsForHash().put(RedisKey.MS_PERMISSION_KEY, service, permission); stringRedisTemplate.opsForHash().put(RedisKey.MS_PERMISSION_KEY, service, permission);

View File

@ -18,7 +18,7 @@ public interface BaseProjectMapper {
int removeIssuePlatform(@Param("platform") String platform, @Param("workspaceId") String workspaceId); int removeIssuePlatform(@Param("platform") String platform, @Param("workspaceId") String workspaceId);
List<ProjectDTO> getUserProject(@Param("proRequest") ProjectRequest request); List<Project> getUserProject(@Param("proRequest") ProjectRequest request);
String getSystemIdByProjectId(String projectId); String getSystemIdByProjectId(String projectId);
@ -49,4 +49,6 @@ public interface BaseProjectMapper {
void updateUseDefaultCaseTemplateProject(@Param("originId") String originId,@Param("templateId") String templateId,@Param("projectId") String projectId); void updateUseDefaultCaseTemplateProject(@Param("originId") String originId,@Param("templateId") String templateId,@Param("projectId") String projectId);
List<String> getThirdPartProjectIds(); List<String> getThirdPartProjectIds();
Project selectOne();
} }

View File

@ -138,7 +138,7 @@
FROM project FROM project
WHERE workspace_id = #{workspaceId} WHERE workspace_id = #{workspaceId}
</select> </select>
<select id="getUserProject" resultType="io.metersphere.dto.ProjectDTO"> <select id="getUserProject" resultType="io.metersphere.base.domain.Project">
SELECT DISTINCT p.* SELECT DISTINCT p.*
FROM `group` g FROM `group` g
JOIN user_group ug ON g.id = ug.group_id JOIN user_group ug ON g.id = ug.group_id
@ -435,4 +435,7 @@
#{id} #{id}
</foreach> </foreach>
</select> </select>
<select id="selectOne" resultType="io.metersphere.base.domain.Project">
SELECT * FROM project LIMIT 1
</select>
</mapper> </mapper>

View File

@ -34,4 +34,6 @@ public interface BaseUserMapper {
void updateLastProjectIdIfNull(@Param("projectId") String projectId, @Param("userId") String userId); void updateLastProjectIdIfNull(@Param("projectId") String projectId, @Param("userId") String userId);
void updateLastWorkspaceIdIfNull(@Param("workspaceId") String workspaceId, @Param("userId") String userId); void updateLastWorkspaceIdIfNull(@Param("workspaceId") String workspaceId, @Param("userId") String userId);
boolean isSuperUser(String userId);
} }

View File

@ -112,7 +112,9 @@
FROM user FROM user
<include refid="queryWhereCondition"/> <include refid="queryWhereCondition"/>
</select> </select>
<select id="isSuperUser" resultType="java.lang.Boolean">
select count(*) from user_group where user_id = #{userId} and group_id = 'super_group'
</select>
<update id="updateLastProjectIdIfNull"> <update id="updateLastProjectIdIfNull">
UPDATE user SET last_project_id = #{projectId} WHERE id = #{userId} UPDATE user SET last_project_id = #{projectId} WHERE id = #{userId}
AND (last_project_id IS NULL OR last_project_id = '') AND (last_project_id IS NULL OR last_project_id = '')

View File

@ -4,6 +4,7 @@ package io.metersphere.commons.constants;
* 系统内置用户组常量 * 系统内置用户组常量
*/ */
public class UserGroupConstants { public class UserGroupConstants {
public static final String SUPER_GROUP = "super_group";
public static final String ADMIN = "admin"; public static final String ADMIN = "admin";
public static final String ORG_ADMIN = "org_admin"; public static final String ORG_ADMIN = "org_admin";
public static final String ORG_MEMBER = "org_member"; public static final String ORG_MEMBER = "org_member";

View File

@ -29,7 +29,7 @@ public class BaseProjectController {
* @return List<ProjectDTO> * @return List<ProjectDTO>
*/ */
@PostMapping("/list/related") @PostMapping("/list/related")
public List<ProjectDTO> getUserProject(@RequestBody ProjectRequest request) { public List<Project> getUserProject(@RequestBody ProjectRequest request) {
return baseProjectService.getUserProject(request); return baseProjectService.getUserProject(request);
} }

View File

@ -105,4 +105,9 @@ public class BaseUserController {
public void updateCurrentUserByResourceId(@PathVariable String resourceId) { public void updateCurrentUserByResourceId(@PathVariable String resourceId) {
baseUserService.updateCurrentUserByResourceId(resourceId); baseUserService.updateCurrentUserByResourceId(resourceId);
} }
@GetMapping("/is/super/{userid}")
public boolean isSuperUser(@PathVariable String userid) {
return baseUserService.isSuperUser(userid);
}
} }

View File

@ -11,4 +11,10 @@ public class GroupResource implements Serializable {
private String id; private String id;
private String name; private String name;
private Boolean license = false; private Boolean license = false;
/**
* 系统设置工作空间项目类型 公用的权限模块
* e.g. 个人信息
*/
private boolean global = false;
} }

View File

@ -7,6 +7,7 @@ import io.metersphere.base.mapper.UserMapper;
import io.metersphere.base.mapper.ext.BaseProjectMapper; import io.metersphere.base.mapper.ext.BaseProjectMapper;
import io.metersphere.base.mapper.ext.BaseProjectVersionMapper; import io.metersphere.base.mapper.ext.BaseProjectVersionMapper;
import io.metersphere.base.mapper.ext.BaseUserGroupMapper; import io.metersphere.base.mapper.ext.BaseUserGroupMapper;
import io.metersphere.base.mapper.ext.BaseUserMapper;
import io.metersphere.commons.constants.ProjectApplicationType; import io.metersphere.commons.constants.ProjectApplicationType;
import io.metersphere.commons.exception.MSException; import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.JSON; import io.metersphere.commons.utils.JSON;
@ -54,6 +55,8 @@ public class BaseProjectService {
private BaseProjectVersionMapper baseProjectVersionMapper; private BaseProjectVersionMapper baseProjectVersionMapper;
@Resource @Resource
private BaseProjectApplicationService baseProjectApplicationService; private BaseProjectApplicationService baseProjectApplicationService;
@Resource
private BaseUserMapper baseUserMapper;
private String genSystemId() { private String genSystemId() {
@ -90,7 +93,19 @@ public class BaseProjectService {
return baseProjectMapper.getProjectWithWorkspace(request); return baseProjectMapper.getProjectWithWorkspace(request);
} }
public List<ProjectDTO> getUserProject(ProjectRequest request) { public List<Project> getUserProject(ProjectRequest request) {
boolean isSuper = baseUserMapper.isSuperUser(SessionUtils.getUserId());
if (isSuper) {
ProjectExample example = new ProjectExample();
ProjectExample.Criteria criteria = example.createCriteria();
if (StringUtils.isNotBlank(request.getName())) {
criteria.andNameLike(request.getName());
}
if (StringUtils.isNotBlank(request.getWorkspaceId())) {
criteria.andWorkspaceIdEqualTo(request.getWorkspaceId());
}
return projectMapper.selectByExample(example);
}
if (StringUtils.isNotBlank(request.getName())) { if (StringUtils.isNotBlank(request.getName())) {
request.setName(StringUtils.wrapIfMissing(request.getName(), "%")); request.setName(StringUtils.wrapIfMissing(request.getName(), "%"));
} }
@ -359,4 +374,8 @@ public class BaseProjectService {
public void deleteFile(String fileId) { public void deleteFile(String fileId) {
fileMetadataService.deleteFile(fileId); fileMetadataService.deleteFile(fileId);
} }
public Project selectOne() {
return baseProjectMapper.selectOne();
}
} }

View File

@ -242,17 +242,39 @@ public class BaseUserService {
// 获取最新UserDTO // 获取最新UserDTO
UserDTO user = getUserDTO(sessionUser.getId()); UserDTO user = getUserDTO(sessionUser.getId());
User newUser = new User(); User newUser = new User();
boolean isSuper = baseUserMapper.isSuperUser(sessionUser.getId());
if (StringUtils.equals("workspace", sign)) { if (StringUtils.equals("workspace", sign)) {
user.setLastWorkspaceId(sourceId); user.setLastWorkspaceId(sourceId);
sessionUser.setLastWorkspaceId(sourceId); sessionUser.setLastWorkspaceId(sourceId);
List<Project> projects = getProjectListByWsAndUserId(sessionUser.getId(), sourceId); List<Project> projects = getProjectListByWsAndUserId(sessionUser.getId(), sourceId);
if (projects.size() > 0) { if (CollectionUtils.isNotEmpty(projects)) {
user.setLastProjectId(projects.get(0).getId()); user.setLastProjectId(projects.get(0).getId());
} else {
if (isSuper) {
ProjectExample example = new ProjectExample();
example.createCriteria().andWorkspaceIdEqualTo(sourceId);
List<Project> allWsProject = projectMapper.selectByExample(example);
if (CollectionUtils.isNotEmpty(allWsProject)) {
user.setLastProjectId(allWsProject.get(0).getId());
}
} else { } else {
user.setLastProjectId(StringUtils.EMPTY); user.setLastProjectId(StringUtils.EMPTY);
} }
} }
}
BeanUtils.copyProperties(user, newUser);
// 切换工作空间或组织之后更新 session 里的 user
SessionUtils.putUser(SessionUser.fromUser(user, SessionUtils.getSessionId()));
userMapper.updateByPrimaryKeySelective(newUser);
}
private void switchSuperUserResource(String projectId, String workspaceId, UserDTO sessionUser) {
// 获取最新UserDTO
UserDTO user = getUserDTO(sessionUser.getId());
User newUser = new User();
user.setLastWorkspaceId(workspaceId);
sessionUser.setLastWorkspaceId(workspaceId);
user.setLastProjectId(projectId);
BeanUtils.copyProperties(user, newUser); BeanUtils.copyProperties(user, newUser);
// 切换工作空间或组织之后更新 session 里的 user // 切换工作空间或组织之后更新 session 里的 user
SessionUtils.putUser(SessionUser.fromUser(user, SessionUtils.getSessionId())); SessionUtils.putUser(SessionUser.fromUser(user, SessionUtils.getSessionId()));
@ -417,12 +439,24 @@ public class BaseUserService {
if (workspaces.size() > 0) { if (workspaces.size() > 0) {
String wsId = workspaces.get(0).getSourceId(); String wsId = workspaces.get(0).getSourceId();
switchUserResource("workspace", wsId, user); switchUserResource("workspace", wsId, user);
} else {
List<String> superGroupIds = user.getGroups()
.stream()
.map(Group::getId)
.filter(id -> StringUtils.equals(id, UserGroupConstants.SUPER_GROUP))
.collect(Collectors.toList());
if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(superGroupIds)) {
Project p = baseProjectMapper.selectOne();
if (p != null) {
switchSuperUserResource(p.getId(), p.getWorkspaceId(), user);
}
} else { } else {
// 用户登录之后没有项目和工作空间的权限就把值清空 // 用户登录之后没有项目和工作空间的权限就把值清空
user.setLastWorkspaceId(StringUtils.EMPTY); user.setLastWorkspaceId(StringUtils.EMPTY);
user.setLastProjectId(StringUtils.EMPTY); user.setLastProjectId(StringUtils.EMPTY);
updateUser(user); updateUser(user);
} }
}
} else { } else {
UserGroup userGroup = project.stream().filter(p -> StringUtils.isNotBlank(p.getSourceId())) UserGroup userGroup = project.stream().filter(p -> StringUtils.isNotBlank(p.getSourceId()))
.collect(Collectors.toList()).get(0); .collect(Collectors.toList()).get(0);
@ -450,6 +484,8 @@ public class BaseUserService {
user.setLastWorkspaceId(project.getWorkspaceId()); user.setLastWorkspaceId(project.getWorkspaceId());
updateUser(user); updateUser(user);
return true; return true;
} else {
return baseUserMapper.isSuperUser(user.getId());
} }
} }
return false; return false;
@ -496,6 +532,8 @@ public class BaseUserService {
user.setLastWorkspaceId(wsId); user.setLastWorkspaceId(wsId);
updateUser(user); updateUser(user);
return true; return true;
} else {
return baseUserMapper.isSuperUser(user.getId());
} }
} }
return false; return false;
@ -739,4 +777,16 @@ public class BaseUserService {
user.setLastWorkspaceId(project.getWorkspaceId()); user.setLastWorkspaceId(project.getWorkspaceId());
userMapper.updateByPrimaryKeySelective(user); userMapper.updateByPrimaryKeySelective(user);
} }
public boolean isSuperUser(String userid) {
if (StringUtils.isBlank(userid)) {
MSException.throwException("userid is blank.");
}
return baseUserMapper.isSuperUser(userid);
}
public List<String> getAllUserIds() {
List<User> users = userMapper.selectByExample(new UserExample());
return users.stream().map(User::getId).collect(Collectors.toList());
}
} }

View File

@ -4,6 +4,7 @@ import io.metersphere.base.domain.Workspace;
import io.metersphere.base.domain.WorkspaceExample; import io.metersphere.base.domain.WorkspaceExample;
import io.metersphere.base.mapper.WorkspaceMapper; import io.metersphere.base.mapper.WorkspaceMapper;
import io.metersphere.base.mapper.ext.BaseUserGroupMapper; import io.metersphere.base.mapper.ext.BaseUserGroupMapper;
import io.metersphere.base.mapper.ext.BaseUserMapper;
import io.metersphere.dto.RelatedSource; import io.metersphere.dto.RelatedSource;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
@ -19,8 +20,14 @@ public class BaseWorkspaceService {
private BaseUserGroupMapper baseUserGroupMapper; private BaseUserGroupMapper baseUserGroupMapper;
@Resource @Resource
private WorkspaceMapper workspaceMapper; private WorkspaceMapper workspaceMapper;
@Resource
private BaseUserMapper baseUserMapper;
public List<Workspace> getWorkspaceListByUserId(String userId) { public List<Workspace> getWorkspaceListByUserId(String userId) {
boolean isSuper = baseUserMapper.isSuperUser(userId);
if (isSuper) {
return workspaceMapper.selectByExample(new WorkspaceExample());
}
List<RelatedSource> relatedSource = baseUserGroupMapper.getRelatedSource(userId); List<RelatedSource> relatedSource = baseUserGroupMapper.getRelatedSource(userId);
List<String> wsIds = relatedSource List<String> wsIds = relatedSource
.stream() .stream()

View File

@ -5,32 +5,9 @@
<select id="getGroupList" resultType="io.metersphere.dto.GroupDTO"> <select id="getGroupList" resultType="io.metersphere.dto.GroupDTO">
SELECT *, SELECT *,
<if test="request.onlyQueryCurrentProject == true">
(SELECT COUNT(DISTINCT ug.user_id) FROM user_group ug JOIN user ON ug.user_id = user.id WHERE ug.group_id = (SELECT COUNT(DISTINCT ug.user_id) FROM user_group ug JOIN user ON ug.user_id = user.id WHERE ug.group_id =
temp.id AND ug.source_id = #{request.projectId}) AS memberSize temp.id AND ug.source_id = #{request.projectId}) AS memberSize
</if>
<if test="request.onlyQueryCurrentProject == false">
(SELECT COUNT(DISTINCT ug.user_id) FROM user_group ug JOIN user ON ug.user_id = user.id WHERE ug.group_id =
temp.id) AS memberSize
</if>
FROM ( FROM (
SELECT g.*, w.name AS scopeName FROM `group` g, workspace w
<where>
and g.scope_id = w.id
<if test="request.types != null and request.types.size() > 0">
AND g.type IN
<foreach collection="request.types" item="type" separator="," open="(" close=")">
#{type}
</foreach>
</if>
<if test="request.scopes != null and request.scopes.size() > 0">
AND g.scope_id IN
<foreach collection="request.scopes" item="scope" separator="," open="(" close=")">
#{scope}
</foreach>
</if>
</where>
UNION DISTINCT
SELECT g.*, 'global' AS scopeName FROM `group` g SELECT g.*, 'global' AS scopeName FROM `group` g
<where> <where>
g.scope_id = 'global' g.scope_id = 'global'
@ -63,7 +40,7 @@
WHERE temp.name LIKE CONCAT('%', #{request.name},'%') WHERE temp.name LIKE CONCAT('%', #{request.name},'%')
</if> </if>
<if test="request.orders == null or request.orders.size() == 0"> <if test="request.orders == null or request.orders.size() == 0">
ORDER BY field(temp.type, 'SYSTEM', 'ORGANIZATION', 'WORKSPACE', 'PROJECT'), temp.update_time, temp.name ORDER BY field(temp.type, 'SYSTEM', 'WORKSPACE', 'PROJECT'), temp.update_time, temp.name
</if> </if>
<if test="request.orders != null and request.orders.size() > 0"> <if test="request.orders != null and request.orders.size() > 0">
ORDER BY ORDER BY

View File

@ -36,21 +36,12 @@ public class GroupController {
@Resource @Resource
private GroupService groupService; private GroupService groupService;
@PostMapping("/get/{goPage}/{pageSize}")
@RequiresPermissions(value = {PermissionConstants.SYSTEM_GROUP_READ}, logical = Logical.OR)
public Pager<List<GroupDTO>> getGroupList(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody EditGroupRequest request) {
request.setGoPage(goPage);
request.setPageSize(pageSize);
return groupService.getGroupList(request);
}
@PostMapping("/get/current/project/{goPage}/{pageSize}") @PostMapping("/get/current/project/{goPage}/{pageSize}")
@RequiresPermissions(value = {PermissionConstants.PROJECT_GROUP_READ}, logical = Logical.OR) @RequiresPermissions(value = {PermissionConstants.PROJECT_GROUP_READ}, logical = Logical.OR)
public Pager<List<GroupDTO>> getCurrentProjectGroupList(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody EditGroupRequest request) { public Pager<List<GroupDTO>> getCurrentProjectGroupList(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody EditGroupRequest request) {
request.setOnlyQueryCurrentProject(true);
request.setGoPage(goPage); request.setGoPage(goPage);
request.setPageSize(pageSize); request.setPageSize(pageSize);
return groupService.getGroupList(request); return groupService.getProjectGroupList(request);
} }
@GetMapping("/get/all") @GetMapping("/get/all")
@ -127,13 +118,6 @@ public class GroupController {
return groupService.getResource(type, id); return groupService.getResource(type, id);
} }
@PostMapping("/user/{goPage}/{pageSize}")
@RequiresPermissions(value = {PermissionConstants.SYSTEM_GROUP_READ}, logical = Logical.OR)
public Pager<List<User>> getGroupUser(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody EditGroupRequest editGroupRequest) {
Page<Object> page = PageHelper.startPage(goPage, pageSize, true);
return PageUtils.setPageInfo(page, groupService.getGroupUser(editGroupRequest));
}
@PostMapping("/current/project/user/{goPage}/{pageSize}") @PostMapping("/current/project/user/{goPage}/{pageSize}")
@RequiresPermissions(value = {PermissionConstants.PROJECT_GROUP_READ}, logical = Logical.OR) @RequiresPermissions(value = {PermissionConstants.PROJECT_GROUP_READ}, logical = Logical.OR)
public Pager<List<User>> getCurrentProjectGroupUser(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody EditGroupRequest editGroupRequest) { public Pager<List<User>> getCurrentProjectGroupUser(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody EditGroupRequest editGroupRequest) {

View File

@ -67,6 +67,8 @@ public class GroupService {
private UserMapper userMapper; private UserMapper userMapper;
@Resource @Resource
private MicroService microService; private MicroService microService;
@Resource
private BaseUserService baseUserService;
private static final String GLOBAL = "global"; private static final String GLOBAL = "global";
// 服务权限拼装顺序 // 服务权限拼装顺序
@ -86,22 +88,27 @@ public class GroupService {
put(UserGroupType.PROJECT, "项目"); put(UserGroupType.PROJECT, "项目");
}}; }};
public Pager<List<GroupDTO>> getGroupList(EditGroupRequest request) { public Pager<List<GroupDTO>> getProjectGroupList(EditGroupRequest request) {
SessionUser user = SessionUtils.getUser(); SessionUser user = SessionUtils.getUser();
List<UserGroupDTO> userGroup = baseUserGroupMapper.getUserGroup(Objects.requireNonNull(user).getId(), request.getProjectId()); List<UserGroupDTO> userGroup = baseUserGroupMapper.getUserGroup(Objects.requireNonNull(user).getId(), request.getProjectId());
List<String> groupTypeList = userGroup.stream().map(UserGroupDTO::getType).distinct().collect(Collectors.toList()); List<String> groupTypeList = userGroup.stream().map(UserGroupDTO::getType).distinct().collect(Collectors.toList());
if (groupTypeList.isEmpty()) {
if (baseUserService.isSuperUser(user.getId())) {
groupTypeList.add(UserGroupType.PROJECT);
}
}
return getGroups(groupTypeList, request); return getGroups(groupTypeList, request);
} }
public void buildUserInfo(List<GroupDTO> testCases) { public void buildUserInfo(List<GroupDTO> groups) {
if (CollectionUtils.isEmpty(testCases)) { if (CollectionUtils.isEmpty(groups)) {
return; return;
} }
List<String> userIds = testCases.stream().map(GroupDTO::getCreator).collect(Collectors.toList()); List<String> userIds = groups.stream().map(GroupDTO::getCreator).collect(Collectors.toList());
if (!userIds.isEmpty()) { if (!userIds.isEmpty()) {
Map<String, String> userMap = ServiceUtils.getUserNameMap(userIds); Map<String, String> userMap = ServiceUtils.getUserNameMap(userIds);
testCases.forEach(caseResult -> { groups.forEach(caseResult -> {
caseResult.setCreator(userMap.get(caseResult.getCreator())); caseResult.setCreator(userMap.getOrDefault(caseResult.getCreator(), caseResult.getCreator()));
}); });
} }
} }
@ -142,6 +149,9 @@ public class GroupService {
} }
public void editGroup(EditGroupRequest request) { public void editGroup(EditGroupRequest request) {
if (StringUtils.equals(request.getId(), UserGroupConstants.SUPER_GROUP)) {
MSException.throwException("超级管理员无法编辑!");
}
if (StringUtils.equals(request.getId(), UserGroupConstants.ADMIN)) { if (StringUtils.equals(request.getId(), UserGroupConstants.ADMIN)) {
MSException.throwException("系统管理员无法编辑!"); MSException.throwException("系统管理员无法编辑!");
} }

View File

@ -5,14 +5,8 @@
<select id="getGroupList" resultType="io.metersphere.dto.GroupDTO"> <select id="getGroupList" resultType="io.metersphere.dto.GroupDTO">
SELECT *, SELECT *,
<if test="request.onlyQueryCurrentProject == true">
(SELECT COUNT(DISTINCT ug.user_id) FROM user_group ug JOIN user ON ug.user_id = user.id WHERE ug.group_id =
temp.id AND ug.source_id = #{request.projectId}) AS memberSize
</if>
<if test="request.onlyQueryCurrentProject == false">
(SELECT COUNT(DISTINCT ug.user_id) FROM user_group ug JOIN user ON ug.user_id = user.id WHERE ug.group_id = (SELECT COUNT(DISTINCT ug.user_id) FROM user_group ug JOIN user ON ug.user_id = user.id WHERE ug.group_id =
temp.id) AS memberSize temp.id) AS memberSize
</if>
FROM ( FROM (
SELECT g.*, w.name AS scopeName FROM `group` g, workspace w SELECT g.*, w.name AS scopeName FROM `group` g, workspace w
<where> <where>
@ -41,6 +35,17 @@
</foreach> </foreach>
</if> </if>
</where> </where>
UNION DISTINCT
SELECT g.*, 'system' AS scopeName FROM `group` g
<where>
g.scope_id = 'system'
<if test="request.types != null and request.types.size() > 0">
AND g.type IN
<foreach collection="request.types" item="type" separator="," open="(" close=")">
#{type}
</foreach>
</if>
</where>
union distinct union distinct
select g.*, p.name as scopeName from `group` g, project p select g.*, p.name as scopeName from `group` g, project p
<where> <where>
@ -63,7 +68,9 @@
WHERE temp.name LIKE CONCAT('%', #{request.name},'%') WHERE temp.name LIKE CONCAT('%', #{request.name},'%')
</if> </if>
<if test="request.orders == null or request.orders.size() == 0"> <if test="request.orders == null or request.orders.size() == 0">
ORDER BY field(temp.type, 'SYSTEM', 'ORGANIZATION', 'WORKSPACE', 'PROJECT'), temp.update_time, temp.name ORDER BY field(temp.type, 'SYSTEM', 'WORKSPACE', 'PROJECT'),
field(temp.scope_id, 'system') desc,
temp.update_time, temp.name
</if> </if>
<if test="request.orders != null and request.orders.size() > 0"> <if test="request.orders != null and request.orders.size() > 0">
ORDER BY ORDER BY

View File

@ -44,15 +44,6 @@ public class GroupController {
return groupService.getGroupList(request); return groupService.getGroupList(request);
} }
@PostMapping("/get/current/project/{goPage}/{pageSize}")
@RequiresPermissions(value = {PermissionConstants.PROJECT_GROUP_READ}, logical = Logical.OR)
public Pager<List<GroupDTO>> getCurrentProjectGroupList(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody EditGroupRequest request) {
request.setOnlyQueryCurrentProject(true);
request.setGoPage(goPage);
request.setPageSize(pageSize);
return groupService.getGroupList(request);
}
@GetMapping("/get/all") @GetMapping("/get/all")
public List<GroupDTO> getAllGroup() { public List<GroupDTO> getAllGroup() {
return groupService.getAllGroup(); return groupService.getAllGroup();
@ -134,17 +125,6 @@ public class GroupController {
return PageUtils.setPageInfo(page, groupService.getGroupUser(editGroupRequest)); return PageUtils.setPageInfo(page, groupService.getGroupUser(editGroupRequest));
} }
@PostMapping("/current/project/user/{goPage}/{pageSize}")
@RequiresPermissions(value = {PermissionConstants.PROJECT_GROUP_READ}, logical = Logical.OR)
public Pager<List<User>> getCurrentProjectGroupUser(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody EditGroupRequest editGroupRequest) {
editGroupRequest.setOnlyQueryCurrentProject(true);
if (StringUtils.isBlank(editGroupRequest.getProjectId())) {
editGroupRequest.setProjectId(SessionUtils.getCurrentProjectId());
}
Page<Object> page = PageHelper.startPage(goPage, pageSize, true);
return PageUtils.setPageInfo(page, groupService.getGroupUser(editGroupRequest));
}
@GetMapping("/rm/{userId}/{groupId}") @GetMapping("/rm/{userId}/{groupId}")
public void removeGroupMember(@PathVariable String userId, @PathVariable String groupId) { public void removeGroupMember(@PathVariable String userId, @PathVariable String groupId) {
groupService.removeGroupMember(userId, groupId); groupService.removeGroupMember(userId, groupId);

View File

@ -1,5 +1,6 @@
package io.metersphere.listener; package io.metersphere.listener;
import io.metersphere.commons.utils.LogUtil;
import io.metersphere.service.PlatformPluginService; import io.metersphere.service.PlatformPluginService;
import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner; import org.springframework.boot.ApplicationRunner;
@ -15,6 +16,7 @@ public class InitListener implements ApplicationRunner {
@Override @Override
public void run(ApplicationArguments applicationArguments) { public void run(ApplicationArguments applicationArguments) {
LogUtil.info("================= SYSTEM-SETTING 应用启动 =================");
platformPluginService.loadPlatFormPlugins(); platformPluginService.loadPlatFormPlugins();
} }
} }

View File

@ -68,11 +68,20 @@ public class GroupService {
private UserMapper userMapper; private UserMapper userMapper;
private static final String GLOBAL = "global"; private static final String GLOBAL = "global";
private static final String SUPER_GROUP = "super_group";
private static final String PERSONAL_PREFIX = "PERSONAL";
// 服务权限拼装顺序 // 服务权限拼装顺序
private static final String[] servicePermissionLoadOrder = {MicroServiceName.PROJECT_MANAGEMENT, private static final String[] servicePermissionLoadOrder = {
MicroServiceName.TEST_TRACK, MicroServiceName.API_TEST, MicroServiceName.UI_TEST, MicroServiceName.SYSTEM_SETTING,
MicroServiceName.PERFORMANCE_TEST, MicroServiceName.REPORT_STAT, MicroServiceName.SYSTEM_SETTING}; MicroServiceName.PROJECT_MANAGEMENT,
MicroServiceName.TEST_TRACK,
MicroServiceName.API_TEST,
MicroServiceName.UI_TEST,
MicroServiceName.PERFORMANCE_TEST,
MicroServiceName.REPORT_STAT
};
private static final Map<String, List<String>> map = new HashMap<>(4) {{ private static final Map<String, List<String>> map = new HashMap<>(4) {{
put(UserGroupType.SYSTEM, Arrays.asList(UserGroupType.SYSTEM, UserGroupType.WORKSPACE, UserGroupType.PROJECT)); put(UserGroupType.SYSTEM, Arrays.asList(UserGroupType.SYSTEM, UserGroupType.WORKSPACE, UserGroupType.PROJECT));
@ -93,14 +102,11 @@ public class GroupService {
return getGroups(groupTypeList, request); return getGroups(groupTypeList, request);
} }
public void buildUserInfo(List<GroupDTO> testCases) { public void buildUserInfo(List<GroupDTO> groups) {
List<String> userIds = new ArrayList(); List<String> userIds = groups.stream().map(GroupDTO::getCreator).collect(Collectors.toList());
userIds.addAll(testCases.stream().map(GroupDTO::getCreator).collect(Collectors.toList()));
if (!userIds.isEmpty()) { if (!userIds.isEmpty()) {
Map<String, String> userMap = ServiceUtils.getUserNameMap(userIds); Map<String, String> userMap = ServiceUtils.getUserNameMap(userIds);
testCases.forEach(caseResult -> { groups.forEach(caseResult -> caseResult.setCreator(userMap.getOrDefault(caseResult.getCreator(), caseResult.getCreator())));
caseResult.setCreator(userMap.get(caseResult.getCreator()));
});
} }
} }
@ -140,6 +146,9 @@ public class GroupService {
} }
public void editGroup(EditGroupRequest request) { public void editGroup(EditGroupRequest request) {
if (StringUtils.equals(request.getId(), UserGroupConstants.SUPER_GROUP)) {
MSException.throwException("超级管理员无法编辑!");
}
if (StringUtils.equals(request.getId(), UserGroupConstants.ADMIN)) { if (StringUtils.equals(request.getId(), UserGroupConstants.ADMIN)) {
MSException.throwException("系统管理员无法编辑!"); MSException.throwException("系统管理员无法编辑!");
} }
@ -176,19 +185,22 @@ public class GroupService {
example.createCriteria().andGroupIdEqualTo(group.getId()); example.createCriteria().andGroupIdEqualTo(group.getId());
List<UserGroupPermission> groupPermissions = userGroupPermissionMapper.selectByExample(example); List<UserGroupPermission> groupPermissions = userGroupPermissionMapper.selectByExample(example);
List<String> groupPermissionIds = groupPermissions.stream().map(UserGroupPermission::getPermissionId).collect(Collectors.toList()); List<String> groupPermissionIds = groupPermissions.stream().map(UserGroupPermission::getPermissionId).collect(Collectors.toList());
GroupJson groupJson = this.loadPermissionJsonFromService(); GroupJson groupJson = this.loadPermissionJsonFromService();
if (groupJson == null) { if (groupJson == null) {
MSException.throwException(Translator.get("read_permission_file_fail")); MSException.throwException(Translator.get("read_permission_file_fail"));
} }
List<GroupResource> resource = groupJson.getResource(); List<GroupResource> resource = groupJson.getResource();
List<GroupPermission> permissions = groupJson.getPermissions(); List<GroupPermission> permissions = groupJson.getPermissions();
List<GroupResourceDTO> dtoPermissions = dto.getPermissions(); List<GroupResourceDTO> dtoPermissions = dto.getPermissions();
dtoPermissions.addAll(getResourcePermission(resource, permissions, group.getType(), groupPermissionIds)); dtoPermissions.addAll(getResourcePermission(resource, permissions, group, groupPermissionIds));
return dto; return dto;
} }
private GroupJson loadPermissionJsonFromService() { private GroupJson loadPermissionJsonFromService() {
GroupJson groupJson = null; GroupJson groupJson = null;
List<GroupResource> globalResource = new ArrayList<>();
try { try {
for (String service : servicePermissionLoadOrder) { for (String service : servicePermissionLoadOrder) {
Object obj = stringRedisTemplate.opsForHash().get(RedisKey.MS_PERMISSION_KEY, service); Object obj = stringRedisTemplate.opsForHash().get(RedisKey.MS_PERMISSION_KEY, service);
@ -199,11 +211,23 @@ public class GroupService {
GroupJson temp = JSON.parseObject((String) obj, GroupJson.class); GroupJson temp = JSON.parseObject((String) obj, GroupJson.class);
if (groupJson == null) { if (groupJson == null) {
groupJson = temp; groupJson = temp;
// 全局权限放系统设置模块
if (StringUtils.equals(service, MicroServiceName.SYSTEM_SETTING)) {
globalResource = temp.getResource()
.stream()
.filter(gp -> BooleanUtils.isTrue(gp.isGlobal()))
.collect(Collectors.toList());
temp.getResource().removeIf(gp -> BooleanUtils.isTrue(gp.isGlobal()));
}
} else { } else {
groupJson.getResource().addAll(temp.getResource()); groupJson.getResource().addAll(temp.getResource());
groupJson.getPermissions().addAll(temp.getPermissions()); groupJson.getPermissions().addAll(temp.getPermissions());
} }
} }
// 拼装权限的时候放在最后
if (groupJson != null && !globalResource.isEmpty()) {
groupJson.getResource().addAll(globalResource);
}
} catch (Exception e) { } catch (Exception e) {
LogUtil.error(e); LogUtil.error(e);
} }
@ -292,8 +316,7 @@ public class GroupService {
scopeList = Arrays.asList(GLOBAL, resourceId, request.getProjectId()); scopeList = Arrays.asList(GLOBAL, resourceId, request.getProjectId());
} }
GroupExample groupExample = new GroupExample(); GroupExample groupExample = new GroupExample();
groupExample.createCriteria().andScopeIdIn(scopeList) groupExample.createCriteria().andScopeIdIn(scopeList).andTypeEqualTo(type);
.andTypeEqualTo(type);
return groupMapper.selectByExample(groupExample); return groupMapper.selectByExample(groupExample);
} }
@ -301,15 +324,23 @@ public class GroupService {
return baseUserGroupMapper.getWorkspaceMemberGroups(workspaceId, userId); return baseUserGroupMapper.getWorkspaceMemberGroups(workspaceId, userId);
} }
private List<GroupResourceDTO> getResourcePermission(List<GroupResource> resource, List<GroupPermission> permissions, String type, List<String> permissionList) { private List<GroupResourceDTO> getResourcePermission(List<GroupResource> resources, List<GroupPermission> permissions, Group group, List<String> permissionList) {
List<GroupResourceDTO> dto = new ArrayList<>(); List<GroupResourceDTO> dto = new ArrayList<>();
List<GroupResource> resources = resource.stream().filter(g -> g.getId().startsWith(type) || g.getId().startsWith("PERSONAL")).collect(Collectors.toList()); List<GroupResource> grs;
if (StringUtils.equals(group.getId(), SUPER_GROUP)) {
grs = resources;
} else {
grs = resources
.stream()
.filter(g -> g.getId().startsWith(group.getType()) || g.getId().startsWith(PERSONAL_PREFIX))
.collect(Collectors.toList());
}
permissions.forEach(p -> { permissions.forEach(p -> {
if (permissionList.contains(p.getId())) { if (permissionList.contains(p.getId())) {
p.setChecked(true); p.setChecked(true);
} }
}); });
for (GroupResource r : resources) { for (GroupResource r : grs) {
GroupResourceDTO resourceDTO = new GroupResourceDTO(); GroupResourceDTO resourceDTO = new GroupResourceDTO();
resourceDTO.setResource(r); resourceDTO.setResource(r);
List<GroupPermission> collect = permissions List<GroupPermission> collect = permissions
@ -453,9 +484,14 @@ public class GroupService {
UserGroupExample userGroupExample = new UserGroupExample(); UserGroupExample userGroupExample = new UserGroupExample();
userGroupExample.createCriteria().andUserIdEqualTo(userId).andGroupIdEqualTo(group.getId()); userGroupExample.createCriteria().andUserIdEqualTo(userId).andGroupIdEqualTo(group.getId());
List<UserGroup> userGroups = userGroupMapper.selectByExample(userGroupExample); List<UserGroup> userGroups = userGroupMapper.selectByExample(userGroupExample);
if (userGroups.size() <= 0) { if (userGroups.size() == 0) {
UserGroup userGroup = new UserGroup(UUID.randomUUID().toString(), userId, group.getId(), UserGroup userGroup = new UserGroup(
"system", System.currentTimeMillis(), System.currentTimeMillis()); UUID.randomUUID().toString(),
userId,
group.getId(),
"system",
System.currentTimeMillis(),
System.currentTimeMillis());
userGroupMapper.insertSelective(userGroup); userGroupMapper.insertSelective(userGroup);
} }
} }

View File

@ -195,14 +195,6 @@ public class SystemProjectService {
return baseProjectMapper.getProjectWithWorkspace(request); return baseProjectMapper.getProjectWithWorkspace(request);
} }
public List<ProjectDTO> getUserProject(ProjectRequest request) {
if (StringUtils.isNotBlank(request.getName())) {
request.setName(StringUtils.wrapIfMissing(request.getName(), "%"));
}
request.setOrders(ServiceUtils.getDefaultOrder(request.getOrders()));
return baseProjectMapper.getUserProject(request);
}
public List<Project> getProjectByIds(List<String> ids) { public List<Project> getProjectByIds(List<String> ids) {
if (!CollectionUtils.isEmpty(ids)) { if (!CollectionUtils.isEmpty(ids)) {
ProjectExample example = new ProjectExample(); ProjectExample example = new ProjectExample();

View File

@ -85,6 +85,8 @@ public class UserService {
private BaseProjectMapper baseProjectMapper; private BaseProjectMapper baseProjectMapper;
@Resource @Resource
private BaseWorkspaceMapper baseWorkspaceMapper; private BaseWorkspaceMapper baseWorkspaceMapper;
@Resource
private BaseUserService baseUserService;
public List<UserDetail> queryTypeByIds(List<String> userIds) { public List<UserDetail> queryTypeByIds(List<String> userIds) {
return baseUserMapper.queryTypeByIds(userIds); return baseUserMapper.queryTypeByIds(userIds);
@ -412,20 +414,45 @@ public class UserService {
public void addMember(AddMemberRequest request) { public void addMember(AddMemberRequest request) {
if (!CollectionUtils.isEmpty(request.getUserIds())) { if (CollectionUtils.isEmpty(request.getUserIds())
|| CollectionUtils.isEmpty(request.getGroupIds())) {
LogUtil.warn("user ids or group ids is empty.");
return;
}
if (CollectionUtils.isNotEmpty(request.getUserIds())) {
QuotaService quotaService = CommonBeanFactory.getBean(QuotaService.class); QuotaService quotaService = CommonBeanFactory.getBean(QuotaService.class);
checkQuota(quotaService, "WORKSPACE", Collections.singletonList(request.getWorkspaceId()), request.getUserIds()); checkQuota(quotaService, "WORKSPACE", Collections.singletonList(request.getWorkspaceId()), request.getUserIds());
}
List<String> allUserIds = baseUserService.getAllUserIds();
GroupExample groupExample = new GroupExample();
groupExample.createCriteria().andTypeEqualTo(UserGroupType.WORKSPACE);
List<Group> wsGroups = groupMapper.selectByExample(groupExample);
List<String> wsGroupIds = wsGroups
.stream()
.map(Group::getId)
.collect(Collectors.toList());
for (String userId : request.getUserIds()) { for (String userId : request.getUserIds()) {
if (!allUserIds.contains(userId)) {
LogUtil.warn("user id {} is not exist!", userId);
continue;
}
UserGroupExample userGroupExample = new UserGroupExample(); UserGroupExample userGroupExample = new UserGroupExample();
userGroupExample.createCriteria().andUserIdEqualTo(userId).andSourceIdEqualTo(request.getWorkspaceId()); userGroupExample.createCriteria().andUserIdEqualTo(userId).andSourceIdEqualTo(request.getWorkspaceId());
List<UserGroup> userGroups = userGroupMapper.selectByExample(userGroupExample); List<UserGroup> userGroups = userGroupMapper.selectByExample(userGroupExample);
if (userGroups.size() > 0) { if (userGroups.size() > 0) {
MSException.throwException(Translator.get("user_already_exists")); MSException.throwException(Translator.get("user_already_exists"));
} else { }
for (String groupId : request.getGroupIds()) { for (String groupId : request.getGroupIds()) {
if (!wsGroupIds.contains(groupId)) {
LogUtil.warn("group id {} is not exist or not belong to workspace level.", groupId);
continue;
}
UserGroup userGroup = new UserGroup(); UserGroup userGroup = new UserGroup();
userGroup.setGroupId(groupId); userGroup.setGroupId(groupId);
userGroup.setSourceId(request.getWorkspaceId()); userGroup.setSourceId(request.getWorkspaceId());
@ -437,8 +464,6 @@ public class UserService {
} }
} }
} }
}
}
public void deleteMember(String workspaceId, String userId) { public void deleteMember(String workspaceId, String userId) {
GroupExample groupExample = new GroupExample(); GroupExample groupExample = new GroupExample();
@ -1240,7 +1265,7 @@ public class UserService {
private void addGroupMember(String type, String sourceId, List<String> userIds, List<String> groupIds) { private void addGroupMember(String type, String sourceId, List<String> userIds, List<String> groupIds) {
if (!StringUtils.equalsAny(type, "PROJECT", "WORKSPACE") || StringUtils.isBlank(sourceId) if (!StringUtils.equalsAny(type, "PROJECT", "WORKSPACE") || StringUtils.isBlank(sourceId)
|| CollectionUtils.isEmpty(userIds) || CollectionUtils.isEmpty(groupIds)) { || CollectionUtils.isEmpty(userIds) || CollectionUtils.isEmpty(groupIds)) {
LogUtil.info("add member warning, please check param!"); LogUtil.warn("add member warning, please check param!");
return; return;
} }
this.checkQuotaOfMemberSize(type, sourceId, userIds); this.checkQuotaOfMemberSize(type, sourceId, userIds);
@ -1248,7 +1273,7 @@ public class UserService {
for (String userId : userIds) { for (String userId : userIds) {
User user = userMapper.selectByPrimaryKey(userId); User user = userMapper.selectByPrimaryKey(userId);
if (user == null) { if (user == null) {
LogUtil.info("add member warning, invalid user id: " + userId); LogUtil.warn("add member warning, invalid user id: " + userId);
continue; continue;
} }
List<String> toAddGroupIds = new ArrayList<>(groupIds); List<String> toAddGroupIds = new ArrayList<>(groupIds);
@ -1260,8 +1285,13 @@ public class UserService {
continue; continue;
} }
for (String groupId : toAddGroupIds) { for (String groupId : toAddGroupIds) {
UserGroup userGroup = new UserGroup(UUID.randomUUID().toString(), userId, groupId, UserGroup userGroup = new UserGroup(
sourceId, System.currentTimeMillis(), System.currentTimeMillis()); UUID.randomUUID().toString(),
userId,
groupId,
sourceId,
System.currentTimeMillis(),
System.currentTimeMillis());
userGroupMapper.insertSelective(userGroup); userGroupMapper.insertSelective(userGroup);
} }
} }

View File

@ -347,6 +347,10 @@
"id": "SYSTEM_OPERATING_LOG", "id": "SYSTEM_OPERATING_LOG",
"name": "permission.system_operation_log.name" "name": "permission.system_operation_log.name"
}, },
{
"id": "SYSTEM_PLUGIN",
"name": "permission.system_plugin.name"
},
{ {
"id": "WORKSPACE_USER", "id": "WORKSPACE_USER",
"name": "permission.workspace_user.name" "name": "permission.workspace_user.name"
@ -372,13 +376,10 @@
"id": "WORKSPACE_OPERATING_LOG", "id": "WORKSPACE_OPERATING_LOG",
"name": "permission.workspace_operation_log.name" "name": "permission.workspace_operation_log.name"
}, },
{
"id": "SYSTEM_PLUGIN",
"name": "permission.system_plugin.name"
},
{ {
"id": "PERSONAL_INFORMATION", "id": "PERSONAL_INFORMATION",
"name": "permission.personal_information.name" "name": "permission.personal_information.name",
"global": true
} }
] ]
} }

View File

@ -99,7 +99,7 @@ export default {
}, },
isReadOnly() { isReadOnly() {
return function (data) { return function (data) {
const isDefaultSystemGroup = this.group.id === 'admin' && data.resource.id === 'SYSTEM_GROUP'; const isDefaultSystemGroup = (this.group.id === 'admin' || this.group.id === 'super_group') && data.resource.id === 'SYSTEM_GROUP';
return this.readOnly || isDefaultSystemGroup; return this.readOnly || isDefaultSystemGroup;
} }
} }
@ -143,8 +143,13 @@ export default {
}, },
_getUniteMenu() { _getUniteMenu() {
let menu = ['TRACK', 'API', 'UI', 'PERFORMANCE', 'REPORT']; let menu = ['TRACK', 'API', 'UI', 'PERFORMANCE', 'REPORT'];
// PROJECT_USER
let isFirstProjectType = false;
for (let i = 0; i < this.tableData.length; i++) { for (let i = 0; i < this.tableData.length; i++) {
if (i === 0) { if (i === 0) {
if (this.tableData[i].type === GROUP_TYPE.PROJECT) {
isFirstProjectType = true;
}
this.spanArr.push(1); this.spanArr.push(1);
this.pos = 0 this.pos = 0
} else { } else {
@ -153,8 +158,13 @@ export default {
if (this.tableData[i].type !== GROUP_TYPE.PROJECT) { if (this.tableData[i].type !== GROUP_TYPE.PROJECT) {
sign = this.tableData[i].type === this.tableData[i - 1].type; sign = this.tableData[i].type === this.tableData[i - 1].type;
} else { } else {
sign = !menu.includes(this.tableData[i].resource.id.split('_')[1]) ? let hasSubModule = menu.includes(this.tableData[i].resource.id.split('_')[1]);
true : this.tableData[i].resource.id.split('_')[1] === this.tableData[i - 1].resource.id.split('_')[1] if (hasSubModule) {
sign = this.tableData[i].resource.id.split('_')[1] === this.tableData[i - 1].resource.id.split('_')[1];
} else {
sign = isFirstProjectType;
isFirstProjectType = true;
}
} }
if (sign) { if (sign) {
this.spanArr[this.pos] += 1; this.spanArr[this.pos] += 1;

View File

@ -47,7 +47,7 @@ export default {
return function (permission) { return function (permission) {
// //
const isSystemGroupPermission = permission.id === 'SYSTEM_GROUP:READ' || permission.id === 'SYSTEM_GROUP:READ+SETTING_PERMISSION'; const isSystemGroupPermission = permission.id === 'SYSTEM_GROUP:READ' || permission.id === 'SYSTEM_GROUP:READ+SETTING_PERMISSION';
const isDefaultSystemGroup = this.group.id === 'admin' && isSystemGroupPermission; const isDefaultSystemGroup = (this.group.id === 'admin' || this.group.id === 'super_group') && isSystemGroupPermission;
return this.readOnly || isDefaultSystemGroup; return this.readOnly || isDefaultSystemGroup;
} }
} }

View File

@ -28,6 +28,7 @@
<el-table-column prop="scopeName" :label="$t('group.scope')"> <el-table-column prop="scopeName" :label="$t('group.scope')">
<template v-slot="scope"> <template v-slot="scope">
<span v-if="scope.row.scopeId ==='global'">{{ $t('group.global') }}</span> <span v-if="scope.row.scopeId ==='global'">{{ $t('group.global') }}</span>
<span v-else-if="scope.row.scopeId ==='system'">{{ $t('group.system') }}</span>
<span v-else>{{ scope.row.scopeName }}</span> <span v-else>{{ scope.row.scopeName }}</span>
</template> </template>
</el-table-column> </el-table-column>
@ -42,10 +43,22 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="creator" :label="$t('group.operator')"/> <el-table-column prop="creator" :label="$t('group.operator')"/>
<el-table-column prop="description" :label="$t('group.description')"/> <el-table-column prop="description" :label="$t('group.description')" show-overflow-tooltip/>
<el-table-column :label="$t('commons.operating')" min-width="120"> <el-table-column :label="$t('commons.operating')" min-width="120">
<template v-slot:default="scope"> <template v-slot="scope">
<div> <div v-if="scope.row.id === 'super_group'">
<ms-table-operator
:is-show="true"
@editClick="edit(scope.row)" @deleteClick="del(scope.row)">
<template v-slot:middle>
<ms-table-operator-button
v-permission="['SYSTEM_GROUP:READ+SETTING_PERMISSION']"
:tip="$t('group.set_permission')" icon="el-icon-s-tools"
@exec="setPermission(scope.row)"/>
</template>
</ms-table-operator>
</div>
<div v-else>
<ms-table-operator <ms-table-operator
:edit-permission="['SYSTEM_GROUP:READ+EDIT']" :edit-permission="['SYSTEM_GROUP:READ+EDIT']"
:delete-permission="['SYSTEM_GROUP:READ+DELETE']" :delete-permission="['SYSTEM_GROUP:READ+DELETE']"

View File

@ -360,6 +360,9 @@ export default {
let data = res.data; let data = res.data;
if (data) { if (data) {
this._setResource(data, index, type); this._setResource(data, index, type);
if (id === 'super_group') {
return;
}
if (isHaveWorkspace === false) { if (isHaveWorkspace === false) {
this.addWorkspaceGroup(id, index); this.addWorkspaceGroup(id, index);
} }