130 lines
7.8 KiB
Java
130 lines
7.8 KiB
Java
package com.mgm.mcrm;
|
|
|
|
import com.auth0.jwt.JWT;
|
|
import com.auth0.jwt.algorithms.Algorithm;
|
|
import com.mgm.mcrm.appsetting.controllers.CfgSettingController;
|
|
import com.mgm.mcrm.appsetting.dtos.CfgSettingQueryRequest;
|
|
import com.mgm.mcrm.appsetting.models.CfgSettings;
|
|
import com.mgm.mcrm.appsetting.models.SysSetting;
|
|
import com.mgm.mcrm.appsetting.services.SettingService;
|
|
import com.mgm.mcrm.appsetting.services.SysSettingService;
|
|
import com.mgm.mcrm.authorization.services.UserTokenService;
|
|
import com.mgm.mcrm.common.config.WebFilterConfig;
|
|
import com.mgm.mcrm.logging.controllers.SysLogAppController;
|
|
import com.mgm.mcrm.logging.dtos.AppLogDto;
|
|
import com.mgm.mcrm.logging.models.SysLogApp;
|
|
import com.mgm.mcrm.logging.services.SysLogAppService;
|
|
import org.junit.jupiter.api.Test;
|
|
import org.springframework.mock.web.MockHttpServletRequest;
|
|
import org.springframework.mock.web.MockHttpServletResponse;
|
|
import org.springframework.test.util.ReflectionTestUtils;
|
|
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
|
|
|
import java.util.concurrent.atomic.AtomicBoolean;
|
|
|
|
import static org.junit.jupiter.api.Assertions.*;
|
|
import static org.mockito.Mockito.*;
|
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
|
|
|
class PublicEndpointsMigrationTest {
|
|
@Test void publicConfigurationRejectsOtherKeysBeforeQuery() throws Exception {
|
|
var service = mock(SettingService.class);
|
|
var controller = new CfgSettingController();
|
|
ReflectionTestUtils.setField(controller, "settingService", service);
|
|
for (String key : new String[]{null, "", "MACAU_IP", "macau_string", "MACAU_STRING "}) {
|
|
var query = new CfgSettingQueryRequest(); query.setKeyName(key);
|
|
var result = controller.getPublicSettingByKey(new MockHttpServletRequest(), query).getBody();
|
|
assertFalse(result.isSuccess()); assertEquals("SETTING_KEY_NOT_ALLOWED", result.getCode());
|
|
}
|
|
assertFalse(controller.getPublicSettingByKey(new MockHttpServletRequest(), null).getBody().isSuccess());
|
|
verifyNoInteractions(service);
|
|
var setting = new CfgSettings();
|
|
when(service.getSettingByKey("MACAU_STRING")).thenReturn(setting);
|
|
var query = new CfgSettingQueryRequest(); query.setKeyName("MACAU_STRING");
|
|
assertSame(setting, controller.getPublicSettingByKey(new MockHttpServletRequest(), query).getBody().getData());
|
|
verify(service).getSettingByKey("MACAU_STRING");
|
|
}
|
|
|
|
@Test void publicLoginSettingsOnlyFetchTwoAllowedKeysAndAllowMissingSettings() {
|
|
var service = mock(SysSettingService.class);
|
|
var controller = new CfgSettingController();
|
|
ReflectionTestUtils.setField(controller, "sysSettingService", service);
|
|
var sso = new SysSetting(); var tpd = new SysSetting();
|
|
when(service.getSysSettingByKey("APP_MOCK_SSO")).thenReturn(sso);
|
|
when(service.getSysSettingByKey("APP_MOCK_TPD")).thenReturn(tpd);
|
|
assertEquals(java.util.List.of(sso, tpd), controller.getPublicLoginSettings(new MockHttpServletRequest()).getBody().getData());
|
|
verify(service).getSysSettingByKey("APP_MOCK_SSO");
|
|
verify(service).getSysSettingByKey("APP_MOCK_TPD");
|
|
verifyNoMoreInteractions(service);
|
|
when(service.getSysSettingByKey("APP_MOCK_TPD")).thenReturn(null);
|
|
assertEquals(1, controller.getPublicLoginSettings(new MockHttpServletRequest()).getBody().getData().size());
|
|
}
|
|
|
|
@Test void filterAllowsOnlyNewPublicRoutesAndKeepsRefreshProtected() throws Exception {
|
|
var config = new WebFilterConfig();
|
|
var tokens = mock(UserTokenService.class);
|
|
ReflectionTestUtils.setField(config, "secretKey", "test-only-key");
|
|
ReflectionTestUtils.setField(config, "userTokenService", tokens);
|
|
var filter = config.jwtAuthFilter().getFilter();
|
|
for (String route : new String[]{"/system/write_public_log", "/system/sys_setting/get_public_login_settings", "/web/setting/get_public_setting_by_key"}) {
|
|
var reached = new AtomicBoolean();
|
|
filter.doFilter(new MockHttpServletRequest("POST", "/api" + route), new MockHttpServletResponse(),
|
|
(req, res) -> reached.set(true));
|
|
assertTrue(reached.get(), route);
|
|
}
|
|
for (String route : new String[]{"/system/write_log", "/system/sys_setting/get_list", "/web/setting/get_setting_by_key", "/app/booking/mock_cancel", "/app/refresh_token"}) {
|
|
var reached = new AtomicBoolean(); var response = new MockHttpServletResponse();
|
|
filter.doFilter(new MockHttpServletRequest("POST", "/api" + route), response, (req, res) -> reached.set(true));
|
|
assertFalse(reached.get(), route); assertEquals(401, response.getStatus(), route);
|
|
}
|
|
}
|
|
|
|
private SysLogAppController logs(SysLogAppService service) {
|
|
var controller = new SysLogAppController();
|
|
ReflectionTestUtils.setField(controller, "logService", service);
|
|
when(service.save(any(SysLogApp.class))).thenAnswer(call -> call.getArgument(0));
|
|
return controller;
|
|
}
|
|
|
|
@Test void anonymousIdentityCannotBeSpoofedAndNullBodiesAreSafe() {
|
|
var service = mock(SysLogAppService.class); var controller = logs(service);
|
|
var dto = new AppLogDto(); dto.setLoginId("admin");
|
|
var result = controller.writePublicAppLog(new MockHttpServletRequest(), dto).getBody().getData();
|
|
assertEquals("ANONYMOUS", result.getLoginId()); assertNull(result.getLogDesc());
|
|
assertNull(result.getRequestBody()); assertNull(result.getResponseBody()); assertEquals(0, result.getTagSuccess());
|
|
assertEquals(400, controller.writePublicAppLog(new MockHttpServletRequest(), null).getStatusCode().value());
|
|
verify(service, times(1)).save(any(SysLogApp.class));
|
|
}
|
|
|
|
@Test void authenticatedLogUsesTokenIdentityAndRequiresIdentity() {
|
|
var service = mock(SysLogAppService.class); var controller = logs(service);
|
|
var dto = new AppLogDto(); dto.setLoginId("forged-user");
|
|
var request = new MockHttpServletRequest();
|
|
assertEquals(401, controller.writeAppLog(request, dto).getStatusCode().value());
|
|
verify(service, never()).save(any());
|
|
// Controller identity test; JWT admission is covered separately by the filter test.
|
|
request.addHeader("Authorization", "Bearer " + JWT.create().withSubject("80001")
|
|
.withClaim("login_id", "actual-user").sign(Algorithm.HMAC256("test-only-key")));
|
|
assertEquals("actual-user", controller.writeAppLog(request, dto).getBody().getData().getLoginId());
|
|
}
|
|
|
|
@Test void logsLimitInputAndEscapeText() {
|
|
var controller = logs(mock(SysLogAppService.class));
|
|
var dto = new AppLogDto(); dto.setEventCode("e".repeat(101)); dto.setTransId("t".repeat(101));
|
|
dto.setLogDesc("x".repeat(999) + "<ignored"); dto.setRequestBody("r".repeat(4001)); dto.setResponseBody("<script>&");
|
|
var log = controller.writePublicAppLog(new MockHttpServletRequest(), dto).getBody().getData();
|
|
assertEquals(100, log.getEventCode().length()); assertEquals(100, log.getTransId().length());
|
|
assertEquals("x".repeat(999) + "<", log.getLogDesc());
|
|
assertEquals(4000, log.getRequestBody().length()); assertEquals("<script>&", log.getResponseBody());
|
|
}
|
|
|
|
@Test void httpRejectsMissingAndMalformedLogBodiesWithoutSaving() throws Exception {
|
|
var service = mock(SysLogAppService.class); var mvc = MockMvcBuilders.standaloneSetup(logs(service)).build();
|
|
mvc.perform(post("/api/system/write_public_log")).andExpect(status().isBadRequest());
|
|
mvc.perform(post("/api/system/write_public_log").contentType("application/json")
|
|
.content("{\"tagSuccess\":\"not-a-number\"}")).andExpect(status().isBadRequest());
|
|
verify(service, never()).save(any());
|
|
}
|
|
}
|