-
Notifications
You must be signed in to change notification settings - Fork 8
feat: 비밀번호 정책 추가 #435
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Gyuhyeok99
merged 4 commits into
solid-connection:develop
from
Gyuhyeok99:feat/434-add-password-policy
Aug 12, 2025
Merged
feat: 비밀번호 정책 추가 #435
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
4 changes: 4 additions & 0 deletions
4
src/main/java/com/example/solidconnection/auth/dto/EmailSignInRequest.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
5 changes: 4 additions & 1 deletion
5
src/main/java/com/example/solidconnection/auth/dto/EmailSignUpTokenRequest.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
20 changes: 20 additions & 0 deletions
20
src/main/java/com/example/solidconnection/auth/dto/validation/Password.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| package com.example.solidconnection.auth.dto.validation; | ||
|
|
||
| import jakarta.validation.Constraint; | ||
| import jakarta.validation.Payload; | ||
| import java.lang.annotation.ElementType; | ||
| import java.lang.annotation.Retention; | ||
| import java.lang.annotation.RetentionPolicy; | ||
| import java.lang.annotation.Target; | ||
|
|
||
| @Target({ElementType.FIELD, ElementType.RECORD_COMPONENT}) | ||
| @Retention(RetentionPolicy.RUNTIME) | ||
| @Constraint(validatedBy = PasswordValidator.class) | ||
| public @interface Password { | ||
|
|
||
| String message() default "비밀번호는 영문, 숫자, 특수문자를 포함한 8자리 이상이어야 합니다."; | ||
|
|
||
| Class<?>[] groups() default {}; | ||
|
|
||
| Class<? extends Payload>[] payload() default {}; | ||
| } |
16 changes: 16 additions & 0 deletions
16
src/main/java/com/example/solidconnection/auth/dto/validation/PasswordValidator.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| package com.example.solidconnection.auth.dto.validation; | ||
|
|
||
| import jakarta.validation.ConstraintValidator; | ||
| import jakarta.validation.ConstraintValidatorContext; | ||
|
|
||
| public class PasswordValidator implements ConstraintValidator<Password, String> { | ||
|
|
||
| @Override | ||
| public boolean isValid(String value, ConstraintValidatorContext context) { | ||
| if (value == null || value.isBlank()) { | ||
| return true; | ||
| } | ||
|
|
||
| return value.matches("^(?=.*[A-Za-z])(?=.*\\d)(?=.*[!@#$%^&*()_+\\-={}\\[\\]|:;\"'<>,.?/`~])\\S{8,}$"); | ||
| } | ||
|
Comment on lines
+14
to
+15
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent ❓ Verification inconclusive[3] 정규식 퍼포먼스 개선과 정책 명확화 제안(사전 컴파일 + 유니코드 옵션)
적용 diff(ASCII 정책 유지, 사전 컴파일): @@
-import jakarta.validation.ConstraintValidator;
-import jakarta.validation.ConstraintValidatorContext;
+import jakarta.validation.ConstraintValidator;
+import jakarta.validation.ConstraintValidatorContext;
+import java.util.regex.Pattern;
@@
-public class PasswordValidator implements ConstraintValidator<Password, String> {
+public class PasswordValidator implements ConstraintValidator<Password, String> {
+
+ private static final Pattern PASSWORD_PATTERN = Pattern.compile(
+ "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[!@#$%^&*()_+\\-={}\\[\\]|:;\\\"'<>,.?/`~])\\S{8,}$"
+ );
@@
- return value.matches("^(?=.*[A-Za-z])(?=.*\\d)(?=.*[!@#$%^&*()_+\\-={}\\[\\]|:;\"'<>,.?/`~])\\S{8,}$");
+ return PASSWORD_PATTERN.matcher(value).matches();유니코드 ‘문자’ 허용(선택사항) 예시:
private static final Pattern PASSWORD_PATTERN = Pattern.compile(
"^(?=.*\\p{L})(?=.*\\d)(?=.*[\\p{Punct}\\p{S}])\\S{8,}$"
);추가로 테스트 케이스 보강을 권장합니다.
정규식 성능 최적화 및 정책 명확화 제안
위 제안을 반영해 보시고, 패턴 변경이 전체 검증 로직에 미치는 영향을 함께 확인하세요. 🤖 Prompt for AI Agents |
||
| } | ||
42 changes: 42 additions & 0 deletions
42
src/test/java/com/example/solidconnection/auth/dto/validation/PasswordValidatorTest.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| package com.example.solidconnection.auth.dto.validation; | ||
|
|
||
| import static org.assertj.core.api.Assertions.assertThat; | ||
|
|
||
| import org.junit.jupiter.api.DisplayName; | ||
| import org.junit.jupiter.api.Test; | ||
|
|
||
| @DisplayName("비밀번호 유효성 검사 테스트") | ||
| class PasswordValidatorTest { | ||
|
|
||
| private final PasswordValidator validator = new PasswordValidator(); | ||
|
|
||
| @Test | ||
| void 정상_패턴이면_true를_반환한다() { | ||
| assertThat(validator.isValid("abcd123!", null)).isTrue(); | ||
| } | ||
|
|
||
| @Test | ||
| void 숫자가_없으면_false를_반환한다() { | ||
| assertThat(validator.isValid("abcdefg!", null)).isFalse(); | ||
| } | ||
|
|
||
| @Test | ||
| void 영문자가_없으면_false를_반환한다() { | ||
| assertThat(validator.isValid("1234567!", null)).isFalse(); | ||
| } | ||
|
|
||
| @Test | ||
| void 특수문자가_없으면_false를_반환한다() { | ||
| assertThat(validator.isValid("abcd1234", null)).isFalse(); | ||
| } | ||
|
|
||
| @Test | ||
| void 공백을_포함하면_false를_반환한다() { | ||
| assertThat(validator.isValid("abcd123! ", null)).isFalse(); | ||
| } | ||
|
|
||
| @Test | ||
| void 길이가_8자_미만이면_false를_반환한다() { | ||
| assertThat(validator.isValid("ab1!ab", null)).isFalse(); | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
비밀번호 정책 추가는 OK, “어노테이션 순서 민감도”는 그룹 시퀀스로 해결하세요.
아래는 DTO 필드의 그룹 지정 예시입니다.
그리고 그룹/시퀀스 정의 예시입니다(패키지 내 공용 인터페이스로 두고 재사용 권장).
컨트롤러 바인딩 시 그룹 시퀀스를 사용하세요.
PasswordValidator 보완 예시(입력 공백 위임):
다음 스크립트로 환경/구현 상태를 점검해 주세요.
원하시면 그룹/시퀀스 도입 PR 보조 커밋과 테스트 케이스(순서 의존성 제거)를 바로 생성해드리겠습니다.
🏁 Script executed:
Length of output: 12161
그룹 시퀀스로 검증 순서를 고정하세요
그룹/시퀀스 정의
•
RequiredChecks와PasswordPolicyChecks인터페이스를 만들고•
@GroupSequence({RequiredChecks.class, PasswordPolicyChecks.class})로 순서를 지정합니다.DTO 필드에 그룹 지정
•
EmailSignInRequest와EmailSignUpTokenRequest의password필드에diff - @Password - @NotBlank(message = "비밀번호를 입력해주세요.") + @NotBlank(message = "비밀번호를 입력해주세요.", groups = RequiredChecks.class) + @Password(groups = PasswordPolicyChecks.class)를 적용하세요.
컨트롤러에 시퀀스 적용
•
/sign-in등 관련 엔드포인트 메서드에@Validated(ValidationSequence.class)를 붙여 그룹 시퀀스를 활성화합니다.순서 의존성 제거 테스트 추가
• 어노테이션 배치 순서를 바꿔도 동일한 검증 결과가 나오는지 검증하는 파라미터라이즈드 테스트를 작성하세요.
추가 참고
PasswordValidator는 이미null·빈 문자열을 허용하도록(return true) 구현되어 있어@NotBlank에 입력 여부 체크를 위임하고 있습니다.hibernate.validator.fail_fast설정은 기본값(false)으로 확인되어 있으며, 그룹 시퀀스 도입으로 모든 순서 이슈를 완벽히 제거할 수 있습니다.📝 Committable suggestion
🤖 Prompt for AI Agents