-
Notifications
You must be signed in to change notification settings - Fork 0
[App] 회원가입 페이지/기능 구현 #66
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
Changes from all commits
531f1b6
04ee159
5ac100b
2ceb479
fdcea4f
1e1e8f9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| package app.db; | ||
|
|
||
| import app.model.User; | ||
| import database.ConnectionManager; | ||
| import database.CrudRepository; | ||
|
|
||
| public class UserRepository extends CrudRepository<User> { | ||
| public UserRepository(ConnectionManager connectionManager) { | ||
| super(connectionManager, User.class); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,8 @@ | ||
| package app.handler; | ||
|
|
||
| import app.db.Database; | ||
| import app.db.UserRepository; | ||
| import app.model.User; | ||
| import config.VariableConfig; | ||
| import exception.ErrorCode; | ||
| import exception.ServiceException; | ||
| import http.HttpMethod; | ||
|
|
@@ -14,19 +15,58 @@ | |
| import web.response.RedirectResponse; | ||
|
|
||
| public class RegisterWithPost extends SingleArgHandler<QueryParameters> { | ||
| private static final String EMAIL = "email"; | ||
| private static final String NICKNAME = "nickname"; | ||
| private static final String PASSWORD = "password"; | ||
|
|
||
| private static final Logger log = LoggerFactory.getLogger(RegisterWithPost.class); | ||
|
|
||
| public RegisterWithPost() { | ||
| private final UserRepository userRepository; | ||
|
|
||
| public RegisterWithPost(UserRepository userRepository) { | ||
| super(HttpMethod.POST, "/user/create"); | ||
| this.userRepository = userRepository; | ||
| } | ||
|
|
||
| @Override | ||
| public HandlerResponse handle(QueryParameters params) { | ||
| String email = params.getQueryValue("email").orElseThrow(()-> new ServiceException(ErrorCode.MISSING_REGISTER_TOKEN, "email required")); | ||
| String nickname = params.getQueryValue("nickname").orElseThrow(()-> new ServiceException(ErrorCode.MISSING_REGISTER_TOKEN, "nickname required")); | ||
| String password = params.getQueryValue("password").orElseThrow(()-> new ServiceException(ErrorCode.MISSING_REGISTER_TOKEN, "password required")); | ||
| Database.addUser(new User(password, nickname, email, UserRole.MEMBER.toString())); | ||
| log.info("Registered - password:{}, nickname:{}, email:{}", password, nickname, email); | ||
| String email = getRequired(params, EMAIL); | ||
| String nickname = getRequired(params, NICKNAME); | ||
| String password = getRequired(params, PASSWORD); | ||
|
|
||
| validate(email, nickname, password); | ||
|
|
||
| User saved = userRepository.save( | ||
| new User(password, nickname, email, UserRole.MEMBER.toString())); | ||
|
|
||
| log.info("Registered id:{}, email:{}, nickname:{}, password:{}", | ||
| saved.getId(), email, nickname, password); | ||
| return RedirectResponse.to("/login"); | ||
| } | ||
|
|
||
| private void validate(String email, String nickname, String password) { | ||
| validateDuplicate(email, nickname); | ||
| validateLength(email, VariableConfig.EMAIL_MIN, VariableConfig.EMAIL_MAX, ErrorCode.EMAIL_LENGTH_INVALID); | ||
| validateLength(nickname, VariableConfig.NICKNAME_MIN, VariableConfig.NICKNAME_MAX, ErrorCode.NICKNAME_LENGTH_INVALID); | ||
| validateLength(password, VariableConfig.PASSWORD_MIN, VariableConfig.PASSWORD_MAX, ErrorCode.PASSWORD_LENGTH_INVALID); | ||
|
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. 문제: 제안: 이미 정의된 상수를 활용하도록 수정하세요: if (!userRepository.findByColumn(EMAIL, email).isEmpty()) |
||
| } | ||
|
|
||
| private String getRequired(QueryParameters params, String key) { | ||
| return params.getQueryValue(key) | ||
| .orElseThrow(() -> new ServiceException(ErrorCode.MISSING_REGISTER_TOKEN, key + " required")); | ||
| } | ||
|
|
||
| private void validateLength(String value, int min, int max, ErrorCode code) { | ||
| int len = value.length(); | ||
| if (len < min || len > max) | ||
| throw new ServiceException(code); | ||
| } | ||
|
|
||
| private void validateDuplicate(String email, String nickname) { | ||
| if (!userRepository.findByColumn(EMAIL, email).isEmpty()) | ||
| throw new ServiceException(ErrorCode.EMAIL_ALREADY_EXISTS); | ||
|
|
||
| if (!userRepository.findByColumn(NICKNAME, nickname).isEmpty()) | ||
| throw new ServiceException(ErrorCode.NICKNAME_ALREADY_EXISTS); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,4 +12,11 @@ public class VariableConfig { | |
|
|
||
| public static final long IDLE_MS = 30*60*100; | ||
| public static final long ABSOLUTE_MS = 180*60*100; | ||
|
|
||
| public static final int EMAIL_MAX = 50; | ||
| public static final int EMAIL_MIN = 4; | ||
| public static final int NICKNAME_MAX = 12; | ||
| public static final int NICKNAME_MIN = 4; | ||
| public static final int PASSWORD_MAX = 16; | ||
| public static final int PASSWORD_MIN = 4; | ||
|
Comment on lines
+19
to
+21
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. 제안: 빈 줄 처리. 가독성 개선을 위해 상수 그룹 사이의 빈 줄을 하나로 줄이세요: public static final int EMAIL_MAX = 50;
public static final int EMAIL_MIN = 4; |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -43,10 +43,10 @@ public T save(T entity) { | |
| if (Modifier.isStatic(field.getModifiers())) { | ||
| continue; | ||
| } | ||
| if ("id".equals(field.getName())) { | ||
| if ("id".equals(toColumnName(field.getName()))) { | ||
| continue; | ||
| } | ||
| sqlBuilder.append(field.getName()).append(", "); | ||
| sqlBuilder.append(toColumnName(field.getName())).append(", "); | ||
|
Comment on lines
43
to
+49
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. 문제: 맥락: if ("id".equals(field.getName())) {
continue;
}camelCase 필드명으로 비교하는 게 논리적으로 더 명확합니다. |
||
| placeholder.append("?, "); | ||
| insertFields.add(field); | ||
| } | ||
|
|
@@ -128,7 +128,7 @@ public List<T> findAll() { | |
| } | ||
|
|
||
| public List<T> findByColumn(String columnName, Object value) { | ||
| String sql = "SELECT * FROM " + tableName + " WHERE " + columnName + " = ?"; | ||
| String sql = "SELECT * FROM " + tableName + " WHERE " + toColumnName(columnName) + " = ?"; | ||
|
|
||
|
Comment on lines
128
to
132
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. 문제: 확인 사항: |
||
| try (Connection conn = connectionManager.getConnection(); | ||
| PreparedStatement pstmt = conn.prepareStatement(sql)) { | ||
|
|
@@ -145,7 +145,7 @@ public List<T> findByColumn(String columnName, Object value) { | |
| } | ||
|
|
||
| } catch (SQLException e) { | ||
| throw new ErrorException("엔티티 조회 중 오류 (column=" + columnName + ", value=" + value + ")", e); | ||
| throw new ErrorException("엔티티 조회 중 오류 (column=" + toColumnName(columnName) + ", value=" + value + ")", e); | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -167,10 +167,10 @@ public void update(T entity) { | |
| if (Modifier.isStatic(field.getModifiers())) { | ||
| continue; | ||
| } | ||
| if ("id".equals(field.getName())) { | ||
| if ("id".equals(toColumnName(field.getName()))) { | ||
| continue; | ||
| } | ||
| sql.append(field.getName()).append(" = ?, "); | ||
| sql.append(toColumnName(field.getName())).append(" = ?, "); | ||
|
Comment on lines
167
to
+173
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. 문제: 제안: 원본 필드명으로 비교하세요: if ("id".equals(field.getName())) {
continue;
} |
||
| updateFields.add(field); | ||
| } | ||
|
|
||
|
|
@@ -264,7 +264,7 @@ private T mapRow(ResultSet resultSet) { | |
| continue; | ||
| } | ||
|
|
||
| String columnName = field.getName(); | ||
| String columnName = toColumnName(field.getName()); | ||
| field.setAccessible(true); | ||
|
|
||
| Class<?> fieldType = field.getType(); | ||
|
|
@@ -311,4 +311,9 @@ private String toTableName(Class<?> clazz) { | |
| } | ||
| return name; | ||
| } | ||
|
|
||
| private String toColumnName(String str){ | ||
| String snake = str.replaceAll("(?<!^)([A-Z])", "_$1"); | ||
| return snake.toLowerCase(); | ||
| } | ||
| } | ||
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.
문제: 로그 메시지에 민감한 정보(비밀번호)가 포함되어 있습니다. 본 PR에서는 로그 출력을 추가했는데, 비밀번호를 그대로 출력하는 것은 보안 위험입니다.
제안: 비밀번호를 로그에 기록하지 않으세요: