feat(auth): return Sa-Token on login and add tenant/user list APIs
This commit is contained in:
@@ -3,15 +3,19 @@ package com.sino.mci.admin.controller;
|
|||||||
import com.sino.mci.admin.dto.CreateTenantRequest;
|
import com.sino.mci.admin.dto.CreateTenantRequest;
|
||||||
import com.sino.mci.admin.dto.CreateUserRequest;
|
import com.sino.mci.admin.dto.CreateUserRequest;
|
||||||
import com.sino.mci.admin.dto.LoginRequest;
|
import com.sino.mci.admin.dto.LoginRequest;
|
||||||
import com.sino.mci.admin.dto.LoginResponse;
|
import com.sino.mci.admin.dto.PlatformUserResponse;
|
||||||
|
import com.sino.mci.admin.dto.TokenResponse;
|
||||||
import com.sino.mci.admin.dto.UserResponse;
|
import com.sino.mci.admin.dto.UserResponse;
|
||||||
import com.sino.mci.admin.entity.Tenant;
|
import com.sino.mci.admin.entity.Tenant;
|
||||||
|
import com.sino.mci.admin.security.AuthContext;
|
||||||
import com.sino.mci.admin.service.AccountService;
|
import com.sino.mci.admin.service.AccountService;
|
||||||
import com.sino.mci.shared.web.ApiResponse;
|
import com.sino.mci.shared.web.ApiResponse;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/v1/account")
|
@RequestMapping("/api/v1/account")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@@ -24,6 +28,11 @@ public class AccountController {
|
|||||||
return ApiResponse.ok(accountService.createTenant(request));
|
return ApiResponse.ok(accountService.createTenant(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/tenant/list")
|
||||||
|
public ApiResponse<List<Tenant>> listTenants() {
|
||||||
|
return ApiResponse.ok(accountService.listTenants());
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping("/user")
|
@PostMapping("/user")
|
||||||
public ApiResponse<UserResponse> createUser(
|
public ApiResponse<UserResponse> createUser(
|
||||||
@RequestHeader("X-Tenant-Code") String tenantCode,
|
@RequestHeader("X-Tenant-Code") String tenantCode,
|
||||||
@@ -31,10 +40,20 @@ public class AccountController {
|
|||||||
return ApiResponse.ok(accountService.createUser(tenantCode, request));
|
return ApiResponse.ok(accountService.createUser(tenantCode, request));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/user/list")
|
||||||
|
public ApiResponse<List<PlatformUserResponse>> listUsers() {
|
||||||
|
return ApiResponse.ok(accountService.listUsers(AuthContext.currentTenantCode()));
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping("/login")
|
@PostMapping("/login")
|
||||||
public ApiResponse<LoginResponse> login(
|
public ApiResponse<TokenResponse> login(
|
||||||
@RequestHeader("X-Tenant-Code") String tenantCode,
|
@RequestHeader("X-Tenant-Code") String tenantCode,
|
||||||
@Valid @RequestBody LoginRequest request) {
|
@Valid @RequestBody LoginRequest request) {
|
||||||
return ApiResponse.ok(accountService.login(tenantCode, request.getUsername(), request.getPassword()));
|
return ApiResponse.ok(accountService.login(tenantCode, request.getUsername(), request.getPassword()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/me")
|
||||||
|
public ApiResponse<AuthContext.AuthUser> me() {
|
||||||
|
return ApiResponse.ok(AuthContext.get());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.sino.mci.admin.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class PlatformUserResponse {
|
||||||
|
private Long id;
|
||||||
|
private String tenantCode;
|
||||||
|
private String username;
|
||||||
|
private String realName;
|
||||||
|
private String phone;
|
||||||
|
private Integer status;
|
||||||
|
private List<String> roleCodes;
|
||||||
|
private LocalDateTime createTime;
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.sino.mci.admin.dto;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class TokenResponse {
|
||||||
|
private String token;
|
||||||
|
private LoginResponse userInfo;
|
||||||
|
}
|
||||||
@@ -13,7 +13,10 @@ public class AuthInterceptor implements HandlerInterceptor {
|
|||||||
@Override
|
@Override
|
||||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
|
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
|
||||||
String path = request.getRequestURI();
|
String path = request.getRequestURI();
|
||||||
if (path.contains("/api/v1/account/login")) {
|
String method = request.getMethod();
|
||||||
|
if (path.contains("/api/v1/account/login")
|
||||||
|
|| ("POST".equals(method) && isExactPath(path, "/api/v1/account/tenant"))
|
||||||
|
|| ("POST".equals(method) && isExactPath(path, "/api/v1/account/user"))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,4 +28,11 @@ public class AuthInterceptor implements HandlerInterceptor {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isExactPath(String requestUri, String endpointPath) {
|
||||||
|
String contextPath = "/msg-platform";
|
||||||
|
return requestUri.equals(endpointPath)
|
||||||
|
|| requestUri.equals(contextPath + endpointPath)
|
||||||
|
|| requestUri.endsWith(endpointPath) && requestUri.length() == contextPath.length() + endpointPath.length();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
package com.sino.mci.admin.service;
|
package com.sino.mci.admin.service;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.sino.mci.admin.dto.CreateTenantRequest;
|
import com.sino.mci.admin.dto.CreateTenantRequest;
|
||||||
import com.sino.mci.admin.dto.CreateUserRequest;
|
import com.sino.mci.admin.dto.CreateUserRequest;
|
||||||
import com.sino.mci.admin.dto.LoginResponse;
|
import com.sino.mci.admin.dto.LoginResponse;
|
||||||
|
import com.sino.mci.admin.dto.PlatformUserResponse;
|
||||||
|
import com.sino.mci.admin.dto.TokenResponse;
|
||||||
import com.sino.mci.admin.dto.UserResponse;
|
import com.sino.mci.admin.dto.UserResponse;
|
||||||
import com.sino.mci.admin.entity.PlatformRole;
|
import com.sino.mci.admin.entity.PlatformRole;
|
||||||
import com.sino.mci.admin.entity.PlatformUser;
|
import com.sino.mci.admin.entity.PlatformUser;
|
||||||
@@ -92,7 +95,7 @@ public class AccountService {
|
|||||||
return toUserResponse(user);
|
return toUserResponse(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LoginResponse login(String tenantCode, String username, String password) {
|
public TokenResponse login(String tenantCode, String username, String password) {
|
||||||
PlatformUser user = userMapper.selectOne(
|
PlatformUser user = userMapper.selectOne(
|
||||||
new LambdaQueryWrapper<PlatformUser>()
|
new LambdaQueryWrapper<PlatformUser>()
|
||||||
.eq(PlatformUser::getTenantCode, tenantCode)
|
.eq(PlatformUser::getTenantCode, tenantCode)
|
||||||
@@ -102,14 +105,30 @@ public class AccountService {
|
|||||||
throw new UnauthorizedException("用户名或密码错误");
|
throw new UnauthorizedException("用户名或密码错误");
|
||||||
}
|
}
|
||||||
|
|
||||||
LoginResponse response = new LoginResponse();
|
LoginResponse userInfo = new LoginResponse();
|
||||||
response.setId(user.getId());
|
userInfo.setId(user.getId());
|
||||||
response.setTenantCode(user.getTenantCode());
|
userInfo.setTenantCode(user.getTenantCode());
|
||||||
response.setUsername(user.getUsername());
|
userInfo.setUsername(user.getUsername());
|
||||||
response.setRealName(user.getRealName());
|
userInfo.setRealName(user.getRealName());
|
||||||
response.setPhone(user.getPhone());
|
userInfo.setPhone(user.getPhone());
|
||||||
response.setRoleCodes(loadRoleCodes(user.getId()));
|
userInfo.setRoleCodes(loadRoleCodes(user.getId()));
|
||||||
return response;
|
|
||||||
|
StpUtil.login(user.getId());
|
||||||
|
StpUtil.getSession().set("tenantCode", user.getTenantCode());
|
||||||
|
StpUtil.getSession().set("username", user.getUsername());
|
||||||
|
StpUtil.getSession().set("roleCodes", userInfo.getRoleCodes());
|
||||||
|
|
||||||
|
return new TokenResponse(StpUtil.getTokenValue(), userInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Tenant> listTenants() {
|
||||||
|
return tenantMapper.selectList(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<PlatformUserResponse> listUsers(String tenantCode) {
|
||||||
|
List<PlatformUser> users = userMapper.selectList(
|
||||||
|
new LambdaQueryWrapper<PlatformUser>().eq(PlatformUser::getTenantCode, tenantCode));
|
||||||
|
return users.stream().map(this::toPlatformUserResponse).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
private UserResponse toUserResponse(PlatformUser user) {
|
private UserResponse toUserResponse(PlatformUser user) {
|
||||||
@@ -127,6 +146,19 @@ public class AccountService {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private PlatformUserResponse toPlatformUserResponse(PlatformUser user) {
|
||||||
|
PlatformUserResponse response = new PlatformUserResponse();
|
||||||
|
response.setId(user.getId());
|
||||||
|
response.setTenantCode(user.getTenantCode());
|
||||||
|
response.setUsername(user.getUsername());
|
||||||
|
response.setRealName(user.getRealName());
|
||||||
|
response.setPhone(user.getPhone());
|
||||||
|
response.setStatus(user.getStatus());
|
||||||
|
response.setRoleCodes(loadRoleCodes(user.getId()));
|
||||||
|
response.setCreateTime(user.getCreateTime());
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
private List<String> loadRoleCodes(Long userId) {
|
private List<String> loadRoleCodes(Long userId) {
|
||||||
return userRoleMapper.selectList(
|
return userRoleMapper.selectList(
|
||||||
new LambdaQueryWrapper<UserRole>().eq(UserRole::getUserId, userId))
|
new LambdaQueryWrapper<UserRole>().eq(UserRole::getUserId, userId))
|
||||||
|
|||||||
@@ -16,6 +16,9 @@ public class WebConfig implements WebMvcConfigurer {
|
|||||||
public void addInterceptors(InterceptorRegistry registry) {
|
public void addInterceptors(InterceptorRegistry registry) {
|
||||||
registry.addInterceptor(authInterceptor)
|
registry.addInterceptor(authInterceptor)
|
||||||
.addPathPatterns("/msg-platform/api/v1/**", "/api/v1/**")
|
.addPathPatterns("/msg-platform/api/v1/**", "/api/v1/**")
|
||||||
.excludePathPatterns("/msg-platform/api/v1/account/login", "/api/v1/account/login");
|
.excludePathPatterns(
|
||||||
|
"/msg-platform/api/v1/account/login", "/api/v1/account/login",
|
||||||
|
"/msg-platform/api/v1/account/tenant", "/api/v1/account/tenant",
|
||||||
|
"/msg-platform/api/v1/account/user", "/api/v1/account/user");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
INSERT IGNORE INTO mci_platform_role (role_code, role_name, permissions) VALUES
|
||||||
|
('platform_admin', '平台管理员', '["tenant:manage", "user:manage", "*"]');
|
||||||
@@ -10,6 +10,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static com.sino.mci.test.AuthTestHelper.createTenantAndLogin;
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
@@ -26,17 +27,12 @@ public class ChannelControllerTest {
|
|||||||
@Test
|
@Test
|
||||||
void shouldCreateChannelSubjectAndAccount() throws Exception {
|
void shouldCreateChannelSubjectAndAccount() throws Exception {
|
||||||
String tenantCode = "channel-" + UUID.randomUUID().toString().substring(0, 8);
|
String tenantCode = "channel-" + UUID.randomUUID().toString().substring(0, 8);
|
||||||
String tenantPayload = String.format("{\"tenantCode\":\"%s\",\"tenantName\":\"渠道测试\"}", tenantCode);
|
String authToken = createTenantAndLogin(mockMvc, tenantCode, "渠道测试");
|
||||||
mockMvc.perform(post("/msg-platform/api/v1/account/tenant")
|
|
||||||
.contextPath("/msg-platform")
|
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
|
||||||
.content(tenantPayload))
|
|
||||||
.andExpect(status().isOk())
|
|
||||||
.andExpect(jsonPath("$.code").value(0));
|
|
||||||
|
|
||||||
String subjectPayload = "{\"channelType\":\"wecom\",\"subjectCode\":\"sino\",\"subjectName\":\"Sino\"}";
|
String subjectPayload = "{\"channelType\":\"wecom\",\"subjectCode\":\"sino\",\"subjectName\":\"Sino\"}";
|
||||||
mockMvc.perform(post("/msg-platform/api/v1/channel-subject")
|
mockMvc.perform(post("/msg-platform/api/v1/channel-subject")
|
||||||
.contextPath("/msg-platform")
|
.contextPath("/msg-platform")
|
||||||
|
.header("Authorization", authToken)
|
||||||
.header("X-Tenant-Code", tenantCode)
|
.header("X-Tenant-Code", tenantCode)
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content(subjectPayload))
|
.content(subjectPayload))
|
||||||
@@ -47,6 +43,7 @@ public class ChannelControllerTest {
|
|||||||
String accountPayload = "{\"accountType\":1,\"channelType\":\"wecom\",\"accountId\":\"ZhangSan\",\"accountName\":\"张三\"}";
|
String accountPayload = "{\"accountType\":1,\"channelType\":\"wecom\",\"accountId\":\"ZhangSan\",\"accountName\":\"张三\"}";
|
||||||
mockMvc.perform(post("/msg-platform/api/v1/channel-account")
|
mockMvc.perform(post("/msg-platform/api/v1/channel-account")
|
||||||
.contextPath("/msg-platform")
|
.contextPath("/msg-platform")
|
||||||
|
.header("Authorization", authToken)
|
||||||
.header("X-Tenant-Code", tenantCode)
|
.header("X-Tenant-Code", tenantCode)
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content(accountPayload))
|
.content(accountPayload))
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static com.sino.mci.test.AuthTestHelper.createTenantAndLogin;
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
@@ -26,17 +27,12 @@ public class CrmControllerTest {
|
|||||||
@Test
|
@Test
|
||||||
void shouldCreatePersonTagAndConversation() throws Exception {
|
void shouldCreatePersonTagAndConversation() throws Exception {
|
||||||
String tenantCode = "crm-" + UUID.randomUUID().toString().substring(0, 8);
|
String tenantCode = "crm-" + UUID.randomUUID().toString().substring(0, 8);
|
||||||
String tenantPayload = String.format("{\"tenantCode\":\"%s\",\"tenantName\":\"CRM测试\"}", tenantCode);
|
String authToken = createTenantAndLogin(mockMvc, tenantCode, "CRM测试");
|
||||||
mockMvc.perform(post("/msg-platform/api/v1/account/tenant")
|
|
||||||
.contextPath("/msg-platform")
|
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
|
||||||
.content(tenantPayload))
|
|
||||||
.andExpect(status().isOk())
|
|
||||||
.andExpect(jsonPath("$.code").value(0));
|
|
||||||
|
|
||||||
String personPayload = "{\"personCode\":\"P001\",\"personName\":\"张三\",\"phone\":\"13800138000\",\"personType\":3}";
|
String personPayload = "{\"personCode\":\"P001\",\"personName\":\"张三\",\"phone\":\"13800138000\",\"personType\":3}";
|
||||||
mockMvc.perform(post("/msg-platform/api/v1/person")
|
mockMvc.perform(post("/msg-platform/api/v1/person")
|
||||||
.contextPath("/msg-platform")
|
.contextPath("/msg-platform")
|
||||||
|
.header("Authorization", authToken)
|
||||||
.header("X-Tenant-Code", tenantCode)
|
.header("X-Tenant-Code", tenantCode)
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content(personPayload))
|
.content(personPayload))
|
||||||
@@ -47,6 +43,7 @@ public class CrmControllerTest {
|
|||||||
String tagPayload = "{\"parentId\":0,\"tagName\":\"客户\"}";
|
String tagPayload = "{\"parentId\":0,\"tagName\":\"客户\"}";
|
||||||
mockMvc.perform(post("/msg-platform/api/v1/tag")
|
mockMvc.perform(post("/msg-platform/api/v1/tag")
|
||||||
.contextPath("/msg-platform")
|
.contextPath("/msg-platform")
|
||||||
|
.header("Authorization", authToken)
|
||||||
.header("X-Tenant-Code", tenantCode)
|
.header("X-Tenant-Code", tenantCode)
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content(tagPayload))
|
.content(tagPayload))
|
||||||
@@ -57,6 +54,7 @@ public class CrmControllerTest {
|
|||||||
String conversationPayload = "{\"conversationType\":2,\"channelType\":\"wecom\",\"channelConversationId\":\"roomid_123\",\"conversationName\":\"测试群\"}";
|
String conversationPayload = "{\"conversationType\":2,\"channelType\":\"wecom\",\"channelConversationId\":\"roomid_123\",\"conversationName\":\"测试群\"}";
|
||||||
mockMvc.perform(post("/msg-platform/api/v1/conversation")
|
mockMvc.perform(post("/msg-platform/api/v1/conversation")
|
||||||
.contextPath("/msg-platform")
|
.contextPath("/msg-platform")
|
||||||
|
.header("Authorization", authToken)
|
||||||
.header("X-Tenant-Code", tenantCode)
|
.header("X-Tenant-Code", tenantCode)
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content(conversationPayload))
|
.content(conversationPayload))
|
||||||
@@ -66,6 +64,7 @@ public class CrmControllerTest {
|
|||||||
|
|
||||||
mockMvc.perform(get("/msg-platform/api/v1/tag/list")
|
mockMvc.perform(get("/msg-platform/api/v1/tag/list")
|
||||||
.contextPath("/msg-platform")
|
.contextPath("/msg-platform")
|
||||||
|
.header("Authorization", authToken)
|
||||||
.header("X-Tenant-Code", tenantCode))
|
.header("X-Tenant-Code", tenantCode))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$.code").value(0))
|
.andExpect(jsonPath("$.code").value(0))
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static com.sino.mci.test.AuthTestHelper.createTenantAndLogin;
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
@@ -26,17 +27,12 @@ public class InboundFlowControllerTest {
|
|||||||
@Test
|
@Test
|
||||||
void shouldCreateFlowAndReceiveMessage() throws Exception {
|
void shouldCreateFlowAndReceiveMessage() throws Exception {
|
||||||
String tenantCode = "flow-" + UUID.randomUUID().toString().substring(0, 8);
|
String tenantCode = "flow-" + UUID.randomUUID().toString().substring(0, 8);
|
||||||
String tenantPayload = String.format("{\"tenantCode\":\"%s\",\"tenantName\":\"流程测试\",\"inboundWebhookUrl\":\"http://localhost:9999/webhook\"}", tenantCode);
|
String authToken = createTenantAndLogin(mockMvc, tenantCode, "流程测试");
|
||||||
mockMvc.perform(post("/msg-platform/api/v1/account/tenant")
|
|
||||||
.contextPath("/msg-platform")
|
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
|
||||||
.content(tenantPayload))
|
|
||||||
.andExpect(status().isOk())
|
|
||||||
.andExpect(jsonPath("$.code").value(0));
|
|
||||||
|
|
||||||
String flowPayload = "{\"flowCode\":\"inbound_default\",\"flowName\":\"默认入站流程\",\"flowType\":\"inbound\",\"definitionJson\":{\"nodes\":[{\"id\":\"receive\",\"type\":\"receive\"},{\"id\":\"intent\",\"type\":\"intent\"},{\"id\":\"webhook\",\"type\":\"webhook\"}]}}";
|
String flowPayload = "{\"flowCode\":\"inbound_default\",\"flowName\":\"默认入站流程\",\"flowType\":\"inbound\",\"definitionJson\":{\"nodes\":[{\"id\":\"receive\",\"type\":\"receive\"},{\"id\":\"intent\",\"type\":\"intent\"},{\"id\":\"webhook\",\"type\":\"webhook\"}]}}";
|
||||||
mockMvc.perform(post("/msg-platform/api/v1/inbound/flow")
|
mockMvc.perform(post("/msg-platform/api/v1/inbound/flow")
|
||||||
.contextPath("/msg-platform")
|
.contextPath("/msg-platform")
|
||||||
|
.header("Authorization", authToken)
|
||||||
.header("X-Tenant-Code", tenantCode)
|
.header("X-Tenant-Code", tenantCode)
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content(flowPayload))
|
.content(flowPayload))
|
||||||
@@ -45,12 +41,14 @@ public class InboundFlowControllerTest {
|
|||||||
|
|
||||||
mockMvc.perform(post("/msg-platform/api/v1/inbound/flow/inbound_default/publish")
|
mockMvc.perform(post("/msg-platform/api/v1/inbound/flow/inbound_default/publish")
|
||||||
.contextPath("/msg-platform")
|
.contextPath("/msg-platform")
|
||||||
|
.header("Authorization", authToken)
|
||||||
.header("X-Tenant-Code", tenantCode))
|
.header("X-Tenant-Code", tenantCode))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$.code").value(0));
|
.andExpect(jsonPath("$.code").value(0));
|
||||||
|
|
||||||
mockMvc.perform(get("/msg-platform/api/v1/inbound/flow/inbound_default")
|
mockMvc.perform(get("/msg-platform/api/v1/inbound/flow/inbound_default")
|
||||||
.contextPath("/msg-platform")
|
.contextPath("/msg-platform")
|
||||||
|
.header("Authorization", authToken)
|
||||||
.header("X-Tenant-Code", tenantCode))
|
.header("X-Tenant-Code", tenantCode))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$.code").value(0))
|
.andExpect(jsonPath("$.code").value(0))
|
||||||
@@ -62,6 +60,7 @@ public class InboundFlowControllerTest {
|
|||||||
eventId);
|
eventId);
|
||||||
mockMvc.perform(post("/msg-platform/api/v1/inbound/receive")
|
mockMvc.perform(post("/msg-platform/api/v1/inbound/receive")
|
||||||
.contextPath("/msg-platform")
|
.contextPath("/msg-platform")
|
||||||
|
.header("Authorization", authToken)
|
||||||
.header("X-Tenant-Code", tenantCode)
|
.header("X-Tenant-Code", tenantCode)
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content(messagePayload))
|
.content(messagePayload))
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static com.sino.mci.test.AuthTestHelper.createTenantAndLogin;
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
@@ -26,18 +27,12 @@ public class SendControllerTest {
|
|||||||
@Test
|
@Test
|
||||||
void shouldTestSendToConversationAndQueryRecords() throws Exception {
|
void shouldTestSendToConversationAndQueryRecords() throws Exception {
|
||||||
String tenantCode = "send-" + UUID.randomUUID().toString().substring(0, 8);
|
String tenantCode = "send-" + UUID.randomUUID().toString().substring(0, 8);
|
||||||
|
String authToken = createTenantAndLogin(mockMvc, tenantCode, "发送测试");
|
||||||
String tenantPayload = String.format("{\"tenantCode\":\"%s\",\"tenantName\":\"发送测试\"}", tenantCode);
|
|
||||||
mockMvc.perform(post("/msg-platform/api/v1/account/tenant")
|
|
||||||
.contextPath("/msg-platform")
|
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
|
||||||
.content(tenantPayload))
|
|
||||||
.andExpect(status().isOk())
|
|
||||||
.andExpect(jsonPath("$.code").value(0));
|
|
||||||
|
|
||||||
String accountPayload = "{\"accountType\":1,\"channelType\":\"wecom\",\"accountId\":\"ZhangSan\",\"accountName\":\"张三\"}";
|
String accountPayload = "{\"accountType\":1,\"channelType\":\"wecom\",\"accountId\":\"ZhangSan\",\"accountName\":\"张三\"}";
|
||||||
String accountResponse = mockMvc.perform(post("/msg-platform/api/v1/channel-account")
|
String accountResponse = mockMvc.perform(post("/msg-platform/api/v1/channel-account")
|
||||||
.contextPath("/msg-platform")
|
.contextPath("/msg-platform")
|
||||||
|
.header("Authorization", authToken)
|
||||||
.header("X-Tenant-Code", tenantCode)
|
.header("X-Tenant-Code", tenantCode)
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content(accountPayload))
|
.content(accountPayload))
|
||||||
@@ -49,6 +44,7 @@ public class SendControllerTest {
|
|||||||
String conversationPayload = "{\"conversationType\":2,\"channelType\":\"wecom\",\"channelConversationId\":\"room-001\",\"conversationName\":\"测试群\"}";
|
String conversationPayload = "{\"conversationType\":2,\"channelType\":\"wecom\",\"channelConversationId\":\"room-001\",\"conversationName\":\"测试群\"}";
|
||||||
String conversationResponse = mockMvc.perform(post("/msg-platform/api/v1/conversation")
|
String conversationResponse = mockMvc.perform(post("/msg-platform/api/v1/conversation")
|
||||||
.contextPath("/msg-platform")
|
.contextPath("/msg-platform")
|
||||||
|
.header("Authorization", authToken)
|
||||||
.header("X-Tenant-Code", tenantCode)
|
.header("X-Tenant-Code", tenantCode)
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content(conversationPayload))
|
.content(conversationPayload))
|
||||||
@@ -60,6 +56,7 @@ public class SendControllerTest {
|
|||||||
String bindPayload = String.format("{\"accountId\":%d,\"bindingType\":1,\"sortOrder\":1}", accountId);
|
String bindPayload = String.format("{\"accountId\":%d,\"bindingType\":1,\"sortOrder\":1}", accountId);
|
||||||
mockMvc.perform(post("/msg-platform/api/v1/conversation/" + conversationId + "/bind-account")
|
mockMvc.perform(post("/msg-platform/api/v1/conversation/" + conversationId + "/bind-account")
|
||||||
.contextPath("/msg-platform")
|
.contextPath("/msg-platform")
|
||||||
|
.header("Authorization", authToken)
|
||||||
.header("X-Tenant-Code", tenantCode)
|
.header("X-Tenant-Code", tenantCode)
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content(bindPayload))
|
.content(bindPayload))
|
||||||
@@ -71,6 +68,7 @@ public class SendControllerTest {
|
|||||||
conversationId);
|
conversationId);
|
||||||
String sendResponse = mockMvc.perform(post("/msg-platform/api/v1/send/test")
|
String sendResponse = mockMvc.perform(post("/msg-platform/api/v1/send/test")
|
||||||
.contextPath("/msg-platform")
|
.contextPath("/msg-platform")
|
||||||
|
.header("Authorization", authToken)
|
||||||
.header("X-Tenant-Code", tenantCode)
|
.header("X-Tenant-Code", tenantCode)
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content(sendPayload))
|
.content(sendPayload))
|
||||||
@@ -83,6 +81,7 @@ public class SendControllerTest {
|
|||||||
|
|
||||||
mockMvc.perform(get("/msg-platform/api/v1/send/" + taskId + "/records")
|
mockMvc.perform(get("/msg-platform/api/v1/send/" + taskId + "/records")
|
||||||
.contextPath("/msg-platform")
|
.contextPath("/msg-platform")
|
||||||
|
.header("Authorization", authToken)
|
||||||
.header("X-Tenant-Code", tenantCode))
|
.header("X-Tenant-Code", tenantCode))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$.code").value(0))
|
.andExpect(jsonPath("$.code").value(0))
|
||||||
@@ -94,17 +93,12 @@ public class SendControllerTest {
|
|||||||
@Test
|
@Test
|
||||||
void shouldRejectUnsupportedTargetType() throws Exception {
|
void shouldRejectUnsupportedTargetType() throws Exception {
|
||||||
String tenantCode = "send-" + UUID.randomUUID().toString().substring(0, 8);
|
String tenantCode = "send-" + UUID.randomUUID().toString().substring(0, 8);
|
||||||
String tenantPayload = String.format("{\"tenantCode\":\"%s\",\"tenantName\":\"发送测试\"}", tenantCode);
|
String authToken = createTenantAndLogin(mockMvc, tenantCode, "发送测试");
|
||||||
mockMvc.perform(post("/msg-platform/api/v1/account/tenant")
|
|
||||||
.contextPath("/msg-platform")
|
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
|
||||||
.content(tenantPayload))
|
|
||||||
.andExpect(status().isOk())
|
|
||||||
.andExpect(jsonPath("$.code").value(0));
|
|
||||||
|
|
||||||
String sendPayload = "{\"targetType\":\"rule\",\"targetValue\":{},\"contentType\":\"text\",\"content\":{\"text\":\"hello\"}}";
|
String sendPayload = "{\"targetType\":\"rule\",\"targetValue\":{},\"contentType\":\"text\",\"content\":{\"text\":\"hello\"}}";
|
||||||
mockMvc.perform(post("/msg-platform/api/v1/send/test")
|
mockMvc.perform(post("/msg-platform/api/v1/send/test")
|
||||||
.contextPath("/msg-platform")
|
.contextPath("/msg-platform")
|
||||||
|
.header("Authorization", authToken)
|
||||||
.header("X-Tenant-Code", tenantCode)
|
.header("X-Tenant-Code", tenantCode)
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content(sendPayload))
|
.content(sendPayload))
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
package com.sino.mci.test;
|
||||||
|
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
|
import org.springframework.test.web.servlet.MvcResult;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
public class AuthTestHelper {
|
||||||
|
|
||||||
|
public static final String ADMIN_USERNAME = "admin";
|
||||||
|
public static final String ADMIN_PASSWORD = "admin123";
|
||||||
|
|
||||||
|
public static String createTenantAndLogin(MockMvc mockMvc) throws Exception {
|
||||||
|
String tenantCode = "test-" + UUID.randomUUID().toString().substring(0, 8);
|
||||||
|
return createTenantAndLogin(mockMvc, tenantCode, "测试租户");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String createTenantAndLogin(MockMvc mockMvc, String tenantCode, String tenantName) throws Exception {
|
||||||
|
createTenant(mockMvc, tenantCode, tenantName);
|
||||||
|
createAdminUser(mockMvc, tenantCode);
|
||||||
|
return login(mockMvc, tenantCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void createTenant(MockMvc mockMvc, String tenantCode, String tenantName) throws Exception {
|
||||||
|
String payload = String.format("{\"tenantCode\":\"%s\",\"tenantName\":\"%s\"}", tenantCode, tenantName);
|
||||||
|
mockMvc.perform(post("/msg-platform/api/v1/account/tenant")
|
||||||
|
.contextPath("/msg-platform")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.content(payload))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.code").value(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void createAdminUser(MockMvc mockMvc, String tenantCode) throws Exception {
|
||||||
|
String payload = String.format(
|
||||||
|
"{\"username\":\"%s\",\"password\":\"%s\",\"realName\":\"管理员\",\"phone\":\"13800138000\",\"roleCodes\":[\"platform_admin\"]}",
|
||||||
|
ADMIN_USERNAME, ADMIN_PASSWORD);
|
||||||
|
mockMvc.perform(post("/msg-platform/api/v1/account/user")
|
||||||
|
.contextPath("/msg-platform")
|
||||||
|
.header("X-Tenant-Code", tenantCode)
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.content(payload))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.code").value(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String login(MockMvc mockMvc, String tenantCode) throws Exception {
|
||||||
|
String payload = String.format("{\"username\":\"%s\",\"password\":\"%s\"}", ADMIN_USERNAME, ADMIN_PASSWORD);
|
||||||
|
MvcResult result = mockMvc.perform(post("/msg-platform/api/v1/account/login")
|
||||||
|
.contextPath("/msg-platform")
|
||||||
|
.header("X-Tenant-Code", tenantCode)
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.content(payload))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.code").value(0))
|
||||||
|
.andReturn();
|
||||||
|
return "Bearer " + com.jayway.jsonpath.JsonPath.read(result.getResponse().getContentAsString(), "$.data.token");
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user