리팩토링 3탄(feat.ChatGPT)

Moon·2024년 2월 23일
0
post-thumbnail

비밀번호 정책이 변경 되어 로직을 수정해야하는 업무를 받았다.

이번 리팩토링에서는 MAP을 활용하고, 테스트케이스를 만들어 간단한 테스트를 진행하였다.


(변경 전) '대문자, 소문자, 특수문자, 숫자' 중 4가지를 모두 포함
(변경 후) '대문자, 소문자, 특수문자, 숫자' 중 최소 3가지를 포함

기존 로직을 살펴보면, 서버에서 설정을 받아와 해당하는 유효성 검사 타입에 따라
정규식에 더한 이후, 한 번에 유효성 검사를 확인하는 것을 확인할 수 있다.


package refactoring3;

import java.util.regex.Pattern;

public class PasswordUtil {

    public static boolean checkValidPassword(String newPassword) {
        boolean result = true;

        // 서버설정으로부터 비밀번호 정책 받아오기
        // ...

        // 패스워드 정책
        String pwdCValidType    = "U,L,S,N";
        String pwdMinLength     = "8";
        String pwdMaxLength     = "20";

        // 비밀번호 길이 체크 로직
        // if (짧거나 길다면) return false;
        
        // 정규표현식 생성
        String regExpStrMust = "^";

        // 비밀번호 정책 배열 생성
        String[] validType = pwdCValidType.split(",");

        for(int i =0; i < validType.length; i++){
            switch (validType[i]){
                case "U" :  // 대문자
                    regExpStrMust += "(?=.*[A-Z])";
                    break;
                case "L" :  // 소문자
                    regExpStrMust += "(?=.*[a-z])";
                    break;
                case "S" :  // 특수문자
                    regExpStrMust += "(?=.*[~!@#$%^&*+=_{}:;'\"<>,./()|-])";
                    break;
                case "N" :  // 숫자
                    regExpStrMust += "(?=.*[0-9])";
                    break;
            }
        }

        // 비멀번호 유효성 검사
        if(Pattern.compile(regExpStrMust).matcher(newPassword).find()){
            return true;
        } else {
            return false;
        }

    }
}

기존 로직을 사용할 경우, 최소 3가지라는 개념을 적용할 수 없어 변경이 필요했다.

MAP으로 정규표현식을 담아준 후, 해당하는 서버 설정에 따라 유효성 검사를 진행하며

끝으로 해당 유효성 검사가 충족되었는지를 판단한다.

package refactoring3;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

public class refactoredPasswordUtil {

    public static boolean checkValidPassword(String newPassword) {
        boolean result = true;

        // 서버설정으로부터 비밀번호 정책 받아오기
        // ...

        // 패스워드 정책
        String pwdCValidType    = "3,U,L,S,N";
        String pwdMinLength     = "8";
        String pwdMaxLength     = "20";

        // 비밀번호 길이 체크 로직
        // if (짧거나 길다면) return false;

        // 정규표현식
        String upperRegex = "(?=.*[A-Z])";      // 대문자
        String smallRegex = ".(?=.*[a-z])";      // 소문자
        String specialRegex = "(?=.*[~!@#$%^&*+=_{}:;'\"<>,./()|-])";   // 특수문자
        String numberRegex = "(?=.*[0-9])";     // 숫자

        // 정규표현식 MAP 생성
        Map<String, Pattern> checkValidType = new HashMap<>();
        checkValidType.put("U", Pattern.compile(upperRegex));
        checkValidType.put("L", Pattern.compile(smallRegex));
        checkValidType.put("S", Pattern.compile(specialRegex));
        checkValidType.put("N", Pattern.compile(numberRegex));

        // 비밀번호 정책 배열 생성
        String[] validType = pwdCValidType.split(",");

        // 비밀번호 검사를 위한 int값 생성
        int requiredCount = Integer.parseInt(validType[0]);
        int satisfiedCount = 0;


        // 비멀번호 유효성 검사
        for (String valid : validType){
            if (isNumeric(valid)) continue;

            Pattern checkRegex = checkValidType.get(valid);
            if (checkRegex.matcher(newPassword).find()) satisfiedCount++;
        }

        // 검사한 비밀번호 유효성 수가 부족하다면 false return
        return satisfiedCount >= requiredCount;
    }

    public static boolean isNumeric(String str) {
        return str.chars().allMatch(Character::isDigit);
    }
}

내가 작성한 코드가 문제 없이 작동하는지 확인이 필요했다.
간단하게 테스트 코드를 작성하였다.
ChatGPT의 도움을 빌려 테스트 케이스를 받았고, 테스트 결과 모든 케이스를 통과하는 것을 확인할 수 있었다.

package refactoring3;

public class testPasswordUtil {

    public static void main(String[] args) {

        // 유효한 비밀번호 (대문자, 소문자, 특수문자, 숫자 중 3가지 포함)
        String[] validPasswords = {
                "ValidPassword1!",   // 대문자, 소문자, 숫자 포함
                "PaSsWoRd123@",      // 대문자, 소문자, 특수문자 포함
                "SecurePwd!2022",    // 대문자, 특수문자, 숫자 포함
                "9StrongPwd!",       // 소문자, 특수문자, 숫자 포함
                "Passw0rd!!2024",    // 대문자, 소문자, 특수문자 포함
                "My$ecurePwd11",     // 대문자, 특수문자, 숫자 포함
                "Pwd!9876My",        // 대문자, 특수문자, 숫자 포함
                "V@lidP@ssw0rd"      // 대문자, 소문자, 특수문자 포함
        };

        // 유효하지 않은 비밀번호
        String[] invalidPasswords = {
                "NoNumbers",                   // 특수문자, 숫자 없음
                "nouppercaseor123",            // 특수문자, 대문자 없음
                "SPECIAL123123",               // 특수문자, 소문자 없음
                "12@3456789",                  // 대문자, 소문 없음
                "onlylower@caseletters",       // 대문자, 숫자 없음
                "abcd1234567",                 // 대문자, 특수문자 없음
                "ACD213456",                   // 소문자, 특수문자 없음
                "ABCD@#!@%$",                  // 소문자, 숫자 없음
                "AacDfdfasd"                   // 특수문자, 숫자 없음
        };

        for (String test : validPasswords){
            if(refactoredPasswordUtil.checkValidPassword(test)){
                System.out.println("테스트 통과");
            } else {
                System.out.println("테스트 실패" + test);
            }
        }

        System.out.println("=================");

        for (String test : invalidPasswords){
            if (refactoredPasswordUtil.checkValidPassword(test)){
                System.out.println("테스트 실패" + test);
            } else {
                System.out.println("테스트 통과");
            }
        }

    }
}
테스트 통과
테스트 통과
테스트 통과
테스트 통과
테스트 통과
테스트 통과
테스트 통과
테스트 통과
=================
테스트 통과
테스트 통과
테스트 통과
테스트 통과
테스트 통과
테스트 통과
테스트 통과
테스트 통과
테스트 통과
profile
안녕하세요. Moon입니다!

0개의 댓글