feat(项目管理): 项目增加查询组织下的有权限的项目的接口

This commit is contained in:
wxg0103 2023-08-30 12:47:27 +08:00 committed by 刘瑞斌
parent 5b5e931a77
commit d9f11ca900
23 changed files with 395 additions and 150 deletions

View File

@ -117,4 +117,5 @@ public class PermissionConstants {
public static final String PROJECT_APPLICATION_TEST_PLAN_READ = "PROJECT_APPLICATION_TEST_PLAN:READ";
public static final String PROJECT_APPLICATION_TEST_PLAN_UPDATE = "PROJECT_APPLICATION_TEST_PLAN:UPDATE";
public static final String PROJECT_BASE_INFO_READ = "PROJECT_BASE_INFO:READ";
}

View File

@ -13,7 +13,7 @@ import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/license")
@Tag(name="license校验")
@Tag(name = "系统设置-系统-授权管理")
public class LicenseController {
@GetMapping("/validate")
@Operation(summary = "license校验")

View File

@ -71,7 +71,7 @@ public class OperationLogModule {
public static final String SETTING_ORGANIZATION_USER_ROLE = "SETTING_ORGANIZATION_USER_ROLE";
//系统设置-组织-项目
public static final String SETTING_SYSTEM_ORGANIZATION_PROJECT = "SETTING_SYSTEM_ORGANIZATION_PROJECT";
public static final String SETTING_ORGANIZATION_PROJECT = "SETTING_ORGANIZATION_PROJECT";
//项目管理
public static final String PROJECT_MANAGEMENT = "PROJECT_MANAGEMENT"; // 项目管理

View File

@ -107,4 +107,5 @@ permission.project_fake_error.name=Fake error
permission.project_application.name=Project application
permission.project_application_test_plan.read=Test plan read
permission.project_application_test_plan.update=Test plan update
permission.project_base_info.name=Project base info

View File

@ -107,3 +107,4 @@ permission.project_fake_error.name=误报库
permission.project_application.name=应用管理
permission.project_application_test_plan.read=测试计划-查询
permission.project_application_test_plan.update=测试计划-编辑
permission.project_base_info.name=基础信息

View File

@ -106,4 +106,5 @@ permission.project_message.name=消息管理
permission.project_fake_error.name=誤報庫
permission.project_application.name=應用管理
permission.project_application_test_plan.read=測試計劃-查詢
permission.project_application_test_plan.update=測試計劃-編輯
permission.project_application_test_plan.update=測試計劃-編輯
permission.project_base_info.name=基礎信息

View File

@ -1,33 +1,45 @@
package io.metersphere.project.controller;
import io.metersphere.project.domain.Project;
import io.metersphere.project.request.ProjectSwitchRequest;
import io.metersphere.project.service.ProjectService;
import io.metersphere.validation.groups.Created;
import io.metersphere.validation.groups.Updated;
import io.metersphere.sdk.constants.PermissionConstants;
import io.metersphere.sdk.dto.ProjectExtendDTO;
import io.metersphere.sdk.dto.UserDTO;
import io.metersphere.sdk.util.SessionUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("project")
@Tag(name = "项目管理")
@RequestMapping("/project")
public class ProjectController {
@Resource
private ProjectService projectService;
@GetMapping("list-all")
public List<Project> selectAll() {
return projectService.list();
@GetMapping("/get/{id}")
@Operation(summary = "基本信息")
@RequiresPermissions(PermissionConstants.PROJECT_BASE_INFO_READ)
public ProjectExtendDTO getProject(@PathVariable String id) {
return projectService.getProjectById(id);
}
@PostMapping("add")
public Project add(@Validated({Created.class}) @RequestBody Project project) {
return projectService.add(project);
@GetMapping("/list/options/{organizationId}")
@Operation(summary = "根据项目ID获取所有有权限的项目")
@RequiresPermissions(PermissionConstants.PROJECT_BASE_INFO_READ)
public List<Project> getUserProject(@PathVariable String organizationId) {
return projectService.getUserProject(organizationId, SessionUtils.getUserId());
}
@PostMapping("edit")
public Project edit(@Validated({Updated.class}) @RequestBody Project project) {
return projectService.edit(project);
@PostMapping("/switch")
@Operation(summary = "切换项目")
@RequiresPermissions(PermissionConstants.PROJECT_BASE_INFO_READ)
public UserDTO switchProject(@RequestBody ProjectSwitchRequest request) {
return projectService.switchProject(request, SessionUtils.getUserId());
}
}

View File

@ -0,0 +1,11 @@
package io.metersphere.project.mapper;
import io.metersphere.project.domain.Project;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface ExtProjectMapper {
List<Project> getUserProject(@Param("organizationId") String organizationId, @Param("userId") String userId);
}

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="io.metersphere.project.mapper.ExtProjectMapper">
<select id="getUserProject" resultType="io.metersphere.project.domain.Project">
SELECT DISTINCT p.*
FROM user_role u
JOIN user_role_relation urr ON u.id = urr.role_id
JOIN project p ON p.id = urr.source_id
JOIN user on urr.user_id = user.id
where urr.user_id = #{userId} and u.type = 'PROJECT'
AND p.organization_id = #{organizationId} and p.enable = 1 and user.deleted = 0
</select>
</mapper>

View File

@ -0,0 +1,17 @@
package io.metersphere.project.request;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.Data;
@Data
public class ProjectSwitchRequest {
@Schema(description = "项目ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{project.id.not_blank}")
@Size(min = 1, max = 50, message = "{project.id.length_range}")
private String projectId;
@Schema(description = "用户ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{user.id.not_blank}")
private String userId;
}

View File

@ -2,34 +2,92 @@ package io.metersphere.project.service;
import io.metersphere.project.domain.Project;
import io.metersphere.project.domain.ProjectExample;
import io.metersphere.project.mapper.ExtProjectMapper;
import io.metersphere.project.mapper.ProjectMapper;
import io.metersphere.project.request.ProjectSwitchRequest;
import io.metersphere.sdk.constants.InternalUserRole;
import io.metersphere.sdk.dto.ProjectExtendDTO;
import io.metersphere.sdk.dto.SessionUser;
import io.metersphere.sdk.dto.UserDTO;
import io.metersphere.sdk.exception.MSException;
import io.metersphere.sdk.service.BaseUserService;
import io.metersphere.sdk.util.BeanUtils;
import io.metersphere.sdk.util.JSON;
import io.metersphere.sdk.util.SessionUtils;
import io.metersphere.sdk.util.Translator;
import io.metersphere.system.domain.User;
import io.metersphere.system.domain.UserRoleRelation;
import io.metersphere.system.domain.UserRoleRelationExample;
import io.metersphere.system.mapper.OrganizationMapper;
import io.metersphere.system.mapper.UserRoleRelationMapper;
import jakarta.annotation.Resource;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.UUID;
@Service
@Transactional(rollbackFor = Exception.class)
public class ProjectService {
@Resource
private ProjectMapper projectMapper;
@Resource
private UserRoleRelationMapper userRoleRelationMapper;
@Resource
private ExtProjectMapper extProjectMapper;
@Resource
private BaseUserService baseUserService;
@Resource
private OrganizationMapper organizationMapper;
public List<Project> list() {
return projectMapper.selectByExample(new ProjectExample());
public List<Project> getUserProject(String organizationId, String userId) {
if (organizationMapper.selectByPrimaryKey(organizationId) == null) {
throw new MSException(Translator.get("organization_not_exist"));
}
//判断用户是否是系统管理员
UserRoleRelationExample userRoleRelationExample = new UserRoleRelationExample();
userRoleRelationExample.createCriteria().andUserIdEqualTo(userId).andRoleIdEqualTo(InternalUserRole.ADMIN.name());
List<UserRoleRelation> list = userRoleRelationMapper.selectByExample(userRoleRelationExample);
if (CollectionUtils.isNotEmpty(list)) {
ProjectExample example = new ProjectExample();
example.createCriteria().andOrganizationIdEqualTo(organizationId).andEnableEqualTo(true);
return projectMapper.selectByExample(example);
}
return extProjectMapper.getUserProject(organizationId, userId);
}
public Project add(Project project) {
project.setId(UUID.randomUUID().toString());
project.setCreateTime(System.currentTimeMillis());
project.setUpdateTime(System.currentTimeMillis());
projectMapper.insertSelective(project);
return project;
public UserDTO switchProject(ProjectSwitchRequest request, String currentUserId) {
if (!StringUtils.equals(currentUserId, request.getUserId())) {
throw new MSException(Translator.get("not_authorized"));
}
if (projectMapper.selectByPrimaryKey(request.getProjectId()) == null) {
throw new MSException(Translator.get("project_not_exist"));
}
User user = new User();
user.setId(request.getUserId());
user.setLastProjectId(request.getProjectId());
baseUserService.updateUser(user);
UserDTO userDTO = baseUserService.getUserDTO(user.getId());
SessionUtils.putUser(SessionUser.fromUser(userDTO, SessionUtils.getSessionId()));
return SessionUtils.getUser();
}
public Project edit(Project project) {
projectMapper.updateByPrimaryKeySelective(project);
return projectMapper.selectByPrimaryKey(project.getId());
public ProjectExtendDTO getProjectById(String id) {
Project project = projectMapper.selectByPrimaryKey(id);
ProjectExtendDTO projectExtendDTO = new ProjectExtendDTO();
if (ObjectUtils.isNotEmpty(project)) {
BeanUtils.copyBean(projectExtendDTO, project);
if (StringUtils.isNotEmpty(project.getModuleSetting())) {
projectExtendDTO.setModuleIds(JSON.parseArray(project.getModuleSetting(), String.class));
}
} else {
return null;
}
return projectExtendDTO;
}
}

View File

@ -4,6 +4,15 @@
"name": "permission.project.name",
"type": "PROJECT",
"children": [
{
"id": "PROJECT_BASE_INFO",
"name": "permission.project.read",
"permissions": [
{
"id": "PROJECT:READ"
}
]
},
{
"id": "PROJECT_USER",
"name": "permission.project_user.name",

View File

@ -1,19 +1,31 @@
package io.metersphere.project.controller;
import com.jayway.jsonpath.JsonPath;
import io.metersphere.project.domain.Project;
import io.metersphere.project.domain.ProjectExample;
import io.metersphere.project.mapper.ProjectMapper;
import io.metersphere.project.request.ProjectSwitchRequest;
import io.metersphere.sdk.base.BaseTest;
import io.metersphere.sdk.constants.PermissionConstants;
import io.metersphere.sdk.constants.SessionConstants;
import io.metersphere.sdk.controller.handler.ResultHolder;
import io.metersphere.sdk.dto.ProjectExtendDTO;
import io.metersphere.sdk.dto.UserDTO;
import io.metersphere.sdk.util.JSON;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.api.*;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.test.context.jdbc.SqlConfig;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import java.nio.charset.StandardCharsets;
import java.util.List;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@ -24,57 +36,165 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
public class ProjectControllerTests extends BaseTest {
@Resource
private MockMvc mockMvc;
private static final String prefix = "/project";
private static final String getOptions = prefix + "/list/options/";
@Resource
private ProjectMapper projectMapper;
// 添加项目
// @Test
// @Order(1)
// public void testAddProject() throws Exception {
// Project project = new Project();
// project.setName("test");
// project.setCreateUser("admin");
// project.setOrganizationId("default");
//
//
// var result = mockMvc.perform(MockMvcRequestBuilders.post("/project/add")
// .header(SessionConstants.HEADER_TOKEN, sessionId)
// .header(SessionConstants.CSRF_TOKEN, csrfToken)
// .content(JSON.toJSONString(project))
// .contentType(MediaType.APPLICATION_JSON))
// .andExpect(status().isOk())
// .andExpect(content().contentType(MediaType.APPLICATION_JSON))
// .andReturn();
// projectId = JsonPath.read(result.getResponse().getContentAsString(), "$.data.id");
// }
//
// @Test
// @Order(2)
// public void testEditProject() throws Exception {
// Project project = new Project();
// project.setId(projectId);
// project.setName("test2");
// project.setCreateUser("admin");
// project.setOrganizationId("default");
//
// mockMvc.perform(MockMvcRequestBuilders.post("/project/edit")
// .header(SessionConstants.HEADER_TOKEN, sessionId)
// .header(SessionConstants.CSRF_TOKEN, csrfToken)
// .content(JSON.toJSONString(project))
// .contentType(MediaType.APPLICATION_JSON))
// .andExpect(status().isOk())
// .andExpect(content().contentType(MediaType.APPLICATION_JSON))
// ;
// }
//
// @Test
// @Order(3)
// public void testSelectAll() throws Exception {
// mockMvc.perform(MockMvcRequestBuilders.get("/project/list-all")
// .header(SessionConstants.HEADER_TOKEN, sessionId)
// .header(SessionConstants.CSRF_TOKEN, csrfToken))
// .andExpect(status().isOk())
// .andExpect(content().contentType(MediaType.APPLICATION_JSON))
// // .andExpect(jsonPath("$.person.name").value("Jason"))
// ;
// }
public static <T> T parseObjectFromMvcResult(MvcResult mvcResult, Class<T> parseClass) {
try {
String returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
ResultHolder resultHolder = JSON.parseObject(returnData, ResultHolder.class);
//返回请求正常
Assertions.assertNotNull(resultHolder);
return JSON.parseObject(JSON.toJSONString(resultHolder.getData()), parseClass);
} catch (Exception ignore) {
}
return null;
}
private MvcResult responseGet(String url) throws Exception {
return mockMvc.perform(MockMvcRequestBuilders.get(url)
.header(SessionConstants.HEADER_TOKEN, sessionId)
.header(SessionConstants.CSRF_TOKEN, csrfToken)
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON)).andReturn();
}
@Test
@Order(1)
@Sql(scripts = {"/dml/init_project.sql"},
config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED),
executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
public void testGetProject() throws Exception {
MvcResult mvcResult = responseGet(prefix + "/get/projectId");
ProjectExtendDTO getProjects = parseObjectFromMvcResult(mvcResult, ProjectExtendDTO.class);
Assertions.assertNotNull(getProjects);
//权限校验
requestGetPermissionTest(PermissionConstants.PROJECT_BASE_INFO_READ, prefix + "/get/projectId");
}
@Test
@Order(2)
public void testGetProjectError() throws Exception {
//项目不存在
MvcResult mvcResult = this.responseGet(prefix + "/get/111111");
ProjectExtendDTO project = parseObjectFromMvcResult(mvcResult, ProjectExtendDTO.class);
Assertions.assertNull(project);
}
@Test
@Order(3)
public void testGetOptionsSuccess() throws Exception {
MvcResult mvcResult = this.responseGet(getOptions + "default_organization");
List<Project> list = parseObjectFromMvcResult(mvcResult, List.class);
Assertions.assertNotNull(list);
ProjectExample example = new ProjectExample();
example.createCriteria().andOrganizationIdEqualTo("default_organization").andEnableEqualTo(true);
Assertions.assertEquals(projectMapper.countByExample(example), list.size());
mvcResult = mockMvc.perform(MockMvcRequestBuilders.post("/login")
.content(String.format("{\"username\":\"%s\",\"password\":\"%s\"}", "admin1", "admin1@metersphere.io"))
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andReturn();
String sessionId = JsonPath.read(mvcResult.getResponse().getContentAsString(), "$.data.sessionId");
String csrfToken = JsonPath.read(mvcResult.getResponse().getContentAsString(), "$.data.csrfToken");
mvcResult = mockMvc.perform(MockMvcRequestBuilders.get(getOptions + "default_organization")
.header(SessionConstants.HEADER_TOKEN, sessionId)
.header(SessionConstants.CSRF_TOKEN, csrfToken)
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON)).andReturn();
list = parseObjectFromMvcResult(mvcResult, List.class);
Assertions.assertNotNull(list);
//被删除的用户 查出来的是空的
mvcResult = mockMvc.perform(MockMvcRequestBuilders.post("/login")
.content(String.format("{\"username\":\"%s\",\"password\":\"%s\"}", "delete", "deleted@metersphere.io"))
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andReturn();
sessionId = JsonPath.read(mvcResult.getResponse().getContentAsString(), "$.data.sessionId");
csrfToken = JsonPath.read(mvcResult.getResponse().getContentAsString(), "$.data.csrfToken");
mvcResult = mockMvc.perform(MockMvcRequestBuilders.get(getOptions + "default_organization")
.header(SessionConstants.HEADER_TOKEN, sessionId)
.header(SessionConstants.CSRF_TOKEN, csrfToken)
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON)).andReturn();
list = parseObjectFromMvcResult(mvcResult, List.class);
//断言list是空的
Assertions.assertEquals(0, list.size());
//权限校验
requestGetPermissionTest(PermissionConstants.PROJECT_BASE_INFO_READ, getOptions + "default_organization");
}
@Test
@Order(4)
public void testGetOptionsError() throws Exception {
//组织不存在
requestGet(getOptions + "111111", status().is5xxServerError());
}
@Test
@Order(5)
public void testSwitchProject() throws Exception {
//切换项目
ProjectSwitchRequest request = new ProjectSwitchRequest();
request.setProjectId("projectId");
request.setUserId("admin");
MvcResult mvcResult = requestPostWithOkAndReturn(prefix + "/switch", request);
UserDTO userDTO = parseObjectFromMvcResult(mvcResult, UserDTO.class);
Assertions.assertNotNull(userDTO);
Assertions.assertEquals("projectId", userDTO.getLastProjectId());
request.setProjectId("default_project");
//权限校验
requestPostPermissionTest(PermissionConstants.PROJECT_BASE_INFO_READ, prefix + "/switch", request);
}
@Test
@Order(6)
public void testSwitchProjectError() throws Exception {
//项目id为空
ProjectSwitchRequest request = new ProjectSwitchRequest();
request.setProjectId("");
request.setUserId("admin");
requestPost(prefix + "/switch", request, status().isBadRequest());
//用户id为空
request.setProjectId("projectId");
request.setUserId("");
requestPost(prefix + "/switch", request, status().isBadRequest());
//项目不存在
request = new ProjectSwitchRequest();
request.setProjectId("111111");
request.setUserId("admin");
requestPost(prefix + "/switch", request, status().is5xxServerError());
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post("/login")
.content(String.format("{\"username\":\"%s\",\"password\":\"%s\"}", "delete", "deleted@metersphere.io"))
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andReturn();
String sessionId = JsonPath.read(mvcResult.getResponse().getContentAsString(), "$.data.sessionId");
String csrfToken = JsonPath.read(mvcResult.getResponse().getContentAsString(), "$.data.csrfToken");
request.setProjectId("projectId");
mockMvc.perform(MockMvcRequestBuilders.post(prefix + "/switch", request)
.header(SessionConstants.HEADER_TOKEN, sessionId)
.header(SessionConstants.CSRF_TOKEN, csrfToken)
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().is5xxServerError())
.andExpect(content().contentType(MediaType.APPLICATION_JSON)).andReturn();
}
}

View File

@ -0,0 +1,30 @@
# 插入测试数据
replace into user(id, name, email, password, create_time, update_time, language, last_organization_id, phone, source,
last_project_id, create_user, update_user)
VALUES ('admin1', 'test1', 'admin1@metersphere.io', MD5('admin1@metersphere.io'),
UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, NULL, NUll, '', 'LOCAL', 'projectId1', 'admin', 'admin');
replace into user(id, name, email, password, create_time, update_time, language, last_organization_id, phone, source,
last_project_id, create_user, update_user)
VALUES ('admin1', 'test1', 'admin1@metersphere.io', MD5('admin1@metersphere.io'),
UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, NULL, NUll, '', 'LOCAL', 'projectId1', 'admin', 'admin');
replace into user(id, name, email, password, create_time, update_time, language, last_organization_id, phone, source,
last_project_id, create_user, update_user,deleted)
VALUES ('delete', 'test2', 'deleted@metersphere.io', MD5('deleted@metersphere.io'),
UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, NULL, NUll, '', 'LOCAL', NULL, 'admin', 'admin',1);
replace INTO project (id, num, organization_id, name, description, create_user, update_user, create_time, update_time, enable,module_setting) VALUES ('projectId', null, (SELECT id FROM organization WHERE name LIKE '默认组织'), '默认项目', '系统默认创建的项目', 'admin', 'admin', unix_timestamp() * 1000, unix_timestamp() * 1000,1, '["apiTest","uiTest"]');
replace INTO project (id, num, organization_id, name, description, create_user, update_user, create_time, update_time,enable) VALUES ('projectId1', null, (SELECT id FROM organization WHERE name LIKE '默认组织'), '默认项目1', '系统默认创建的项目', 'admin', 'admin', unix_timestamp() * 1000, unix_timestamp() * 1000,1);
replace INTO project (id, num, organization_id, name, description, create_user, update_user, create_time,update_time,enable ) VALUES ('projectId2', null, (SELECT id FROM organization WHERE name LIKE '默认组织'), '默认项目2', '系统默认创建的项目', 'admin', 'admin', unix_timestamp() * 1000, unix_timestamp() * 1000,1);
replace INTO project (id, num, organization_id, name, description, create_user, update_user, create_time,update_time,enable, module_setting) VALUES ('projectId3', null, (SELECT id FROM organization WHERE name LIKE '默认组织'), '默认项目3', '系统默认创建的项目', 'admin', 'admin', unix_timestamp() * 1000, unix_timestamp() * 1000,1,'["apiTest","uiTest"]');
replace INTO project (id, num, organization_id, name, description, create_user, update_user, create_time,update_time,enable, module_setting) VALUES ('projectId4', null, (SELECT id FROM organization WHERE name LIKE '默认组织'), '默认项目4', '系统默认创建的项目', 'admin', 'admin', unix_timestamp() * 1000, unix_timestamp() * 1000,1,'["apiTest","uiTest","loadTest"]');
replace INTO project (id, num, organization_id, name, description, create_user, update_user, create_time,update_time,enable,module_setting) VALUES ('projectId5', null, (SELECT id FROM organization WHERE name LIKE '默认组织'), '默认项目5', '系统默认创建的项目', 'test', 'test', unix_timestamp() * 1000, unix_timestamp() * 1000,1,'["apiTest","uiTest"]');
# 插入测试数据 给组织增加成员
replace INTO user_role_relation (id, user_id, role_id, source_id, create_time, create_user )VALUES ('user_role_relation1','admin1','org_admin','default_organization','1684747668321','admin');
replace INTO user_role_relation (id, user_id, role_id, source_id, create_time, create_user )VALUES ('user_role_relation2','delete','org_admin','default_organization','1684747668321','admin');
replace INTO user_role_relation (id, user_id, role_id, source_id, create_time, create_user )VALUES ('user_role_relation6','delete','project_member','projectId1','1684747668321','admin');
replace INTO user_role_relation (id, user_id, role_id, source_id, create_time, create_user )VALUES ('user_role_relation3','admin1','project_member','projectId1','1684747668321','admin');
replace INTO user_role_relation (id, user_id, role_id, source_id, create_time, create_user )VALUES ('user_role_relation4','admin1','project_member','projectId2','1684747668321','admin');
replace INTO user_role_relation (id, user_id, role_id, source_id, create_time, create_user )VALUES ('user_role_relation5','admin1','project_member','projectId3','1684747668321','admin');
replace INTO user_role_permission(id, role_id, permission_id) VALUES ('user_role_permission1','project_member','PROJECT_BASE_INFO:READ');

View File

@ -142,11 +142,11 @@ public class OrganizationProjectController {
return organizationProjectService.removeProjectMember(projectId, userId, SessionUtils.getUserId());
}
@GetMapping("/user-admin-list/{organizationId}/{projectId}")
@GetMapping("/user-admin-list/{organizationId}")
@Operation(summary = "系统设置-组织-项目-获取管理员列表")
@RequiresPermissions(PermissionConstants.ORGANIZATION_PROJECT_READ)
public List<UserExtend> getUserAdminList(@PathVariable String organizationId, @PathVariable String projectId) {
return organizationProjectService.getUserAdminList(organizationId, projectId);
public List<UserExtend> getUserAdminList(@PathVariable String organizationId) {
return organizationProjectService.getUserAdminList(organizationId);
}
@GetMapping("/user-member-list/{organizationId}/{projectId}")

View File

@ -20,7 +20,7 @@ public interface ExtSystemProjectMapper {
List<OrganizationProjectOptionsDTO> selectProjectOptions(@Param("organizationId") String organizationId);
List<UserExtend> getUserAdminList(@Param("userIds") List<String> userIds, @Param("projectId") String projectId);
List<UserExtend> getUserAdminList(@Param("organizationId") String organizationId);
List<UserExtend> getUserMemberList(@Param("userIds") List<String> userIds, @Param("projectId") String projectId);
}

View File

@ -20,7 +20,7 @@
or user.phone like CONCAT('%', #{request.keyword},'%'))
</if>
</where>
ORDER BY `user`.update_time DESC) temp GROUP BY temp.id
ORDER BY `user`.update_time DESC) temp GROUP BY temp.id ORDER BY adminFlag DESC
</select>
<select id="getProjectList" resultType="io.metersphere.sdk.dto.ProjectDTO">
select p.id,
@ -113,20 +113,9 @@
</sql>
<select id="getUserAdminList" resultType="io.metersphere.system.dto.UserExtend">
select distinct u.*, MAX( if (temp.role_id = 'project_admin', true, false)) as adminFlag from
user u left join (select * from user_role_relation urr where urr.source_id = #{projectId}) temp on temp.user_id = u.id
<where>
u.deleted = 0
<if test="userIds != null and userIds.size > 0 ">
and u.id in
<foreach collection="userIds" item="userId" open="(" separator="," close=")">
#{userId}
</foreach>
</if>
</where>
group by u.id
select distinct u.*
from `user` u left join user_role_relation urr on urr.user_id = u.id
where u.deleted = 0 and urr.source_id = #{organizationId}
</select>

View File

@ -32,7 +32,7 @@ public class OrganizationProjectLogService {
null,
null,
OperationLogType.ADD.name(),
OperationLogModule.SETTING_SYSTEM_ORGANIZATION_PROJECT,
OperationLogModule.SETTING_ORGANIZATION_PROJECT,
project.getName());
dto.setOriginalValue(JSON.toJSONBytes(project));
@ -52,7 +52,7 @@ public class OrganizationProjectLogService {
project.getId(),
project.getCreateUser(),
OperationLogType.UPDATE.name(),
OperationLogModule.SETTING_SYSTEM_ORGANIZATION_PROJECT,
OperationLogModule.SETTING_ORGANIZATION_PROJECT,
project.getName());
dto.setOriginalValue(JSON.toJSONBytes(project));
@ -95,7 +95,7 @@ public class OrganizationProjectLogService {
id,
project.getCreateUser(),
OperationLogType.DELETE.name(),
OperationLogModule.SETTING_SYSTEM_ORGANIZATION_PROJECT,
OperationLogModule.SETTING_ORGANIZATION_PROJECT,
project.getName());
dto.setOriginalValue(JSON.toJSONBytes(project));
@ -118,7 +118,7 @@ public class OrganizationProjectLogService {
id,
null,
OperationLogType.RECOVER.name(),
OperationLogModule.SETTING_SYSTEM_ORGANIZATION_PROJECT,
OperationLogModule.SETTING_ORGANIZATION_PROJECT,
project.getName());
dto.setOriginalValue(JSON.toJSONBytes(project));
return dto;

View File

@ -57,7 +57,7 @@ public class OrganizationProjectService {
* @return
*/
public ProjectExtendDTO add(AddProjectRequest addProjectDTO, String createUser) {
return commonProjectService.add(addProjectDTO, createUser, ADD_PROJECT, OperationLogModule.SETTING_SYSTEM_ORGANIZATION_PROJECT);
return commonProjectService.add(addProjectDTO, createUser, ADD_PROJECT, OperationLogModule.SETTING_ORGANIZATION_PROJECT);
}
public List<ProjectDTO> getProjectList(OrganizationProjectRequest request) {
@ -68,7 +68,7 @@ public class OrganizationProjectService {
}
public ProjectExtendDTO update(UpdateProjectRequest updateProjectDto, String updateUser) {
return commonProjectService.update(updateProjectDto, updateUser, UPDATE_PROJECT, OperationLogModule.SETTING_SYSTEM_ORGANIZATION_PROJECT);
return commonProjectService.update(updateProjectDto, updateUser, UPDATE_PROJECT, OperationLogModule.SETTING_ORGANIZATION_PROJECT);
}
public int delete(String id, String deleteUser) {
@ -86,11 +86,11 @@ public class OrganizationProjectService {
*/
public void addProjectMember(ProjectAddMemberBatchRequest request, String createUser) {
commonProjectService.addProjectMember(request, createUser, ADD_MEMBER,
OperationLogType.ADD.name(), Translator.get("add"), OperationLogModule.SETTING_SYSTEM_ORGANIZATION_PROJECT);
OperationLogType.ADD.name(), Translator.get("add"), OperationLogModule.SETTING_ORGANIZATION_PROJECT);
}
public int removeProjectMember(String projectId, String userId, String createUser) {
return commonProjectService.removeProjectMember(projectId, userId, createUser, OperationLogModule.SETTING_SYSTEM_ORGANIZATION_PROJECT, StringUtils.join(REMOVE_PROJECT_MEMBER, projectId, "/", userId));
return commonProjectService.removeProjectMember(projectId, userId, createUser, OperationLogModule.SETTING_ORGANIZATION_PROJECT, StringUtils.join(REMOVE_PROJECT_MEMBER, projectId, "/", userId));
}
public int revoke(String id) {
@ -105,18 +105,9 @@ public class OrganizationProjectService {
commonProjectService.disable(id);
}
public List<UserExtend> getUserAdminList(String organizationId, String projectId) {
public List<UserExtend> getUserAdminList(String organizationId) {
checkOrgIsExist(organizationId);
commonProjectService.checkProjectNotExist(projectId);
UserRoleRelationExample example = new UserRoleRelationExample();
example.createCriteria().andSourceIdEqualTo(organizationId);
List<UserRoleRelation> userRoleRelations = userRoleRelationMapper.selectByExample(example);
List<String> userIds = userRoleRelations.stream().map(UserRoleRelation::getUserId).distinct().collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(userIds)) {
return extSystemProjectMapper.getUserAdminList(userIds, projectId);
} else {
return null;
}
return extSystemProjectMapper.getUserAdminList(organizationId);
}
public List<UserExtend> getUserMemberList(String organizationId, String projectId) {

View File

@ -308,7 +308,6 @@ public class OrganizationProjectControllerTests extends BaseTest {
@Test
@Order(4)
public void testGetProjectError() throws Exception {
//项目不存在
//项目不存在
MvcResult mvcResult = this.responseGet(getProject + "111111");
ProjectExtendDTO project = parseObjectFromMvcResult(mvcResult, ProjectExtendDTO.class);
@ -721,28 +720,16 @@ public class OrganizationProjectControllerTests extends BaseTest {
public void testGetAdminList() throws Exception {
//组织下面有成员 返回不为空
String organizationId = getDefault().getId();
String projectId = "projectId4";
MvcResult mvcResult = responseGet(getAdminList + organizationId + "/" + projectId);
MvcResult mvcResult = responseGet(getAdminList + organizationId);
List<UserDTO> userDTOS = parseObjectFromMvcResult(mvcResult, List.class);
assert userDTOS != null;
Assertions.assertFalse(userDTOS.isEmpty());
// @@校验权限
requestGetPermissionTest(PermissionConstants.ORGANIZATION_PROJECT_READ, getAdminList + organizationId + "/" + projectId);
//组织下面没有成员 返回为空
organizationId = "default-organization-20";
projectId = "projectId4";
mvcResult = responseGet(getAdminList + organizationId + "/" + projectId);
userDTOS = parseObjectFromMvcResult(mvcResult, List.class);
Assertions.assertNull(userDTOS);
requestGetPermissionTest(PermissionConstants.ORGANIZATION_PROJECT_READ, getAdminList + organizationId);
//组织不存在
organizationId = "organizationId111";
projectId = "projectId4";
this.responseGet(getAdminList + organizationId + "/" + projectId, ERROR_REQUEST_MATCHER);
//项目不存在
organizationId = getDefault().getId();
projectId = "projectId111";
this.responseGet(getAdminList + organizationId + "/" + projectId, ERROR_REQUEST_MATCHER);
this.responseGet(getAdminList + organizationId, ERROR_REQUEST_MATCHER);
}

View File

@ -16,12 +16,12 @@ replace into user(id, name, email, password, create_time, update_time, language,
VALUES ('test', 'test', 'admin3@metersphere.io', MD5('admin2@metersphere.io'),
UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, NULL, NUll, '', 'LOCAL', NULL, 'admin', 'admin');
replace INTO project (id, num, organization_id, name, description, create_user, update_user, create_time, update_time,module_setting) VALUES ('projectId', null, (SELECT id FROM organization WHERE name LIKE '默认组织'), '默认项目', '系统默认创建的项目', 'admin', 'admin', unix_timestamp() * 1000, unix_timestamp() * 1000, '["apiTest","uiTest"]');
replace INTO project (id, num, organization_id, name, description, create_user, update_user, create_time, update_time) VALUES ('projectId1', null, (SELECT id FROM organization WHERE name LIKE '默认组织'), '默认项目1', '系统默认创建的项目', 'admin', 'admin', unix_timestamp() * 1000, unix_timestamp() * 1000);
replace INTO project (id, num, organization_id, name, description, create_user, update_user, create_time, update_time) VALUES ('projectId2', null, (SELECT id FROM organization WHERE name LIKE '默认组织'), '默认项目2', '系统默认创建的项目', 'admin', 'admin', unix_timestamp() * 1000, unix_timestamp() * 1000);
replace INTO project (id, num, organization_id, name, description, create_user, update_user, create_time, update_time, module_setting) VALUES ('projectId3', null, (SELECT id FROM organization WHERE name LIKE '默认组织'), '默认项目3', '系统默认创建的项目', 'admin', 'admin', unix_timestamp() * 1000, unix_timestamp() * 1000,'["apiTest","uiTest"]');
replace INTO project (id, num, organization_id, name, description, create_user, update_user, create_time, update_time,module_setting) VALUES ('projectId4', null, (SELECT id FROM organization WHERE name LIKE '默认组织'), '默认项目4', '系统默认创建的项目', 'admin', 'admin', unix_timestamp() * 1000, unix_timestamp() * 1000,'["apiTest","uiTest","loadTest"]');
replace INTO project (id, num, organization_id, name, description, create_user, update_user, create_time, update_time,module_setting) VALUES ('projectId5', null, (SELECT id FROM organization WHERE name LIKE '默认组织'), '默认项目5', '系统默认创建的项目', 'test', 'test', unix_timestamp() * 1000, unix_timestamp() * 1000,'["apiTest","uiTest"]');
replace INTO project (id, num, organization_id, name, description, create_user, update_user, create_time, update_time, enable,module_setting) VALUES ('projectId', null, (SELECT id FROM organization WHERE name LIKE '默认组织'), '默认项目', '系统默认创建的项目', 'admin', 'admin', unix_timestamp() * 1000, unix_timestamp() * 1000,1, '["apiTest","uiTest"]');
replace INTO project (id, num, organization_id, name, description, create_user, update_user, create_time, update_time,enable) VALUES ('projectId1', null, (SELECT id FROM organization WHERE name LIKE '默认组织'), '默认项目1', '系统默认创建的项目', 'admin', 'admin', unix_timestamp() * 1000, unix_timestamp() * 1000,1);
replace INTO project (id, num, organization_id, name, description, create_user, update_user, create_time,update_time,enable ) VALUES ('projectId2', null, (SELECT id FROM organization WHERE name LIKE '默认组织'), '默认项目2', '系统默认创建的项目', 'admin', 'admin', unix_timestamp() * 1000, unix_timestamp() * 1000,1);
replace INTO project (id, num, organization_id, name, description, create_user, update_user, create_time,update_time,enable, module_setting) VALUES ('projectId3', null, (SELECT id FROM organization WHERE name LIKE '默认组织'), '默认项目3', '系统默认创建的项目', 'admin', 'admin', unix_timestamp() * 1000, unix_timestamp() * 1000,1,'["apiTest","uiTest"]');
replace INTO project (id, num, organization_id, name, description, create_user, update_user, create_time,update_time,enable, module_setting) VALUES ('projectId4', null, (SELECT id FROM organization WHERE name LIKE '默认组织'), '默认项目4', '系统默认创建的项目', 'admin', 'admin', unix_timestamp() * 1000, unix_timestamp() * 1000,1,'["apiTest","uiTest","loadTest"]');
replace INTO project (id, num, organization_id, name, description, create_user, update_user, create_time,update_time,enable,module_setting) VALUES ('projectId5', null, (SELECT id FROM organization WHERE name LIKE '默认组织'), '默认项目5', '系统默认创建的项目', 'test', 'test', unix_timestamp() * 1000, unix_timestamp() * 1000,1,'["apiTest","uiTest"]');
# 插入测试数据 给组织增加成员

View File

@ -26,4 +26,5 @@ VALUES ('ORGANIZATION', '组织级别权限校验', '', 1, 'ORGANIZATION', 16206
-- 初始化用户和组的关系
INSERT INTO user_role_relation (id, user_id, role_id, source_id, create_time, create_user)
SELECT 'ORGANIZATION', 'ORGANIZATION', 'ORGANIZATION', id, 1684747668375, 'admin' FROM organization WHERE num = 100001;
SELECT 'ORGANIZATION', 'ORGANIZATION', 'ORGANIZATION', id, 1684747668375, 'admin' FROM organization WHERE num = 100001;

View File

@ -1,11 +1,12 @@
# 插入测试数据
replace INTO project (id, num, organization_id, name, description, create_user, update_user, create_time, update_time,module_setting) VALUES ('projectId', null, (SELECT id FROM organization WHERE name LIKE '默认组织'), '默认项目', '系统默认创建的项目', 'admin', 'admin', unix_timestamp() * 1000, unix_timestamp() * 1000, '["apiTest","uiTest"]');
replace INTO project (id, num, organization_id, name, description, create_user, update_user, create_time, update_time,module_setting) VALUES ('projectId', null, (SELECT id FROM organization WHERE name LIKE '默认组织'), '默认项目', '系统默认创建的项目', 'admin', 'admin', unix_timestamp() * 1000, unix_timestamp() * 1000, '["apiTest","uiTest"]');
replace INTO project (id, num, organization_id, name, description, create_user, update_user, create_time, update_time) VALUES ('projectId1', null, (SELECT id FROM organization WHERE name LIKE '默认组织'), '默认项目1', '系统默认创建的项目', 'admin', 'admin', unix_timestamp() * 1000, unix_timestamp() * 1000);
replace INTO project (id, num, organization_id, name, description, create_user, update_user, create_time, update_time) VALUES ('projectId2', null, (SELECT id FROM organization WHERE name LIKE '默认组织'), '默认项目2', '系统默认创建的项目', 'admin', 'admin', unix_timestamp() * 1000, unix_timestamp() * 1000);
replace INTO project (id, num, organization_id, name, description, create_user, update_user, create_time, update_time, module_setting) VALUES ('projectId3', null, (SELECT id FROM organization WHERE name LIKE '默认组织'), '默认项目3', '系统默认创建的项目', 'admin', 'admin', unix_timestamp() * 1000, unix_timestamp() * 1000,'["apiTest","uiTest"]');
replace INTO project (id, num, organization_id, name, description, create_user, update_user, create_time, update_time,module_setting) VALUES ('projectId4', null, (SELECT id FROM organization WHERE name LIKE '默认组织'), '默认项目4', '系统默认创建的项目', 'admin', 'admin', unix_timestamp() * 1000, unix_timestamp() * 1000,'["apiTest","uiTest","loadTest"]');
replace INTO project (id, num, organization_id, name, description, create_user, update_user, create_time, update_time,module_setting) VALUES ('projectId5', null, (SELECT id FROM organization WHERE name LIKE '默认组织'), '默认项目5', '系统默认创建的项目', 'test', 'test', unix_timestamp() * 1000, unix_timestamp() * 1000,'["apiTest","uiTest"]');
replace INTO project (id, num, organization_id, name, description, create_user, update_user, create_time, update_time, enable,module_setting) VALUES ('projectId', null, (SELECT id FROM organization WHERE name LIKE '默认组织'), '默认项目', '系统默认创建的项目', 'admin', 'admin', unix_timestamp() * 1000, unix_timestamp() * 1000,1, '["apiTest","uiTest"]');
replace INTO project (id, num, organization_id, name, description, create_user, update_user, create_time, update_time,enable) VALUES ('projectId1', null, (SELECT id FROM organization WHERE name LIKE '默认组织'), '默认项目1', '系统默认创建的项目', 'admin', 'admin', unix_timestamp() * 1000, unix_timestamp() * 1000,1);
replace INTO project (id, num, organization_id, name, description, create_user, update_user, create_time,update_time,enable ) VALUES ('projectId2', null, (SELECT id FROM organization WHERE name LIKE '默认组织'), '默认项目2', '系统默认创建的项目', 'admin', 'admin', unix_timestamp() * 1000, unix_timestamp() * 1000,1);
replace INTO project (id, num, organization_id, name, description, create_user, update_user, create_time,update_time,enable, module_setting) VALUES ('projectId3', null, (SELECT id FROM organization WHERE name LIKE '默认组织'), '默认项目3', '系统默认创建的项目', 'admin', 'admin', unix_timestamp() * 1000, unix_timestamp() * 1000,1,'["apiTest","uiTest"]');
replace INTO project (id, num, organization_id, name, description, create_user, update_user, create_time,update_time,enable, module_setting) VALUES ('projectId4', null, (SELECT id FROM organization WHERE name LIKE '默认组织'), '默认项目4', '系统默认创建的项目', 'admin', 'admin', unix_timestamp() * 1000, unix_timestamp() * 1000,1,'["apiTest","uiTest","loadTest"]');
replace INTO project (id, num, organization_id, name, description, create_user, update_user, create_time,update_time,enable,module_setting) VALUES ('projectId5', null, (SELECT id FROM organization WHERE name LIKE '默认组织'), '默认项目5', '系统默认创建的项目', 'test', 'test', unix_timestamp() * 1000, unix_timestamp() * 1000,1,'["apiTest","uiTest"]');
replace into user(id, name, email, password, create_time, update_time, language, last_organization_id, phone, source,
last_project_id, create_user, update_user)
VALUES ('admin1', 'test1', 'admin1@metersphere.io', MD5('admin1@metersphere.io'),