어댑터 암복호화 필터 리팩토링

- 커스텀 패키지 지정
- 변수 이동
This commit is contained in:
curry772
2026-05-26 09:54:11 +09:00
parent a51453a57f
commit 0e96e9470e
9 changed files with 88 additions and 33 deletions
@@ -85,7 +85,7 @@ class OutCryptoFilterTest {
@DisplayName("1-2. buildAad — CRYPTO_AAD_PROP 설정, tempProp에 값 없음 → null")
void testBuildAad_propSet_noTempValue_returnsNull() {
Properties prop = new Properties();
prop.setProperty(OutCryptoFilter.PROP_AAD_PROP, "aadKey");
prop.setProperty(AbstractCryptoFilter.PROP_AAD_HEADER, "aadKey");
assertNull(filter.buildAad(prop, tempProp));
}
@@ -95,7 +95,7 @@ class OutCryptoFilterTest {
void testBuildAad_propSet_tempValuePresent_returnsByte() {
String aadVal = "aad-value-xyz";
Properties prop = new Properties();
prop.setProperty(OutCryptoFilter.PROP_AAD_PROP, "aadKey");
prop.setProperty(AbstractCryptoFilter.PROP_AAD_HEADER, "aadKey");
tempProp.setProperty("aadKey", aadVal);
assertArrayEquals(aadVal.getBytes(StandardCharsets.UTF_8), filter.buildAad(prop, tempProp));
@@ -118,7 +118,7 @@ class OutCryptoFilterTest {
@DisplayName("2-2. FIELD scope, fromPath='/' — body 전체 암호화 → toPath 필드명으로 래핑")
void testPreFilter_field_encryptFromRoot() throws Exception {
String body = "{\"userId\":\"U001\"}";
Properties prop = fieldEncryptProps("/", "/encryptedData");
Properties prop = fieldEncryptProps(tempProp, "/", "/encryptedData");
Object result = filter.doPreFilter("g", "a", prop, body, tempProp);
@@ -129,7 +129,7 @@ class OutCryptoFilterTest {
@DisplayName("2-3. FIELD scope — fromPath 평문 암호화 → toPath Base64 반영")
void testPreFilter_field_encryptSpecificPath() throws Exception {
String body = "{\"data\":\"secret\",\"enc\":\"\"}";
Properties prop = fieldEncryptProps("/data", "/enc");
Properties prop = fieldEncryptProps(tempProp, "/data", "/enc");
Object result = filter.doPreFilter("g", "a", prop, body, tempProp);
@@ -141,7 +141,7 @@ class OutCryptoFilterTest {
@DisplayName("2-4. FIELD scope — fromPath 값 없음 → body 그대로 반환")
void testPreFilter_field_missingFromPath_passThrough() throws Exception {
String body = "{\"other\":\"value\"}";
Properties prop = fieldEncryptProps("/data", "/enc");
Properties prop = fieldEncryptProps(tempProp, "/data", "/enc");
Object result = filter.doPreFilter("g", "a", prop, body, tempProp);
@@ -176,7 +176,7 @@ class OutCryptoFilterTest {
@DisplayName("3-2. FIELD scope — fromPath 복호화 → toPath 반영")
void testPostFilter_field_decryptToPath() throws Exception {
String body = "{\"enc\":\"" + CIPHER_B64 + "\",\"result\":\"\"}";
Properties prop = fieldDecryptProps("/enc", "/result");
Properties prop = fieldDecryptProps(tempProp, "/enc", "/result");
Object result = filter.doPostFilter("g", "a", prop, body, tempProp);
@@ -188,7 +188,7 @@ class OutCryptoFilterTest {
@DisplayName("3-3. FIELD scope, toPath='/' — 복호화된 텍스트로 body 전체 교체")
void testPostFilter_field_decryptToRoot() throws Exception {
String body = "{\"enc\":\"" + CIPHER_B64 + "\"}";
Properties prop = fieldDecryptProps("/enc", "/");
Properties prop = fieldDecryptProps(tempProp, "/enc", "/");
Object result = filter.doPostFilter("g", "a", prop, body, tempProp);
@@ -199,7 +199,7 @@ class OutCryptoFilterTest {
@DisplayName("3-4. FIELD scope — fromPath 값 없음 → body 그대로 반환")
void testPostFilter_field_missingFromPath_passThrough() throws Exception {
String body = "{\"other\":\"value\"}";
Properties prop = fieldDecryptProps("/enc", "/result");
Properties prop = fieldDecryptProps(tempProp, "/enc", "/result");
Object result = filter.doPostFilter("g", "a", prop, body, tempProp);
@@ -216,7 +216,7 @@ class OutCryptoFilterTest {
void testPreFilter_body_aadFromTempProp() throws Exception {
String aadVal = "out-aad-value";
Properties prop = bodyEncryptProps();
prop.setProperty(OutCryptoFilter.PROP_AAD_PROP, "myAadKey");
prop.setProperty(AbstractCryptoFilter.PROP_AAD_HEADER, "myAadKey");
tempProp.setProperty("myAadKey", aadVal);
filter.doPreFilter("g", "a", prop, PLAIN_STR, tempProp);
@@ -248,21 +248,21 @@ class OutCryptoFilterTest {
return bodyEncryptProps();
}
private Properties fieldEncryptProps(String fromPath, String toPath) {
private Properties fieldEncryptProps(Properties tempProp, String fromPath, String toPath) {
Properties p = new Properties();
p.setProperty(AbstractCryptoFilter.PROP_MODULE_NAME, MODULE);
p.setProperty(AbstractCryptoFilter.PROP_SCOPE, "FIELD");
p.setProperty(AbstractCryptoFilter.PROP_ENC_FROM_PATH, fromPath);
p.setProperty(AbstractCryptoFilter.PROP_ENC_TO_PATH, toPath);
tempProp.setProperty(AbstractCryptoFilter.PROP_ENC_FROM_PATH, fromPath);
tempProp.setProperty(AbstractCryptoFilter.PROP_ENC_TO_PATH, toPath);
return p;
}
private Properties fieldDecryptProps(String fromPath, String toPath) {
private Properties fieldDecryptProps(Properties tempProp, String fromPath, String toPath) {
Properties p = new Properties();
p.setProperty(AbstractCryptoFilter.PROP_MODULE_NAME, MODULE);
p.setProperty(AbstractCryptoFilter.PROP_SCOPE, "FIELD");
p.setProperty(AbstractCryptoFilter.PROP_DEC_FROM_PATH, fromPath);
p.setProperty(AbstractCryptoFilter.PROP_DEC_TO_PATH, toPath);
tempProp.setProperty(AbstractCryptoFilter.PROP_DEC_FROM_PATH, fromPath);
tempProp.setProperty(AbstractCryptoFilter.PROP_DEC_TO_PATH, toPath);
return p;
}
}
@@ -6,12 +6,14 @@ import static org.mockito.Mockito.*;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.mockito.ArgumentCaptor;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
@@ -88,6 +90,47 @@ class InCryptoFilterTest {
assertTrue(result.isEmpty());
}
@SuppressWarnings("unchecked")
@Test
@DisplayName("1-2. buildRuntimeContext 오버라이드 시 runtimeContext가 복호화 서비스에 전달된다")
void testBuildRuntimeContext_override_passedToDecrypt() throws Exception {
InCryptoFilter filterWithCtx = new InCryptoFilter() {
@Override
protected Map<String, String> buildRuntimeContext(Properties p, HttpServletRequest req) {
Map<String, String> ctx = new HashMap<>();
ctx.put("groupSeq", "G001");
return ctx;
}
};
String body = "{\"enc\":\"" + CIPHER_B64 + "\",\"result\":\"\"}";
filterWithCtx.doPreFilter("g", "a", body, fieldDecryptProps("/enc", "/result"), mockRequest, mockResponse);
ArgumentCaptor<Map> ctxCaptor = ArgumentCaptor.forClass(Map.class);
verify(mockService).decrypt(eq(MODULE), ctxCaptor.capture(), isNull(), eq(CIPHER));
assertEquals("G001", ctxCaptor.getValue().get("groupSeq"));
}
@SuppressWarnings("unchecked")
@Test
@DisplayName("1-3. buildRuntimeContext 오버라이드 시 runtimeContext가 암호화 서비스에 전달된다")
void testBuildRuntimeContext_override_passedToEncrypt() throws Exception {
InCryptoFilter filterWithCtx = new InCryptoFilter() {
@Override
protected Map<String, String> buildRuntimeContext(Properties p, HttpServletRequest req) {
Map<String, String> ctx = new HashMap<>();
ctx.put("groupSeq", "G001");
return ctx;
}
};
filterWithCtx.doPostFilter("g", "a", "plain-body", fieldEncryptProps("/", "/encryptedData"), mockRequest, mockResponse);
ArgumentCaptor<Map> ctxCaptor = ArgumentCaptor.forClass(Map.class);
verify(mockService).encrypt(eq(MODULE), ctxCaptor.capture(), isNull(), any(byte[].class));
assertEquals("G001", ctxCaptor.getValue().get("groupSeq"));
}
// =========================================================================
// 2. buildAad
// =========================================================================
@@ -151,6 +194,19 @@ class InCryptoFilterTest {
assertEquals(PLAIN_STR, result);
}
@Test
@DisplayName("3-4. message가 String/byte[] 외 타입 — toString() 변환 후 처리")
void testPreFilter_body_nonStringMessage_usesToString() throws Exception {
Object nonStringMsg = new Object() {
@Override
public String toString() { return CIPHER_B64; }
};
Object result = filter.doPreFilter("g", "a", nonStringMsg, bodyDecryptProps(), mockRequest, mockResponse);
assertEquals(PLAIN_STR, result);
}
// =========================================================================
// 4. doPreFilter — FIELD scope 복호화
// =========================================================================