test: RoomescapeLogMaskingConverter 테스트 추가 및 잘못 작성된 로직 수정

This commit is contained in:
이상진 2025-07-29 15:47:57 +09:00
parent e2f77b982b
commit 7131d11fad
2 changed files with 87 additions and 10 deletions

View File

@ -36,7 +36,7 @@ class RoomescapeLogMaskingConverter : MessageConverter() {
private fun maskedPlainMessage(message: String): String { private fun maskedPlainMessage(message: String): String {
val keys: String = SENSITIVE_KEYS.joinToString("|") val keys: String = SENSITIVE_KEYS.joinToString("|")
val regex = Regex("(?i)($keys)(\\s*=\\s*)(\\S+)") val regex = Regex("(?i)($keys)(\\s*=\\s*)([^,\\s]+)")
return regex.replace(message) { matchResult -> return regex.replace(message) { matchResult ->
val key = matchResult.groupValues[1] val key = matchResult.groupValues[1]
@ -47,19 +47,11 @@ class RoomescapeLogMaskingConverter : MessageConverter() {
} }
} }
private fun maskValue(value: String): String {
return if (value.length <= 2) {
MASK
} else {
"${value.first()}$MASK${value.last()}"
}
}
private fun maskRecursive(node: JsonNode?) { private fun maskRecursive(node: JsonNode?) {
node?.forEachEntry { key, childNode -> node?.forEachEntry { key, childNode ->
when { when {
childNode.isValueNode -> { childNode.isValueNode -> {
if (key in SENSITIVE_KEYS) (node as ObjectNode).put(key, MASK) if (key in SENSITIVE_KEYS) (node as ObjectNode).put(key, maskValue(childNode.asText()))
} }
childNode.isObject -> maskRecursive(childNode) childNode.isObject -> maskRecursive(childNode)
@ -78,4 +70,12 @@ class RoomescapeLogMaskingConverter : MessageConverter() {
} }
} }
} }
private fun maskValue(value: String): String {
return if (value.length <= 2) {
MASK
} else {
"${value.first()}$MASK${value.last()}"
}
}
} }

View File

@ -0,0 +1,77 @@
package roomescape.common.log
import ch.qos.logback.classic.spi.ILoggingEvent
import io.kotest.assertions.assertSoftly
import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.equals.shouldBeEqual
import io.kotest.matchers.string.shouldContain
import io.mockk.every
import io.mockk.mockk
class RoomescapeLogMaskingConverterTest : FunSpec({
val converter = RoomescapeLogMaskingConverter()
val event: ILoggingEvent = mockk()
context("평문 로그에서는 key=value 형식을 처리한다.") {
test("2글자 초과이면 맨 앞, 맨 뒤를 제외한 나머지를 가린다.") {
val email = "a@a.a"
val password = "password12"
val accessToken = "accessToken12"
every {
event.formattedMessage
} returns "email=${email}, password=${password}, accessToken = $accessToken"
assertSoftly(converter.convert(event)) {
this shouldContain "email=${email}"
this shouldContain "password=${password.first()}****${password.last()}"
this shouldContain "accessToken = ${accessToken.first()}****${accessToken.last()}"
}
}
test("2글자 이하이면 전부 가린다.") {
val email = "a@a.a"
val password = "pa"
val accessToken = "a"
every {
event.formattedMessage
} returns "email=${email}, password=${password}, accessToken = ${accessToken}"
assertSoftly(converter.convert(event)) {
this shouldContain "email=${email}"
this shouldContain "password=****"
this shouldContain "accessToken = ****"
}
}
}
context("JSON 형식 로그를 처리한다.") {
val json = "{\"request_body\":{\"email\":\"a@a.a\",\"password\":\"password12\"}}"
test("2글자 초과이면 맨 앞, 맨 뒤를 제외한 나머지를 가린다.") {
val password = "password12"
val json = "{\"request_body\":{\"email\":\"a@a.a\",\"password\":\"${password}\"}}"
every {
event.formattedMessage
} returns json
converter.convert(event) shouldBeEqual "{\"request_body\":{\"email\":\"a@a.a\",\"password\":\"${password.first()}****${password.last()}\"}}"
}
test("2글자 이하이면 전부 가린다.") {
val password = "pa"
val json = "{\"request_body\":{\"email\":\"a@a.a\",\"password\":\"${password}\"}}"
every {
event.formattedMessage
} returns json
converter.convert(event) shouldBeEqual "{\"request_body\":{\"email\":\"a@a.a\",\"password\":\"****\"}}"
}
}
})