This commit is contained in:
@@ -12,6 +12,6 @@ PortalTermsManController_약관관리_APIGW_INSERT,UPDATE,DELETE
|
|||||||
ProdClientManController_운영Client (키정보)관리_APIGW_INSERT,UPDATE,DELETE
|
ProdClientManController_운영Client (키정보)관리_APIGW_INSERT,UPDATE,DELETE
|
||||||
ApiSpecController_API스펙관리_APIGW_INSERT,DELETE
|
ApiSpecController_API스펙관리_APIGW_INSERT,DELETE
|
||||||
MessageTemplateManController_메세지템플릿관리_APIGW_INSERT,UPDATE,DELETE
|
MessageTemplateManController_메세지템플릿관리_APIGW_INSERT,UPDATE,DELETE
|
||||||
PortalPartnershipManController_피드백/개선요청관리_APIGW_UNMASK
|
PortalPartnershipManController_피드백/개선요청관리_APIGW_UNMASK,DELETE
|
||||||
PortalPropertyController_포탈 프로퍼티 관리_APIGW_UPDATE
|
PortalPropertyController_포탈 프로퍼티 관리_APIGW_UPDATE
|
||||||
PortalUserTermsManController_약관동의 이력_APIGW_UNMASK
|
PortalUserTermsManController_약관동의 이력_APIGW_UNMASK
|
||||||
@@ -1,5 +1,10 @@
|
|||||||
/**
|
/**
|
||||||
* 문자열 마스킹 처리를 위한 유틸리티
|
* 문자열 마스킹 처리를 위한 유틸리티
|
||||||
|
*
|
||||||
|
* 보안아키텍처 표준 마스킹 규칙(Java MaskingUtils)과 동일한 결과를 내도록 구현한다.
|
||||||
|
* 이름 2자: 뒤 1자리(가나→가*) / 3자 이상: 앞뒤 제외 가운데 전체(가나다라→가**라)
|
||||||
|
* 이메일 아이디 앞2·뒤2 마스킹, 4자 이하 전체(test→****, test123→**st1**)
|
||||||
|
* 전화 2·3번째 세그먼트 각각 뒤 2자리(010-1234-1234→010-12**-12**)
|
||||||
*/
|
*/
|
||||||
const StringMaskingUtil = {
|
const StringMaskingUtil = {
|
||||||
|
|
||||||
@@ -8,41 +13,51 @@ const StringMaskingUtil = {
|
|||||||
return str != null && str !== '';
|
return str != null && str !== '';
|
||||||
},
|
},
|
||||||
|
|
||||||
// 이름 마스킹 처리
|
// '*' 반복 생성
|
||||||
|
_stars: function(count) {
|
||||||
|
return count > 0 ? '*'.repeat(count) : '';
|
||||||
|
},
|
||||||
|
|
||||||
|
// 세그먼트 뒤 count 자리 마스킹
|
||||||
|
_maskSegmentTail: function(segment, count) {
|
||||||
|
if (segment.length <= count) {
|
||||||
|
return this._stars(segment.length);
|
||||||
|
}
|
||||||
|
return segment.substring(0, segment.length - count) + this._stars(count);
|
||||||
|
},
|
||||||
|
|
||||||
|
// 이름 마스킹 처리 (2자: 뒤 1자리, 3자 이상: 앞뒤 제외 가운데 전체)
|
||||||
maskName: function(name) {
|
maskName: function(name) {
|
||||||
if (!this.isValidString(name)) {
|
if (!this.isValidString(name)) {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
return name.length > 1 ?
|
const len = name.length;
|
||||||
name.substring(0, name.length - 1) + "*" :
|
if (len === 1) {
|
||||||
name;
|
return name;
|
||||||
|
}
|
||||||
|
if (len === 2) {
|
||||||
|
return name.charAt(0) + '*';
|
||||||
|
}
|
||||||
|
return name.charAt(0) + this._stars(len - 2) + name.charAt(len - 1);
|
||||||
},
|
},
|
||||||
|
|
||||||
// 이메일 마스킹 처리
|
// 이메일 마스킹 처리 (아이디 앞2·뒤2, 4자 이하 전체)
|
||||||
maskEmail: function(email) {
|
maskEmail: function(email) {
|
||||||
if (!this.isValidString(email) || !email.includes('@')) {
|
if (!this.isValidString(email) || !email.includes('@')) {
|
||||||
return email;
|
return email;
|
||||||
}
|
}
|
||||||
|
|
||||||
const parts = email.split('@');
|
const atIdx = email.indexOf('@');
|
||||||
if (parts.length !== 2) {
|
const local = email.substring(0, atIdx);
|
||||||
return email;
|
const domain = email.substring(atIdx);
|
||||||
|
|
||||||
|
if (local.length <= 4) {
|
||||||
|
return this._stars(local.length) + domain;
|
||||||
}
|
}
|
||||||
|
return this._stars(2) + local.substring(2, local.length - 2) + this._stars(2) + domain;
|
||||||
const localPart = parts[0];
|
|
||||||
let maskedLocal;
|
|
||||||
|
|
||||||
if (localPart.length <= 3) {
|
|
||||||
maskedLocal = localPart.substring(0, 1) +
|
|
||||||
'*'.repeat(localPart.length - 1);
|
|
||||||
} else {
|
|
||||||
maskedLocal = localPart.substring(0, localPart.length - 3) + '***';
|
|
||||||
}
|
|
||||||
|
|
||||||
return maskedLocal + '@' + parts[1];
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// 휴대폰 번호 마스킹 처리
|
// 휴대폰/전화 번호 마스킹 처리 (2·3번째 세그먼트 각각 뒤 2자리)
|
||||||
maskMobileNumber: function(number) {
|
maskMobileNumber: function(number) {
|
||||||
if (!this.isValidString(number)) {
|
if (!this.isValidString(number)) {
|
||||||
return number;
|
return number;
|
||||||
@@ -50,8 +65,10 @@ const StringMaskingUtil = {
|
|||||||
|
|
||||||
const parts = number.split('-');
|
const parts = number.split('-');
|
||||||
if (parts.length === 3) {
|
if (parts.length === 3) {
|
||||||
return parts[0] + '-****-' + parts[2];
|
return parts[0] + '-' +
|
||||||
|
this._maskSegmentTail(parts[1], 2) + '-' +
|
||||||
|
this._maskSegmentTail(parts[2], 2);
|
||||||
}
|
}
|
||||||
return number;
|
return number;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -26,31 +26,6 @@ function formatFile(cellvalue, options, rowObject) {
|
|||||||
return cellvalue + icon;
|
return cellvalue + icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatDelete(cellvalue, options, rowObject) {
|
|
||||||
return '<button type="button" class="cssbtn" level="W" onclick="deleteRow(\'' + rowObject.id + '\');" '
|
|
||||||
+ 'style="background-color:#dc3545;border-color:#dc3545;color:white;padding:2px 8px;">삭제</button>';
|
|
||||||
}
|
|
||||||
|
|
||||||
function deleteRow(id) {
|
|
||||||
if (!confirm('선택한 항목을 삭제하시겠습니까?')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
type: "POST",
|
|
||||||
url: url,
|
|
||||||
dataType: "json",
|
|
||||||
data: { cmd: 'DELETE', id: id },
|
|
||||||
success: function(data) {
|
|
||||||
alert('삭제되었습니다.');
|
|
||||||
$("#grid").trigger("reloadGrid");
|
|
||||||
},
|
|
||||||
error: function(e) {
|
|
||||||
alert('삭제 중 오류가 발생했습니다.');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function deleteSelectedRows() {
|
function deleteSelectedRows() {
|
||||||
var selectedIds = $("#grid").jqGrid('getGridParam', 'selarrrow');
|
var selectedIds = $("#grid").jqGrid('getGridParam', 'selarrrow');
|
||||||
|
|
||||||
@@ -91,14 +66,13 @@ $(document).ready(function() {
|
|||||||
searchBizSubject: $('input[name=searchBizSubject]').val() ,
|
searchBizSubject: $('input[name=searchBizSubject]').val() ,
|
||||||
searchBizDetail: $('input[name=searchBizDetail]').val()
|
searchBizDetail: $('input[name=searchBizDetail]').val()
|
||||||
},
|
},
|
||||||
colNames:['No.', 'ID', '제목', '작성자', '작성일시', '관리'],
|
colNames:['No.', 'ID', '제목', '작성자', '작성일시'],
|
||||||
colModel:[
|
colModel:[
|
||||||
{ name : 'rowNum' , align:'center', width: 40, sortable: false },
|
{ name : 'rowNum' , align:'center', width: 40, sortable: false },
|
||||||
{ name : 'id' , align:'center', key: true, hidden: true},
|
{ name : 'id' , align:'center', key: true, hidden: true},
|
||||||
{ name : 'bizSubject' , align:'center', width: 150, formatter: formatFile },
|
{ name : 'bizSubject' , align:'center', width: 150, formatter: formatFile },
|
||||||
{ name : 'createdByName' , align:'center' ,width: 80},
|
{ name : 'createdByName' , align:'center' ,width: 80},
|
||||||
{ name : 'createdDate' , align:'center', width: 100, formatter: timeStampFormat },
|
{ name : 'createdDate' , align:'center', width: 100, formatter: timeStampFormat }
|
||||||
{ name : 'act' , align:'center', width: 60, sortable: false, formatter: formatDelete }
|
|
||||||
],
|
],
|
||||||
jsonReader: {
|
jsonReader: {
|
||||||
repeatitems:false
|
repeatitems:false
|
||||||
|
|||||||
@@ -92,6 +92,27 @@ $(document).ready(function() {
|
|||||||
goNav(returnUrl);//LIST로 이동
|
goNav(returnUrl);//LIST로 이동
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$("#btn_delete").click(function(){
|
||||||
|
if (!confirm('선택한 항목을 삭제하시겠습니까?')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: url,
|
||||||
|
dataType: "json",
|
||||||
|
data: { cmd: 'DELETE', id: key },
|
||||||
|
success: function(data) {
|
||||||
|
alert('삭제되었습니다.');
|
||||||
|
var returnUrl = getReturnUrlForReturn();
|
||||||
|
goNav(returnUrl);//LIST로 이동
|
||||||
|
},
|
||||||
|
error: function(e) {
|
||||||
|
alert('삭제 중 오류가 발생했습니다.');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
$("#btn_unmask").click(function () {
|
$("#btn_unmask").click(function () {
|
||||||
const reason = prompt("마스킹 해제 사유를 입력하세요:");
|
const reason = prompt("마스킹 해제 사유를 입력하세요:");
|
||||||
|
|
||||||
@@ -134,6 +155,7 @@ $(document).ready(function() {
|
|||||||
<div class="content_middle">
|
<div class="content_middle">
|
||||||
<div class="search_wrap">
|
<div class="search_wrap">
|
||||||
<button type="button" class="cssbtn" id="btn_unmask" level="W" status="DETAIL"><i class="material-icons">lock_open</i> 마스킹해제</button>
|
<button type="button" class="cssbtn" id="btn_unmask" level="W" status="DETAIL"><i class="material-icons">lock_open</i> 마스킹해제</button>
|
||||||
|
<button type="button" class="cssbtn" id="btn_delete" level="W" status="DETAIL" style="background-color: #dc3545; border-color: #dc3545; color: white;"><i class="material-icons">delete_forever</i> 삭제</button>
|
||||||
<button type="button" class="cssbtn" id="btn_previous" level="R" status="DETAIL,NEW"><i class="material-icons">arrow_back</i> <%= localeMessage.getString("button.previous") %></button>
|
<button type="button" class="cssbtn" id="btn_previous" level="R" status="DETAIL,NEW"><i class="material-icons">arrow_back</i> <%= localeMessage.getString("button.previous") %></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="title">피드백/개선요청 신청 상세</div>
|
<div class="title">피드백/개선요청 신청 상세</div>
|
||||||
|
|||||||
@@ -267,17 +267,14 @@ public class SmsAuthService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 전화번호 마스킹
|
* 전화번호 마스킹 (표준 규칙: 2·3번째 세그먼트 각각 뒤 2자리)
|
||||||
|
* 예: 010-1234-5678 → 010-12**-56**
|
||||||
*/
|
*/
|
||||||
public String maskPhoneNumber(String phone) {
|
public String maskPhoneNumber(String phone) {
|
||||||
if (StringUtils.isEmpty(phone)) {
|
if (StringUtils.isEmpty(phone)) {
|
||||||
return "****";
|
return "****";
|
||||||
}
|
}
|
||||||
String cleaned = phone.replaceAll("[^0-9]", "");
|
return com.eactive.eai.common.util.MaskingUtils.maskPhoneNumber(phone);
|
||||||
if (cleaned.length() < 7) {
|
|
||||||
return "****";
|
|
||||||
}
|
|
||||||
return cleaned.substring(0, 3) + "****" + cleaned.substring(cleaned.length() - 4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -134,8 +134,8 @@ public class SsoController implements InterceptorSkipController {
|
|||||||
log.debug("SSO 사용자 정보 - userId: {}, name: {}, phone: {}, email: {}",
|
log.debug("SSO 사용자 정보 - userId: {}, name: {}, phone: {}, email: {}",
|
||||||
userId,
|
userId,
|
||||||
MaskingUtils.maskName(name),
|
MaskingUtils.maskName(name),
|
||||||
maskPhoneNumber(cellPhoneNo),
|
MaskingUtils.maskPhoneNumber(cellPhoneNo),
|
||||||
maskEmail(email));
|
MaskingUtils.maskEmailId(email));
|
||||||
|
|
||||||
// 사용자 생성 또는 업데이트
|
// 사용자 생성 또는 업데이트
|
||||||
UserInfo userInfo = findOrCreateUser(info, extendedInfo);
|
UserInfo userInfo = findOrCreateUser(info, extendedInfo);
|
||||||
@@ -341,33 +341,4 @@ public class SsoController implements InterceptorSkipController {
|
|||||||
}
|
}
|
||||||
return phone.replaceAll("[^0-9]", "");
|
return phone.replaceAll("[^0-9]", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 휴대폰번호 마스킹 (로그용)
|
|
||||||
*/
|
|
||||||
private String maskPhoneNumber(String phone) {
|
|
||||||
if (StringUtils.isEmpty(phone) || phone.length() < 4) {
|
|
||||||
return "****";
|
|
||||||
}
|
|
||||||
// 010-1234-5678 → 010-****-5678
|
|
||||||
String cleaned = phone.replaceAll("[^0-9]", "");
|
|
||||||
if (cleaned.length() < 7) {
|
|
||||||
return "****";
|
|
||||||
}
|
|
||||||
return cleaned.substring(0, 3) + "****" + cleaned.substring(cleaned.length() - 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 이메일 마스킹 (로그용)
|
|
||||||
*/
|
|
||||||
private String maskEmail(String email) {
|
|
||||||
if (StringUtils.isEmpty(email) || !email.contains("@")) {
|
|
||||||
return "****";
|
|
||||||
}
|
|
||||||
int atIndex = email.indexOf("@");
|
|
||||||
if (atIndex <= 2) {
|
|
||||||
return "**" + email.substring(atIndex);
|
|
||||||
}
|
|
||||||
return email.substring(0, 2) + "**" + email.substring(atIndex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,83 +1,52 @@
|
|||||||
package com.eactive.eai.rms.onl.apim.masking;
|
package com.eactive.eai.rms.onl.apim.masking;
|
||||||
|
|
||||||
import com.eactive.eai.rms.common.util.StringUtils;
|
/**
|
||||||
|
* 개인정보 마스킹 유틸리티 (eapim-admin)
|
||||||
import java.util.Arrays;
|
*
|
||||||
import java.util.List;
|
* <p>실제 마스킹 규칙은 보안아키텍처 표준 구현인
|
||||||
import java.util.stream.Collectors;
|
* {@link com.eactive.eai.common.util.MaskingUtils}(elink-online-core)에 위임한다.
|
||||||
|
* 기존 호출부 호환을 위해 메서드명/시그니처는 그대로 유지한다.</p>
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* 이메일 eact***@gmail.com (구) → **ct1**@gmail.com (앞2·뒤2, 4자 이하 전체)
|
||||||
|
* 이름 홍길* (구) → 홍*동 (2자 뒤1, 3자↑ 가운데 전체)
|
||||||
|
* 전화 010-****-5678 (구) → 010-12**-56** (세그먼트별 뒤 2자리)
|
||||||
|
* IPv4 192.168.***.1 (3번째 옥텟) / IPv6 마지막 그룹, 콤마 다중 IP 지원
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
public class MaskingUtils {
|
public class MaskingUtils {
|
||||||
|
|
||||||
|
private MaskingUtils() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 이메일 주소의 ID 부분을 마스킹 처리
|
* 이메일 주소의 ID 부분을 마스킹 처리
|
||||||
* 예: eactive@gmail.com => eact***@gmail.com
|
* 예: aajjbacc@gmail.com => **jjba**@gmail.com
|
||||||
*/
|
*/
|
||||||
public static String maskEmailId(String email) {
|
public static String maskEmailId(String email) {
|
||||||
if (email == null || email.isEmpty() || !email.contains("@")) {
|
return com.eactive.eai.common.util.MaskingUtils.maskEmail(email);
|
||||||
return email;
|
|
||||||
}
|
|
||||||
|
|
||||||
String[] parts = email.split("@");
|
|
||||||
String id = parts[0];
|
|
||||||
String domain = parts[1];
|
|
||||||
|
|
||||||
if (id.length() <= 3) {
|
|
||||||
return "***" + "@" + domain;
|
|
||||||
}
|
|
||||||
|
|
||||||
String maskedId = id.substring(0, id.length() - 3) + "***";
|
|
||||||
return maskedId + "@" + domain;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 이름의 마지막 글자를 마스킹 처리
|
* 이름 마스킹 처리 (2자: 뒤 1자리, 3자 이상: 앞뒤 제외 가운데 전체)
|
||||||
|
* 예: 홍길동 => 홍*동
|
||||||
*/
|
*/
|
||||||
public static String maskName(String name) {
|
public static String maskName(String name) {
|
||||||
if (name == null || name.isEmpty() || name.length() < 2) {
|
return com.eactive.eai.common.util.MaskingUtils.maskKoreanName(name);
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
return name.substring(0, name.length() - 1) + "*";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 전화번호 마스킹 처리
|
* 전화번호/휴대폰/FAX 마스킹 처리 (2·3번째 세그먼트 각각 뒤 2자리)
|
||||||
* 예: 010-1234-5678 => 010-****-5678
|
* 예: 010-1234-5678 => 010-12**-56**
|
||||||
*/
|
*/
|
||||||
public static String maskPhoneNumber(String phoneNumber) {
|
public static String maskPhoneNumber(String phoneNumber) {
|
||||||
if (phoneNumber == null || phoneNumber.isEmpty()) {
|
return com.eactive.eai.common.util.MaskingUtils.maskPhoneNumber(phoneNumber);
|
||||||
return phoneNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
String[] parts = phoneNumber.split("-");
|
|
||||||
if (parts.length != 3) {
|
|
||||||
return phoneNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
return parts[0] + "-****-" + parts[2];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IP 주소 마스킹 처리
|
* IP 주소 마스킹 처리 (IPv4 3번째 옥텟 / IPv6 마지막 그룹, 콤마 다중 IP 지원)
|
||||||
* 예: 192.168.1.1 => 192.168.*.*
|
* 예: 192.168.1.1 => 192.168.***.1
|
||||||
*/
|
*/
|
||||||
public static String maskIpAddress(String ipAddresses) {
|
public static String maskIpAddress(String ipAddresses) {
|
||||||
if (StringUtils.isBlank(ipAddresses)) {
|
return com.eactive.eai.common.util.MaskingUtils.maskIpAddress(ipAddresses);
|
||||||
return ipAddresses;
|
|
||||||
}
|
|
||||||
|
|
||||||
String[] ips = ipAddresses.split(",");
|
|
||||||
List<String> maskedIps = Arrays.stream(ips)
|
|
||||||
.map(ip -> {
|
|
||||||
String[] parts = ip.trim().split("\\.");
|
|
||||||
if (parts.length == 4) {
|
|
||||||
// 세 번째 octet을 ***로 마스킹
|
|
||||||
parts[2] = "***";
|
|
||||||
return String.join(".", parts);
|
|
||||||
}
|
|
||||||
return ip; // 유효하지 않은 IP 형식은 그대로 반환
|
|
||||||
})
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
return String.join(",", maskedIps);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,128 @@
|
|||||||
|
package com.eactive.eai.rms.onl.apim.masking;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eapim-admin {@link MaskingUtils}가 보안아키텍처 표준 규칙(elink-online-core)으로
|
||||||
|
* 위임되어 동작하는지 검증한다.
|
||||||
|
*/
|
||||||
|
class MaskingUtilsTest {
|
||||||
|
|
||||||
|
// --- 이메일 (maskEmailId) ---
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("이메일 — 아이디 앞2·뒤2 마스킹")
|
||||||
|
void maskEmailId_normal() {
|
||||||
|
assertEquals("**st1**@test.com", MaskingUtils.maskEmailId("test123@test.com"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("이메일 — 아이디 4자: 전체 마스킹")
|
||||||
|
void maskEmailId_fourChars() {
|
||||||
|
assertEquals("****@test.com", MaskingUtils.maskEmailId("test@test.com"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("이메일 — 아이디 1자: 전체 마스킹")
|
||||||
|
void maskEmailId_oneChar() {
|
||||||
|
assertEquals("*@123.com", MaskingUtils.maskEmailId("1@123.com"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("이메일 — @ 없으면 원본 / null·빈문자 방어")
|
||||||
|
void maskEmailId_invalidAndNull() {
|
||||||
|
assertEquals("notanemail", MaskingUtils.maskEmailId("notanemail"));
|
||||||
|
assertNull(MaskingUtils.maskEmailId(null));
|
||||||
|
assertEquals("", MaskingUtils.maskEmailId(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- 이름 (maskName) ---
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("이름 — 2자: 뒤 1자리")
|
||||||
|
void maskName_2chars() {
|
||||||
|
assertEquals("가*", MaskingUtils.maskName("가나"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("이름 — 3자: 가운데 1자리")
|
||||||
|
void maskName_3chars() {
|
||||||
|
assertEquals("가*다", MaskingUtils.maskName("가나다"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("이름 — 4자: 앞뒤 제외 가운데 전체")
|
||||||
|
void maskName_4chars() {
|
||||||
|
assertEquals("가**라", MaskingUtils.maskName("가나다라"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("이름 — 5자: 앞뒤 제외 가운데 전체")
|
||||||
|
void maskName_5chars() {
|
||||||
|
assertEquals("가***마", MaskingUtils.maskName("가나다라마"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("이름 — 1자/null/빈문자 방어")
|
||||||
|
void maskName_oneAndNull() {
|
||||||
|
assertEquals("가", MaskingUtils.maskName("가"));
|
||||||
|
assertNull(MaskingUtils.maskName(null));
|
||||||
|
assertEquals("", MaskingUtils.maskName(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- 전화/휴대폰/Fax (maskPhoneNumber) ---
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("전화 — 2·3번째 세그먼트 각 뒤 2자리")
|
||||||
|
void maskPhoneNumber_normal() {
|
||||||
|
assertEquals("010-12**-12**", MaskingUtils.maskPhoneNumber("010-1234-1234"));
|
||||||
|
assertEquals("064-12**-56**", MaskingUtils.maskPhoneNumber("064-1234-5678"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("전화 — 하이픈 없는 11자리")
|
||||||
|
void maskPhoneNumber_noHyphen() {
|
||||||
|
assertEquals("01012**56**", MaskingUtils.maskPhoneNumber("01012345678"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("전화 — null/빈문자 방어")
|
||||||
|
void maskPhoneNumber_null() {
|
||||||
|
assertNull(MaskingUtils.maskPhoneNumber(null));
|
||||||
|
assertEquals("", MaskingUtils.maskPhoneNumber(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- IP (maskIpAddress) ---
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("IPv4 — 3번째 옥텟 마스킹")
|
||||||
|
void maskIpAddress_ipv4() {
|
||||||
|
assertEquals("172.0.***.1", MaskingUtils.maskIpAddress("172.0.0.1"));
|
||||||
|
assertEquals("192.168.***.1", MaskingUtils.maskIpAddress("192.168.100.1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("IPv6 — 마지막 그룹 마스킹")
|
||||||
|
void maskIpAddress_ipv6() {
|
||||||
|
assertEquals(
|
||||||
|
"AAAA:BBBB:CCCC:DDDD:EEEE:FFFF:0000:****",
|
||||||
|
MaskingUtils.maskIpAddress("AAAA:BBBB:CCCC:DDDD:EEEE:FFFF:0000:1111"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("IP — 쉼표 구분 다중 IPv4")
|
||||||
|
void maskIpAddress_multiple() {
|
||||||
|
assertEquals("192.168.***.1,10.0.***.2", MaskingUtils.maskIpAddress("192.168.100.1,10.0.0.2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("IP — null/빈문자 방어")
|
||||||
|
void maskIpAddress_null() {
|
||||||
|
assertNull(MaskingUtils.maskIpAddress(null));
|
||||||
|
assertEquals("", MaskingUtils.maskIpAddress(""));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user