修复来源消息列表酒店参数鉴权

This commit is contained in:
andy
2026-07-16 11:45:58 +07:00
parent 5c0a5d21d0
commit 93ecfb08a9
4 changed files with 90 additions and 16 deletions

View File

@@ -74,10 +74,10 @@ class SourceMessageControllerTest {
));
performAuthorized(mockMvc, adminToken(), get("/api/source-messages")
.param("hotelId", "HOTEL-TEST")
.param("externalConversationId", "conversation-api-001")
.param("pageNum", "1")
.param("pageSize", "20"))
.param("hotel_id", "HOTEL-TEST")
.param("external_conversation_id", "conversation-api-001")
.param("page_num", "1")
.param("page_size", "20"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.items[0].id").value(result.inboxId().toString()))
.andExpect(jsonPath("$.items[0].externalMessageId").value("mail-api-001"))

View File

@@ -39,7 +39,9 @@ import org.springframework.test.web.servlet.MockMvc;
"auth.bootstrap.default-hotel-id=HOTEL-TEST",
"auth.bootstrap.default-hotel-name=测试酒店",
"auth.bootstrap.default-hotel-time-zone=Asia/Bangkok",
"superagent.task-result.hmac-secret=test-superagent-secret"
"superagent.task-result.hmac-secret=test-superagent-secret",
"mcp.enabled=true",
"mcp.auth-token=test-mcp-token"
})
@AutoConfigureMockMvc
@ActiveProfiles("test")
@@ -99,6 +101,34 @@ class FrontendReadAuthorizationControllerTest {
.andExpect(jsonPath("$.error_code").value("FRONTEND_PERMISSION_DENIED"));
}
@Test
void shouldRejectSourceMessageReadWhenTokenMissing() throws Exception {
mockMvc.perform(get("/api/source-messages")
.param("hotel_id", HOTEL_ID))
.andExpect(status().isUnauthorized())
.andExpect(jsonPath("$.error_code").value("AUTH_TOKEN_REQUIRED"));
}
@Test
void shouldRejectSourceMessageReadWhenPermissionMissing() throws Exception {
String token = loginToken(mockMvc, "cp1-no-permission", "NoPerm@123456");
performAuthorized(mockMvc, token, get("/api/source-messages")
.param("hotel_id", HOTEL_ID))
.andExpect(status().isForbidden())
.andExpect(jsonPath("$.error_code").value("FRONTEND_PERMISSION_DENIED"));
}
@Test
void shouldRejectSourceMessageListAcrossHotelsWhenSnakeHotelIdProvided() throws Exception {
String token = loginToken(mockMvc, "cp1-admin", "Admin@123456");
performAuthorized(mockMvc, token, get("/api/source-messages")
.param("hotel_id", OTHER_HOTEL_ID))
.andExpect(status().isForbidden())
.andExpect(jsonPath("$.error_code").value("HOTEL_ACCESS_DENIED"));
}
@Test
void shouldRejectReservationAndSourceMessageDetailAcrossHotels() throws Exception {
String token = loginToken(mockMvc, "cp1-admin", "Admin@123456");
@@ -133,6 +163,31 @@ class FrontendReadAuthorizationControllerTest {
.andExpect(jsonPath("$.error_code").value("AUTH_HEADER_MISSING"));
}
@Test
void shouldKeepAiQueryEndpointOutsideFrontendLoginInterceptor() throws Exception {
mockMvc.perform(post("/api/ai-query/v1/case-context")
.contentType(MediaType.APPLICATION_JSON)
.content("{}"))
.andExpect(status().isUnauthorized())
.andExpect(jsonPath("$.error.code").value("AUTH_HEADER_MISSING"));
}
@Test
void shouldKeepMcpEndpointOutsideFrontendLoginInterceptor() throws Exception {
mockMvc.perform(post("/mcp")
.contentType(MediaType.APPLICATION_JSON)
.content("""
{
"jsonrpc": "2.0",
"id": "cp1-mcp-auth-001",
"method": "tools/list",
"params": {}
}
"""))
.andExpect(status().isUnauthorized())
.andExpect(jsonPath("$.error.data.code").value("MCP_AUTH_INVALID"));
}
private SourceMessageCaptureResult captureOtherHotelSourceMessage() {
return captureService.capture(new CaptureSourceMessageCommand(
OTHER_HOTEL_ID,